ActivityManagerService.java revision 71e737c8e8b970d780b930ebc6eacb4464d4a6aa
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.ITaskStackListener; 41import android.app.ProfilerInfo; 42import android.app.admin.DevicePolicyManager; 43import android.app.usage.UsageEvents; 44import android.app.usage.UsageStatsManagerInternal; 45import android.appwidget.AppWidgetManager; 46import android.content.res.Resources; 47import android.graphics.Bitmap; 48import android.graphics.Point; 49import android.graphics.Rect; 50import android.os.BatteryStats; 51import android.os.PersistableBundle; 52import android.os.storage.IMountService; 53import android.os.storage.StorageManager; 54import android.service.voice.IVoiceInteractionSession; 55import android.util.ArrayMap; 56import android.util.ArraySet; 57import android.util.SparseIntArray; 58 59import com.android.internal.R; 60import com.android.internal.annotations.GuardedBy; 61import com.android.internal.app.IAppOpsService; 62import com.android.internal.app.IVoiceInteractor; 63import com.android.internal.app.ProcessMap; 64import com.android.internal.app.ProcessStats; 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.Installer; 85import com.android.server.pm.UserManagerService; 86import com.android.server.statusbar.StatusBarManagerInternal; 87import com.android.server.wm.AppTransition; 88import com.android.server.wm.WindowManagerService; 89import com.google.android.collect.Lists; 90import com.google.android.collect.Maps; 91 92import libcore.io.IoUtils; 93 94import org.xmlpull.v1.XmlPullParser; 95import org.xmlpull.v1.XmlPullParserException; 96import org.xmlpull.v1.XmlSerializer; 97 98import android.app.Activity; 99import android.app.ActivityManager; 100import android.app.ActivityManager.RunningTaskInfo; 101import android.app.ActivityManager.StackInfo; 102import android.app.ActivityManagerInternal; 103import android.app.ActivityManagerNative; 104import android.app.ActivityOptions; 105import android.app.ActivityThread; 106import android.app.AlertDialog; 107import android.app.AppGlobals; 108import android.app.ApplicationErrorReport; 109import android.app.Dialog; 110import android.app.IActivityController; 111import android.app.IApplicationThread; 112import android.app.IInstrumentationWatcher; 113import android.app.INotificationManager; 114import android.app.IProcessObserver; 115import android.app.IServiceConnection; 116import android.app.IStopUserCallback; 117import android.app.IUiAutomationConnection; 118import android.app.IUserSwitchObserver; 119import android.app.Instrumentation; 120import android.app.Notification; 121import android.app.NotificationManager; 122import android.app.PendingIntent; 123import android.app.backup.IBackupManager; 124import android.content.ActivityNotFoundException; 125import android.content.BroadcastReceiver; 126import android.content.ClipData; 127import android.content.ComponentCallbacks2; 128import android.content.ComponentName; 129import android.content.ContentProvider; 130import android.content.ContentResolver; 131import android.content.Context; 132import android.content.DialogInterface; 133import android.content.IContentProvider; 134import android.content.IIntentReceiver; 135import android.content.IIntentSender; 136import android.content.Intent; 137import android.content.IntentFilter; 138import android.content.IntentSender; 139import android.content.pm.ActivityInfo; 140import android.content.pm.ApplicationInfo; 141import android.content.pm.ConfigurationInfo; 142import android.content.pm.IPackageDataObserver; 143import android.content.pm.IPackageManager; 144import android.content.pm.InstrumentationInfo; 145import android.content.pm.PackageInfo; 146import android.content.pm.PackageManager; 147import android.content.pm.ParceledListSlice; 148import android.content.pm.UserInfo; 149import android.content.pm.PackageManager.NameNotFoundException; 150import android.content.pm.PathPermission; 151import android.content.pm.ProviderInfo; 152import android.content.pm.ResolveInfo; 153import android.content.pm.ServiceInfo; 154import android.content.res.CompatibilityInfo; 155import android.content.res.Configuration; 156import android.net.Proxy; 157import android.net.ProxyInfo; 158import android.net.Uri; 159import android.os.Binder; 160import android.os.Build; 161import android.os.Bundle; 162import android.os.Debug; 163import android.os.DropBoxManager; 164import android.os.Environment; 165import android.os.FactoryTest; 166import android.os.FileObserver; 167import android.os.FileUtils; 168import android.os.Handler; 169import android.os.IBinder; 170import android.os.IPermissionController; 171import android.os.IRemoteCallback; 172import android.os.IUserManager; 173import android.os.Looper; 174import android.os.Message; 175import android.os.Parcel; 176import android.os.ParcelFileDescriptor; 177import android.os.PowerManagerInternal; 178import android.os.Process; 179import android.os.RemoteCallbackList; 180import android.os.RemoteException; 181import android.os.SELinux; 182import android.os.ServiceManager; 183import android.os.StrictMode; 184import android.os.SystemClock; 185import android.os.SystemProperties; 186import android.os.UpdateLock; 187import android.os.UserHandle; 188import android.os.UserManager; 189import android.provider.Settings; 190import android.text.format.DateUtils; 191import android.text.format.Time; 192import android.util.AtomicFile; 193import android.util.EventLog; 194import android.util.Log; 195import android.util.Pair; 196import android.util.PrintWriterPrinter; 197import android.util.Slog; 198import android.util.SparseArray; 199import android.util.TimeUtils; 200import android.util.Xml; 201import android.view.Gravity; 202import android.view.LayoutInflater; 203import android.view.View; 204import android.view.WindowManager; 205 206import dalvik.system.VMRuntime; 207 208import java.io.BufferedInputStream; 209import java.io.BufferedOutputStream; 210import java.io.DataInputStream; 211import java.io.DataOutputStream; 212import java.io.File; 213import java.io.FileDescriptor; 214import java.io.FileInputStream; 215import java.io.FileNotFoundException; 216import java.io.FileOutputStream; 217import java.io.IOException; 218import java.io.InputStreamReader; 219import java.io.PrintWriter; 220import java.io.StringWriter; 221import java.lang.ref.WeakReference; 222import java.util.ArrayList; 223import java.util.Arrays; 224import java.util.Collections; 225import java.util.Comparator; 226import java.util.HashMap; 227import java.util.HashSet; 228import java.util.Iterator; 229import java.util.List; 230import java.util.Locale; 231import java.util.Map; 232import java.util.Set; 233import java.util.concurrent.atomic.AtomicBoolean; 234import java.util.concurrent.atomic.AtomicLong; 235 236public final class ActivityManagerService extends ActivityManagerNative 237 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 238 239 private static final String USER_DATA_DIR = "/data/user/"; 240 // File that stores last updated system version and called preboot receivers 241 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 242 243 static final String TAG = "ActivityManager"; 244 static final String TAG_MU = "ActivityManagerServiceMU"; 245 static final boolean DEBUG = false; 246 static final boolean localLOGV = DEBUG; 247 static final boolean DEBUG_BACKUP = localLOGV || false; 248 static final boolean DEBUG_BROADCAST = localLOGV || false; 249 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 250 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 251 static final boolean DEBUG_CLEANUP = localLOGV || false; 252 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 253 static final boolean DEBUG_FOCUS = false; 254 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 255 static final boolean DEBUG_MU = localLOGV || false; 256 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 257 static final boolean DEBUG_LRU = localLOGV || false; 258 static final boolean DEBUG_PAUSE = localLOGV || false; 259 static final boolean DEBUG_POWER = localLOGV || false; 260 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 261 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 262 static final boolean DEBUG_PROCESSES = localLOGV || false; 263 static final boolean DEBUG_PROVIDER = localLOGV || false; 264 static final boolean DEBUG_RESULTS = localLOGV || false; 265 static final boolean DEBUG_SERVICE = localLOGV || false; 266 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 267 static final boolean DEBUG_STACK = localLOGV || false; 268 static final boolean DEBUG_SWITCH = localLOGV || false; 269 static final boolean DEBUG_TASKS = localLOGV || false; 270 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 271 static final boolean DEBUG_TRANSITION = localLOGV || false; 272 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 273 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 274 static final boolean DEBUG_VISBILITY = localLOGV || false; 275 static final boolean DEBUG_PSS = localLOGV || false; 276 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 277 static final boolean DEBUG_RECENTS = localLOGV || false; 278 static final boolean VALIDATE_TOKENS = false; 279 static final boolean SHOW_ACTIVITY_START_TIME = true; 280 281 // Control over CPU and battery monitoring. 282 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 283 static final boolean MONITOR_CPU_USAGE = true; 284 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 285 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 286 static final boolean MONITOR_THREAD_CPU_USAGE = false; 287 288 // The flags that are set for all calls we make to the package manager. 289 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 290 291 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 292 293 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 294 295 // Maximum number recent bitmaps to keep in memory. 296 static final int MAX_RECENT_BITMAPS = 3; 297 298 // Amount of time after a call to stopAppSwitches() during which we will 299 // prevent further untrusted switches from happening. 300 static final long APP_SWITCH_DELAY_TIME = 5*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. 304 static final int PROC_START_TIMEOUT = 10*1000; 305 306 // How long we wait for a launched process to attach to the activity manager 307 // before we decide it's never going to come up for real, when the process was 308 // started with a wrapper for instrumentation (such as Valgrind) because it 309 // could take much longer than usual. 310 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 311 312 // How long to wait after going idle before forcing apps to GC. 313 static final int GC_TIMEOUT = 5*1000; 314 315 // The minimum amount of time between successive GC requests for a process. 316 static final int GC_MIN_INTERVAL = 60*1000; 317 318 // The minimum amount of time between successive PSS requests for a process. 319 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 320 321 // The minimum amount of time between successive PSS requests for a process 322 // when the request is due to the memory state being lowered. 323 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 324 325 // The rate at which we check for apps using excessive power -- 15 mins. 326 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 327 328 // The minimum sample duration we will allow before deciding we have 329 // enough data on wake locks to start killing things. 330 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 331 332 // The minimum sample duration we will allow before deciding we have 333 // enough data on CPU usage to start killing things. 334 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 335 336 // How long we allow a receiver to run before giving up on it. 337 static final int BROADCAST_FG_TIMEOUT = 10*1000; 338 static final int BROADCAST_BG_TIMEOUT = 60*1000; 339 340 // How long we wait until we timeout on key dispatching. 341 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 342 343 // How long we wait until we timeout on key dispatching during instrumentation. 344 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 345 346 // Amount of time we wait for observers to handle a user switch before 347 // giving up on them and unfreezing the screen. 348 static final int USER_SWITCH_TIMEOUT = 2*1000; 349 350 // Maximum number of users we allow to be running at a time. 351 static final int MAX_RUNNING_USERS = 3; 352 353 // How long to wait in getAssistContextExtras for the activity and foreground services 354 // to respond with the result. 355 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 356 357 // Maximum number of persisted Uri grants a package is allowed 358 static final int MAX_PERSISTED_URI_GRANTS = 128; 359 360 static final int MY_PID = Process.myPid(); 361 362 static final String[] EMPTY_STRING_ARRAY = new String[0]; 363 364 // How many bytes to write into the dropbox log before truncating 365 static final int DROPBOX_MAX_SIZE = 256 * 1024; 366 367 // Access modes for handleIncomingUser. 368 static final int ALLOW_NON_FULL = 0; 369 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 370 static final int ALLOW_FULL_ONLY = 2; 371 372 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 373 374 // Delay in notifying task stack change listeners (in millis) 375 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 376 377 /** All system services */ 378 SystemServiceManager mSystemServiceManager; 379 380 private Installer mInstaller; 381 382 /** Run all ActivityStacks through this */ 383 ActivityStackSupervisor mStackSupervisor; 384 385 /** Task stack change listeners. */ 386 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 387 new RemoteCallbackList<ITaskStackListener>(); 388 389 public IntentFirewall mIntentFirewall; 390 391 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 392 // default actuion automatically. Important for devices without direct input 393 // devices. 394 private boolean mShowDialogs = true; 395 396 BroadcastQueue mFgBroadcastQueue; 397 BroadcastQueue mBgBroadcastQueue; 398 // Convenient for easy iteration over the queues. Foreground is first 399 // so that dispatch of foreground broadcasts gets precedence. 400 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 401 402 BroadcastQueue broadcastQueueForIntent(Intent intent) { 403 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 404 if (DEBUG_BACKGROUND_BROADCAST) { 405 Slog.i(TAG, "Broadcast intent " + intent + " on " 406 + (isFg ? "foreground" : "background") 407 + " queue"); 408 } 409 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 410 } 411 412 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 413 for (BroadcastQueue queue : mBroadcastQueues) { 414 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 415 if (r != null) { 416 return r; 417 } 418 } 419 return null; 420 } 421 422 /** 423 * Activity we have told the window manager to have key focus. 424 */ 425 ActivityRecord mFocusedActivity = null; 426 427 /** 428 * List of intents that were used to start the most recent tasks. 429 */ 430 ArrayList<TaskRecord> mRecentTasks; 431 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 432 433 /** 434 * For addAppTask: cached of the last activity component that was added. 435 */ 436 ComponentName mLastAddedTaskComponent; 437 438 /** 439 * For addAppTask: cached of the last activity uid that was added. 440 */ 441 int mLastAddedTaskUid; 442 443 /** 444 * For addAppTask: cached of the last ActivityInfo that was added. 445 */ 446 ActivityInfo mLastAddedTaskActivity; 447 448 public class PendingAssistExtras extends Binder implements Runnable { 449 public final ActivityRecord activity; 450 public final Bundle extras; 451 public final Intent intent; 452 public final String hint; 453 public final int userHandle; 454 public boolean haveResult = false; 455 public Bundle result = null; 456 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 457 String _hint, int _userHandle) { 458 activity = _activity; 459 extras = _extras; 460 intent = _intent; 461 hint = _hint; 462 userHandle = _userHandle; 463 } 464 @Override 465 public void run() { 466 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 467 synchronized (this) { 468 haveResult = true; 469 notifyAll(); 470 } 471 } 472 } 473 474 final ArrayList<PendingAssistExtras> mPendingAssistExtras 475 = new ArrayList<PendingAssistExtras>(); 476 477 /** 478 * Process management. 479 */ 480 final ProcessList mProcessList = new ProcessList(); 481 482 /** 483 * All of the applications we currently have running organized by name. 484 * The keys are strings of the application package name (as 485 * returned by the package manager), and the keys are ApplicationRecord 486 * objects. 487 */ 488 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 489 490 /** 491 * Tracking long-term execution of processes to look for abuse and other 492 * bad app behavior. 493 */ 494 final ProcessStatsService mProcessStats; 495 496 /** 497 * The currently running isolated processes. 498 */ 499 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 500 501 /** 502 * Counter for assigning isolated process uids, to avoid frequently reusing the 503 * same ones. 504 */ 505 int mNextIsolatedProcessUid = 0; 506 507 /** 508 * The currently running heavy-weight process, if any. 509 */ 510 ProcessRecord mHeavyWeightProcess = null; 511 512 /** 513 * The last time that various processes have crashed. 514 */ 515 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 516 517 /** 518 * Information about a process that is currently marked as bad. 519 */ 520 static final class BadProcessInfo { 521 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 522 this.time = time; 523 this.shortMsg = shortMsg; 524 this.longMsg = longMsg; 525 this.stack = stack; 526 } 527 528 final long time; 529 final String shortMsg; 530 final String longMsg; 531 final String stack; 532 } 533 534 /** 535 * Set of applications that we consider to be bad, and will reject 536 * incoming broadcasts from (which the user has no control over). 537 * Processes are added to this set when they have crashed twice within 538 * a minimum amount of time; they are removed from it when they are 539 * later restarted (hopefully due to some user action). The value is the 540 * time it was added to the list. 541 */ 542 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 543 544 /** 545 * All of the processes we currently have running organized by pid. 546 * The keys are the pid running the application. 547 * 548 * <p>NOTE: This object is protected by its own lock, NOT the global 549 * activity manager lock! 550 */ 551 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 552 553 /** 554 * All of the processes that have been forced to be foreground. The key 555 * is the pid of the caller who requested it (we hold a death 556 * link on it). 557 */ 558 abstract class ForegroundToken implements IBinder.DeathRecipient { 559 int pid; 560 IBinder token; 561 } 562 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 563 564 /** 565 * List of records for processes that someone had tried to start before the 566 * system was ready. We don't start them at that point, but ensure they 567 * are started by the time booting is complete. 568 */ 569 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 570 571 /** 572 * List of persistent applications that are in the process 573 * of being started. 574 */ 575 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 576 577 /** 578 * Processes that are being forcibly torn down. 579 */ 580 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 581 582 /** 583 * List of running applications, sorted by recent usage. 584 * The first entry in the list is the least recently used. 585 */ 586 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 587 588 /** 589 * Where in mLruProcesses that the processes hosting activities start. 590 */ 591 int mLruProcessActivityStart = 0; 592 593 /** 594 * Where in mLruProcesses that the processes hosting services start. 595 * This is after (lower index) than mLruProcessesActivityStart. 596 */ 597 int mLruProcessServiceStart = 0; 598 599 /** 600 * List of processes that should gc as soon as things are idle. 601 */ 602 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 603 604 /** 605 * Processes we want to collect PSS data from. 606 */ 607 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 608 609 /** 610 * Last time we requested PSS data of all processes. 611 */ 612 long mLastFullPssTime = SystemClock.uptimeMillis(); 613 614 /** 615 * If set, the next time we collect PSS data we should do a full collection 616 * with data from native processes and the kernel. 617 */ 618 boolean mFullPssPending = false; 619 620 /** 621 * This is the process holding what we currently consider to be 622 * the "home" activity. 623 */ 624 ProcessRecord mHomeProcess; 625 626 /** 627 * This is the process holding the activity the user last visited that 628 * is in a different process from the one they are currently in. 629 */ 630 ProcessRecord mPreviousProcess; 631 632 /** 633 * The time at which the previous process was last visible. 634 */ 635 long mPreviousProcessVisibleTime; 636 637 /** 638 * Which uses have been started, so are allowed to run code. 639 */ 640 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 641 642 /** 643 * LRU list of history of current users. Most recently current is at the end. 644 */ 645 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 646 647 /** 648 * Constant array of the users that are currently started. 649 */ 650 int[] mStartedUserArray = new int[] { 0 }; 651 652 /** 653 * Registered observers of the user switching mechanics. 654 */ 655 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 656 = new RemoteCallbackList<IUserSwitchObserver>(); 657 658 /** 659 * Currently active user switch. 660 */ 661 Object mCurUserSwitchCallback; 662 663 /** 664 * Packages that the user has asked to have run in screen size 665 * compatibility mode instead of filling the screen. 666 */ 667 final CompatModePackages mCompatModePackages; 668 669 /** 670 * Set of IntentSenderRecord objects that are currently active. 671 */ 672 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 673 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 674 675 /** 676 * Fingerprints (hashCode()) of stack traces that we've 677 * already logged DropBox entries for. Guarded by itself. If 678 * something (rogue user app) forces this over 679 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 680 */ 681 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 682 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 683 684 /** 685 * Strict Mode background batched logging state. 686 * 687 * The string buffer is guarded by itself, and its lock is also 688 * used to determine if another batched write is already 689 * in-flight. 690 */ 691 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 692 693 /** 694 * Keeps track of all IIntentReceivers that have been registered for 695 * broadcasts. Hash keys are the receiver IBinder, hash value is 696 * a ReceiverList. 697 */ 698 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 699 new HashMap<IBinder, ReceiverList>(); 700 701 /** 702 * Resolver for broadcast intents to registered receivers. 703 * Holds BroadcastFilter (subclass of IntentFilter). 704 */ 705 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 706 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 707 @Override 708 protected boolean allowFilterResult( 709 BroadcastFilter filter, List<BroadcastFilter> dest) { 710 IBinder target = filter.receiverList.receiver.asBinder(); 711 for (int i=dest.size()-1; i>=0; i--) { 712 if (dest.get(i).receiverList.receiver.asBinder() == target) { 713 return false; 714 } 715 } 716 return true; 717 } 718 719 @Override 720 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 721 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 722 || userId == filter.owningUserId) { 723 return super.newResult(filter, match, userId); 724 } 725 return null; 726 } 727 728 @Override 729 protected BroadcastFilter[] newArray(int size) { 730 return new BroadcastFilter[size]; 731 } 732 733 @Override 734 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 735 return packageName.equals(filter.packageName); 736 } 737 }; 738 739 /** 740 * State of all active sticky broadcasts per user. Keys are the action of the 741 * sticky Intent, values are an ArrayList of all broadcasted intents with 742 * that action (which should usually be one). The SparseArray is keyed 743 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 744 * for stickies that are sent to all users. 745 */ 746 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 747 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 748 749 final ActiveServices mServices; 750 751 /** 752 * Backup/restore process management 753 */ 754 String mBackupAppName = null; 755 BackupRecord mBackupTarget = null; 756 757 final ProviderMap mProviderMap; 758 759 /** 760 * List of content providers who have clients waiting for them. The 761 * application is currently being launched and the provider will be 762 * removed from this list once it is published. 763 */ 764 final ArrayList<ContentProviderRecord> mLaunchingProviders 765 = new ArrayList<ContentProviderRecord>(); 766 767 /** 768 * File storing persisted {@link #mGrantedUriPermissions}. 769 */ 770 private final AtomicFile mGrantFile; 771 772 /** XML constants used in {@link #mGrantFile} */ 773 private static final String TAG_URI_GRANTS = "uri-grants"; 774 private static final String TAG_URI_GRANT = "uri-grant"; 775 private static final String ATTR_USER_HANDLE = "userHandle"; 776 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 777 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 778 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 779 private static final String ATTR_TARGET_PKG = "targetPkg"; 780 private static final String ATTR_URI = "uri"; 781 private static final String ATTR_MODE_FLAGS = "modeFlags"; 782 private static final String ATTR_CREATED_TIME = "createdTime"; 783 private static final String ATTR_PREFIX = "prefix"; 784 785 /** 786 * Global set of specific {@link Uri} permissions that have been granted. 787 * This optimized lookup structure maps from {@link UriPermission#targetUid} 788 * to {@link UriPermission#uri} to {@link UriPermission}. 789 */ 790 @GuardedBy("this") 791 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 792 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 793 794 public static class GrantUri { 795 public final int sourceUserId; 796 public final Uri uri; 797 public boolean prefix; 798 799 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 800 this.sourceUserId = sourceUserId; 801 this.uri = uri; 802 this.prefix = prefix; 803 } 804 805 @Override 806 public int hashCode() { 807 int hashCode = 1; 808 hashCode = 31 * hashCode + sourceUserId; 809 hashCode = 31 * hashCode + uri.hashCode(); 810 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 811 return hashCode; 812 } 813 814 @Override 815 public boolean equals(Object o) { 816 if (o instanceof GrantUri) { 817 GrantUri other = (GrantUri) o; 818 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 819 && prefix == other.prefix; 820 } 821 return false; 822 } 823 824 @Override 825 public String toString() { 826 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 827 if (prefix) result += " [prefix]"; 828 return result; 829 } 830 831 public String toSafeString() { 832 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 833 if (prefix) result += " [prefix]"; 834 return result; 835 } 836 837 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 838 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 839 ContentProvider.getUriWithoutUserId(uri), false); 840 } 841 } 842 843 CoreSettingsObserver mCoreSettingsObserver; 844 845 /** 846 * Thread-local storage used to carry caller permissions over through 847 * indirect content-provider access. 848 */ 849 private class Identity { 850 public final IBinder token; 851 public final int pid; 852 public final int uid; 853 854 Identity(IBinder _token, int _pid, int _uid) { 855 token = _token; 856 pid = _pid; 857 uid = _uid; 858 } 859 } 860 861 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 862 863 /** 864 * All information we have collected about the runtime performance of 865 * any user id that can impact battery performance. 866 */ 867 final BatteryStatsService mBatteryStatsService; 868 869 /** 870 * Information about component usage 871 */ 872 UsageStatsManagerInternal mUsageStatsService; 873 874 /** 875 * Information about and control over application operations 876 */ 877 final AppOpsService mAppOpsService; 878 879 /** 880 * Save recent tasks information across reboots. 881 */ 882 final TaskPersister mTaskPersister; 883 884 /** 885 * Current configuration information. HistoryRecord objects are given 886 * a reference to this object to indicate which configuration they are 887 * currently running in, so this object must be kept immutable. 888 */ 889 Configuration mConfiguration = new Configuration(); 890 891 /** 892 * Current sequencing integer of the configuration, for skipping old 893 * configurations. 894 */ 895 int mConfigurationSeq = 0; 896 897 /** 898 * Hardware-reported OpenGLES version. 899 */ 900 final int GL_ES_VERSION; 901 902 /** 903 * List of initialization arguments to pass to all processes when binding applications to them. 904 * For example, references to the commonly used services. 905 */ 906 HashMap<String, IBinder> mAppBindArgs; 907 908 /** 909 * Temporary to avoid allocations. Protected by main lock. 910 */ 911 final StringBuilder mStringBuilder = new StringBuilder(256); 912 913 /** 914 * Used to control how we initialize the service. 915 */ 916 ComponentName mTopComponent; 917 String mTopAction = Intent.ACTION_MAIN; 918 String mTopData; 919 boolean mProcessesReady = false; 920 boolean mSystemReady = false; 921 boolean mBooting = false; 922 boolean mCallFinishBooting = false; 923 boolean mBootAnimationComplete = false; 924 boolean mWaitingUpdate = false; 925 boolean mDidUpdate = false; 926 boolean mOnBattery = false; 927 boolean mLaunchWarningShown = false; 928 929 Context mContext; 930 931 int mFactoryTest; 932 933 boolean mCheckedForSetup; 934 935 /** 936 * The time at which we will allow normal application switches again, 937 * after a call to {@link #stopAppSwitches()}. 938 */ 939 long mAppSwitchesAllowedTime; 940 941 /** 942 * This is set to true after the first switch after mAppSwitchesAllowedTime 943 * is set; any switches after that will clear the time. 944 */ 945 boolean mDidAppSwitch; 946 947 /** 948 * Last time (in realtime) at which we checked for power usage. 949 */ 950 long mLastPowerCheckRealtime; 951 952 /** 953 * Last time (in uptime) at which we checked for power usage. 954 */ 955 long mLastPowerCheckUptime; 956 957 /** 958 * Set while we are wanting to sleep, to prevent any 959 * activities from being started/resumed. 960 */ 961 private boolean mSleeping = false; 962 963 /** 964 * Set while we are running a voice interaction. This overrides 965 * sleeping while it is active. 966 */ 967 private boolean mRunningVoice = false; 968 969 /** 970 * State of external calls telling us if the device is awake or asleep. 971 */ 972 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 973 974 static final int LOCK_SCREEN_HIDDEN = 0; 975 static final int LOCK_SCREEN_LEAVING = 1; 976 static final int LOCK_SCREEN_SHOWN = 2; 977 /** 978 * State of external call telling us if the lock screen is shown. 979 */ 980 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 981 982 /** 983 * Set if we are shutting down the system, similar to sleeping. 984 */ 985 boolean mShuttingDown = false; 986 987 /** 988 * Current sequence id for oom_adj computation traversal. 989 */ 990 int mAdjSeq = 0; 991 992 /** 993 * Current sequence id for process LRU updating. 994 */ 995 int mLruSeq = 0; 996 997 /** 998 * Keep track of the non-cached/empty process we last found, to help 999 * determine how to distribute cached/empty processes next time. 1000 */ 1001 int mNumNonCachedProcs = 0; 1002 1003 /** 1004 * Keep track of the number of cached hidden procs, to balance oom adj 1005 * distribution between those and empty procs. 1006 */ 1007 int mNumCachedHiddenProcs = 0; 1008 1009 /** 1010 * Keep track of the number of service processes we last found, to 1011 * determine on the next iteration which should be B services. 1012 */ 1013 int mNumServiceProcs = 0; 1014 int mNewNumAServiceProcs = 0; 1015 int mNewNumServiceProcs = 0; 1016 1017 /** 1018 * Allow the current computed overall memory level of the system to go down? 1019 * This is set to false when we are killing processes for reasons other than 1020 * memory management, so that the now smaller process list will not be taken as 1021 * an indication that memory is tighter. 1022 */ 1023 boolean mAllowLowerMemLevel = false; 1024 1025 /** 1026 * The last computed memory level, for holding when we are in a state that 1027 * processes are going away for other reasons. 1028 */ 1029 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1030 1031 /** 1032 * The last total number of process we have, to determine if changes actually look 1033 * like a shrinking number of process due to lower RAM. 1034 */ 1035 int mLastNumProcesses; 1036 1037 /** 1038 * The uptime of the last time we performed idle maintenance. 1039 */ 1040 long mLastIdleTime = SystemClock.uptimeMillis(); 1041 1042 /** 1043 * Total time spent with RAM that has been added in the past since the last idle time. 1044 */ 1045 long mLowRamTimeSinceLastIdle = 0; 1046 1047 /** 1048 * If RAM is currently low, when that horrible situation started. 1049 */ 1050 long mLowRamStartTime = 0; 1051 1052 /** 1053 * For reporting to battery stats the current top application. 1054 */ 1055 private String mCurResumedPackage = null; 1056 private int mCurResumedUid = -1; 1057 1058 /** 1059 * For reporting to battery stats the apps currently running foreground 1060 * service. The ProcessMap is package/uid tuples; each of these contain 1061 * an array of the currently foreground processes. 1062 */ 1063 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1064 = new ProcessMap<ArrayList<ProcessRecord>>(); 1065 1066 /** 1067 * This is set if we had to do a delayed dexopt of an app before launching 1068 * it, to increase the ANR timeouts in that case. 1069 */ 1070 boolean mDidDexOpt; 1071 1072 /** 1073 * Set if the systemServer made a call to enterSafeMode. 1074 */ 1075 boolean mSafeMode; 1076 1077 String mDebugApp = null; 1078 boolean mWaitForDebugger = false; 1079 boolean mDebugTransient = false; 1080 String mOrigDebugApp = null; 1081 boolean mOrigWaitForDebugger = false; 1082 boolean mAlwaysFinishActivities = false; 1083 IActivityController mController = null; 1084 String mProfileApp = null; 1085 ProcessRecord mProfileProc = null; 1086 String mProfileFile; 1087 ParcelFileDescriptor mProfileFd; 1088 int mSamplingInterval = 0; 1089 boolean mAutoStopProfiler = false; 1090 int mProfileType = 0; 1091 String mOpenGlTraceApp = null; 1092 1093 static class ProcessChangeItem { 1094 static final int CHANGE_ACTIVITIES = 1<<0; 1095 static final int CHANGE_PROCESS_STATE = 1<<1; 1096 int changes; 1097 int uid; 1098 int pid; 1099 int processState; 1100 boolean foregroundActivities; 1101 } 1102 1103 final RemoteCallbackList<IProcessObserver> mProcessObservers 1104 = new RemoteCallbackList<IProcessObserver>(); 1105 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1106 1107 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1108 = new ArrayList<ProcessChangeItem>(); 1109 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1110 = new ArrayList<ProcessChangeItem>(); 1111 1112 /** 1113 * Runtime CPU use collection thread. This object's lock is used to 1114 * perform synchronization with the thread (notifying it to run). 1115 */ 1116 final Thread mProcessCpuThread; 1117 1118 /** 1119 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1120 * Must acquire this object's lock when accessing it. 1121 * NOTE: this lock will be held while doing long operations (trawling 1122 * through all processes in /proc), so it should never be acquired by 1123 * any critical paths such as when holding the main activity manager lock. 1124 */ 1125 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1126 MONITOR_THREAD_CPU_USAGE); 1127 final AtomicLong mLastCpuTime = new AtomicLong(0); 1128 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1129 1130 long mLastWriteTime = 0; 1131 1132 /** 1133 * Used to retain an update lock when the foreground activity is in 1134 * immersive mode. 1135 */ 1136 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1137 1138 /** 1139 * Set to true after the system has finished booting. 1140 */ 1141 boolean mBooted = false; 1142 1143 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1144 int mProcessLimitOverride = -1; 1145 1146 WindowManagerService mWindowManager; 1147 1148 final ActivityThread mSystemThread; 1149 1150 // Holds the current foreground user's id 1151 int mCurrentUserId = 0; 1152 // Holds the target user's id during a user switch 1153 int mTargetUserId = UserHandle.USER_NULL; 1154 // If there are multiple profiles for the current user, their ids are here 1155 // Currently only the primary user can have managed profiles 1156 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1157 1158 /** 1159 * Mapping from each known user ID to the profile group ID it is associated with. 1160 */ 1161 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1162 1163 private UserManagerService mUserManager; 1164 1165 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1166 final ProcessRecord mApp; 1167 final int mPid; 1168 final IApplicationThread mAppThread; 1169 1170 AppDeathRecipient(ProcessRecord app, int pid, 1171 IApplicationThread thread) { 1172 if (localLOGV) Slog.v( 1173 TAG, "New death recipient " + this 1174 + " for thread " + thread.asBinder()); 1175 mApp = app; 1176 mPid = pid; 1177 mAppThread = thread; 1178 } 1179 1180 @Override 1181 public void binderDied() { 1182 if (localLOGV) Slog.v( 1183 TAG, "Death received in " + this 1184 + " for thread " + mAppThread.asBinder()); 1185 synchronized(ActivityManagerService.this) { 1186 appDiedLocked(mApp, mPid, mAppThread); 1187 } 1188 } 1189 } 1190 1191 static final int SHOW_ERROR_MSG = 1; 1192 static final int SHOW_NOT_RESPONDING_MSG = 2; 1193 static final int SHOW_FACTORY_ERROR_MSG = 3; 1194 static final int UPDATE_CONFIGURATION_MSG = 4; 1195 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1196 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1197 static final int SERVICE_TIMEOUT_MSG = 12; 1198 static final int UPDATE_TIME_ZONE = 13; 1199 static final int SHOW_UID_ERROR_MSG = 14; 1200 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1201 static final int PROC_START_TIMEOUT_MSG = 20; 1202 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1203 static final int KILL_APPLICATION_MSG = 22; 1204 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1205 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1206 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1207 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1208 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1209 static final int CLEAR_DNS_CACHE_MSG = 28; 1210 static final int UPDATE_HTTP_PROXY_MSG = 29; 1211 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1212 static final int DISPATCH_PROCESSES_CHANGED = 31; 1213 static final int DISPATCH_PROCESS_DIED = 32; 1214 static final int REPORT_MEM_USAGE_MSG = 33; 1215 static final int REPORT_USER_SWITCH_MSG = 34; 1216 static final int CONTINUE_USER_SWITCH_MSG = 35; 1217 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1218 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1219 static final int PERSIST_URI_GRANTS_MSG = 38; 1220 static final int REQUEST_ALL_PSS_MSG = 39; 1221 static final int START_PROFILES_MSG = 40; 1222 static final int UPDATE_TIME = 41; 1223 static final int SYSTEM_USER_START_MSG = 42; 1224 static final int SYSTEM_USER_CURRENT_MSG = 43; 1225 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1226 static final int FINISH_BOOTING_MSG = 45; 1227 static final int START_USER_SWITCH_MSG = 46; 1228 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1229 static final int DISMISS_DIALOG_MSG = 48; 1230 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1231 1232 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1233 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1234 static final int FIRST_COMPAT_MODE_MSG = 300; 1235 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1236 1237 CompatModeDialog mCompatModeDialog; 1238 long mLastMemUsageReportTime = 0; 1239 1240 /** 1241 * Flag whether the current user is a "monkey", i.e. whether 1242 * the UI is driven by a UI automation tool. 1243 */ 1244 private boolean mUserIsMonkey; 1245 1246 /** Flag whether the device has a Recents UI */ 1247 boolean mHasRecents; 1248 1249 /** The dimensions of the thumbnails in the Recents UI. */ 1250 int mThumbnailWidth; 1251 int mThumbnailHeight; 1252 1253 final ServiceThread mHandlerThread; 1254 final MainHandler mHandler; 1255 1256 final class MainHandler extends Handler { 1257 public MainHandler(Looper looper) { 1258 super(looper, null, true); 1259 } 1260 1261 @Override 1262 public void handleMessage(Message msg) { 1263 switch (msg.what) { 1264 case SHOW_ERROR_MSG: { 1265 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1266 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1267 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1268 synchronized (ActivityManagerService.this) { 1269 ProcessRecord proc = (ProcessRecord)data.get("app"); 1270 AppErrorResult res = (AppErrorResult) data.get("result"); 1271 if (proc != null && proc.crashDialog != null) { 1272 Slog.e(TAG, "App already has crash dialog: " + proc); 1273 if (res != null) { 1274 res.set(0); 1275 } 1276 return; 1277 } 1278 boolean isBackground = (UserHandle.getAppId(proc.uid) 1279 >= Process.FIRST_APPLICATION_UID 1280 && proc.pid != MY_PID); 1281 for (int userId : mCurrentProfileIds) { 1282 isBackground &= (proc.userId != userId); 1283 } 1284 if (isBackground && !showBackground) { 1285 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1286 if (res != null) { 1287 res.set(0); 1288 } 1289 return; 1290 } 1291 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1292 Dialog d = new AppErrorDialog(mContext, 1293 ActivityManagerService.this, res, proc); 1294 d.show(); 1295 proc.crashDialog = d; 1296 } else { 1297 // The device is asleep, so just pretend that the user 1298 // saw a crash dialog and hit "force quit". 1299 if (res != null) { 1300 res.set(0); 1301 } 1302 } 1303 } 1304 1305 ensureBootCompleted(); 1306 } break; 1307 case SHOW_NOT_RESPONDING_MSG: { 1308 synchronized (ActivityManagerService.this) { 1309 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1310 ProcessRecord proc = (ProcessRecord)data.get("app"); 1311 if (proc != null && proc.anrDialog != null) { 1312 Slog.e(TAG, "App already has anr dialog: " + proc); 1313 return; 1314 } 1315 1316 Intent intent = new Intent("android.intent.action.ANR"); 1317 if (!mProcessesReady) { 1318 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1319 | Intent.FLAG_RECEIVER_FOREGROUND); 1320 } 1321 broadcastIntentLocked(null, null, intent, 1322 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1323 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1324 1325 if (mShowDialogs) { 1326 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1327 mContext, proc, (ActivityRecord)data.get("activity"), 1328 msg.arg1 != 0); 1329 d.show(); 1330 proc.anrDialog = d; 1331 } else { 1332 // Just kill the app if there is no dialog to be shown. 1333 killAppAtUsersRequest(proc, null); 1334 } 1335 } 1336 1337 ensureBootCompleted(); 1338 } break; 1339 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1340 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1341 synchronized (ActivityManagerService.this) { 1342 ProcessRecord proc = (ProcessRecord) data.get("app"); 1343 if (proc == null) { 1344 Slog.e(TAG, "App not found when showing strict mode dialog."); 1345 break; 1346 } 1347 if (proc.crashDialog != null) { 1348 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1349 return; 1350 } 1351 AppErrorResult res = (AppErrorResult) data.get("result"); 1352 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1353 Dialog d = new StrictModeViolationDialog(mContext, 1354 ActivityManagerService.this, res, proc); 1355 d.show(); 1356 proc.crashDialog = d; 1357 } else { 1358 // The device is asleep, so just pretend that the user 1359 // saw a crash dialog and hit "force quit". 1360 res.set(0); 1361 } 1362 } 1363 ensureBootCompleted(); 1364 } break; 1365 case SHOW_FACTORY_ERROR_MSG: { 1366 Dialog d = new FactoryErrorDialog( 1367 mContext, msg.getData().getCharSequence("msg")); 1368 d.show(); 1369 ensureBootCompleted(); 1370 } break; 1371 case UPDATE_CONFIGURATION_MSG: { 1372 final ContentResolver resolver = mContext.getContentResolver(); 1373 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1374 } break; 1375 case GC_BACKGROUND_PROCESSES_MSG: { 1376 synchronized (ActivityManagerService.this) { 1377 performAppGcsIfAppropriateLocked(); 1378 } 1379 } break; 1380 case WAIT_FOR_DEBUGGER_MSG: { 1381 synchronized (ActivityManagerService.this) { 1382 ProcessRecord app = (ProcessRecord)msg.obj; 1383 if (msg.arg1 != 0) { 1384 if (!app.waitedForDebugger) { 1385 Dialog d = new AppWaitingForDebuggerDialog( 1386 ActivityManagerService.this, 1387 mContext, app); 1388 app.waitDialog = d; 1389 app.waitedForDebugger = true; 1390 d.show(); 1391 } 1392 } else { 1393 if (app.waitDialog != null) { 1394 app.waitDialog.dismiss(); 1395 app.waitDialog = null; 1396 } 1397 } 1398 } 1399 } break; 1400 case SERVICE_TIMEOUT_MSG: { 1401 if (mDidDexOpt) { 1402 mDidDexOpt = false; 1403 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1404 nmsg.obj = msg.obj; 1405 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1406 return; 1407 } 1408 mServices.serviceTimeout((ProcessRecord)msg.obj); 1409 } break; 1410 case UPDATE_TIME_ZONE: { 1411 synchronized (ActivityManagerService.this) { 1412 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1413 ProcessRecord r = mLruProcesses.get(i); 1414 if (r.thread != null) { 1415 try { 1416 r.thread.updateTimeZone(); 1417 } catch (RemoteException ex) { 1418 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1419 } 1420 } 1421 } 1422 } 1423 } break; 1424 case CLEAR_DNS_CACHE_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1427 ProcessRecord r = mLruProcesses.get(i); 1428 if (r.thread != null) { 1429 try { 1430 r.thread.clearDnsCache(); 1431 } catch (RemoteException ex) { 1432 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1433 } 1434 } 1435 } 1436 } 1437 } break; 1438 case UPDATE_HTTP_PROXY_MSG: { 1439 ProxyInfo proxy = (ProxyInfo)msg.obj; 1440 String host = ""; 1441 String port = ""; 1442 String exclList = ""; 1443 Uri pacFileUrl = Uri.EMPTY; 1444 if (proxy != null) { 1445 host = proxy.getHost(); 1446 port = Integer.toString(proxy.getPort()); 1447 exclList = proxy.getExclusionListAsString(); 1448 pacFileUrl = proxy.getPacFileUrl(); 1449 } 1450 synchronized (ActivityManagerService.this) { 1451 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1452 ProcessRecord r = mLruProcesses.get(i); 1453 if (r.thread != null) { 1454 try { 1455 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1456 } catch (RemoteException ex) { 1457 Slog.w(TAG, "Failed to update http proxy for: " + 1458 r.info.processName); 1459 } 1460 } 1461 } 1462 } 1463 } break; 1464 case SHOW_UID_ERROR_MSG: { 1465 if (mShowDialogs) { 1466 AlertDialog d = new BaseErrorDialog(mContext); 1467 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1468 d.setCancelable(false); 1469 d.setTitle(mContext.getText(R.string.android_system_label)); 1470 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1471 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1472 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1473 d.show(); 1474 } 1475 } break; 1476 case SHOW_FINGERPRINT_ERROR_MSG: { 1477 if (mShowDialogs) { 1478 AlertDialog d = new BaseErrorDialog(mContext); 1479 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1480 d.setCancelable(false); 1481 d.setTitle(mContext.getText(R.string.android_system_label)); 1482 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1483 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1484 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1485 d.show(); 1486 } 1487 } break; 1488 case PROC_START_TIMEOUT_MSG: { 1489 if (mDidDexOpt) { 1490 mDidDexOpt = false; 1491 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1492 nmsg.obj = msg.obj; 1493 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1494 return; 1495 } 1496 ProcessRecord app = (ProcessRecord)msg.obj; 1497 synchronized (ActivityManagerService.this) { 1498 processStartTimedOutLocked(app); 1499 } 1500 } break; 1501 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1502 synchronized (ActivityManagerService.this) { 1503 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1504 } 1505 } break; 1506 case KILL_APPLICATION_MSG: { 1507 synchronized (ActivityManagerService.this) { 1508 int appid = msg.arg1; 1509 boolean restart = (msg.arg2 == 1); 1510 Bundle bundle = (Bundle)msg.obj; 1511 String pkg = bundle.getString("pkg"); 1512 String reason = bundle.getString("reason"); 1513 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1514 false, UserHandle.USER_ALL, reason); 1515 } 1516 } break; 1517 case FINALIZE_PENDING_INTENT_MSG: { 1518 ((PendingIntentRecord)msg.obj).completeFinalize(); 1519 } break; 1520 case POST_HEAVY_NOTIFICATION_MSG: { 1521 INotificationManager inm = NotificationManager.getService(); 1522 if (inm == null) { 1523 return; 1524 } 1525 1526 ActivityRecord root = (ActivityRecord)msg.obj; 1527 ProcessRecord process = root.app; 1528 if (process == null) { 1529 return; 1530 } 1531 1532 try { 1533 Context context = mContext.createPackageContext(process.info.packageName, 0); 1534 String text = mContext.getString(R.string.heavy_weight_notification, 1535 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1536 Notification notification = new Notification(); 1537 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1538 notification.when = 0; 1539 notification.flags = Notification.FLAG_ONGOING_EVENT; 1540 notification.tickerText = text; 1541 notification.defaults = 0; // please be quiet 1542 notification.sound = null; 1543 notification.vibrate = null; 1544 notification.color = mContext.getResources().getColor( 1545 com.android.internal.R.color.system_notification_accent_color); 1546 notification.setLatestEventInfo(context, text, 1547 mContext.getText(R.string.heavy_weight_notification_detail), 1548 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1549 PendingIntent.FLAG_CANCEL_CURRENT, null, 1550 new UserHandle(root.userId))); 1551 1552 try { 1553 int[] outId = new int[1]; 1554 inm.enqueueNotificationWithTag("android", "android", null, 1555 R.string.heavy_weight_notification, 1556 notification, outId, root.userId); 1557 } catch (RuntimeException e) { 1558 Slog.w(ActivityManagerService.TAG, 1559 "Error showing notification for heavy-weight app", e); 1560 } catch (RemoteException e) { 1561 } 1562 } catch (NameNotFoundException e) { 1563 Slog.w(TAG, "Unable to create context for heavy notification", e); 1564 } 1565 } break; 1566 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1567 INotificationManager inm = NotificationManager.getService(); 1568 if (inm == null) { 1569 return; 1570 } 1571 try { 1572 inm.cancelNotificationWithTag("android", null, 1573 R.string.heavy_weight_notification, msg.arg1); 1574 } catch (RuntimeException e) { 1575 Slog.w(ActivityManagerService.TAG, 1576 "Error canceling notification for service", e); 1577 } catch (RemoteException e) { 1578 } 1579 } break; 1580 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1581 synchronized (ActivityManagerService.this) { 1582 checkExcessivePowerUsageLocked(true); 1583 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1584 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1585 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1586 } 1587 } break; 1588 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1589 synchronized (ActivityManagerService.this) { 1590 ActivityRecord ar = (ActivityRecord)msg.obj; 1591 if (mCompatModeDialog != null) { 1592 if (mCompatModeDialog.mAppInfo.packageName.equals( 1593 ar.info.applicationInfo.packageName)) { 1594 return; 1595 } 1596 mCompatModeDialog.dismiss(); 1597 mCompatModeDialog = null; 1598 } 1599 if (ar != null && false) { 1600 if (mCompatModePackages.getPackageAskCompatModeLocked( 1601 ar.packageName)) { 1602 int mode = mCompatModePackages.computeCompatModeLocked( 1603 ar.info.applicationInfo); 1604 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1605 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1606 mCompatModeDialog = new CompatModeDialog( 1607 ActivityManagerService.this, mContext, 1608 ar.info.applicationInfo); 1609 mCompatModeDialog.show(); 1610 } 1611 } 1612 } 1613 } 1614 break; 1615 } 1616 case DISPATCH_PROCESSES_CHANGED: { 1617 dispatchProcessesChanged(); 1618 break; 1619 } 1620 case DISPATCH_PROCESS_DIED: { 1621 final int pid = msg.arg1; 1622 final int uid = msg.arg2; 1623 dispatchProcessDied(pid, uid); 1624 break; 1625 } 1626 case REPORT_MEM_USAGE_MSG: { 1627 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1628 Thread thread = new Thread() { 1629 @Override public void run() { 1630 reportMemUsage(memInfos); 1631 } 1632 }; 1633 thread.start(); 1634 break; 1635 } 1636 case START_USER_SWITCH_MSG: { 1637 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1638 break; 1639 } 1640 case REPORT_USER_SWITCH_MSG: { 1641 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1642 break; 1643 } 1644 case CONTINUE_USER_SWITCH_MSG: { 1645 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1646 break; 1647 } 1648 case USER_SWITCH_TIMEOUT_MSG: { 1649 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1650 break; 1651 } 1652 case IMMERSIVE_MODE_LOCK_MSG: { 1653 final boolean nextState = (msg.arg1 != 0); 1654 if (mUpdateLock.isHeld() != nextState) { 1655 if (DEBUG_IMMERSIVE) { 1656 final ActivityRecord r = (ActivityRecord) msg.obj; 1657 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1658 } 1659 if (nextState) { 1660 mUpdateLock.acquire(); 1661 } else { 1662 mUpdateLock.release(); 1663 } 1664 } 1665 break; 1666 } 1667 case PERSIST_URI_GRANTS_MSG: { 1668 writeGrantedUriPermissions(); 1669 break; 1670 } 1671 case REQUEST_ALL_PSS_MSG: { 1672 synchronized (ActivityManagerService.this) { 1673 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1674 } 1675 break; 1676 } 1677 case START_PROFILES_MSG: { 1678 synchronized (ActivityManagerService.this) { 1679 startProfilesLocked(); 1680 } 1681 break; 1682 } 1683 case UPDATE_TIME: { 1684 synchronized (ActivityManagerService.this) { 1685 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1686 ProcessRecord r = mLruProcesses.get(i); 1687 if (r.thread != null) { 1688 try { 1689 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1690 } catch (RemoteException ex) { 1691 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1692 } 1693 } 1694 } 1695 } 1696 break; 1697 } 1698 case SYSTEM_USER_START_MSG: { 1699 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1700 Integer.toString(msg.arg1), msg.arg1); 1701 mSystemServiceManager.startUser(msg.arg1); 1702 break; 1703 } 1704 case SYSTEM_USER_CURRENT_MSG: { 1705 mBatteryStatsService.noteEvent( 1706 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1707 Integer.toString(msg.arg2), msg.arg2); 1708 mBatteryStatsService.noteEvent( 1709 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1710 Integer.toString(msg.arg1), msg.arg1); 1711 mSystemServiceManager.switchUser(msg.arg1); 1712 break; 1713 } 1714 case ENTER_ANIMATION_COMPLETE_MSG: { 1715 synchronized (ActivityManagerService.this) { 1716 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1717 if (r != null && r.app != null && r.app.thread != null) { 1718 try { 1719 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1720 } catch (RemoteException e) { 1721 } 1722 } 1723 } 1724 break; 1725 } 1726 case FINISH_BOOTING_MSG: { 1727 if (msg.arg1 != 0) { 1728 finishBooting(); 1729 } 1730 if (msg.arg2 != 0) { 1731 enableScreenAfterBoot(); 1732 } 1733 break; 1734 } 1735 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1736 try { 1737 Locale l = (Locale) msg.obj; 1738 IBinder service = ServiceManager.getService("mount"); 1739 IMountService mountService = IMountService.Stub.asInterface(service); 1740 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1741 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1742 } catch (RemoteException e) { 1743 Log.e(TAG, "Error storing locale for decryption UI", e); 1744 } 1745 break; 1746 } 1747 case DISMISS_DIALOG_MSG: { 1748 final Dialog d = (Dialog) msg.obj; 1749 d.dismiss(); 1750 break; 1751 } 1752 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1753 synchronized (ActivityManagerService.this) { 1754 int i = mTaskStackListeners.beginBroadcast(); 1755 while (i > 0) { 1756 i--; 1757 try { 1758 // Make a one-way callback to the listener 1759 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1760 } catch (RemoteException e){ 1761 // Handled by the RemoteCallbackList 1762 } 1763 } 1764 mTaskStackListeners.finishBroadcast(); 1765 } 1766 break; 1767 } 1768 } 1769 } 1770 }; 1771 1772 static final int COLLECT_PSS_BG_MSG = 1; 1773 1774 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1775 @Override 1776 public void handleMessage(Message msg) { 1777 switch (msg.what) { 1778 case COLLECT_PSS_BG_MSG: { 1779 long start = SystemClock.uptimeMillis(); 1780 MemInfoReader memInfo = null; 1781 synchronized (ActivityManagerService.this) { 1782 if (mFullPssPending) { 1783 mFullPssPending = false; 1784 memInfo = new MemInfoReader(); 1785 } 1786 } 1787 if (memInfo != null) { 1788 updateCpuStatsNow(); 1789 long nativeTotalPss = 0; 1790 synchronized (mProcessCpuTracker) { 1791 final int N = mProcessCpuTracker.countStats(); 1792 for (int j=0; j<N; j++) { 1793 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1794 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1795 // This is definitely an application process; skip it. 1796 continue; 1797 } 1798 synchronized (mPidsSelfLocked) { 1799 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1800 // This is one of our own processes; skip it. 1801 continue; 1802 } 1803 } 1804 nativeTotalPss += Debug.getPss(st.pid, null); 1805 } 1806 } 1807 memInfo.readMemInfo(); 1808 synchronized (ActivityManagerService.this) { 1809 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1810 + (SystemClock.uptimeMillis()-start) + "ms"); 1811 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1812 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1813 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1814 } 1815 } 1816 1817 int i = 0; 1818 int num = 0; 1819 long[] tmp = new long[1]; 1820 do { 1821 ProcessRecord proc; 1822 int procState; 1823 int pid; 1824 synchronized (ActivityManagerService.this) { 1825 if (i >= mPendingPssProcesses.size()) { 1826 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1827 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1828 mPendingPssProcesses.clear(); 1829 return; 1830 } 1831 proc = mPendingPssProcesses.get(i); 1832 procState = proc.pssProcState; 1833 if (proc.thread != null && procState == proc.setProcState) { 1834 pid = proc.pid; 1835 } else { 1836 proc = null; 1837 pid = 0; 1838 } 1839 i++; 1840 } 1841 if (proc != null) { 1842 long pss = Debug.getPss(pid, tmp); 1843 synchronized (ActivityManagerService.this) { 1844 if (proc.thread != null && proc.setProcState == procState 1845 && proc.pid == pid) { 1846 num++; 1847 proc.lastPssTime = SystemClock.uptimeMillis(); 1848 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1849 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1850 + ": " + pss + " lastPss=" + proc.lastPss 1851 + " state=" + ProcessList.makeProcStateString(procState)); 1852 if (proc.initialIdlePss == 0) { 1853 proc.initialIdlePss = pss; 1854 } 1855 proc.lastPss = pss; 1856 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1857 proc.lastCachedPss = pss; 1858 } 1859 } 1860 } 1861 } 1862 } while (true); 1863 } 1864 } 1865 } 1866 }; 1867 1868 public void setSystemProcess() { 1869 try { 1870 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1871 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1872 ServiceManager.addService("meminfo", new MemBinder(this)); 1873 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1874 ServiceManager.addService("dbinfo", new DbBinder(this)); 1875 if (MONITOR_CPU_USAGE) { 1876 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1877 } 1878 ServiceManager.addService("permission", new PermissionController(this)); 1879 1880 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1881 "android", STOCK_PM_FLAGS); 1882 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1883 1884 synchronized (this) { 1885 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1886 app.persistent = true; 1887 app.pid = MY_PID; 1888 app.maxAdj = ProcessList.SYSTEM_ADJ; 1889 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1890 mProcessNames.put(app.processName, app.uid, app); 1891 synchronized (mPidsSelfLocked) { 1892 mPidsSelfLocked.put(app.pid, app); 1893 } 1894 updateLruProcessLocked(app, false, null); 1895 updateOomAdjLocked(); 1896 } 1897 } catch (PackageManager.NameNotFoundException e) { 1898 throw new RuntimeException( 1899 "Unable to find android system package", e); 1900 } 1901 } 1902 1903 public void setWindowManager(WindowManagerService wm) { 1904 mWindowManager = wm; 1905 mStackSupervisor.setWindowManager(wm); 1906 } 1907 1908 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1909 mUsageStatsService = usageStatsManager; 1910 } 1911 1912 public void startObservingNativeCrashes() { 1913 final NativeCrashListener ncl = new NativeCrashListener(this); 1914 ncl.start(); 1915 } 1916 1917 public IAppOpsService getAppOpsService() { 1918 return mAppOpsService; 1919 } 1920 1921 static class MemBinder extends Binder { 1922 ActivityManagerService mActivityManagerService; 1923 MemBinder(ActivityManagerService activityManagerService) { 1924 mActivityManagerService = activityManagerService; 1925 } 1926 1927 @Override 1928 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1929 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1930 != PackageManager.PERMISSION_GRANTED) { 1931 pw.println("Permission Denial: can't dump meminfo from from pid=" 1932 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1933 + " without permission " + android.Manifest.permission.DUMP); 1934 return; 1935 } 1936 1937 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1938 } 1939 } 1940 1941 static class GraphicsBinder extends Binder { 1942 ActivityManagerService mActivityManagerService; 1943 GraphicsBinder(ActivityManagerService activityManagerService) { 1944 mActivityManagerService = activityManagerService; 1945 } 1946 1947 @Override 1948 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1949 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1950 != PackageManager.PERMISSION_GRANTED) { 1951 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1952 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1953 + " without permission " + android.Manifest.permission.DUMP); 1954 return; 1955 } 1956 1957 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1958 } 1959 } 1960 1961 static class DbBinder extends Binder { 1962 ActivityManagerService mActivityManagerService; 1963 DbBinder(ActivityManagerService activityManagerService) { 1964 mActivityManagerService = activityManagerService; 1965 } 1966 1967 @Override 1968 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1969 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1970 != PackageManager.PERMISSION_GRANTED) { 1971 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1972 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1973 + " without permission " + android.Manifest.permission.DUMP); 1974 return; 1975 } 1976 1977 mActivityManagerService.dumpDbInfo(fd, pw, args); 1978 } 1979 } 1980 1981 static class CpuBinder extends Binder { 1982 ActivityManagerService mActivityManagerService; 1983 CpuBinder(ActivityManagerService activityManagerService) { 1984 mActivityManagerService = activityManagerService; 1985 } 1986 1987 @Override 1988 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1989 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1990 != PackageManager.PERMISSION_GRANTED) { 1991 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1992 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1993 + " without permission " + android.Manifest.permission.DUMP); 1994 return; 1995 } 1996 1997 synchronized (mActivityManagerService.mProcessCpuTracker) { 1998 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1999 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2000 SystemClock.uptimeMillis())); 2001 } 2002 } 2003 } 2004 2005 public static final class Lifecycle extends SystemService { 2006 private final ActivityManagerService mService; 2007 2008 public Lifecycle(Context context) { 2009 super(context); 2010 mService = new ActivityManagerService(context); 2011 } 2012 2013 @Override 2014 public void onStart() { 2015 mService.start(); 2016 } 2017 2018 public ActivityManagerService getService() { 2019 return mService; 2020 } 2021 } 2022 2023 // Note: This method is invoked on the main thread but may need to attach various 2024 // handlers to other threads. So take care to be explicit about the looper. 2025 public ActivityManagerService(Context systemContext) { 2026 mContext = systemContext; 2027 mFactoryTest = FactoryTest.getMode(); 2028 mSystemThread = ActivityThread.currentActivityThread(); 2029 2030 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2031 2032 mHandlerThread = new ServiceThread(TAG, 2033 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2034 mHandlerThread.start(); 2035 mHandler = new MainHandler(mHandlerThread.getLooper()); 2036 2037 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2038 "foreground", BROADCAST_FG_TIMEOUT, false); 2039 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2040 "background", BROADCAST_BG_TIMEOUT, true); 2041 mBroadcastQueues[0] = mFgBroadcastQueue; 2042 mBroadcastQueues[1] = mBgBroadcastQueue; 2043 2044 mServices = new ActiveServices(this); 2045 mProviderMap = new ProviderMap(this); 2046 2047 // TODO: Move creation of battery stats service outside of activity manager service. 2048 File dataDir = Environment.getDataDirectory(); 2049 File systemDir = new File(dataDir, "system"); 2050 systemDir.mkdirs(); 2051 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2052 mBatteryStatsService.getActiveStatistics().readLocked(); 2053 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2054 mOnBattery = DEBUG_POWER ? true 2055 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2056 mBatteryStatsService.getActiveStatistics().setCallback(this); 2057 2058 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2059 2060 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2061 2062 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2063 2064 // User 0 is the first and only user that runs at boot. 2065 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2066 mUserLru.add(Integer.valueOf(0)); 2067 updateStartedUserArrayLocked(); 2068 2069 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2070 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2071 2072 mConfiguration.setToDefaults(); 2073 mConfiguration.setLocale(Locale.getDefault()); 2074 2075 mConfigurationSeq = mConfiguration.seq = 1; 2076 mProcessCpuTracker.init(); 2077 2078 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2079 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2080 mStackSupervisor = new ActivityStackSupervisor(this); 2081 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2082 2083 mProcessCpuThread = new Thread("CpuTracker") { 2084 @Override 2085 public void run() { 2086 while (true) { 2087 try { 2088 try { 2089 synchronized(this) { 2090 final long now = SystemClock.uptimeMillis(); 2091 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2092 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2093 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2094 // + ", write delay=" + nextWriteDelay); 2095 if (nextWriteDelay < nextCpuDelay) { 2096 nextCpuDelay = nextWriteDelay; 2097 } 2098 if (nextCpuDelay > 0) { 2099 mProcessCpuMutexFree.set(true); 2100 this.wait(nextCpuDelay); 2101 } 2102 } 2103 } catch (InterruptedException e) { 2104 } 2105 updateCpuStatsNow(); 2106 } catch (Exception e) { 2107 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2108 } 2109 } 2110 } 2111 }; 2112 2113 Watchdog.getInstance().addMonitor(this); 2114 Watchdog.getInstance().addThread(mHandler); 2115 } 2116 2117 public void setSystemServiceManager(SystemServiceManager mgr) { 2118 mSystemServiceManager = mgr; 2119 } 2120 2121 public void setInstaller(Installer installer) { 2122 mInstaller = installer; 2123 } 2124 2125 private void start() { 2126 Process.removeAllProcessGroups(); 2127 mProcessCpuThread.start(); 2128 2129 mBatteryStatsService.publish(mContext); 2130 mAppOpsService.publish(mContext); 2131 Slog.d("AppOps", "AppOpsService published"); 2132 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2133 } 2134 2135 public void initPowerManagement() { 2136 mStackSupervisor.initPowerManagement(); 2137 mBatteryStatsService.initPowerManagement(); 2138 } 2139 2140 @Override 2141 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2142 throws RemoteException { 2143 if (code == SYSPROPS_TRANSACTION) { 2144 // We need to tell all apps about the system property change. 2145 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2146 synchronized(this) { 2147 final int NP = mProcessNames.getMap().size(); 2148 for (int ip=0; ip<NP; ip++) { 2149 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2150 final int NA = apps.size(); 2151 for (int ia=0; ia<NA; ia++) { 2152 ProcessRecord app = apps.valueAt(ia); 2153 if (app.thread != null) { 2154 procs.add(app.thread.asBinder()); 2155 } 2156 } 2157 } 2158 } 2159 2160 int N = procs.size(); 2161 for (int i=0; i<N; i++) { 2162 Parcel data2 = Parcel.obtain(); 2163 try { 2164 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2165 } catch (RemoteException e) { 2166 } 2167 data2.recycle(); 2168 } 2169 } 2170 try { 2171 return super.onTransact(code, data, reply, flags); 2172 } catch (RuntimeException e) { 2173 // The activity manager only throws security exceptions, so let's 2174 // log all others. 2175 if (!(e instanceof SecurityException)) { 2176 Slog.wtf(TAG, "Activity Manager Crash", e); 2177 } 2178 throw e; 2179 } 2180 } 2181 2182 void updateCpuStats() { 2183 final long now = SystemClock.uptimeMillis(); 2184 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2185 return; 2186 } 2187 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2188 synchronized (mProcessCpuThread) { 2189 mProcessCpuThread.notify(); 2190 } 2191 } 2192 } 2193 2194 void updateCpuStatsNow() { 2195 synchronized (mProcessCpuTracker) { 2196 mProcessCpuMutexFree.set(false); 2197 final long now = SystemClock.uptimeMillis(); 2198 boolean haveNewCpuStats = false; 2199 2200 if (MONITOR_CPU_USAGE && 2201 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2202 mLastCpuTime.set(now); 2203 haveNewCpuStats = true; 2204 mProcessCpuTracker.update(); 2205 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2206 //Slog.i(TAG, "Total CPU usage: " 2207 // + mProcessCpu.getTotalCpuPercent() + "%"); 2208 2209 // Slog the cpu usage if the property is set. 2210 if ("true".equals(SystemProperties.get("events.cpu"))) { 2211 int user = mProcessCpuTracker.getLastUserTime(); 2212 int system = mProcessCpuTracker.getLastSystemTime(); 2213 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2214 int irq = mProcessCpuTracker.getLastIrqTime(); 2215 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2216 int idle = mProcessCpuTracker.getLastIdleTime(); 2217 2218 int total = user + system + iowait + irq + softIrq + idle; 2219 if (total == 0) total = 1; 2220 2221 EventLog.writeEvent(EventLogTags.CPU, 2222 ((user+system+iowait+irq+softIrq) * 100) / total, 2223 (user * 100) / total, 2224 (system * 100) / total, 2225 (iowait * 100) / total, 2226 (irq * 100) / total, 2227 (softIrq * 100) / total); 2228 } 2229 } 2230 2231 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2232 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2233 synchronized(bstats) { 2234 synchronized(mPidsSelfLocked) { 2235 if (haveNewCpuStats) { 2236 if (mOnBattery) { 2237 int perc = bstats.startAddingCpuLocked(); 2238 int totalUTime = 0; 2239 int totalSTime = 0; 2240 final int N = mProcessCpuTracker.countStats(); 2241 for (int i=0; i<N; i++) { 2242 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2243 if (!st.working) { 2244 continue; 2245 } 2246 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2247 int otherUTime = (st.rel_utime*perc)/100; 2248 int otherSTime = (st.rel_stime*perc)/100; 2249 totalUTime += otherUTime; 2250 totalSTime += otherSTime; 2251 if (pr != null) { 2252 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2253 if (ps == null || !ps.isActive()) { 2254 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2255 pr.info.uid, pr.processName); 2256 } 2257 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2258 st.rel_stime-otherSTime); 2259 ps.addSpeedStepTimes(cpuSpeedTimes); 2260 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2261 } else { 2262 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2263 if (ps == null || !ps.isActive()) { 2264 st.batteryStats = ps = bstats.getProcessStatsLocked( 2265 bstats.mapUid(st.uid), st.name); 2266 } 2267 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2268 st.rel_stime-otherSTime); 2269 ps.addSpeedStepTimes(cpuSpeedTimes); 2270 } 2271 } 2272 bstats.finishAddingCpuLocked(perc, totalUTime, 2273 totalSTime, cpuSpeedTimes); 2274 } 2275 } 2276 } 2277 2278 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2279 mLastWriteTime = now; 2280 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2281 } 2282 } 2283 } 2284 } 2285 2286 @Override 2287 public void batteryNeedsCpuUpdate() { 2288 updateCpuStatsNow(); 2289 } 2290 2291 @Override 2292 public void batteryPowerChanged(boolean onBattery) { 2293 // When plugging in, update the CPU stats first before changing 2294 // the plug state. 2295 updateCpuStatsNow(); 2296 synchronized (this) { 2297 synchronized(mPidsSelfLocked) { 2298 mOnBattery = DEBUG_POWER ? true : onBattery; 2299 } 2300 } 2301 } 2302 2303 /** 2304 * Initialize the application bind args. These are passed to each 2305 * process when the bindApplication() IPC is sent to the process. They're 2306 * lazily setup to make sure the services are running when they're asked for. 2307 */ 2308 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2309 if (mAppBindArgs == null) { 2310 mAppBindArgs = new HashMap<>(); 2311 2312 // Isolated processes won't get this optimization, so that we don't 2313 // violate the rules about which services they have access to. 2314 if (!isolated) { 2315 // Setup the application init args 2316 mAppBindArgs.put("package", ServiceManager.getService("package")); 2317 mAppBindArgs.put("window", ServiceManager.getService("window")); 2318 mAppBindArgs.put(Context.ALARM_SERVICE, 2319 ServiceManager.getService(Context.ALARM_SERVICE)); 2320 } 2321 } 2322 return mAppBindArgs; 2323 } 2324 2325 final void setFocusedActivityLocked(ActivityRecord r) { 2326 if (mFocusedActivity != r) { 2327 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2328 mFocusedActivity = r; 2329 if (r.task != null && r.task.voiceInteractor != null) { 2330 startRunningVoiceLocked(); 2331 } else { 2332 finishRunningVoiceLocked(); 2333 } 2334 mStackSupervisor.setFocusedStack(r); 2335 if (r != null) { 2336 mWindowManager.setFocusedApp(r.appToken, true); 2337 } 2338 applyUpdateLockStateLocked(r); 2339 } 2340 } 2341 2342 final void clearFocusedActivity(ActivityRecord r) { 2343 if (mFocusedActivity == r) { 2344 mFocusedActivity = null; 2345 } 2346 } 2347 2348 @Override 2349 public void setFocusedStack(int stackId) { 2350 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2351 synchronized (ActivityManagerService.this) { 2352 ActivityStack stack = mStackSupervisor.getStack(stackId); 2353 if (stack != null) { 2354 ActivityRecord r = stack.topRunningActivityLocked(null); 2355 if (r != null) { 2356 setFocusedActivityLocked(r); 2357 } 2358 } 2359 } 2360 } 2361 2362 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2363 @Override 2364 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2365 synchronized (ActivityManagerService.this) { 2366 if (listener != null) { 2367 mTaskStackListeners.register(listener); 2368 } 2369 } 2370 } 2371 2372 @Override 2373 public void notifyActivityDrawn(IBinder token) { 2374 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2375 synchronized (this) { 2376 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2377 if (r != null) { 2378 r.task.stack.notifyActivityDrawnLocked(r); 2379 } 2380 } 2381 } 2382 2383 final void applyUpdateLockStateLocked(ActivityRecord r) { 2384 // Modifications to the UpdateLock state are done on our handler, outside 2385 // the activity manager's locks. The new state is determined based on the 2386 // state *now* of the relevant activity record. The object is passed to 2387 // the handler solely for logging detail, not to be consulted/modified. 2388 final boolean nextState = r != null && r.immersive; 2389 mHandler.sendMessage( 2390 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2391 } 2392 2393 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2394 Message msg = Message.obtain(); 2395 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2396 msg.obj = r.task.askedCompatMode ? null : r; 2397 mHandler.sendMessage(msg); 2398 } 2399 2400 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2401 String what, Object obj, ProcessRecord srcApp) { 2402 app.lastActivityTime = now; 2403 2404 if (app.activities.size() > 0) { 2405 // Don't want to touch dependent processes that are hosting activities. 2406 return index; 2407 } 2408 2409 int lrui = mLruProcesses.lastIndexOf(app); 2410 if (lrui < 0) { 2411 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2412 + what + " " + obj + " from " + srcApp); 2413 return index; 2414 } 2415 2416 if (lrui >= index) { 2417 // Don't want to cause this to move dependent processes *back* in the 2418 // list as if they were less frequently used. 2419 return index; 2420 } 2421 2422 if (lrui >= mLruProcessActivityStart) { 2423 // Don't want to touch dependent processes that are hosting activities. 2424 return index; 2425 } 2426 2427 mLruProcesses.remove(lrui); 2428 if (index > 0) { 2429 index--; 2430 } 2431 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2432 + " in LRU list: " + app); 2433 mLruProcesses.add(index, app); 2434 return index; 2435 } 2436 2437 final void removeLruProcessLocked(ProcessRecord app) { 2438 int lrui = mLruProcesses.lastIndexOf(app); 2439 if (lrui >= 0) { 2440 if (!app.killed) { 2441 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2442 Process.killProcessQuiet(app.pid); 2443 Process.killProcessGroup(app.info.uid, app.pid); 2444 } 2445 if (lrui <= mLruProcessActivityStart) { 2446 mLruProcessActivityStart--; 2447 } 2448 if (lrui <= mLruProcessServiceStart) { 2449 mLruProcessServiceStart--; 2450 } 2451 mLruProcesses.remove(lrui); 2452 } 2453 } 2454 2455 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2456 ProcessRecord client) { 2457 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2458 || app.treatLikeActivity; 2459 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2460 if (!activityChange && hasActivity) { 2461 // The process has activities, so we are only allowing activity-based adjustments 2462 // to move it. It should be kept in the front of the list with other 2463 // processes that have activities, and we don't want those to change their 2464 // order except due to activity operations. 2465 return; 2466 } 2467 2468 mLruSeq++; 2469 final long now = SystemClock.uptimeMillis(); 2470 app.lastActivityTime = now; 2471 2472 // First a quick reject: if the app is already at the position we will 2473 // put it, then there is nothing to do. 2474 if (hasActivity) { 2475 final int N = mLruProcesses.size(); 2476 if (N > 0 && mLruProcesses.get(N-1) == app) { 2477 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2478 return; 2479 } 2480 } else { 2481 if (mLruProcessServiceStart > 0 2482 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2483 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2484 return; 2485 } 2486 } 2487 2488 int lrui = mLruProcesses.lastIndexOf(app); 2489 2490 if (app.persistent && lrui >= 0) { 2491 // We don't care about the position of persistent processes, as long as 2492 // they are in the list. 2493 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2494 return; 2495 } 2496 2497 /* In progress: compute new position first, so we can avoid doing work 2498 if the process is not actually going to move. Not yet working. 2499 int addIndex; 2500 int nextIndex; 2501 boolean inActivity = false, inService = false; 2502 if (hasActivity) { 2503 // Process has activities, put it at the very tipsy-top. 2504 addIndex = mLruProcesses.size(); 2505 nextIndex = mLruProcessServiceStart; 2506 inActivity = true; 2507 } else if (hasService) { 2508 // Process has services, put it at the top of the service list. 2509 addIndex = mLruProcessActivityStart; 2510 nextIndex = mLruProcessServiceStart; 2511 inActivity = true; 2512 inService = true; 2513 } else { 2514 // Process not otherwise of interest, it goes to the top of the non-service area. 2515 addIndex = mLruProcessServiceStart; 2516 if (client != null) { 2517 int clientIndex = mLruProcesses.lastIndexOf(client); 2518 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2519 + app); 2520 if (clientIndex >= 0 && addIndex > clientIndex) { 2521 addIndex = clientIndex; 2522 } 2523 } 2524 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2525 } 2526 2527 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2528 + mLruProcessActivityStart + "): " + app); 2529 */ 2530 2531 if (lrui >= 0) { 2532 if (lrui < mLruProcessActivityStart) { 2533 mLruProcessActivityStart--; 2534 } 2535 if (lrui < mLruProcessServiceStart) { 2536 mLruProcessServiceStart--; 2537 } 2538 /* 2539 if (addIndex > lrui) { 2540 addIndex--; 2541 } 2542 if (nextIndex > lrui) { 2543 nextIndex--; 2544 } 2545 */ 2546 mLruProcesses.remove(lrui); 2547 } 2548 2549 /* 2550 mLruProcesses.add(addIndex, app); 2551 if (inActivity) { 2552 mLruProcessActivityStart++; 2553 } 2554 if (inService) { 2555 mLruProcessActivityStart++; 2556 } 2557 */ 2558 2559 int nextIndex; 2560 if (hasActivity) { 2561 final int N = mLruProcesses.size(); 2562 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2563 // Process doesn't have activities, but has clients with 2564 // activities... move it up, but one below the top (the top 2565 // should always have a real activity). 2566 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2567 mLruProcesses.add(N-1, app); 2568 // To keep it from spamming the LRU list (by making a bunch of clients), 2569 // we will push down any other entries owned by the app. 2570 final int uid = app.info.uid; 2571 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2572 ProcessRecord subProc = mLruProcesses.get(i); 2573 if (subProc.info.uid == uid) { 2574 // We want to push this one down the list. If the process after 2575 // it is for the same uid, however, don't do so, because we don't 2576 // want them internally to be re-ordered. 2577 if (mLruProcesses.get(i-1).info.uid != uid) { 2578 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2579 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2580 ProcessRecord tmp = mLruProcesses.get(i); 2581 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2582 mLruProcesses.set(i-1, tmp); 2583 i--; 2584 } 2585 } else { 2586 // A gap, we can stop here. 2587 break; 2588 } 2589 } 2590 } else { 2591 // Process has activities, put it at the very tipsy-top. 2592 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2593 mLruProcesses.add(app); 2594 } 2595 nextIndex = mLruProcessServiceStart; 2596 } else if (hasService) { 2597 // Process has services, put it at the top of the service list. 2598 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2599 mLruProcesses.add(mLruProcessActivityStart, app); 2600 nextIndex = mLruProcessServiceStart; 2601 mLruProcessActivityStart++; 2602 } else { 2603 // Process not otherwise of interest, it goes to the top of the non-service area. 2604 int index = mLruProcessServiceStart; 2605 if (client != null) { 2606 // If there is a client, don't allow the process to be moved up higher 2607 // in the list than that client. 2608 int clientIndex = mLruProcesses.lastIndexOf(client); 2609 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2610 + " when updating " + app); 2611 if (clientIndex <= lrui) { 2612 // Don't allow the client index restriction to push it down farther in the 2613 // list than it already is. 2614 clientIndex = lrui; 2615 } 2616 if (clientIndex >= 0 && index > clientIndex) { 2617 index = clientIndex; 2618 } 2619 } 2620 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2621 mLruProcesses.add(index, app); 2622 nextIndex = index-1; 2623 mLruProcessActivityStart++; 2624 mLruProcessServiceStart++; 2625 } 2626 2627 // If the app is currently using a content provider or service, 2628 // bump those processes as well. 2629 for (int j=app.connections.size()-1; j>=0; j--) { 2630 ConnectionRecord cr = app.connections.valueAt(j); 2631 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2632 && cr.binding.service.app != null 2633 && cr.binding.service.app.lruSeq != mLruSeq 2634 && !cr.binding.service.app.persistent) { 2635 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2636 "service connection", cr, app); 2637 } 2638 } 2639 for (int j=app.conProviders.size()-1; j>=0; j--) { 2640 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2641 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2642 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2643 "provider reference", cpr, app); 2644 } 2645 } 2646 } 2647 2648 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2649 if (uid == Process.SYSTEM_UID) { 2650 // The system gets to run in any process. If there are multiple 2651 // processes with the same uid, just pick the first (this 2652 // should never happen). 2653 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2654 if (procs == null) return null; 2655 final int N = procs.size(); 2656 for (int i = 0; i < N; i++) { 2657 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2658 } 2659 } 2660 ProcessRecord proc = mProcessNames.get(processName, uid); 2661 if (false && proc != null && !keepIfLarge 2662 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2663 && proc.lastCachedPss >= 4000) { 2664 // Turn this condition on to cause killing to happen regularly, for testing. 2665 if (proc.baseProcessTracker != null) { 2666 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2667 } 2668 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2669 } else if (proc != null && !keepIfLarge 2670 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2671 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2672 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2673 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2674 if (proc.baseProcessTracker != null) { 2675 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2676 } 2677 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2678 } 2679 } 2680 return proc; 2681 } 2682 2683 void ensurePackageDexOpt(String packageName) { 2684 IPackageManager pm = AppGlobals.getPackageManager(); 2685 try { 2686 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2687 mDidDexOpt = true; 2688 } 2689 } catch (RemoteException e) { 2690 } 2691 } 2692 2693 boolean isNextTransitionForward() { 2694 int transit = mWindowManager.getPendingAppTransition(); 2695 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2696 || transit == AppTransition.TRANSIT_TASK_OPEN 2697 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2698 } 2699 2700 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2701 String processName, String abiOverride, int uid, Runnable crashHandler) { 2702 synchronized(this) { 2703 ApplicationInfo info = new ApplicationInfo(); 2704 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2705 // For isolated processes, the former contains the parent's uid and the latter the 2706 // actual uid of the isolated process. 2707 // In the special case introduced by this method (which is, starting an isolated 2708 // process directly from the SystemServer without an actual parent app process) the 2709 // closest thing to a parent's uid is SYSTEM_UID. 2710 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2711 // the |isolated| logic in the ProcessRecord constructor. 2712 info.uid = Process.SYSTEM_UID; 2713 info.processName = processName; 2714 info.className = entryPoint; 2715 info.packageName = "android"; 2716 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2717 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2718 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2719 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2720 crashHandler); 2721 return proc != null ? proc.pid : 0; 2722 } 2723 } 2724 2725 final ProcessRecord startProcessLocked(String processName, 2726 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2727 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2728 boolean isolated, boolean keepIfLarge) { 2729 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2730 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2731 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2732 null /* crashHandler */); 2733 } 2734 2735 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2736 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2737 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2738 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2739 long startTime = SystemClock.elapsedRealtime(); 2740 ProcessRecord app; 2741 if (!isolated) { 2742 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2743 checkTime(startTime, "startProcess: after getProcessRecord"); 2744 } else { 2745 // If this is an isolated process, it can't re-use an existing process. 2746 app = null; 2747 } 2748 // We don't have to do anything more if: 2749 // (1) There is an existing application record; and 2750 // (2) The caller doesn't think it is dead, OR there is no thread 2751 // object attached to it so we know it couldn't have crashed; and 2752 // (3) There is a pid assigned to it, so it is either starting or 2753 // already running. 2754 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2755 + " app=" + app + " knownToBeDead=" + knownToBeDead 2756 + " thread=" + (app != null ? app.thread : null) 2757 + " pid=" + (app != null ? app.pid : -1)); 2758 if (app != null && app.pid > 0) { 2759 if (!knownToBeDead || app.thread == null) { 2760 // We already have the app running, or are waiting for it to 2761 // come up (we have a pid but not yet its thread), so keep it. 2762 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2763 // If this is a new package in the process, add the package to the list 2764 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2765 checkTime(startTime, "startProcess: done, added package to proc"); 2766 return app; 2767 } 2768 2769 // An application record is attached to a previous process, 2770 // clean it up now. 2771 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2772 checkTime(startTime, "startProcess: bad proc running, killing"); 2773 Process.killProcessGroup(app.info.uid, app.pid); 2774 handleAppDiedLocked(app, true, true); 2775 checkTime(startTime, "startProcess: done killing old proc"); 2776 } 2777 2778 String hostingNameStr = hostingName != null 2779 ? hostingName.flattenToShortString() : null; 2780 2781 if (!isolated) { 2782 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2783 // If we are in the background, then check to see if this process 2784 // is bad. If so, we will just silently fail. 2785 if (mBadProcesses.get(info.processName, info.uid) != null) { 2786 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2787 + "/" + info.processName); 2788 return null; 2789 } 2790 } else { 2791 // When the user is explicitly starting a process, then clear its 2792 // crash count so that we won't make it bad until they see at 2793 // least one crash dialog again, and make the process good again 2794 // if it had been bad. 2795 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2796 + "/" + info.processName); 2797 mProcessCrashTimes.remove(info.processName, info.uid); 2798 if (mBadProcesses.get(info.processName, info.uid) != null) { 2799 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2800 UserHandle.getUserId(info.uid), info.uid, 2801 info.processName); 2802 mBadProcesses.remove(info.processName, info.uid); 2803 if (app != null) { 2804 app.bad = false; 2805 } 2806 } 2807 } 2808 } 2809 2810 if (app == null) { 2811 checkTime(startTime, "startProcess: creating new process record"); 2812 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2813 app.crashHandler = crashHandler; 2814 if (app == null) { 2815 Slog.w(TAG, "Failed making new process record for " 2816 + processName + "/" + info.uid + " isolated=" + isolated); 2817 return null; 2818 } 2819 mProcessNames.put(processName, app.uid, app); 2820 if (isolated) { 2821 mIsolatedProcesses.put(app.uid, app); 2822 } 2823 checkTime(startTime, "startProcess: done creating new process record"); 2824 } else { 2825 // If this is a new package in the process, add the package to the list 2826 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2827 checkTime(startTime, "startProcess: added package to existing proc"); 2828 } 2829 2830 // If the system is not ready yet, then hold off on starting this 2831 // process until it is. 2832 if (!mProcessesReady 2833 && !isAllowedWhileBooting(info) 2834 && !allowWhileBooting) { 2835 if (!mProcessesOnHold.contains(app)) { 2836 mProcessesOnHold.add(app); 2837 } 2838 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2839 checkTime(startTime, "startProcess: returning with proc on hold"); 2840 return app; 2841 } 2842 2843 checkTime(startTime, "startProcess: stepping in to startProcess"); 2844 startProcessLocked( 2845 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2846 checkTime(startTime, "startProcess: done starting proc!"); 2847 return (app.pid != 0) ? app : null; 2848 } 2849 2850 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2851 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2852 } 2853 2854 private final void startProcessLocked(ProcessRecord app, 2855 String hostingType, String hostingNameStr) { 2856 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2857 null /* entryPoint */, null /* entryPointArgs */); 2858 } 2859 2860 private final void startProcessLocked(ProcessRecord app, String hostingType, 2861 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2862 long startTime = SystemClock.elapsedRealtime(); 2863 if (app.pid > 0 && app.pid != MY_PID) { 2864 checkTime(startTime, "startProcess: removing from pids map"); 2865 synchronized (mPidsSelfLocked) { 2866 mPidsSelfLocked.remove(app.pid); 2867 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2868 } 2869 checkTime(startTime, "startProcess: done removing from pids map"); 2870 app.setPid(0); 2871 } 2872 2873 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2874 "startProcessLocked removing on hold: " + app); 2875 mProcessesOnHold.remove(app); 2876 2877 checkTime(startTime, "startProcess: starting to update cpu stats"); 2878 updateCpuStats(); 2879 checkTime(startTime, "startProcess: done updating cpu stats"); 2880 2881 try { 2882 int uid = app.uid; 2883 2884 int[] gids = null; 2885 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2886 if (!app.isolated) { 2887 int[] permGids = null; 2888 try { 2889 checkTime(startTime, "startProcess: getting gids from package manager"); 2890 final PackageManager pm = mContext.getPackageManager(); 2891 permGids = pm.getPackageGids(app.info.packageName); 2892 2893 if (Environment.isExternalStorageEmulated()) { 2894 checkTime(startTime, "startProcess: checking external storage perm"); 2895 if (pm.checkPermission( 2896 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2897 app.info.packageName) == PERMISSION_GRANTED) { 2898 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2899 } else { 2900 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2901 } 2902 } 2903 } catch (PackageManager.NameNotFoundException e) { 2904 Slog.w(TAG, "Unable to retrieve gids", e); 2905 } 2906 2907 /* 2908 * Add shared application and profile GIDs so applications can share some 2909 * resources like shared libraries and access user-wide resources 2910 */ 2911 if (permGids == null) { 2912 gids = new int[2]; 2913 } else { 2914 gids = new int[permGids.length + 2]; 2915 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2916 } 2917 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2918 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2919 } 2920 checkTime(startTime, "startProcess: building args"); 2921 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2922 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2923 && mTopComponent != null 2924 && app.processName.equals(mTopComponent.getPackageName())) { 2925 uid = 0; 2926 } 2927 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2928 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2929 uid = 0; 2930 } 2931 } 2932 int debugFlags = 0; 2933 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2934 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2935 // Also turn on CheckJNI for debuggable apps. It's quite 2936 // awkward to turn on otherwise. 2937 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2938 } 2939 // Run the app in safe mode if its manifest requests so or the 2940 // system is booted in safe mode. 2941 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2942 mSafeMode == true) { 2943 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2944 } 2945 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2946 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2947 } 2948 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2949 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2950 } 2951 if ("1".equals(SystemProperties.get("debug.assert"))) { 2952 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2953 } 2954 2955 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2956 if (requiredAbi == null) { 2957 requiredAbi = Build.SUPPORTED_ABIS[0]; 2958 } 2959 2960 String instructionSet = null; 2961 if (app.info.primaryCpuAbi != null) { 2962 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 2963 } 2964 2965 // Start the process. It will either succeed and return a result containing 2966 // the PID of the new process, or else throw a RuntimeException. 2967 boolean isActivityProcess = (entryPoint == null); 2968 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 2969 checkTime(startTime, "startProcess: asking zygote to start proc"); 2970 Process.ProcessStartResult startResult = Process.start(entryPoint, 2971 app.processName, uid, uid, gids, debugFlags, mountExternal, 2972 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 2973 app.info.dataDir, entryPointArgs); 2974 checkTime(startTime, "startProcess: returned from zygote!"); 2975 2976 if (app.isolated) { 2977 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2978 } 2979 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2980 checkTime(startTime, "startProcess: done updating battery stats"); 2981 2982 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2983 UserHandle.getUserId(uid), startResult.pid, uid, 2984 app.processName, hostingType, 2985 hostingNameStr != null ? hostingNameStr : ""); 2986 2987 if (app.persistent) { 2988 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2989 } 2990 2991 checkTime(startTime, "startProcess: building log message"); 2992 StringBuilder buf = mStringBuilder; 2993 buf.setLength(0); 2994 buf.append("Start proc "); 2995 buf.append(app.processName); 2996 if (!isActivityProcess) { 2997 buf.append(" ["); 2998 buf.append(entryPoint); 2999 buf.append("]"); 3000 } 3001 buf.append(" for "); 3002 buf.append(hostingType); 3003 if (hostingNameStr != null) { 3004 buf.append(" "); 3005 buf.append(hostingNameStr); 3006 } 3007 buf.append(": pid="); 3008 buf.append(startResult.pid); 3009 buf.append(" uid="); 3010 buf.append(uid); 3011 buf.append(" gids={"); 3012 if (gids != null) { 3013 for (int gi=0; gi<gids.length; gi++) { 3014 if (gi != 0) buf.append(", "); 3015 buf.append(gids[gi]); 3016 3017 } 3018 } 3019 buf.append("}"); 3020 if (requiredAbi != null) { 3021 buf.append(" abi="); 3022 buf.append(requiredAbi); 3023 } 3024 Slog.i(TAG, buf.toString()); 3025 app.setPid(startResult.pid); 3026 app.usingWrapper = startResult.usingWrapper; 3027 app.removed = false; 3028 app.killed = false; 3029 app.killedByAm = false; 3030 checkTime(startTime, "startProcess: starting to update pids map"); 3031 synchronized (mPidsSelfLocked) { 3032 this.mPidsSelfLocked.put(startResult.pid, app); 3033 if (isActivityProcess) { 3034 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3035 msg.obj = app; 3036 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3037 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3038 } 3039 } 3040 checkTime(startTime, "startProcess: done updating pids map"); 3041 } catch (RuntimeException e) { 3042 // XXX do better error recovery. 3043 app.setPid(0); 3044 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3045 if (app.isolated) { 3046 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3047 } 3048 Slog.e(TAG, "Failure starting process " + app.processName, e); 3049 } 3050 } 3051 3052 void updateUsageStats(ActivityRecord component, boolean resumed) { 3053 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3054 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3055 if (resumed) { 3056 if (mUsageStatsService != null) { 3057 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3058 UsageEvents.Event.MOVE_TO_FOREGROUND); 3059 } 3060 synchronized (stats) { 3061 stats.noteActivityResumedLocked(component.app.uid); 3062 } 3063 } else { 3064 if (mUsageStatsService != null) { 3065 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3066 UsageEvents.Event.MOVE_TO_BACKGROUND); 3067 } 3068 synchronized (stats) { 3069 stats.noteActivityPausedLocked(component.app.uid); 3070 } 3071 } 3072 } 3073 3074 Intent getHomeIntent() { 3075 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3076 intent.setComponent(mTopComponent); 3077 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3078 intent.addCategory(Intent.CATEGORY_HOME); 3079 } 3080 return intent; 3081 } 3082 3083 boolean startHomeActivityLocked(int userId) { 3084 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3085 && mTopAction == null) { 3086 // We are running in factory test mode, but unable to find 3087 // the factory test app, so just sit around displaying the 3088 // error message and don't try to start anything. 3089 return false; 3090 } 3091 Intent intent = getHomeIntent(); 3092 ActivityInfo aInfo = 3093 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3094 if (aInfo != null) { 3095 intent.setComponent(new ComponentName( 3096 aInfo.applicationInfo.packageName, aInfo.name)); 3097 // Don't do this if the home app is currently being 3098 // instrumented. 3099 aInfo = new ActivityInfo(aInfo); 3100 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3101 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3102 aInfo.applicationInfo.uid, true); 3103 if (app == null || app.instrumentationClass == null) { 3104 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3105 mStackSupervisor.startHomeActivity(intent, aInfo); 3106 } 3107 } 3108 3109 return true; 3110 } 3111 3112 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3113 ActivityInfo ai = null; 3114 ComponentName comp = intent.getComponent(); 3115 try { 3116 if (comp != null) { 3117 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3118 } else { 3119 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3120 intent, 3121 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3122 flags, userId); 3123 3124 if (info != null) { 3125 ai = info.activityInfo; 3126 } 3127 } 3128 } catch (RemoteException e) { 3129 // ignore 3130 } 3131 3132 return ai; 3133 } 3134 3135 /** 3136 * Starts the "new version setup screen" if appropriate. 3137 */ 3138 void startSetupActivityLocked() { 3139 // Only do this once per boot. 3140 if (mCheckedForSetup) { 3141 return; 3142 } 3143 3144 // We will show this screen if the current one is a different 3145 // version than the last one shown, and we are not running in 3146 // low-level factory test mode. 3147 final ContentResolver resolver = mContext.getContentResolver(); 3148 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3149 Settings.Global.getInt(resolver, 3150 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3151 mCheckedForSetup = true; 3152 3153 // See if we should be showing the platform update setup UI. 3154 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3155 List<ResolveInfo> ris = mContext.getPackageManager() 3156 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3157 3158 // We don't allow third party apps to replace this. 3159 ResolveInfo ri = null; 3160 for (int i=0; ris != null && i<ris.size(); i++) { 3161 if ((ris.get(i).activityInfo.applicationInfo.flags 3162 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3163 ri = ris.get(i); 3164 break; 3165 } 3166 } 3167 3168 if (ri != null) { 3169 String vers = ri.activityInfo.metaData != null 3170 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3171 : null; 3172 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3173 vers = ri.activityInfo.applicationInfo.metaData.getString( 3174 Intent.METADATA_SETUP_VERSION); 3175 } 3176 String lastVers = Settings.Secure.getString( 3177 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3178 if (vers != null && !vers.equals(lastVers)) { 3179 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3180 intent.setComponent(new ComponentName( 3181 ri.activityInfo.packageName, ri.activityInfo.name)); 3182 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3183 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3184 null); 3185 } 3186 } 3187 } 3188 } 3189 3190 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3191 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3192 } 3193 3194 void enforceNotIsolatedCaller(String caller) { 3195 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3196 throw new SecurityException("Isolated process not allowed to call " + caller); 3197 } 3198 } 3199 3200 void enforceShellRestriction(String restriction, int userHandle) { 3201 if (Binder.getCallingUid() == Process.SHELL_UID) { 3202 if (userHandle < 0 3203 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3204 throw new SecurityException("Shell does not have permission to access user " 3205 + userHandle); 3206 } 3207 } 3208 } 3209 3210 @Override 3211 public int getFrontActivityScreenCompatMode() { 3212 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3213 synchronized (this) { 3214 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3215 } 3216 } 3217 3218 @Override 3219 public void setFrontActivityScreenCompatMode(int mode) { 3220 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3221 "setFrontActivityScreenCompatMode"); 3222 synchronized (this) { 3223 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3224 } 3225 } 3226 3227 @Override 3228 public int getPackageScreenCompatMode(String packageName) { 3229 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3230 synchronized (this) { 3231 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3232 } 3233 } 3234 3235 @Override 3236 public void setPackageScreenCompatMode(String packageName, int mode) { 3237 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3238 "setPackageScreenCompatMode"); 3239 synchronized (this) { 3240 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3241 } 3242 } 3243 3244 @Override 3245 public boolean getPackageAskScreenCompat(String packageName) { 3246 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3247 synchronized (this) { 3248 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3249 } 3250 } 3251 3252 @Override 3253 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3254 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3255 "setPackageAskScreenCompat"); 3256 synchronized (this) { 3257 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3258 } 3259 } 3260 3261 private void dispatchProcessesChanged() { 3262 int N; 3263 synchronized (this) { 3264 N = mPendingProcessChanges.size(); 3265 if (mActiveProcessChanges.length < N) { 3266 mActiveProcessChanges = new ProcessChangeItem[N]; 3267 } 3268 mPendingProcessChanges.toArray(mActiveProcessChanges); 3269 mAvailProcessChanges.addAll(mPendingProcessChanges); 3270 mPendingProcessChanges.clear(); 3271 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3272 } 3273 3274 int i = mProcessObservers.beginBroadcast(); 3275 while (i > 0) { 3276 i--; 3277 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3278 if (observer != null) { 3279 try { 3280 for (int j=0; j<N; j++) { 3281 ProcessChangeItem item = mActiveProcessChanges[j]; 3282 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3283 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3284 + item.pid + " uid=" + item.uid + ": " 3285 + item.foregroundActivities); 3286 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3287 item.foregroundActivities); 3288 } 3289 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3290 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3291 + item.pid + " uid=" + item.uid + ": " + item.processState); 3292 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3293 } 3294 } 3295 } catch (RemoteException e) { 3296 } 3297 } 3298 } 3299 mProcessObservers.finishBroadcast(); 3300 } 3301 3302 private void dispatchProcessDied(int pid, int uid) { 3303 int i = mProcessObservers.beginBroadcast(); 3304 while (i > 0) { 3305 i--; 3306 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3307 if (observer != null) { 3308 try { 3309 observer.onProcessDied(pid, uid); 3310 } catch (RemoteException e) { 3311 } 3312 } 3313 } 3314 mProcessObservers.finishBroadcast(); 3315 } 3316 3317 @Override 3318 public final int startActivity(IApplicationThread caller, String callingPackage, 3319 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3320 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3321 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3322 resultWho, requestCode, startFlags, profilerInfo, options, 3323 UserHandle.getCallingUserId()); 3324 } 3325 3326 @Override 3327 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3328 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3329 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3330 enforceNotIsolatedCaller("startActivity"); 3331 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3332 false, ALLOW_FULL_ONLY, "startActivity", null); 3333 // TODO: Switch to user app stacks here. 3334 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3335 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3336 profilerInfo, null, null, options, userId, null, null); 3337 } 3338 3339 @Override 3340 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3341 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3342 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3343 3344 // This is very dangerous -- it allows you to perform a start activity (including 3345 // permission grants) as any app that may launch one of your own activities. So 3346 // we will only allow this to be done from activities that are part of the core framework, 3347 // and then only when they are running as the system. 3348 final ActivityRecord sourceRecord; 3349 final int targetUid; 3350 final String targetPackage; 3351 synchronized (this) { 3352 if (resultTo == null) { 3353 throw new SecurityException("Must be called from an activity"); 3354 } 3355 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3356 if (sourceRecord == null) { 3357 throw new SecurityException("Called with bad activity token: " + resultTo); 3358 } 3359 if (!sourceRecord.info.packageName.equals("android")) { 3360 throw new SecurityException( 3361 "Must be called from an activity that is declared in the android package"); 3362 } 3363 if (sourceRecord.app == null) { 3364 throw new SecurityException("Called without a process attached to activity"); 3365 } 3366 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3367 // This is still okay, as long as this activity is running under the 3368 // uid of the original calling activity. 3369 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3370 throw new SecurityException( 3371 "Calling activity in uid " + sourceRecord.app.uid 3372 + " must be system uid or original calling uid " 3373 + sourceRecord.launchedFromUid); 3374 } 3375 } 3376 targetUid = sourceRecord.launchedFromUid; 3377 targetPackage = sourceRecord.launchedFromPackage; 3378 } 3379 3380 if (userId == UserHandle.USER_NULL) { 3381 userId = UserHandle.getUserId(sourceRecord.app.uid); 3382 } 3383 3384 // TODO: Switch to user app stacks here. 3385 try { 3386 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3387 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3388 null, null, options, userId, null, null); 3389 return ret; 3390 } catch (SecurityException e) { 3391 // XXX need to figure out how to propagate to original app. 3392 // A SecurityException here is generally actually a fault of the original 3393 // calling activity (such as a fairly granting permissions), so propagate it 3394 // back to them. 3395 /* 3396 StringBuilder msg = new StringBuilder(); 3397 msg.append("While launching"); 3398 msg.append(intent.toString()); 3399 msg.append(": "); 3400 msg.append(e.getMessage()); 3401 */ 3402 throw e; 3403 } 3404 } 3405 3406 @Override 3407 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3408 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3409 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3410 enforceNotIsolatedCaller("startActivityAndWait"); 3411 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3412 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3413 WaitResult res = new WaitResult(); 3414 // TODO: Switch to user app stacks here. 3415 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3416 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3417 options, userId, null, null); 3418 return res; 3419 } 3420 3421 @Override 3422 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3423 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3424 int startFlags, Configuration config, Bundle options, int userId) { 3425 enforceNotIsolatedCaller("startActivityWithConfig"); 3426 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3427 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3428 // TODO: Switch to user app stacks here. 3429 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3430 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3431 null, null, config, options, userId, null, null); 3432 return ret; 3433 } 3434 3435 @Override 3436 public int startActivityIntentSender(IApplicationThread caller, 3437 IntentSender intent, Intent fillInIntent, String resolvedType, 3438 IBinder resultTo, String resultWho, int requestCode, 3439 int flagsMask, int flagsValues, Bundle options) { 3440 enforceNotIsolatedCaller("startActivityIntentSender"); 3441 // Refuse possible leaked file descriptors 3442 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3443 throw new IllegalArgumentException("File descriptors passed in Intent"); 3444 } 3445 3446 IIntentSender sender = intent.getTarget(); 3447 if (!(sender instanceof PendingIntentRecord)) { 3448 throw new IllegalArgumentException("Bad PendingIntent object"); 3449 } 3450 3451 PendingIntentRecord pir = (PendingIntentRecord)sender; 3452 3453 synchronized (this) { 3454 // If this is coming from the currently resumed activity, it is 3455 // effectively saying that app switches are allowed at this point. 3456 final ActivityStack stack = getFocusedStack(); 3457 if (stack.mResumedActivity != null && 3458 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3459 mAppSwitchesAllowedTime = 0; 3460 } 3461 } 3462 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3463 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3464 return ret; 3465 } 3466 3467 @Override 3468 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3469 Intent intent, String resolvedType, IVoiceInteractionSession session, 3470 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3471 Bundle options, int userId) { 3472 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3473 != PackageManager.PERMISSION_GRANTED) { 3474 String msg = "Permission Denial: startVoiceActivity() from pid=" 3475 + Binder.getCallingPid() 3476 + ", uid=" + Binder.getCallingUid() 3477 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3478 Slog.w(TAG, msg); 3479 throw new SecurityException(msg); 3480 } 3481 if (session == null || interactor == null) { 3482 throw new NullPointerException("null session or interactor"); 3483 } 3484 userId = handleIncomingUser(callingPid, callingUid, userId, 3485 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3486 // TODO: Switch to user app stacks here. 3487 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3488 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3489 null, options, userId, null, null); 3490 } 3491 3492 @Override 3493 public boolean startNextMatchingActivity(IBinder callingActivity, 3494 Intent intent, Bundle options) { 3495 // Refuse possible leaked file descriptors 3496 if (intent != null && intent.hasFileDescriptors() == true) { 3497 throw new IllegalArgumentException("File descriptors passed in Intent"); 3498 } 3499 3500 synchronized (this) { 3501 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3502 if (r == null) { 3503 ActivityOptions.abort(options); 3504 return false; 3505 } 3506 if (r.app == null || r.app.thread == null) { 3507 // The caller is not running... d'oh! 3508 ActivityOptions.abort(options); 3509 return false; 3510 } 3511 intent = new Intent(intent); 3512 // The caller is not allowed to change the data. 3513 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3514 // And we are resetting to find the next component... 3515 intent.setComponent(null); 3516 3517 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3518 3519 ActivityInfo aInfo = null; 3520 try { 3521 List<ResolveInfo> resolves = 3522 AppGlobals.getPackageManager().queryIntentActivities( 3523 intent, r.resolvedType, 3524 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3525 UserHandle.getCallingUserId()); 3526 3527 // Look for the original activity in the list... 3528 final int N = resolves != null ? resolves.size() : 0; 3529 for (int i=0; i<N; i++) { 3530 ResolveInfo rInfo = resolves.get(i); 3531 if (rInfo.activityInfo.packageName.equals(r.packageName) 3532 && rInfo.activityInfo.name.equals(r.info.name)) { 3533 // We found the current one... the next matching is 3534 // after it. 3535 i++; 3536 if (i<N) { 3537 aInfo = resolves.get(i).activityInfo; 3538 } 3539 if (debug) { 3540 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3541 + "/" + r.info.name); 3542 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3543 + "/" + aInfo.name); 3544 } 3545 break; 3546 } 3547 } 3548 } catch (RemoteException e) { 3549 } 3550 3551 if (aInfo == null) { 3552 // Nobody who is next! 3553 ActivityOptions.abort(options); 3554 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3555 return false; 3556 } 3557 3558 intent.setComponent(new ComponentName( 3559 aInfo.applicationInfo.packageName, aInfo.name)); 3560 intent.setFlags(intent.getFlags()&~( 3561 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3562 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3563 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3564 Intent.FLAG_ACTIVITY_NEW_TASK)); 3565 3566 // Okay now we need to start the new activity, replacing the 3567 // currently running activity. This is a little tricky because 3568 // we want to start the new one as if the current one is finished, 3569 // but not finish the current one first so that there is no flicker. 3570 // And thus... 3571 final boolean wasFinishing = r.finishing; 3572 r.finishing = true; 3573 3574 // Propagate reply information over to the new activity. 3575 final ActivityRecord resultTo = r.resultTo; 3576 final String resultWho = r.resultWho; 3577 final int requestCode = r.requestCode; 3578 r.resultTo = null; 3579 if (resultTo != null) { 3580 resultTo.removeResultsLocked(r, resultWho, requestCode); 3581 } 3582 3583 final long origId = Binder.clearCallingIdentity(); 3584 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3585 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3586 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3587 -1, r.launchedFromUid, 0, options, false, null, null, null); 3588 Binder.restoreCallingIdentity(origId); 3589 3590 r.finishing = wasFinishing; 3591 if (res != ActivityManager.START_SUCCESS) { 3592 return false; 3593 } 3594 return true; 3595 } 3596 } 3597 3598 @Override 3599 public final int startActivityFromRecents(int taskId, Bundle options) { 3600 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3601 String msg = "Permission Denial: startActivityFromRecents called without " + 3602 START_TASKS_FROM_RECENTS; 3603 Slog.w(TAG, msg); 3604 throw new SecurityException(msg); 3605 } 3606 return startActivityFromRecentsInner(taskId, options); 3607 } 3608 3609 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3610 final TaskRecord task; 3611 final int callingUid; 3612 final String callingPackage; 3613 final Intent intent; 3614 final int userId; 3615 synchronized (this) { 3616 task = recentTaskForIdLocked(taskId); 3617 if (task == null) { 3618 throw new IllegalArgumentException("Task " + taskId + " not found."); 3619 } 3620 callingUid = task.mCallingUid; 3621 callingPackage = task.mCallingPackage; 3622 intent = task.intent; 3623 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3624 userId = task.userId; 3625 } 3626 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3627 options, userId, null, task); 3628 } 3629 3630 final int startActivityInPackage(int uid, String callingPackage, 3631 Intent intent, String resolvedType, IBinder resultTo, 3632 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3633 IActivityContainer container, TaskRecord inTask) { 3634 3635 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3636 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3637 3638 // TODO: Switch to user app stacks here. 3639 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3640 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3641 null, null, null, options, userId, container, inTask); 3642 return ret; 3643 } 3644 3645 @Override 3646 public final int startActivities(IApplicationThread caller, String callingPackage, 3647 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3648 int userId) { 3649 enforceNotIsolatedCaller("startActivities"); 3650 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3651 false, ALLOW_FULL_ONLY, "startActivity", null); 3652 // TODO: Switch to user app stacks here. 3653 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3654 resolvedTypes, resultTo, options, userId); 3655 return ret; 3656 } 3657 3658 final int startActivitiesInPackage(int uid, String callingPackage, 3659 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3660 Bundle options, int userId) { 3661 3662 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3663 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3664 // TODO: Switch to user app stacks here. 3665 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3666 resultTo, options, userId); 3667 return ret; 3668 } 3669 3670 //explicitly remove thd old information in mRecentTasks when removing existing user. 3671 private void removeRecentTasksForUserLocked(int userId) { 3672 if(userId <= 0) { 3673 Slog.i(TAG, "Can't remove recent task on user " + userId); 3674 return; 3675 } 3676 3677 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3678 TaskRecord tr = mRecentTasks.get(i); 3679 if (tr.userId == userId) { 3680 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3681 + " when finishing user" + userId); 3682 mRecentTasks.remove(i); 3683 tr.removedFromRecents(); 3684 } 3685 } 3686 3687 // Remove tasks from persistent storage. 3688 notifyTaskPersisterLocked(null, true); 3689 } 3690 3691 // Sort by taskId 3692 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3693 @Override 3694 public int compare(TaskRecord lhs, TaskRecord rhs) { 3695 return rhs.taskId - lhs.taskId; 3696 } 3697 }; 3698 3699 // Extract the affiliates of the chain containing mRecentTasks[start]. 3700 private int processNextAffiliateChainLocked(int start) { 3701 final TaskRecord startTask = mRecentTasks.get(start); 3702 final int affiliateId = startTask.mAffiliatedTaskId; 3703 3704 // Quick identification of isolated tasks. I.e. those not launched behind. 3705 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3706 startTask.mNextAffiliate == null) { 3707 // There is still a slim chance that there are other tasks that point to this task 3708 // and that the chain is so messed up that this task no longer points to them but 3709 // the gain of this optimization outweighs the risk. 3710 startTask.inRecents = true; 3711 return start + 1; 3712 } 3713 3714 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3715 mTmpRecents.clear(); 3716 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3717 final TaskRecord task = mRecentTasks.get(i); 3718 if (task.mAffiliatedTaskId == affiliateId) { 3719 mRecentTasks.remove(i); 3720 mTmpRecents.add(task); 3721 } 3722 } 3723 3724 // Sort them all by taskId. That is the order they were create in and that order will 3725 // always be correct. 3726 Collections.sort(mTmpRecents, mTaskRecordComparator); 3727 3728 // Go through and fix up the linked list. 3729 // The first one is the end of the chain and has no next. 3730 final TaskRecord first = mTmpRecents.get(0); 3731 first.inRecents = true; 3732 if (first.mNextAffiliate != null) { 3733 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3734 first.setNextAffiliate(null); 3735 notifyTaskPersisterLocked(first, false); 3736 } 3737 // Everything in the middle is doubly linked from next to prev. 3738 final int tmpSize = mTmpRecents.size(); 3739 for (int i = 0; i < tmpSize - 1; ++i) { 3740 final TaskRecord next = mTmpRecents.get(i); 3741 final TaskRecord prev = mTmpRecents.get(i + 1); 3742 if (next.mPrevAffiliate != prev) { 3743 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3744 " setting prev=" + prev); 3745 next.setPrevAffiliate(prev); 3746 notifyTaskPersisterLocked(next, false); 3747 } 3748 if (prev.mNextAffiliate != next) { 3749 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3750 " setting next=" + next); 3751 prev.setNextAffiliate(next); 3752 notifyTaskPersisterLocked(prev, false); 3753 } 3754 prev.inRecents = true; 3755 } 3756 // The last one is the beginning of the list and has no prev. 3757 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3758 if (last.mPrevAffiliate != null) { 3759 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3760 last.setPrevAffiliate(null); 3761 notifyTaskPersisterLocked(last, false); 3762 } 3763 3764 // Insert the group back into mRecentTasks at start. 3765 mRecentTasks.addAll(start, mTmpRecents); 3766 3767 // Let the caller know where we left off. 3768 return start + tmpSize; 3769 } 3770 3771 /** 3772 * Update the recent tasks lists: make sure tasks should still be here (their 3773 * applications / activities still exist), update their availability, fixup ordering 3774 * of affiliations. 3775 */ 3776 void cleanupRecentTasksLocked(int userId) { 3777 if (mRecentTasks == null) { 3778 // Happens when called from the packagemanager broadcast before boot. 3779 return; 3780 } 3781 3782 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3783 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3784 final IPackageManager pm = AppGlobals.getPackageManager(); 3785 final ActivityInfo dummyAct = new ActivityInfo(); 3786 final ApplicationInfo dummyApp = new ApplicationInfo(); 3787 3788 int N = mRecentTasks.size(); 3789 3790 int[] users = userId == UserHandle.USER_ALL 3791 ? getUsersLocked() : new int[] { userId }; 3792 for (int user : users) { 3793 for (int i = 0; i < N; i++) { 3794 TaskRecord task = mRecentTasks.get(i); 3795 if (task.userId != user) { 3796 // Only look at tasks for the user ID of interest. 3797 continue; 3798 } 3799 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3800 // This situation is broken, and we should just get rid of it now. 3801 mRecentTasks.remove(i); 3802 task.removedFromRecents(); 3803 i--; 3804 N--; 3805 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3806 continue; 3807 } 3808 // Check whether this activity is currently available. 3809 if (task.realActivity != null) { 3810 ActivityInfo ai = availActCache.get(task.realActivity); 3811 if (ai == null) { 3812 try { 3813 ai = pm.getActivityInfo(task.realActivity, 3814 PackageManager.GET_UNINSTALLED_PACKAGES 3815 | PackageManager.GET_DISABLED_COMPONENTS, user); 3816 } catch (RemoteException e) { 3817 // Will never happen. 3818 continue; 3819 } 3820 if (ai == null) { 3821 ai = dummyAct; 3822 } 3823 availActCache.put(task.realActivity, ai); 3824 } 3825 if (ai == dummyAct) { 3826 // This could be either because the activity no longer exists, or the 3827 // app is temporarily gone. For the former we want to remove the recents 3828 // entry; for the latter we want to mark it as unavailable. 3829 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3830 if (app == null) { 3831 try { 3832 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3833 PackageManager.GET_UNINSTALLED_PACKAGES 3834 | PackageManager.GET_DISABLED_COMPONENTS, user); 3835 } catch (RemoteException e) { 3836 // Will never happen. 3837 continue; 3838 } 3839 if (app == null) { 3840 app = dummyApp; 3841 } 3842 availAppCache.put(task.realActivity.getPackageName(), app); 3843 } 3844 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3845 // Doesn't exist any more! Good-bye. 3846 mRecentTasks.remove(i); 3847 task.removedFromRecents(); 3848 i--; 3849 N--; 3850 Slog.w(TAG, "Removing no longer valid recent: " + task); 3851 continue; 3852 } else { 3853 // Otherwise just not available for now. 3854 if (task.isAvailable) { 3855 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3856 + task); 3857 } 3858 task.isAvailable = false; 3859 } 3860 } else { 3861 if (!ai.enabled || !ai.applicationInfo.enabled 3862 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3863 if (task.isAvailable) { 3864 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3865 + task + " (enabled=" + ai.enabled + "/" 3866 + ai.applicationInfo.enabled + " flags=" 3867 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3868 } 3869 task.isAvailable = false; 3870 } else { 3871 if (!task.isAvailable) { 3872 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3873 + task); 3874 } 3875 task.isAvailable = true; 3876 } 3877 } 3878 } 3879 } 3880 } 3881 3882 // Verify the affiliate chain for each task. 3883 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3884 } 3885 3886 mTmpRecents.clear(); 3887 // mRecentTasks is now in sorted, affiliated order. 3888 } 3889 3890 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3891 int N = mRecentTasks.size(); 3892 TaskRecord top = task; 3893 int topIndex = taskIndex; 3894 while (top.mNextAffiliate != null && topIndex > 0) { 3895 top = top.mNextAffiliate; 3896 topIndex--; 3897 } 3898 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3899 + topIndex + " from intial " + taskIndex); 3900 // Find the end of the chain, doing a sanity check along the way. 3901 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3902 int endIndex = topIndex; 3903 TaskRecord prev = top; 3904 while (endIndex < N) { 3905 TaskRecord cur = mRecentTasks.get(endIndex); 3906 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3907 + endIndex + " " + cur); 3908 if (cur == top) { 3909 // Verify start of the chain. 3910 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3911 Slog.wtf(TAG, "Bad chain @" + endIndex 3912 + ": first task has next affiliate: " + prev); 3913 sane = false; 3914 break; 3915 } 3916 } else { 3917 // Verify middle of the chain's next points back to the one before. 3918 if (cur.mNextAffiliate != prev 3919 || cur.mNextAffiliateTaskId != prev.taskId) { 3920 Slog.wtf(TAG, "Bad chain @" + endIndex 3921 + ": middle task " + cur + " @" + endIndex 3922 + " has bad next affiliate " 3923 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3924 + ", expected " + prev); 3925 sane = false; 3926 break; 3927 } 3928 } 3929 if (cur.mPrevAffiliateTaskId == -1) { 3930 // Chain ends here. 3931 if (cur.mPrevAffiliate != null) { 3932 Slog.wtf(TAG, "Bad chain @" + endIndex 3933 + ": last task " + cur + " has previous affiliate " 3934 + cur.mPrevAffiliate); 3935 sane = false; 3936 } 3937 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3938 break; 3939 } else { 3940 // Verify middle of the chain's prev points to a valid item. 3941 if (cur.mPrevAffiliate == null) { 3942 Slog.wtf(TAG, "Bad chain @" + endIndex 3943 + ": task " + cur + " has previous affiliate " 3944 + cur.mPrevAffiliate + " but should be id " 3945 + cur.mPrevAffiliate); 3946 sane = false; 3947 break; 3948 } 3949 } 3950 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3951 Slog.wtf(TAG, "Bad chain @" + endIndex 3952 + ": task " + cur + " has affiliated id " 3953 + cur.mAffiliatedTaskId + " but should be " 3954 + task.mAffiliatedTaskId); 3955 sane = false; 3956 break; 3957 } 3958 prev = cur; 3959 endIndex++; 3960 if (endIndex >= N) { 3961 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3962 + ": last task " + prev); 3963 sane = false; 3964 break; 3965 } 3966 } 3967 if (sane) { 3968 if (endIndex < taskIndex) { 3969 Slog.wtf(TAG, "Bad chain @" + endIndex 3970 + ": did not extend to task " + task + " @" + taskIndex); 3971 sane = false; 3972 } 3973 } 3974 if (sane) { 3975 // All looks good, we can just move all of the affiliated tasks 3976 // to the top. 3977 for (int i=topIndex; i<=endIndex; i++) { 3978 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 3979 + " from " + i + " to " + (i-topIndex)); 3980 TaskRecord cur = mRecentTasks.remove(i); 3981 mRecentTasks.add(i-topIndex, cur); 3982 } 3983 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 3984 + " to " + endIndex); 3985 return true; 3986 } 3987 3988 // Whoops, couldn't do it. 3989 return false; 3990 } 3991 3992 final void addRecentTaskLocked(TaskRecord task) { 3993 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 3994 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 3995 3996 int N = mRecentTasks.size(); 3997 // Quick case: check if the top-most recent task is the same. 3998 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 3999 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4000 return; 4001 } 4002 // Another quick case: check if this is part of a set of affiliated 4003 // tasks that are at the top. 4004 if (isAffiliated && N > 0 && task.inRecents 4005 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4006 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4007 + " at top when adding " + task); 4008 return; 4009 } 4010 // Another quick case: never add voice sessions. 4011 if (task.voiceSession != null) { 4012 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4013 return; 4014 } 4015 4016 boolean needAffiliationFix = false; 4017 4018 // Slightly less quick case: the task is already in recents, so all we need 4019 // to do is move it. 4020 if (task.inRecents) { 4021 int taskIndex = mRecentTasks.indexOf(task); 4022 if (taskIndex >= 0) { 4023 if (!isAffiliated) { 4024 // Simple case: this is not an affiliated task, so we just move it to the front. 4025 mRecentTasks.remove(taskIndex); 4026 mRecentTasks.add(0, task); 4027 notifyTaskPersisterLocked(task, false); 4028 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4029 + " from " + taskIndex); 4030 return; 4031 } else { 4032 // More complicated: need to keep all affiliated tasks together. 4033 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4034 // All went well. 4035 return; 4036 } 4037 4038 // Uh oh... something bad in the affiliation chain, try to rebuild 4039 // everything and then go through our general path of adding a new task. 4040 needAffiliationFix = true; 4041 } 4042 } else { 4043 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4044 needAffiliationFix = true; 4045 } 4046 } 4047 4048 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4049 trimRecentsForTaskLocked(task, true); 4050 4051 N = mRecentTasks.size(); 4052 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4053 final TaskRecord tr = mRecentTasks.remove(N - 1); 4054 tr.removedFromRecents(); 4055 N--; 4056 } 4057 task.inRecents = true; 4058 if (!isAffiliated || needAffiliationFix) { 4059 // If this is a simple non-affiliated task, or we had some failure trying to 4060 // handle it as part of an affilated task, then just place it at the top. 4061 mRecentTasks.add(0, task); 4062 } else if (isAffiliated) { 4063 // If this is a new affiliated task, then move all of the affiliated tasks 4064 // to the front and insert this new one. 4065 TaskRecord other = task.mNextAffiliate; 4066 if (other == null) { 4067 other = task.mPrevAffiliate; 4068 } 4069 if (other != null) { 4070 int otherIndex = mRecentTasks.indexOf(other); 4071 if (otherIndex >= 0) { 4072 // Insert new task at appropriate location. 4073 int taskIndex; 4074 if (other == task.mNextAffiliate) { 4075 // We found the index of our next affiliation, which is who is 4076 // before us in the list, so add after that point. 4077 taskIndex = otherIndex+1; 4078 } else { 4079 // We found the index of our previous affiliation, which is who is 4080 // after us in the list, so add at their position. 4081 taskIndex = otherIndex; 4082 } 4083 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4084 + taskIndex + ": " + task); 4085 mRecentTasks.add(taskIndex, task); 4086 4087 // Now move everything to the front. 4088 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4089 // All went well. 4090 return; 4091 } 4092 4093 // Uh oh... something bad in the affiliation chain, try to rebuild 4094 // everything and then go through our general path of adding a new task. 4095 needAffiliationFix = true; 4096 } else { 4097 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4098 + other); 4099 needAffiliationFix = true; 4100 } 4101 } else { 4102 if (DEBUG_RECENTS) Slog.d(TAG, 4103 "addRecent: adding affiliated task without next/prev:" + task); 4104 needAffiliationFix = true; 4105 } 4106 } 4107 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4108 4109 if (needAffiliationFix) { 4110 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4111 cleanupRecentTasksLocked(task.userId); 4112 } 4113 } 4114 4115 /** 4116 * If needed, remove oldest existing entries in recents that are for the same kind 4117 * of task as the given one. 4118 */ 4119 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4120 int N = mRecentTasks.size(); 4121 final Intent intent = task.intent; 4122 final boolean document = intent != null && intent.isDocument(); 4123 4124 int maxRecents = task.maxRecents - 1; 4125 for (int i=0; i<N; i++) { 4126 final TaskRecord tr = mRecentTasks.get(i); 4127 if (task != tr) { 4128 if (task.userId != tr.userId) { 4129 continue; 4130 } 4131 if (i > MAX_RECENT_BITMAPS) { 4132 tr.freeLastThumbnail(); 4133 } 4134 final Intent trIntent = tr.intent; 4135 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4136 (intent == null || !intent.filterEquals(trIntent))) { 4137 continue; 4138 } 4139 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4140 if (document && trIsDocument) { 4141 // These are the same document activity (not necessarily the same doc). 4142 if (maxRecents > 0) { 4143 --maxRecents; 4144 continue; 4145 } 4146 // Hit the maximum number of documents for this task. Fall through 4147 // and remove this document from recents. 4148 } else if (document || trIsDocument) { 4149 // Only one of these is a document. Not the droid we're looking for. 4150 continue; 4151 } 4152 } 4153 4154 if (!doTrim) { 4155 // If the caller is not actually asking for a trim, just tell them we reached 4156 // a point where the trim would happen. 4157 return i; 4158 } 4159 4160 // Either task and tr are the same or, their affinities match or their intents match 4161 // and neither of them is a document, or they are documents using the same activity 4162 // and their maxRecents has been reached. 4163 tr.disposeThumbnail(); 4164 mRecentTasks.remove(i); 4165 if (task != tr) { 4166 tr.removedFromRecents(); 4167 } 4168 i--; 4169 N--; 4170 if (task.intent == null) { 4171 // If the new recent task we are adding is not fully 4172 // specified, then replace it with the existing recent task. 4173 task = tr; 4174 } 4175 notifyTaskPersisterLocked(tr, false); 4176 } 4177 4178 return -1; 4179 } 4180 4181 @Override 4182 public void reportActivityFullyDrawn(IBinder token) { 4183 synchronized (this) { 4184 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4185 if (r == null) { 4186 return; 4187 } 4188 r.reportFullyDrawnLocked(); 4189 } 4190 } 4191 4192 @Override 4193 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4194 synchronized (this) { 4195 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4196 if (r == null) { 4197 return; 4198 } 4199 final long origId = Binder.clearCallingIdentity(); 4200 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4201 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4202 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4203 if (config != null) { 4204 r.frozenBeforeDestroy = true; 4205 if (!updateConfigurationLocked(config, r, false, false)) { 4206 mStackSupervisor.resumeTopActivitiesLocked(); 4207 } 4208 } 4209 Binder.restoreCallingIdentity(origId); 4210 } 4211 } 4212 4213 @Override 4214 public int getRequestedOrientation(IBinder token) { 4215 synchronized (this) { 4216 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4217 if (r == null) { 4218 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4219 } 4220 return mWindowManager.getAppOrientation(r.appToken); 4221 } 4222 } 4223 4224 /** 4225 * This is the internal entry point for handling Activity.finish(). 4226 * 4227 * @param token The Binder token referencing the Activity we want to finish. 4228 * @param resultCode Result code, if any, from this Activity. 4229 * @param resultData Result data (Intent), if any, from this Activity. 4230 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4231 * the root Activity in the task. 4232 * 4233 * @return Returns true if the activity successfully finished, or false if it is still running. 4234 */ 4235 @Override 4236 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4237 boolean finishTask) { 4238 // Refuse possible leaked file descriptors 4239 if (resultData != null && resultData.hasFileDescriptors() == true) { 4240 throw new IllegalArgumentException("File descriptors passed in Intent"); 4241 } 4242 4243 synchronized(this) { 4244 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4245 if (r == null) { 4246 return true; 4247 } 4248 // Keep track of the root activity of the task before we finish it 4249 TaskRecord tr = r.task; 4250 ActivityRecord rootR = tr.getRootActivity(); 4251 if (rootR == null) { 4252 Slog.w(TAG, "Finishing task with all activities already finished"); 4253 } 4254 // Do not allow task to finish in Lock Task mode. 4255 if (tr == mStackSupervisor.mLockTaskModeTask) { 4256 if (rootR == r) { 4257 Slog.i(TAG, "Not finishing task in lock task mode"); 4258 mStackSupervisor.showLockTaskToast(); 4259 return false; 4260 } 4261 } 4262 if (mController != null) { 4263 // Find the first activity that is not finishing. 4264 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4265 if (next != null) { 4266 // ask watcher if this is allowed 4267 boolean resumeOK = true; 4268 try { 4269 resumeOK = mController.activityResuming(next.packageName); 4270 } catch (RemoteException e) { 4271 mController = null; 4272 Watchdog.getInstance().setActivityController(null); 4273 } 4274 4275 if (!resumeOK) { 4276 Slog.i(TAG, "Not finishing activity because controller resumed"); 4277 return false; 4278 } 4279 } 4280 } 4281 final long origId = Binder.clearCallingIdentity(); 4282 try { 4283 boolean res; 4284 if (finishTask && r == rootR) { 4285 // If requested, remove the task that is associated to this activity only if it 4286 // was the root activity in the task. The result code and data is ignored 4287 // because we don't support returning them across task boundaries. 4288 res = removeTaskByIdLocked(tr.taskId, false); 4289 if (!res) { 4290 Slog.i(TAG, "Removing task failed to finish activity"); 4291 } 4292 } else { 4293 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4294 resultData, "app-request", true); 4295 if (!res) { 4296 Slog.i(TAG, "Failed to finish by app-request"); 4297 } 4298 } 4299 return res; 4300 } finally { 4301 Binder.restoreCallingIdentity(origId); 4302 } 4303 } 4304 } 4305 4306 @Override 4307 public final void finishHeavyWeightApp() { 4308 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4309 != PackageManager.PERMISSION_GRANTED) { 4310 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4311 + Binder.getCallingPid() 4312 + ", uid=" + Binder.getCallingUid() 4313 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4314 Slog.w(TAG, msg); 4315 throw new SecurityException(msg); 4316 } 4317 4318 synchronized(this) { 4319 if (mHeavyWeightProcess == null) { 4320 return; 4321 } 4322 4323 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4324 mHeavyWeightProcess.activities); 4325 for (int i=0; i<activities.size(); i++) { 4326 ActivityRecord r = activities.get(i); 4327 if (!r.finishing) { 4328 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4329 null, "finish-heavy", true); 4330 } 4331 } 4332 4333 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4334 mHeavyWeightProcess.userId, 0)); 4335 mHeavyWeightProcess = null; 4336 } 4337 } 4338 4339 @Override 4340 public void crashApplication(int uid, int initialPid, String packageName, 4341 String message) { 4342 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4343 != PackageManager.PERMISSION_GRANTED) { 4344 String msg = "Permission Denial: crashApplication() from pid=" 4345 + Binder.getCallingPid() 4346 + ", uid=" + Binder.getCallingUid() 4347 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4348 Slog.w(TAG, msg); 4349 throw new SecurityException(msg); 4350 } 4351 4352 synchronized(this) { 4353 ProcessRecord proc = null; 4354 4355 // Figure out which process to kill. We don't trust that initialPid 4356 // still has any relation to current pids, so must scan through the 4357 // list. 4358 synchronized (mPidsSelfLocked) { 4359 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4360 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4361 if (p.uid != uid) { 4362 continue; 4363 } 4364 if (p.pid == initialPid) { 4365 proc = p; 4366 break; 4367 } 4368 if (p.pkgList.containsKey(packageName)) { 4369 proc = p; 4370 } 4371 } 4372 } 4373 4374 if (proc == null) { 4375 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4376 + " initialPid=" + initialPid 4377 + " packageName=" + packageName); 4378 return; 4379 } 4380 4381 if (proc.thread != null) { 4382 if (proc.pid == Process.myPid()) { 4383 Log.w(TAG, "crashApplication: trying to crash self!"); 4384 return; 4385 } 4386 long ident = Binder.clearCallingIdentity(); 4387 try { 4388 proc.thread.scheduleCrash(message); 4389 } catch (RemoteException e) { 4390 } 4391 Binder.restoreCallingIdentity(ident); 4392 } 4393 } 4394 } 4395 4396 @Override 4397 public final void finishSubActivity(IBinder token, String resultWho, 4398 int requestCode) { 4399 synchronized(this) { 4400 final long origId = Binder.clearCallingIdentity(); 4401 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4402 if (r != null) { 4403 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4404 } 4405 Binder.restoreCallingIdentity(origId); 4406 } 4407 } 4408 4409 @Override 4410 public boolean finishActivityAffinity(IBinder token) { 4411 synchronized(this) { 4412 final long origId = Binder.clearCallingIdentity(); 4413 try { 4414 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4415 4416 ActivityRecord rootR = r.task.getRootActivity(); 4417 // Do not allow task to finish in Lock Task mode. 4418 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4419 if (rootR == r) { 4420 mStackSupervisor.showLockTaskToast(); 4421 return false; 4422 } 4423 } 4424 boolean res = false; 4425 if (r != null) { 4426 res = r.task.stack.finishActivityAffinityLocked(r); 4427 } 4428 return res; 4429 } finally { 4430 Binder.restoreCallingIdentity(origId); 4431 } 4432 } 4433 } 4434 4435 @Override 4436 public void finishVoiceTask(IVoiceInteractionSession session) { 4437 synchronized(this) { 4438 final long origId = Binder.clearCallingIdentity(); 4439 try { 4440 mStackSupervisor.finishVoiceTask(session); 4441 } finally { 4442 Binder.restoreCallingIdentity(origId); 4443 } 4444 } 4445 4446 } 4447 4448 @Override 4449 public boolean releaseActivityInstance(IBinder token) { 4450 synchronized(this) { 4451 final long origId = Binder.clearCallingIdentity(); 4452 try { 4453 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4454 if (r.task == null || r.task.stack == null) { 4455 return false; 4456 } 4457 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4458 } finally { 4459 Binder.restoreCallingIdentity(origId); 4460 } 4461 } 4462 } 4463 4464 @Override 4465 public void releaseSomeActivities(IApplicationThread appInt) { 4466 synchronized(this) { 4467 final long origId = Binder.clearCallingIdentity(); 4468 try { 4469 ProcessRecord app = getRecordForAppLocked(appInt); 4470 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4471 } finally { 4472 Binder.restoreCallingIdentity(origId); 4473 } 4474 } 4475 } 4476 4477 @Override 4478 public boolean willActivityBeVisible(IBinder token) { 4479 synchronized(this) { 4480 ActivityStack stack = ActivityRecord.getStackLocked(token); 4481 if (stack != null) { 4482 return stack.willActivityBeVisibleLocked(token); 4483 } 4484 return false; 4485 } 4486 } 4487 4488 @Override 4489 public void overridePendingTransition(IBinder token, String packageName, 4490 int enterAnim, int exitAnim) { 4491 synchronized(this) { 4492 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4493 if (self == null) { 4494 return; 4495 } 4496 4497 final long origId = Binder.clearCallingIdentity(); 4498 4499 if (self.state == ActivityState.RESUMED 4500 || self.state == ActivityState.PAUSING) { 4501 mWindowManager.overridePendingAppTransition(packageName, 4502 enterAnim, exitAnim, null); 4503 } 4504 4505 Binder.restoreCallingIdentity(origId); 4506 } 4507 } 4508 4509 /** 4510 * Main function for removing an existing process from the activity manager 4511 * as a result of that process going away. Clears out all connections 4512 * to the process. 4513 */ 4514 private final void handleAppDiedLocked(ProcessRecord app, 4515 boolean restarting, boolean allowRestart) { 4516 int pid = app.pid; 4517 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4518 if (!kept && !restarting) { 4519 removeLruProcessLocked(app); 4520 if (pid > 0) { 4521 ProcessList.remove(pid); 4522 } 4523 } 4524 4525 if (mProfileProc == app) { 4526 clearProfilerLocked(); 4527 } 4528 4529 // Remove this application's activities from active lists. 4530 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4531 4532 app.activities.clear(); 4533 4534 if (app.instrumentationClass != null) { 4535 Slog.w(TAG, "Crash of app " + app.processName 4536 + " running instrumentation " + app.instrumentationClass); 4537 Bundle info = new Bundle(); 4538 info.putString("shortMsg", "Process crashed."); 4539 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4540 } 4541 4542 if (!restarting) { 4543 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4544 // If there was nothing to resume, and we are not already 4545 // restarting this process, but there is a visible activity that 4546 // is hosted by the process... then make sure all visible 4547 // activities are running, taking care of restarting this 4548 // process. 4549 if (hasVisibleActivities) { 4550 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4551 } 4552 } 4553 } 4554 } 4555 4556 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4557 IBinder threadBinder = thread.asBinder(); 4558 // Find the application record. 4559 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4560 ProcessRecord rec = mLruProcesses.get(i); 4561 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4562 return i; 4563 } 4564 } 4565 return -1; 4566 } 4567 4568 final ProcessRecord getRecordForAppLocked( 4569 IApplicationThread thread) { 4570 if (thread == null) { 4571 return null; 4572 } 4573 4574 int appIndex = getLRURecordIndexForAppLocked(thread); 4575 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4576 } 4577 4578 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4579 // If there are no longer any background processes running, 4580 // and the app that died was not running instrumentation, 4581 // then tell everyone we are now low on memory. 4582 boolean haveBg = false; 4583 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4584 ProcessRecord rec = mLruProcesses.get(i); 4585 if (rec.thread != null 4586 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4587 haveBg = true; 4588 break; 4589 } 4590 } 4591 4592 if (!haveBg) { 4593 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4594 if (doReport) { 4595 long now = SystemClock.uptimeMillis(); 4596 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4597 doReport = false; 4598 } else { 4599 mLastMemUsageReportTime = now; 4600 } 4601 } 4602 final ArrayList<ProcessMemInfo> memInfos 4603 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4604 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4605 long now = SystemClock.uptimeMillis(); 4606 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4607 ProcessRecord rec = mLruProcesses.get(i); 4608 if (rec == dyingProc || rec.thread == null) { 4609 continue; 4610 } 4611 if (doReport) { 4612 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4613 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4614 } 4615 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4616 // The low memory report is overriding any current 4617 // state for a GC request. Make sure to do 4618 // heavy/important/visible/foreground processes first. 4619 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4620 rec.lastRequestedGc = 0; 4621 } else { 4622 rec.lastRequestedGc = rec.lastLowMemory; 4623 } 4624 rec.reportLowMemory = true; 4625 rec.lastLowMemory = now; 4626 mProcessesToGc.remove(rec); 4627 addProcessToGcListLocked(rec); 4628 } 4629 } 4630 if (doReport) { 4631 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4632 mHandler.sendMessage(msg); 4633 } 4634 scheduleAppGcsLocked(); 4635 } 4636 } 4637 4638 final void appDiedLocked(ProcessRecord app) { 4639 appDiedLocked(app, app.pid, app.thread); 4640 } 4641 4642 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4643 // First check if this ProcessRecord is actually active for the pid. 4644 synchronized (mPidsSelfLocked) { 4645 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4646 if (curProc != app) { 4647 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4648 return; 4649 } 4650 } 4651 4652 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4653 synchronized (stats) { 4654 stats.noteProcessDiedLocked(app.info.uid, pid); 4655 } 4656 4657 Process.killProcessQuiet(pid); 4658 Process.killProcessGroup(app.info.uid, pid); 4659 app.killed = true; 4660 4661 // Clean up already done if the process has been re-started. 4662 if (app.pid == pid && app.thread != null && 4663 app.thread.asBinder() == thread.asBinder()) { 4664 boolean doLowMem = app.instrumentationClass == null; 4665 boolean doOomAdj = doLowMem; 4666 if (!app.killedByAm) { 4667 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4668 + ") has died"); 4669 mAllowLowerMemLevel = true; 4670 } else { 4671 // Note that we always want to do oom adj to update our state with the 4672 // new number of procs. 4673 mAllowLowerMemLevel = false; 4674 doLowMem = false; 4675 } 4676 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4677 if (DEBUG_CLEANUP) Slog.v( 4678 TAG, "Dying app: " + app + ", pid: " + pid 4679 + ", thread: " + thread.asBinder()); 4680 handleAppDiedLocked(app, false, true); 4681 4682 if (doOomAdj) { 4683 updateOomAdjLocked(); 4684 } 4685 if (doLowMem) { 4686 doLowMemReportIfNeededLocked(app); 4687 } 4688 } else if (app.pid != pid) { 4689 // A new process has already been started. 4690 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4691 + ") has died and restarted (pid " + app.pid + ")."); 4692 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4693 } else if (DEBUG_PROCESSES) { 4694 Slog.d(TAG, "Received spurious death notification for thread " 4695 + thread.asBinder()); 4696 } 4697 } 4698 4699 /** 4700 * If a stack trace dump file is configured, dump process stack traces. 4701 * @param clearTraces causes the dump file to be erased prior to the new 4702 * traces being written, if true; when false, the new traces will be 4703 * appended to any existing file content. 4704 * @param firstPids of dalvik VM processes to dump stack traces for first 4705 * @param lastPids of dalvik VM processes to dump stack traces for last 4706 * @param nativeProcs optional list of native process names to dump stack crawls 4707 * @return file containing stack traces, or null if no dump file is configured 4708 */ 4709 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4710 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4711 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4712 if (tracesPath == null || tracesPath.length() == 0) { 4713 return null; 4714 } 4715 4716 File tracesFile = new File(tracesPath); 4717 try { 4718 File tracesDir = tracesFile.getParentFile(); 4719 if (!tracesDir.exists()) { 4720 tracesDir.mkdirs(); 4721 if (!SELinux.restorecon(tracesDir)) { 4722 return null; 4723 } 4724 } 4725 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4726 4727 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4728 tracesFile.createNewFile(); 4729 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4730 } catch (IOException e) { 4731 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4732 return null; 4733 } 4734 4735 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4736 return tracesFile; 4737 } 4738 4739 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4740 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4741 // Use a FileObserver to detect when traces finish writing. 4742 // The order of traces is considered important to maintain for legibility. 4743 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4744 @Override 4745 public synchronized void onEvent(int event, String path) { notify(); } 4746 }; 4747 4748 try { 4749 observer.startWatching(); 4750 4751 // First collect all of the stacks of the most important pids. 4752 if (firstPids != null) { 4753 try { 4754 int num = firstPids.size(); 4755 for (int i = 0; i < num; i++) { 4756 synchronized (observer) { 4757 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4758 observer.wait(200); // Wait for write-close, give up after 200msec 4759 } 4760 } 4761 } catch (InterruptedException e) { 4762 Slog.wtf(TAG, e); 4763 } 4764 } 4765 4766 // Next collect the stacks of the native pids 4767 if (nativeProcs != null) { 4768 int[] pids = Process.getPidsForCommands(nativeProcs); 4769 if (pids != null) { 4770 for (int pid : pids) { 4771 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4772 } 4773 } 4774 } 4775 4776 // Lastly, measure CPU usage. 4777 if (processCpuTracker != null) { 4778 processCpuTracker.init(); 4779 System.gc(); 4780 processCpuTracker.update(); 4781 try { 4782 synchronized (processCpuTracker) { 4783 processCpuTracker.wait(500); // measure over 1/2 second. 4784 } 4785 } catch (InterruptedException e) { 4786 } 4787 processCpuTracker.update(); 4788 4789 // We'll take the stack crawls of just the top apps using CPU. 4790 final int N = processCpuTracker.countWorkingStats(); 4791 int numProcs = 0; 4792 for (int i=0; i<N && numProcs<5; i++) { 4793 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4794 if (lastPids.indexOfKey(stats.pid) >= 0) { 4795 numProcs++; 4796 try { 4797 synchronized (observer) { 4798 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4799 observer.wait(200); // Wait for write-close, give up after 200msec 4800 } 4801 } catch (InterruptedException e) { 4802 Slog.wtf(TAG, e); 4803 } 4804 4805 } 4806 } 4807 } 4808 } finally { 4809 observer.stopWatching(); 4810 } 4811 } 4812 4813 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4814 if (true || IS_USER_BUILD) { 4815 return; 4816 } 4817 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4818 if (tracesPath == null || tracesPath.length() == 0) { 4819 return; 4820 } 4821 4822 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4823 StrictMode.allowThreadDiskWrites(); 4824 try { 4825 final File tracesFile = new File(tracesPath); 4826 final File tracesDir = tracesFile.getParentFile(); 4827 final File tracesTmp = new File(tracesDir, "__tmp__"); 4828 try { 4829 if (!tracesDir.exists()) { 4830 tracesDir.mkdirs(); 4831 if (!SELinux.restorecon(tracesDir.getPath())) { 4832 return; 4833 } 4834 } 4835 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4836 4837 if (tracesFile.exists()) { 4838 tracesTmp.delete(); 4839 tracesFile.renameTo(tracesTmp); 4840 } 4841 StringBuilder sb = new StringBuilder(); 4842 Time tobj = new Time(); 4843 tobj.set(System.currentTimeMillis()); 4844 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4845 sb.append(": "); 4846 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4847 sb.append(" since "); 4848 sb.append(msg); 4849 FileOutputStream fos = new FileOutputStream(tracesFile); 4850 fos.write(sb.toString().getBytes()); 4851 if (app == null) { 4852 fos.write("\n*** No application process!".getBytes()); 4853 } 4854 fos.close(); 4855 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4856 } catch (IOException e) { 4857 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4858 return; 4859 } 4860 4861 if (app != null) { 4862 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4863 firstPids.add(app.pid); 4864 dumpStackTraces(tracesPath, firstPids, null, null, null); 4865 } 4866 4867 File lastTracesFile = null; 4868 File curTracesFile = null; 4869 for (int i=9; i>=0; i--) { 4870 String name = String.format(Locale.US, "slow%02d.txt", i); 4871 curTracesFile = new File(tracesDir, name); 4872 if (curTracesFile.exists()) { 4873 if (lastTracesFile != null) { 4874 curTracesFile.renameTo(lastTracesFile); 4875 } else { 4876 curTracesFile.delete(); 4877 } 4878 } 4879 lastTracesFile = curTracesFile; 4880 } 4881 tracesFile.renameTo(curTracesFile); 4882 if (tracesTmp.exists()) { 4883 tracesTmp.renameTo(tracesFile); 4884 } 4885 } finally { 4886 StrictMode.setThreadPolicy(oldPolicy); 4887 } 4888 } 4889 4890 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4891 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4892 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4893 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4894 4895 if (mController != null) { 4896 try { 4897 // 0 == continue, -1 = kill process immediately 4898 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4899 if (res < 0 && app.pid != MY_PID) { 4900 app.kill("anr", true); 4901 } 4902 } catch (RemoteException e) { 4903 mController = null; 4904 Watchdog.getInstance().setActivityController(null); 4905 } 4906 } 4907 4908 long anrTime = SystemClock.uptimeMillis(); 4909 if (MONITOR_CPU_USAGE) { 4910 updateCpuStatsNow(); 4911 } 4912 4913 synchronized (this) { 4914 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4915 if (mShuttingDown) { 4916 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4917 return; 4918 } else if (app.notResponding) { 4919 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4920 return; 4921 } else if (app.crashing) { 4922 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4923 return; 4924 } 4925 4926 // In case we come through here for the same app before completing 4927 // this one, mark as anring now so we will bail out. 4928 app.notResponding = true; 4929 4930 // Log the ANR to the event log. 4931 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4932 app.processName, app.info.flags, annotation); 4933 4934 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4935 firstPids.add(app.pid); 4936 4937 int parentPid = app.pid; 4938 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4939 if (parentPid != app.pid) firstPids.add(parentPid); 4940 4941 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4942 4943 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4944 ProcessRecord r = mLruProcesses.get(i); 4945 if (r != null && r.thread != null) { 4946 int pid = r.pid; 4947 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4948 if (r.persistent) { 4949 firstPids.add(pid); 4950 } else { 4951 lastPids.put(pid, Boolean.TRUE); 4952 } 4953 } 4954 } 4955 } 4956 } 4957 4958 // Log the ANR to the main log. 4959 StringBuilder info = new StringBuilder(); 4960 info.setLength(0); 4961 info.append("ANR in ").append(app.processName); 4962 if (activity != null && activity.shortComponentName != null) { 4963 info.append(" (").append(activity.shortComponentName).append(")"); 4964 } 4965 info.append("\n"); 4966 info.append("PID: ").append(app.pid).append("\n"); 4967 if (annotation != null) { 4968 info.append("Reason: ").append(annotation).append("\n"); 4969 } 4970 if (parent != null && parent != activity) { 4971 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4972 } 4973 4974 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4975 4976 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4977 NATIVE_STACKS_OF_INTEREST); 4978 4979 String cpuInfo = null; 4980 if (MONITOR_CPU_USAGE) { 4981 updateCpuStatsNow(); 4982 synchronized (mProcessCpuTracker) { 4983 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4984 } 4985 info.append(processCpuTracker.printCurrentLoad()); 4986 info.append(cpuInfo); 4987 } 4988 4989 info.append(processCpuTracker.printCurrentState(anrTime)); 4990 4991 Slog.e(TAG, info.toString()); 4992 if (tracesFile == null) { 4993 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4994 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4995 } 4996 4997 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4998 cpuInfo, tracesFile, null); 4999 5000 if (mController != null) { 5001 try { 5002 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5003 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5004 if (res != 0) { 5005 if (res < 0 && app.pid != MY_PID) { 5006 app.kill("anr", true); 5007 } else { 5008 synchronized (this) { 5009 mServices.scheduleServiceTimeoutLocked(app); 5010 } 5011 } 5012 return; 5013 } 5014 } catch (RemoteException e) { 5015 mController = null; 5016 Watchdog.getInstance().setActivityController(null); 5017 } 5018 } 5019 5020 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5021 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5022 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5023 5024 synchronized (this) { 5025 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5026 app.kill("bg anr", true); 5027 return; 5028 } 5029 5030 // Set the app's notResponding state, and look up the errorReportReceiver 5031 makeAppNotRespondingLocked(app, 5032 activity != null ? activity.shortComponentName : null, 5033 annotation != null ? "ANR " + annotation : "ANR", 5034 info.toString()); 5035 5036 // Bring up the infamous App Not Responding dialog 5037 Message msg = Message.obtain(); 5038 HashMap<String, Object> map = new HashMap<String, Object>(); 5039 msg.what = SHOW_NOT_RESPONDING_MSG; 5040 msg.obj = map; 5041 msg.arg1 = aboveSystem ? 1 : 0; 5042 map.put("app", app); 5043 if (activity != null) { 5044 map.put("activity", activity); 5045 } 5046 5047 mHandler.sendMessage(msg); 5048 } 5049 } 5050 5051 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5052 if (!mLaunchWarningShown) { 5053 mLaunchWarningShown = true; 5054 mHandler.post(new Runnable() { 5055 @Override 5056 public void run() { 5057 synchronized (ActivityManagerService.this) { 5058 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5059 d.show(); 5060 mHandler.postDelayed(new Runnable() { 5061 @Override 5062 public void run() { 5063 synchronized (ActivityManagerService.this) { 5064 d.dismiss(); 5065 mLaunchWarningShown = false; 5066 } 5067 } 5068 }, 4000); 5069 } 5070 } 5071 }); 5072 } 5073 } 5074 5075 @Override 5076 public boolean clearApplicationUserData(final String packageName, 5077 final IPackageDataObserver observer, int userId) { 5078 enforceNotIsolatedCaller("clearApplicationUserData"); 5079 int uid = Binder.getCallingUid(); 5080 int pid = Binder.getCallingPid(); 5081 userId = handleIncomingUser(pid, uid, 5082 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5083 long callingId = Binder.clearCallingIdentity(); 5084 try { 5085 IPackageManager pm = AppGlobals.getPackageManager(); 5086 int pkgUid = -1; 5087 synchronized(this) { 5088 try { 5089 pkgUid = pm.getPackageUid(packageName, userId); 5090 } catch (RemoteException e) { 5091 } 5092 if (pkgUid == -1) { 5093 Slog.w(TAG, "Invalid packageName: " + packageName); 5094 if (observer != null) { 5095 try { 5096 observer.onRemoveCompleted(packageName, false); 5097 } catch (RemoteException e) { 5098 Slog.i(TAG, "Observer no longer exists."); 5099 } 5100 } 5101 return false; 5102 } 5103 if (uid == pkgUid || checkComponentPermission( 5104 android.Manifest.permission.CLEAR_APP_USER_DATA, 5105 pid, uid, -1, true) 5106 == PackageManager.PERMISSION_GRANTED) { 5107 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5108 } else { 5109 throw new SecurityException("PID " + pid + " does not have permission " 5110 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5111 + " of package " + packageName); 5112 } 5113 5114 // Remove all tasks match the cleared application package and user 5115 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5116 final TaskRecord tr = mRecentTasks.get(i); 5117 final String taskPackageName = 5118 tr.getBaseIntent().getComponent().getPackageName(); 5119 if (tr.userId != userId) continue; 5120 if (!taskPackageName.equals(packageName)) continue; 5121 removeTaskByIdLocked(tr.taskId, false); 5122 } 5123 } 5124 5125 try { 5126 // Clear application user data 5127 pm.clearApplicationUserData(packageName, observer, userId); 5128 5129 synchronized(this) { 5130 // Remove all permissions granted from/to this package 5131 removeUriPermissionsForPackageLocked(packageName, userId, true); 5132 } 5133 5134 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5135 Uri.fromParts("package", packageName, null)); 5136 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5137 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5138 null, null, 0, null, null, null, false, false, userId); 5139 } catch (RemoteException e) { 5140 } 5141 } finally { 5142 Binder.restoreCallingIdentity(callingId); 5143 } 5144 return true; 5145 } 5146 5147 @Override 5148 public void killBackgroundProcesses(final String packageName, int userId) { 5149 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5150 != PackageManager.PERMISSION_GRANTED && 5151 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5152 != PackageManager.PERMISSION_GRANTED) { 5153 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5154 + Binder.getCallingPid() 5155 + ", uid=" + Binder.getCallingUid() 5156 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5157 Slog.w(TAG, msg); 5158 throw new SecurityException(msg); 5159 } 5160 5161 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5162 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5163 long callingId = Binder.clearCallingIdentity(); 5164 try { 5165 IPackageManager pm = AppGlobals.getPackageManager(); 5166 synchronized(this) { 5167 int appId = -1; 5168 try { 5169 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5170 } catch (RemoteException e) { 5171 } 5172 if (appId == -1) { 5173 Slog.w(TAG, "Invalid packageName: " + packageName); 5174 return; 5175 } 5176 killPackageProcessesLocked(packageName, appId, userId, 5177 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5178 } 5179 } finally { 5180 Binder.restoreCallingIdentity(callingId); 5181 } 5182 } 5183 5184 @Override 5185 public void killAllBackgroundProcesses() { 5186 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5187 != PackageManager.PERMISSION_GRANTED) { 5188 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5189 + Binder.getCallingPid() 5190 + ", uid=" + Binder.getCallingUid() 5191 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5192 Slog.w(TAG, msg); 5193 throw new SecurityException(msg); 5194 } 5195 5196 long callingId = Binder.clearCallingIdentity(); 5197 try { 5198 synchronized(this) { 5199 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5200 final int NP = mProcessNames.getMap().size(); 5201 for (int ip=0; ip<NP; ip++) { 5202 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5203 final int NA = apps.size(); 5204 for (int ia=0; ia<NA; ia++) { 5205 ProcessRecord app = apps.valueAt(ia); 5206 if (app.persistent) { 5207 // we don't kill persistent processes 5208 continue; 5209 } 5210 if (app.removed) { 5211 procs.add(app); 5212 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5213 app.removed = true; 5214 procs.add(app); 5215 } 5216 } 5217 } 5218 5219 int N = procs.size(); 5220 for (int i=0; i<N; i++) { 5221 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5222 } 5223 mAllowLowerMemLevel = true; 5224 updateOomAdjLocked(); 5225 doLowMemReportIfNeededLocked(null); 5226 } 5227 } finally { 5228 Binder.restoreCallingIdentity(callingId); 5229 } 5230 } 5231 5232 @Override 5233 public void forceStopPackage(final String packageName, int userId) { 5234 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5235 != PackageManager.PERMISSION_GRANTED) { 5236 String msg = "Permission Denial: forceStopPackage() from pid=" 5237 + Binder.getCallingPid() 5238 + ", uid=" + Binder.getCallingUid() 5239 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5240 Slog.w(TAG, msg); 5241 throw new SecurityException(msg); 5242 } 5243 final int callingPid = Binder.getCallingPid(); 5244 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5245 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5246 long callingId = Binder.clearCallingIdentity(); 5247 try { 5248 IPackageManager pm = AppGlobals.getPackageManager(); 5249 synchronized(this) { 5250 int[] users = userId == UserHandle.USER_ALL 5251 ? getUsersLocked() : new int[] { userId }; 5252 for (int user : users) { 5253 int pkgUid = -1; 5254 try { 5255 pkgUid = pm.getPackageUid(packageName, user); 5256 } catch (RemoteException e) { 5257 } 5258 if (pkgUid == -1) { 5259 Slog.w(TAG, "Invalid packageName: " + packageName); 5260 continue; 5261 } 5262 try { 5263 pm.setPackageStoppedState(packageName, true, user); 5264 } catch (RemoteException e) { 5265 } catch (IllegalArgumentException e) { 5266 Slog.w(TAG, "Failed trying to unstop package " 5267 + packageName + ": " + e); 5268 } 5269 if (isUserRunningLocked(user, false)) { 5270 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5271 } 5272 } 5273 } 5274 } finally { 5275 Binder.restoreCallingIdentity(callingId); 5276 } 5277 } 5278 5279 @Override 5280 public void addPackageDependency(String packageName) { 5281 synchronized (this) { 5282 int callingPid = Binder.getCallingPid(); 5283 if (callingPid == Process.myPid()) { 5284 // Yeah, um, no. 5285 Slog.w(TAG, "Can't addPackageDependency on system process"); 5286 return; 5287 } 5288 ProcessRecord proc; 5289 synchronized (mPidsSelfLocked) { 5290 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5291 } 5292 if (proc != null) { 5293 if (proc.pkgDeps == null) { 5294 proc.pkgDeps = new ArraySet<String>(1); 5295 } 5296 proc.pkgDeps.add(packageName); 5297 } 5298 } 5299 } 5300 5301 /* 5302 * The pkg name and app id have to be specified. 5303 */ 5304 @Override 5305 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5306 if (pkg == null) { 5307 return; 5308 } 5309 // Make sure the uid is valid. 5310 if (appid < 0) { 5311 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5312 return; 5313 } 5314 int callerUid = Binder.getCallingUid(); 5315 // Only the system server can kill an application 5316 if (callerUid == Process.SYSTEM_UID) { 5317 // Post an aysnc message to kill the application 5318 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5319 msg.arg1 = appid; 5320 msg.arg2 = 0; 5321 Bundle bundle = new Bundle(); 5322 bundle.putString("pkg", pkg); 5323 bundle.putString("reason", reason); 5324 msg.obj = bundle; 5325 mHandler.sendMessage(msg); 5326 } else { 5327 throw new SecurityException(callerUid + " cannot kill pkg: " + 5328 pkg); 5329 } 5330 } 5331 5332 @Override 5333 public void closeSystemDialogs(String reason) { 5334 enforceNotIsolatedCaller("closeSystemDialogs"); 5335 5336 final int pid = Binder.getCallingPid(); 5337 final int uid = Binder.getCallingUid(); 5338 final long origId = Binder.clearCallingIdentity(); 5339 try { 5340 synchronized (this) { 5341 // Only allow this from foreground processes, so that background 5342 // applications can't abuse it to prevent system UI from being shown. 5343 if (uid >= Process.FIRST_APPLICATION_UID) { 5344 ProcessRecord proc; 5345 synchronized (mPidsSelfLocked) { 5346 proc = mPidsSelfLocked.get(pid); 5347 } 5348 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5349 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5350 + " from background process " + proc); 5351 return; 5352 } 5353 } 5354 closeSystemDialogsLocked(reason); 5355 } 5356 } finally { 5357 Binder.restoreCallingIdentity(origId); 5358 } 5359 } 5360 5361 void closeSystemDialogsLocked(String reason) { 5362 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5363 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5364 | Intent.FLAG_RECEIVER_FOREGROUND); 5365 if (reason != null) { 5366 intent.putExtra("reason", reason); 5367 } 5368 mWindowManager.closeSystemDialogs(reason); 5369 5370 mStackSupervisor.closeSystemDialogsLocked(); 5371 5372 broadcastIntentLocked(null, null, intent, null, 5373 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5374 Process.SYSTEM_UID, UserHandle.USER_ALL); 5375 } 5376 5377 @Override 5378 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5379 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5380 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5381 for (int i=pids.length-1; i>=0; i--) { 5382 ProcessRecord proc; 5383 int oomAdj; 5384 synchronized (this) { 5385 synchronized (mPidsSelfLocked) { 5386 proc = mPidsSelfLocked.get(pids[i]); 5387 oomAdj = proc != null ? proc.setAdj : 0; 5388 } 5389 } 5390 infos[i] = new Debug.MemoryInfo(); 5391 Debug.getMemoryInfo(pids[i], infos[i]); 5392 if (proc != null) { 5393 synchronized (this) { 5394 if (proc.thread != null && proc.setAdj == oomAdj) { 5395 // Record this for posterity if the process has been stable. 5396 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5397 infos[i].getTotalUss(), false, proc.pkgList); 5398 } 5399 } 5400 } 5401 } 5402 return infos; 5403 } 5404 5405 @Override 5406 public long[] getProcessPss(int[] pids) { 5407 enforceNotIsolatedCaller("getProcessPss"); 5408 long[] pss = new long[pids.length]; 5409 for (int i=pids.length-1; i>=0; i--) { 5410 ProcessRecord proc; 5411 int oomAdj; 5412 synchronized (this) { 5413 synchronized (mPidsSelfLocked) { 5414 proc = mPidsSelfLocked.get(pids[i]); 5415 oomAdj = proc != null ? proc.setAdj : 0; 5416 } 5417 } 5418 long[] tmpUss = new long[1]; 5419 pss[i] = Debug.getPss(pids[i], tmpUss); 5420 if (proc != null) { 5421 synchronized (this) { 5422 if (proc.thread != null && proc.setAdj == oomAdj) { 5423 // Record this for posterity if the process has been stable. 5424 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5425 } 5426 } 5427 } 5428 } 5429 return pss; 5430 } 5431 5432 @Override 5433 public void killApplicationProcess(String processName, int uid) { 5434 if (processName == null) { 5435 return; 5436 } 5437 5438 int callerUid = Binder.getCallingUid(); 5439 // Only the system server can kill an application 5440 if (callerUid == Process.SYSTEM_UID) { 5441 synchronized (this) { 5442 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5443 if (app != null && app.thread != null) { 5444 try { 5445 app.thread.scheduleSuicide(); 5446 } catch (RemoteException e) { 5447 // If the other end already died, then our work here is done. 5448 } 5449 } else { 5450 Slog.w(TAG, "Process/uid not found attempting kill of " 5451 + processName + " / " + uid); 5452 } 5453 } 5454 } else { 5455 throw new SecurityException(callerUid + " cannot kill app process: " + 5456 processName); 5457 } 5458 } 5459 5460 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5461 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5462 false, true, false, false, UserHandle.getUserId(uid), reason); 5463 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5464 Uri.fromParts("package", packageName, null)); 5465 if (!mProcessesReady) { 5466 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5467 | Intent.FLAG_RECEIVER_FOREGROUND); 5468 } 5469 intent.putExtra(Intent.EXTRA_UID, uid); 5470 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5471 broadcastIntentLocked(null, null, intent, 5472 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5473 false, false, 5474 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5475 } 5476 5477 private void forceStopUserLocked(int userId, String reason) { 5478 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5479 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5480 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5481 | Intent.FLAG_RECEIVER_FOREGROUND); 5482 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5483 broadcastIntentLocked(null, null, intent, 5484 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5485 false, false, 5486 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5487 } 5488 5489 private final boolean killPackageProcessesLocked(String packageName, int appId, 5490 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5491 boolean doit, boolean evenPersistent, String reason) { 5492 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5493 5494 // Remove all processes this package may have touched: all with the 5495 // same UID (except for the system or root user), and all whose name 5496 // matches the package name. 5497 final int NP = mProcessNames.getMap().size(); 5498 for (int ip=0; ip<NP; ip++) { 5499 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5500 final int NA = apps.size(); 5501 for (int ia=0; ia<NA; ia++) { 5502 ProcessRecord app = apps.valueAt(ia); 5503 if (app.persistent && !evenPersistent) { 5504 // we don't kill persistent processes 5505 continue; 5506 } 5507 if (app.removed) { 5508 if (doit) { 5509 procs.add(app); 5510 } 5511 continue; 5512 } 5513 5514 // Skip process if it doesn't meet our oom adj requirement. 5515 if (app.setAdj < minOomAdj) { 5516 continue; 5517 } 5518 5519 // If no package is specified, we call all processes under the 5520 // give user id. 5521 if (packageName == null) { 5522 if (app.userId != userId) { 5523 continue; 5524 } 5525 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5526 continue; 5527 } 5528 // Package has been specified, we want to hit all processes 5529 // that match it. We need to qualify this by the processes 5530 // that are running under the specified app and user ID. 5531 } else { 5532 final boolean isDep = app.pkgDeps != null 5533 && app.pkgDeps.contains(packageName); 5534 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5535 continue; 5536 } 5537 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5538 continue; 5539 } 5540 if (!app.pkgList.containsKey(packageName) && !isDep) { 5541 continue; 5542 } 5543 } 5544 5545 // Process has passed all conditions, kill it! 5546 if (!doit) { 5547 return true; 5548 } 5549 app.removed = true; 5550 procs.add(app); 5551 } 5552 } 5553 5554 int N = procs.size(); 5555 for (int i=0; i<N; i++) { 5556 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5557 } 5558 updateOomAdjLocked(); 5559 return N > 0; 5560 } 5561 5562 private final boolean forceStopPackageLocked(String name, int appId, 5563 boolean callerWillRestart, boolean purgeCache, boolean doit, 5564 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5565 int i; 5566 int N; 5567 5568 if (userId == UserHandle.USER_ALL && name == null) { 5569 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5570 } 5571 5572 if (appId < 0 && name != null) { 5573 try { 5574 appId = UserHandle.getAppId( 5575 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5576 } catch (RemoteException e) { 5577 } 5578 } 5579 5580 if (doit) { 5581 if (name != null) { 5582 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5583 + " user=" + userId + ": " + reason); 5584 } else { 5585 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5586 } 5587 5588 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5589 for (int ip=pmap.size()-1; ip>=0; ip--) { 5590 SparseArray<Long> ba = pmap.valueAt(ip); 5591 for (i=ba.size()-1; i>=0; i--) { 5592 boolean remove = false; 5593 final int entUid = ba.keyAt(i); 5594 if (name != null) { 5595 if (userId == UserHandle.USER_ALL) { 5596 if (UserHandle.getAppId(entUid) == appId) { 5597 remove = true; 5598 } 5599 } else { 5600 if (entUid == UserHandle.getUid(userId, appId)) { 5601 remove = true; 5602 } 5603 } 5604 } else if (UserHandle.getUserId(entUid) == userId) { 5605 remove = true; 5606 } 5607 if (remove) { 5608 ba.removeAt(i); 5609 } 5610 } 5611 if (ba.size() == 0) { 5612 pmap.removeAt(ip); 5613 } 5614 } 5615 } 5616 5617 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5618 -100, callerWillRestart, true, doit, evenPersistent, 5619 name == null ? ("stop user " + userId) : ("stop " + name)); 5620 5621 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5622 if (!doit) { 5623 return true; 5624 } 5625 didSomething = true; 5626 } 5627 5628 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5629 if (!doit) { 5630 return true; 5631 } 5632 didSomething = true; 5633 } 5634 5635 if (name == null) { 5636 // Remove all sticky broadcasts from this user. 5637 mStickyBroadcasts.remove(userId); 5638 } 5639 5640 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5641 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5642 userId, providers)) { 5643 if (!doit) { 5644 return true; 5645 } 5646 didSomething = true; 5647 } 5648 N = providers.size(); 5649 for (i=0; i<N; i++) { 5650 removeDyingProviderLocked(null, providers.get(i), true); 5651 } 5652 5653 // Remove transient permissions granted from/to this package/user 5654 removeUriPermissionsForPackageLocked(name, userId, false); 5655 5656 if (name == null || uninstalling) { 5657 // Remove pending intents. For now we only do this when force 5658 // stopping users, because we have some problems when doing this 5659 // for packages -- app widgets are not currently cleaned up for 5660 // such packages, so they can be left with bad pending intents. 5661 if (mIntentSenderRecords.size() > 0) { 5662 Iterator<WeakReference<PendingIntentRecord>> it 5663 = mIntentSenderRecords.values().iterator(); 5664 while (it.hasNext()) { 5665 WeakReference<PendingIntentRecord> wpir = it.next(); 5666 if (wpir == null) { 5667 it.remove(); 5668 continue; 5669 } 5670 PendingIntentRecord pir = wpir.get(); 5671 if (pir == null) { 5672 it.remove(); 5673 continue; 5674 } 5675 if (name == null) { 5676 // Stopping user, remove all objects for the user. 5677 if (pir.key.userId != userId) { 5678 // Not the same user, skip it. 5679 continue; 5680 } 5681 } else { 5682 if (UserHandle.getAppId(pir.uid) != appId) { 5683 // Different app id, skip it. 5684 continue; 5685 } 5686 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5687 // Different user, skip it. 5688 continue; 5689 } 5690 if (!pir.key.packageName.equals(name)) { 5691 // Different package, skip it. 5692 continue; 5693 } 5694 } 5695 if (!doit) { 5696 return true; 5697 } 5698 didSomething = true; 5699 it.remove(); 5700 pir.canceled = true; 5701 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5702 pir.key.activity.pendingResults.remove(pir.ref); 5703 } 5704 } 5705 } 5706 } 5707 5708 if (doit) { 5709 if (purgeCache && name != null) { 5710 AttributeCache ac = AttributeCache.instance(); 5711 if (ac != null) { 5712 ac.removePackage(name); 5713 } 5714 } 5715 if (mBooted) { 5716 mStackSupervisor.resumeTopActivitiesLocked(); 5717 mStackSupervisor.scheduleIdleLocked(); 5718 } 5719 } 5720 5721 return didSomething; 5722 } 5723 5724 private final boolean removeProcessLocked(ProcessRecord app, 5725 boolean callerWillRestart, boolean allowRestart, String reason) { 5726 final String name = app.processName; 5727 final int uid = app.uid; 5728 if (DEBUG_PROCESSES) Slog.d( 5729 TAG, "Force removing proc " + app.toShortString() + " (" + name 5730 + "/" + uid + ")"); 5731 5732 mProcessNames.remove(name, uid); 5733 mIsolatedProcesses.remove(app.uid); 5734 if (mHeavyWeightProcess == app) { 5735 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5736 mHeavyWeightProcess.userId, 0)); 5737 mHeavyWeightProcess = null; 5738 } 5739 boolean needRestart = false; 5740 if (app.pid > 0 && app.pid != MY_PID) { 5741 int pid = app.pid; 5742 synchronized (mPidsSelfLocked) { 5743 mPidsSelfLocked.remove(pid); 5744 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5745 } 5746 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5747 if (app.isolated) { 5748 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5749 } 5750 app.kill(reason, true); 5751 handleAppDiedLocked(app, true, allowRestart); 5752 removeLruProcessLocked(app); 5753 5754 if (app.persistent && !app.isolated) { 5755 if (!callerWillRestart) { 5756 addAppLocked(app.info, false, null /* ABI override */); 5757 } else { 5758 needRestart = true; 5759 } 5760 } 5761 } else { 5762 mRemovedProcesses.add(app); 5763 } 5764 5765 return needRestart; 5766 } 5767 5768 private final void processStartTimedOutLocked(ProcessRecord app) { 5769 final int pid = app.pid; 5770 boolean gone = false; 5771 synchronized (mPidsSelfLocked) { 5772 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5773 if (knownApp != null && knownApp.thread == null) { 5774 mPidsSelfLocked.remove(pid); 5775 gone = true; 5776 } 5777 } 5778 5779 if (gone) { 5780 Slog.w(TAG, "Process " + app + " failed to attach"); 5781 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5782 pid, app.uid, app.processName); 5783 mProcessNames.remove(app.processName, app.uid); 5784 mIsolatedProcesses.remove(app.uid); 5785 if (mHeavyWeightProcess == app) { 5786 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5787 mHeavyWeightProcess.userId, 0)); 5788 mHeavyWeightProcess = null; 5789 } 5790 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5791 if (app.isolated) { 5792 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5793 } 5794 // Take care of any launching providers waiting for this process. 5795 checkAppInLaunchingProvidersLocked(app, true); 5796 // Take care of any services that are waiting for the process. 5797 mServices.processStartTimedOutLocked(app); 5798 app.kill("start timeout", true); 5799 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5800 Slog.w(TAG, "Unattached app died before backup, skipping"); 5801 try { 5802 IBackupManager bm = IBackupManager.Stub.asInterface( 5803 ServiceManager.getService(Context.BACKUP_SERVICE)); 5804 bm.agentDisconnected(app.info.packageName); 5805 } catch (RemoteException e) { 5806 // Can't happen; the backup manager is local 5807 } 5808 } 5809 if (isPendingBroadcastProcessLocked(pid)) { 5810 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5811 skipPendingBroadcastLocked(pid); 5812 } 5813 } else { 5814 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5815 } 5816 } 5817 5818 private final boolean attachApplicationLocked(IApplicationThread thread, 5819 int pid) { 5820 5821 // Find the application record that is being attached... either via 5822 // the pid if we are running in multiple processes, or just pull the 5823 // next app record if we are emulating process with anonymous threads. 5824 ProcessRecord app; 5825 if (pid != MY_PID && pid >= 0) { 5826 synchronized (mPidsSelfLocked) { 5827 app = mPidsSelfLocked.get(pid); 5828 } 5829 } else { 5830 app = null; 5831 } 5832 5833 if (app == null) { 5834 Slog.w(TAG, "No pending application record for pid " + pid 5835 + " (IApplicationThread " + thread + "); dropping process"); 5836 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5837 if (pid > 0 && pid != MY_PID) { 5838 Process.killProcessQuiet(pid); 5839 //TODO: Process.killProcessGroup(app.info.uid, pid); 5840 } else { 5841 try { 5842 thread.scheduleExit(); 5843 } catch (Exception e) { 5844 // Ignore exceptions. 5845 } 5846 } 5847 return false; 5848 } 5849 5850 // If this application record is still attached to a previous 5851 // process, clean it up now. 5852 if (app.thread != null) { 5853 handleAppDiedLocked(app, true, true); 5854 } 5855 5856 // Tell the process all about itself. 5857 5858 if (localLOGV) Slog.v( 5859 TAG, "Binding process pid " + pid + " to record " + app); 5860 5861 final String processName = app.processName; 5862 try { 5863 AppDeathRecipient adr = new AppDeathRecipient( 5864 app, pid, thread); 5865 thread.asBinder().linkToDeath(adr, 0); 5866 app.deathRecipient = adr; 5867 } catch (RemoteException e) { 5868 app.resetPackageList(mProcessStats); 5869 startProcessLocked(app, "link fail", processName); 5870 return false; 5871 } 5872 5873 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5874 5875 app.makeActive(thread, mProcessStats); 5876 app.curAdj = app.setAdj = -100; 5877 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5878 app.forcingToForeground = null; 5879 updateProcessForegroundLocked(app, false, false); 5880 app.hasShownUi = false; 5881 app.debugging = false; 5882 app.cached = false; 5883 5884 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5885 5886 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5887 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5888 5889 if (!normalMode) { 5890 Slog.i(TAG, "Launching preboot mode app: " + app); 5891 } 5892 5893 if (localLOGV) Slog.v( 5894 TAG, "New app record " + app 5895 + " thread=" + thread.asBinder() + " pid=" + pid); 5896 try { 5897 int testMode = IApplicationThread.DEBUG_OFF; 5898 if (mDebugApp != null && mDebugApp.equals(processName)) { 5899 testMode = mWaitForDebugger 5900 ? IApplicationThread.DEBUG_WAIT 5901 : IApplicationThread.DEBUG_ON; 5902 app.debugging = true; 5903 if (mDebugTransient) { 5904 mDebugApp = mOrigDebugApp; 5905 mWaitForDebugger = mOrigWaitForDebugger; 5906 } 5907 } 5908 String profileFile = app.instrumentationProfileFile; 5909 ParcelFileDescriptor profileFd = null; 5910 int samplingInterval = 0; 5911 boolean profileAutoStop = false; 5912 if (mProfileApp != null && mProfileApp.equals(processName)) { 5913 mProfileProc = app; 5914 profileFile = mProfileFile; 5915 profileFd = mProfileFd; 5916 samplingInterval = mSamplingInterval; 5917 profileAutoStop = mAutoStopProfiler; 5918 } 5919 boolean enableOpenGlTrace = false; 5920 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5921 enableOpenGlTrace = true; 5922 mOpenGlTraceApp = null; 5923 } 5924 5925 // If the app is being launched for restore or full backup, set it up specially 5926 boolean isRestrictedBackupMode = false; 5927 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5928 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5929 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5930 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5931 } 5932 5933 ensurePackageDexOpt(app.instrumentationInfo != null 5934 ? app.instrumentationInfo.packageName 5935 : app.info.packageName); 5936 if (app.instrumentationClass != null) { 5937 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5938 } 5939 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5940 + processName + " with config " + mConfiguration); 5941 ApplicationInfo appInfo = app.instrumentationInfo != null 5942 ? app.instrumentationInfo : app.info; 5943 app.compat = compatibilityInfoForPackageLocked(appInfo); 5944 if (profileFd != null) { 5945 profileFd = profileFd.dup(); 5946 } 5947 ProfilerInfo profilerInfo = profileFile == null ? null 5948 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5949 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5950 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5951 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5952 isRestrictedBackupMode || !normalMode, app.persistent, 5953 new Configuration(mConfiguration), app.compat, 5954 getCommonServicesLocked(app.isolated), 5955 mCoreSettingsObserver.getCoreSettingsLocked()); 5956 updateLruProcessLocked(app, false, null); 5957 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5958 } catch (Exception e) { 5959 // todo: Yikes! What should we do? For now we will try to 5960 // start another process, but that could easily get us in 5961 // an infinite loop of restarting processes... 5962 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 5963 5964 app.resetPackageList(mProcessStats); 5965 app.unlinkDeathRecipient(); 5966 startProcessLocked(app, "bind fail", processName); 5967 return false; 5968 } 5969 5970 // Remove this record from the list of starting applications. 5971 mPersistentStartingProcesses.remove(app); 5972 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5973 "Attach application locked removing on hold: " + app); 5974 mProcessesOnHold.remove(app); 5975 5976 boolean badApp = false; 5977 boolean didSomething = false; 5978 5979 // See if the top visible activity is waiting to run in this process... 5980 if (normalMode) { 5981 try { 5982 if (mStackSupervisor.attachApplicationLocked(app)) { 5983 didSomething = true; 5984 } 5985 } catch (Exception e) { 5986 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 5987 badApp = true; 5988 } 5989 } 5990 5991 // Find any services that should be running in this process... 5992 if (!badApp) { 5993 try { 5994 didSomething |= mServices.attachApplicationLocked(app, processName); 5995 } catch (Exception e) { 5996 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 5997 badApp = true; 5998 } 5999 } 6000 6001 // Check if a next-broadcast receiver is in this process... 6002 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6003 try { 6004 didSomething |= sendPendingBroadcastsLocked(app); 6005 } catch (Exception e) { 6006 // If the app died trying to launch the receiver we declare it 'bad' 6007 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6008 badApp = true; 6009 } 6010 } 6011 6012 // Check whether the next backup agent is in this process... 6013 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6014 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6015 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6016 try { 6017 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6018 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6019 mBackupTarget.backupMode); 6020 } catch (Exception e) { 6021 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6022 badApp = true; 6023 } 6024 } 6025 6026 if (badApp) { 6027 app.kill("error during init", true); 6028 handleAppDiedLocked(app, false, true); 6029 return false; 6030 } 6031 6032 if (!didSomething) { 6033 updateOomAdjLocked(); 6034 } 6035 6036 return true; 6037 } 6038 6039 @Override 6040 public final void attachApplication(IApplicationThread thread) { 6041 synchronized (this) { 6042 int callingPid = Binder.getCallingPid(); 6043 final long origId = Binder.clearCallingIdentity(); 6044 attachApplicationLocked(thread, callingPid); 6045 Binder.restoreCallingIdentity(origId); 6046 } 6047 } 6048 6049 @Override 6050 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6051 final long origId = Binder.clearCallingIdentity(); 6052 synchronized (this) { 6053 ActivityStack stack = ActivityRecord.getStackLocked(token); 6054 if (stack != null) { 6055 ActivityRecord r = 6056 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6057 if (stopProfiling) { 6058 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6059 try { 6060 mProfileFd.close(); 6061 } catch (IOException e) { 6062 } 6063 clearProfilerLocked(); 6064 } 6065 } 6066 } 6067 } 6068 Binder.restoreCallingIdentity(origId); 6069 } 6070 6071 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6072 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6073 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6074 } 6075 6076 void enableScreenAfterBoot() { 6077 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6078 SystemClock.uptimeMillis()); 6079 mWindowManager.enableScreenAfterBoot(); 6080 6081 synchronized (this) { 6082 updateEventDispatchingLocked(); 6083 } 6084 } 6085 6086 @Override 6087 public void showBootMessage(final CharSequence msg, final boolean always) { 6088 enforceNotIsolatedCaller("showBootMessage"); 6089 mWindowManager.showBootMessage(msg, always); 6090 } 6091 6092 @Override 6093 public void keyguardWaitingForActivityDrawn() { 6094 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6095 final long token = Binder.clearCallingIdentity(); 6096 try { 6097 synchronized (this) { 6098 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6099 mWindowManager.keyguardWaitingForActivityDrawn(); 6100 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6101 mLockScreenShown = LOCK_SCREEN_LEAVING; 6102 updateSleepIfNeededLocked(); 6103 } 6104 } 6105 } finally { 6106 Binder.restoreCallingIdentity(token); 6107 } 6108 } 6109 6110 final void finishBooting() { 6111 synchronized (this) { 6112 if (!mBootAnimationComplete) { 6113 mCallFinishBooting = true; 6114 return; 6115 } 6116 mCallFinishBooting = false; 6117 } 6118 6119 ArraySet<String> completedIsas = new ArraySet<String>(); 6120 for (String abi : Build.SUPPORTED_ABIS) { 6121 Process.establishZygoteConnectionForAbi(abi); 6122 final String instructionSet = VMRuntime.getInstructionSet(abi); 6123 if (!completedIsas.contains(instructionSet)) { 6124 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6125 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6126 } 6127 completedIsas.add(instructionSet); 6128 } 6129 } 6130 6131 IntentFilter pkgFilter = new IntentFilter(); 6132 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6133 pkgFilter.addDataScheme("package"); 6134 mContext.registerReceiver(new BroadcastReceiver() { 6135 @Override 6136 public void onReceive(Context context, Intent intent) { 6137 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6138 if (pkgs != null) { 6139 for (String pkg : pkgs) { 6140 synchronized (ActivityManagerService.this) { 6141 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6142 0, "finished booting")) { 6143 setResultCode(Activity.RESULT_OK); 6144 return; 6145 } 6146 } 6147 } 6148 } 6149 } 6150 }, pkgFilter); 6151 6152 // Let system services know. 6153 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6154 6155 synchronized (this) { 6156 // Ensure that any processes we had put on hold are now started 6157 // up. 6158 final int NP = mProcessesOnHold.size(); 6159 if (NP > 0) { 6160 ArrayList<ProcessRecord> procs = 6161 new ArrayList<ProcessRecord>(mProcessesOnHold); 6162 for (int ip=0; ip<NP; ip++) { 6163 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6164 + procs.get(ip)); 6165 startProcessLocked(procs.get(ip), "on-hold", null); 6166 } 6167 } 6168 6169 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6170 // Start looking for apps that are abusing wake locks. 6171 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6172 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6173 // Tell anyone interested that we are done booting! 6174 SystemProperties.set("sys.boot_completed", "1"); 6175 6176 // And trigger dev.bootcomplete if we are not showing encryption progress 6177 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6178 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6179 SystemProperties.set("dev.bootcomplete", "1"); 6180 } 6181 for (int i=0; i<mStartedUsers.size(); i++) { 6182 UserStartedState uss = mStartedUsers.valueAt(i); 6183 if (uss.mState == UserStartedState.STATE_BOOTING) { 6184 uss.mState = UserStartedState.STATE_RUNNING; 6185 final int userId = mStartedUsers.keyAt(i); 6186 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6187 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6188 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6189 broadcastIntentLocked(null, null, intent, null, 6190 new IIntentReceiver.Stub() { 6191 @Override 6192 public void performReceive(Intent intent, int resultCode, 6193 String data, Bundle extras, boolean ordered, 6194 boolean sticky, int sendingUser) { 6195 synchronized (ActivityManagerService.this) { 6196 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6197 true, false); 6198 } 6199 } 6200 }, 6201 0, null, null, 6202 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6203 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6204 userId); 6205 } 6206 } 6207 scheduleStartProfilesLocked(); 6208 } 6209 } 6210 } 6211 6212 @Override 6213 public void bootAnimationComplete() { 6214 final boolean callFinishBooting; 6215 synchronized (this) { 6216 callFinishBooting = mCallFinishBooting; 6217 mBootAnimationComplete = true; 6218 } 6219 if (callFinishBooting) { 6220 finishBooting(); 6221 } 6222 } 6223 6224 final void ensureBootCompleted() { 6225 boolean booting; 6226 boolean enableScreen; 6227 synchronized (this) { 6228 booting = mBooting; 6229 mBooting = false; 6230 enableScreen = !mBooted; 6231 mBooted = true; 6232 } 6233 6234 if (booting) { 6235 finishBooting(); 6236 } 6237 6238 if (enableScreen) { 6239 enableScreenAfterBoot(); 6240 } 6241 } 6242 6243 @Override 6244 public final void activityResumed(IBinder token) { 6245 final long origId = Binder.clearCallingIdentity(); 6246 synchronized(this) { 6247 ActivityStack stack = ActivityRecord.getStackLocked(token); 6248 if (stack != null) { 6249 ActivityRecord.activityResumedLocked(token); 6250 } 6251 } 6252 Binder.restoreCallingIdentity(origId); 6253 } 6254 6255 @Override 6256 public final void activityPaused(IBinder token) { 6257 final long origId = Binder.clearCallingIdentity(); 6258 synchronized(this) { 6259 ActivityStack stack = ActivityRecord.getStackLocked(token); 6260 if (stack != null) { 6261 stack.activityPausedLocked(token, false); 6262 } 6263 } 6264 Binder.restoreCallingIdentity(origId); 6265 } 6266 6267 @Override 6268 public final void activityStopped(IBinder token, Bundle icicle, 6269 PersistableBundle persistentState, CharSequence description) { 6270 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6271 6272 // Refuse possible leaked file descriptors 6273 if (icicle != null && icicle.hasFileDescriptors()) { 6274 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6275 } 6276 6277 final long origId = Binder.clearCallingIdentity(); 6278 6279 synchronized (this) { 6280 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6281 if (r != null) { 6282 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6283 } 6284 } 6285 6286 trimApplications(); 6287 6288 Binder.restoreCallingIdentity(origId); 6289 } 6290 6291 @Override 6292 public final void activityDestroyed(IBinder token) { 6293 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6294 synchronized (this) { 6295 ActivityStack stack = ActivityRecord.getStackLocked(token); 6296 if (stack != null) { 6297 stack.activityDestroyedLocked(token); 6298 } 6299 } 6300 } 6301 6302 @Override 6303 public final void backgroundResourcesReleased(IBinder token) { 6304 final long origId = Binder.clearCallingIdentity(); 6305 try { 6306 synchronized (this) { 6307 ActivityStack stack = ActivityRecord.getStackLocked(token); 6308 if (stack != null) { 6309 stack.backgroundResourcesReleased(); 6310 } 6311 } 6312 } finally { 6313 Binder.restoreCallingIdentity(origId); 6314 } 6315 } 6316 6317 @Override 6318 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6319 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6320 } 6321 6322 @Override 6323 public final void notifyEnterAnimationComplete(IBinder token) { 6324 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6325 } 6326 6327 @Override 6328 public String getCallingPackage(IBinder token) { 6329 synchronized (this) { 6330 ActivityRecord r = getCallingRecordLocked(token); 6331 return r != null ? r.info.packageName : null; 6332 } 6333 } 6334 6335 @Override 6336 public ComponentName getCallingActivity(IBinder token) { 6337 synchronized (this) { 6338 ActivityRecord r = getCallingRecordLocked(token); 6339 return r != null ? r.intent.getComponent() : null; 6340 } 6341 } 6342 6343 private ActivityRecord getCallingRecordLocked(IBinder token) { 6344 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6345 if (r == null) { 6346 return null; 6347 } 6348 return r.resultTo; 6349 } 6350 6351 @Override 6352 public ComponentName getActivityClassForToken(IBinder token) { 6353 synchronized(this) { 6354 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6355 if (r == null) { 6356 return null; 6357 } 6358 return r.intent.getComponent(); 6359 } 6360 } 6361 6362 @Override 6363 public String getPackageForToken(IBinder token) { 6364 synchronized(this) { 6365 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6366 if (r == null) { 6367 return null; 6368 } 6369 return r.packageName; 6370 } 6371 } 6372 6373 @Override 6374 public IIntentSender getIntentSender(int type, 6375 String packageName, IBinder token, String resultWho, 6376 int requestCode, Intent[] intents, String[] resolvedTypes, 6377 int flags, Bundle options, int userId) { 6378 enforceNotIsolatedCaller("getIntentSender"); 6379 // Refuse possible leaked file descriptors 6380 if (intents != null) { 6381 if (intents.length < 1) { 6382 throw new IllegalArgumentException("Intents array length must be >= 1"); 6383 } 6384 for (int i=0; i<intents.length; i++) { 6385 Intent intent = intents[i]; 6386 if (intent != null) { 6387 if (intent.hasFileDescriptors()) { 6388 throw new IllegalArgumentException("File descriptors passed in Intent"); 6389 } 6390 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6391 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6392 throw new IllegalArgumentException( 6393 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6394 } 6395 intents[i] = new Intent(intent); 6396 } 6397 } 6398 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6399 throw new IllegalArgumentException( 6400 "Intent array length does not match resolvedTypes length"); 6401 } 6402 } 6403 if (options != null) { 6404 if (options.hasFileDescriptors()) { 6405 throw new IllegalArgumentException("File descriptors passed in options"); 6406 } 6407 } 6408 6409 synchronized(this) { 6410 int callingUid = Binder.getCallingUid(); 6411 int origUserId = userId; 6412 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6413 type == ActivityManager.INTENT_SENDER_BROADCAST, 6414 ALLOW_NON_FULL, "getIntentSender", null); 6415 if (origUserId == UserHandle.USER_CURRENT) { 6416 // We don't want to evaluate this until the pending intent is 6417 // actually executed. However, we do want to always do the 6418 // security checking for it above. 6419 userId = UserHandle.USER_CURRENT; 6420 } 6421 try { 6422 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6423 int uid = AppGlobals.getPackageManager() 6424 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6425 if (!UserHandle.isSameApp(callingUid, uid)) { 6426 String msg = "Permission Denial: getIntentSender() from pid=" 6427 + Binder.getCallingPid() 6428 + ", uid=" + Binder.getCallingUid() 6429 + ", (need uid=" + uid + ")" 6430 + " is not allowed to send as package " + packageName; 6431 Slog.w(TAG, msg); 6432 throw new SecurityException(msg); 6433 } 6434 } 6435 6436 return getIntentSenderLocked(type, packageName, callingUid, userId, 6437 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6438 6439 } catch (RemoteException e) { 6440 throw new SecurityException(e); 6441 } 6442 } 6443 } 6444 6445 IIntentSender getIntentSenderLocked(int type, String packageName, 6446 int callingUid, int userId, IBinder token, String resultWho, 6447 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6448 Bundle options) { 6449 if (DEBUG_MU) 6450 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6451 ActivityRecord activity = null; 6452 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6453 activity = ActivityRecord.isInStackLocked(token); 6454 if (activity == null) { 6455 return null; 6456 } 6457 if (activity.finishing) { 6458 return null; 6459 } 6460 } 6461 6462 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6463 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6464 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6465 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6466 |PendingIntent.FLAG_UPDATE_CURRENT); 6467 6468 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6469 type, packageName, activity, resultWho, 6470 requestCode, intents, resolvedTypes, flags, options, userId); 6471 WeakReference<PendingIntentRecord> ref; 6472 ref = mIntentSenderRecords.get(key); 6473 PendingIntentRecord rec = ref != null ? ref.get() : null; 6474 if (rec != null) { 6475 if (!cancelCurrent) { 6476 if (updateCurrent) { 6477 if (rec.key.requestIntent != null) { 6478 rec.key.requestIntent.replaceExtras(intents != null ? 6479 intents[intents.length - 1] : null); 6480 } 6481 if (intents != null) { 6482 intents[intents.length-1] = rec.key.requestIntent; 6483 rec.key.allIntents = intents; 6484 rec.key.allResolvedTypes = resolvedTypes; 6485 } else { 6486 rec.key.allIntents = null; 6487 rec.key.allResolvedTypes = null; 6488 } 6489 } 6490 return rec; 6491 } 6492 rec.canceled = true; 6493 mIntentSenderRecords.remove(key); 6494 } 6495 if (noCreate) { 6496 return rec; 6497 } 6498 rec = new PendingIntentRecord(this, key, callingUid); 6499 mIntentSenderRecords.put(key, rec.ref); 6500 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6501 if (activity.pendingResults == null) { 6502 activity.pendingResults 6503 = new HashSet<WeakReference<PendingIntentRecord>>(); 6504 } 6505 activity.pendingResults.add(rec.ref); 6506 } 6507 return rec; 6508 } 6509 6510 @Override 6511 public void cancelIntentSender(IIntentSender sender) { 6512 if (!(sender instanceof PendingIntentRecord)) { 6513 return; 6514 } 6515 synchronized(this) { 6516 PendingIntentRecord rec = (PendingIntentRecord)sender; 6517 try { 6518 int uid = AppGlobals.getPackageManager() 6519 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6520 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6521 String msg = "Permission Denial: cancelIntentSender() from pid=" 6522 + Binder.getCallingPid() 6523 + ", uid=" + Binder.getCallingUid() 6524 + " is not allowed to cancel packges " 6525 + rec.key.packageName; 6526 Slog.w(TAG, msg); 6527 throw new SecurityException(msg); 6528 } 6529 } catch (RemoteException e) { 6530 throw new SecurityException(e); 6531 } 6532 cancelIntentSenderLocked(rec, true); 6533 } 6534 } 6535 6536 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6537 rec.canceled = true; 6538 mIntentSenderRecords.remove(rec.key); 6539 if (cleanActivity && rec.key.activity != null) { 6540 rec.key.activity.pendingResults.remove(rec.ref); 6541 } 6542 } 6543 6544 @Override 6545 public String getPackageForIntentSender(IIntentSender pendingResult) { 6546 if (!(pendingResult instanceof PendingIntentRecord)) { 6547 return null; 6548 } 6549 try { 6550 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6551 return res.key.packageName; 6552 } catch (ClassCastException e) { 6553 } 6554 return null; 6555 } 6556 6557 @Override 6558 public int getUidForIntentSender(IIntentSender sender) { 6559 if (sender instanceof PendingIntentRecord) { 6560 try { 6561 PendingIntentRecord res = (PendingIntentRecord)sender; 6562 return res.uid; 6563 } catch (ClassCastException e) { 6564 } 6565 } 6566 return -1; 6567 } 6568 6569 @Override 6570 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6571 if (!(pendingResult instanceof PendingIntentRecord)) { 6572 return false; 6573 } 6574 try { 6575 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6576 if (res.key.allIntents == null) { 6577 return false; 6578 } 6579 for (int i=0; i<res.key.allIntents.length; i++) { 6580 Intent intent = res.key.allIntents[i]; 6581 if (intent.getPackage() != null && intent.getComponent() != null) { 6582 return false; 6583 } 6584 } 6585 return true; 6586 } catch (ClassCastException e) { 6587 } 6588 return false; 6589 } 6590 6591 @Override 6592 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6593 if (!(pendingResult instanceof PendingIntentRecord)) { 6594 return false; 6595 } 6596 try { 6597 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6598 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6599 return true; 6600 } 6601 return false; 6602 } catch (ClassCastException e) { 6603 } 6604 return false; 6605 } 6606 6607 @Override 6608 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6609 if (!(pendingResult instanceof PendingIntentRecord)) { 6610 return null; 6611 } 6612 try { 6613 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6614 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6615 } catch (ClassCastException e) { 6616 } 6617 return null; 6618 } 6619 6620 @Override 6621 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6622 if (!(pendingResult instanceof PendingIntentRecord)) { 6623 return null; 6624 } 6625 try { 6626 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6627 Intent intent = res.key.requestIntent; 6628 if (intent != null) { 6629 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6630 || res.lastTagPrefix.equals(prefix))) { 6631 return res.lastTag; 6632 } 6633 res.lastTagPrefix = prefix; 6634 StringBuilder sb = new StringBuilder(128); 6635 if (prefix != null) { 6636 sb.append(prefix); 6637 } 6638 if (intent.getAction() != null) { 6639 sb.append(intent.getAction()); 6640 } else if (intent.getComponent() != null) { 6641 intent.getComponent().appendShortString(sb); 6642 } else { 6643 sb.append("?"); 6644 } 6645 return res.lastTag = sb.toString(); 6646 } 6647 } catch (ClassCastException e) { 6648 } 6649 return null; 6650 } 6651 6652 @Override 6653 public void setProcessLimit(int max) { 6654 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6655 "setProcessLimit()"); 6656 synchronized (this) { 6657 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6658 mProcessLimitOverride = max; 6659 } 6660 trimApplications(); 6661 } 6662 6663 @Override 6664 public int getProcessLimit() { 6665 synchronized (this) { 6666 return mProcessLimitOverride; 6667 } 6668 } 6669 6670 void foregroundTokenDied(ForegroundToken token) { 6671 synchronized (ActivityManagerService.this) { 6672 synchronized (mPidsSelfLocked) { 6673 ForegroundToken cur 6674 = mForegroundProcesses.get(token.pid); 6675 if (cur != token) { 6676 return; 6677 } 6678 mForegroundProcesses.remove(token.pid); 6679 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6680 if (pr == null) { 6681 return; 6682 } 6683 pr.forcingToForeground = null; 6684 updateProcessForegroundLocked(pr, false, false); 6685 } 6686 updateOomAdjLocked(); 6687 } 6688 } 6689 6690 @Override 6691 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6692 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6693 "setProcessForeground()"); 6694 synchronized(this) { 6695 boolean changed = false; 6696 6697 synchronized (mPidsSelfLocked) { 6698 ProcessRecord pr = mPidsSelfLocked.get(pid); 6699 if (pr == null && isForeground) { 6700 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6701 return; 6702 } 6703 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6704 if (oldToken != null) { 6705 oldToken.token.unlinkToDeath(oldToken, 0); 6706 mForegroundProcesses.remove(pid); 6707 if (pr != null) { 6708 pr.forcingToForeground = null; 6709 } 6710 changed = true; 6711 } 6712 if (isForeground && token != null) { 6713 ForegroundToken newToken = new ForegroundToken() { 6714 @Override 6715 public void binderDied() { 6716 foregroundTokenDied(this); 6717 } 6718 }; 6719 newToken.pid = pid; 6720 newToken.token = token; 6721 try { 6722 token.linkToDeath(newToken, 0); 6723 mForegroundProcesses.put(pid, newToken); 6724 pr.forcingToForeground = token; 6725 changed = true; 6726 } catch (RemoteException e) { 6727 // If the process died while doing this, we will later 6728 // do the cleanup with the process death link. 6729 } 6730 } 6731 } 6732 6733 if (changed) { 6734 updateOomAdjLocked(); 6735 } 6736 } 6737 } 6738 6739 // ========================================================= 6740 // PERMISSIONS 6741 // ========================================================= 6742 6743 static class PermissionController extends IPermissionController.Stub { 6744 ActivityManagerService mActivityManagerService; 6745 PermissionController(ActivityManagerService activityManagerService) { 6746 mActivityManagerService = activityManagerService; 6747 } 6748 6749 @Override 6750 public boolean checkPermission(String permission, int pid, int uid) { 6751 return mActivityManagerService.checkPermission(permission, pid, 6752 uid) == PackageManager.PERMISSION_GRANTED; 6753 } 6754 } 6755 6756 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6757 @Override 6758 public int checkComponentPermission(String permission, int pid, int uid, 6759 int owningUid, boolean exported) { 6760 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6761 owningUid, exported); 6762 } 6763 6764 @Override 6765 public Object getAMSLock() { 6766 return ActivityManagerService.this; 6767 } 6768 } 6769 6770 /** 6771 * This can be called with or without the global lock held. 6772 */ 6773 int checkComponentPermission(String permission, int pid, int uid, 6774 int owningUid, boolean exported) { 6775 if (pid == MY_PID) { 6776 return PackageManager.PERMISSION_GRANTED; 6777 } 6778 return ActivityManager.checkComponentPermission(permission, uid, 6779 owningUid, exported); 6780 } 6781 6782 /** 6783 * As the only public entry point for permissions checking, this method 6784 * can enforce the semantic that requesting a check on a null global 6785 * permission is automatically denied. (Internally a null permission 6786 * string is used when calling {@link #checkComponentPermission} in cases 6787 * when only uid-based security is needed.) 6788 * 6789 * This can be called with or without the global lock held. 6790 */ 6791 @Override 6792 public int checkPermission(String permission, int pid, int uid) { 6793 if (permission == null) { 6794 return PackageManager.PERMISSION_DENIED; 6795 } 6796 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6797 } 6798 6799 @Override 6800 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6801 if (permission == null) { 6802 return PackageManager.PERMISSION_DENIED; 6803 } 6804 6805 // We might be performing an operation on behalf of an indirect binder 6806 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6807 // client identity accordingly before proceeding. 6808 Identity tlsIdentity = sCallerIdentity.get(); 6809 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6810 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6811 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6812 uid = tlsIdentity.uid; 6813 pid = tlsIdentity.pid; 6814 } 6815 6816 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6817 } 6818 6819 /** 6820 * Binder IPC calls go through the public entry point. 6821 * This can be called with or without the global lock held. 6822 */ 6823 int checkCallingPermission(String permission) { 6824 return checkPermission(permission, 6825 Binder.getCallingPid(), 6826 UserHandle.getAppId(Binder.getCallingUid())); 6827 } 6828 6829 /** 6830 * This can be called with or without the global lock held. 6831 */ 6832 void enforceCallingPermission(String permission, String func) { 6833 if (checkCallingPermission(permission) 6834 == PackageManager.PERMISSION_GRANTED) { 6835 return; 6836 } 6837 6838 String msg = "Permission Denial: " + func + " from pid=" 6839 + Binder.getCallingPid() 6840 + ", uid=" + Binder.getCallingUid() 6841 + " requires " + permission; 6842 Slog.w(TAG, msg); 6843 throw new SecurityException(msg); 6844 } 6845 6846 /** 6847 * Determine if UID is holding permissions required to access {@link Uri} in 6848 * the given {@link ProviderInfo}. Final permission checking is always done 6849 * in {@link ContentProvider}. 6850 */ 6851 private final boolean checkHoldingPermissionsLocked( 6852 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6853 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6854 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6855 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6856 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6857 != PERMISSION_GRANTED) { 6858 return false; 6859 } 6860 } 6861 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6862 } 6863 6864 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6865 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6866 if (pi.applicationInfo.uid == uid) { 6867 return true; 6868 } else if (!pi.exported) { 6869 return false; 6870 } 6871 6872 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6873 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6874 try { 6875 // check if target holds top-level <provider> permissions 6876 if (!readMet && pi.readPermission != null && considerUidPermissions 6877 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6878 readMet = true; 6879 } 6880 if (!writeMet && pi.writePermission != null && considerUidPermissions 6881 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6882 writeMet = true; 6883 } 6884 6885 // track if unprotected read/write is allowed; any denied 6886 // <path-permission> below removes this ability 6887 boolean allowDefaultRead = pi.readPermission == null; 6888 boolean allowDefaultWrite = pi.writePermission == null; 6889 6890 // check if target holds any <path-permission> that match uri 6891 final PathPermission[] pps = pi.pathPermissions; 6892 if (pps != null) { 6893 final String path = grantUri.uri.getPath(); 6894 int i = pps.length; 6895 while (i > 0 && (!readMet || !writeMet)) { 6896 i--; 6897 PathPermission pp = pps[i]; 6898 if (pp.match(path)) { 6899 if (!readMet) { 6900 final String pprperm = pp.getReadPermission(); 6901 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6902 + pprperm + " for " + pp.getPath() 6903 + ": match=" + pp.match(path) 6904 + " check=" + pm.checkUidPermission(pprperm, uid)); 6905 if (pprperm != null) { 6906 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6907 == PERMISSION_GRANTED) { 6908 readMet = true; 6909 } else { 6910 allowDefaultRead = false; 6911 } 6912 } 6913 } 6914 if (!writeMet) { 6915 final String ppwperm = pp.getWritePermission(); 6916 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6917 + ppwperm + " for " + pp.getPath() 6918 + ": match=" + pp.match(path) 6919 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6920 if (ppwperm != null) { 6921 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6922 == PERMISSION_GRANTED) { 6923 writeMet = true; 6924 } else { 6925 allowDefaultWrite = false; 6926 } 6927 } 6928 } 6929 } 6930 } 6931 } 6932 6933 // grant unprotected <provider> read/write, if not blocked by 6934 // <path-permission> above 6935 if (allowDefaultRead) readMet = true; 6936 if (allowDefaultWrite) writeMet = true; 6937 6938 } catch (RemoteException e) { 6939 return false; 6940 } 6941 6942 return readMet && writeMet; 6943 } 6944 6945 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6946 ProviderInfo pi = null; 6947 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6948 if (cpr != null) { 6949 pi = cpr.info; 6950 } else { 6951 try { 6952 pi = AppGlobals.getPackageManager().resolveContentProvider( 6953 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6954 } catch (RemoteException ex) { 6955 } 6956 } 6957 return pi; 6958 } 6959 6960 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6961 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6962 if (targetUris != null) { 6963 return targetUris.get(grantUri); 6964 } 6965 return null; 6966 } 6967 6968 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6969 String targetPkg, int targetUid, GrantUri grantUri) { 6970 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6971 if (targetUris == null) { 6972 targetUris = Maps.newArrayMap(); 6973 mGrantedUriPermissions.put(targetUid, targetUris); 6974 } 6975 6976 UriPermission perm = targetUris.get(grantUri); 6977 if (perm == null) { 6978 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6979 targetUris.put(grantUri, perm); 6980 } 6981 6982 return perm; 6983 } 6984 6985 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6986 final int modeFlags) { 6987 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6988 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6989 : UriPermission.STRENGTH_OWNED; 6990 6991 // Root gets to do everything. 6992 if (uid == 0) { 6993 return true; 6994 } 6995 6996 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6997 if (perms == null) return false; 6998 6999 // First look for exact match 7000 final UriPermission exactPerm = perms.get(grantUri); 7001 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7002 return true; 7003 } 7004 7005 // No exact match, look for prefixes 7006 final int N = perms.size(); 7007 for (int i = 0; i < N; i++) { 7008 final UriPermission perm = perms.valueAt(i); 7009 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7010 && perm.getStrength(modeFlags) >= minStrength) { 7011 return true; 7012 } 7013 } 7014 7015 return false; 7016 } 7017 7018 /** 7019 * @param uri This uri must NOT contain an embedded userId. 7020 * @param userId The userId in which the uri is to be resolved. 7021 */ 7022 @Override 7023 public int checkUriPermission(Uri uri, int pid, int uid, 7024 final int modeFlags, int userId, IBinder callerToken) { 7025 enforceNotIsolatedCaller("checkUriPermission"); 7026 7027 // Another redirected-binder-call permissions check as in 7028 // {@link checkPermissionWithToken}. 7029 Identity tlsIdentity = sCallerIdentity.get(); 7030 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7031 uid = tlsIdentity.uid; 7032 pid = tlsIdentity.pid; 7033 } 7034 7035 // Our own process gets to do everything. 7036 if (pid == MY_PID) { 7037 return PackageManager.PERMISSION_GRANTED; 7038 } 7039 synchronized (this) { 7040 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7041 ? PackageManager.PERMISSION_GRANTED 7042 : PackageManager.PERMISSION_DENIED; 7043 } 7044 } 7045 7046 /** 7047 * Check if the targetPkg can be granted permission to access uri by 7048 * the callingUid using the given modeFlags. Throws a security exception 7049 * if callingUid is not allowed to do this. Returns the uid of the target 7050 * if the URI permission grant should be performed; returns -1 if it is not 7051 * needed (for example targetPkg already has permission to access the URI). 7052 * If you already know the uid of the target, you can supply it in 7053 * lastTargetUid else set that to -1. 7054 */ 7055 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7056 final int modeFlags, int lastTargetUid) { 7057 if (!Intent.isAccessUriMode(modeFlags)) { 7058 return -1; 7059 } 7060 7061 if (targetPkg != null) { 7062 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7063 "Checking grant " + targetPkg + " permission to " + grantUri); 7064 } 7065 7066 final IPackageManager pm = AppGlobals.getPackageManager(); 7067 7068 // If this is not a content: uri, we can't do anything with it. 7069 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7070 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7071 "Can't grant URI permission for non-content URI: " + grantUri); 7072 return -1; 7073 } 7074 7075 final String authority = grantUri.uri.getAuthority(); 7076 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7077 if (pi == null) { 7078 Slog.w(TAG, "No content provider found for permission check: " + 7079 grantUri.uri.toSafeString()); 7080 return -1; 7081 } 7082 7083 int targetUid = lastTargetUid; 7084 if (targetUid < 0 && targetPkg != null) { 7085 try { 7086 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7087 if (targetUid < 0) { 7088 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7089 "Can't grant URI permission no uid for: " + targetPkg); 7090 return -1; 7091 } 7092 } catch (RemoteException ex) { 7093 return -1; 7094 } 7095 } 7096 7097 if (targetUid >= 0) { 7098 // First... does the target actually need this permission? 7099 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7100 // No need to grant the target this permission. 7101 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7102 "Target " + targetPkg + " already has full permission to " + grantUri); 7103 return -1; 7104 } 7105 } else { 7106 // First... there is no target package, so can anyone access it? 7107 boolean allowed = pi.exported; 7108 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7109 if (pi.readPermission != null) { 7110 allowed = false; 7111 } 7112 } 7113 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7114 if (pi.writePermission != null) { 7115 allowed = false; 7116 } 7117 } 7118 if (allowed) { 7119 return -1; 7120 } 7121 } 7122 7123 /* There is a special cross user grant if: 7124 * - The target is on another user. 7125 * - Apps on the current user can access the uri without any uid permissions. 7126 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7127 * grant uri permissions. 7128 */ 7129 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7130 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7131 modeFlags, false /*without considering the uid permissions*/); 7132 7133 // Second... is the provider allowing granting of URI permissions? 7134 if (!specialCrossUserGrant) { 7135 if (!pi.grantUriPermissions) { 7136 throw new SecurityException("Provider " + pi.packageName 7137 + "/" + pi.name 7138 + " does not allow granting of Uri permissions (uri " 7139 + grantUri + ")"); 7140 } 7141 if (pi.uriPermissionPatterns != null) { 7142 final int N = pi.uriPermissionPatterns.length; 7143 boolean allowed = false; 7144 for (int i=0; i<N; i++) { 7145 if (pi.uriPermissionPatterns[i] != null 7146 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7147 allowed = true; 7148 break; 7149 } 7150 } 7151 if (!allowed) { 7152 throw new SecurityException("Provider " + pi.packageName 7153 + "/" + pi.name 7154 + " does not allow granting of permission to path of Uri " 7155 + grantUri); 7156 } 7157 } 7158 } 7159 7160 // Third... does the caller itself have permission to access 7161 // this uri? 7162 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7163 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7164 // Require they hold a strong enough Uri permission 7165 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7166 throw new SecurityException("Uid " + callingUid 7167 + " does not have permission to uri " + grantUri); 7168 } 7169 } 7170 } 7171 return targetUid; 7172 } 7173 7174 /** 7175 * @param uri This uri must NOT contain an embedded userId. 7176 * @param userId The userId in which the uri is to be resolved. 7177 */ 7178 @Override 7179 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7180 final int modeFlags, int userId) { 7181 enforceNotIsolatedCaller("checkGrantUriPermission"); 7182 synchronized(this) { 7183 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7184 new GrantUri(userId, uri, false), modeFlags, -1); 7185 } 7186 } 7187 7188 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7189 final int modeFlags, UriPermissionOwner owner) { 7190 if (!Intent.isAccessUriMode(modeFlags)) { 7191 return; 7192 } 7193 7194 // So here we are: the caller has the assumed permission 7195 // to the uri, and the target doesn't. Let's now give this to 7196 // the target. 7197 7198 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7199 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7200 7201 final String authority = grantUri.uri.getAuthority(); 7202 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7203 if (pi == null) { 7204 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7205 return; 7206 } 7207 7208 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7209 grantUri.prefix = true; 7210 } 7211 final UriPermission perm = findOrCreateUriPermissionLocked( 7212 pi.packageName, targetPkg, targetUid, grantUri); 7213 perm.grantModes(modeFlags, owner); 7214 } 7215 7216 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7217 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7218 if (targetPkg == null) { 7219 throw new NullPointerException("targetPkg"); 7220 } 7221 int targetUid; 7222 final IPackageManager pm = AppGlobals.getPackageManager(); 7223 try { 7224 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7225 } catch (RemoteException ex) { 7226 return; 7227 } 7228 7229 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7230 targetUid); 7231 if (targetUid < 0) { 7232 return; 7233 } 7234 7235 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7236 owner); 7237 } 7238 7239 static class NeededUriGrants extends ArrayList<GrantUri> { 7240 final String targetPkg; 7241 final int targetUid; 7242 final int flags; 7243 7244 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7245 this.targetPkg = targetPkg; 7246 this.targetUid = targetUid; 7247 this.flags = flags; 7248 } 7249 } 7250 7251 /** 7252 * Like checkGrantUriPermissionLocked, but takes an Intent. 7253 */ 7254 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7255 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7256 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7257 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7258 + " clip=" + (intent != null ? intent.getClipData() : null) 7259 + " from " + intent + "; flags=0x" 7260 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7261 7262 if (targetPkg == null) { 7263 throw new NullPointerException("targetPkg"); 7264 } 7265 7266 if (intent == null) { 7267 return null; 7268 } 7269 Uri data = intent.getData(); 7270 ClipData clip = intent.getClipData(); 7271 if (data == null && clip == null) { 7272 return null; 7273 } 7274 // Default userId for uris in the intent (if they don't specify it themselves) 7275 int contentUserHint = intent.getContentUserHint(); 7276 if (contentUserHint == UserHandle.USER_CURRENT) { 7277 contentUserHint = UserHandle.getUserId(callingUid); 7278 } 7279 final IPackageManager pm = AppGlobals.getPackageManager(); 7280 int targetUid; 7281 if (needed != null) { 7282 targetUid = needed.targetUid; 7283 } else { 7284 try { 7285 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7286 } catch (RemoteException ex) { 7287 return null; 7288 } 7289 if (targetUid < 0) { 7290 if (DEBUG_URI_PERMISSION) { 7291 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7292 + " on user " + targetUserId); 7293 } 7294 return null; 7295 } 7296 } 7297 if (data != null) { 7298 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7299 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7300 targetUid); 7301 if (targetUid > 0) { 7302 if (needed == null) { 7303 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7304 } 7305 needed.add(grantUri); 7306 } 7307 } 7308 if (clip != null) { 7309 for (int i=0; i<clip.getItemCount(); i++) { 7310 Uri uri = clip.getItemAt(i).getUri(); 7311 if (uri != null) { 7312 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7313 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7314 targetUid); 7315 if (targetUid > 0) { 7316 if (needed == null) { 7317 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7318 } 7319 needed.add(grantUri); 7320 } 7321 } else { 7322 Intent clipIntent = clip.getItemAt(i).getIntent(); 7323 if (clipIntent != null) { 7324 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7325 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7326 if (newNeeded != null) { 7327 needed = newNeeded; 7328 } 7329 } 7330 } 7331 } 7332 } 7333 7334 return needed; 7335 } 7336 7337 /** 7338 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7339 */ 7340 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7341 UriPermissionOwner owner) { 7342 if (needed != null) { 7343 for (int i=0; i<needed.size(); i++) { 7344 GrantUri grantUri = needed.get(i); 7345 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7346 grantUri, needed.flags, owner); 7347 } 7348 } 7349 } 7350 7351 void grantUriPermissionFromIntentLocked(int callingUid, 7352 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7353 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7354 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7355 if (needed == null) { 7356 return; 7357 } 7358 7359 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7360 } 7361 7362 /** 7363 * @param uri This uri must NOT contain an embedded userId. 7364 * @param userId The userId in which the uri is to be resolved. 7365 */ 7366 @Override 7367 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7368 final int modeFlags, int userId) { 7369 enforceNotIsolatedCaller("grantUriPermission"); 7370 GrantUri grantUri = new GrantUri(userId, uri, false); 7371 synchronized(this) { 7372 final ProcessRecord r = getRecordForAppLocked(caller); 7373 if (r == null) { 7374 throw new SecurityException("Unable to find app for caller " 7375 + caller 7376 + " when granting permission to uri " + grantUri); 7377 } 7378 if (targetPkg == null) { 7379 throw new IllegalArgumentException("null target"); 7380 } 7381 if (grantUri == null) { 7382 throw new IllegalArgumentException("null uri"); 7383 } 7384 7385 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7386 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7387 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7388 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7389 7390 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7391 UserHandle.getUserId(r.uid)); 7392 } 7393 } 7394 7395 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7396 if (perm.modeFlags == 0) { 7397 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7398 perm.targetUid); 7399 if (perms != null) { 7400 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7401 "Removing " + perm.targetUid + " permission to " + perm.uri); 7402 7403 perms.remove(perm.uri); 7404 if (perms.isEmpty()) { 7405 mGrantedUriPermissions.remove(perm.targetUid); 7406 } 7407 } 7408 } 7409 } 7410 7411 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7412 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7413 7414 final IPackageManager pm = AppGlobals.getPackageManager(); 7415 final String authority = grantUri.uri.getAuthority(); 7416 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7417 if (pi == null) { 7418 Slog.w(TAG, "No content provider found for permission revoke: " 7419 + grantUri.toSafeString()); 7420 return; 7421 } 7422 7423 // Does the caller have this permission on the URI? 7424 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7425 // If they don't have direct access to the URI, then revoke any 7426 // ownerless URI permissions that have been granted to them. 7427 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7428 if (perms != null) { 7429 boolean persistChanged = false; 7430 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7431 final UriPermission perm = it.next(); 7432 if (perm.uri.sourceUserId == grantUri.sourceUserId 7433 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7434 if (DEBUG_URI_PERMISSION) 7435 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7436 " permission to " + perm.uri); 7437 persistChanged |= perm.revokeModes( 7438 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7439 if (perm.modeFlags == 0) { 7440 it.remove(); 7441 } 7442 } 7443 } 7444 if (perms.isEmpty()) { 7445 mGrantedUriPermissions.remove(callingUid); 7446 } 7447 if (persistChanged) { 7448 schedulePersistUriGrants(); 7449 } 7450 } 7451 return; 7452 } 7453 7454 boolean persistChanged = false; 7455 7456 // Go through all of the permissions and remove any that match. 7457 int N = mGrantedUriPermissions.size(); 7458 for (int i = 0; i < N; i++) { 7459 final int targetUid = mGrantedUriPermissions.keyAt(i); 7460 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7461 7462 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7463 final UriPermission perm = it.next(); 7464 if (perm.uri.sourceUserId == grantUri.sourceUserId 7465 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7466 if (DEBUG_URI_PERMISSION) 7467 Slog.v(TAG, 7468 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7469 persistChanged |= perm.revokeModes( 7470 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7471 if (perm.modeFlags == 0) { 7472 it.remove(); 7473 } 7474 } 7475 } 7476 7477 if (perms.isEmpty()) { 7478 mGrantedUriPermissions.remove(targetUid); 7479 N--; 7480 i--; 7481 } 7482 } 7483 7484 if (persistChanged) { 7485 schedulePersistUriGrants(); 7486 } 7487 } 7488 7489 /** 7490 * @param uri This uri must NOT contain an embedded userId. 7491 * @param userId The userId in which the uri is to be resolved. 7492 */ 7493 @Override 7494 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7495 int userId) { 7496 enforceNotIsolatedCaller("revokeUriPermission"); 7497 synchronized(this) { 7498 final ProcessRecord r = getRecordForAppLocked(caller); 7499 if (r == null) { 7500 throw new SecurityException("Unable to find app for caller " 7501 + caller 7502 + " when revoking permission to uri " + uri); 7503 } 7504 if (uri == null) { 7505 Slog.w(TAG, "revokeUriPermission: null uri"); 7506 return; 7507 } 7508 7509 if (!Intent.isAccessUriMode(modeFlags)) { 7510 return; 7511 } 7512 7513 final IPackageManager pm = AppGlobals.getPackageManager(); 7514 final String authority = uri.getAuthority(); 7515 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7516 if (pi == null) { 7517 Slog.w(TAG, "No content provider found for permission revoke: " 7518 + uri.toSafeString()); 7519 return; 7520 } 7521 7522 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7523 } 7524 } 7525 7526 /** 7527 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7528 * given package. 7529 * 7530 * @param packageName Package name to match, or {@code null} to apply to all 7531 * packages. 7532 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7533 * to all users. 7534 * @param persistable If persistable grants should be removed. 7535 */ 7536 private void removeUriPermissionsForPackageLocked( 7537 String packageName, int userHandle, boolean persistable) { 7538 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7539 throw new IllegalArgumentException("Must narrow by either package or user"); 7540 } 7541 7542 boolean persistChanged = false; 7543 7544 int N = mGrantedUriPermissions.size(); 7545 for (int i = 0; i < N; i++) { 7546 final int targetUid = mGrantedUriPermissions.keyAt(i); 7547 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7548 7549 // Only inspect grants matching user 7550 if (userHandle == UserHandle.USER_ALL 7551 || userHandle == UserHandle.getUserId(targetUid)) { 7552 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7553 final UriPermission perm = it.next(); 7554 7555 // Only inspect grants matching package 7556 if (packageName == null || perm.sourcePkg.equals(packageName) 7557 || perm.targetPkg.equals(packageName)) { 7558 persistChanged |= perm.revokeModes(persistable 7559 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7560 7561 // Only remove when no modes remain; any persisted grants 7562 // will keep this alive. 7563 if (perm.modeFlags == 0) { 7564 it.remove(); 7565 } 7566 } 7567 } 7568 7569 if (perms.isEmpty()) { 7570 mGrantedUriPermissions.remove(targetUid); 7571 N--; 7572 i--; 7573 } 7574 } 7575 } 7576 7577 if (persistChanged) { 7578 schedulePersistUriGrants(); 7579 } 7580 } 7581 7582 @Override 7583 public IBinder newUriPermissionOwner(String name) { 7584 enforceNotIsolatedCaller("newUriPermissionOwner"); 7585 synchronized(this) { 7586 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7587 return owner.getExternalTokenLocked(); 7588 } 7589 } 7590 7591 /** 7592 * @param uri This uri must NOT contain an embedded userId. 7593 * @param sourceUserId The userId in which the uri is to be resolved. 7594 * @param targetUserId The userId of the app that receives the grant. 7595 */ 7596 @Override 7597 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7598 final int modeFlags, int sourceUserId, int targetUserId) { 7599 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7600 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7601 synchronized(this) { 7602 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7603 if (owner == null) { 7604 throw new IllegalArgumentException("Unknown owner: " + token); 7605 } 7606 if (fromUid != Binder.getCallingUid()) { 7607 if (Binder.getCallingUid() != Process.myUid()) { 7608 // Only system code can grant URI permissions on behalf 7609 // of other users. 7610 throw new SecurityException("nice try"); 7611 } 7612 } 7613 if (targetPkg == null) { 7614 throw new IllegalArgumentException("null target"); 7615 } 7616 if (uri == null) { 7617 throw new IllegalArgumentException("null uri"); 7618 } 7619 7620 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7621 modeFlags, owner, targetUserId); 7622 } 7623 } 7624 7625 /** 7626 * @param uri This uri must NOT contain an embedded userId. 7627 * @param userId The userId in which the uri is to be resolved. 7628 */ 7629 @Override 7630 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7631 synchronized(this) { 7632 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7633 if (owner == null) { 7634 throw new IllegalArgumentException("Unknown owner: " + token); 7635 } 7636 7637 if (uri == null) { 7638 owner.removeUriPermissionsLocked(mode); 7639 } else { 7640 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7641 } 7642 } 7643 } 7644 7645 private void schedulePersistUriGrants() { 7646 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7647 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7648 10 * DateUtils.SECOND_IN_MILLIS); 7649 } 7650 } 7651 7652 private void writeGrantedUriPermissions() { 7653 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7654 7655 // Snapshot permissions so we can persist without lock 7656 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7657 synchronized (this) { 7658 final int size = mGrantedUriPermissions.size(); 7659 for (int i = 0; i < size; i++) { 7660 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7661 for (UriPermission perm : perms.values()) { 7662 if (perm.persistedModeFlags != 0) { 7663 persist.add(perm.snapshot()); 7664 } 7665 } 7666 } 7667 } 7668 7669 FileOutputStream fos = null; 7670 try { 7671 fos = mGrantFile.startWrite(); 7672 7673 XmlSerializer out = new FastXmlSerializer(); 7674 out.setOutput(fos, "utf-8"); 7675 out.startDocument(null, true); 7676 out.startTag(null, TAG_URI_GRANTS); 7677 for (UriPermission.Snapshot perm : persist) { 7678 out.startTag(null, TAG_URI_GRANT); 7679 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7680 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7681 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7682 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7683 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7684 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7685 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7686 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7687 out.endTag(null, TAG_URI_GRANT); 7688 } 7689 out.endTag(null, TAG_URI_GRANTS); 7690 out.endDocument(); 7691 7692 mGrantFile.finishWrite(fos); 7693 } catch (IOException e) { 7694 if (fos != null) { 7695 mGrantFile.failWrite(fos); 7696 } 7697 } 7698 } 7699 7700 private void readGrantedUriPermissionsLocked() { 7701 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7702 7703 final long now = System.currentTimeMillis(); 7704 7705 FileInputStream fis = null; 7706 try { 7707 fis = mGrantFile.openRead(); 7708 final XmlPullParser in = Xml.newPullParser(); 7709 in.setInput(fis, null); 7710 7711 int type; 7712 while ((type = in.next()) != END_DOCUMENT) { 7713 final String tag = in.getName(); 7714 if (type == START_TAG) { 7715 if (TAG_URI_GRANT.equals(tag)) { 7716 final int sourceUserId; 7717 final int targetUserId; 7718 final int userHandle = readIntAttribute(in, 7719 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7720 if (userHandle != UserHandle.USER_NULL) { 7721 // For backwards compatibility. 7722 sourceUserId = userHandle; 7723 targetUserId = userHandle; 7724 } else { 7725 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7726 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7727 } 7728 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7729 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7730 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7731 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7732 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7733 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7734 7735 // Sanity check that provider still belongs to source package 7736 final ProviderInfo pi = getProviderInfoLocked( 7737 uri.getAuthority(), sourceUserId); 7738 if (pi != null && sourcePkg.equals(pi.packageName)) { 7739 int targetUid = -1; 7740 try { 7741 targetUid = AppGlobals.getPackageManager() 7742 .getPackageUid(targetPkg, targetUserId); 7743 } catch (RemoteException e) { 7744 } 7745 if (targetUid != -1) { 7746 final UriPermission perm = findOrCreateUriPermissionLocked( 7747 sourcePkg, targetPkg, targetUid, 7748 new GrantUri(sourceUserId, uri, prefix)); 7749 perm.initPersistedModes(modeFlags, createdTime); 7750 } 7751 } else { 7752 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7753 + " but instead found " + pi); 7754 } 7755 } 7756 } 7757 } 7758 } catch (FileNotFoundException e) { 7759 // Missing grants is okay 7760 } catch (IOException e) { 7761 Slog.wtf(TAG, "Failed reading Uri grants", e); 7762 } catch (XmlPullParserException e) { 7763 Slog.wtf(TAG, "Failed reading Uri grants", e); 7764 } finally { 7765 IoUtils.closeQuietly(fis); 7766 } 7767 } 7768 7769 /** 7770 * @param uri This uri must NOT contain an embedded userId. 7771 * @param userId The userId in which the uri is to be resolved. 7772 */ 7773 @Override 7774 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7775 enforceNotIsolatedCaller("takePersistableUriPermission"); 7776 7777 Preconditions.checkFlagsArgument(modeFlags, 7778 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7779 7780 synchronized (this) { 7781 final int callingUid = Binder.getCallingUid(); 7782 boolean persistChanged = false; 7783 GrantUri grantUri = new GrantUri(userId, uri, false); 7784 7785 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7786 new GrantUri(userId, uri, false)); 7787 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7788 new GrantUri(userId, uri, true)); 7789 7790 final boolean exactValid = (exactPerm != null) 7791 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7792 final boolean prefixValid = (prefixPerm != null) 7793 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7794 7795 if (!(exactValid || prefixValid)) { 7796 throw new SecurityException("No persistable permission grants found for UID " 7797 + callingUid + " and Uri " + grantUri.toSafeString()); 7798 } 7799 7800 if (exactValid) { 7801 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7802 } 7803 if (prefixValid) { 7804 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7805 } 7806 7807 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7808 7809 if (persistChanged) { 7810 schedulePersistUriGrants(); 7811 } 7812 } 7813 } 7814 7815 /** 7816 * @param uri This uri must NOT contain an embedded userId. 7817 * @param userId The userId in which the uri is to be resolved. 7818 */ 7819 @Override 7820 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7821 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7822 7823 Preconditions.checkFlagsArgument(modeFlags, 7824 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7825 7826 synchronized (this) { 7827 final int callingUid = Binder.getCallingUid(); 7828 boolean persistChanged = false; 7829 7830 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7831 new GrantUri(userId, uri, false)); 7832 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7833 new GrantUri(userId, uri, true)); 7834 if (exactPerm == null && prefixPerm == null) { 7835 throw new SecurityException("No permission grants found for UID " + callingUid 7836 + " and Uri " + uri.toSafeString()); 7837 } 7838 7839 if (exactPerm != null) { 7840 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7841 removeUriPermissionIfNeededLocked(exactPerm); 7842 } 7843 if (prefixPerm != null) { 7844 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7845 removeUriPermissionIfNeededLocked(prefixPerm); 7846 } 7847 7848 if (persistChanged) { 7849 schedulePersistUriGrants(); 7850 } 7851 } 7852 } 7853 7854 /** 7855 * Prune any older {@link UriPermission} for the given UID until outstanding 7856 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7857 * 7858 * @return if any mutations occured that require persisting. 7859 */ 7860 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7861 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7862 if (perms == null) return false; 7863 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7864 7865 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7866 for (UriPermission perm : perms.values()) { 7867 if (perm.persistedModeFlags != 0) { 7868 persisted.add(perm); 7869 } 7870 } 7871 7872 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7873 if (trimCount <= 0) return false; 7874 7875 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7876 for (int i = 0; i < trimCount; i++) { 7877 final UriPermission perm = persisted.get(i); 7878 7879 if (DEBUG_URI_PERMISSION) { 7880 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7881 } 7882 7883 perm.releasePersistableModes(~0); 7884 removeUriPermissionIfNeededLocked(perm); 7885 } 7886 7887 return true; 7888 } 7889 7890 @Override 7891 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7892 String packageName, boolean incoming) { 7893 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7894 Preconditions.checkNotNull(packageName, "packageName"); 7895 7896 final int callingUid = Binder.getCallingUid(); 7897 final IPackageManager pm = AppGlobals.getPackageManager(); 7898 try { 7899 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7900 if (packageUid != callingUid) { 7901 throw new SecurityException( 7902 "Package " + packageName + " does not belong to calling UID " + callingUid); 7903 } 7904 } catch (RemoteException e) { 7905 throw new SecurityException("Failed to verify package name ownership"); 7906 } 7907 7908 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7909 synchronized (this) { 7910 if (incoming) { 7911 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7912 callingUid); 7913 if (perms == null) { 7914 Slog.w(TAG, "No permission grants found for " + packageName); 7915 } else { 7916 for (UriPermission perm : perms.values()) { 7917 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7918 result.add(perm.buildPersistedPublicApiObject()); 7919 } 7920 } 7921 } 7922 } else { 7923 final int size = mGrantedUriPermissions.size(); 7924 for (int i = 0; i < size; i++) { 7925 final ArrayMap<GrantUri, UriPermission> perms = 7926 mGrantedUriPermissions.valueAt(i); 7927 for (UriPermission perm : perms.values()) { 7928 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7929 result.add(perm.buildPersistedPublicApiObject()); 7930 } 7931 } 7932 } 7933 } 7934 } 7935 return new ParceledListSlice<android.content.UriPermission>(result); 7936 } 7937 7938 @Override 7939 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7940 synchronized (this) { 7941 ProcessRecord app = 7942 who != null ? getRecordForAppLocked(who) : null; 7943 if (app == null) return; 7944 7945 Message msg = Message.obtain(); 7946 msg.what = WAIT_FOR_DEBUGGER_MSG; 7947 msg.obj = app; 7948 msg.arg1 = waiting ? 1 : 0; 7949 mHandler.sendMessage(msg); 7950 } 7951 } 7952 7953 @Override 7954 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7955 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7956 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7957 outInfo.availMem = Process.getFreeMemory(); 7958 outInfo.totalMem = Process.getTotalMemory(); 7959 outInfo.threshold = homeAppMem; 7960 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7961 outInfo.hiddenAppThreshold = cachedAppMem; 7962 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7963 ProcessList.SERVICE_ADJ); 7964 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7965 ProcessList.VISIBLE_APP_ADJ); 7966 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7967 ProcessList.FOREGROUND_APP_ADJ); 7968 } 7969 7970 // ========================================================= 7971 // TASK MANAGEMENT 7972 // ========================================================= 7973 7974 @Override 7975 public List<IAppTask> getAppTasks(String callingPackage) { 7976 int callingUid = Binder.getCallingUid(); 7977 long ident = Binder.clearCallingIdentity(); 7978 7979 synchronized(this) { 7980 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7981 try { 7982 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7983 7984 final int N = mRecentTasks.size(); 7985 for (int i = 0; i < N; i++) { 7986 TaskRecord tr = mRecentTasks.get(i); 7987 // Skip tasks that do not match the caller. We don't need to verify 7988 // callingPackage, because we are also limiting to callingUid and know 7989 // that will limit to the correct security sandbox. 7990 if (tr.effectiveUid != callingUid) { 7991 continue; 7992 } 7993 Intent intent = tr.getBaseIntent(); 7994 if (intent == null || 7995 !callingPackage.equals(intent.getComponent().getPackageName())) { 7996 continue; 7997 } 7998 ActivityManager.RecentTaskInfo taskInfo = 7999 createRecentTaskInfoFromTaskRecord(tr); 8000 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8001 list.add(taskImpl); 8002 } 8003 } finally { 8004 Binder.restoreCallingIdentity(ident); 8005 } 8006 return list; 8007 } 8008 } 8009 8010 @Override 8011 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8012 final int callingUid = Binder.getCallingUid(); 8013 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8014 8015 synchronized(this) { 8016 if (localLOGV) Slog.v( 8017 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8018 8019 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8020 callingUid); 8021 8022 // TODO: Improve with MRU list from all ActivityStacks. 8023 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8024 } 8025 8026 return list; 8027 } 8028 8029 /** 8030 * Creates a new RecentTaskInfo from a TaskRecord. 8031 */ 8032 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8033 // Update the task description to reflect any changes in the task stack 8034 tr.updateTaskDescription(); 8035 8036 // Compose the recent task info 8037 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8038 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8039 rti.persistentId = tr.taskId; 8040 rti.baseIntent = new Intent(tr.getBaseIntent()); 8041 rti.origActivity = tr.origActivity; 8042 rti.description = tr.lastDescription; 8043 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8044 rti.userId = tr.userId; 8045 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8046 rti.firstActiveTime = tr.firstActiveTime; 8047 rti.lastActiveTime = tr.lastActiveTime; 8048 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8049 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8050 return rti; 8051 } 8052 8053 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8054 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8055 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8056 if (!allowed) { 8057 if (checkPermission(android.Manifest.permission.GET_TASKS, 8058 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8059 // Temporary compatibility: some existing apps on the system image may 8060 // still be requesting the old permission and not switched to the new 8061 // one; if so, we'll still allow them full access. This means we need 8062 // to see if they are holding the old permission and are a system app. 8063 try { 8064 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8065 allowed = true; 8066 Slog.w(TAG, caller + ": caller " + callingUid 8067 + " is using old GET_TASKS but privileged; allowing"); 8068 } 8069 } catch (RemoteException e) { 8070 } 8071 } 8072 } 8073 if (!allowed) { 8074 Slog.w(TAG, caller + ": caller " + callingUid 8075 + " does not hold GET_TASKS; limiting output"); 8076 } 8077 return allowed; 8078 } 8079 8080 @Override 8081 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8082 final int callingUid = Binder.getCallingUid(); 8083 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8084 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8085 8086 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8087 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8088 synchronized (this) { 8089 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8090 callingUid); 8091 final boolean detailed = checkCallingPermission( 8092 android.Manifest.permission.GET_DETAILED_TASKS) 8093 == PackageManager.PERMISSION_GRANTED; 8094 8095 final int N = mRecentTasks.size(); 8096 ArrayList<ActivityManager.RecentTaskInfo> res 8097 = new ArrayList<ActivityManager.RecentTaskInfo>( 8098 maxNum < N ? maxNum : N); 8099 8100 final Set<Integer> includedUsers; 8101 if (includeProfiles) { 8102 includedUsers = getProfileIdsLocked(userId); 8103 } else { 8104 includedUsers = new HashSet<Integer>(); 8105 } 8106 includedUsers.add(Integer.valueOf(userId)); 8107 8108 for (int i=0; i<N && maxNum > 0; i++) { 8109 TaskRecord tr = mRecentTasks.get(i); 8110 // Only add calling user or related users recent tasks 8111 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8112 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8113 continue; 8114 } 8115 8116 // Return the entry if desired by the caller. We always return 8117 // the first entry, because callers always expect this to be the 8118 // foreground app. We may filter others if the caller has 8119 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8120 // we should exclude the entry. 8121 8122 if (i == 0 8123 || withExcluded 8124 || (tr.intent == null) 8125 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8126 == 0)) { 8127 if (!allowed) { 8128 // If the caller doesn't have the GET_TASKS permission, then only 8129 // allow them to see a small subset of tasks -- their own and home. 8130 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8131 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8132 continue; 8133 } 8134 } 8135 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8136 if (tr.stack != null && tr.stack.isHomeStack()) { 8137 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8138 continue; 8139 } 8140 } 8141 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8142 // Don't include auto remove tasks that are finished or finishing. 8143 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8144 + tr); 8145 continue; 8146 } 8147 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8148 && !tr.isAvailable) { 8149 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8150 continue; 8151 } 8152 8153 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8154 if (!detailed) { 8155 rti.baseIntent.replaceExtras((Bundle)null); 8156 } 8157 8158 res.add(rti); 8159 maxNum--; 8160 } 8161 } 8162 return res; 8163 } 8164 } 8165 8166 private TaskRecord taskForIdLocked(int id) { 8167 final TaskRecord task = recentTaskForIdLocked(id); 8168 if (task != null) { 8169 return task; 8170 } 8171 8172 // Don't give up. Sometimes it just hasn't made it to recents yet. 8173 return mStackSupervisor.anyTaskForIdLocked(id); 8174 } 8175 8176 private TaskRecord recentTaskForIdLocked(int id) { 8177 final int N = mRecentTasks.size(); 8178 for (int i=0; i<N; i++) { 8179 TaskRecord tr = mRecentTasks.get(i); 8180 if (tr.taskId == id) { 8181 return tr; 8182 } 8183 } 8184 return null; 8185 } 8186 8187 @Override 8188 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8189 synchronized (this) { 8190 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8191 "getTaskThumbnail()"); 8192 TaskRecord tr = recentTaskForIdLocked(id); 8193 if (tr != null) { 8194 return tr.getTaskThumbnailLocked(); 8195 } 8196 } 8197 return null; 8198 } 8199 8200 @Override 8201 public int addAppTask(IBinder activityToken, Intent intent, 8202 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8203 final int callingUid = Binder.getCallingUid(); 8204 final long callingIdent = Binder.clearCallingIdentity(); 8205 8206 try { 8207 synchronized (this) { 8208 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8209 if (r == null) { 8210 throw new IllegalArgumentException("Activity does not exist; token=" 8211 + activityToken); 8212 } 8213 ComponentName comp = intent.getComponent(); 8214 if (comp == null) { 8215 throw new IllegalArgumentException("Intent " + intent 8216 + " must specify explicit component"); 8217 } 8218 if (thumbnail.getWidth() != mThumbnailWidth 8219 || thumbnail.getHeight() != mThumbnailHeight) { 8220 throw new IllegalArgumentException("Bad thumbnail size: got " 8221 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8222 + mThumbnailWidth + "x" + mThumbnailHeight); 8223 } 8224 if (intent.getSelector() != null) { 8225 intent.setSelector(null); 8226 } 8227 if (intent.getSourceBounds() != null) { 8228 intent.setSourceBounds(null); 8229 } 8230 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8231 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8232 // The caller has added this as an auto-remove task... that makes no 8233 // sense, so turn off auto-remove. 8234 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8235 } 8236 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8237 // Must be a new task. 8238 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8239 } 8240 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8241 mLastAddedTaskActivity = null; 8242 } 8243 ActivityInfo ainfo = mLastAddedTaskActivity; 8244 if (ainfo == null) { 8245 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8246 comp, 0, UserHandle.getUserId(callingUid)); 8247 if (ainfo.applicationInfo.uid != callingUid) { 8248 throw new SecurityException( 8249 "Can't add task for another application: target uid=" 8250 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8251 } 8252 } 8253 8254 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8255 intent, description); 8256 8257 int trimIdx = trimRecentsForTaskLocked(task, false); 8258 if (trimIdx >= 0) { 8259 // If this would have caused a trim, then we'll abort because that 8260 // means it would be added at the end of the list but then just removed. 8261 return -1; 8262 } 8263 8264 final int N = mRecentTasks.size(); 8265 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8266 final TaskRecord tr = mRecentTasks.remove(N - 1); 8267 tr.removedFromRecents(); 8268 } 8269 8270 task.inRecents = true; 8271 mRecentTasks.add(task); 8272 r.task.stack.addTask(task, false, false); 8273 8274 task.setLastThumbnail(thumbnail); 8275 task.freeLastThumbnail(); 8276 8277 return task.taskId; 8278 } 8279 } finally { 8280 Binder.restoreCallingIdentity(callingIdent); 8281 } 8282 } 8283 8284 @Override 8285 public Point getAppTaskThumbnailSize() { 8286 synchronized (this) { 8287 return new Point(mThumbnailWidth, mThumbnailHeight); 8288 } 8289 } 8290 8291 @Override 8292 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8293 synchronized (this) { 8294 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8295 if (r != null) { 8296 r.setTaskDescription(td); 8297 r.task.updateTaskDescription(); 8298 } 8299 } 8300 } 8301 8302 @Override 8303 public Bitmap getTaskDescriptionIcon(String filename) { 8304 if (!FileUtils.isValidExtFilename(filename) 8305 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8306 throw new IllegalArgumentException("Bad filename: " + filename); 8307 } 8308 return mTaskPersister.getTaskDescriptionIcon(filename); 8309 } 8310 8311 @Override 8312 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8313 throws RemoteException { 8314 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8315 opts.getCustomInPlaceResId() == 0) { 8316 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8317 "with valid animation"); 8318 } 8319 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8320 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8321 opts.getCustomInPlaceResId()); 8322 mWindowManager.executeAppTransition(); 8323 } 8324 8325 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8326 mRecentTasks.remove(tr); 8327 tr.removedFromRecents(); 8328 ComponentName component = tr.getBaseIntent().getComponent(); 8329 if (component == null) { 8330 Slog.w(TAG, "No component for base intent of task: " + tr); 8331 return; 8332 } 8333 8334 if (!killProcess) { 8335 return; 8336 } 8337 8338 // Determine if the process(es) for this task should be killed. 8339 final String pkg = component.getPackageName(); 8340 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8341 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8342 for (int i = 0; i < pmap.size(); i++) { 8343 8344 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8345 for (int j = 0; j < uids.size(); j++) { 8346 ProcessRecord proc = uids.valueAt(j); 8347 if (proc.userId != tr.userId) { 8348 // Don't kill process for a different user. 8349 continue; 8350 } 8351 if (proc == mHomeProcess) { 8352 // Don't kill the home process along with tasks from the same package. 8353 continue; 8354 } 8355 if (!proc.pkgList.containsKey(pkg)) { 8356 // Don't kill process that is not associated with this task. 8357 continue; 8358 } 8359 8360 for (int k = 0; k < proc.activities.size(); k++) { 8361 TaskRecord otherTask = proc.activities.get(k).task; 8362 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8363 // Don't kill process(es) that has an activity in a different task that is 8364 // also in recents. 8365 return; 8366 } 8367 } 8368 8369 // Add process to kill list. 8370 procsToKill.add(proc); 8371 } 8372 } 8373 8374 // Find any running services associated with this app and stop if needed. 8375 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8376 8377 // Kill the running processes. 8378 for (int i = 0; i < procsToKill.size(); i++) { 8379 ProcessRecord pr = procsToKill.get(i); 8380 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8381 pr.kill("remove task", true); 8382 } else { 8383 pr.waitingToKill = "remove task"; 8384 } 8385 } 8386 } 8387 8388 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8389 // Remove all tasks with activities in the specified package from the list of recent tasks 8390 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8391 TaskRecord tr = mRecentTasks.get(i); 8392 if (tr.userId != userId) continue; 8393 8394 ComponentName cn = tr.intent.getComponent(); 8395 if (cn != null && cn.getPackageName().equals(packageName)) { 8396 // If the package name matches, remove the task. 8397 removeTaskByIdLocked(tr.taskId, true); 8398 } 8399 } 8400 } 8401 8402 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8403 final IPackageManager pm = AppGlobals.getPackageManager(); 8404 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8405 8406 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8407 TaskRecord tr = mRecentTasks.get(i); 8408 if (tr.userId != userId) continue; 8409 8410 ComponentName cn = tr.intent.getComponent(); 8411 if (cn != null && cn.getPackageName().equals(packageName)) { 8412 // Skip if component still exists in the package. 8413 if (componentsKnownToExist.contains(cn)) continue; 8414 8415 try { 8416 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8417 if (info != null) { 8418 componentsKnownToExist.add(cn); 8419 } else { 8420 removeTaskByIdLocked(tr.taskId, false); 8421 } 8422 } catch (RemoteException e) { 8423 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8424 } 8425 } 8426 } 8427 } 8428 8429 /** 8430 * Removes the task with the specified task id. 8431 * 8432 * @param taskId Identifier of the task to be removed. 8433 * @param killProcess Kill any process associated with the task if possible. 8434 * @return Returns true if the given task was found and removed. 8435 */ 8436 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8437 TaskRecord tr = taskForIdLocked(taskId); 8438 if (tr != null) { 8439 tr.removeTaskActivitiesLocked(); 8440 cleanUpRemovedTaskLocked(tr, killProcess); 8441 if (tr.isPersistable) { 8442 notifyTaskPersisterLocked(null, true); 8443 } 8444 return true; 8445 } 8446 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8447 return false; 8448 } 8449 8450 @Override 8451 public boolean removeTask(int taskId) { 8452 synchronized (this) { 8453 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8454 "removeTask()"); 8455 long ident = Binder.clearCallingIdentity(); 8456 try { 8457 return removeTaskByIdLocked(taskId, true); 8458 } finally { 8459 Binder.restoreCallingIdentity(ident); 8460 } 8461 } 8462 } 8463 8464 /** 8465 * TODO: Add mController hook 8466 */ 8467 @Override 8468 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8469 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8470 "moveTaskToFront()"); 8471 8472 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8473 synchronized(this) { 8474 moveTaskToFrontLocked(taskId, flags, options); 8475 } 8476 } 8477 8478 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8479 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8480 Binder.getCallingUid(), -1, -1, "Task to front")) { 8481 ActivityOptions.abort(options); 8482 return; 8483 } 8484 final long origId = Binder.clearCallingIdentity(); 8485 try { 8486 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8487 if (task == null) { 8488 Slog.d(TAG, "Could not find task for id: "+ taskId); 8489 return; 8490 } 8491 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8492 mStackSupervisor.showLockTaskToast(); 8493 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8494 return; 8495 } 8496 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8497 if (prev != null && prev.isRecentsActivity()) { 8498 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8499 } 8500 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8501 } finally { 8502 Binder.restoreCallingIdentity(origId); 8503 } 8504 ActivityOptions.abort(options); 8505 } 8506 8507 @Override 8508 public void moveTaskToBack(int taskId) { 8509 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8510 "moveTaskToBack()"); 8511 8512 synchronized(this) { 8513 TaskRecord tr = taskForIdLocked(taskId); 8514 if (tr != null) { 8515 if (tr == mStackSupervisor.mLockTaskModeTask) { 8516 mStackSupervisor.showLockTaskToast(); 8517 return; 8518 } 8519 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8520 ActivityStack stack = tr.stack; 8521 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8522 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8523 Binder.getCallingUid(), -1, -1, "Task to back")) { 8524 return; 8525 } 8526 } 8527 final long origId = Binder.clearCallingIdentity(); 8528 try { 8529 stack.moveTaskToBackLocked(taskId, null); 8530 } finally { 8531 Binder.restoreCallingIdentity(origId); 8532 } 8533 } 8534 } 8535 } 8536 8537 /** 8538 * Moves an activity, and all of the other activities within the same task, to the bottom 8539 * of the history stack. The activity's order within the task is unchanged. 8540 * 8541 * @param token A reference to the activity we wish to move 8542 * @param nonRoot If false then this only works if the activity is the root 8543 * of a task; if true it will work for any activity in a task. 8544 * @return Returns true if the move completed, false if not. 8545 */ 8546 @Override 8547 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8548 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8549 synchronized(this) { 8550 final long origId = Binder.clearCallingIdentity(); 8551 try { 8552 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8553 if (taskId >= 0) { 8554 if ((mStackSupervisor.mLockTaskModeTask != null) 8555 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8556 mStackSupervisor.showLockTaskToast(); 8557 return false; 8558 } 8559 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8560 } 8561 } finally { 8562 Binder.restoreCallingIdentity(origId); 8563 } 8564 } 8565 return false; 8566 } 8567 8568 @Override 8569 public void moveTaskBackwards(int task) { 8570 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8571 "moveTaskBackwards()"); 8572 8573 synchronized(this) { 8574 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8575 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8576 return; 8577 } 8578 final long origId = Binder.clearCallingIdentity(); 8579 moveTaskBackwardsLocked(task); 8580 Binder.restoreCallingIdentity(origId); 8581 } 8582 } 8583 8584 private final void moveTaskBackwardsLocked(int task) { 8585 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8586 } 8587 8588 @Override 8589 public IBinder getHomeActivityToken() throws RemoteException { 8590 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8591 "getHomeActivityToken()"); 8592 synchronized (this) { 8593 return mStackSupervisor.getHomeActivityToken(); 8594 } 8595 } 8596 8597 @Override 8598 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8599 IActivityContainerCallback callback) throws RemoteException { 8600 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8601 "createActivityContainer()"); 8602 synchronized (this) { 8603 if (parentActivityToken == null) { 8604 throw new IllegalArgumentException("parent token must not be null"); 8605 } 8606 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8607 if (r == null) { 8608 return null; 8609 } 8610 if (callback == null) { 8611 throw new IllegalArgumentException("callback must not be null"); 8612 } 8613 return mStackSupervisor.createActivityContainer(r, callback); 8614 } 8615 } 8616 8617 @Override 8618 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8619 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8620 "deleteActivityContainer()"); 8621 synchronized (this) { 8622 mStackSupervisor.deleteActivityContainer(container); 8623 } 8624 } 8625 8626 @Override 8627 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8628 throws RemoteException { 8629 synchronized (this) { 8630 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8631 if (stack != null) { 8632 return stack.mActivityContainer; 8633 } 8634 return null; 8635 } 8636 } 8637 8638 @Override 8639 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8640 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8641 "moveTaskToStack()"); 8642 if (stackId == HOME_STACK_ID) { 8643 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8644 new RuntimeException("here").fillInStackTrace()); 8645 } 8646 synchronized (this) { 8647 long ident = Binder.clearCallingIdentity(); 8648 try { 8649 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8650 + stackId + " toTop=" + toTop); 8651 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8652 } finally { 8653 Binder.restoreCallingIdentity(ident); 8654 } 8655 } 8656 } 8657 8658 @Override 8659 public void resizeStack(int stackBoxId, Rect bounds) { 8660 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8661 "resizeStackBox()"); 8662 long ident = Binder.clearCallingIdentity(); 8663 try { 8664 mWindowManager.resizeStack(stackBoxId, bounds); 8665 } finally { 8666 Binder.restoreCallingIdentity(ident); 8667 } 8668 } 8669 8670 @Override 8671 public List<StackInfo> getAllStackInfos() { 8672 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8673 "getAllStackInfos()"); 8674 long ident = Binder.clearCallingIdentity(); 8675 try { 8676 synchronized (this) { 8677 return mStackSupervisor.getAllStackInfosLocked(); 8678 } 8679 } finally { 8680 Binder.restoreCallingIdentity(ident); 8681 } 8682 } 8683 8684 @Override 8685 public StackInfo getStackInfo(int stackId) { 8686 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8687 "getStackInfo()"); 8688 long ident = Binder.clearCallingIdentity(); 8689 try { 8690 synchronized (this) { 8691 return mStackSupervisor.getStackInfoLocked(stackId); 8692 } 8693 } finally { 8694 Binder.restoreCallingIdentity(ident); 8695 } 8696 } 8697 8698 @Override 8699 public boolean isInHomeStack(int taskId) { 8700 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8701 "getStackInfo()"); 8702 long ident = Binder.clearCallingIdentity(); 8703 try { 8704 synchronized (this) { 8705 TaskRecord tr = taskForIdLocked(taskId); 8706 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8707 } 8708 } finally { 8709 Binder.restoreCallingIdentity(ident); 8710 } 8711 } 8712 8713 @Override 8714 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8715 synchronized(this) { 8716 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8717 } 8718 } 8719 8720 private boolean isLockTaskAuthorized(String pkg) { 8721 final DevicePolicyManager dpm = (DevicePolicyManager) 8722 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8723 try { 8724 int uid = mContext.getPackageManager().getPackageUid(pkg, 8725 Binder.getCallingUserHandle().getIdentifier()); 8726 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8727 } catch (NameNotFoundException e) { 8728 return false; 8729 } 8730 } 8731 8732 void startLockTaskMode(TaskRecord task) { 8733 final String pkg; 8734 synchronized (this) { 8735 pkg = task.intent.getComponent().getPackageName(); 8736 } 8737 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8738 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8739 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8740 StatusBarManagerInternal.class); 8741 if (statusBarManager != null) { 8742 statusBarManager.showScreenPinningRequest(); 8743 } 8744 return; 8745 } 8746 long ident = Binder.clearCallingIdentity(); 8747 try { 8748 synchronized (this) { 8749 // Since we lost lock on task, make sure it is still there. 8750 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8751 if (task != null) { 8752 if (!isSystemInitiated 8753 && ((mStackSupervisor.getFocusedStack() == null) 8754 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8755 throw new IllegalArgumentException("Invalid task, not in foreground"); 8756 } 8757 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8758 } 8759 } 8760 } finally { 8761 Binder.restoreCallingIdentity(ident); 8762 } 8763 } 8764 8765 @Override 8766 public void startLockTaskMode(int taskId) { 8767 final TaskRecord task; 8768 long ident = Binder.clearCallingIdentity(); 8769 try { 8770 synchronized (this) { 8771 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8772 } 8773 } finally { 8774 Binder.restoreCallingIdentity(ident); 8775 } 8776 if (task != null) { 8777 startLockTaskMode(task); 8778 } 8779 } 8780 8781 @Override 8782 public void startLockTaskMode(IBinder token) { 8783 final TaskRecord task; 8784 long ident = Binder.clearCallingIdentity(); 8785 try { 8786 synchronized (this) { 8787 final ActivityRecord r = ActivityRecord.forToken(token); 8788 if (r == null) { 8789 return; 8790 } 8791 task = r.task; 8792 } 8793 } finally { 8794 Binder.restoreCallingIdentity(ident); 8795 } 8796 if (task != null) { 8797 startLockTaskMode(task); 8798 } 8799 } 8800 8801 @Override 8802 public void startLockTaskModeOnCurrent() throws RemoteException { 8803 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8804 "startLockTaskModeOnCurrent"); 8805 long ident = Binder.clearCallingIdentity(); 8806 try { 8807 ActivityRecord r = null; 8808 synchronized (this) { 8809 r = mStackSupervisor.topRunningActivityLocked(); 8810 } 8811 startLockTaskMode(r.task); 8812 } finally { 8813 Binder.restoreCallingIdentity(ident); 8814 } 8815 } 8816 8817 @Override 8818 public void stopLockTaskMode() { 8819 // Verify that the user matches the package of the intent for the TaskRecord 8820 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8821 // and stopLockTaskMode. 8822 final int callingUid = Binder.getCallingUid(); 8823 if (callingUid != Process.SYSTEM_UID) { 8824 try { 8825 String pkg = 8826 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8827 int uid = mContext.getPackageManager().getPackageUid(pkg, 8828 Binder.getCallingUserHandle().getIdentifier()); 8829 if (uid != callingUid) { 8830 throw new SecurityException("Invalid uid, expected " + uid); 8831 } 8832 } catch (NameNotFoundException e) { 8833 Log.d(TAG, "stopLockTaskMode " + e); 8834 return; 8835 } 8836 } 8837 long ident = Binder.clearCallingIdentity(); 8838 try { 8839 Log.d(TAG, "stopLockTaskMode"); 8840 // Stop lock task 8841 synchronized (this) { 8842 mStackSupervisor.setLockTaskModeLocked(null, false); 8843 } 8844 } finally { 8845 Binder.restoreCallingIdentity(ident); 8846 } 8847 } 8848 8849 @Override 8850 public void stopLockTaskModeOnCurrent() throws RemoteException { 8851 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8852 "stopLockTaskModeOnCurrent"); 8853 long ident = Binder.clearCallingIdentity(); 8854 try { 8855 stopLockTaskMode(); 8856 } finally { 8857 Binder.restoreCallingIdentity(ident); 8858 } 8859 } 8860 8861 @Override 8862 public boolean isInLockTaskMode() { 8863 synchronized (this) { 8864 return mStackSupervisor.isInLockTaskMode(); 8865 } 8866 } 8867 8868 // ========================================================= 8869 // CONTENT PROVIDERS 8870 // ========================================================= 8871 8872 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8873 List<ProviderInfo> providers = null; 8874 try { 8875 providers = AppGlobals.getPackageManager(). 8876 queryContentProviders(app.processName, app.uid, 8877 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8878 } catch (RemoteException ex) { 8879 } 8880 if (DEBUG_MU) 8881 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8882 int userId = app.userId; 8883 if (providers != null) { 8884 int N = providers.size(); 8885 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8886 for (int i=0; i<N; i++) { 8887 ProviderInfo cpi = 8888 (ProviderInfo)providers.get(i); 8889 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8890 cpi.name, cpi.flags); 8891 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8892 // This is a singleton provider, but a user besides the 8893 // default user is asking to initialize a process it runs 8894 // in... well, no, it doesn't actually run in this process, 8895 // it runs in the process of the default user. Get rid of it. 8896 providers.remove(i); 8897 N--; 8898 i--; 8899 continue; 8900 } 8901 8902 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8903 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8904 if (cpr == null) { 8905 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8906 mProviderMap.putProviderByClass(comp, cpr); 8907 } 8908 if (DEBUG_MU) 8909 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8910 app.pubProviders.put(cpi.name, cpr); 8911 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8912 // Don't add this if it is a platform component that is marked 8913 // to run in multiple processes, because this is actually 8914 // part of the framework so doesn't make sense to track as a 8915 // separate apk in the process. 8916 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8917 mProcessStats); 8918 } 8919 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8920 } 8921 } 8922 return providers; 8923 } 8924 8925 /** 8926 * Check if {@link ProcessRecord} has a possible chance at accessing the 8927 * given {@link ProviderInfo}. Final permission checking is always done 8928 * in {@link ContentProvider}. 8929 */ 8930 private final String checkContentProviderPermissionLocked( 8931 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8932 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8933 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8934 boolean checkedGrants = false; 8935 if (checkUser) { 8936 // Looking for cross-user grants before enforcing the typical cross-users permissions 8937 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8938 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8939 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8940 return null; 8941 } 8942 checkedGrants = true; 8943 } 8944 userId = handleIncomingUser(callingPid, callingUid, userId, 8945 false, ALLOW_NON_FULL, 8946 "checkContentProviderPermissionLocked " + cpi.authority, null); 8947 if (userId != tmpTargetUserId) { 8948 // When we actually went to determine the final targer user ID, this ended 8949 // up different than our initial check for the authority. This is because 8950 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8951 // SELF. So we need to re-check the grants again. 8952 checkedGrants = false; 8953 } 8954 } 8955 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8956 cpi.applicationInfo.uid, cpi.exported) 8957 == PackageManager.PERMISSION_GRANTED) { 8958 return null; 8959 } 8960 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8961 cpi.applicationInfo.uid, cpi.exported) 8962 == PackageManager.PERMISSION_GRANTED) { 8963 return null; 8964 } 8965 8966 PathPermission[] pps = cpi.pathPermissions; 8967 if (pps != null) { 8968 int i = pps.length; 8969 while (i > 0) { 8970 i--; 8971 PathPermission pp = pps[i]; 8972 String pprperm = pp.getReadPermission(); 8973 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8974 cpi.applicationInfo.uid, cpi.exported) 8975 == PackageManager.PERMISSION_GRANTED) { 8976 return null; 8977 } 8978 String ppwperm = pp.getWritePermission(); 8979 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8980 cpi.applicationInfo.uid, cpi.exported) 8981 == PackageManager.PERMISSION_GRANTED) { 8982 return null; 8983 } 8984 } 8985 } 8986 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8987 return null; 8988 } 8989 8990 String msg; 8991 if (!cpi.exported) { 8992 msg = "Permission Denial: opening provider " + cpi.name 8993 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8994 + ", uid=" + callingUid + ") that is not exported from uid " 8995 + cpi.applicationInfo.uid; 8996 } else { 8997 msg = "Permission Denial: opening provider " + cpi.name 8998 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8999 + ", uid=" + callingUid + ") requires " 9000 + cpi.readPermission + " or " + cpi.writePermission; 9001 } 9002 Slog.w(TAG, msg); 9003 return msg; 9004 } 9005 9006 /** 9007 * Returns if the ContentProvider has granted a uri to callingUid 9008 */ 9009 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9010 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9011 if (perms != null) { 9012 for (int i=perms.size()-1; i>=0; i--) { 9013 GrantUri grantUri = perms.keyAt(i); 9014 if (grantUri.sourceUserId == userId || !checkUser) { 9015 if (matchesProvider(grantUri.uri, cpi)) { 9016 return true; 9017 } 9018 } 9019 } 9020 } 9021 return false; 9022 } 9023 9024 /** 9025 * Returns true if the uri authority is one of the authorities specified in the provider. 9026 */ 9027 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9028 String uriAuth = uri.getAuthority(); 9029 String cpiAuth = cpi.authority; 9030 if (cpiAuth.indexOf(';') == -1) { 9031 return cpiAuth.equals(uriAuth); 9032 } 9033 String[] cpiAuths = cpiAuth.split(";"); 9034 int length = cpiAuths.length; 9035 for (int i = 0; i < length; i++) { 9036 if (cpiAuths[i].equals(uriAuth)) return true; 9037 } 9038 return false; 9039 } 9040 9041 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9042 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9043 if (r != null) { 9044 for (int i=0; i<r.conProviders.size(); i++) { 9045 ContentProviderConnection conn = r.conProviders.get(i); 9046 if (conn.provider == cpr) { 9047 if (DEBUG_PROVIDER) Slog.v(TAG, 9048 "Adding provider requested by " 9049 + r.processName + " from process " 9050 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9051 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9052 if (stable) { 9053 conn.stableCount++; 9054 conn.numStableIncs++; 9055 } else { 9056 conn.unstableCount++; 9057 conn.numUnstableIncs++; 9058 } 9059 return conn; 9060 } 9061 } 9062 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9063 if (stable) { 9064 conn.stableCount = 1; 9065 conn.numStableIncs = 1; 9066 } else { 9067 conn.unstableCount = 1; 9068 conn.numUnstableIncs = 1; 9069 } 9070 cpr.connections.add(conn); 9071 r.conProviders.add(conn); 9072 return conn; 9073 } 9074 cpr.addExternalProcessHandleLocked(externalProcessToken); 9075 return null; 9076 } 9077 9078 boolean decProviderCountLocked(ContentProviderConnection conn, 9079 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9080 if (conn != null) { 9081 cpr = conn.provider; 9082 if (DEBUG_PROVIDER) Slog.v(TAG, 9083 "Removing provider requested by " 9084 + conn.client.processName + " from process " 9085 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9086 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9087 if (stable) { 9088 conn.stableCount--; 9089 } else { 9090 conn.unstableCount--; 9091 } 9092 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9093 cpr.connections.remove(conn); 9094 conn.client.conProviders.remove(conn); 9095 return true; 9096 } 9097 return false; 9098 } 9099 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9100 return false; 9101 } 9102 9103 private void checkTime(long startTime, String where) { 9104 long now = SystemClock.elapsedRealtime(); 9105 if ((now-startTime) > 1000) { 9106 // If we are taking more than a second, log about it. 9107 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9108 } 9109 } 9110 9111 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9112 String name, IBinder token, boolean stable, int userId) { 9113 ContentProviderRecord cpr; 9114 ContentProviderConnection conn = null; 9115 ProviderInfo cpi = null; 9116 9117 synchronized(this) { 9118 long startTime = SystemClock.elapsedRealtime(); 9119 9120 ProcessRecord r = null; 9121 if (caller != null) { 9122 r = getRecordForAppLocked(caller); 9123 if (r == null) { 9124 throw new SecurityException( 9125 "Unable to find app for caller " + caller 9126 + " (pid=" + Binder.getCallingPid() 9127 + ") when getting content provider " + name); 9128 } 9129 } 9130 9131 boolean checkCrossUser = true; 9132 9133 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9134 9135 // First check if this content provider has been published... 9136 cpr = mProviderMap.getProviderByName(name, userId); 9137 // If that didn't work, check if it exists for user 0 and then 9138 // verify that it's a singleton provider before using it. 9139 if (cpr == null && userId != UserHandle.USER_OWNER) { 9140 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9141 if (cpr != null) { 9142 cpi = cpr.info; 9143 if (isSingleton(cpi.processName, cpi.applicationInfo, 9144 cpi.name, cpi.flags) 9145 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9146 userId = UserHandle.USER_OWNER; 9147 checkCrossUser = false; 9148 } else { 9149 cpr = null; 9150 cpi = null; 9151 } 9152 } 9153 } 9154 9155 boolean providerRunning = cpr != null; 9156 if (providerRunning) { 9157 cpi = cpr.info; 9158 String msg; 9159 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9160 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9161 != null) { 9162 throw new SecurityException(msg); 9163 } 9164 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9165 9166 if (r != null && cpr.canRunHere(r)) { 9167 // This provider has been published or is in the process 9168 // of being published... but it is also allowed to run 9169 // in the caller's process, so don't make a connection 9170 // and just let the caller instantiate its own instance. 9171 ContentProviderHolder holder = cpr.newHolder(null); 9172 // don't give caller the provider object, it needs 9173 // to make its own. 9174 holder.provider = null; 9175 return holder; 9176 } 9177 9178 final long origId = Binder.clearCallingIdentity(); 9179 9180 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9181 9182 // In this case the provider instance already exists, so we can 9183 // return it right away. 9184 conn = incProviderCountLocked(r, cpr, token, stable); 9185 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9186 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9187 // If this is a perceptible app accessing the provider, 9188 // make sure to count it as being accessed and thus 9189 // back up on the LRU list. This is good because 9190 // content providers are often expensive to start. 9191 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9192 updateLruProcessLocked(cpr.proc, false, null); 9193 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9194 } 9195 } 9196 9197 if (cpr.proc != null) { 9198 if (false) { 9199 if (cpr.name.flattenToShortString().equals( 9200 "com.android.providers.calendar/.CalendarProvider2")) { 9201 Slog.v(TAG, "****************** KILLING " 9202 + cpr.name.flattenToShortString()); 9203 Process.killProcess(cpr.proc.pid); 9204 } 9205 } 9206 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9207 boolean success = updateOomAdjLocked(cpr.proc); 9208 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9209 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9210 // NOTE: there is still a race here where a signal could be 9211 // pending on the process even though we managed to update its 9212 // adj level. Not sure what to do about this, but at least 9213 // the race is now smaller. 9214 if (!success) { 9215 // Uh oh... it looks like the provider's process 9216 // has been killed on us. We need to wait for a new 9217 // process to be started, and make sure its death 9218 // doesn't kill our process. 9219 Slog.i(TAG, 9220 "Existing provider " + cpr.name.flattenToShortString() 9221 + " is crashing; detaching " + r); 9222 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9223 checkTime(startTime, "getContentProviderImpl: before appDied"); 9224 appDiedLocked(cpr.proc); 9225 checkTime(startTime, "getContentProviderImpl: after appDied"); 9226 if (!lastRef) { 9227 // This wasn't the last ref our process had on 9228 // the provider... we have now been killed, bail. 9229 return null; 9230 } 9231 providerRunning = false; 9232 conn = null; 9233 } 9234 } 9235 9236 Binder.restoreCallingIdentity(origId); 9237 } 9238 9239 boolean singleton; 9240 if (!providerRunning) { 9241 try { 9242 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9243 cpi = AppGlobals.getPackageManager(). 9244 resolveContentProvider(name, 9245 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9246 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9247 } catch (RemoteException ex) { 9248 } 9249 if (cpi == null) { 9250 return null; 9251 } 9252 // If the provider is a singleton AND 9253 // (it's a call within the same user || the provider is a 9254 // privileged app) 9255 // Then allow connecting to the singleton provider 9256 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9257 cpi.name, cpi.flags) 9258 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9259 if (singleton) { 9260 userId = UserHandle.USER_OWNER; 9261 } 9262 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9263 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9264 9265 String msg; 9266 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9267 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9268 != null) { 9269 throw new SecurityException(msg); 9270 } 9271 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9272 9273 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9274 && !cpi.processName.equals("system")) { 9275 // If this content provider does not run in the system 9276 // process, and the system is not yet ready to run other 9277 // processes, then fail fast instead of hanging. 9278 throw new IllegalArgumentException( 9279 "Attempt to launch content provider before system ready"); 9280 } 9281 9282 // Make sure that the user who owns this provider is started. If not, 9283 // we don't want to allow it to run. 9284 if (mStartedUsers.get(userId) == null) { 9285 Slog.w(TAG, "Unable to launch app " 9286 + cpi.applicationInfo.packageName + "/" 9287 + cpi.applicationInfo.uid + " for provider " 9288 + name + ": user " + userId + " is stopped"); 9289 return null; 9290 } 9291 9292 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9293 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9294 cpr = mProviderMap.getProviderByClass(comp, userId); 9295 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9296 final boolean firstClass = cpr == null; 9297 if (firstClass) { 9298 final long ident = Binder.clearCallingIdentity(); 9299 try { 9300 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9301 ApplicationInfo ai = 9302 AppGlobals.getPackageManager(). 9303 getApplicationInfo( 9304 cpi.applicationInfo.packageName, 9305 STOCK_PM_FLAGS, userId); 9306 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9307 if (ai == null) { 9308 Slog.w(TAG, "No package info for content provider " 9309 + cpi.name); 9310 return null; 9311 } 9312 ai = getAppInfoForUser(ai, userId); 9313 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9314 } catch (RemoteException ex) { 9315 // pm is in same process, this will never happen. 9316 } finally { 9317 Binder.restoreCallingIdentity(ident); 9318 } 9319 } 9320 9321 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9322 9323 if (r != null && cpr.canRunHere(r)) { 9324 // If this is a multiprocess provider, then just return its 9325 // info and allow the caller to instantiate it. Only do 9326 // this if the provider is the same user as the caller's 9327 // process, or can run as root (so can be in any process). 9328 return cpr.newHolder(null); 9329 } 9330 9331 if (DEBUG_PROVIDER) { 9332 RuntimeException e = new RuntimeException("here"); 9333 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9334 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9335 } 9336 9337 // This is single process, and our app is now connecting to it. 9338 // See if we are already in the process of launching this 9339 // provider. 9340 final int N = mLaunchingProviders.size(); 9341 int i; 9342 for (i=0; i<N; i++) { 9343 if (mLaunchingProviders.get(i) == cpr) { 9344 break; 9345 } 9346 } 9347 9348 // If the provider is not already being launched, then get it 9349 // started. 9350 if (i >= N) { 9351 final long origId = Binder.clearCallingIdentity(); 9352 9353 try { 9354 // Content provider is now in use, its package can't be stopped. 9355 try { 9356 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9357 AppGlobals.getPackageManager().setPackageStoppedState( 9358 cpr.appInfo.packageName, false, userId); 9359 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9360 } catch (RemoteException e) { 9361 } catch (IllegalArgumentException e) { 9362 Slog.w(TAG, "Failed trying to unstop package " 9363 + cpr.appInfo.packageName + ": " + e); 9364 } 9365 9366 // Use existing process if already started 9367 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9368 ProcessRecord proc = getProcessRecordLocked( 9369 cpi.processName, cpr.appInfo.uid, false); 9370 if (proc != null && proc.thread != null) { 9371 if (DEBUG_PROVIDER) { 9372 Slog.d(TAG, "Installing in existing process " + proc); 9373 } 9374 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9375 proc.pubProviders.put(cpi.name, cpr); 9376 try { 9377 proc.thread.scheduleInstallProvider(cpi); 9378 } catch (RemoteException e) { 9379 } 9380 } else { 9381 checkTime(startTime, "getContentProviderImpl: before start process"); 9382 proc = startProcessLocked(cpi.processName, 9383 cpr.appInfo, false, 0, "content provider", 9384 new ComponentName(cpi.applicationInfo.packageName, 9385 cpi.name), false, false, false); 9386 checkTime(startTime, "getContentProviderImpl: after start process"); 9387 if (proc == null) { 9388 Slog.w(TAG, "Unable to launch app " 9389 + cpi.applicationInfo.packageName + "/" 9390 + cpi.applicationInfo.uid + " for provider " 9391 + name + ": process is bad"); 9392 return null; 9393 } 9394 } 9395 cpr.launchingApp = proc; 9396 mLaunchingProviders.add(cpr); 9397 } finally { 9398 Binder.restoreCallingIdentity(origId); 9399 } 9400 } 9401 9402 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9403 9404 // Make sure the provider is published (the same provider class 9405 // may be published under multiple names). 9406 if (firstClass) { 9407 mProviderMap.putProviderByClass(comp, cpr); 9408 } 9409 9410 mProviderMap.putProviderByName(name, cpr); 9411 conn = incProviderCountLocked(r, cpr, token, stable); 9412 if (conn != null) { 9413 conn.waiting = true; 9414 } 9415 } 9416 checkTime(startTime, "getContentProviderImpl: done!"); 9417 } 9418 9419 // Wait for the provider to be published... 9420 synchronized (cpr) { 9421 while (cpr.provider == null) { 9422 if (cpr.launchingApp == null) { 9423 Slog.w(TAG, "Unable to launch app " 9424 + cpi.applicationInfo.packageName + "/" 9425 + cpi.applicationInfo.uid + " for provider " 9426 + name + ": launching app became null"); 9427 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9428 UserHandle.getUserId(cpi.applicationInfo.uid), 9429 cpi.applicationInfo.packageName, 9430 cpi.applicationInfo.uid, name); 9431 return null; 9432 } 9433 try { 9434 if (DEBUG_MU) { 9435 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9436 + cpr.launchingApp); 9437 } 9438 if (conn != null) { 9439 conn.waiting = true; 9440 } 9441 cpr.wait(); 9442 } catch (InterruptedException ex) { 9443 } finally { 9444 if (conn != null) { 9445 conn.waiting = false; 9446 } 9447 } 9448 } 9449 } 9450 return cpr != null ? cpr.newHolder(conn) : null; 9451 } 9452 9453 @Override 9454 public final ContentProviderHolder getContentProvider( 9455 IApplicationThread caller, String name, int userId, boolean stable) { 9456 enforceNotIsolatedCaller("getContentProvider"); 9457 if (caller == null) { 9458 String msg = "null IApplicationThread when getting content provider " 9459 + name; 9460 Slog.w(TAG, msg); 9461 throw new SecurityException(msg); 9462 } 9463 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9464 // with cross-user grant. 9465 return getContentProviderImpl(caller, name, null, stable, userId); 9466 } 9467 9468 public ContentProviderHolder getContentProviderExternal( 9469 String name, int userId, IBinder token) { 9470 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9471 "Do not have permission in call getContentProviderExternal()"); 9472 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9473 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9474 return getContentProviderExternalUnchecked(name, token, userId); 9475 } 9476 9477 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9478 IBinder token, int userId) { 9479 return getContentProviderImpl(null, name, token, true, userId); 9480 } 9481 9482 /** 9483 * Drop a content provider from a ProcessRecord's bookkeeping 9484 */ 9485 public void removeContentProvider(IBinder connection, boolean stable) { 9486 enforceNotIsolatedCaller("removeContentProvider"); 9487 long ident = Binder.clearCallingIdentity(); 9488 try { 9489 synchronized (this) { 9490 ContentProviderConnection conn; 9491 try { 9492 conn = (ContentProviderConnection)connection; 9493 } catch (ClassCastException e) { 9494 String msg ="removeContentProvider: " + connection 9495 + " not a ContentProviderConnection"; 9496 Slog.w(TAG, msg); 9497 throw new IllegalArgumentException(msg); 9498 } 9499 if (conn == null) { 9500 throw new NullPointerException("connection is null"); 9501 } 9502 if (decProviderCountLocked(conn, null, null, stable)) { 9503 updateOomAdjLocked(); 9504 } 9505 } 9506 } finally { 9507 Binder.restoreCallingIdentity(ident); 9508 } 9509 } 9510 9511 public void removeContentProviderExternal(String name, IBinder token) { 9512 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9513 "Do not have permission in call removeContentProviderExternal()"); 9514 int userId = UserHandle.getCallingUserId(); 9515 long ident = Binder.clearCallingIdentity(); 9516 try { 9517 removeContentProviderExternalUnchecked(name, token, userId); 9518 } finally { 9519 Binder.restoreCallingIdentity(ident); 9520 } 9521 } 9522 9523 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9524 synchronized (this) { 9525 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9526 if(cpr == null) { 9527 //remove from mProvidersByClass 9528 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9529 return; 9530 } 9531 9532 //update content provider record entry info 9533 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9534 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9535 if (localCpr.hasExternalProcessHandles()) { 9536 if (localCpr.removeExternalProcessHandleLocked(token)) { 9537 updateOomAdjLocked(); 9538 } else { 9539 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9540 + " with no external reference for token: " 9541 + token + "."); 9542 } 9543 } else { 9544 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9545 + " with no external references."); 9546 } 9547 } 9548 } 9549 9550 public final void publishContentProviders(IApplicationThread caller, 9551 List<ContentProviderHolder> providers) { 9552 if (providers == null) { 9553 return; 9554 } 9555 9556 enforceNotIsolatedCaller("publishContentProviders"); 9557 synchronized (this) { 9558 final ProcessRecord r = getRecordForAppLocked(caller); 9559 if (DEBUG_MU) 9560 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9561 if (r == null) { 9562 throw new SecurityException( 9563 "Unable to find app for caller " + caller 9564 + " (pid=" + Binder.getCallingPid() 9565 + ") when publishing content providers"); 9566 } 9567 9568 final long origId = Binder.clearCallingIdentity(); 9569 9570 final int N = providers.size(); 9571 for (int i=0; i<N; i++) { 9572 ContentProviderHolder src = providers.get(i); 9573 if (src == null || src.info == null || src.provider == null) { 9574 continue; 9575 } 9576 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9577 if (DEBUG_MU) 9578 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9579 if (dst != null) { 9580 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9581 mProviderMap.putProviderByClass(comp, dst); 9582 String names[] = dst.info.authority.split(";"); 9583 for (int j = 0; j < names.length; j++) { 9584 mProviderMap.putProviderByName(names[j], dst); 9585 } 9586 9587 int NL = mLaunchingProviders.size(); 9588 int j; 9589 for (j=0; j<NL; j++) { 9590 if (mLaunchingProviders.get(j) == dst) { 9591 mLaunchingProviders.remove(j); 9592 j--; 9593 NL--; 9594 } 9595 } 9596 synchronized (dst) { 9597 dst.provider = src.provider; 9598 dst.proc = r; 9599 dst.notifyAll(); 9600 } 9601 updateOomAdjLocked(r); 9602 } 9603 } 9604 9605 Binder.restoreCallingIdentity(origId); 9606 } 9607 } 9608 9609 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9610 ContentProviderConnection conn; 9611 try { 9612 conn = (ContentProviderConnection)connection; 9613 } catch (ClassCastException e) { 9614 String msg ="refContentProvider: " + connection 9615 + " not a ContentProviderConnection"; 9616 Slog.w(TAG, msg); 9617 throw new IllegalArgumentException(msg); 9618 } 9619 if (conn == null) { 9620 throw new NullPointerException("connection is null"); 9621 } 9622 9623 synchronized (this) { 9624 if (stable > 0) { 9625 conn.numStableIncs += stable; 9626 } 9627 stable = conn.stableCount + stable; 9628 if (stable < 0) { 9629 throw new IllegalStateException("stableCount < 0: " + stable); 9630 } 9631 9632 if (unstable > 0) { 9633 conn.numUnstableIncs += unstable; 9634 } 9635 unstable = conn.unstableCount + unstable; 9636 if (unstable < 0) { 9637 throw new IllegalStateException("unstableCount < 0: " + unstable); 9638 } 9639 9640 if ((stable+unstable) <= 0) { 9641 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9642 + stable + " unstable=" + unstable); 9643 } 9644 conn.stableCount = stable; 9645 conn.unstableCount = unstable; 9646 return !conn.dead; 9647 } 9648 } 9649 9650 public void unstableProviderDied(IBinder connection) { 9651 ContentProviderConnection conn; 9652 try { 9653 conn = (ContentProviderConnection)connection; 9654 } catch (ClassCastException e) { 9655 String msg ="refContentProvider: " + connection 9656 + " not a ContentProviderConnection"; 9657 Slog.w(TAG, msg); 9658 throw new IllegalArgumentException(msg); 9659 } 9660 if (conn == null) { 9661 throw new NullPointerException("connection is null"); 9662 } 9663 9664 // Safely retrieve the content provider associated with the connection. 9665 IContentProvider provider; 9666 synchronized (this) { 9667 provider = conn.provider.provider; 9668 } 9669 9670 if (provider == null) { 9671 // Um, yeah, we're way ahead of you. 9672 return; 9673 } 9674 9675 // Make sure the caller is being honest with us. 9676 if (provider.asBinder().pingBinder()) { 9677 // Er, no, still looks good to us. 9678 synchronized (this) { 9679 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9680 + " says " + conn + " died, but we don't agree"); 9681 return; 9682 } 9683 } 9684 9685 // Well look at that! It's dead! 9686 synchronized (this) { 9687 if (conn.provider.provider != provider) { 9688 // But something changed... good enough. 9689 return; 9690 } 9691 9692 ProcessRecord proc = conn.provider.proc; 9693 if (proc == null || proc.thread == null) { 9694 // Seems like the process is already cleaned up. 9695 return; 9696 } 9697 9698 // As far as we're concerned, this is just like receiving a 9699 // death notification... just a bit prematurely. 9700 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9701 + ") early provider death"); 9702 final long ident = Binder.clearCallingIdentity(); 9703 try { 9704 appDiedLocked(proc); 9705 } finally { 9706 Binder.restoreCallingIdentity(ident); 9707 } 9708 } 9709 } 9710 9711 @Override 9712 public void appNotRespondingViaProvider(IBinder connection) { 9713 enforceCallingPermission( 9714 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9715 9716 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9717 if (conn == null) { 9718 Slog.w(TAG, "ContentProviderConnection is null"); 9719 return; 9720 } 9721 9722 final ProcessRecord host = conn.provider.proc; 9723 if (host == null) { 9724 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9725 return; 9726 } 9727 9728 final long token = Binder.clearCallingIdentity(); 9729 try { 9730 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9731 } finally { 9732 Binder.restoreCallingIdentity(token); 9733 } 9734 } 9735 9736 public final void installSystemProviders() { 9737 List<ProviderInfo> providers; 9738 synchronized (this) { 9739 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9740 providers = generateApplicationProvidersLocked(app); 9741 if (providers != null) { 9742 for (int i=providers.size()-1; i>=0; i--) { 9743 ProviderInfo pi = (ProviderInfo)providers.get(i); 9744 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9745 Slog.w(TAG, "Not installing system proc provider " + pi.name 9746 + ": not system .apk"); 9747 providers.remove(i); 9748 } 9749 } 9750 } 9751 } 9752 if (providers != null) { 9753 mSystemThread.installSystemProviders(providers); 9754 } 9755 9756 mCoreSettingsObserver = new CoreSettingsObserver(this); 9757 9758 //mUsageStatsService.monitorPackages(); 9759 } 9760 9761 /** 9762 * Allows apps to retrieve the MIME type of a URI. 9763 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9764 * users, then it does not need permission to access the ContentProvider. 9765 * Either, it needs cross-user uri grants. 9766 * 9767 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9768 * 9769 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9770 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9771 */ 9772 public String getProviderMimeType(Uri uri, int userId) { 9773 enforceNotIsolatedCaller("getProviderMimeType"); 9774 final String name = uri.getAuthority(); 9775 int callingUid = Binder.getCallingUid(); 9776 int callingPid = Binder.getCallingPid(); 9777 long ident = 0; 9778 boolean clearedIdentity = false; 9779 userId = unsafeConvertIncomingUser(userId); 9780 if (canClearIdentity(callingPid, callingUid, userId)) { 9781 clearedIdentity = true; 9782 ident = Binder.clearCallingIdentity(); 9783 } 9784 ContentProviderHolder holder = null; 9785 try { 9786 holder = getContentProviderExternalUnchecked(name, null, userId); 9787 if (holder != null) { 9788 return holder.provider.getType(uri); 9789 } 9790 } catch (RemoteException e) { 9791 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9792 return null; 9793 } finally { 9794 // We need to clear the identity to call removeContentProviderExternalUnchecked 9795 if (!clearedIdentity) { 9796 ident = Binder.clearCallingIdentity(); 9797 } 9798 try { 9799 if (holder != null) { 9800 removeContentProviderExternalUnchecked(name, null, userId); 9801 } 9802 } finally { 9803 Binder.restoreCallingIdentity(ident); 9804 } 9805 } 9806 9807 return null; 9808 } 9809 9810 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9811 if (UserHandle.getUserId(callingUid) == userId) { 9812 return true; 9813 } 9814 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9815 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9816 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9817 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9818 return true; 9819 } 9820 return false; 9821 } 9822 9823 // ========================================================= 9824 // GLOBAL MANAGEMENT 9825 // ========================================================= 9826 9827 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9828 boolean isolated, int isolatedUid) { 9829 String proc = customProcess != null ? customProcess : info.processName; 9830 BatteryStatsImpl.Uid.Proc ps = null; 9831 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9832 int uid = info.uid; 9833 if (isolated) { 9834 if (isolatedUid == 0) { 9835 int userId = UserHandle.getUserId(uid); 9836 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9837 while (true) { 9838 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9839 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9840 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9841 } 9842 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9843 mNextIsolatedProcessUid++; 9844 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9845 // No process for this uid, use it. 9846 break; 9847 } 9848 stepsLeft--; 9849 if (stepsLeft <= 0) { 9850 return null; 9851 } 9852 } 9853 } else { 9854 // Special case for startIsolatedProcess (internal only), where 9855 // the uid of the isolated process is specified by the caller. 9856 uid = isolatedUid; 9857 } 9858 } 9859 return new ProcessRecord(stats, info, proc, uid); 9860 } 9861 9862 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9863 String abiOverride) { 9864 ProcessRecord app; 9865 if (!isolated) { 9866 app = getProcessRecordLocked(info.processName, info.uid, true); 9867 } else { 9868 app = null; 9869 } 9870 9871 if (app == null) { 9872 app = newProcessRecordLocked(info, null, isolated, 0); 9873 mProcessNames.put(info.processName, app.uid, app); 9874 if (isolated) { 9875 mIsolatedProcesses.put(app.uid, app); 9876 } 9877 updateLruProcessLocked(app, false, null); 9878 updateOomAdjLocked(); 9879 } 9880 9881 // This package really, really can not be stopped. 9882 try { 9883 AppGlobals.getPackageManager().setPackageStoppedState( 9884 info.packageName, false, UserHandle.getUserId(app.uid)); 9885 } catch (RemoteException e) { 9886 } catch (IllegalArgumentException e) { 9887 Slog.w(TAG, "Failed trying to unstop package " 9888 + info.packageName + ": " + e); 9889 } 9890 9891 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9892 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9893 app.persistent = true; 9894 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9895 } 9896 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9897 mPersistentStartingProcesses.add(app); 9898 startProcessLocked(app, "added application", app.processName, abiOverride, 9899 null /* entryPoint */, null /* entryPointArgs */); 9900 } 9901 9902 return app; 9903 } 9904 9905 public void unhandledBack() { 9906 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9907 "unhandledBack()"); 9908 9909 synchronized(this) { 9910 final long origId = Binder.clearCallingIdentity(); 9911 try { 9912 getFocusedStack().unhandledBackLocked(); 9913 } finally { 9914 Binder.restoreCallingIdentity(origId); 9915 } 9916 } 9917 } 9918 9919 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9920 enforceNotIsolatedCaller("openContentUri"); 9921 final int userId = UserHandle.getCallingUserId(); 9922 String name = uri.getAuthority(); 9923 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9924 ParcelFileDescriptor pfd = null; 9925 if (cph != null) { 9926 // We record the binder invoker's uid in thread-local storage before 9927 // going to the content provider to open the file. Later, in the code 9928 // that handles all permissions checks, we look for this uid and use 9929 // that rather than the Activity Manager's own uid. The effect is that 9930 // we do the check against the caller's permissions even though it looks 9931 // to the content provider like the Activity Manager itself is making 9932 // the request. 9933 Binder token = new Binder(); 9934 sCallerIdentity.set(new Identity( 9935 token, Binder.getCallingPid(), Binder.getCallingUid())); 9936 try { 9937 pfd = cph.provider.openFile(null, uri, "r", null, token); 9938 } catch (FileNotFoundException e) { 9939 // do nothing; pfd will be returned null 9940 } finally { 9941 // Ensure that whatever happens, we clean up the identity state 9942 sCallerIdentity.remove(); 9943 } 9944 9945 // We've got the fd now, so we're done with the provider. 9946 removeContentProviderExternalUnchecked(name, null, userId); 9947 } else { 9948 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9949 } 9950 return pfd; 9951 } 9952 9953 // Actually is sleeping or shutting down or whatever else in the future 9954 // is an inactive state. 9955 public boolean isSleepingOrShuttingDown() { 9956 return isSleeping() || mShuttingDown; 9957 } 9958 9959 public boolean isSleeping() { 9960 return mSleeping; 9961 } 9962 9963 void onWakefulnessChanged(int wakefulness) { 9964 synchronized(this) { 9965 mWakefulness = wakefulness; 9966 updateSleepIfNeededLocked(); 9967 } 9968 } 9969 9970 void finishRunningVoiceLocked() { 9971 if (mRunningVoice) { 9972 mRunningVoice = false; 9973 updateSleepIfNeededLocked(); 9974 } 9975 } 9976 9977 void updateSleepIfNeededLocked() { 9978 if (mSleeping && !shouldSleepLocked()) { 9979 mSleeping = false; 9980 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9981 } else if (!mSleeping && shouldSleepLocked()) { 9982 mSleeping = true; 9983 mStackSupervisor.goingToSleepLocked(); 9984 9985 // Initialize the wake times of all processes. 9986 checkExcessivePowerUsageLocked(false); 9987 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9988 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9989 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9990 } 9991 } 9992 9993 private boolean shouldSleepLocked() { 9994 // Resume applications while running a voice interactor. 9995 if (mRunningVoice) { 9996 return false; 9997 } 9998 9999 switch (mWakefulness) { 10000 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10001 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10002 // If we're interactive but applications are already paused then defer 10003 // resuming them until the lock screen is hidden. 10004 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10005 case PowerManagerInternal.WAKEFULNESS_DOZING: 10006 // If we're dozing then pause applications whenever the lock screen is shown. 10007 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10008 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10009 default: 10010 // If we're asleep then pause applications unconditionally. 10011 return true; 10012 } 10013 } 10014 10015 /** Pokes the task persister. */ 10016 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10017 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10018 // Never persist the home stack. 10019 return; 10020 } 10021 mTaskPersister.wakeup(task, flush); 10022 } 10023 10024 /** Notifies all listeners when the task stack has changed. */ 10025 void notifyTaskStackChangedLocked() { 10026 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10027 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10028 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10029 } 10030 10031 @Override 10032 public boolean shutdown(int timeout) { 10033 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10034 != PackageManager.PERMISSION_GRANTED) { 10035 throw new SecurityException("Requires permission " 10036 + android.Manifest.permission.SHUTDOWN); 10037 } 10038 10039 boolean timedout = false; 10040 10041 synchronized(this) { 10042 mShuttingDown = true; 10043 updateEventDispatchingLocked(); 10044 timedout = mStackSupervisor.shutdownLocked(timeout); 10045 } 10046 10047 mAppOpsService.shutdown(); 10048 if (mUsageStatsService != null) { 10049 mUsageStatsService.prepareShutdown(); 10050 } 10051 mBatteryStatsService.shutdown(); 10052 synchronized (this) { 10053 mProcessStats.shutdownLocked(); 10054 notifyTaskPersisterLocked(null, true); 10055 } 10056 10057 return timedout; 10058 } 10059 10060 public final void activitySlept(IBinder token) { 10061 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10062 10063 final long origId = Binder.clearCallingIdentity(); 10064 10065 synchronized (this) { 10066 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10067 if (r != null) { 10068 mStackSupervisor.activitySleptLocked(r); 10069 } 10070 } 10071 10072 Binder.restoreCallingIdentity(origId); 10073 } 10074 10075 private String lockScreenShownToString() { 10076 switch (mLockScreenShown) { 10077 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10078 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10079 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10080 default: return "Unknown=" + mLockScreenShown; 10081 } 10082 } 10083 10084 void logLockScreen(String msg) { 10085 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10086 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10087 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10088 + " mSleeping=" + mSleeping); 10089 } 10090 10091 void startRunningVoiceLocked() { 10092 if (!mRunningVoice) { 10093 mRunningVoice = true; 10094 updateSleepIfNeededLocked(); 10095 } 10096 } 10097 10098 private void updateEventDispatchingLocked() { 10099 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10100 } 10101 10102 public void setLockScreenShown(boolean shown) { 10103 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10104 != PackageManager.PERMISSION_GRANTED) { 10105 throw new SecurityException("Requires permission " 10106 + android.Manifest.permission.DEVICE_POWER); 10107 } 10108 10109 synchronized(this) { 10110 long ident = Binder.clearCallingIdentity(); 10111 try { 10112 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10113 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10114 updateSleepIfNeededLocked(); 10115 } finally { 10116 Binder.restoreCallingIdentity(ident); 10117 } 10118 } 10119 } 10120 10121 @Override 10122 public void stopAppSwitches() { 10123 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10124 != PackageManager.PERMISSION_GRANTED) { 10125 throw new SecurityException("Requires permission " 10126 + android.Manifest.permission.STOP_APP_SWITCHES); 10127 } 10128 10129 synchronized(this) { 10130 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10131 + APP_SWITCH_DELAY_TIME; 10132 mDidAppSwitch = false; 10133 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10134 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10135 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10136 } 10137 } 10138 10139 public void resumeAppSwitches() { 10140 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10141 != PackageManager.PERMISSION_GRANTED) { 10142 throw new SecurityException("Requires permission " 10143 + android.Manifest.permission.STOP_APP_SWITCHES); 10144 } 10145 10146 synchronized(this) { 10147 // Note that we don't execute any pending app switches... we will 10148 // let those wait until either the timeout, or the next start 10149 // activity request. 10150 mAppSwitchesAllowedTime = 0; 10151 } 10152 } 10153 10154 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10155 int callingPid, int callingUid, String name) { 10156 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10157 return true; 10158 } 10159 10160 int perm = checkComponentPermission( 10161 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10162 sourceUid, -1, true); 10163 if (perm == PackageManager.PERMISSION_GRANTED) { 10164 return true; 10165 } 10166 10167 // If the actual IPC caller is different from the logical source, then 10168 // also see if they are allowed to control app switches. 10169 if (callingUid != -1 && callingUid != sourceUid) { 10170 perm = checkComponentPermission( 10171 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10172 callingUid, -1, true); 10173 if (perm == PackageManager.PERMISSION_GRANTED) { 10174 return true; 10175 } 10176 } 10177 10178 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10179 return false; 10180 } 10181 10182 public void setDebugApp(String packageName, boolean waitForDebugger, 10183 boolean persistent) { 10184 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10185 "setDebugApp()"); 10186 10187 long ident = Binder.clearCallingIdentity(); 10188 try { 10189 // Note that this is not really thread safe if there are multiple 10190 // callers into it at the same time, but that's not a situation we 10191 // care about. 10192 if (persistent) { 10193 final ContentResolver resolver = mContext.getContentResolver(); 10194 Settings.Global.putString( 10195 resolver, Settings.Global.DEBUG_APP, 10196 packageName); 10197 Settings.Global.putInt( 10198 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10199 waitForDebugger ? 1 : 0); 10200 } 10201 10202 synchronized (this) { 10203 if (!persistent) { 10204 mOrigDebugApp = mDebugApp; 10205 mOrigWaitForDebugger = mWaitForDebugger; 10206 } 10207 mDebugApp = packageName; 10208 mWaitForDebugger = waitForDebugger; 10209 mDebugTransient = !persistent; 10210 if (packageName != null) { 10211 forceStopPackageLocked(packageName, -1, false, false, true, true, 10212 false, UserHandle.USER_ALL, "set debug app"); 10213 } 10214 } 10215 } finally { 10216 Binder.restoreCallingIdentity(ident); 10217 } 10218 } 10219 10220 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10221 synchronized (this) { 10222 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10223 if (!isDebuggable) { 10224 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10225 throw new SecurityException("Process not debuggable: " + app.packageName); 10226 } 10227 } 10228 10229 mOpenGlTraceApp = processName; 10230 } 10231 } 10232 10233 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10234 synchronized (this) { 10235 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10236 if (!isDebuggable) { 10237 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10238 throw new SecurityException("Process not debuggable: " + app.packageName); 10239 } 10240 } 10241 mProfileApp = processName; 10242 mProfileFile = profilerInfo.profileFile; 10243 if (mProfileFd != null) { 10244 try { 10245 mProfileFd.close(); 10246 } catch (IOException e) { 10247 } 10248 mProfileFd = null; 10249 } 10250 mProfileFd = profilerInfo.profileFd; 10251 mSamplingInterval = profilerInfo.samplingInterval; 10252 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10253 mProfileType = 0; 10254 } 10255 } 10256 10257 @Override 10258 public void setAlwaysFinish(boolean enabled) { 10259 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10260 "setAlwaysFinish()"); 10261 10262 Settings.Global.putInt( 10263 mContext.getContentResolver(), 10264 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10265 10266 synchronized (this) { 10267 mAlwaysFinishActivities = enabled; 10268 } 10269 } 10270 10271 @Override 10272 public void setActivityController(IActivityController controller) { 10273 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10274 "setActivityController()"); 10275 synchronized (this) { 10276 mController = controller; 10277 Watchdog.getInstance().setActivityController(controller); 10278 } 10279 } 10280 10281 @Override 10282 public void setUserIsMonkey(boolean userIsMonkey) { 10283 synchronized (this) { 10284 synchronized (mPidsSelfLocked) { 10285 final int callingPid = Binder.getCallingPid(); 10286 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10287 if (precessRecord == null) { 10288 throw new SecurityException("Unknown process: " + callingPid); 10289 } 10290 if (precessRecord.instrumentationUiAutomationConnection == null) { 10291 throw new SecurityException("Only an instrumentation process " 10292 + "with a UiAutomation can call setUserIsMonkey"); 10293 } 10294 } 10295 mUserIsMonkey = userIsMonkey; 10296 } 10297 } 10298 10299 @Override 10300 public boolean isUserAMonkey() { 10301 synchronized (this) { 10302 // If there is a controller also implies the user is a monkey. 10303 return (mUserIsMonkey || mController != null); 10304 } 10305 } 10306 10307 public void requestBugReport() { 10308 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10309 SystemProperties.set("ctl.start", "bugreport"); 10310 } 10311 10312 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10313 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10314 } 10315 10316 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10317 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10318 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10319 } 10320 return KEY_DISPATCHING_TIMEOUT; 10321 } 10322 10323 @Override 10324 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10325 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10326 != PackageManager.PERMISSION_GRANTED) { 10327 throw new SecurityException("Requires permission " 10328 + android.Manifest.permission.FILTER_EVENTS); 10329 } 10330 ProcessRecord proc; 10331 long timeout; 10332 synchronized (this) { 10333 synchronized (mPidsSelfLocked) { 10334 proc = mPidsSelfLocked.get(pid); 10335 } 10336 timeout = getInputDispatchingTimeoutLocked(proc); 10337 } 10338 10339 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10340 return -1; 10341 } 10342 10343 return timeout; 10344 } 10345 10346 /** 10347 * Handle input dispatching timeouts. 10348 * Returns whether input dispatching should be aborted or not. 10349 */ 10350 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10351 final ActivityRecord activity, final ActivityRecord parent, 10352 final boolean aboveSystem, String reason) { 10353 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10354 != PackageManager.PERMISSION_GRANTED) { 10355 throw new SecurityException("Requires permission " 10356 + android.Manifest.permission.FILTER_EVENTS); 10357 } 10358 10359 final String annotation; 10360 if (reason == null) { 10361 annotation = "Input dispatching timed out"; 10362 } else { 10363 annotation = "Input dispatching timed out (" + reason + ")"; 10364 } 10365 10366 if (proc != null) { 10367 synchronized (this) { 10368 if (proc.debugging) { 10369 return false; 10370 } 10371 10372 if (mDidDexOpt) { 10373 // Give more time since we were dexopting. 10374 mDidDexOpt = false; 10375 return false; 10376 } 10377 10378 if (proc.instrumentationClass != null) { 10379 Bundle info = new Bundle(); 10380 info.putString("shortMsg", "keyDispatchingTimedOut"); 10381 info.putString("longMsg", annotation); 10382 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10383 return true; 10384 } 10385 } 10386 mHandler.post(new Runnable() { 10387 @Override 10388 public void run() { 10389 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10390 } 10391 }); 10392 } 10393 10394 return true; 10395 } 10396 10397 public Bundle getAssistContextExtras(int requestType) { 10398 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10399 UserHandle.getCallingUserId()); 10400 if (pae == null) { 10401 return null; 10402 } 10403 synchronized (pae) { 10404 while (!pae.haveResult) { 10405 try { 10406 pae.wait(); 10407 } catch (InterruptedException e) { 10408 } 10409 } 10410 if (pae.result != null) { 10411 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10412 } 10413 } 10414 synchronized (this) { 10415 mPendingAssistExtras.remove(pae); 10416 mHandler.removeCallbacks(pae); 10417 } 10418 return pae.extras; 10419 } 10420 10421 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10422 int userHandle) { 10423 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10424 "getAssistContextExtras()"); 10425 PendingAssistExtras pae; 10426 Bundle extras = new Bundle(); 10427 synchronized (this) { 10428 ActivityRecord activity = getFocusedStack().mResumedActivity; 10429 if (activity == null) { 10430 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10431 return null; 10432 } 10433 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10434 if (activity.app == null || activity.app.thread == null) { 10435 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10436 return null; 10437 } 10438 if (activity.app.pid == Binder.getCallingPid()) { 10439 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10440 return null; 10441 } 10442 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10443 try { 10444 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10445 requestType); 10446 mPendingAssistExtras.add(pae); 10447 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10448 } catch (RemoteException e) { 10449 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10450 return null; 10451 } 10452 return pae; 10453 } 10454 } 10455 10456 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10457 PendingAssistExtras pae = (PendingAssistExtras)token; 10458 synchronized (pae) { 10459 pae.result = extras; 10460 pae.haveResult = true; 10461 pae.notifyAll(); 10462 if (pae.intent == null) { 10463 // Caller is just waiting for the result. 10464 return; 10465 } 10466 } 10467 10468 // We are now ready to launch the assist activity. 10469 synchronized (this) { 10470 boolean exists = mPendingAssistExtras.remove(pae); 10471 mHandler.removeCallbacks(pae); 10472 if (!exists) { 10473 // Timed out. 10474 return; 10475 } 10476 } 10477 pae.intent.replaceExtras(extras); 10478 if (pae.hint != null) { 10479 pae.intent.putExtra(pae.hint, true); 10480 } 10481 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10482 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10483 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10484 closeSystemDialogs("assist"); 10485 try { 10486 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10487 } catch (ActivityNotFoundException e) { 10488 Slog.w(TAG, "No activity to handle assist action.", e); 10489 } 10490 } 10491 10492 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10493 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10494 } 10495 10496 public void registerProcessObserver(IProcessObserver observer) { 10497 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10498 "registerProcessObserver()"); 10499 synchronized (this) { 10500 mProcessObservers.register(observer); 10501 } 10502 } 10503 10504 @Override 10505 public void unregisterProcessObserver(IProcessObserver observer) { 10506 synchronized (this) { 10507 mProcessObservers.unregister(observer); 10508 } 10509 } 10510 10511 @Override 10512 public boolean convertFromTranslucent(IBinder token) { 10513 final long origId = Binder.clearCallingIdentity(); 10514 try { 10515 synchronized (this) { 10516 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10517 if (r == null) { 10518 return false; 10519 } 10520 final boolean translucentChanged = r.changeWindowTranslucency(true); 10521 if (translucentChanged) { 10522 r.task.stack.releaseBackgroundResources(); 10523 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10524 } 10525 mWindowManager.setAppFullscreen(token, true); 10526 return translucentChanged; 10527 } 10528 } finally { 10529 Binder.restoreCallingIdentity(origId); 10530 } 10531 } 10532 10533 @Override 10534 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10535 final long origId = Binder.clearCallingIdentity(); 10536 try { 10537 synchronized (this) { 10538 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10539 if (r == null) { 10540 return false; 10541 } 10542 int index = r.task.mActivities.lastIndexOf(r); 10543 if (index > 0) { 10544 ActivityRecord under = r.task.mActivities.get(index - 1); 10545 under.returningOptions = options; 10546 } 10547 final boolean translucentChanged = r.changeWindowTranslucency(false); 10548 if (translucentChanged) { 10549 r.task.stack.convertToTranslucent(r); 10550 } 10551 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10552 mWindowManager.setAppFullscreen(token, false); 10553 return translucentChanged; 10554 } 10555 } finally { 10556 Binder.restoreCallingIdentity(origId); 10557 } 10558 } 10559 10560 @Override 10561 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10562 final long origId = Binder.clearCallingIdentity(); 10563 try { 10564 synchronized (this) { 10565 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10566 if (r != null) { 10567 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10568 } 10569 } 10570 return false; 10571 } finally { 10572 Binder.restoreCallingIdentity(origId); 10573 } 10574 } 10575 10576 @Override 10577 public boolean isBackgroundVisibleBehind(IBinder token) { 10578 final long origId = Binder.clearCallingIdentity(); 10579 try { 10580 synchronized (this) { 10581 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10582 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10583 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10584 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10585 return visible; 10586 } 10587 } finally { 10588 Binder.restoreCallingIdentity(origId); 10589 } 10590 } 10591 10592 @Override 10593 public ActivityOptions getActivityOptions(IBinder token) { 10594 final long origId = Binder.clearCallingIdentity(); 10595 try { 10596 synchronized (this) { 10597 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10598 if (r != null) { 10599 final ActivityOptions activityOptions = r.pendingOptions; 10600 r.pendingOptions = null; 10601 return activityOptions; 10602 } 10603 return null; 10604 } 10605 } finally { 10606 Binder.restoreCallingIdentity(origId); 10607 } 10608 } 10609 10610 @Override 10611 public void setImmersive(IBinder token, boolean immersive) { 10612 synchronized(this) { 10613 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10614 if (r == null) { 10615 throw new IllegalArgumentException(); 10616 } 10617 r.immersive = immersive; 10618 10619 // update associated state if we're frontmost 10620 if (r == mFocusedActivity) { 10621 if (DEBUG_IMMERSIVE) { 10622 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10623 } 10624 applyUpdateLockStateLocked(r); 10625 } 10626 } 10627 } 10628 10629 @Override 10630 public boolean isImmersive(IBinder token) { 10631 synchronized (this) { 10632 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10633 if (r == null) { 10634 throw new IllegalArgumentException(); 10635 } 10636 return r.immersive; 10637 } 10638 } 10639 10640 public boolean isTopActivityImmersive() { 10641 enforceNotIsolatedCaller("startActivity"); 10642 synchronized (this) { 10643 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10644 return (r != null) ? r.immersive : false; 10645 } 10646 } 10647 10648 @Override 10649 public boolean isTopOfTask(IBinder token) { 10650 synchronized (this) { 10651 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10652 if (r == null) { 10653 throw new IllegalArgumentException(); 10654 } 10655 return r.task.getTopActivity() == r; 10656 } 10657 } 10658 10659 public final void enterSafeMode() { 10660 synchronized(this) { 10661 // It only makes sense to do this before the system is ready 10662 // and started launching other packages. 10663 if (!mSystemReady) { 10664 try { 10665 AppGlobals.getPackageManager().enterSafeMode(); 10666 } catch (RemoteException e) { 10667 } 10668 } 10669 10670 mSafeMode = true; 10671 } 10672 } 10673 10674 public final void showSafeModeOverlay() { 10675 View v = LayoutInflater.from(mContext).inflate( 10676 com.android.internal.R.layout.safe_mode, null); 10677 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10678 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10679 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10680 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10681 lp.gravity = Gravity.BOTTOM | Gravity.START; 10682 lp.format = v.getBackground().getOpacity(); 10683 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10684 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10685 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10686 ((WindowManager)mContext.getSystemService( 10687 Context.WINDOW_SERVICE)).addView(v, lp); 10688 } 10689 10690 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10691 if (!(sender instanceof PendingIntentRecord)) { 10692 return; 10693 } 10694 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10695 synchronized (stats) { 10696 if (mBatteryStatsService.isOnBattery()) { 10697 mBatteryStatsService.enforceCallingPermission(); 10698 PendingIntentRecord rec = (PendingIntentRecord)sender; 10699 int MY_UID = Binder.getCallingUid(); 10700 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10701 BatteryStatsImpl.Uid.Pkg pkg = 10702 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10703 sourcePkg != null ? sourcePkg : rec.key.packageName); 10704 pkg.incWakeupsLocked(); 10705 } 10706 } 10707 } 10708 10709 public boolean killPids(int[] pids, String pReason, boolean secure) { 10710 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10711 throw new SecurityException("killPids only available to the system"); 10712 } 10713 String reason = (pReason == null) ? "Unknown" : pReason; 10714 // XXX Note: don't acquire main activity lock here, because the window 10715 // manager calls in with its locks held. 10716 10717 boolean killed = false; 10718 synchronized (mPidsSelfLocked) { 10719 int[] types = new int[pids.length]; 10720 int worstType = 0; 10721 for (int i=0; i<pids.length; i++) { 10722 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10723 if (proc != null) { 10724 int type = proc.setAdj; 10725 types[i] = type; 10726 if (type > worstType) { 10727 worstType = type; 10728 } 10729 } 10730 } 10731 10732 // If the worst oom_adj is somewhere in the cached proc LRU range, 10733 // then constrain it so we will kill all cached procs. 10734 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10735 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10736 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10737 } 10738 10739 // If this is not a secure call, don't let it kill processes that 10740 // are important. 10741 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10742 worstType = ProcessList.SERVICE_ADJ; 10743 } 10744 10745 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10746 for (int i=0; i<pids.length; i++) { 10747 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10748 if (proc == null) { 10749 continue; 10750 } 10751 int adj = proc.setAdj; 10752 if (adj >= worstType && !proc.killedByAm) { 10753 proc.kill(reason, true); 10754 killed = true; 10755 } 10756 } 10757 } 10758 return killed; 10759 } 10760 10761 @Override 10762 public void killUid(int uid, String reason) { 10763 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10764 throw new SecurityException("killUid only available to the system"); 10765 } 10766 synchronized (this) { 10767 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10768 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10769 reason != null ? reason : "kill uid"); 10770 } 10771 } 10772 10773 @Override 10774 public boolean killProcessesBelowForeground(String reason) { 10775 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10776 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10777 } 10778 10779 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10780 } 10781 10782 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10783 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10784 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10785 } 10786 10787 boolean killed = false; 10788 synchronized (mPidsSelfLocked) { 10789 final int size = mPidsSelfLocked.size(); 10790 for (int i = 0; i < size; i++) { 10791 final int pid = mPidsSelfLocked.keyAt(i); 10792 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10793 if (proc == null) continue; 10794 10795 final int adj = proc.setAdj; 10796 if (adj > belowAdj && !proc.killedByAm) { 10797 proc.kill(reason, true); 10798 killed = true; 10799 } 10800 } 10801 } 10802 return killed; 10803 } 10804 10805 @Override 10806 public void hang(final IBinder who, boolean allowRestart) { 10807 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10808 != PackageManager.PERMISSION_GRANTED) { 10809 throw new SecurityException("Requires permission " 10810 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10811 } 10812 10813 final IBinder.DeathRecipient death = new DeathRecipient() { 10814 @Override 10815 public void binderDied() { 10816 synchronized (this) { 10817 notifyAll(); 10818 } 10819 } 10820 }; 10821 10822 try { 10823 who.linkToDeath(death, 0); 10824 } catch (RemoteException e) { 10825 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10826 return; 10827 } 10828 10829 synchronized (this) { 10830 Watchdog.getInstance().setAllowRestart(allowRestart); 10831 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10832 synchronized (death) { 10833 while (who.isBinderAlive()) { 10834 try { 10835 death.wait(); 10836 } catch (InterruptedException e) { 10837 } 10838 } 10839 } 10840 Watchdog.getInstance().setAllowRestart(true); 10841 } 10842 } 10843 10844 @Override 10845 public void restart() { 10846 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10847 != PackageManager.PERMISSION_GRANTED) { 10848 throw new SecurityException("Requires permission " 10849 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10850 } 10851 10852 Log.i(TAG, "Sending shutdown broadcast..."); 10853 10854 BroadcastReceiver br = new BroadcastReceiver() { 10855 @Override public void onReceive(Context context, Intent intent) { 10856 // Now the broadcast is done, finish up the low-level shutdown. 10857 Log.i(TAG, "Shutting down activity manager..."); 10858 shutdown(10000); 10859 Log.i(TAG, "Shutdown complete, restarting!"); 10860 Process.killProcess(Process.myPid()); 10861 System.exit(10); 10862 } 10863 }; 10864 10865 // First send the high-level shut down broadcast. 10866 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10867 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10868 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10869 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10870 mContext.sendOrderedBroadcastAsUser(intent, 10871 UserHandle.ALL, null, br, mHandler, 0, null, null); 10872 */ 10873 br.onReceive(mContext, intent); 10874 } 10875 10876 private long getLowRamTimeSinceIdle(long now) { 10877 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10878 } 10879 10880 @Override 10881 public void performIdleMaintenance() { 10882 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10883 != PackageManager.PERMISSION_GRANTED) { 10884 throw new SecurityException("Requires permission " 10885 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10886 } 10887 10888 synchronized (this) { 10889 final long now = SystemClock.uptimeMillis(); 10890 final long timeSinceLastIdle = now - mLastIdleTime; 10891 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10892 mLastIdleTime = now; 10893 mLowRamTimeSinceLastIdle = 0; 10894 if (mLowRamStartTime != 0) { 10895 mLowRamStartTime = now; 10896 } 10897 10898 StringBuilder sb = new StringBuilder(128); 10899 sb.append("Idle maintenance over "); 10900 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10901 sb.append(" low RAM for "); 10902 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10903 Slog.i(TAG, sb.toString()); 10904 10905 // If at least 1/3 of our time since the last idle period has been spent 10906 // with RAM low, then we want to kill processes. 10907 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10908 10909 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10910 ProcessRecord proc = mLruProcesses.get(i); 10911 if (proc.notCachedSinceIdle) { 10912 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10913 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10914 if (doKilling && proc.initialIdlePss != 0 10915 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10916 proc.kill("idle maint (pss " + proc.lastPss 10917 + " from " + proc.initialIdlePss + ")", true); 10918 } 10919 } 10920 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10921 proc.notCachedSinceIdle = true; 10922 proc.initialIdlePss = 0; 10923 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10924 isSleeping(), now); 10925 } 10926 } 10927 10928 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10929 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10930 } 10931 } 10932 10933 private void retrieveSettings() { 10934 final ContentResolver resolver = mContext.getContentResolver(); 10935 String debugApp = Settings.Global.getString( 10936 resolver, Settings.Global.DEBUG_APP); 10937 boolean waitForDebugger = Settings.Global.getInt( 10938 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10939 boolean alwaysFinishActivities = Settings.Global.getInt( 10940 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10941 boolean forceRtl = Settings.Global.getInt( 10942 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10943 // Transfer any global setting for forcing RTL layout, into a System Property 10944 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10945 10946 Configuration configuration = new Configuration(); 10947 Settings.System.getConfiguration(resolver, configuration); 10948 if (forceRtl) { 10949 // This will take care of setting the correct layout direction flags 10950 configuration.setLayoutDirection(configuration.locale); 10951 } 10952 10953 synchronized (this) { 10954 mDebugApp = mOrigDebugApp = debugApp; 10955 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10956 mAlwaysFinishActivities = alwaysFinishActivities; 10957 // This happens before any activities are started, so we can 10958 // change mConfiguration in-place. 10959 updateConfigurationLocked(configuration, null, false, true); 10960 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10961 } 10962 } 10963 10964 /** Loads resources after the current configuration has been set. */ 10965 private void loadResourcesOnSystemReady() { 10966 final Resources res = mContext.getResources(); 10967 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10968 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10969 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10970 } 10971 10972 public boolean testIsSystemReady() { 10973 // no need to synchronize(this) just to read & return the value 10974 return mSystemReady; 10975 } 10976 10977 private static File getCalledPreBootReceiversFile() { 10978 File dataDir = Environment.getDataDirectory(); 10979 File systemDir = new File(dataDir, "system"); 10980 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10981 return fname; 10982 } 10983 10984 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10985 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10986 File file = getCalledPreBootReceiversFile(); 10987 FileInputStream fis = null; 10988 try { 10989 fis = new FileInputStream(file); 10990 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10991 int fvers = dis.readInt(); 10992 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10993 String vers = dis.readUTF(); 10994 String codename = dis.readUTF(); 10995 String build = dis.readUTF(); 10996 if (android.os.Build.VERSION.RELEASE.equals(vers) 10997 && android.os.Build.VERSION.CODENAME.equals(codename) 10998 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10999 int num = dis.readInt(); 11000 while (num > 0) { 11001 num--; 11002 String pkg = dis.readUTF(); 11003 String cls = dis.readUTF(); 11004 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11005 } 11006 } 11007 } 11008 } catch (FileNotFoundException e) { 11009 } catch (IOException e) { 11010 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11011 } finally { 11012 if (fis != null) { 11013 try { 11014 fis.close(); 11015 } catch (IOException e) { 11016 } 11017 } 11018 } 11019 return lastDoneReceivers; 11020 } 11021 11022 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11023 File file = getCalledPreBootReceiversFile(); 11024 FileOutputStream fos = null; 11025 DataOutputStream dos = null; 11026 try { 11027 fos = new FileOutputStream(file); 11028 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11029 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11030 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11031 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11032 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11033 dos.writeInt(list.size()); 11034 for (int i=0; i<list.size(); i++) { 11035 dos.writeUTF(list.get(i).getPackageName()); 11036 dos.writeUTF(list.get(i).getClassName()); 11037 } 11038 } catch (IOException e) { 11039 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11040 file.delete(); 11041 } finally { 11042 FileUtils.sync(fos); 11043 if (dos != null) { 11044 try { 11045 dos.close(); 11046 } catch (IOException e) { 11047 // TODO Auto-generated catch block 11048 e.printStackTrace(); 11049 } 11050 } 11051 } 11052 } 11053 11054 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11055 ArrayList<ComponentName> doneReceivers, int userId) { 11056 boolean waitingUpdate = false; 11057 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11058 List<ResolveInfo> ris = null; 11059 try { 11060 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11061 intent, null, 0, userId); 11062 } catch (RemoteException e) { 11063 } 11064 if (ris != null) { 11065 for (int i=ris.size()-1; i>=0; i--) { 11066 if ((ris.get(i).activityInfo.applicationInfo.flags 11067 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11068 ris.remove(i); 11069 } 11070 } 11071 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11072 11073 // For User 0, load the version number. When delivering to a new user, deliver 11074 // to all receivers. 11075 if (userId == UserHandle.USER_OWNER) { 11076 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11077 for (int i=0; i<ris.size(); i++) { 11078 ActivityInfo ai = ris.get(i).activityInfo; 11079 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11080 if (lastDoneReceivers.contains(comp)) { 11081 // We already did the pre boot receiver for this app with the current 11082 // platform version, so don't do it again... 11083 ris.remove(i); 11084 i--; 11085 // ...however, do keep it as one that has been done, so we don't 11086 // forget about it when rewriting the file of last done receivers. 11087 doneReceivers.add(comp); 11088 } 11089 } 11090 } 11091 11092 // If primary user, send broadcast to all available users, else just to userId 11093 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11094 : new int[] { userId }; 11095 for (int i = 0; i < ris.size(); i++) { 11096 ActivityInfo ai = ris.get(i).activityInfo; 11097 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11098 doneReceivers.add(comp); 11099 intent.setComponent(comp); 11100 for (int j=0; j<users.length; j++) { 11101 IIntentReceiver finisher = null; 11102 // On last receiver and user, set up a completion callback 11103 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11104 finisher = new IIntentReceiver.Stub() { 11105 public void performReceive(Intent intent, int resultCode, 11106 String data, Bundle extras, boolean ordered, 11107 boolean sticky, int sendingUser) { 11108 // The raw IIntentReceiver interface is called 11109 // with the AM lock held, so redispatch to 11110 // execute our code without the lock. 11111 mHandler.post(onFinishCallback); 11112 } 11113 }; 11114 } 11115 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11116 + " for user " + users[j]); 11117 broadcastIntentLocked(null, null, intent, null, finisher, 11118 0, null, null, null, AppOpsManager.OP_NONE, 11119 true, false, MY_PID, Process.SYSTEM_UID, 11120 users[j]); 11121 if (finisher != null) { 11122 waitingUpdate = true; 11123 } 11124 } 11125 } 11126 } 11127 11128 return waitingUpdate; 11129 } 11130 11131 public void systemReady(final Runnable goingCallback) { 11132 synchronized(this) { 11133 if (mSystemReady) { 11134 // If we're done calling all the receivers, run the next "boot phase" passed in 11135 // by the SystemServer 11136 if (goingCallback != null) { 11137 goingCallback.run(); 11138 } 11139 return; 11140 } 11141 11142 // Make sure we have the current profile info, since it is needed for 11143 // security checks. 11144 updateCurrentProfileIdsLocked(); 11145 11146 if (mRecentTasks == null) { 11147 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11148 if (!mRecentTasks.isEmpty()) { 11149 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11150 } 11151 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11152 mTaskPersister.startPersisting(); 11153 } 11154 11155 // Check to see if there are any update receivers to run. 11156 if (!mDidUpdate) { 11157 if (mWaitingUpdate) { 11158 return; 11159 } 11160 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11161 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11162 public void run() { 11163 synchronized (ActivityManagerService.this) { 11164 mDidUpdate = true; 11165 } 11166 writeLastDonePreBootReceivers(doneReceivers); 11167 showBootMessage(mContext.getText( 11168 R.string.android_upgrading_complete), 11169 false); 11170 systemReady(goingCallback); 11171 } 11172 }, doneReceivers, UserHandle.USER_OWNER); 11173 11174 if (mWaitingUpdate) { 11175 return; 11176 } 11177 mDidUpdate = true; 11178 } 11179 11180 mAppOpsService.systemReady(); 11181 mSystemReady = true; 11182 } 11183 11184 ArrayList<ProcessRecord> procsToKill = null; 11185 synchronized(mPidsSelfLocked) { 11186 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11187 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11188 if (!isAllowedWhileBooting(proc.info)){ 11189 if (procsToKill == null) { 11190 procsToKill = new ArrayList<ProcessRecord>(); 11191 } 11192 procsToKill.add(proc); 11193 } 11194 } 11195 } 11196 11197 synchronized(this) { 11198 if (procsToKill != null) { 11199 for (int i=procsToKill.size()-1; i>=0; i--) { 11200 ProcessRecord proc = procsToKill.get(i); 11201 Slog.i(TAG, "Removing system update proc: " + proc); 11202 removeProcessLocked(proc, true, false, "system update done"); 11203 } 11204 } 11205 11206 // Now that we have cleaned up any update processes, we 11207 // are ready to start launching real processes and know that 11208 // we won't trample on them any more. 11209 mProcessesReady = true; 11210 } 11211 11212 Slog.i(TAG, "System now ready"); 11213 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11214 SystemClock.uptimeMillis()); 11215 11216 synchronized(this) { 11217 // Make sure we have no pre-ready processes sitting around. 11218 11219 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11220 ResolveInfo ri = mContext.getPackageManager() 11221 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11222 STOCK_PM_FLAGS); 11223 CharSequence errorMsg = null; 11224 if (ri != null) { 11225 ActivityInfo ai = ri.activityInfo; 11226 ApplicationInfo app = ai.applicationInfo; 11227 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11228 mTopAction = Intent.ACTION_FACTORY_TEST; 11229 mTopData = null; 11230 mTopComponent = new ComponentName(app.packageName, 11231 ai.name); 11232 } else { 11233 errorMsg = mContext.getResources().getText( 11234 com.android.internal.R.string.factorytest_not_system); 11235 } 11236 } else { 11237 errorMsg = mContext.getResources().getText( 11238 com.android.internal.R.string.factorytest_no_action); 11239 } 11240 if (errorMsg != null) { 11241 mTopAction = null; 11242 mTopData = null; 11243 mTopComponent = null; 11244 Message msg = Message.obtain(); 11245 msg.what = SHOW_FACTORY_ERROR_MSG; 11246 msg.getData().putCharSequence("msg", errorMsg); 11247 mHandler.sendMessage(msg); 11248 } 11249 } 11250 } 11251 11252 retrieveSettings(); 11253 loadResourcesOnSystemReady(); 11254 11255 synchronized (this) { 11256 readGrantedUriPermissionsLocked(); 11257 } 11258 11259 if (goingCallback != null) goingCallback.run(); 11260 11261 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11262 Integer.toString(mCurrentUserId), mCurrentUserId); 11263 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11264 Integer.toString(mCurrentUserId), mCurrentUserId); 11265 mSystemServiceManager.startUser(mCurrentUserId); 11266 11267 synchronized (this) { 11268 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11269 try { 11270 List apps = AppGlobals.getPackageManager(). 11271 getPersistentApplications(STOCK_PM_FLAGS); 11272 if (apps != null) { 11273 int N = apps.size(); 11274 int i; 11275 for (i=0; i<N; i++) { 11276 ApplicationInfo info 11277 = (ApplicationInfo)apps.get(i); 11278 if (info != null && 11279 !info.packageName.equals("android")) { 11280 addAppLocked(info, false, null /* ABI override */); 11281 } 11282 } 11283 } 11284 } catch (RemoteException ex) { 11285 // pm is in same process, this will never happen. 11286 } 11287 } 11288 11289 // Start up initial activity. 11290 mBooting = true; 11291 startHomeActivityLocked(mCurrentUserId); 11292 11293 try { 11294 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11295 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11296 + " data partition or your device will be unstable."); 11297 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11298 } 11299 } catch (RemoteException e) { 11300 } 11301 11302 if (!Build.isFingerprintConsistent()) { 11303 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11304 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11305 } 11306 11307 long ident = Binder.clearCallingIdentity(); 11308 try { 11309 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11310 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11311 | Intent.FLAG_RECEIVER_FOREGROUND); 11312 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11313 broadcastIntentLocked(null, null, intent, 11314 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11315 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11316 intent = new Intent(Intent.ACTION_USER_STARTING); 11317 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11318 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11319 broadcastIntentLocked(null, null, intent, 11320 null, new IIntentReceiver.Stub() { 11321 @Override 11322 public void performReceive(Intent intent, int resultCode, String data, 11323 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11324 throws RemoteException { 11325 } 11326 }, 0, null, null, 11327 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11328 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11329 } catch (Throwable t) { 11330 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11331 } finally { 11332 Binder.restoreCallingIdentity(ident); 11333 } 11334 mStackSupervisor.resumeTopActivitiesLocked(); 11335 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11336 } 11337 } 11338 11339 private boolean makeAppCrashingLocked(ProcessRecord app, 11340 String shortMsg, String longMsg, String stackTrace) { 11341 app.crashing = true; 11342 app.crashingReport = generateProcessError(app, 11343 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11344 startAppProblemLocked(app); 11345 app.stopFreezingAllLocked(); 11346 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11347 } 11348 11349 private void makeAppNotRespondingLocked(ProcessRecord app, 11350 String activity, String shortMsg, String longMsg) { 11351 app.notResponding = true; 11352 app.notRespondingReport = generateProcessError(app, 11353 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11354 activity, shortMsg, longMsg, null); 11355 startAppProblemLocked(app); 11356 app.stopFreezingAllLocked(); 11357 } 11358 11359 /** 11360 * Generate a process error record, suitable for attachment to a ProcessRecord. 11361 * 11362 * @param app The ProcessRecord in which the error occurred. 11363 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11364 * ActivityManager.AppErrorStateInfo 11365 * @param activity The activity associated with the crash, if known. 11366 * @param shortMsg Short message describing the crash. 11367 * @param longMsg Long message describing the crash. 11368 * @param stackTrace Full crash stack trace, may be null. 11369 * 11370 * @return Returns a fully-formed AppErrorStateInfo record. 11371 */ 11372 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11373 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11374 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11375 11376 report.condition = condition; 11377 report.processName = app.processName; 11378 report.pid = app.pid; 11379 report.uid = app.info.uid; 11380 report.tag = activity; 11381 report.shortMsg = shortMsg; 11382 report.longMsg = longMsg; 11383 report.stackTrace = stackTrace; 11384 11385 return report; 11386 } 11387 11388 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11389 synchronized (this) { 11390 app.crashing = false; 11391 app.crashingReport = null; 11392 app.notResponding = false; 11393 app.notRespondingReport = null; 11394 if (app.anrDialog == fromDialog) { 11395 app.anrDialog = null; 11396 } 11397 if (app.waitDialog == fromDialog) { 11398 app.waitDialog = null; 11399 } 11400 if (app.pid > 0 && app.pid != MY_PID) { 11401 handleAppCrashLocked(app, null, null, null); 11402 app.kill("user request after error", true); 11403 } 11404 } 11405 } 11406 11407 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11408 String stackTrace) { 11409 long now = SystemClock.uptimeMillis(); 11410 11411 Long crashTime; 11412 if (!app.isolated) { 11413 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11414 } else { 11415 crashTime = null; 11416 } 11417 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11418 // This process loses! 11419 Slog.w(TAG, "Process " + app.info.processName 11420 + " has crashed too many times: killing!"); 11421 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11422 app.userId, app.info.processName, app.uid); 11423 mStackSupervisor.handleAppCrashLocked(app); 11424 if (!app.persistent) { 11425 // We don't want to start this process again until the user 11426 // explicitly does so... but for persistent process, we really 11427 // need to keep it running. If a persistent process is actually 11428 // repeatedly crashing, then badness for everyone. 11429 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11430 app.info.processName); 11431 if (!app.isolated) { 11432 // XXX We don't have a way to mark isolated processes 11433 // as bad, since they don't have a peristent identity. 11434 mBadProcesses.put(app.info.processName, app.uid, 11435 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11436 mProcessCrashTimes.remove(app.info.processName, app.uid); 11437 } 11438 app.bad = true; 11439 app.removed = true; 11440 // Don't let services in this process be restarted and potentially 11441 // annoy the user repeatedly. Unless it is persistent, since those 11442 // processes run critical code. 11443 removeProcessLocked(app, false, false, "crash"); 11444 mStackSupervisor.resumeTopActivitiesLocked(); 11445 return false; 11446 } 11447 mStackSupervisor.resumeTopActivitiesLocked(); 11448 } else { 11449 mStackSupervisor.finishTopRunningActivityLocked(app); 11450 } 11451 11452 // Bump up the crash count of any services currently running in the proc. 11453 for (int i=app.services.size()-1; i>=0; i--) { 11454 // Any services running in the application need to be placed 11455 // back in the pending list. 11456 ServiceRecord sr = app.services.valueAt(i); 11457 sr.crashCount++; 11458 } 11459 11460 // If the crashing process is what we consider to be the "home process" and it has been 11461 // replaced by a third-party app, clear the package preferred activities from packages 11462 // with a home activity running in the process to prevent a repeatedly crashing app 11463 // from blocking the user to manually clear the list. 11464 final ArrayList<ActivityRecord> activities = app.activities; 11465 if (app == mHomeProcess && activities.size() > 0 11466 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11467 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11468 final ActivityRecord r = activities.get(activityNdx); 11469 if (r.isHomeActivity()) { 11470 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11471 try { 11472 ActivityThread.getPackageManager() 11473 .clearPackagePreferredActivities(r.packageName); 11474 } catch (RemoteException c) { 11475 // pm is in same process, this will never happen. 11476 } 11477 } 11478 } 11479 } 11480 11481 if (!app.isolated) { 11482 // XXX Can't keep track of crash times for isolated processes, 11483 // because they don't have a perisistent identity. 11484 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11485 } 11486 11487 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11488 return true; 11489 } 11490 11491 void startAppProblemLocked(ProcessRecord app) { 11492 // If this app is not running under the current user, then we 11493 // can't give it a report button because that would require 11494 // launching the report UI under a different user. 11495 app.errorReportReceiver = null; 11496 11497 for (int userId : mCurrentProfileIds) { 11498 if (app.userId == userId) { 11499 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11500 mContext, app.info.packageName, app.info.flags); 11501 } 11502 } 11503 skipCurrentReceiverLocked(app); 11504 } 11505 11506 void skipCurrentReceiverLocked(ProcessRecord app) { 11507 for (BroadcastQueue queue : mBroadcastQueues) { 11508 queue.skipCurrentReceiverLocked(app); 11509 } 11510 } 11511 11512 /** 11513 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11514 * The application process will exit immediately after this call returns. 11515 * @param app object of the crashing app, null for the system server 11516 * @param crashInfo describing the exception 11517 */ 11518 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11519 ProcessRecord r = findAppProcess(app, "Crash"); 11520 final String processName = app == null ? "system_server" 11521 : (r == null ? "unknown" : r.processName); 11522 11523 handleApplicationCrashInner("crash", r, processName, crashInfo); 11524 } 11525 11526 /* Native crash reporting uses this inner version because it needs to be somewhat 11527 * decoupled from the AM-managed cleanup lifecycle 11528 */ 11529 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11530 ApplicationErrorReport.CrashInfo crashInfo) { 11531 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11532 UserHandle.getUserId(Binder.getCallingUid()), processName, 11533 r == null ? -1 : r.info.flags, 11534 crashInfo.exceptionClassName, 11535 crashInfo.exceptionMessage, 11536 crashInfo.throwFileName, 11537 crashInfo.throwLineNumber); 11538 11539 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11540 11541 crashApplication(r, crashInfo); 11542 } 11543 11544 public void handleApplicationStrictModeViolation( 11545 IBinder app, 11546 int violationMask, 11547 StrictMode.ViolationInfo info) { 11548 ProcessRecord r = findAppProcess(app, "StrictMode"); 11549 if (r == null) { 11550 return; 11551 } 11552 11553 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11554 Integer stackFingerprint = info.hashCode(); 11555 boolean logIt = true; 11556 synchronized (mAlreadyLoggedViolatedStacks) { 11557 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11558 logIt = false; 11559 // TODO: sub-sample into EventLog for these, with 11560 // the info.durationMillis? Then we'd get 11561 // the relative pain numbers, without logging all 11562 // the stack traces repeatedly. We'd want to do 11563 // likewise in the client code, which also does 11564 // dup suppression, before the Binder call. 11565 } else { 11566 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11567 mAlreadyLoggedViolatedStacks.clear(); 11568 } 11569 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11570 } 11571 } 11572 if (logIt) { 11573 logStrictModeViolationToDropBox(r, info); 11574 } 11575 } 11576 11577 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11578 AppErrorResult result = new AppErrorResult(); 11579 synchronized (this) { 11580 final long origId = Binder.clearCallingIdentity(); 11581 11582 Message msg = Message.obtain(); 11583 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11584 HashMap<String, Object> data = new HashMap<String, Object>(); 11585 data.put("result", result); 11586 data.put("app", r); 11587 data.put("violationMask", violationMask); 11588 data.put("info", info); 11589 msg.obj = data; 11590 mHandler.sendMessage(msg); 11591 11592 Binder.restoreCallingIdentity(origId); 11593 } 11594 int res = result.get(); 11595 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11596 } 11597 } 11598 11599 // Depending on the policy in effect, there could be a bunch of 11600 // these in quick succession so we try to batch these together to 11601 // minimize disk writes, number of dropbox entries, and maximize 11602 // compression, by having more fewer, larger records. 11603 private void logStrictModeViolationToDropBox( 11604 ProcessRecord process, 11605 StrictMode.ViolationInfo info) { 11606 if (info == null) { 11607 return; 11608 } 11609 final boolean isSystemApp = process == null || 11610 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11611 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11612 final String processName = process == null ? "unknown" : process.processName; 11613 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11614 final DropBoxManager dbox = (DropBoxManager) 11615 mContext.getSystemService(Context.DROPBOX_SERVICE); 11616 11617 // Exit early if the dropbox isn't configured to accept this report type. 11618 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11619 11620 boolean bufferWasEmpty; 11621 boolean needsFlush; 11622 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11623 synchronized (sb) { 11624 bufferWasEmpty = sb.length() == 0; 11625 appendDropBoxProcessHeaders(process, processName, sb); 11626 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11627 sb.append("System-App: ").append(isSystemApp).append("\n"); 11628 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11629 if (info.violationNumThisLoop != 0) { 11630 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11631 } 11632 if (info.numAnimationsRunning != 0) { 11633 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11634 } 11635 if (info.broadcastIntentAction != null) { 11636 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11637 } 11638 if (info.durationMillis != -1) { 11639 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11640 } 11641 if (info.numInstances != -1) { 11642 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11643 } 11644 if (info.tags != null) { 11645 for (String tag : info.tags) { 11646 sb.append("Span-Tag: ").append(tag).append("\n"); 11647 } 11648 } 11649 sb.append("\n"); 11650 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11651 sb.append(info.crashInfo.stackTrace); 11652 } 11653 sb.append("\n"); 11654 11655 // Only buffer up to ~64k. Various logging bits truncate 11656 // things at 128k. 11657 needsFlush = (sb.length() > 64 * 1024); 11658 } 11659 11660 // Flush immediately if the buffer's grown too large, or this 11661 // is a non-system app. Non-system apps are isolated with a 11662 // different tag & policy and not batched. 11663 // 11664 // Batching is useful during internal testing with 11665 // StrictMode settings turned up high. Without batching, 11666 // thousands of separate files could be created on boot. 11667 if (!isSystemApp || needsFlush) { 11668 new Thread("Error dump: " + dropboxTag) { 11669 @Override 11670 public void run() { 11671 String report; 11672 synchronized (sb) { 11673 report = sb.toString(); 11674 sb.delete(0, sb.length()); 11675 sb.trimToSize(); 11676 } 11677 if (report.length() != 0) { 11678 dbox.addText(dropboxTag, report); 11679 } 11680 } 11681 }.start(); 11682 return; 11683 } 11684 11685 // System app batching: 11686 if (!bufferWasEmpty) { 11687 // An existing dropbox-writing thread is outstanding, so 11688 // we don't need to start it up. The existing thread will 11689 // catch the buffer appends we just did. 11690 return; 11691 } 11692 11693 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11694 // (After this point, we shouldn't access AMS internal data structures.) 11695 new Thread("Error dump: " + dropboxTag) { 11696 @Override 11697 public void run() { 11698 // 5 second sleep to let stacks arrive and be batched together 11699 try { 11700 Thread.sleep(5000); // 5 seconds 11701 } catch (InterruptedException e) {} 11702 11703 String errorReport; 11704 synchronized (mStrictModeBuffer) { 11705 errorReport = mStrictModeBuffer.toString(); 11706 if (errorReport.length() == 0) { 11707 return; 11708 } 11709 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11710 mStrictModeBuffer.trimToSize(); 11711 } 11712 dbox.addText(dropboxTag, errorReport); 11713 } 11714 }.start(); 11715 } 11716 11717 /** 11718 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11719 * @param app object of the crashing app, null for the system server 11720 * @param tag reported by the caller 11721 * @param system whether this wtf is coming from the system 11722 * @param crashInfo describing the context of the error 11723 * @return true if the process should exit immediately (WTF is fatal) 11724 */ 11725 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11726 final ApplicationErrorReport.CrashInfo crashInfo) { 11727 final int callingUid = Binder.getCallingUid(); 11728 final int callingPid = Binder.getCallingPid(); 11729 11730 if (system) { 11731 // If this is coming from the system, we could very well have low-level 11732 // system locks held, so we want to do this all asynchronously. And we 11733 // never want this to become fatal, so there is that too. 11734 mHandler.post(new Runnable() { 11735 @Override public void run() { 11736 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11737 } 11738 }); 11739 return false; 11740 } 11741 11742 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11743 crashInfo); 11744 11745 if (r != null && r.pid != Process.myPid() && 11746 Settings.Global.getInt(mContext.getContentResolver(), 11747 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11748 crashApplication(r, crashInfo); 11749 return true; 11750 } else { 11751 return false; 11752 } 11753 } 11754 11755 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11756 final ApplicationErrorReport.CrashInfo crashInfo) { 11757 final ProcessRecord r = findAppProcess(app, "WTF"); 11758 final String processName = app == null ? "system_server" 11759 : (r == null ? "unknown" : r.processName); 11760 11761 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11762 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11763 11764 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11765 11766 return r; 11767 } 11768 11769 /** 11770 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11771 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11772 */ 11773 private ProcessRecord findAppProcess(IBinder app, String reason) { 11774 if (app == null) { 11775 return null; 11776 } 11777 11778 synchronized (this) { 11779 final int NP = mProcessNames.getMap().size(); 11780 for (int ip=0; ip<NP; ip++) { 11781 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11782 final int NA = apps.size(); 11783 for (int ia=0; ia<NA; ia++) { 11784 ProcessRecord p = apps.valueAt(ia); 11785 if (p.thread != null && p.thread.asBinder() == app) { 11786 return p; 11787 } 11788 } 11789 } 11790 11791 Slog.w(TAG, "Can't find mystery application for " + reason 11792 + " from pid=" + Binder.getCallingPid() 11793 + " uid=" + Binder.getCallingUid() + ": " + app); 11794 return null; 11795 } 11796 } 11797 11798 /** 11799 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11800 * to append various headers to the dropbox log text. 11801 */ 11802 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11803 StringBuilder sb) { 11804 // Watchdog thread ends up invoking this function (with 11805 // a null ProcessRecord) to add the stack file to dropbox. 11806 // Do not acquire a lock on this (am) in such cases, as it 11807 // could cause a potential deadlock, if and when watchdog 11808 // is invoked due to unavailability of lock on am and it 11809 // would prevent watchdog from killing system_server. 11810 if (process == null) { 11811 sb.append("Process: ").append(processName).append("\n"); 11812 return; 11813 } 11814 // Note: ProcessRecord 'process' is guarded by the service 11815 // instance. (notably process.pkgList, which could otherwise change 11816 // concurrently during execution of this method) 11817 synchronized (this) { 11818 sb.append("Process: ").append(processName).append("\n"); 11819 int flags = process.info.flags; 11820 IPackageManager pm = AppGlobals.getPackageManager(); 11821 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11822 for (int ip=0; ip<process.pkgList.size(); ip++) { 11823 String pkg = process.pkgList.keyAt(ip); 11824 sb.append("Package: ").append(pkg); 11825 try { 11826 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11827 if (pi != null) { 11828 sb.append(" v").append(pi.versionCode); 11829 if (pi.versionName != null) { 11830 sb.append(" (").append(pi.versionName).append(")"); 11831 } 11832 } 11833 } catch (RemoteException e) { 11834 Slog.e(TAG, "Error getting package info: " + pkg, e); 11835 } 11836 sb.append("\n"); 11837 } 11838 } 11839 } 11840 11841 private static String processClass(ProcessRecord process) { 11842 if (process == null || process.pid == MY_PID) { 11843 return "system_server"; 11844 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11845 return "system_app"; 11846 } else { 11847 return "data_app"; 11848 } 11849 } 11850 11851 /** 11852 * Write a description of an error (crash, WTF, ANR) to the drop box. 11853 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11854 * @param process which caused the error, null means the system server 11855 * @param activity which triggered the error, null if unknown 11856 * @param parent activity related to the error, null if unknown 11857 * @param subject line related to the error, null if absent 11858 * @param report in long form describing the error, null if absent 11859 * @param logFile to include in the report, null if none 11860 * @param crashInfo giving an application stack trace, null if absent 11861 */ 11862 public void addErrorToDropBox(String eventType, 11863 ProcessRecord process, String processName, ActivityRecord activity, 11864 ActivityRecord parent, String subject, 11865 final String report, final File logFile, 11866 final ApplicationErrorReport.CrashInfo crashInfo) { 11867 // NOTE -- this must never acquire the ActivityManagerService lock, 11868 // otherwise the watchdog may be prevented from resetting the system. 11869 11870 final String dropboxTag = processClass(process) + "_" + eventType; 11871 final DropBoxManager dbox = (DropBoxManager) 11872 mContext.getSystemService(Context.DROPBOX_SERVICE); 11873 11874 // Exit early if the dropbox isn't configured to accept this report type. 11875 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11876 11877 final StringBuilder sb = new StringBuilder(1024); 11878 appendDropBoxProcessHeaders(process, processName, sb); 11879 if (activity != null) { 11880 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11881 } 11882 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11883 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11884 } 11885 if (parent != null && parent != activity) { 11886 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11887 } 11888 if (subject != null) { 11889 sb.append("Subject: ").append(subject).append("\n"); 11890 } 11891 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11892 if (Debug.isDebuggerConnected()) { 11893 sb.append("Debugger: Connected\n"); 11894 } 11895 sb.append("\n"); 11896 11897 // Do the rest in a worker thread to avoid blocking the caller on I/O 11898 // (After this point, we shouldn't access AMS internal data structures.) 11899 Thread worker = new Thread("Error dump: " + dropboxTag) { 11900 @Override 11901 public void run() { 11902 if (report != null) { 11903 sb.append(report); 11904 } 11905 if (logFile != null) { 11906 try { 11907 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11908 "\n\n[[TRUNCATED]]")); 11909 } catch (IOException e) { 11910 Slog.e(TAG, "Error reading " + logFile, e); 11911 } 11912 } 11913 if (crashInfo != null && crashInfo.stackTrace != null) { 11914 sb.append(crashInfo.stackTrace); 11915 } 11916 11917 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11918 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11919 if (lines > 0) { 11920 sb.append("\n"); 11921 11922 // Merge several logcat streams, and take the last N lines 11923 InputStreamReader input = null; 11924 try { 11925 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11926 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11927 "-b", "crash", 11928 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11929 11930 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11931 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11932 input = new InputStreamReader(logcat.getInputStream()); 11933 11934 int num; 11935 char[] buf = new char[8192]; 11936 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11937 } catch (IOException e) { 11938 Slog.e(TAG, "Error running logcat", e); 11939 } finally { 11940 if (input != null) try { input.close(); } catch (IOException e) {} 11941 } 11942 } 11943 11944 dbox.addText(dropboxTag, sb.toString()); 11945 } 11946 }; 11947 11948 if (process == null) { 11949 // If process is null, we are being called from some internal code 11950 // and may be about to die -- run this synchronously. 11951 worker.run(); 11952 } else { 11953 worker.start(); 11954 } 11955 } 11956 11957 /** 11958 * Bring up the "unexpected error" dialog box for a crashing app. 11959 * Deal with edge cases (intercepts from instrumented applications, 11960 * ActivityController, error intent receivers, that sort of thing). 11961 * @param r the application crashing 11962 * @param crashInfo describing the failure 11963 */ 11964 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11965 long timeMillis = System.currentTimeMillis(); 11966 String shortMsg = crashInfo.exceptionClassName; 11967 String longMsg = crashInfo.exceptionMessage; 11968 String stackTrace = crashInfo.stackTrace; 11969 if (shortMsg != null && longMsg != null) { 11970 longMsg = shortMsg + ": " + longMsg; 11971 } else if (shortMsg != null) { 11972 longMsg = shortMsg; 11973 } 11974 11975 AppErrorResult result = new AppErrorResult(); 11976 synchronized (this) { 11977 if (mController != null) { 11978 try { 11979 String name = r != null ? r.processName : null; 11980 int pid = r != null ? r.pid : Binder.getCallingPid(); 11981 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11982 if (!mController.appCrashed(name, pid, 11983 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11984 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11985 && "Native crash".equals(crashInfo.exceptionClassName)) { 11986 Slog.w(TAG, "Skip killing native crashed app " + name 11987 + "(" + pid + ") during testing"); 11988 } else { 11989 Slog.w(TAG, "Force-killing crashed app " + name 11990 + " at watcher's request"); 11991 if (r != null) { 11992 r.kill("crash", true); 11993 } else { 11994 // Huh. 11995 Process.killProcess(pid); 11996 Process.killProcessGroup(uid, pid); 11997 } 11998 } 11999 return; 12000 } 12001 } catch (RemoteException e) { 12002 mController = null; 12003 Watchdog.getInstance().setActivityController(null); 12004 } 12005 } 12006 12007 final long origId = Binder.clearCallingIdentity(); 12008 12009 // If this process is running instrumentation, finish it. 12010 if (r != null && r.instrumentationClass != null) { 12011 Slog.w(TAG, "Error in app " + r.processName 12012 + " running instrumentation " + r.instrumentationClass + ":"); 12013 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12014 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12015 Bundle info = new Bundle(); 12016 info.putString("shortMsg", shortMsg); 12017 info.putString("longMsg", longMsg); 12018 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12019 Binder.restoreCallingIdentity(origId); 12020 return; 12021 } 12022 12023 // If we can't identify the process or it's already exceeded its crash quota, 12024 // quit right away without showing a crash dialog. 12025 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12026 Binder.restoreCallingIdentity(origId); 12027 return; 12028 } 12029 12030 Message msg = Message.obtain(); 12031 msg.what = SHOW_ERROR_MSG; 12032 HashMap data = new HashMap(); 12033 data.put("result", result); 12034 data.put("app", r); 12035 msg.obj = data; 12036 mHandler.sendMessage(msg); 12037 12038 Binder.restoreCallingIdentity(origId); 12039 } 12040 12041 int res = result.get(); 12042 12043 Intent appErrorIntent = null; 12044 synchronized (this) { 12045 if (r != null && !r.isolated) { 12046 // XXX Can't keep track of crash time for isolated processes, 12047 // since they don't have a persistent identity. 12048 mProcessCrashTimes.put(r.info.processName, r.uid, 12049 SystemClock.uptimeMillis()); 12050 } 12051 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12052 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12053 } 12054 } 12055 12056 if (appErrorIntent != null) { 12057 try { 12058 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12059 } catch (ActivityNotFoundException e) { 12060 Slog.w(TAG, "bug report receiver dissappeared", e); 12061 } 12062 } 12063 } 12064 12065 Intent createAppErrorIntentLocked(ProcessRecord r, 12066 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12067 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12068 if (report == null) { 12069 return null; 12070 } 12071 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12072 result.setComponent(r.errorReportReceiver); 12073 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12074 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12075 return result; 12076 } 12077 12078 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12079 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12080 if (r.errorReportReceiver == null) { 12081 return null; 12082 } 12083 12084 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12085 return null; 12086 } 12087 12088 ApplicationErrorReport report = new ApplicationErrorReport(); 12089 report.packageName = r.info.packageName; 12090 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12091 report.processName = r.processName; 12092 report.time = timeMillis; 12093 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12094 12095 if (r.crashing || r.forceCrashReport) { 12096 report.type = ApplicationErrorReport.TYPE_CRASH; 12097 report.crashInfo = crashInfo; 12098 } else if (r.notResponding) { 12099 report.type = ApplicationErrorReport.TYPE_ANR; 12100 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12101 12102 report.anrInfo.activity = r.notRespondingReport.tag; 12103 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12104 report.anrInfo.info = r.notRespondingReport.longMsg; 12105 } 12106 12107 return report; 12108 } 12109 12110 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12111 enforceNotIsolatedCaller("getProcessesInErrorState"); 12112 // assume our apps are happy - lazy create the list 12113 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12114 12115 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12116 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12117 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12118 12119 synchronized (this) { 12120 12121 // iterate across all processes 12122 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12123 ProcessRecord app = mLruProcesses.get(i); 12124 if (!allUsers && app.userId != userId) { 12125 continue; 12126 } 12127 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12128 // This one's in trouble, so we'll generate a report for it 12129 // crashes are higher priority (in case there's a crash *and* an anr) 12130 ActivityManager.ProcessErrorStateInfo report = null; 12131 if (app.crashing) { 12132 report = app.crashingReport; 12133 } else if (app.notResponding) { 12134 report = app.notRespondingReport; 12135 } 12136 12137 if (report != null) { 12138 if (errList == null) { 12139 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12140 } 12141 errList.add(report); 12142 } else { 12143 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12144 " crashing = " + app.crashing + 12145 " notResponding = " + app.notResponding); 12146 } 12147 } 12148 } 12149 } 12150 12151 return errList; 12152 } 12153 12154 static int procStateToImportance(int procState, int memAdj, 12155 ActivityManager.RunningAppProcessInfo currApp) { 12156 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12157 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12158 currApp.lru = memAdj; 12159 } else { 12160 currApp.lru = 0; 12161 } 12162 return imp; 12163 } 12164 12165 private void fillInProcMemInfo(ProcessRecord app, 12166 ActivityManager.RunningAppProcessInfo outInfo) { 12167 outInfo.pid = app.pid; 12168 outInfo.uid = app.info.uid; 12169 if (mHeavyWeightProcess == app) { 12170 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12171 } 12172 if (app.persistent) { 12173 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12174 } 12175 if (app.activities.size() > 0) { 12176 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12177 } 12178 outInfo.lastTrimLevel = app.trimMemoryLevel; 12179 int adj = app.curAdj; 12180 int procState = app.curProcState; 12181 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12182 outInfo.importanceReasonCode = app.adjTypeCode; 12183 outInfo.processState = app.curProcState; 12184 } 12185 12186 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12187 enforceNotIsolatedCaller("getRunningAppProcesses"); 12188 // Lazy instantiation of list 12189 List<ActivityManager.RunningAppProcessInfo> runList = null; 12190 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12191 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12192 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12193 synchronized (this) { 12194 // Iterate across all processes 12195 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12196 ProcessRecord app = mLruProcesses.get(i); 12197 if (!allUsers && app.userId != userId) { 12198 continue; 12199 } 12200 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12201 // Generate process state info for running application 12202 ActivityManager.RunningAppProcessInfo currApp = 12203 new ActivityManager.RunningAppProcessInfo(app.processName, 12204 app.pid, app.getPackageList()); 12205 fillInProcMemInfo(app, currApp); 12206 if (app.adjSource instanceof ProcessRecord) { 12207 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12208 currApp.importanceReasonImportance = 12209 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12210 app.adjSourceProcState); 12211 } else if (app.adjSource instanceof ActivityRecord) { 12212 ActivityRecord r = (ActivityRecord)app.adjSource; 12213 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12214 } 12215 if (app.adjTarget instanceof ComponentName) { 12216 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12217 } 12218 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12219 // + " lru=" + currApp.lru); 12220 if (runList == null) { 12221 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12222 } 12223 runList.add(currApp); 12224 } 12225 } 12226 } 12227 return runList; 12228 } 12229 12230 public List<ApplicationInfo> getRunningExternalApplications() { 12231 enforceNotIsolatedCaller("getRunningExternalApplications"); 12232 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12233 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12234 if (runningApps != null && runningApps.size() > 0) { 12235 Set<String> extList = new HashSet<String>(); 12236 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12237 if (app.pkgList != null) { 12238 for (String pkg : app.pkgList) { 12239 extList.add(pkg); 12240 } 12241 } 12242 } 12243 IPackageManager pm = AppGlobals.getPackageManager(); 12244 for (String pkg : extList) { 12245 try { 12246 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12247 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12248 retList.add(info); 12249 } 12250 } catch (RemoteException e) { 12251 } 12252 } 12253 } 12254 return retList; 12255 } 12256 12257 @Override 12258 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12259 enforceNotIsolatedCaller("getMyMemoryState"); 12260 synchronized (this) { 12261 ProcessRecord proc; 12262 synchronized (mPidsSelfLocked) { 12263 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12264 } 12265 fillInProcMemInfo(proc, outInfo); 12266 } 12267 } 12268 12269 @Override 12270 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12271 if (checkCallingPermission(android.Manifest.permission.DUMP) 12272 != PackageManager.PERMISSION_GRANTED) { 12273 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12274 + Binder.getCallingPid() 12275 + ", uid=" + Binder.getCallingUid() 12276 + " without permission " 12277 + android.Manifest.permission.DUMP); 12278 return; 12279 } 12280 12281 boolean dumpAll = false; 12282 boolean dumpClient = false; 12283 String dumpPackage = null; 12284 12285 int opti = 0; 12286 while (opti < args.length) { 12287 String opt = args[opti]; 12288 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12289 break; 12290 } 12291 opti++; 12292 if ("-a".equals(opt)) { 12293 dumpAll = true; 12294 } else if ("-c".equals(opt)) { 12295 dumpClient = true; 12296 } else if ("-h".equals(opt)) { 12297 pw.println("Activity manager dump options:"); 12298 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12299 pw.println(" cmd may be one of:"); 12300 pw.println(" a[ctivities]: activity stack state"); 12301 pw.println(" r[recents]: recent activities state"); 12302 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12303 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12304 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12305 pw.println(" o[om]: out of memory management"); 12306 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12307 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12308 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12309 pw.println(" service [COMP_SPEC]: service client-side state"); 12310 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12311 pw.println(" all: dump all activities"); 12312 pw.println(" top: dump the top activity"); 12313 pw.println(" write: write all pending state to storage"); 12314 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12315 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12316 pw.println(" a partial substring in a component name, a"); 12317 pw.println(" hex object identifier."); 12318 pw.println(" -a: include all available server state."); 12319 pw.println(" -c: include client state."); 12320 return; 12321 } else { 12322 pw.println("Unknown argument: " + opt + "; use -h for help"); 12323 } 12324 } 12325 12326 long origId = Binder.clearCallingIdentity(); 12327 boolean more = false; 12328 // Is the caller requesting to dump a particular piece of data? 12329 if (opti < args.length) { 12330 String cmd = args[opti]; 12331 opti++; 12332 if ("activities".equals(cmd) || "a".equals(cmd)) { 12333 synchronized (this) { 12334 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12335 } 12336 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12337 synchronized (this) { 12338 dumpRecentsLocked(fd, pw, args, opti, true, null); 12339 } 12340 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12341 String[] newArgs; 12342 String name; 12343 if (opti >= args.length) { 12344 name = null; 12345 newArgs = EMPTY_STRING_ARRAY; 12346 } else { 12347 name = args[opti]; 12348 opti++; 12349 newArgs = new String[args.length - opti]; 12350 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12351 args.length - opti); 12352 } 12353 synchronized (this) { 12354 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12355 } 12356 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12357 String[] newArgs; 12358 String name; 12359 if (opti >= args.length) { 12360 name = null; 12361 newArgs = EMPTY_STRING_ARRAY; 12362 } else { 12363 name = args[opti]; 12364 opti++; 12365 newArgs = new String[args.length - opti]; 12366 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12367 args.length - opti); 12368 } 12369 synchronized (this) { 12370 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12371 } 12372 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12373 String[] newArgs; 12374 String name; 12375 if (opti >= args.length) { 12376 name = null; 12377 newArgs = EMPTY_STRING_ARRAY; 12378 } else { 12379 name = args[opti]; 12380 opti++; 12381 newArgs = new String[args.length - opti]; 12382 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12383 args.length - opti); 12384 } 12385 synchronized (this) { 12386 dumpProcessesLocked(fd, pw, args, opti, true, name); 12387 } 12388 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12389 synchronized (this) { 12390 dumpOomLocked(fd, pw, args, opti, true); 12391 } 12392 } else if ("provider".equals(cmd)) { 12393 String[] newArgs; 12394 String name; 12395 if (opti >= args.length) { 12396 name = null; 12397 newArgs = EMPTY_STRING_ARRAY; 12398 } else { 12399 name = args[opti]; 12400 opti++; 12401 newArgs = new String[args.length - opti]; 12402 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12403 } 12404 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12405 pw.println("No providers match: " + name); 12406 pw.println("Use -h for help."); 12407 } 12408 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12409 synchronized (this) { 12410 dumpProvidersLocked(fd, pw, args, opti, true, null); 12411 } 12412 } else if ("service".equals(cmd)) { 12413 String[] newArgs; 12414 String name; 12415 if (opti >= args.length) { 12416 name = null; 12417 newArgs = EMPTY_STRING_ARRAY; 12418 } else { 12419 name = args[opti]; 12420 opti++; 12421 newArgs = new String[args.length - opti]; 12422 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12423 args.length - opti); 12424 } 12425 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12426 pw.println("No services match: " + name); 12427 pw.println("Use -h for help."); 12428 } 12429 } else if ("package".equals(cmd)) { 12430 String[] newArgs; 12431 if (opti >= args.length) { 12432 pw.println("package: no package name specified"); 12433 pw.println("Use -h for help."); 12434 } else { 12435 dumpPackage = args[opti]; 12436 opti++; 12437 newArgs = new String[args.length - opti]; 12438 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12439 args.length - opti); 12440 args = newArgs; 12441 opti = 0; 12442 more = true; 12443 } 12444 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12445 synchronized (this) { 12446 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12447 } 12448 } else if ("write".equals(cmd)) { 12449 mTaskPersister.flush(); 12450 pw.println("All tasks persisted."); 12451 return; 12452 } else { 12453 // Dumping a single activity? 12454 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12455 pw.println("Bad activity command, or no activities match: " + cmd); 12456 pw.println("Use -h for help."); 12457 } 12458 } 12459 if (!more) { 12460 Binder.restoreCallingIdentity(origId); 12461 return; 12462 } 12463 } 12464 12465 // No piece of data specified, dump everything. 12466 synchronized (this) { 12467 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12468 pw.println(); 12469 if (dumpAll) { 12470 pw.println("-------------------------------------------------------------------------------"); 12471 } 12472 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12473 pw.println(); 12474 if (dumpAll) { 12475 pw.println("-------------------------------------------------------------------------------"); 12476 } 12477 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12478 pw.println(); 12479 if (dumpAll) { 12480 pw.println("-------------------------------------------------------------------------------"); 12481 } 12482 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12483 pw.println(); 12484 if (dumpAll) { 12485 pw.println("-------------------------------------------------------------------------------"); 12486 } 12487 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12488 pw.println(); 12489 if (dumpAll) { 12490 pw.println("-------------------------------------------------------------------------------"); 12491 } 12492 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12493 pw.println(); 12494 if (dumpAll) { 12495 pw.println("-------------------------------------------------------------------------------"); 12496 } 12497 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12498 } 12499 Binder.restoreCallingIdentity(origId); 12500 } 12501 12502 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12503 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12504 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12505 12506 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12507 dumpPackage); 12508 boolean needSep = printedAnything; 12509 12510 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12511 dumpPackage, needSep, " mFocusedActivity: "); 12512 if (printed) { 12513 printedAnything = true; 12514 needSep = false; 12515 } 12516 12517 if (dumpPackage == null) { 12518 if (needSep) { 12519 pw.println(); 12520 } 12521 needSep = true; 12522 printedAnything = true; 12523 mStackSupervisor.dump(pw, " "); 12524 } 12525 12526 if (!printedAnything) { 12527 pw.println(" (nothing)"); 12528 } 12529 } 12530 12531 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12532 int opti, boolean dumpAll, String dumpPackage) { 12533 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12534 12535 boolean printedAnything = false; 12536 12537 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12538 boolean printedHeader = false; 12539 12540 final int N = mRecentTasks.size(); 12541 for (int i=0; i<N; i++) { 12542 TaskRecord tr = mRecentTasks.get(i); 12543 if (dumpPackage != null) { 12544 if (tr.realActivity == null || 12545 !dumpPackage.equals(tr.realActivity)) { 12546 continue; 12547 } 12548 } 12549 if (!printedHeader) { 12550 pw.println(" Recent tasks:"); 12551 printedHeader = true; 12552 printedAnything = true; 12553 } 12554 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12555 pw.println(tr); 12556 if (dumpAll) { 12557 mRecentTasks.get(i).dump(pw, " "); 12558 } 12559 } 12560 } 12561 12562 if (!printedAnything) { 12563 pw.println(" (nothing)"); 12564 } 12565 } 12566 12567 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12568 int opti, boolean dumpAll, String dumpPackage) { 12569 boolean needSep = false; 12570 boolean printedAnything = false; 12571 int numPers = 0; 12572 12573 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12574 12575 if (dumpAll) { 12576 final int NP = mProcessNames.getMap().size(); 12577 for (int ip=0; ip<NP; ip++) { 12578 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12579 final int NA = procs.size(); 12580 for (int ia=0; ia<NA; ia++) { 12581 ProcessRecord r = procs.valueAt(ia); 12582 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12583 continue; 12584 } 12585 if (!needSep) { 12586 pw.println(" All known processes:"); 12587 needSep = true; 12588 printedAnything = true; 12589 } 12590 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12591 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12592 pw.print(" "); pw.println(r); 12593 r.dump(pw, " "); 12594 if (r.persistent) { 12595 numPers++; 12596 } 12597 } 12598 } 12599 } 12600 12601 if (mIsolatedProcesses.size() > 0) { 12602 boolean printed = false; 12603 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12604 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12605 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12606 continue; 12607 } 12608 if (!printed) { 12609 if (needSep) { 12610 pw.println(); 12611 } 12612 pw.println(" Isolated process list (sorted by uid):"); 12613 printedAnything = true; 12614 printed = true; 12615 needSep = true; 12616 } 12617 pw.println(String.format("%sIsolated #%2d: %s", 12618 " ", i, r.toString())); 12619 } 12620 } 12621 12622 if (mLruProcesses.size() > 0) { 12623 if (needSep) { 12624 pw.println(); 12625 } 12626 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12627 pw.print(" total, non-act at "); 12628 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12629 pw.print(", non-svc at "); 12630 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12631 pw.println("):"); 12632 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12633 needSep = true; 12634 printedAnything = true; 12635 } 12636 12637 if (dumpAll || dumpPackage != null) { 12638 synchronized (mPidsSelfLocked) { 12639 boolean printed = false; 12640 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12641 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12642 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12643 continue; 12644 } 12645 if (!printed) { 12646 if (needSep) pw.println(); 12647 needSep = true; 12648 pw.println(" PID mappings:"); 12649 printed = true; 12650 printedAnything = true; 12651 } 12652 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12653 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12654 } 12655 } 12656 } 12657 12658 if (mForegroundProcesses.size() > 0) { 12659 synchronized (mPidsSelfLocked) { 12660 boolean printed = false; 12661 for (int i=0; i<mForegroundProcesses.size(); i++) { 12662 ProcessRecord r = mPidsSelfLocked.get( 12663 mForegroundProcesses.valueAt(i).pid); 12664 if (dumpPackage != null && (r == null 12665 || !r.pkgList.containsKey(dumpPackage))) { 12666 continue; 12667 } 12668 if (!printed) { 12669 if (needSep) pw.println(); 12670 needSep = true; 12671 pw.println(" Foreground Processes:"); 12672 printed = true; 12673 printedAnything = true; 12674 } 12675 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12676 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12677 } 12678 } 12679 } 12680 12681 if (mPersistentStartingProcesses.size() > 0) { 12682 if (needSep) pw.println(); 12683 needSep = true; 12684 printedAnything = true; 12685 pw.println(" Persisent processes that are starting:"); 12686 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12687 "Starting Norm", "Restarting PERS", dumpPackage); 12688 } 12689 12690 if (mRemovedProcesses.size() > 0) { 12691 if (needSep) pw.println(); 12692 needSep = true; 12693 printedAnything = true; 12694 pw.println(" Processes that are being removed:"); 12695 dumpProcessList(pw, this, mRemovedProcesses, " ", 12696 "Removed Norm", "Removed PERS", dumpPackage); 12697 } 12698 12699 if (mProcessesOnHold.size() > 0) { 12700 if (needSep) pw.println(); 12701 needSep = true; 12702 printedAnything = true; 12703 pw.println(" Processes that are on old until the system is ready:"); 12704 dumpProcessList(pw, this, mProcessesOnHold, " ", 12705 "OnHold Norm", "OnHold PERS", dumpPackage); 12706 } 12707 12708 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12709 12710 if (mProcessCrashTimes.getMap().size() > 0) { 12711 boolean printed = false; 12712 long now = SystemClock.uptimeMillis(); 12713 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12714 final int NP = pmap.size(); 12715 for (int ip=0; ip<NP; ip++) { 12716 String pname = pmap.keyAt(ip); 12717 SparseArray<Long> uids = pmap.valueAt(ip); 12718 final int N = uids.size(); 12719 for (int i=0; i<N; i++) { 12720 int puid = uids.keyAt(i); 12721 ProcessRecord r = mProcessNames.get(pname, puid); 12722 if (dumpPackage != null && (r == null 12723 || !r.pkgList.containsKey(dumpPackage))) { 12724 continue; 12725 } 12726 if (!printed) { 12727 if (needSep) pw.println(); 12728 needSep = true; 12729 pw.println(" Time since processes crashed:"); 12730 printed = true; 12731 printedAnything = true; 12732 } 12733 pw.print(" Process "); pw.print(pname); 12734 pw.print(" uid "); pw.print(puid); 12735 pw.print(": last crashed "); 12736 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12737 pw.println(" ago"); 12738 } 12739 } 12740 } 12741 12742 if (mBadProcesses.getMap().size() > 0) { 12743 boolean printed = false; 12744 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12745 final int NP = pmap.size(); 12746 for (int ip=0; ip<NP; ip++) { 12747 String pname = pmap.keyAt(ip); 12748 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12749 final int N = uids.size(); 12750 for (int i=0; i<N; i++) { 12751 int puid = uids.keyAt(i); 12752 ProcessRecord r = mProcessNames.get(pname, puid); 12753 if (dumpPackage != null && (r == null 12754 || !r.pkgList.containsKey(dumpPackage))) { 12755 continue; 12756 } 12757 if (!printed) { 12758 if (needSep) pw.println(); 12759 needSep = true; 12760 pw.println(" Bad processes:"); 12761 printedAnything = true; 12762 } 12763 BadProcessInfo info = uids.valueAt(i); 12764 pw.print(" Bad process "); pw.print(pname); 12765 pw.print(" uid "); pw.print(puid); 12766 pw.print(": crashed at time "); pw.println(info.time); 12767 if (info.shortMsg != null) { 12768 pw.print(" Short msg: "); pw.println(info.shortMsg); 12769 } 12770 if (info.longMsg != null) { 12771 pw.print(" Long msg: "); pw.println(info.longMsg); 12772 } 12773 if (info.stack != null) { 12774 pw.println(" Stack:"); 12775 int lastPos = 0; 12776 for (int pos=0; pos<info.stack.length(); pos++) { 12777 if (info.stack.charAt(pos) == '\n') { 12778 pw.print(" "); 12779 pw.write(info.stack, lastPos, pos-lastPos); 12780 pw.println(); 12781 lastPos = pos+1; 12782 } 12783 } 12784 if (lastPos < info.stack.length()) { 12785 pw.print(" "); 12786 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12787 pw.println(); 12788 } 12789 } 12790 } 12791 } 12792 } 12793 12794 if (dumpPackage == null) { 12795 pw.println(); 12796 needSep = false; 12797 pw.println(" mStartedUsers:"); 12798 for (int i=0; i<mStartedUsers.size(); i++) { 12799 UserStartedState uss = mStartedUsers.valueAt(i); 12800 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12801 pw.print(": "); uss.dump("", pw); 12802 } 12803 pw.print(" mStartedUserArray: ["); 12804 for (int i=0; i<mStartedUserArray.length; i++) { 12805 if (i > 0) pw.print(", "); 12806 pw.print(mStartedUserArray[i]); 12807 } 12808 pw.println("]"); 12809 pw.print(" mUserLru: ["); 12810 for (int i=0; i<mUserLru.size(); i++) { 12811 if (i > 0) pw.print(", "); 12812 pw.print(mUserLru.get(i)); 12813 } 12814 pw.println("]"); 12815 if (dumpAll) { 12816 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12817 } 12818 synchronized (mUserProfileGroupIdsSelfLocked) { 12819 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12820 pw.println(" mUserProfileGroupIds:"); 12821 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12822 pw.print(" User #"); 12823 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12824 pw.print(" -> profile #"); 12825 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12826 } 12827 } 12828 } 12829 } 12830 if (mHomeProcess != null && (dumpPackage == null 12831 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12832 if (needSep) { 12833 pw.println(); 12834 needSep = false; 12835 } 12836 pw.println(" mHomeProcess: " + mHomeProcess); 12837 } 12838 if (mPreviousProcess != null && (dumpPackage == null 12839 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12840 if (needSep) { 12841 pw.println(); 12842 needSep = false; 12843 } 12844 pw.println(" mPreviousProcess: " + mPreviousProcess); 12845 } 12846 if (dumpAll) { 12847 StringBuilder sb = new StringBuilder(128); 12848 sb.append(" mPreviousProcessVisibleTime: "); 12849 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12850 pw.println(sb); 12851 } 12852 if (mHeavyWeightProcess != null && (dumpPackage == null 12853 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12854 if (needSep) { 12855 pw.println(); 12856 needSep = false; 12857 } 12858 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12859 } 12860 if (dumpPackage == null) { 12861 pw.println(" mConfiguration: " + mConfiguration); 12862 } 12863 if (dumpAll) { 12864 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12865 if (mCompatModePackages.getPackages().size() > 0) { 12866 boolean printed = false; 12867 for (Map.Entry<String, Integer> entry 12868 : mCompatModePackages.getPackages().entrySet()) { 12869 String pkg = entry.getKey(); 12870 int mode = entry.getValue(); 12871 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12872 continue; 12873 } 12874 if (!printed) { 12875 pw.println(" mScreenCompatPackages:"); 12876 printed = true; 12877 } 12878 pw.print(" "); pw.print(pkg); pw.print(": "); 12879 pw.print(mode); pw.println(); 12880 } 12881 } 12882 } 12883 if (dumpPackage == null) { 12884 pw.println(" mWakefulness=" 12885 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 12886 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 12887 + lockScreenShownToString()); 12888 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12889 } 12890 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12891 || mOrigWaitForDebugger) { 12892 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12893 || dumpPackage.equals(mOrigDebugApp)) { 12894 if (needSep) { 12895 pw.println(); 12896 needSep = false; 12897 } 12898 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12899 + " mDebugTransient=" + mDebugTransient 12900 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12901 } 12902 } 12903 if (mOpenGlTraceApp != null) { 12904 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12905 if (needSep) { 12906 pw.println(); 12907 needSep = false; 12908 } 12909 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12910 } 12911 } 12912 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12913 || mProfileFd != null) { 12914 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12915 if (needSep) { 12916 pw.println(); 12917 needSep = false; 12918 } 12919 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12920 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12921 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12922 + mAutoStopProfiler); 12923 pw.println(" mProfileType=" + mProfileType); 12924 } 12925 } 12926 if (dumpPackage == null) { 12927 if (mAlwaysFinishActivities || mController != null) { 12928 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12929 + " mController=" + mController); 12930 } 12931 if (dumpAll) { 12932 pw.println(" Total persistent processes: " + numPers); 12933 pw.println(" mProcessesReady=" + mProcessesReady 12934 + " mSystemReady=" + mSystemReady 12935 + " mBooted=" + mBooted 12936 + " mFactoryTest=" + mFactoryTest); 12937 pw.println(" mBooting=" + mBooting 12938 + " mCallFinishBooting=" + mCallFinishBooting 12939 + " mBootAnimationComplete=" + mBootAnimationComplete); 12940 pw.print(" mLastPowerCheckRealtime="); 12941 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12942 pw.println(""); 12943 pw.print(" mLastPowerCheckUptime="); 12944 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12945 pw.println(""); 12946 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12947 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12948 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12949 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12950 + " (" + mLruProcesses.size() + " total)" 12951 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12952 + " mNumServiceProcs=" + mNumServiceProcs 12953 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12954 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12955 + " mLastMemoryLevel" + mLastMemoryLevel 12956 + " mLastNumProcesses" + mLastNumProcesses); 12957 long now = SystemClock.uptimeMillis(); 12958 pw.print(" mLastIdleTime="); 12959 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12960 pw.print(" mLowRamSinceLastIdle="); 12961 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12962 pw.println(); 12963 } 12964 } 12965 12966 if (!printedAnything) { 12967 pw.println(" (nothing)"); 12968 } 12969 } 12970 12971 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12972 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12973 if (mProcessesToGc.size() > 0) { 12974 boolean printed = false; 12975 long now = SystemClock.uptimeMillis(); 12976 for (int i=0; i<mProcessesToGc.size(); i++) { 12977 ProcessRecord proc = mProcessesToGc.get(i); 12978 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12979 continue; 12980 } 12981 if (!printed) { 12982 if (needSep) pw.println(); 12983 needSep = true; 12984 pw.println(" Processes that are waiting to GC:"); 12985 printed = true; 12986 } 12987 pw.print(" Process "); pw.println(proc); 12988 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12989 pw.print(", last gced="); 12990 pw.print(now-proc.lastRequestedGc); 12991 pw.print(" ms ago, last lowMem="); 12992 pw.print(now-proc.lastLowMemory); 12993 pw.println(" ms ago"); 12994 12995 } 12996 } 12997 return needSep; 12998 } 12999 13000 void printOomLevel(PrintWriter pw, String name, int adj) { 13001 pw.print(" "); 13002 if (adj >= 0) { 13003 pw.print(' '); 13004 if (adj < 10) pw.print(' '); 13005 } else { 13006 if (adj > -10) pw.print(' '); 13007 } 13008 pw.print(adj); 13009 pw.print(": "); 13010 pw.print(name); 13011 pw.print(" ("); 13012 pw.print(mProcessList.getMemLevel(adj)/1024); 13013 pw.println(" kB)"); 13014 } 13015 13016 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13017 int opti, boolean dumpAll) { 13018 boolean needSep = false; 13019 13020 if (mLruProcesses.size() > 0) { 13021 if (needSep) pw.println(); 13022 needSep = true; 13023 pw.println(" OOM levels:"); 13024 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13025 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13026 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13027 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13028 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13029 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13030 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13031 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13032 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13033 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13034 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13035 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13036 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13037 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13038 13039 if (needSep) pw.println(); 13040 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13041 pw.print(" total, non-act at "); 13042 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13043 pw.print(", non-svc at "); 13044 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13045 pw.println("):"); 13046 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13047 needSep = true; 13048 } 13049 13050 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13051 13052 pw.println(); 13053 pw.println(" mHomeProcess: " + mHomeProcess); 13054 pw.println(" mPreviousProcess: " + mPreviousProcess); 13055 if (mHeavyWeightProcess != null) { 13056 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13057 } 13058 13059 return true; 13060 } 13061 13062 /** 13063 * There are three ways to call this: 13064 * - no provider specified: dump all the providers 13065 * - a flattened component name that matched an existing provider was specified as the 13066 * first arg: dump that one provider 13067 * - the first arg isn't the flattened component name of an existing provider: 13068 * dump all providers whose component contains the first arg as a substring 13069 */ 13070 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13071 int opti, boolean dumpAll) { 13072 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13073 } 13074 13075 static class ItemMatcher { 13076 ArrayList<ComponentName> components; 13077 ArrayList<String> strings; 13078 ArrayList<Integer> objects; 13079 boolean all; 13080 13081 ItemMatcher() { 13082 all = true; 13083 } 13084 13085 void build(String name) { 13086 ComponentName componentName = ComponentName.unflattenFromString(name); 13087 if (componentName != null) { 13088 if (components == null) { 13089 components = new ArrayList<ComponentName>(); 13090 } 13091 components.add(componentName); 13092 all = false; 13093 } else { 13094 int objectId = 0; 13095 // Not a '/' separated full component name; maybe an object ID? 13096 try { 13097 objectId = Integer.parseInt(name, 16); 13098 if (objects == null) { 13099 objects = new ArrayList<Integer>(); 13100 } 13101 objects.add(objectId); 13102 all = false; 13103 } catch (RuntimeException e) { 13104 // Not an integer; just do string match. 13105 if (strings == null) { 13106 strings = new ArrayList<String>(); 13107 } 13108 strings.add(name); 13109 all = false; 13110 } 13111 } 13112 } 13113 13114 int build(String[] args, int opti) { 13115 for (; opti<args.length; opti++) { 13116 String name = args[opti]; 13117 if ("--".equals(name)) { 13118 return opti+1; 13119 } 13120 build(name); 13121 } 13122 return opti; 13123 } 13124 13125 boolean match(Object object, ComponentName comp) { 13126 if (all) { 13127 return true; 13128 } 13129 if (components != null) { 13130 for (int i=0; i<components.size(); i++) { 13131 if (components.get(i).equals(comp)) { 13132 return true; 13133 } 13134 } 13135 } 13136 if (objects != null) { 13137 for (int i=0; i<objects.size(); i++) { 13138 if (System.identityHashCode(object) == objects.get(i)) { 13139 return true; 13140 } 13141 } 13142 } 13143 if (strings != null) { 13144 String flat = comp.flattenToString(); 13145 for (int i=0; i<strings.size(); i++) { 13146 if (flat.contains(strings.get(i))) { 13147 return true; 13148 } 13149 } 13150 } 13151 return false; 13152 } 13153 } 13154 13155 /** 13156 * There are three things that cmd can be: 13157 * - a flattened component name that matches an existing activity 13158 * - the cmd arg isn't the flattened component name of an existing activity: 13159 * dump all activity whose component contains the cmd as a substring 13160 * - A hex number of the ActivityRecord object instance. 13161 */ 13162 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13163 int opti, boolean dumpAll) { 13164 ArrayList<ActivityRecord> activities; 13165 13166 synchronized (this) { 13167 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13168 } 13169 13170 if (activities.size() <= 0) { 13171 return false; 13172 } 13173 13174 String[] newArgs = new String[args.length - opti]; 13175 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13176 13177 TaskRecord lastTask = null; 13178 boolean needSep = false; 13179 for (int i=activities.size()-1; i>=0; i--) { 13180 ActivityRecord r = activities.get(i); 13181 if (needSep) { 13182 pw.println(); 13183 } 13184 needSep = true; 13185 synchronized (this) { 13186 if (lastTask != r.task) { 13187 lastTask = r.task; 13188 pw.print("TASK "); pw.print(lastTask.affinity); 13189 pw.print(" id="); pw.println(lastTask.taskId); 13190 if (dumpAll) { 13191 lastTask.dump(pw, " "); 13192 } 13193 } 13194 } 13195 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13196 } 13197 return true; 13198 } 13199 13200 /** 13201 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13202 * there is a thread associated with the activity. 13203 */ 13204 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13205 final ActivityRecord r, String[] args, boolean dumpAll) { 13206 String innerPrefix = prefix + " "; 13207 synchronized (this) { 13208 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13209 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13210 pw.print(" pid="); 13211 if (r.app != null) pw.println(r.app.pid); 13212 else pw.println("(not running)"); 13213 if (dumpAll) { 13214 r.dump(pw, innerPrefix); 13215 } 13216 } 13217 if (r.app != null && r.app.thread != null) { 13218 // flush anything that is already in the PrintWriter since the thread is going 13219 // to write to the file descriptor directly 13220 pw.flush(); 13221 try { 13222 TransferPipe tp = new TransferPipe(); 13223 try { 13224 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13225 r.appToken, innerPrefix, args); 13226 tp.go(fd); 13227 } finally { 13228 tp.kill(); 13229 } 13230 } catch (IOException e) { 13231 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13232 } catch (RemoteException e) { 13233 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13234 } 13235 } 13236 } 13237 13238 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13239 int opti, boolean dumpAll, String dumpPackage) { 13240 boolean needSep = false; 13241 boolean onlyHistory = false; 13242 boolean printedAnything = false; 13243 13244 if ("history".equals(dumpPackage)) { 13245 if (opti < args.length && "-s".equals(args[opti])) { 13246 dumpAll = false; 13247 } 13248 onlyHistory = true; 13249 dumpPackage = null; 13250 } 13251 13252 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13253 if (!onlyHistory && dumpAll) { 13254 if (mRegisteredReceivers.size() > 0) { 13255 boolean printed = false; 13256 Iterator it = mRegisteredReceivers.values().iterator(); 13257 while (it.hasNext()) { 13258 ReceiverList r = (ReceiverList)it.next(); 13259 if (dumpPackage != null && (r.app == null || 13260 !dumpPackage.equals(r.app.info.packageName))) { 13261 continue; 13262 } 13263 if (!printed) { 13264 pw.println(" Registered Receivers:"); 13265 needSep = true; 13266 printed = true; 13267 printedAnything = true; 13268 } 13269 pw.print(" * "); pw.println(r); 13270 r.dump(pw, " "); 13271 } 13272 } 13273 13274 if (mReceiverResolver.dump(pw, needSep ? 13275 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13276 " ", dumpPackage, false, false)) { 13277 needSep = true; 13278 printedAnything = true; 13279 } 13280 } 13281 13282 for (BroadcastQueue q : mBroadcastQueues) { 13283 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13284 printedAnything |= needSep; 13285 } 13286 13287 needSep = true; 13288 13289 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13290 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13291 if (needSep) { 13292 pw.println(); 13293 } 13294 needSep = true; 13295 printedAnything = true; 13296 pw.print(" Sticky broadcasts for user "); 13297 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13298 StringBuilder sb = new StringBuilder(128); 13299 for (Map.Entry<String, ArrayList<Intent>> ent 13300 : mStickyBroadcasts.valueAt(user).entrySet()) { 13301 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13302 if (dumpAll) { 13303 pw.println(":"); 13304 ArrayList<Intent> intents = ent.getValue(); 13305 final int N = intents.size(); 13306 for (int i=0; i<N; i++) { 13307 sb.setLength(0); 13308 sb.append(" Intent: "); 13309 intents.get(i).toShortString(sb, false, true, false, false); 13310 pw.println(sb.toString()); 13311 Bundle bundle = intents.get(i).getExtras(); 13312 if (bundle != null) { 13313 pw.print(" "); 13314 pw.println(bundle.toString()); 13315 } 13316 } 13317 } else { 13318 pw.println(""); 13319 } 13320 } 13321 } 13322 } 13323 13324 if (!onlyHistory && dumpAll) { 13325 pw.println(); 13326 for (BroadcastQueue queue : mBroadcastQueues) { 13327 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13328 + queue.mBroadcastsScheduled); 13329 } 13330 pw.println(" mHandler:"); 13331 mHandler.dump(new PrintWriterPrinter(pw), " "); 13332 needSep = true; 13333 printedAnything = true; 13334 } 13335 13336 if (!printedAnything) { 13337 pw.println(" (nothing)"); 13338 } 13339 } 13340 13341 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13342 int opti, boolean dumpAll, String dumpPackage) { 13343 boolean needSep; 13344 boolean printedAnything = false; 13345 13346 ItemMatcher matcher = new ItemMatcher(); 13347 matcher.build(args, opti); 13348 13349 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13350 13351 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13352 printedAnything |= needSep; 13353 13354 if (mLaunchingProviders.size() > 0) { 13355 boolean printed = false; 13356 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13357 ContentProviderRecord r = mLaunchingProviders.get(i); 13358 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13359 continue; 13360 } 13361 if (!printed) { 13362 if (needSep) pw.println(); 13363 needSep = true; 13364 pw.println(" Launching content providers:"); 13365 printed = true; 13366 printedAnything = true; 13367 } 13368 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13369 pw.println(r); 13370 } 13371 } 13372 13373 if (mGrantedUriPermissions.size() > 0) { 13374 boolean printed = false; 13375 int dumpUid = -2; 13376 if (dumpPackage != null) { 13377 try { 13378 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13379 } catch (NameNotFoundException e) { 13380 dumpUid = -1; 13381 } 13382 } 13383 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13384 int uid = mGrantedUriPermissions.keyAt(i); 13385 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13386 continue; 13387 } 13388 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13389 if (!printed) { 13390 if (needSep) pw.println(); 13391 needSep = true; 13392 pw.println(" Granted Uri Permissions:"); 13393 printed = true; 13394 printedAnything = true; 13395 } 13396 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13397 for (UriPermission perm : perms.values()) { 13398 pw.print(" "); pw.println(perm); 13399 if (dumpAll) { 13400 perm.dump(pw, " "); 13401 } 13402 } 13403 } 13404 } 13405 13406 if (!printedAnything) { 13407 pw.println(" (nothing)"); 13408 } 13409 } 13410 13411 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13412 int opti, boolean dumpAll, String dumpPackage) { 13413 boolean printed = false; 13414 13415 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13416 13417 if (mIntentSenderRecords.size() > 0) { 13418 Iterator<WeakReference<PendingIntentRecord>> it 13419 = mIntentSenderRecords.values().iterator(); 13420 while (it.hasNext()) { 13421 WeakReference<PendingIntentRecord> ref = it.next(); 13422 PendingIntentRecord rec = ref != null ? ref.get(): null; 13423 if (dumpPackage != null && (rec == null 13424 || !dumpPackage.equals(rec.key.packageName))) { 13425 continue; 13426 } 13427 printed = true; 13428 if (rec != null) { 13429 pw.print(" * "); pw.println(rec); 13430 if (dumpAll) { 13431 rec.dump(pw, " "); 13432 } 13433 } else { 13434 pw.print(" * "); pw.println(ref); 13435 } 13436 } 13437 } 13438 13439 if (!printed) { 13440 pw.println(" (nothing)"); 13441 } 13442 } 13443 13444 private static final int dumpProcessList(PrintWriter pw, 13445 ActivityManagerService service, List list, 13446 String prefix, String normalLabel, String persistentLabel, 13447 String dumpPackage) { 13448 int numPers = 0; 13449 final int N = list.size()-1; 13450 for (int i=N; i>=0; i--) { 13451 ProcessRecord r = (ProcessRecord)list.get(i); 13452 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13453 continue; 13454 } 13455 pw.println(String.format("%s%s #%2d: %s", 13456 prefix, (r.persistent ? persistentLabel : normalLabel), 13457 i, r.toString())); 13458 if (r.persistent) { 13459 numPers++; 13460 } 13461 } 13462 return numPers; 13463 } 13464 13465 private static final boolean dumpProcessOomList(PrintWriter pw, 13466 ActivityManagerService service, List<ProcessRecord> origList, 13467 String prefix, String normalLabel, String persistentLabel, 13468 boolean inclDetails, String dumpPackage) { 13469 13470 ArrayList<Pair<ProcessRecord, Integer>> list 13471 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13472 for (int i=0; i<origList.size(); i++) { 13473 ProcessRecord r = origList.get(i); 13474 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13475 continue; 13476 } 13477 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13478 } 13479 13480 if (list.size() <= 0) { 13481 return false; 13482 } 13483 13484 Comparator<Pair<ProcessRecord, Integer>> comparator 13485 = new Comparator<Pair<ProcessRecord, Integer>>() { 13486 @Override 13487 public int compare(Pair<ProcessRecord, Integer> object1, 13488 Pair<ProcessRecord, Integer> object2) { 13489 if (object1.first.setAdj != object2.first.setAdj) { 13490 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13491 } 13492 if (object1.second.intValue() != object2.second.intValue()) { 13493 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13494 } 13495 return 0; 13496 } 13497 }; 13498 13499 Collections.sort(list, comparator); 13500 13501 final long curRealtime = SystemClock.elapsedRealtime(); 13502 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13503 final long curUptime = SystemClock.uptimeMillis(); 13504 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13505 13506 for (int i=list.size()-1; i>=0; i--) { 13507 ProcessRecord r = list.get(i).first; 13508 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13509 char schedGroup; 13510 switch (r.setSchedGroup) { 13511 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13512 schedGroup = 'B'; 13513 break; 13514 case Process.THREAD_GROUP_DEFAULT: 13515 schedGroup = 'F'; 13516 break; 13517 default: 13518 schedGroup = '?'; 13519 break; 13520 } 13521 char foreground; 13522 if (r.foregroundActivities) { 13523 foreground = 'A'; 13524 } else if (r.foregroundServices) { 13525 foreground = 'S'; 13526 } else { 13527 foreground = ' '; 13528 } 13529 String procState = ProcessList.makeProcStateString(r.curProcState); 13530 pw.print(prefix); 13531 pw.print(r.persistent ? persistentLabel : normalLabel); 13532 pw.print(" #"); 13533 int num = (origList.size()-1)-list.get(i).second; 13534 if (num < 10) pw.print(' '); 13535 pw.print(num); 13536 pw.print(": "); 13537 pw.print(oomAdj); 13538 pw.print(' '); 13539 pw.print(schedGroup); 13540 pw.print('/'); 13541 pw.print(foreground); 13542 pw.print('/'); 13543 pw.print(procState); 13544 pw.print(" trm:"); 13545 if (r.trimMemoryLevel < 10) pw.print(' '); 13546 pw.print(r.trimMemoryLevel); 13547 pw.print(' '); 13548 pw.print(r.toShortString()); 13549 pw.print(" ("); 13550 pw.print(r.adjType); 13551 pw.println(')'); 13552 if (r.adjSource != null || r.adjTarget != null) { 13553 pw.print(prefix); 13554 pw.print(" "); 13555 if (r.adjTarget instanceof ComponentName) { 13556 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13557 } else if (r.adjTarget != null) { 13558 pw.print(r.adjTarget.toString()); 13559 } else { 13560 pw.print("{null}"); 13561 } 13562 pw.print("<="); 13563 if (r.adjSource instanceof ProcessRecord) { 13564 pw.print("Proc{"); 13565 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13566 pw.println("}"); 13567 } else if (r.adjSource != null) { 13568 pw.println(r.adjSource.toString()); 13569 } else { 13570 pw.println("{null}"); 13571 } 13572 } 13573 if (inclDetails) { 13574 pw.print(prefix); 13575 pw.print(" "); 13576 pw.print("oom: max="); pw.print(r.maxAdj); 13577 pw.print(" curRaw="); pw.print(r.curRawAdj); 13578 pw.print(" setRaw="); pw.print(r.setRawAdj); 13579 pw.print(" cur="); pw.print(r.curAdj); 13580 pw.print(" set="); pw.println(r.setAdj); 13581 pw.print(prefix); 13582 pw.print(" "); 13583 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13584 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13585 pw.print(" lastPss="); pw.print(r.lastPss); 13586 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13587 pw.print(prefix); 13588 pw.print(" "); 13589 pw.print("cached="); pw.print(r.cached); 13590 pw.print(" empty="); pw.print(r.empty); 13591 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13592 13593 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13594 if (r.lastWakeTime != 0) { 13595 long wtime; 13596 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13597 synchronized (stats) { 13598 wtime = stats.getProcessWakeTime(r.info.uid, 13599 r.pid, curRealtime); 13600 } 13601 long timeUsed = wtime - r.lastWakeTime; 13602 pw.print(prefix); 13603 pw.print(" "); 13604 pw.print("keep awake over "); 13605 TimeUtils.formatDuration(realtimeSince, pw); 13606 pw.print(" used "); 13607 TimeUtils.formatDuration(timeUsed, pw); 13608 pw.print(" ("); 13609 pw.print((timeUsed*100)/realtimeSince); 13610 pw.println("%)"); 13611 } 13612 if (r.lastCpuTime != 0) { 13613 long timeUsed = r.curCpuTime - r.lastCpuTime; 13614 pw.print(prefix); 13615 pw.print(" "); 13616 pw.print("run cpu over "); 13617 TimeUtils.formatDuration(uptimeSince, pw); 13618 pw.print(" used "); 13619 TimeUtils.formatDuration(timeUsed, pw); 13620 pw.print(" ("); 13621 pw.print((timeUsed*100)/uptimeSince); 13622 pw.println("%)"); 13623 } 13624 } 13625 } 13626 } 13627 return true; 13628 } 13629 13630 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13631 String[] args) { 13632 ArrayList<ProcessRecord> procs; 13633 synchronized (this) { 13634 if (args != null && args.length > start 13635 && args[start].charAt(0) != '-') { 13636 procs = new ArrayList<ProcessRecord>(); 13637 int pid = -1; 13638 try { 13639 pid = Integer.parseInt(args[start]); 13640 } catch (NumberFormatException e) { 13641 } 13642 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13643 ProcessRecord proc = mLruProcesses.get(i); 13644 if (proc.pid == pid) { 13645 procs.add(proc); 13646 } else if (allPkgs && proc.pkgList != null 13647 && proc.pkgList.containsKey(args[start])) { 13648 procs.add(proc); 13649 } else if (proc.processName.equals(args[start])) { 13650 procs.add(proc); 13651 } 13652 } 13653 if (procs.size() <= 0) { 13654 return null; 13655 } 13656 } else { 13657 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13658 } 13659 } 13660 return procs; 13661 } 13662 13663 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13664 PrintWriter pw, String[] args) { 13665 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13666 if (procs == null) { 13667 pw.println("No process found for: " + args[0]); 13668 return; 13669 } 13670 13671 long uptime = SystemClock.uptimeMillis(); 13672 long realtime = SystemClock.elapsedRealtime(); 13673 pw.println("Applications Graphics Acceleration Info:"); 13674 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13675 13676 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13677 ProcessRecord r = procs.get(i); 13678 if (r.thread != null) { 13679 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13680 pw.flush(); 13681 try { 13682 TransferPipe tp = new TransferPipe(); 13683 try { 13684 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13685 tp.go(fd); 13686 } finally { 13687 tp.kill(); 13688 } 13689 } catch (IOException e) { 13690 pw.println("Failure while dumping the app: " + r); 13691 pw.flush(); 13692 } catch (RemoteException e) { 13693 pw.println("Got a RemoteException while dumping the app " + r); 13694 pw.flush(); 13695 } 13696 } 13697 } 13698 } 13699 13700 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13701 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13702 if (procs == null) { 13703 pw.println("No process found for: " + args[0]); 13704 return; 13705 } 13706 13707 pw.println("Applications Database Info:"); 13708 13709 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13710 ProcessRecord r = procs.get(i); 13711 if (r.thread != null) { 13712 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13713 pw.flush(); 13714 try { 13715 TransferPipe tp = new TransferPipe(); 13716 try { 13717 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13718 tp.go(fd); 13719 } finally { 13720 tp.kill(); 13721 } 13722 } catch (IOException e) { 13723 pw.println("Failure while dumping the app: " + r); 13724 pw.flush(); 13725 } catch (RemoteException e) { 13726 pw.println("Got a RemoteException while dumping the app " + r); 13727 pw.flush(); 13728 } 13729 } 13730 } 13731 } 13732 13733 final static class MemItem { 13734 final boolean isProc; 13735 final String label; 13736 final String shortLabel; 13737 final long pss; 13738 final int id; 13739 final boolean hasActivities; 13740 ArrayList<MemItem> subitems; 13741 13742 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13743 boolean _hasActivities) { 13744 isProc = true; 13745 label = _label; 13746 shortLabel = _shortLabel; 13747 pss = _pss; 13748 id = _id; 13749 hasActivities = _hasActivities; 13750 } 13751 13752 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13753 isProc = false; 13754 label = _label; 13755 shortLabel = _shortLabel; 13756 pss = _pss; 13757 id = _id; 13758 hasActivities = false; 13759 } 13760 } 13761 13762 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13763 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13764 if (sort && !isCompact) { 13765 Collections.sort(items, new Comparator<MemItem>() { 13766 @Override 13767 public int compare(MemItem lhs, MemItem rhs) { 13768 if (lhs.pss < rhs.pss) { 13769 return 1; 13770 } else if (lhs.pss > rhs.pss) { 13771 return -1; 13772 } 13773 return 0; 13774 } 13775 }); 13776 } 13777 13778 for (int i=0; i<items.size(); i++) { 13779 MemItem mi = items.get(i); 13780 if (!isCompact) { 13781 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13782 } else if (mi.isProc) { 13783 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13784 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13785 pw.println(mi.hasActivities ? ",a" : ",e"); 13786 } else { 13787 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13788 pw.println(mi.pss); 13789 } 13790 if (mi.subitems != null) { 13791 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13792 true, isCompact); 13793 } 13794 } 13795 } 13796 13797 // These are in KB. 13798 static final long[] DUMP_MEM_BUCKETS = new long[] { 13799 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13800 120*1024, 160*1024, 200*1024, 13801 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13802 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13803 }; 13804 13805 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13806 boolean stackLike) { 13807 int start = label.lastIndexOf('.'); 13808 if (start >= 0) start++; 13809 else start = 0; 13810 int end = label.length(); 13811 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13812 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13813 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13814 out.append(bucket); 13815 out.append(stackLike ? "MB." : "MB "); 13816 out.append(label, start, end); 13817 return; 13818 } 13819 } 13820 out.append(memKB/1024); 13821 out.append(stackLike ? "MB." : "MB "); 13822 out.append(label, start, end); 13823 } 13824 13825 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13826 ProcessList.NATIVE_ADJ, 13827 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13828 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13829 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13830 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13831 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13832 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13833 }; 13834 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13835 "Native", 13836 "System", "Persistent", "Persistent Service", "Foreground", 13837 "Visible", "Perceptible", 13838 "Heavy Weight", "Backup", 13839 "A Services", "Home", 13840 "Previous", "B Services", "Cached" 13841 }; 13842 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13843 "native", 13844 "sys", "pers", "persvc", "fore", 13845 "vis", "percept", 13846 "heavy", "backup", 13847 "servicea", "home", 13848 "prev", "serviceb", "cached" 13849 }; 13850 13851 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13852 long realtime, boolean isCheckinRequest, boolean isCompact) { 13853 if (isCheckinRequest || isCompact) { 13854 // short checkin version 13855 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13856 } else { 13857 pw.println("Applications Memory Usage (kB):"); 13858 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13859 } 13860 } 13861 13862 private static final int KSM_SHARED = 0; 13863 private static final int KSM_SHARING = 1; 13864 private static final int KSM_UNSHARED = 2; 13865 private static final int KSM_VOLATILE = 3; 13866 13867 private final long[] getKsmInfo() { 13868 long[] longOut = new long[4]; 13869 final int[] SINGLE_LONG_FORMAT = new int[] { 13870 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13871 }; 13872 long[] longTmp = new long[1]; 13873 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13874 SINGLE_LONG_FORMAT, null, longTmp, null); 13875 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13876 longTmp[0] = 0; 13877 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13878 SINGLE_LONG_FORMAT, null, longTmp, null); 13879 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13880 longTmp[0] = 0; 13881 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13882 SINGLE_LONG_FORMAT, null, longTmp, null); 13883 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13884 longTmp[0] = 0; 13885 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13886 SINGLE_LONG_FORMAT, null, longTmp, null); 13887 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 13888 return longOut; 13889 } 13890 13891 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13892 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13893 boolean dumpDetails = false; 13894 boolean dumpFullDetails = false; 13895 boolean dumpDalvik = false; 13896 boolean oomOnly = false; 13897 boolean isCompact = false; 13898 boolean localOnly = false; 13899 boolean packages = false; 13900 13901 int opti = 0; 13902 while (opti < args.length) { 13903 String opt = args[opti]; 13904 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13905 break; 13906 } 13907 opti++; 13908 if ("-a".equals(opt)) { 13909 dumpDetails = true; 13910 dumpFullDetails = true; 13911 dumpDalvik = true; 13912 } else if ("-d".equals(opt)) { 13913 dumpDalvik = true; 13914 } else if ("-c".equals(opt)) { 13915 isCompact = true; 13916 } else if ("--oom".equals(opt)) { 13917 oomOnly = true; 13918 } else if ("--local".equals(opt)) { 13919 localOnly = true; 13920 } else if ("--package".equals(opt)) { 13921 packages = true; 13922 } else if ("-h".equals(opt)) { 13923 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13924 pw.println(" -a: include all available information for each process."); 13925 pw.println(" -d: include dalvik details when dumping process details."); 13926 pw.println(" -c: dump in a compact machine-parseable representation."); 13927 pw.println(" --oom: only show processes organized by oom adj."); 13928 pw.println(" --local: only collect details locally, don't call process."); 13929 pw.println(" --package: interpret process arg as package, dumping all"); 13930 pw.println(" processes that have loaded that package."); 13931 pw.println("If [process] is specified it can be the name or "); 13932 pw.println("pid of a specific process to dump."); 13933 return; 13934 } else { 13935 pw.println("Unknown argument: " + opt + "; use -h for help"); 13936 } 13937 } 13938 13939 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13940 long uptime = SystemClock.uptimeMillis(); 13941 long realtime = SystemClock.elapsedRealtime(); 13942 final long[] tmpLong = new long[1]; 13943 13944 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13945 if (procs == null) { 13946 // No Java processes. Maybe they want to print a native process. 13947 if (args != null && args.length > opti 13948 && args[opti].charAt(0) != '-') { 13949 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13950 = new ArrayList<ProcessCpuTracker.Stats>(); 13951 updateCpuStatsNow(); 13952 int findPid = -1; 13953 try { 13954 findPid = Integer.parseInt(args[opti]); 13955 } catch (NumberFormatException e) { 13956 } 13957 synchronized (mProcessCpuTracker) { 13958 final int N = mProcessCpuTracker.countStats(); 13959 for (int i=0; i<N; i++) { 13960 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13961 if (st.pid == findPid || (st.baseName != null 13962 && st.baseName.equals(args[opti]))) { 13963 nativeProcs.add(st); 13964 } 13965 } 13966 } 13967 if (nativeProcs.size() > 0) { 13968 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13969 isCompact); 13970 Debug.MemoryInfo mi = null; 13971 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13972 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13973 final int pid = r.pid; 13974 if (!isCheckinRequest && dumpDetails) { 13975 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13976 } 13977 if (mi == null) { 13978 mi = new Debug.MemoryInfo(); 13979 } 13980 if (dumpDetails || (!brief && !oomOnly)) { 13981 Debug.getMemoryInfo(pid, mi); 13982 } else { 13983 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13984 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13985 } 13986 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13987 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13988 if (isCheckinRequest) { 13989 pw.println(); 13990 } 13991 } 13992 return; 13993 } 13994 } 13995 pw.println("No process found for: " + args[opti]); 13996 return; 13997 } 13998 13999 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14000 dumpDetails = true; 14001 } 14002 14003 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14004 14005 String[] innerArgs = new String[args.length-opti]; 14006 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14007 14008 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14009 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14010 long nativePss = 0; 14011 long dalvikPss = 0; 14012 long otherPss = 0; 14013 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14014 14015 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14016 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14017 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14018 14019 long totalPss = 0; 14020 long cachedPss = 0; 14021 14022 Debug.MemoryInfo mi = null; 14023 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14024 final ProcessRecord r = procs.get(i); 14025 final IApplicationThread thread; 14026 final int pid; 14027 final int oomAdj; 14028 final boolean hasActivities; 14029 synchronized (this) { 14030 thread = r.thread; 14031 pid = r.pid; 14032 oomAdj = r.getSetAdjWithServices(); 14033 hasActivities = r.activities.size() > 0; 14034 } 14035 if (thread != null) { 14036 if (!isCheckinRequest && dumpDetails) { 14037 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14038 } 14039 if (mi == null) { 14040 mi = new Debug.MemoryInfo(); 14041 } 14042 if (dumpDetails || (!brief && !oomOnly)) { 14043 Debug.getMemoryInfo(pid, mi); 14044 } else { 14045 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14046 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14047 } 14048 if (dumpDetails) { 14049 if (localOnly) { 14050 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14051 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14052 if (isCheckinRequest) { 14053 pw.println(); 14054 } 14055 } else { 14056 try { 14057 pw.flush(); 14058 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14059 dumpDalvik, innerArgs); 14060 } catch (RemoteException e) { 14061 if (!isCheckinRequest) { 14062 pw.println("Got RemoteException!"); 14063 pw.flush(); 14064 } 14065 } 14066 } 14067 } 14068 14069 final long myTotalPss = mi.getTotalPss(); 14070 final long myTotalUss = mi.getTotalUss(); 14071 14072 synchronized (this) { 14073 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14074 // Record this for posterity if the process has been stable. 14075 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14076 } 14077 } 14078 14079 if (!isCheckinRequest && mi != null) { 14080 totalPss += myTotalPss; 14081 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14082 (hasActivities ? " / activities)" : ")"), 14083 r.processName, myTotalPss, pid, hasActivities); 14084 procMems.add(pssItem); 14085 procMemsMap.put(pid, pssItem); 14086 14087 nativePss += mi.nativePss; 14088 dalvikPss += mi.dalvikPss; 14089 otherPss += mi.otherPss; 14090 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14091 long mem = mi.getOtherPss(j); 14092 miscPss[j] += mem; 14093 otherPss -= mem; 14094 } 14095 14096 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14097 cachedPss += myTotalPss; 14098 } 14099 14100 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14101 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14102 || oomIndex == (oomPss.length-1)) { 14103 oomPss[oomIndex] += myTotalPss; 14104 if (oomProcs[oomIndex] == null) { 14105 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14106 } 14107 oomProcs[oomIndex].add(pssItem); 14108 break; 14109 } 14110 } 14111 } 14112 } 14113 } 14114 14115 long nativeProcTotalPss = 0; 14116 14117 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14118 // If we are showing aggregations, also look for native processes to 14119 // include so that our aggregations are more accurate. 14120 updateCpuStatsNow(); 14121 synchronized (mProcessCpuTracker) { 14122 final int N = mProcessCpuTracker.countStats(); 14123 for (int i=0; i<N; i++) { 14124 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14125 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14126 if (mi == null) { 14127 mi = new Debug.MemoryInfo(); 14128 } 14129 if (!brief && !oomOnly) { 14130 Debug.getMemoryInfo(st.pid, mi); 14131 } else { 14132 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14133 mi.nativePrivateDirty = (int)tmpLong[0]; 14134 } 14135 14136 final long myTotalPss = mi.getTotalPss(); 14137 totalPss += myTotalPss; 14138 nativeProcTotalPss += myTotalPss; 14139 14140 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14141 st.name, myTotalPss, st.pid, false); 14142 procMems.add(pssItem); 14143 14144 nativePss += mi.nativePss; 14145 dalvikPss += mi.dalvikPss; 14146 otherPss += mi.otherPss; 14147 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14148 long mem = mi.getOtherPss(j); 14149 miscPss[j] += mem; 14150 otherPss -= mem; 14151 } 14152 oomPss[0] += myTotalPss; 14153 if (oomProcs[0] == null) { 14154 oomProcs[0] = new ArrayList<MemItem>(); 14155 } 14156 oomProcs[0].add(pssItem); 14157 } 14158 } 14159 } 14160 14161 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14162 14163 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14164 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14165 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14166 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14167 String label = Debug.MemoryInfo.getOtherLabel(j); 14168 catMems.add(new MemItem(label, label, miscPss[j], j)); 14169 } 14170 14171 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14172 for (int j=0; j<oomPss.length; j++) { 14173 if (oomPss[j] != 0) { 14174 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14175 : DUMP_MEM_OOM_LABEL[j]; 14176 MemItem item = new MemItem(label, label, oomPss[j], 14177 DUMP_MEM_OOM_ADJ[j]); 14178 item.subitems = oomProcs[j]; 14179 oomMems.add(item); 14180 } 14181 } 14182 14183 if (!brief && !oomOnly && !isCompact) { 14184 pw.println(); 14185 pw.println("Total PSS by process:"); 14186 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14187 pw.println(); 14188 } 14189 if (!isCompact) { 14190 pw.println("Total PSS by OOM adjustment:"); 14191 } 14192 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14193 if (!brief && !oomOnly) { 14194 PrintWriter out = categoryPw != null ? categoryPw : pw; 14195 if (!isCompact) { 14196 out.println(); 14197 out.println("Total PSS by category:"); 14198 } 14199 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14200 } 14201 if (!isCompact) { 14202 pw.println(); 14203 } 14204 MemInfoReader memInfo = new MemInfoReader(); 14205 memInfo.readMemInfo(); 14206 if (nativeProcTotalPss > 0) { 14207 synchronized (this) { 14208 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14209 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14210 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14211 } 14212 } 14213 if (!brief) { 14214 if (!isCompact) { 14215 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14216 pw.print(" kB (status "); 14217 switch (mLastMemoryLevel) { 14218 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14219 pw.println("normal)"); 14220 break; 14221 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14222 pw.println("moderate)"); 14223 break; 14224 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14225 pw.println("low)"); 14226 break; 14227 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14228 pw.println("critical)"); 14229 break; 14230 default: 14231 pw.print(mLastMemoryLevel); 14232 pw.println(")"); 14233 break; 14234 } 14235 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14236 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14237 pw.print(cachedPss); pw.print(" cached pss + "); 14238 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14239 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14240 } else { 14241 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14242 pw.print(cachedPss + memInfo.getCachedSizeKb() 14243 + memInfo.getFreeSizeKb()); pw.print(","); 14244 pw.println(totalPss - cachedPss); 14245 } 14246 } 14247 if (!isCompact) { 14248 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14249 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14250 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14251 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14252 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14253 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14254 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14255 } 14256 if (!brief) { 14257 if (memInfo.getZramTotalSizeKb() != 0) { 14258 if (!isCompact) { 14259 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14260 pw.print(" kB physical used for "); 14261 pw.print(memInfo.getSwapTotalSizeKb() 14262 - memInfo.getSwapFreeSizeKb()); 14263 pw.print(" kB in swap ("); 14264 pw.print(memInfo.getSwapTotalSizeKb()); 14265 pw.println(" kB total swap)"); 14266 } else { 14267 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14268 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14269 pw.println(memInfo.getSwapFreeSizeKb()); 14270 } 14271 } 14272 final long[] ksm = getKsmInfo(); 14273 if (!isCompact) { 14274 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14275 || ksm[KSM_VOLATILE] != 0) { 14276 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14277 pw.print(" kB saved from shared "); 14278 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14279 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14280 pw.print(" kB unshared; "); 14281 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14282 } 14283 pw.print(" Tuning: "); 14284 pw.print(ActivityManager.staticGetMemoryClass()); 14285 pw.print(" (large "); 14286 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14287 pw.print("), oom "); 14288 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14289 pw.print(" kB"); 14290 pw.print(", restore limit "); 14291 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14292 pw.print(" kB"); 14293 if (ActivityManager.isLowRamDeviceStatic()) { 14294 pw.print(" (low-ram)"); 14295 } 14296 if (ActivityManager.isHighEndGfx()) { 14297 pw.print(" (high-end-gfx)"); 14298 } 14299 pw.println(); 14300 } else { 14301 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14302 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14303 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14304 pw.print("tuning,"); 14305 pw.print(ActivityManager.staticGetMemoryClass()); 14306 pw.print(','); 14307 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14308 pw.print(','); 14309 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14310 if (ActivityManager.isLowRamDeviceStatic()) { 14311 pw.print(",low-ram"); 14312 } 14313 if (ActivityManager.isHighEndGfx()) { 14314 pw.print(",high-end-gfx"); 14315 } 14316 pw.println(); 14317 } 14318 } 14319 } 14320 } 14321 14322 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14323 String name) { 14324 sb.append(" "); 14325 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14326 sb.append(' '); 14327 sb.append(ProcessList.makeProcStateString(procState)); 14328 sb.append(' '); 14329 ProcessList.appendRamKb(sb, pss); 14330 sb.append(" kB: "); 14331 sb.append(name); 14332 } 14333 14334 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14335 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name); 14336 sb.append(" ("); 14337 sb.append(mi.pid); 14338 sb.append(") "); 14339 sb.append(mi.adjType); 14340 sb.append('\n'); 14341 if (mi.adjReason != null) { 14342 sb.append(" "); 14343 sb.append(mi.adjReason); 14344 sb.append('\n'); 14345 } 14346 } 14347 14348 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14349 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14350 for (int i=0, N=memInfos.size(); i<N; i++) { 14351 ProcessMemInfo mi = memInfos.get(i); 14352 infoMap.put(mi.pid, mi); 14353 } 14354 updateCpuStatsNow(); 14355 synchronized (mProcessCpuTracker) { 14356 final int N = mProcessCpuTracker.countStats(); 14357 for (int i=0; i<N; i++) { 14358 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14359 if (st.vsize > 0) { 14360 long pss = Debug.getPss(st.pid, null); 14361 if (pss > 0) { 14362 if (infoMap.indexOfKey(st.pid) < 0) { 14363 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14364 ProcessList.NATIVE_ADJ, -1, "native", null); 14365 mi.pss = pss; 14366 memInfos.add(mi); 14367 } 14368 } 14369 } 14370 } 14371 } 14372 14373 long totalPss = 0; 14374 for (int i=0, N=memInfos.size(); i<N; i++) { 14375 ProcessMemInfo mi = memInfos.get(i); 14376 if (mi.pss == 0) { 14377 mi.pss = Debug.getPss(mi.pid, null); 14378 } 14379 totalPss += mi.pss; 14380 } 14381 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14382 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14383 if (lhs.oomAdj != rhs.oomAdj) { 14384 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14385 } 14386 if (lhs.pss != rhs.pss) { 14387 return lhs.pss < rhs.pss ? 1 : -1; 14388 } 14389 return 0; 14390 } 14391 }); 14392 14393 StringBuilder tag = new StringBuilder(128); 14394 StringBuilder stack = new StringBuilder(128); 14395 tag.append("Low on memory -- "); 14396 appendMemBucket(tag, totalPss, "total", false); 14397 appendMemBucket(stack, totalPss, "total", true); 14398 14399 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14400 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14401 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14402 14403 boolean firstLine = true; 14404 int lastOomAdj = Integer.MIN_VALUE; 14405 long extraNativeRam = 0; 14406 long cachedPss = 0; 14407 for (int i=0, N=memInfos.size(); i<N; i++) { 14408 ProcessMemInfo mi = memInfos.get(i); 14409 14410 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14411 cachedPss += mi.pss; 14412 } 14413 14414 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14415 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14416 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14417 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14418 if (lastOomAdj != mi.oomAdj) { 14419 lastOomAdj = mi.oomAdj; 14420 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14421 tag.append(" / "); 14422 } 14423 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14424 if (firstLine) { 14425 stack.append(":"); 14426 firstLine = false; 14427 } 14428 stack.append("\n\t at "); 14429 } else { 14430 stack.append("$"); 14431 } 14432 } else { 14433 tag.append(" "); 14434 stack.append("$"); 14435 } 14436 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14437 appendMemBucket(tag, mi.pss, mi.name, false); 14438 } 14439 appendMemBucket(stack, mi.pss, mi.name, true); 14440 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14441 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14442 stack.append("("); 14443 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14444 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14445 stack.append(DUMP_MEM_OOM_LABEL[k]); 14446 stack.append(":"); 14447 stack.append(DUMP_MEM_OOM_ADJ[k]); 14448 } 14449 } 14450 stack.append(")"); 14451 } 14452 } 14453 14454 appendMemInfo(fullNativeBuilder, mi); 14455 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14456 // The short form only has native processes that are >= 1MB. 14457 if (mi.pss >= 1000) { 14458 appendMemInfo(shortNativeBuilder, mi); 14459 } else { 14460 extraNativeRam += mi.pss; 14461 } 14462 } else { 14463 // Short form has all other details, but if we have collected RAM 14464 // from smaller native processes let's dump a summary of that. 14465 if (extraNativeRam > 0) { 14466 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14467 -1, extraNativeRam, "(Other native)"); 14468 shortNativeBuilder.append('\n'); 14469 extraNativeRam = 0; 14470 } 14471 appendMemInfo(fullJavaBuilder, mi); 14472 } 14473 } 14474 14475 fullJavaBuilder.append(" "); 14476 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14477 fullJavaBuilder.append(" kB: TOTAL\n"); 14478 14479 MemInfoReader memInfo = new MemInfoReader(); 14480 memInfo.readMemInfo(); 14481 final long[] infos = memInfo.getRawInfo(); 14482 14483 StringBuilder memInfoBuilder = new StringBuilder(1024); 14484 Debug.getMemInfo(infos); 14485 memInfoBuilder.append(" MemInfo: "); 14486 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14487 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14488 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14489 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14490 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14491 memInfoBuilder.append(" "); 14492 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14493 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14494 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14495 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14496 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14497 memInfoBuilder.append(" ZRAM: "); 14498 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14499 memInfoBuilder.append(" kB RAM, "); 14500 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14501 memInfoBuilder.append(" kB swap total, "); 14502 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14503 memInfoBuilder.append(" kB swap free\n"); 14504 } 14505 final long[] ksm = getKsmInfo(); 14506 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14507 || ksm[KSM_VOLATILE] != 0) { 14508 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14509 memInfoBuilder.append(" kB saved from shared "); 14510 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14511 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14512 memInfoBuilder.append(" kB unshared; "); 14513 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14514 } 14515 memInfoBuilder.append(" Free RAM: "); 14516 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14517 + memInfo.getFreeSizeKb()); 14518 memInfoBuilder.append(" kB\n"); 14519 memInfoBuilder.append(" Used RAM: "); 14520 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14521 memInfoBuilder.append(" kB\n"); 14522 memInfoBuilder.append(" Lost RAM: "); 14523 memInfoBuilder.append(memInfo.getTotalSizeKb() 14524 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14525 - memInfo.getKernelUsedSizeKb()); 14526 memInfoBuilder.append(" kB\n"); 14527 Slog.i(TAG, "Low on memory:"); 14528 Slog.i(TAG, shortNativeBuilder.toString()); 14529 Slog.i(TAG, fullJavaBuilder.toString()); 14530 Slog.i(TAG, memInfoBuilder.toString()); 14531 14532 StringBuilder dropBuilder = new StringBuilder(1024); 14533 /* 14534 StringWriter oomSw = new StringWriter(); 14535 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14536 StringWriter catSw = new StringWriter(); 14537 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14538 String[] emptyArgs = new String[] { }; 14539 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14540 oomPw.flush(); 14541 String oomString = oomSw.toString(); 14542 */ 14543 dropBuilder.append("Low on memory:"); 14544 dropBuilder.append(stack); 14545 dropBuilder.append('\n'); 14546 dropBuilder.append(fullNativeBuilder); 14547 dropBuilder.append(fullJavaBuilder); 14548 dropBuilder.append('\n'); 14549 dropBuilder.append(memInfoBuilder); 14550 dropBuilder.append('\n'); 14551 /* 14552 dropBuilder.append(oomString); 14553 dropBuilder.append('\n'); 14554 */ 14555 StringWriter catSw = new StringWriter(); 14556 synchronized (ActivityManagerService.this) { 14557 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14558 String[] emptyArgs = new String[] { }; 14559 catPw.println(); 14560 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14561 catPw.println(); 14562 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14563 false, false, null); 14564 catPw.println(); 14565 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14566 catPw.flush(); 14567 } 14568 dropBuilder.append(catSw.toString()); 14569 addErrorToDropBox("lowmem", null, "system_server", null, 14570 null, tag.toString(), dropBuilder.toString(), null, null); 14571 //Slog.i(TAG, "Sent to dropbox:"); 14572 //Slog.i(TAG, dropBuilder.toString()); 14573 synchronized (ActivityManagerService.this) { 14574 long now = SystemClock.uptimeMillis(); 14575 if (mLastMemUsageReportTime < now) { 14576 mLastMemUsageReportTime = now; 14577 } 14578 } 14579 } 14580 14581 /** 14582 * Searches array of arguments for the specified string 14583 * @param args array of argument strings 14584 * @param value value to search for 14585 * @return true if the value is contained in the array 14586 */ 14587 private static boolean scanArgs(String[] args, String value) { 14588 if (args != null) { 14589 for (String arg : args) { 14590 if (value.equals(arg)) { 14591 return true; 14592 } 14593 } 14594 } 14595 return false; 14596 } 14597 14598 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14599 ContentProviderRecord cpr, boolean always) { 14600 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14601 14602 if (!inLaunching || always) { 14603 synchronized (cpr) { 14604 cpr.launchingApp = null; 14605 cpr.notifyAll(); 14606 } 14607 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14608 String names[] = cpr.info.authority.split(";"); 14609 for (int j = 0; j < names.length; j++) { 14610 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14611 } 14612 } 14613 14614 for (int i=0; i<cpr.connections.size(); i++) { 14615 ContentProviderConnection conn = cpr.connections.get(i); 14616 if (conn.waiting) { 14617 // If this connection is waiting for the provider, then we don't 14618 // need to mess with its process unless we are always removing 14619 // or for some reason the provider is not currently launching. 14620 if (inLaunching && !always) { 14621 continue; 14622 } 14623 } 14624 ProcessRecord capp = conn.client; 14625 conn.dead = true; 14626 if (conn.stableCount > 0) { 14627 if (!capp.persistent && capp.thread != null 14628 && capp.pid != 0 14629 && capp.pid != MY_PID) { 14630 capp.kill("depends on provider " 14631 + cpr.name.flattenToShortString() 14632 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14633 } 14634 } else if (capp.thread != null && conn.provider.provider != null) { 14635 try { 14636 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14637 } catch (RemoteException e) { 14638 } 14639 // In the protocol here, we don't expect the client to correctly 14640 // clean up this connection, we'll just remove it. 14641 cpr.connections.remove(i); 14642 conn.client.conProviders.remove(conn); 14643 } 14644 } 14645 14646 if (inLaunching && always) { 14647 mLaunchingProviders.remove(cpr); 14648 } 14649 return inLaunching; 14650 } 14651 14652 /** 14653 * Main code for cleaning up a process when it has gone away. This is 14654 * called both as a result of the process dying, or directly when stopping 14655 * a process when running in single process mode. 14656 * 14657 * @return Returns true if the given process has been restarted, so the 14658 * app that was passed in must remain on the process lists. 14659 */ 14660 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14661 boolean restarting, boolean allowRestart, int index) { 14662 if (index >= 0) { 14663 removeLruProcessLocked(app); 14664 ProcessList.remove(app.pid); 14665 } 14666 14667 mProcessesToGc.remove(app); 14668 mPendingPssProcesses.remove(app); 14669 14670 // Dismiss any open dialogs. 14671 if (app.crashDialog != null && !app.forceCrashReport) { 14672 app.crashDialog.dismiss(); 14673 app.crashDialog = null; 14674 } 14675 if (app.anrDialog != null) { 14676 app.anrDialog.dismiss(); 14677 app.anrDialog = null; 14678 } 14679 if (app.waitDialog != null) { 14680 app.waitDialog.dismiss(); 14681 app.waitDialog = null; 14682 } 14683 14684 app.crashing = false; 14685 app.notResponding = false; 14686 14687 app.resetPackageList(mProcessStats); 14688 app.unlinkDeathRecipient(); 14689 app.makeInactive(mProcessStats); 14690 app.waitingToKill = null; 14691 app.forcingToForeground = null; 14692 updateProcessForegroundLocked(app, false, false); 14693 app.foregroundActivities = false; 14694 app.hasShownUi = false; 14695 app.treatLikeActivity = false; 14696 app.hasAboveClient = false; 14697 app.hasClientActivities = false; 14698 14699 mServices.killServicesLocked(app, allowRestart); 14700 14701 boolean restart = false; 14702 14703 // Remove published content providers. 14704 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14705 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14706 final boolean always = app.bad || !allowRestart; 14707 if (removeDyingProviderLocked(app, cpr, always) || always) { 14708 // We left the provider in the launching list, need to 14709 // restart it. 14710 restart = true; 14711 } 14712 14713 cpr.provider = null; 14714 cpr.proc = null; 14715 } 14716 app.pubProviders.clear(); 14717 14718 // Take care of any launching providers waiting for this process. 14719 if (checkAppInLaunchingProvidersLocked(app, false)) { 14720 restart = true; 14721 } 14722 14723 // Unregister from connected content providers. 14724 if (!app.conProviders.isEmpty()) { 14725 for (int i=0; i<app.conProviders.size(); i++) { 14726 ContentProviderConnection conn = app.conProviders.get(i); 14727 conn.provider.connections.remove(conn); 14728 } 14729 app.conProviders.clear(); 14730 } 14731 14732 // At this point there may be remaining entries in mLaunchingProviders 14733 // where we were the only one waiting, so they are no longer of use. 14734 // Look for these and clean up if found. 14735 // XXX Commented out for now. Trying to figure out a way to reproduce 14736 // the actual situation to identify what is actually going on. 14737 if (false) { 14738 for (int i=0; i<mLaunchingProviders.size(); i++) { 14739 ContentProviderRecord cpr = (ContentProviderRecord) 14740 mLaunchingProviders.get(i); 14741 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14742 synchronized (cpr) { 14743 cpr.launchingApp = null; 14744 cpr.notifyAll(); 14745 } 14746 } 14747 } 14748 } 14749 14750 skipCurrentReceiverLocked(app); 14751 14752 // Unregister any receivers. 14753 for (int i=app.receivers.size()-1; i>=0; i--) { 14754 removeReceiverLocked(app.receivers.valueAt(i)); 14755 } 14756 app.receivers.clear(); 14757 14758 // If the app is undergoing backup, tell the backup manager about it 14759 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14760 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14761 + mBackupTarget.appInfo + " died during backup"); 14762 try { 14763 IBackupManager bm = IBackupManager.Stub.asInterface( 14764 ServiceManager.getService(Context.BACKUP_SERVICE)); 14765 bm.agentDisconnected(app.info.packageName); 14766 } catch (RemoteException e) { 14767 // can't happen; backup manager is local 14768 } 14769 } 14770 14771 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14772 ProcessChangeItem item = mPendingProcessChanges.get(i); 14773 if (item.pid == app.pid) { 14774 mPendingProcessChanges.remove(i); 14775 mAvailProcessChanges.add(item); 14776 } 14777 } 14778 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14779 14780 // If the caller is restarting this app, then leave it in its 14781 // current lists and let the caller take care of it. 14782 if (restarting) { 14783 return false; 14784 } 14785 14786 if (!app.persistent || app.isolated) { 14787 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14788 "Removing non-persistent process during cleanup: " + app); 14789 mProcessNames.remove(app.processName, app.uid); 14790 mIsolatedProcesses.remove(app.uid); 14791 if (mHeavyWeightProcess == app) { 14792 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14793 mHeavyWeightProcess.userId, 0)); 14794 mHeavyWeightProcess = null; 14795 } 14796 } else if (!app.removed) { 14797 // This app is persistent, so we need to keep its record around. 14798 // If it is not already on the pending app list, add it there 14799 // and start a new process for it. 14800 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14801 mPersistentStartingProcesses.add(app); 14802 restart = true; 14803 } 14804 } 14805 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14806 "Clean-up removing on hold: " + app); 14807 mProcessesOnHold.remove(app); 14808 14809 if (app == mHomeProcess) { 14810 mHomeProcess = null; 14811 } 14812 if (app == mPreviousProcess) { 14813 mPreviousProcess = null; 14814 } 14815 14816 if (restart && !app.isolated) { 14817 // We have components that still need to be running in the 14818 // process, so re-launch it. 14819 if (index < 0) { 14820 ProcessList.remove(app.pid); 14821 } 14822 mProcessNames.put(app.processName, app.uid, app); 14823 startProcessLocked(app, "restart", app.processName); 14824 return true; 14825 } else if (app.pid > 0 && app.pid != MY_PID) { 14826 // Goodbye! 14827 boolean removed; 14828 synchronized (mPidsSelfLocked) { 14829 mPidsSelfLocked.remove(app.pid); 14830 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14831 } 14832 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14833 if (app.isolated) { 14834 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14835 } 14836 app.setPid(0); 14837 } 14838 return false; 14839 } 14840 14841 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14842 // Look through the content providers we are waiting to have launched, 14843 // and if any run in this process then either schedule a restart of 14844 // the process or kill the client waiting for it if this process has 14845 // gone bad. 14846 int NL = mLaunchingProviders.size(); 14847 boolean restart = false; 14848 for (int i=0; i<NL; i++) { 14849 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14850 if (cpr.launchingApp == app) { 14851 if (!alwaysBad && !app.bad) { 14852 restart = true; 14853 } else { 14854 removeDyingProviderLocked(app, cpr, true); 14855 // cpr should have been removed from mLaunchingProviders 14856 NL = mLaunchingProviders.size(); 14857 i--; 14858 } 14859 } 14860 } 14861 return restart; 14862 } 14863 14864 // ========================================================= 14865 // SERVICES 14866 // ========================================================= 14867 14868 @Override 14869 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14870 int flags) { 14871 enforceNotIsolatedCaller("getServices"); 14872 synchronized (this) { 14873 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14874 } 14875 } 14876 14877 @Override 14878 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14879 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14880 synchronized (this) { 14881 return mServices.getRunningServiceControlPanelLocked(name); 14882 } 14883 } 14884 14885 @Override 14886 public ComponentName startService(IApplicationThread caller, Intent service, 14887 String resolvedType, int userId) { 14888 enforceNotIsolatedCaller("startService"); 14889 // Refuse possible leaked file descriptors 14890 if (service != null && service.hasFileDescriptors() == true) { 14891 throw new IllegalArgumentException("File descriptors passed in Intent"); 14892 } 14893 14894 if (DEBUG_SERVICE) 14895 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14896 synchronized(this) { 14897 final int callingPid = Binder.getCallingPid(); 14898 final int callingUid = Binder.getCallingUid(); 14899 final long origId = Binder.clearCallingIdentity(); 14900 ComponentName res = mServices.startServiceLocked(caller, service, 14901 resolvedType, callingPid, callingUid, userId); 14902 Binder.restoreCallingIdentity(origId); 14903 return res; 14904 } 14905 } 14906 14907 ComponentName startServiceInPackage(int uid, 14908 Intent service, String resolvedType, int userId) { 14909 synchronized(this) { 14910 if (DEBUG_SERVICE) 14911 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14912 final long origId = Binder.clearCallingIdentity(); 14913 ComponentName res = mServices.startServiceLocked(null, service, 14914 resolvedType, -1, uid, userId); 14915 Binder.restoreCallingIdentity(origId); 14916 return res; 14917 } 14918 } 14919 14920 @Override 14921 public int stopService(IApplicationThread caller, Intent service, 14922 String resolvedType, int userId) { 14923 enforceNotIsolatedCaller("stopService"); 14924 // Refuse possible leaked file descriptors 14925 if (service != null && service.hasFileDescriptors() == true) { 14926 throw new IllegalArgumentException("File descriptors passed in Intent"); 14927 } 14928 14929 synchronized(this) { 14930 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14931 } 14932 } 14933 14934 @Override 14935 public IBinder peekService(Intent service, String resolvedType) { 14936 enforceNotIsolatedCaller("peekService"); 14937 // Refuse possible leaked file descriptors 14938 if (service != null && service.hasFileDescriptors() == true) { 14939 throw new IllegalArgumentException("File descriptors passed in Intent"); 14940 } 14941 synchronized(this) { 14942 return mServices.peekServiceLocked(service, resolvedType); 14943 } 14944 } 14945 14946 @Override 14947 public boolean stopServiceToken(ComponentName className, IBinder token, 14948 int startId) { 14949 synchronized(this) { 14950 return mServices.stopServiceTokenLocked(className, token, startId); 14951 } 14952 } 14953 14954 @Override 14955 public void setServiceForeground(ComponentName className, IBinder token, 14956 int id, Notification notification, boolean removeNotification) { 14957 synchronized(this) { 14958 mServices.setServiceForegroundLocked(className, token, id, notification, 14959 removeNotification); 14960 } 14961 } 14962 14963 @Override 14964 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14965 boolean requireFull, String name, String callerPackage) { 14966 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14967 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14968 } 14969 14970 int unsafeConvertIncomingUser(int userId) { 14971 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14972 ? mCurrentUserId : userId; 14973 } 14974 14975 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14976 int allowMode, String name, String callerPackage) { 14977 final int callingUserId = UserHandle.getUserId(callingUid); 14978 if (callingUserId == userId) { 14979 return userId; 14980 } 14981 14982 // Note that we may be accessing mCurrentUserId outside of a lock... 14983 // shouldn't be a big deal, if this is being called outside 14984 // of a locked context there is intrinsically a race with 14985 // the value the caller will receive and someone else changing it. 14986 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14987 // we will switch to the calling user if access to the current user fails. 14988 int targetUserId = unsafeConvertIncomingUser(userId); 14989 14990 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14991 final boolean allow; 14992 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14993 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14994 // If the caller has this permission, they always pass go. And collect $200. 14995 allow = true; 14996 } else if (allowMode == ALLOW_FULL_ONLY) { 14997 // We require full access, sucks to be you. 14998 allow = false; 14999 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15000 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15001 // If the caller does not have either permission, they are always doomed. 15002 allow = false; 15003 } else if (allowMode == ALLOW_NON_FULL) { 15004 // We are blanket allowing non-full access, you lucky caller! 15005 allow = true; 15006 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15007 // We may or may not allow this depending on whether the two users are 15008 // in the same profile. 15009 synchronized (mUserProfileGroupIdsSelfLocked) { 15010 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15011 UserInfo.NO_PROFILE_GROUP_ID); 15012 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15013 UserInfo.NO_PROFILE_GROUP_ID); 15014 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15015 && callingProfile == targetProfile; 15016 } 15017 } else { 15018 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15019 } 15020 if (!allow) { 15021 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15022 // In this case, they would like to just execute as their 15023 // owner user instead of failing. 15024 targetUserId = callingUserId; 15025 } else { 15026 StringBuilder builder = new StringBuilder(128); 15027 builder.append("Permission Denial: "); 15028 builder.append(name); 15029 if (callerPackage != null) { 15030 builder.append(" from "); 15031 builder.append(callerPackage); 15032 } 15033 builder.append(" asks to run as user "); 15034 builder.append(userId); 15035 builder.append(" but is calling from user "); 15036 builder.append(UserHandle.getUserId(callingUid)); 15037 builder.append("; this requires "); 15038 builder.append(INTERACT_ACROSS_USERS_FULL); 15039 if (allowMode != ALLOW_FULL_ONLY) { 15040 builder.append(" or "); 15041 builder.append(INTERACT_ACROSS_USERS); 15042 } 15043 String msg = builder.toString(); 15044 Slog.w(TAG, msg); 15045 throw new SecurityException(msg); 15046 } 15047 } 15048 } 15049 if (!allowAll && targetUserId < 0) { 15050 throw new IllegalArgumentException( 15051 "Call does not support special user #" + targetUserId); 15052 } 15053 // Check shell permission 15054 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15055 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15056 targetUserId)) { 15057 throw new SecurityException("Shell does not have permission to access user " 15058 + targetUserId + "\n " + Debug.getCallers(3)); 15059 } 15060 } 15061 return targetUserId; 15062 } 15063 15064 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15065 String className, int flags) { 15066 boolean result = false; 15067 // For apps that don't have pre-defined UIDs, check for permission 15068 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15069 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15070 if (ActivityManager.checkUidPermission( 15071 INTERACT_ACROSS_USERS, 15072 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15073 ComponentName comp = new ComponentName(aInfo.packageName, className); 15074 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15075 + " requests FLAG_SINGLE_USER, but app does not hold " 15076 + INTERACT_ACROSS_USERS; 15077 Slog.w(TAG, msg); 15078 throw new SecurityException(msg); 15079 } 15080 // Permission passed 15081 result = true; 15082 } 15083 } else if ("system".equals(componentProcessName)) { 15084 result = true; 15085 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15086 // Phone app and persistent apps are allowed to export singleuser providers. 15087 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15088 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15089 } 15090 if (DEBUG_MU) { 15091 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15092 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15093 } 15094 return result; 15095 } 15096 15097 /** 15098 * Checks to see if the caller is in the same app as the singleton 15099 * component, or the component is in a special app. It allows special apps 15100 * to export singleton components but prevents exporting singleton 15101 * components for regular apps. 15102 */ 15103 boolean isValidSingletonCall(int callingUid, int componentUid) { 15104 int componentAppId = UserHandle.getAppId(componentUid); 15105 return UserHandle.isSameApp(callingUid, componentUid) 15106 || componentAppId == Process.SYSTEM_UID 15107 || componentAppId == Process.PHONE_UID 15108 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15109 == PackageManager.PERMISSION_GRANTED; 15110 } 15111 15112 public int bindService(IApplicationThread caller, IBinder token, 15113 Intent service, String resolvedType, 15114 IServiceConnection connection, int flags, int userId) { 15115 enforceNotIsolatedCaller("bindService"); 15116 15117 // Refuse possible leaked file descriptors 15118 if (service != null && service.hasFileDescriptors() == true) { 15119 throw new IllegalArgumentException("File descriptors passed in Intent"); 15120 } 15121 15122 synchronized(this) { 15123 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15124 connection, flags, userId); 15125 } 15126 } 15127 15128 public boolean unbindService(IServiceConnection connection) { 15129 synchronized (this) { 15130 return mServices.unbindServiceLocked(connection); 15131 } 15132 } 15133 15134 public void publishService(IBinder token, Intent intent, IBinder service) { 15135 // Refuse possible leaked file descriptors 15136 if (intent != null && intent.hasFileDescriptors() == true) { 15137 throw new IllegalArgumentException("File descriptors passed in Intent"); 15138 } 15139 15140 synchronized(this) { 15141 if (!(token instanceof ServiceRecord)) { 15142 throw new IllegalArgumentException("Invalid service token"); 15143 } 15144 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15145 } 15146 } 15147 15148 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15149 // Refuse possible leaked file descriptors 15150 if (intent != null && intent.hasFileDescriptors() == true) { 15151 throw new IllegalArgumentException("File descriptors passed in Intent"); 15152 } 15153 15154 synchronized(this) { 15155 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15156 } 15157 } 15158 15159 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15160 synchronized(this) { 15161 if (!(token instanceof ServiceRecord)) { 15162 throw new IllegalArgumentException("Invalid service token"); 15163 } 15164 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15165 } 15166 } 15167 15168 // ========================================================= 15169 // BACKUP AND RESTORE 15170 // ========================================================= 15171 15172 // Cause the target app to be launched if necessary and its backup agent 15173 // instantiated. The backup agent will invoke backupAgentCreated() on the 15174 // activity manager to announce its creation. 15175 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15176 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15177 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15178 15179 synchronized(this) { 15180 // !!! TODO: currently no check here that we're already bound 15181 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15182 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15183 synchronized (stats) { 15184 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15185 } 15186 15187 // Backup agent is now in use, its package can't be stopped. 15188 try { 15189 AppGlobals.getPackageManager().setPackageStoppedState( 15190 app.packageName, false, UserHandle.getUserId(app.uid)); 15191 } catch (RemoteException e) { 15192 } catch (IllegalArgumentException e) { 15193 Slog.w(TAG, "Failed trying to unstop package " 15194 + app.packageName + ": " + e); 15195 } 15196 15197 BackupRecord r = new BackupRecord(ss, app, backupMode); 15198 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15199 ? new ComponentName(app.packageName, app.backupAgentName) 15200 : new ComponentName("android", "FullBackupAgent"); 15201 // startProcessLocked() returns existing proc's record if it's already running 15202 ProcessRecord proc = startProcessLocked(app.processName, app, 15203 false, 0, "backup", hostingName, false, false, false); 15204 if (proc == null) { 15205 Slog.e(TAG, "Unable to start backup agent process " + r); 15206 return false; 15207 } 15208 15209 r.app = proc; 15210 mBackupTarget = r; 15211 mBackupAppName = app.packageName; 15212 15213 // Try not to kill the process during backup 15214 updateOomAdjLocked(proc); 15215 15216 // If the process is already attached, schedule the creation of the backup agent now. 15217 // If it is not yet live, this will be done when it attaches to the framework. 15218 if (proc.thread != null) { 15219 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15220 try { 15221 proc.thread.scheduleCreateBackupAgent(app, 15222 compatibilityInfoForPackageLocked(app), backupMode); 15223 } catch (RemoteException e) { 15224 // Will time out on the backup manager side 15225 } 15226 } else { 15227 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15228 } 15229 // Invariants: at this point, the target app process exists and the application 15230 // is either already running or in the process of coming up. mBackupTarget and 15231 // mBackupAppName describe the app, so that when it binds back to the AM we 15232 // know that it's scheduled for a backup-agent operation. 15233 } 15234 15235 return true; 15236 } 15237 15238 @Override 15239 public void clearPendingBackup() { 15240 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15241 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15242 15243 synchronized (this) { 15244 mBackupTarget = null; 15245 mBackupAppName = null; 15246 } 15247 } 15248 15249 // A backup agent has just come up 15250 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15251 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15252 + " = " + agent); 15253 15254 synchronized(this) { 15255 if (!agentPackageName.equals(mBackupAppName)) { 15256 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15257 return; 15258 } 15259 } 15260 15261 long oldIdent = Binder.clearCallingIdentity(); 15262 try { 15263 IBackupManager bm = IBackupManager.Stub.asInterface( 15264 ServiceManager.getService(Context.BACKUP_SERVICE)); 15265 bm.agentConnected(agentPackageName, agent); 15266 } catch (RemoteException e) { 15267 // can't happen; the backup manager service is local 15268 } catch (Exception e) { 15269 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15270 e.printStackTrace(); 15271 } finally { 15272 Binder.restoreCallingIdentity(oldIdent); 15273 } 15274 } 15275 15276 // done with this agent 15277 public void unbindBackupAgent(ApplicationInfo appInfo) { 15278 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15279 if (appInfo == null) { 15280 Slog.w(TAG, "unbind backup agent for null app"); 15281 return; 15282 } 15283 15284 synchronized(this) { 15285 try { 15286 if (mBackupAppName == null) { 15287 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15288 return; 15289 } 15290 15291 if (!mBackupAppName.equals(appInfo.packageName)) { 15292 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15293 return; 15294 } 15295 15296 // Not backing this app up any more; reset its OOM adjustment 15297 final ProcessRecord proc = mBackupTarget.app; 15298 updateOomAdjLocked(proc); 15299 15300 // If the app crashed during backup, 'thread' will be null here 15301 if (proc.thread != null) { 15302 try { 15303 proc.thread.scheduleDestroyBackupAgent(appInfo, 15304 compatibilityInfoForPackageLocked(appInfo)); 15305 } catch (Exception e) { 15306 Slog.e(TAG, "Exception when unbinding backup agent:"); 15307 e.printStackTrace(); 15308 } 15309 } 15310 } finally { 15311 mBackupTarget = null; 15312 mBackupAppName = null; 15313 } 15314 } 15315 } 15316 // ========================================================= 15317 // BROADCASTS 15318 // ========================================================= 15319 15320 private final List getStickiesLocked(String action, IntentFilter filter, 15321 List cur, int userId) { 15322 final ContentResolver resolver = mContext.getContentResolver(); 15323 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15324 if (stickies == null) { 15325 return cur; 15326 } 15327 final ArrayList<Intent> list = stickies.get(action); 15328 if (list == null) { 15329 return cur; 15330 } 15331 int N = list.size(); 15332 for (int i=0; i<N; i++) { 15333 Intent intent = list.get(i); 15334 if (filter.match(resolver, intent, true, TAG) >= 0) { 15335 if (cur == null) { 15336 cur = new ArrayList<Intent>(); 15337 } 15338 cur.add(intent); 15339 } 15340 } 15341 return cur; 15342 } 15343 15344 boolean isPendingBroadcastProcessLocked(int pid) { 15345 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15346 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15347 } 15348 15349 void skipPendingBroadcastLocked(int pid) { 15350 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15351 for (BroadcastQueue queue : mBroadcastQueues) { 15352 queue.skipPendingBroadcastLocked(pid); 15353 } 15354 } 15355 15356 // The app just attached; send any pending broadcasts that it should receive 15357 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15358 boolean didSomething = false; 15359 for (BroadcastQueue queue : mBroadcastQueues) { 15360 didSomething |= queue.sendPendingBroadcastsLocked(app); 15361 } 15362 return didSomething; 15363 } 15364 15365 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15366 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15367 enforceNotIsolatedCaller("registerReceiver"); 15368 int callingUid; 15369 int callingPid; 15370 synchronized(this) { 15371 ProcessRecord callerApp = null; 15372 if (caller != null) { 15373 callerApp = getRecordForAppLocked(caller); 15374 if (callerApp == null) { 15375 throw new SecurityException( 15376 "Unable to find app for caller " + caller 15377 + " (pid=" + Binder.getCallingPid() 15378 + ") when registering receiver " + receiver); 15379 } 15380 if (callerApp.info.uid != Process.SYSTEM_UID && 15381 !callerApp.pkgList.containsKey(callerPackage) && 15382 !"android".equals(callerPackage)) { 15383 throw new SecurityException("Given caller package " + callerPackage 15384 + " is not running in process " + callerApp); 15385 } 15386 callingUid = callerApp.info.uid; 15387 callingPid = callerApp.pid; 15388 } else { 15389 callerPackage = null; 15390 callingUid = Binder.getCallingUid(); 15391 callingPid = Binder.getCallingPid(); 15392 } 15393 15394 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15395 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15396 15397 List allSticky = null; 15398 15399 // Look for any matching sticky broadcasts... 15400 Iterator actions = filter.actionsIterator(); 15401 if (actions != null) { 15402 while (actions.hasNext()) { 15403 String action = (String)actions.next(); 15404 allSticky = getStickiesLocked(action, filter, allSticky, 15405 UserHandle.USER_ALL); 15406 allSticky = getStickiesLocked(action, filter, allSticky, 15407 UserHandle.getUserId(callingUid)); 15408 } 15409 } else { 15410 allSticky = getStickiesLocked(null, filter, allSticky, 15411 UserHandle.USER_ALL); 15412 allSticky = getStickiesLocked(null, filter, allSticky, 15413 UserHandle.getUserId(callingUid)); 15414 } 15415 15416 // The first sticky in the list is returned directly back to 15417 // the client. 15418 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15419 15420 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15421 + ": " + sticky); 15422 15423 if (receiver == null) { 15424 return sticky; 15425 } 15426 15427 ReceiverList rl 15428 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15429 if (rl == null) { 15430 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15431 userId, receiver); 15432 if (rl.app != null) { 15433 rl.app.receivers.add(rl); 15434 } else { 15435 try { 15436 receiver.asBinder().linkToDeath(rl, 0); 15437 } catch (RemoteException e) { 15438 return sticky; 15439 } 15440 rl.linkedToDeath = true; 15441 } 15442 mRegisteredReceivers.put(receiver.asBinder(), rl); 15443 } else if (rl.uid != callingUid) { 15444 throw new IllegalArgumentException( 15445 "Receiver requested to register for uid " + callingUid 15446 + " was previously registered for uid " + rl.uid); 15447 } else if (rl.pid != callingPid) { 15448 throw new IllegalArgumentException( 15449 "Receiver requested to register for pid " + callingPid 15450 + " was previously registered for pid " + rl.pid); 15451 } else if (rl.userId != userId) { 15452 throw new IllegalArgumentException( 15453 "Receiver requested to register for user " + userId 15454 + " was previously registered for user " + rl.userId); 15455 } 15456 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15457 permission, callingUid, userId); 15458 rl.add(bf); 15459 if (!bf.debugCheck()) { 15460 Slog.w(TAG, "==> For Dynamic broadast"); 15461 } 15462 mReceiverResolver.addFilter(bf); 15463 15464 // Enqueue broadcasts for all existing stickies that match 15465 // this filter. 15466 if (allSticky != null) { 15467 ArrayList receivers = new ArrayList(); 15468 receivers.add(bf); 15469 15470 int N = allSticky.size(); 15471 for (int i=0; i<N; i++) { 15472 Intent intent = (Intent)allSticky.get(i); 15473 BroadcastQueue queue = broadcastQueueForIntent(intent); 15474 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15475 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15476 null, null, false, true, true, -1); 15477 queue.enqueueParallelBroadcastLocked(r); 15478 queue.scheduleBroadcastsLocked(); 15479 } 15480 } 15481 15482 return sticky; 15483 } 15484 } 15485 15486 public void unregisterReceiver(IIntentReceiver receiver) { 15487 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15488 15489 final long origId = Binder.clearCallingIdentity(); 15490 try { 15491 boolean doTrim = false; 15492 15493 synchronized(this) { 15494 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15495 if (rl != null) { 15496 if (rl.curBroadcast != null) { 15497 BroadcastRecord r = rl.curBroadcast; 15498 final boolean doNext = finishReceiverLocked( 15499 receiver.asBinder(), r.resultCode, r.resultData, 15500 r.resultExtras, r.resultAbort); 15501 if (doNext) { 15502 doTrim = true; 15503 r.queue.processNextBroadcast(false); 15504 } 15505 } 15506 15507 if (rl.app != null) { 15508 rl.app.receivers.remove(rl); 15509 } 15510 removeReceiverLocked(rl); 15511 if (rl.linkedToDeath) { 15512 rl.linkedToDeath = false; 15513 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15514 } 15515 } 15516 } 15517 15518 // If we actually concluded any broadcasts, we might now be able 15519 // to trim the recipients' apps from our working set 15520 if (doTrim) { 15521 trimApplications(); 15522 return; 15523 } 15524 15525 } finally { 15526 Binder.restoreCallingIdentity(origId); 15527 } 15528 } 15529 15530 void removeReceiverLocked(ReceiverList rl) { 15531 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15532 int N = rl.size(); 15533 for (int i=0; i<N; i++) { 15534 mReceiverResolver.removeFilter(rl.get(i)); 15535 } 15536 } 15537 15538 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15539 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15540 ProcessRecord r = mLruProcesses.get(i); 15541 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15542 try { 15543 r.thread.dispatchPackageBroadcast(cmd, packages); 15544 } catch (RemoteException ex) { 15545 } 15546 } 15547 } 15548 } 15549 15550 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15551 int callingUid, int[] users) { 15552 List<ResolveInfo> receivers = null; 15553 try { 15554 HashSet<ComponentName> singleUserReceivers = null; 15555 boolean scannedFirstReceivers = false; 15556 for (int user : users) { 15557 // Skip users that have Shell restrictions 15558 if (callingUid == Process.SHELL_UID 15559 && getUserManagerLocked().hasUserRestriction( 15560 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15561 continue; 15562 } 15563 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15564 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15565 if (user != 0 && newReceivers != null) { 15566 // If this is not the primary user, we need to check for 15567 // any receivers that should be filtered out. 15568 for (int i=0; i<newReceivers.size(); i++) { 15569 ResolveInfo ri = newReceivers.get(i); 15570 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15571 newReceivers.remove(i); 15572 i--; 15573 } 15574 } 15575 } 15576 if (newReceivers != null && newReceivers.size() == 0) { 15577 newReceivers = null; 15578 } 15579 if (receivers == null) { 15580 receivers = newReceivers; 15581 } else if (newReceivers != null) { 15582 // We need to concatenate the additional receivers 15583 // found with what we have do far. This would be easy, 15584 // but we also need to de-dup any receivers that are 15585 // singleUser. 15586 if (!scannedFirstReceivers) { 15587 // Collect any single user receivers we had already retrieved. 15588 scannedFirstReceivers = true; 15589 for (int i=0; i<receivers.size(); i++) { 15590 ResolveInfo ri = receivers.get(i); 15591 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15592 ComponentName cn = new ComponentName( 15593 ri.activityInfo.packageName, ri.activityInfo.name); 15594 if (singleUserReceivers == null) { 15595 singleUserReceivers = new HashSet<ComponentName>(); 15596 } 15597 singleUserReceivers.add(cn); 15598 } 15599 } 15600 } 15601 // Add the new results to the existing results, tracking 15602 // and de-dupping single user receivers. 15603 for (int i=0; i<newReceivers.size(); i++) { 15604 ResolveInfo ri = newReceivers.get(i); 15605 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15606 ComponentName cn = new ComponentName( 15607 ri.activityInfo.packageName, ri.activityInfo.name); 15608 if (singleUserReceivers == null) { 15609 singleUserReceivers = new HashSet<ComponentName>(); 15610 } 15611 if (!singleUserReceivers.contains(cn)) { 15612 singleUserReceivers.add(cn); 15613 receivers.add(ri); 15614 } 15615 } else { 15616 receivers.add(ri); 15617 } 15618 } 15619 } 15620 } 15621 } catch (RemoteException ex) { 15622 // pm is in same process, this will never happen. 15623 } 15624 return receivers; 15625 } 15626 15627 private final int broadcastIntentLocked(ProcessRecord callerApp, 15628 String callerPackage, Intent intent, String resolvedType, 15629 IIntentReceiver resultTo, int resultCode, String resultData, 15630 Bundle map, String requiredPermission, int appOp, 15631 boolean ordered, boolean sticky, int callingPid, int callingUid, 15632 int userId) { 15633 intent = new Intent(intent); 15634 15635 // By default broadcasts do not go to stopped apps. 15636 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15637 15638 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15639 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15640 + " ordered=" + ordered + " userid=" + userId); 15641 if ((resultTo != null) && !ordered) { 15642 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15643 } 15644 15645 userId = handleIncomingUser(callingPid, callingUid, userId, 15646 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15647 15648 // Make sure that the user who is receiving this broadcast is started. 15649 // If not, we will just skip it. 15650 15651 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15652 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15653 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15654 Slog.w(TAG, "Skipping broadcast of " + intent 15655 + ": user " + userId + " is stopped"); 15656 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15657 } 15658 } 15659 15660 /* 15661 * Prevent non-system code (defined here to be non-persistent 15662 * processes) from sending protected broadcasts. 15663 */ 15664 int callingAppId = UserHandle.getAppId(callingUid); 15665 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15666 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15667 || callingAppId == Process.NFC_UID || callingUid == 0) { 15668 // Always okay. 15669 } else if (callerApp == null || !callerApp.persistent) { 15670 try { 15671 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15672 intent.getAction())) { 15673 String msg = "Permission Denial: not allowed to send broadcast " 15674 + intent.getAction() + " from pid=" 15675 + callingPid + ", uid=" + callingUid; 15676 Slog.w(TAG, msg); 15677 throw new SecurityException(msg); 15678 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15679 // Special case for compatibility: we don't want apps to send this, 15680 // but historically it has not been protected and apps may be using it 15681 // to poke their own app widget. So, instead of making it protected, 15682 // just limit it to the caller. 15683 if (callerApp == null) { 15684 String msg = "Permission Denial: not allowed to send broadcast " 15685 + intent.getAction() + " from unknown caller."; 15686 Slog.w(TAG, msg); 15687 throw new SecurityException(msg); 15688 } else if (intent.getComponent() != null) { 15689 // They are good enough to send to an explicit component... verify 15690 // it is being sent to the calling app. 15691 if (!intent.getComponent().getPackageName().equals( 15692 callerApp.info.packageName)) { 15693 String msg = "Permission Denial: not allowed to send broadcast " 15694 + intent.getAction() + " to " 15695 + intent.getComponent().getPackageName() + " from " 15696 + callerApp.info.packageName; 15697 Slog.w(TAG, msg); 15698 throw new SecurityException(msg); 15699 } 15700 } else { 15701 // Limit broadcast to their own package. 15702 intent.setPackage(callerApp.info.packageName); 15703 } 15704 } 15705 } catch (RemoteException e) { 15706 Slog.w(TAG, "Remote exception", e); 15707 return ActivityManager.BROADCAST_SUCCESS; 15708 } 15709 } 15710 15711 final String action = intent.getAction(); 15712 if (action != null) { 15713 switch (action) { 15714 case Intent.ACTION_UID_REMOVED: 15715 case Intent.ACTION_PACKAGE_REMOVED: 15716 case Intent.ACTION_PACKAGE_CHANGED: 15717 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15718 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15719 // Handle special intents: if this broadcast is from the package 15720 // manager about a package being removed, we need to remove all of 15721 // its activities from the history stack. 15722 if (checkComponentPermission( 15723 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15724 callingPid, callingUid, -1, true) 15725 != PackageManager.PERMISSION_GRANTED) { 15726 String msg = "Permission Denial: " + intent.getAction() 15727 + " broadcast from " + callerPackage + " (pid=" + callingPid 15728 + ", uid=" + callingUid + ")" 15729 + " requires " 15730 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15731 Slog.w(TAG, msg); 15732 throw new SecurityException(msg); 15733 } 15734 switch (action) { 15735 case Intent.ACTION_UID_REMOVED: 15736 final Bundle intentExtras = intent.getExtras(); 15737 final int uid = intentExtras != null 15738 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15739 if (uid >= 0) { 15740 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15741 synchronized (bs) { 15742 bs.removeUidStatsLocked(uid); 15743 } 15744 mAppOpsService.uidRemoved(uid); 15745 } 15746 break; 15747 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15748 // If resources are unavailable just force stop all those packages 15749 // and flush the attribute cache as well. 15750 String list[] = 15751 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15752 if (list != null && list.length > 0) { 15753 for (int i = 0; i < list.length; i++) { 15754 forceStopPackageLocked(list[i], -1, false, true, true, 15755 false, false, userId, "storage unmount"); 15756 } 15757 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15758 sendPackageBroadcastLocked( 15759 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15760 userId); 15761 } 15762 break; 15763 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15764 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15765 break; 15766 case Intent.ACTION_PACKAGE_REMOVED: 15767 case Intent.ACTION_PACKAGE_CHANGED: 15768 Uri data = intent.getData(); 15769 String ssp; 15770 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15771 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15772 boolean fullUninstall = removed && 15773 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15774 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15775 forceStopPackageLocked(ssp, UserHandle.getAppId( 15776 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15777 false, true, true, false, fullUninstall, userId, 15778 removed ? "pkg removed" : "pkg changed"); 15779 } 15780 if (removed) { 15781 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15782 new String[] {ssp}, userId); 15783 if (fullUninstall) { 15784 mAppOpsService.packageRemoved( 15785 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15786 15787 // Remove all permissions granted from/to this package 15788 removeUriPermissionsForPackageLocked(ssp, userId, true); 15789 15790 removeTasksByPackageNameLocked(ssp, userId); 15791 } 15792 } else { 15793 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15794 } 15795 } 15796 break; 15797 } 15798 break; 15799 case Intent.ACTION_PACKAGE_ADDED: 15800 // Special case for adding a package: by default turn on compatibility mode. 15801 Uri data = intent.getData(); 15802 String ssp; 15803 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 15804 final boolean replacing = 15805 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15806 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 15807 15808 if (replacing) { 15809 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15810 } 15811 } 15812 break; 15813 case Intent.ACTION_TIMEZONE_CHANGED: 15814 // If this is the time zone changed action, queue up a message that will reset 15815 // the timezone of all currently running processes. This message will get 15816 // queued up before the broadcast happens. 15817 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15818 break; 15819 case Intent.ACTION_TIME_CHANGED: 15820 // If the user set the time, let all running processes know. 15821 final int is24Hour = 15822 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 15823 : 0; 15824 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15825 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15826 synchronized (stats) { 15827 stats.noteCurrentTimeChangedLocked(); 15828 } 15829 break; 15830 case Intent.ACTION_CLEAR_DNS_CACHE: 15831 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15832 break; 15833 case Proxy.PROXY_CHANGE_ACTION: 15834 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15835 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15836 break; 15837 } 15838 } 15839 15840 // Add to the sticky list if requested. 15841 if (sticky) { 15842 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15843 callingPid, callingUid) 15844 != PackageManager.PERMISSION_GRANTED) { 15845 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15846 + callingPid + ", uid=" + callingUid 15847 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15848 Slog.w(TAG, msg); 15849 throw new SecurityException(msg); 15850 } 15851 if (requiredPermission != null) { 15852 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15853 + " and enforce permission " + requiredPermission); 15854 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15855 } 15856 if (intent.getComponent() != null) { 15857 throw new SecurityException( 15858 "Sticky broadcasts can't target a specific component"); 15859 } 15860 // We use userId directly here, since the "all" target is maintained 15861 // as a separate set of sticky broadcasts. 15862 if (userId != UserHandle.USER_ALL) { 15863 // But first, if this is not a broadcast to all users, then 15864 // make sure it doesn't conflict with an existing broadcast to 15865 // all users. 15866 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15867 UserHandle.USER_ALL); 15868 if (stickies != null) { 15869 ArrayList<Intent> list = stickies.get(intent.getAction()); 15870 if (list != null) { 15871 int N = list.size(); 15872 int i; 15873 for (i=0; i<N; i++) { 15874 if (intent.filterEquals(list.get(i))) { 15875 throw new IllegalArgumentException( 15876 "Sticky broadcast " + intent + " for user " 15877 + userId + " conflicts with existing global broadcast"); 15878 } 15879 } 15880 } 15881 } 15882 } 15883 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15884 if (stickies == null) { 15885 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15886 mStickyBroadcasts.put(userId, stickies); 15887 } 15888 ArrayList<Intent> list = stickies.get(intent.getAction()); 15889 if (list == null) { 15890 list = new ArrayList<Intent>(); 15891 stickies.put(intent.getAction(), list); 15892 } 15893 int N = list.size(); 15894 int i; 15895 for (i=0; i<N; i++) { 15896 if (intent.filterEquals(list.get(i))) { 15897 // This sticky already exists, replace it. 15898 list.set(i, new Intent(intent)); 15899 break; 15900 } 15901 } 15902 if (i >= N) { 15903 list.add(new Intent(intent)); 15904 } 15905 } 15906 15907 int[] users; 15908 if (userId == UserHandle.USER_ALL) { 15909 // Caller wants broadcast to go to all started users. 15910 users = mStartedUserArray; 15911 } else { 15912 // Caller wants broadcast to go to one specific user. 15913 users = new int[] {userId}; 15914 } 15915 15916 // Figure out who all will receive this broadcast. 15917 List receivers = null; 15918 List<BroadcastFilter> registeredReceivers = null; 15919 // Need to resolve the intent to interested receivers... 15920 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15921 == 0) { 15922 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15923 } 15924 if (intent.getComponent() == null) { 15925 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15926 // Query one target user at a time, excluding shell-restricted users 15927 UserManagerService ums = getUserManagerLocked(); 15928 for (int i = 0; i < users.length; i++) { 15929 if (ums.hasUserRestriction( 15930 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15931 continue; 15932 } 15933 List<BroadcastFilter> registeredReceiversForUser = 15934 mReceiverResolver.queryIntent(intent, 15935 resolvedType, false, users[i]); 15936 if (registeredReceivers == null) { 15937 registeredReceivers = registeredReceiversForUser; 15938 } else if (registeredReceiversForUser != null) { 15939 registeredReceivers.addAll(registeredReceiversForUser); 15940 } 15941 } 15942 } else { 15943 registeredReceivers = mReceiverResolver.queryIntent(intent, 15944 resolvedType, false, userId); 15945 } 15946 } 15947 15948 final boolean replacePending = 15949 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15950 15951 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15952 + " replacePending=" + replacePending); 15953 15954 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15955 if (!ordered && NR > 0) { 15956 // If we are not serializing this broadcast, then send the 15957 // registered receivers separately so they don't wait for the 15958 // components to be launched. 15959 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15960 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15961 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15962 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15963 ordered, sticky, false, userId); 15964 if (DEBUG_BROADCAST) Slog.v( 15965 TAG, "Enqueueing parallel broadcast " + r); 15966 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15967 if (!replaced) { 15968 queue.enqueueParallelBroadcastLocked(r); 15969 queue.scheduleBroadcastsLocked(); 15970 } 15971 registeredReceivers = null; 15972 NR = 0; 15973 } 15974 15975 // Merge into one list. 15976 int ir = 0; 15977 if (receivers != null) { 15978 // A special case for PACKAGE_ADDED: do not allow the package 15979 // being added to see this broadcast. This prevents them from 15980 // using this as a back door to get run as soon as they are 15981 // installed. Maybe in the future we want to have a special install 15982 // broadcast or such for apps, but we'd like to deliberately make 15983 // this decision. 15984 String skipPackages[] = null; 15985 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15986 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15987 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15988 Uri data = intent.getData(); 15989 if (data != null) { 15990 String pkgName = data.getSchemeSpecificPart(); 15991 if (pkgName != null) { 15992 skipPackages = new String[] { pkgName }; 15993 } 15994 } 15995 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15996 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15997 } 15998 if (skipPackages != null && (skipPackages.length > 0)) { 15999 for (String skipPackage : skipPackages) { 16000 if (skipPackage != null) { 16001 int NT = receivers.size(); 16002 for (int it=0; it<NT; it++) { 16003 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16004 if (curt.activityInfo.packageName.equals(skipPackage)) { 16005 receivers.remove(it); 16006 it--; 16007 NT--; 16008 } 16009 } 16010 } 16011 } 16012 } 16013 16014 int NT = receivers != null ? receivers.size() : 0; 16015 int it = 0; 16016 ResolveInfo curt = null; 16017 BroadcastFilter curr = null; 16018 while (it < NT && ir < NR) { 16019 if (curt == null) { 16020 curt = (ResolveInfo)receivers.get(it); 16021 } 16022 if (curr == null) { 16023 curr = registeredReceivers.get(ir); 16024 } 16025 if (curr.getPriority() >= curt.priority) { 16026 // Insert this broadcast record into the final list. 16027 receivers.add(it, curr); 16028 ir++; 16029 curr = null; 16030 it++; 16031 NT++; 16032 } else { 16033 // Skip to the next ResolveInfo in the final list. 16034 it++; 16035 curt = null; 16036 } 16037 } 16038 } 16039 while (ir < NR) { 16040 if (receivers == null) { 16041 receivers = new ArrayList(); 16042 } 16043 receivers.add(registeredReceivers.get(ir)); 16044 ir++; 16045 } 16046 16047 if ((receivers != null && receivers.size() > 0) 16048 || resultTo != null) { 16049 BroadcastQueue queue = broadcastQueueForIntent(intent); 16050 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16051 callerPackage, callingPid, callingUid, resolvedType, 16052 requiredPermission, appOp, receivers, resultTo, resultCode, 16053 resultData, map, ordered, sticky, false, userId); 16054 if (DEBUG_BROADCAST) Slog.v( 16055 TAG, "Enqueueing ordered broadcast " + r 16056 + ": prev had " + queue.mOrderedBroadcasts.size()); 16057 if (DEBUG_BROADCAST) { 16058 int seq = r.intent.getIntExtra("seq", -1); 16059 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16060 } 16061 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16062 if (!replaced) { 16063 queue.enqueueOrderedBroadcastLocked(r); 16064 queue.scheduleBroadcastsLocked(); 16065 } 16066 } 16067 16068 return ActivityManager.BROADCAST_SUCCESS; 16069 } 16070 16071 final Intent verifyBroadcastLocked(Intent intent) { 16072 // Refuse possible leaked file descriptors 16073 if (intent != null && intent.hasFileDescriptors() == true) { 16074 throw new IllegalArgumentException("File descriptors passed in Intent"); 16075 } 16076 16077 int flags = intent.getFlags(); 16078 16079 if (!mProcessesReady) { 16080 // if the caller really truly claims to know what they're doing, go 16081 // ahead and allow the broadcast without launching any receivers 16082 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16083 intent = new Intent(intent); 16084 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16085 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16086 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16087 + " before boot completion"); 16088 throw new IllegalStateException("Cannot broadcast before boot completed"); 16089 } 16090 } 16091 16092 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16093 throw new IllegalArgumentException( 16094 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16095 } 16096 16097 return intent; 16098 } 16099 16100 public final int broadcastIntent(IApplicationThread caller, 16101 Intent intent, String resolvedType, IIntentReceiver resultTo, 16102 int resultCode, String resultData, Bundle map, 16103 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16104 enforceNotIsolatedCaller("broadcastIntent"); 16105 synchronized(this) { 16106 intent = verifyBroadcastLocked(intent); 16107 16108 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16109 final int callingPid = Binder.getCallingPid(); 16110 final int callingUid = Binder.getCallingUid(); 16111 final long origId = Binder.clearCallingIdentity(); 16112 int res = broadcastIntentLocked(callerApp, 16113 callerApp != null ? callerApp.info.packageName : null, 16114 intent, resolvedType, resultTo, 16115 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16116 callingPid, callingUid, userId); 16117 Binder.restoreCallingIdentity(origId); 16118 return res; 16119 } 16120 } 16121 16122 int broadcastIntentInPackage(String packageName, int uid, 16123 Intent intent, String resolvedType, IIntentReceiver resultTo, 16124 int resultCode, String resultData, Bundle map, 16125 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16126 synchronized(this) { 16127 intent = verifyBroadcastLocked(intent); 16128 16129 final long origId = Binder.clearCallingIdentity(); 16130 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16131 resultTo, resultCode, resultData, map, requiredPermission, 16132 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16133 Binder.restoreCallingIdentity(origId); 16134 return res; 16135 } 16136 } 16137 16138 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16139 // Refuse possible leaked file descriptors 16140 if (intent != null && intent.hasFileDescriptors() == true) { 16141 throw new IllegalArgumentException("File descriptors passed in Intent"); 16142 } 16143 16144 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16145 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16146 16147 synchronized(this) { 16148 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16149 != PackageManager.PERMISSION_GRANTED) { 16150 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16151 + Binder.getCallingPid() 16152 + ", uid=" + Binder.getCallingUid() 16153 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16154 Slog.w(TAG, msg); 16155 throw new SecurityException(msg); 16156 } 16157 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16158 if (stickies != null) { 16159 ArrayList<Intent> list = stickies.get(intent.getAction()); 16160 if (list != null) { 16161 int N = list.size(); 16162 int i; 16163 for (i=0; i<N; i++) { 16164 if (intent.filterEquals(list.get(i))) { 16165 list.remove(i); 16166 break; 16167 } 16168 } 16169 if (list.size() <= 0) { 16170 stickies.remove(intent.getAction()); 16171 } 16172 } 16173 if (stickies.size() <= 0) { 16174 mStickyBroadcasts.remove(userId); 16175 } 16176 } 16177 } 16178 } 16179 16180 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16181 String resultData, Bundle resultExtras, boolean resultAbort) { 16182 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16183 if (r == null) { 16184 Slog.w(TAG, "finishReceiver called but not found on queue"); 16185 return false; 16186 } 16187 16188 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16189 } 16190 16191 void backgroundServicesFinishedLocked(int userId) { 16192 for (BroadcastQueue queue : mBroadcastQueues) { 16193 queue.backgroundServicesFinishedLocked(userId); 16194 } 16195 } 16196 16197 public void finishReceiver(IBinder who, int resultCode, String resultData, 16198 Bundle resultExtras, boolean resultAbort) { 16199 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16200 16201 // Refuse possible leaked file descriptors 16202 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16203 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16204 } 16205 16206 final long origId = Binder.clearCallingIdentity(); 16207 try { 16208 boolean doNext = false; 16209 BroadcastRecord r; 16210 16211 synchronized(this) { 16212 r = broadcastRecordForReceiverLocked(who); 16213 if (r != null) { 16214 doNext = r.queue.finishReceiverLocked(r, resultCode, 16215 resultData, resultExtras, resultAbort, true); 16216 } 16217 } 16218 16219 if (doNext) { 16220 r.queue.processNextBroadcast(false); 16221 } 16222 trimApplications(); 16223 } finally { 16224 Binder.restoreCallingIdentity(origId); 16225 } 16226 } 16227 16228 // ========================================================= 16229 // INSTRUMENTATION 16230 // ========================================================= 16231 16232 public boolean startInstrumentation(ComponentName className, 16233 String profileFile, int flags, Bundle arguments, 16234 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16235 int userId, String abiOverride) { 16236 enforceNotIsolatedCaller("startInstrumentation"); 16237 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16238 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16239 // Refuse possible leaked file descriptors 16240 if (arguments != null && arguments.hasFileDescriptors()) { 16241 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16242 } 16243 16244 synchronized(this) { 16245 InstrumentationInfo ii = null; 16246 ApplicationInfo ai = null; 16247 try { 16248 ii = mContext.getPackageManager().getInstrumentationInfo( 16249 className, STOCK_PM_FLAGS); 16250 ai = AppGlobals.getPackageManager().getApplicationInfo( 16251 ii.targetPackage, STOCK_PM_FLAGS, userId); 16252 } catch (PackageManager.NameNotFoundException e) { 16253 } catch (RemoteException e) { 16254 } 16255 if (ii == null) { 16256 reportStartInstrumentationFailure(watcher, className, 16257 "Unable to find instrumentation info for: " + className); 16258 return false; 16259 } 16260 if (ai == null) { 16261 reportStartInstrumentationFailure(watcher, className, 16262 "Unable to find instrumentation target package: " + ii.targetPackage); 16263 return false; 16264 } 16265 16266 int match = mContext.getPackageManager().checkSignatures( 16267 ii.targetPackage, ii.packageName); 16268 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16269 String msg = "Permission Denial: starting instrumentation " 16270 + className + " from pid=" 16271 + Binder.getCallingPid() 16272 + ", uid=" + Binder.getCallingPid() 16273 + " not allowed because package " + ii.packageName 16274 + " does not have a signature matching the target " 16275 + ii.targetPackage; 16276 reportStartInstrumentationFailure(watcher, className, msg); 16277 throw new SecurityException(msg); 16278 } 16279 16280 final long origId = Binder.clearCallingIdentity(); 16281 // Instrumentation can kill and relaunch even persistent processes 16282 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16283 "start instr"); 16284 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16285 app.instrumentationClass = className; 16286 app.instrumentationInfo = ai; 16287 app.instrumentationProfileFile = profileFile; 16288 app.instrumentationArguments = arguments; 16289 app.instrumentationWatcher = watcher; 16290 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16291 app.instrumentationResultClass = className; 16292 Binder.restoreCallingIdentity(origId); 16293 } 16294 16295 return true; 16296 } 16297 16298 /** 16299 * Report errors that occur while attempting to start Instrumentation. Always writes the 16300 * error to the logs, but if somebody is watching, send the report there too. This enables 16301 * the "am" command to report errors with more information. 16302 * 16303 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16304 * @param cn The component name of the instrumentation. 16305 * @param report The error report. 16306 */ 16307 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16308 ComponentName cn, String report) { 16309 Slog.w(TAG, report); 16310 try { 16311 if (watcher != null) { 16312 Bundle results = new Bundle(); 16313 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16314 results.putString("Error", report); 16315 watcher.instrumentationStatus(cn, -1, results); 16316 } 16317 } catch (RemoteException e) { 16318 Slog.w(TAG, e); 16319 } 16320 } 16321 16322 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16323 if (app.instrumentationWatcher != null) { 16324 try { 16325 // NOTE: IInstrumentationWatcher *must* be oneway here 16326 app.instrumentationWatcher.instrumentationFinished( 16327 app.instrumentationClass, 16328 resultCode, 16329 results); 16330 } catch (RemoteException e) { 16331 } 16332 } 16333 if (app.instrumentationUiAutomationConnection != null) { 16334 try { 16335 app.instrumentationUiAutomationConnection.shutdown(); 16336 } catch (RemoteException re) { 16337 /* ignore */ 16338 } 16339 // Only a UiAutomation can set this flag and now that 16340 // it is finished we make sure it is reset to its default. 16341 mUserIsMonkey = false; 16342 } 16343 app.instrumentationWatcher = null; 16344 app.instrumentationUiAutomationConnection = null; 16345 app.instrumentationClass = null; 16346 app.instrumentationInfo = null; 16347 app.instrumentationProfileFile = null; 16348 app.instrumentationArguments = null; 16349 16350 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16351 "finished inst"); 16352 } 16353 16354 public void finishInstrumentation(IApplicationThread target, 16355 int resultCode, Bundle results) { 16356 int userId = UserHandle.getCallingUserId(); 16357 // Refuse possible leaked file descriptors 16358 if (results != null && results.hasFileDescriptors()) { 16359 throw new IllegalArgumentException("File descriptors passed in Intent"); 16360 } 16361 16362 synchronized(this) { 16363 ProcessRecord app = getRecordForAppLocked(target); 16364 if (app == null) { 16365 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16366 return; 16367 } 16368 final long origId = Binder.clearCallingIdentity(); 16369 finishInstrumentationLocked(app, resultCode, results); 16370 Binder.restoreCallingIdentity(origId); 16371 } 16372 } 16373 16374 // ========================================================= 16375 // CONFIGURATION 16376 // ========================================================= 16377 16378 public ConfigurationInfo getDeviceConfigurationInfo() { 16379 ConfigurationInfo config = new ConfigurationInfo(); 16380 synchronized (this) { 16381 config.reqTouchScreen = mConfiguration.touchscreen; 16382 config.reqKeyboardType = mConfiguration.keyboard; 16383 config.reqNavigation = mConfiguration.navigation; 16384 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16385 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16386 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16387 } 16388 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16389 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16390 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16391 } 16392 config.reqGlEsVersion = GL_ES_VERSION; 16393 } 16394 return config; 16395 } 16396 16397 ActivityStack getFocusedStack() { 16398 return mStackSupervisor.getFocusedStack(); 16399 } 16400 16401 public Configuration getConfiguration() { 16402 Configuration ci; 16403 synchronized(this) { 16404 ci = new Configuration(mConfiguration); 16405 } 16406 return ci; 16407 } 16408 16409 public void updatePersistentConfiguration(Configuration values) { 16410 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16411 "updateConfiguration()"); 16412 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16413 "updateConfiguration()"); 16414 if (values == null) { 16415 throw new NullPointerException("Configuration must not be null"); 16416 } 16417 16418 synchronized(this) { 16419 final long origId = Binder.clearCallingIdentity(); 16420 updateConfigurationLocked(values, null, true, false); 16421 Binder.restoreCallingIdentity(origId); 16422 } 16423 } 16424 16425 public void updateConfiguration(Configuration values) { 16426 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16427 "updateConfiguration()"); 16428 16429 synchronized(this) { 16430 if (values == null && mWindowManager != null) { 16431 // sentinel: fetch the current configuration from the window manager 16432 values = mWindowManager.computeNewConfiguration(); 16433 } 16434 16435 if (mWindowManager != null) { 16436 mProcessList.applyDisplaySize(mWindowManager); 16437 } 16438 16439 final long origId = Binder.clearCallingIdentity(); 16440 if (values != null) { 16441 Settings.System.clearConfiguration(values); 16442 } 16443 updateConfigurationLocked(values, null, false, false); 16444 Binder.restoreCallingIdentity(origId); 16445 } 16446 } 16447 16448 /** 16449 * Do either or both things: (1) change the current configuration, and (2) 16450 * make sure the given activity is running with the (now) current 16451 * configuration. Returns true if the activity has been left running, or 16452 * false if <var>starting</var> is being destroyed to match the new 16453 * configuration. 16454 * @param persistent TODO 16455 */ 16456 boolean updateConfigurationLocked(Configuration values, 16457 ActivityRecord starting, boolean persistent, boolean initLocale) { 16458 int changes = 0; 16459 16460 if (values != null) { 16461 Configuration newConfig = new Configuration(mConfiguration); 16462 changes = newConfig.updateFrom(values); 16463 if (changes != 0) { 16464 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16465 Slog.i(TAG, "Updating configuration to: " + values); 16466 } 16467 16468 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16469 16470 if (values.locale != null && !initLocale) { 16471 saveLocaleLocked(values.locale, 16472 !values.locale.equals(mConfiguration.locale), 16473 values.userSetLocale); 16474 } 16475 16476 mConfigurationSeq++; 16477 if (mConfigurationSeq <= 0) { 16478 mConfigurationSeq = 1; 16479 } 16480 newConfig.seq = mConfigurationSeq; 16481 mConfiguration = newConfig; 16482 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16483 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16484 //mUsageStatsService.noteStartConfig(newConfig); 16485 16486 final Configuration configCopy = new Configuration(mConfiguration); 16487 16488 // TODO: If our config changes, should we auto dismiss any currently 16489 // showing dialogs? 16490 mShowDialogs = shouldShowDialogs(newConfig); 16491 16492 AttributeCache ac = AttributeCache.instance(); 16493 if (ac != null) { 16494 ac.updateConfiguration(configCopy); 16495 } 16496 16497 // Make sure all resources in our process are updated 16498 // right now, so that anyone who is going to retrieve 16499 // resource values after we return will be sure to get 16500 // the new ones. This is especially important during 16501 // boot, where the first config change needs to guarantee 16502 // all resources have that config before following boot 16503 // code is executed. 16504 mSystemThread.applyConfigurationToResources(configCopy); 16505 16506 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16507 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16508 msg.obj = new Configuration(configCopy); 16509 mHandler.sendMessage(msg); 16510 } 16511 16512 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16513 ProcessRecord app = mLruProcesses.get(i); 16514 try { 16515 if (app.thread != null) { 16516 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16517 + app.processName + " new config " + mConfiguration); 16518 app.thread.scheduleConfigurationChanged(configCopy); 16519 } 16520 } catch (Exception e) { 16521 } 16522 } 16523 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16524 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16525 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16526 | Intent.FLAG_RECEIVER_FOREGROUND); 16527 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16528 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16529 Process.SYSTEM_UID, UserHandle.USER_ALL); 16530 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16531 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16532 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16533 broadcastIntentLocked(null, null, intent, 16534 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16535 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16536 } 16537 } 16538 } 16539 16540 boolean kept = true; 16541 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16542 // mainStack is null during startup. 16543 if (mainStack != null) { 16544 if (changes != 0 && starting == null) { 16545 // If the configuration changed, and the caller is not already 16546 // in the process of starting an activity, then find the top 16547 // activity to check if its configuration needs to change. 16548 starting = mainStack.topRunningActivityLocked(null); 16549 } 16550 16551 if (starting != null) { 16552 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16553 // And we need to make sure at this point that all other activities 16554 // are made visible with the correct configuration. 16555 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16556 } 16557 } 16558 16559 if (values != null && mWindowManager != null) { 16560 mWindowManager.setNewConfiguration(mConfiguration); 16561 } 16562 16563 return kept; 16564 } 16565 16566 /** 16567 * Decide based on the configuration whether we should shouw the ANR, 16568 * crash, etc dialogs. The idea is that if there is no affordnace to 16569 * press the on-screen buttons, we shouldn't show the dialog. 16570 * 16571 * A thought: SystemUI might also want to get told about this, the Power 16572 * dialog / global actions also might want different behaviors. 16573 */ 16574 private static final boolean shouldShowDialogs(Configuration config) { 16575 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16576 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16577 } 16578 16579 /** 16580 * Save the locale. You must be inside a synchronized (this) block. 16581 */ 16582 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16583 if(isDiff) { 16584 SystemProperties.set("user.language", l.getLanguage()); 16585 SystemProperties.set("user.region", l.getCountry()); 16586 } 16587 16588 if(isPersist) { 16589 SystemProperties.set("persist.sys.language", l.getLanguage()); 16590 SystemProperties.set("persist.sys.country", l.getCountry()); 16591 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16592 16593 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16594 } 16595 } 16596 16597 @Override 16598 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16599 synchronized (this) { 16600 ActivityRecord srec = ActivityRecord.forToken(token); 16601 if (srec.task != null && srec.task.stack != null) { 16602 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16603 } 16604 } 16605 return false; 16606 } 16607 16608 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16609 Intent resultData) { 16610 16611 synchronized (this) { 16612 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16613 if (stack != null) { 16614 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16615 } 16616 return false; 16617 } 16618 } 16619 16620 public int getLaunchedFromUid(IBinder activityToken) { 16621 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16622 if (srec == null) { 16623 return -1; 16624 } 16625 return srec.launchedFromUid; 16626 } 16627 16628 public String getLaunchedFromPackage(IBinder activityToken) { 16629 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16630 if (srec == null) { 16631 return null; 16632 } 16633 return srec.launchedFromPackage; 16634 } 16635 16636 // ========================================================= 16637 // LIFETIME MANAGEMENT 16638 // ========================================================= 16639 16640 // Returns which broadcast queue the app is the current [or imminent] receiver 16641 // on, or 'null' if the app is not an active broadcast recipient. 16642 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16643 BroadcastRecord r = app.curReceiver; 16644 if (r != null) { 16645 return r.queue; 16646 } 16647 16648 // It's not the current receiver, but it might be starting up to become one 16649 synchronized (this) { 16650 for (BroadcastQueue queue : mBroadcastQueues) { 16651 r = queue.mPendingBroadcast; 16652 if (r != null && r.curApp == app) { 16653 // found it; report which queue it's in 16654 return queue; 16655 } 16656 } 16657 } 16658 16659 return null; 16660 } 16661 16662 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16663 boolean doingAll, long now) { 16664 if (mAdjSeq == app.adjSeq) { 16665 // This adjustment has already been computed. 16666 return app.curRawAdj; 16667 } 16668 16669 if (app.thread == null) { 16670 app.adjSeq = mAdjSeq; 16671 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16672 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16673 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16674 } 16675 16676 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16677 app.adjSource = null; 16678 app.adjTarget = null; 16679 app.empty = false; 16680 app.cached = false; 16681 16682 final int activitiesSize = app.activities.size(); 16683 16684 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16685 // The max adjustment doesn't allow this app to be anything 16686 // below foreground, so it is not worth doing work for it. 16687 app.adjType = "fixed"; 16688 app.adjSeq = mAdjSeq; 16689 app.curRawAdj = app.maxAdj; 16690 app.foregroundActivities = false; 16691 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16692 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16693 // System processes can do UI, and when they do we want to have 16694 // them trim their memory after the user leaves the UI. To 16695 // facilitate this, here we need to determine whether or not it 16696 // is currently showing UI. 16697 app.systemNoUi = true; 16698 if (app == TOP_APP) { 16699 app.systemNoUi = false; 16700 } else if (activitiesSize > 0) { 16701 for (int j = 0; j < activitiesSize; j++) { 16702 final ActivityRecord r = app.activities.get(j); 16703 if (r.visible) { 16704 app.systemNoUi = false; 16705 } 16706 } 16707 } 16708 if (!app.systemNoUi) { 16709 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16710 } 16711 return (app.curAdj=app.maxAdj); 16712 } 16713 16714 app.systemNoUi = false; 16715 16716 // Determine the importance of the process, starting with most 16717 // important to least, and assign an appropriate OOM adjustment. 16718 int adj; 16719 int schedGroup; 16720 int procState; 16721 boolean foregroundActivities = false; 16722 BroadcastQueue queue; 16723 if (app == TOP_APP) { 16724 // The last app on the list is the foreground app. 16725 adj = ProcessList.FOREGROUND_APP_ADJ; 16726 schedGroup = Process.THREAD_GROUP_DEFAULT; 16727 app.adjType = "top-activity"; 16728 foregroundActivities = true; 16729 procState = ActivityManager.PROCESS_STATE_TOP; 16730 } else if (app.instrumentationClass != null) { 16731 // Don't want to kill running instrumentation. 16732 adj = ProcessList.FOREGROUND_APP_ADJ; 16733 schedGroup = Process.THREAD_GROUP_DEFAULT; 16734 app.adjType = "instrumentation"; 16735 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16736 } else if ((queue = isReceivingBroadcast(app)) != null) { 16737 // An app that is currently receiving a broadcast also 16738 // counts as being in the foreground for OOM killer purposes. 16739 // It's placed in a sched group based on the nature of the 16740 // broadcast as reflected by which queue it's active in. 16741 adj = ProcessList.FOREGROUND_APP_ADJ; 16742 schedGroup = (queue == mFgBroadcastQueue) 16743 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16744 app.adjType = "broadcast"; 16745 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16746 } else if (app.executingServices.size() > 0) { 16747 // An app that is currently executing a service callback also 16748 // counts as being in the foreground. 16749 adj = ProcessList.FOREGROUND_APP_ADJ; 16750 schedGroup = app.execServicesFg ? 16751 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16752 app.adjType = "exec-service"; 16753 procState = ActivityManager.PROCESS_STATE_SERVICE; 16754 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16755 } else { 16756 // As far as we know the process is empty. We may change our mind later. 16757 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16758 // At this point we don't actually know the adjustment. Use the cached adj 16759 // value that the caller wants us to. 16760 adj = cachedAdj; 16761 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16762 app.cached = true; 16763 app.empty = true; 16764 app.adjType = "cch-empty"; 16765 } 16766 16767 // Examine all activities if not already foreground. 16768 if (!foregroundActivities && activitiesSize > 0) { 16769 for (int j = 0; j < activitiesSize; j++) { 16770 final ActivityRecord r = app.activities.get(j); 16771 if (r.app != app) { 16772 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16773 + app + "?!?"); 16774 continue; 16775 } 16776 if (r.visible) { 16777 // App has a visible activity; only upgrade adjustment. 16778 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16779 adj = ProcessList.VISIBLE_APP_ADJ; 16780 app.adjType = "visible"; 16781 } 16782 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16783 procState = ActivityManager.PROCESS_STATE_TOP; 16784 } 16785 schedGroup = Process.THREAD_GROUP_DEFAULT; 16786 app.cached = false; 16787 app.empty = false; 16788 foregroundActivities = true; 16789 break; 16790 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16791 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16792 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16793 app.adjType = "pausing"; 16794 } 16795 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16796 procState = ActivityManager.PROCESS_STATE_TOP; 16797 } 16798 schedGroup = Process.THREAD_GROUP_DEFAULT; 16799 app.cached = false; 16800 app.empty = false; 16801 foregroundActivities = true; 16802 } else if (r.state == ActivityState.STOPPING) { 16803 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16804 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16805 app.adjType = "stopping"; 16806 } 16807 // For the process state, we will at this point consider the 16808 // process to be cached. It will be cached either as an activity 16809 // or empty depending on whether the activity is finishing. We do 16810 // this so that we can treat the process as cached for purposes of 16811 // memory trimming (determing current memory level, trim command to 16812 // send to process) since there can be an arbitrary number of stopping 16813 // processes and they should soon all go into the cached state. 16814 if (!r.finishing) { 16815 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16816 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16817 } 16818 } 16819 app.cached = false; 16820 app.empty = false; 16821 foregroundActivities = true; 16822 } else { 16823 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16824 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16825 app.adjType = "cch-act"; 16826 } 16827 } 16828 } 16829 } 16830 16831 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16832 if (app.foregroundServices) { 16833 // The user is aware of this app, so make it visible. 16834 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16835 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16836 app.cached = false; 16837 app.adjType = "fg-service"; 16838 schedGroup = Process.THREAD_GROUP_DEFAULT; 16839 } else if (app.forcingToForeground != null) { 16840 // The user is aware of this app, so make it visible. 16841 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16842 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16843 app.cached = false; 16844 app.adjType = "force-fg"; 16845 app.adjSource = app.forcingToForeground; 16846 schedGroup = Process.THREAD_GROUP_DEFAULT; 16847 } 16848 } 16849 16850 if (app == mHeavyWeightProcess) { 16851 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16852 // We don't want to kill the current heavy-weight process. 16853 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16854 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16855 app.cached = false; 16856 app.adjType = "heavy"; 16857 } 16858 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16859 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16860 } 16861 } 16862 16863 if (app == mHomeProcess) { 16864 if (adj > ProcessList.HOME_APP_ADJ) { 16865 // This process is hosting what we currently consider to be the 16866 // home app, so we don't want to let it go into the background. 16867 adj = ProcessList.HOME_APP_ADJ; 16868 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16869 app.cached = false; 16870 app.adjType = "home"; 16871 } 16872 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16873 procState = ActivityManager.PROCESS_STATE_HOME; 16874 } 16875 } 16876 16877 if (app == mPreviousProcess && app.activities.size() > 0) { 16878 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16879 // This was the previous process that showed UI to the user. 16880 // We want to try to keep it around more aggressively, to give 16881 // a good experience around switching between two apps. 16882 adj = ProcessList.PREVIOUS_APP_ADJ; 16883 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16884 app.cached = false; 16885 app.adjType = "previous"; 16886 } 16887 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16888 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16889 } 16890 } 16891 16892 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16893 + " reason=" + app.adjType); 16894 16895 // By default, we use the computed adjustment. It may be changed if 16896 // there are applications dependent on our services or providers, but 16897 // this gives us a baseline and makes sure we don't get into an 16898 // infinite recursion. 16899 app.adjSeq = mAdjSeq; 16900 app.curRawAdj = adj; 16901 app.hasStartedServices = false; 16902 16903 if (mBackupTarget != null && app == mBackupTarget.app) { 16904 // If possible we want to avoid killing apps while they're being backed up 16905 if (adj > ProcessList.BACKUP_APP_ADJ) { 16906 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16907 adj = ProcessList.BACKUP_APP_ADJ; 16908 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16909 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16910 } 16911 app.adjType = "backup"; 16912 app.cached = false; 16913 } 16914 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16915 procState = ActivityManager.PROCESS_STATE_BACKUP; 16916 } 16917 } 16918 16919 boolean mayBeTop = false; 16920 16921 for (int is = app.services.size()-1; 16922 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16923 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16924 || procState > ActivityManager.PROCESS_STATE_TOP); 16925 is--) { 16926 ServiceRecord s = app.services.valueAt(is); 16927 if (s.startRequested) { 16928 app.hasStartedServices = true; 16929 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16930 procState = ActivityManager.PROCESS_STATE_SERVICE; 16931 } 16932 if (app.hasShownUi && app != mHomeProcess) { 16933 // If this process has shown some UI, let it immediately 16934 // go to the LRU list because it may be pretty heavy with 16935 // UI stuff. We'll tag it with a label just to help 16936 // debug and understand what is going on. 16937 if (adj > ProcessList.SERVICE_ADJ) { 16938 app.adjType = "cch-started-ui-services"; 16939 } 16940 } else { 16941 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16942 // This service has seen some activity within 16943 // recent memory, so we will keep its process ahead 16944 // of the background processes. 16945 if (adj > ProcessList.SERVICE_ADJ) { 16946 adj = ProcessList.SERVICE_ADJ; 16947 app.adjType = "started-services"; 16948 app.cached = false; 16949 } 16950 } 16951 // If we have let the service slide into the background 16952 // state, still have some text describing what it is doing 16953 // even though the service no longer has an impact. 16954 if (adj > ProcessList.SERVICE_ADJ) { 16955 app.adjType = "cch-started-services"; 16956 } 16957 } 16958 } 16959 for (int conni = s.connections.size()-1; 16960 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16961 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16962 || procState > ActivityManager.PROCESS_STATE_TOP); 16963 conni--) { 16964 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16965 for (int i = 0; 16966 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16967 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16968 || procState > ActivityManager.PROCESS_STATE_TOP); 16969 i++) { 16970 // XXX should compute this based on the max of 16971 // all connected clients. 16972 ConnectionRecord cr = clist.get(i); 16973 if (cr.binding.client == app) { 16974 // Binding to ourself is not interesting. 16975 continue; 16976 } 16977 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16978 ProcessRecord client = cr.binding.client; 16979 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16980 TOP_APP, doingAll, now); 16981 int clientProcState = client.curProcState; 16982 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16983 // If the other app is cached for any reason, for purposes here 16984 // we are going to consider it empty. The specific cached state 16985 // doesn't propagate except under certain conditions. 16986 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16987 } 16988 String adjType = null; 16989 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16990 // Not doing bind OOM management, so treat 16991 // this guy more like a started service. 16992 if (app.hasShownUi && app != mHomeProcess) { 16993 // If this process has shown some UI, let it immediately 16994 // go to the LRU list because it may be pretty heavy with 16995 // UI stuff. We'll tag it with a label just to help 16996 // debug and understand what is going on. 16997 if (adj > clientAdj) { 16998 adjType = "cch-bound-ui-services"; 16999 } 17000 app.cached = false; 17001 clientAdj = adj; 17002 clientProcState = procState; 17003 } else { 17004 if (now >= (s.lastActivity 17005 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17006 // This service has not seen activity within 17007 // recent memory, so allow it to drop to the 17008 // LRU list if there is no other reason to keep 17009 // it around. We'll also tag it with a label just 17010 // to help debug and undertand what is going on. 17011 if (adj > clientAdj) { 17012 adjType = "cch-bound-services"; 17013 } 17014 clientAdj = adj; 17015 } 17016 } 17017 } 17018 if (adj > clientAdj) { 17019 // If this process has recently shown UI, and 17020 // the process that is binding to it is less 17021 // important than being visible, then we don't 17022 // care about the binding as much as we care 17023 // about letting this process get into the LRU 17024 // list to be killed and restarted if needed for 17025 // memory. 17026 if (app.hasShownUi && app != mHomeProcess 17027 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17028 adjType = "cch-bound-ui-services"; 17029 } else { 17030 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17031 |Context.BIND_IMPORTANT)) != 0) { 17032 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17033 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17034 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17035 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17036 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17037 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17038 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17039 adj = clientAdj; 17040 } else { 17041 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17042 adj = ProcessList.VISIBLE_APP_ADJ; 17043 } 17044 } 17045 if (!client.cached) { 17046 app.cached = false; 17047 } 17048 adjType = "service"; 17049 } 17050 } 17051 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17052 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17053 schedGroup = Process.THREAD_GROUP_DEFAULT; 17054 } 17055 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17056 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17057 // Special handling of clients who are in the top state. 17058 // We *may* want to consider this process to be in the 17059 // top state as well, but only if there is not another 17060 // reason for it to be running. Being on the top is a 17061 // special state, meaning you are specifically running 17062 // for the current top app. If the process is already 17063 // running in the background for some other reason, it 17064 // is more important to continue considering it to be 17065 // in the background state. 17066 mayBeTop = true; 17067 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17068 } else { 17069 // Special handling for above-top states (persistent 17070 // processes). These should not bring the current process 17071 // into the top state, since they are not on top. Instead 17072 // give them the best state after that. 17073 clientProcState = 17074 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17075 } 17076 } 17077 } else { 17078 if (clientProcState < 17079 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17080 clientProcState = 17081 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17082 } 17083 } 17084 if (procState > clientProcState) { 17085 procState = clientProcState; 17086 } 17087 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17088 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17089 app.pendingUiClean = true; 17090 } 17091 if (adjType != null) { 17092 app.adjType = adjType; 17093 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17094 .REASON_SERVICE_IN_USE; 17095 app.adjSource = cr.binding.client; 17096 app.adjSourceProcState = clientProcState; 17097 app.adjTarget = s.name; 17098 } 17099 } 17100 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17101 app.treatLikeActivity = true; 17102 } 17103 final ActivityRecord a = cr.activity; 17104 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17105 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17106 (a.visible || a.state == ActivityState.RESUMED 17107 || a.state == ActivityState.PAUSING)) { 17108 adj = ProcessList.FOREGROUND_APP_ADJ; 17109 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17110 schedGroup = Process.THREAD_GROUP_DEFAULT; 17111 } 17112 app.cached = false; 17113 app.adjType = "service"; 17114 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17115 .REASON_SERVICE_IN_USE; 17116 app.adjSource = a; 17117 app.adjSourceProcState = procState; 17118 app.adjTarget = s.name; 17119 } 17120 } 17121 } 17122 } 17123 } 17124 17125 for (int provi = app.pubProviders.size()-1; 17126 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17127 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17128 || procState > ActivityManager.PROCESS_STATE_TOP); 17129 provi--) { 17130 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17131 for (int i = cpr.connections.size()-1; 17132 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17133 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17134 || procState > ActivityManager.PROCESS_STATE_TOP); 17135 i--) { 17136 ContentProviderConnection conn = cpr.connections.get(i); 17137 ProcessRecord client = conn.client; 17138 if (client == app) { 17139 // Being our own client is not interesting. 17140 continue; 17141 } 17142 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17143 int clientProcState = client.curProcState; 17144 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17145 // If the other app is cached for any reason, for purposes here 17146 // we are going to consider it empty. 17147 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17148 } 17149 if (adj > clientAdj) { 17150 if (app.hasShownUi && app != mHomeProcess 17151 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17152 app.adjType = "cch-ui-provider"; 17153 } else { 17154 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17155 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17156 app.adjType = "provider"; 17157 } 17158 app.cached &= client.cached; 17159 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17160 .REASON_PROVIDER_IN_USE; 17161 app.adjSource = client; 17162 app.adjSourceProcState = clientProcState; 17163 app.adjTarget = cpr.name; 17164 } 17165 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17166 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17167 // Special handling of clients who are in the top state. 17168 // We *may* want to consider this process to be in the 17169 // top state as well, but only if there is not another 17170 // reason for it to be running. Being on the top is a 17171 // special state, meaning you are specifically running 17172 // for the current top app. If the process is already 17173 // running in the background for some other reason, it 17174 // is more important to continue considering it to be 17175 // in the background state. 17176 mayBeTop = true; 17177 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17178 } else { 17179 // Special handling for above-top states (persistent 17180 // processes). These should not bring the current process 17181 // into the top state, since they are not on top. Instead 17182 // give them the best state after that. 17183 clientProcState = 17184 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17185 } 17186 } 17187 if (procState > clientProcState) { 17188 procState = clientProcState; 17189 } 17190 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17191 schedGroup = Process.THREAD_GROUP_DEFAULT; 17192 } 17193 } 17194 // If the provider has external (non-framework) process 17195 // dependencies, ensure that its adjustment is at least 17196 // FOREGROUND_APP_ADJ. 17197 if (cpr.hasExternalProcessHandles()) { 17198 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17199 adj = ProcessList.FOREGROUND_APP_ADJ; 17200 schedGroup = Process.THREAD_GROUP_DEFAULT; 17201 app.cached = false; 17202 app.adjType = "provider"; 17203 app.adjTarget = cpr.name; 17204 } 17205 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17206 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17207 } 17208 } 17209 } 17210 17211 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17212 // A client of one of our services or providers is in the top state. We 17213 // *may* want to be in the top state, but not if we are already running in 17214 // the background for some other reason. For the decision here, we are going 17215 // to pick out a few specific states that we want to remain in when a client 17216 // is top (states that tend to be longer-term) and otherwise allow it to go 17217 // to the top state. 17218 switch (procState) { 17219 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17220 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17221 case ActivityManager.PROCESS_STATE_SERVICE: 17222 // These all are longer-term states, so pull them up to the top 17223 // of the background states, but not all the way to the top state. 17224 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17225 break; 17226 default: 17227 // Otherwise, top is a better choice, so take it. 17228 procState = ActivityManager.PROCESS_STATE_TOP; 17229 break; 17230 } 17231 } 17232 17233 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17234 if (app.hasClientActivities) { 17235 // This is a cached process, but with client activities. Mark it so. 17236 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17237 app.adjType = "cch-client-act"; 17238 } else if (app.treatLikeActivity) { 17239 // This is a cached process, but somebody wants us to treat it like it has 17240 // an activity, okay! 17241 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17242 app.adjType = "cch-as-act"; 17243 } 17244 } 17245 17246 if (adj == ProcessList.SERVICE_ADJ) { 17247 if (doingAll) { 17248 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17249 mNewNumServiceProcs++; 17250 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17251 if (!app.serviceb) { 17252 // This service isn't far enough down on the LRU list to 17253 // normally be a B service, but if we are low on RAM and it 17254 // is large we want to force it down since we would prefer to 17255 // keep launcher over it. 17256 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17257 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17258 app.serviceHighRam = true; 17259 app.serviceb = true; 17260 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17261 } else { 17262 mNewNumAServiceProcs++; 17263 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17264 } 17265 } else { 17266 app.serviceHighRam = false; 17267 } 17268 } 17269 if (app.serviceb) { 17270 adj = ProcessList.SERVICE_B_ADJ; 17271 } 17272 } 17273 17274 app.curRawAdj = adj; 17275 17276 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17277 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17278 if (adj > app.maxAdj) { 17279 adj = app.maxAdj; 17280 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17281 schedGroup = Process.THREAD_GROUP_DEFAULT; 17282 } 17283 } 17284 17285 // Do final modification to adj. Everything we do between here and applying 17286 // the final setAdj must be done in this function, because we will also use 17287 // it when computing the final cached adj later. Note that we don't need to 17288 // worry about this for max adj above, since max adj will always be used to 17289 // keep it out of the cached vaues. 17290 app.curAdj = app.modifyRawOomAdj(adj); 17291 app.curSchedGroup = schedGroup; 17292 app.curProcState = procState; 17293 app.foregroundActivities = foregroundActivities; 17294 17295 return app.curRawAdj; 17296 } 17297 17298 /** 17299 * Schedule PSS collection of a process. 17300 */ 17301 void requestPssLocked(ProcessRecord proc, int procState) { 17302 if (mPendingPssProcesses.contains(proc)) { 17303 return; 17304 } 17305 if (mPendingPssProcesses.size() == 0) { 17306 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17307 } 17308 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17309 proc.pssProcState = procState; 17310 mPendingPssProcesses.add(proc); 17311 } 17312 17313 /** 17314 * Schedule PSS collection of all processes. 17315 */ 17316 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17317 if (!always) { 17318 if (now < (mLastFullPssTime + 17319 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17320 return; 17321 } 17322 } 17323 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17324 mLastFullPssTime = now; 17325 mFullPssPending = true; 17326 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17327 mPendingPssProcesses.clear(); 17328 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17329 ProcessRecord app = mLruProcesses.get(i); 17330 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17331 app.pssProcState = app.setProcState; 17332 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17333 isSleeping(), now); 17334 mPendingPssProcesses.add(app); 17335 } 17336 } 17337 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17338 } 17339 17340 /** 17341 * Ask a given process to GC right now. 17342 */ 17343 final void performAppGcLocked(ProcessRecord app) { 17344 try { 17345 app.lastRequestedGc = SystemClock.uptimeMillis(); 17346 if (app.thread != null) { 17347 if (app.reportLowMemory) { 17348 app.reportLowMemory = false; 17349 app.thread.scheduleLowMemory(); 17350 } else { 17351 app.thread.processInBackground(); 17352 } 17353 } 17354 } catch (Exception e) { 17355 // whatever. 17356 } 17357 } 17358 17359 /** 17360 * Returns true if things are idle enough to perform GCs. 17361 */ 17362 private final boolean canGcNowLocked() { 17363 boolean processingBroadcasts = false; 17364 for (BroadcastQueue q : mBroadcastQueues) { 17365 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17366 processingBroadcasts = true; 17367 } 17368 } 17369 return !processingBroadcasts 17370 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17371 } 17372 17373 /** 17374 * Perform GCs on all processes that are waiting for it, but only 17375 * if things are idle. 17376 */ 17377 final void performAppGcsLocked() { 17378 final int N = mProcessesToGc.size(); 17379 if (N <= 0) { 17380 return; 17381 } 17382 if (canGcNowLocked()) { 17383 while (mProcessesToGc.size() > 0) { 17384 ProcessRecord proc = mProcessesToGc.remove(0); 17385 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17386 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17387 <= SystemClock.uptimeMillis()) { 17388 // To avoid spamming the system, we will GC processes one 17389 // at a time, waiting a few seconds between each. 17390 performAppGcLocked(proc); 17391 scheduleAppGcsLocked(); 17392 return; 17393 } else { 17394 // It hasn't been long enough since we last GCed this 17395 // process... put it in the list to wait for its time. 17396 addProcessToGcListLocked(proc); 17397 break; 17398 } 17399 } 17400 } 17401 17402 scheduleAppGcsLocked(); 17403 } 17404 } 17405 17406 /** 17407 * If all looks good, perform GCs on all processes waiting for them. 17408 */ 17409 final void performAppGcsIfAppropriateLocked() { 17410 if (canGcNowLocked()) { 17411 performAppGcsLocked(); 17412 return; 17413 } 17414 // Still not idle, wait some more. 17415 scheduleAppGcsLocked(); 17416 } 17417 17418 /** 17419 * Schedule the execution of all pending app GCs. 17420 */ 17421 final void scheduleAppGcsLocked() { 17422 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17423 17424 if (mProcessesToGc.size() > 0) { 17425 // Schedule a GC for the time to the next process. 17426 ProcessRecord proc = mProcessesToGc.get(0); 17427 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17428 17429 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17430 long now = SystemClock.uptimeMillis(); 17431 if (when < (now+GC_TIMEOUT)) { 17432 when = now + GC_TIMEOUT; 17433 } 17434 mHandler.sendMessageAtTime(msg, when); 17435 } 17436 } 17437 17438 /** 17439 * Add a process to the array of processes waiting to be GCed. Keeps the 17440 * list in sorted order by the last GC time. The process can't already be 17441 * on the list. 17442 */ 17443 final void addProcessToGcListLocked(ProcessRecord proc) { 17444 boolean added = false; 17445 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17446 if (mProcessesToGc.get(i).lastRequestedGc < 17447 proc.lastRequestedGc) { 17448 added = true; 17449 mProcessesToGc.add(i+1, proc); 17450 break; 17451 } 17452 } 17453 if (!added) { 17454 mProcessesToGc.add(0, proc); 17455 } 17456 } 17457 17458 /** 17459 * Set up to ask a process to GC itself. This will either do it 17460 * immediately, or put it on the list of processes to gc the next 17461 * time things are idle. 17462 */ 17463 final void scheduleAppGcLocked(ProcessRecord app) { 17464 long now = SystemClock.uptimeMillis(); 17465 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17466 return; 17467 } 17468 if (!mProcessesToGc.contains(app)) { 17469 addProcessToGcListLocked(app); 17470 scheduleAppGcsLocked(); 17471 } 17472 } 17473 17474 final void checkExcessivePowerUsageLocked(boolean doKills) { 17475 updateCpuStatsNow(); 17476 17477 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17478 boolean doWakeKills = doKills; 17479 boolean doCpuKills = doKills; 17480 if (mLastPowerCheckRealtime == 0) { 17481 doWakeKills = false; 17482 } 17483 if (mLastPowerCheckUptime == 0) { 17484 doCpuKills = false; 17485 } 17486 if (stats.isScreenOn()) { 17487 doWakeKills = false; 17488 } 17489 final long curRealtime = SystemClock.elapsedRealtime(); 17490 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17491 final long curUptime = SystemClock.uptimeMillis(); 17492 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17493 mLastPowerCheckRealtime = curRealtime; 17494 mLastPowerCheckUptime = curUptime; 17495 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17496 doWakeKills = false; 17497 } 17498 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17499 doCpuKills = false; 17500 } 17501 int i = mLruProcesses.size(); 17502 while (i > 0) { 17503 i--; 17504 ProcessRecord app = mLruProcesses.get(i); 17505 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17506 long wtime; 17507 synchronized (stats) { 17508 wtime = stats.getProcessWakeTime(app.info.uid, 17509 app.pid, curRealtime); 17510 } 17511 long wtimeUsed = wtime - app.lastWakeTime; 17512 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17513 if (DEBUG_POWER) { 17514 StringBuilder sb = new StringBuilder(128); 17515 sb.append("Wake for "); 17516 app.toShortString(sb); 17517 sb.append(": over "); 17518 TimeUtils.formatDuration(realtimeSince, sb); 17519 sb.append(" used "); 17520 TimeUtils.formatDuration(wtimeUsed, sb); 17521 sb.append(" ("); 17522 sb.append((wtimeUsed*100)/realtimeSince); 17523 sb.append("%)"); 17524 Slog.i(TAG, sb.toString()); 17525 sb.setLength(0); 17526 sb.append("CPU for "); 17527 app.toShortString(sb); 17528 sb.append(": over "); 17529 TimeUtils.formatDuration(uptimeSince, sb); 17530 sb.append(" used "); 17531 TimeUtils.formatDuration(cputimeUsed, sb); 17532 sb.append(" ("); 17533 sb.append((cputimeUsed*100)/uptimeSince); 17534 sb.append("%)"); 17535 Slog.i(TAG, sb.toString()); 17536 } 17537 // If a process has held a wake lock for more 17538 // than 50% of the time during this period, 17539 // that sounds bad. Kill! 17540 if (doWakeKills && realtimeSince > 0 17541 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17542 synchronized (stats) { 17543 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17544 realtimeSince, wtimeUsed); 17545 } 17546 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17547 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17548 } else if (doCpuKills && uptimeSince > 0 17549 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17550 synchronized (stats) { 17551 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17552 uptimeSince, cputimeUsed); 17553 } 17554 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17555 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17556 } else { 17557 app.lastWakeTime = wtime; 17558 app.lastCpuTime = app.curCpuTime; 17559 } 17560 } 17561 } 17562 } 17563 17564 private final boolean applyOomAdjLocked(ProcessRecord app, 17565 ProcessRecord TOP_APP, boolean doingAll, long now) { 17566 boolean success = true; 17567 17568 if (app.curRawAdj != app.setRawAdj) { 17569 app.setRawAdj = app.curRawAdj; 17570 } 17571 17572 int changes = 0; 17573 17574 if (app.curAdj != app.setAdj) { 17575 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17576 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17577 TAG, "Set " + app.pid + " " + app.processName + 17578 " adj " + app.curAdj + ": " + app.adjType); 17579 app.setAdj = app.curAdj; 17580 } 17581 17582 if (app.setSchedGroup != app.curSchedGroup) { 17583 app.setSchedGroup = app.curSchedGroup; 17584 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17585 "Setting process group of " + app.processName 17586 + " to " + app.curSchedGroup); 17587 if (app.waitingToKill != null && 17588 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17589 app.kill(app.waitingToKill, true); 17590 success = false; 17591 } else { 17592 if (true) { 17593 long oldId = Binder.clearCallingIdentity(); 17594 try { 17595 Process.setProcessGroup(app.pid, app.curSchedGroup); 17596 } catch (Exception e) { 17597 Slog.w(TAG, "Failed setting process group of " + app.pid 17598 + " to " + app.curSchedGroup); 17599 e.printStackTrace(); 17600 } finally { 17601 Binder.restoreCallingIdentity(oldId); 17602 } 17603 } else { 17604 if (app.thread != null) { 17605 try { 17606 app.thread.setSchedulingGroup(app.curSchedGroup); 17607 } catch (RemoteException e) { 17608 } 17609 } 17610 } 17611 Process.setSwappiness(app.pid, 17612 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17613 } 17614 } 17615 if (app.repForegroundActivities != app.foregroundActivities) { 17616 app.repForegroundActivities = app.foregroundActivities; 17617 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17618 } 17619 if (app.repProcState != app.curProcState) { 17620 app.repProcState = app.curProcState; 17621 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17622 if (app.thread != null) { 17623 try { 17624 if (false) { 17625 //RuntimeException h = new RuntimeException("here"); 17626 Slog.i(TAG, "Sending new process state " + app.repProcState 17627 + " to " + app /*, h*/); 17628 } 17629 app.thread.setProcessState(app.repProcState); 17630 } catch (RemoteException e) { 17631 } 17632 } 17633 } 17634 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17635 app.setProcState)) { 17636 app.lastStateTime = now; 17637 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17638 isSleeping(), now); 17639 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17640 + ProcessList.makeProcStateString(app.setProcState) + " to " 17641 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17642 + (app.nextPssTime-now) + ": " + app); 17643 } else { 17644 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17645 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17646 requestPssLocked(app, app.setProcState); 17647 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17648 isSleeping(), now); 17649 } else if (false && DEBUG_PSS) { 17650 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17651 } 17652 } 17653 if (app.setProcState != app.curProcState) { 17654 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17655 "Proc state change of " + app.processName 17656 + " to " + app.curProcState); 17657 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17658 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17659 if (setImportant && !curImportant) { 17660 // This app is no longer something we consider important enough to allow to 17661 // use arbitrary amounts of battery power. Note 17662 // its current wake lock time to later know to kill it if 17663 // it is not behaving well. 17664 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17665 synchronized (stats) { 17666 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17667 app.pid, SystemClock.elapsedRealtime()); 17668 } 17669 app.lastCpuTime = app.curCpuTime; 17670 17671 } 17672 app.setProcState = app.curProcState; 17673 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17674 app.notCachedSinceIdle = false; 17675 } 17676 if (!doingAll) { 17677 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17678 } else { 17679 app.procStateChanged = true; 17680 } 17681 } 17682 17683 if (changes != 0) { 17684 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17685 int i = mPendingProcessChanges.size()-1; 17686 ProcessChangeItem item = null; 17687 while (i >= 0) { 17688 item = mPendingProcessChanges.get(i); 17689 if (item.pid == app.pid) { 17690 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17691 break; 17692 } 17693 i--; 17694 } 17695 if (i < 0) { 17696 // No existing item in pending changes; need a new one. 17697 final int NA = mAvailProcessChanges.size(); 17698 if (NA > 0) { 17699 item = mAvailProcessChanges.remove(NA-1); 17700 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17701 } else { 17702 item = new ProcessChangeItem(); 17703 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17704 } 17705 item.changes = 0; 17706 item.pid = app.pid; 17707 item.uid = app.info.uid; 17708 if (mPendingProcessChanges.size() == 0) { 17709 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17710 "*** Enqueueing dispatch processes changed!"); 17711 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17712 } 17713 mPendingProcessChanges.add(item); 17714 } 17715 item.changes |= changes; 17716 item.processState = app.repProcState; 17717 item.foregroundActivities = app.repForegroundActivities; 17718 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17719 + Integer.toHexString(System.identityHashCode(item)) 17720 + " " + app.toShortString() + ": changes=" + item.changes 17721 + " procState=" + item.processState 17722 + " foreground=" + item.foregroundActivities 17723 + " type=" + app.adjType + " source=" + app.adjSource 17724 + " target=" + app.adjTarget); 17725 } 17726 17727 return success; 17728 } 17729 17730 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17731 if (proc.thread != null) { 17732 if (proc.baseProcessTracker != null) { 17733 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17734 } 17735 if (proc.repProcState >= 0) { 17736 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17737 proc.repProcState); 17738 } 17739 } 17740 } 17741 17742 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17743 ProcessRecord TOP_APP, boolean doingAll, long now) { 17744 if (app.thread == null) { 17745 return false; 17746 } 17747 17748 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17749 17750 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17751 } 17752 17753 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17754 boolean oomAdj) { 17755 if (isForeground != proc.foregroundServices) { 17756 proc.foregroundServices = isForeground; 17757 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17758 proc.info.uid); 17759 if (isForeground) { 17760 if (curProcs == null) { 17761 curProcs = new ArrayList<ProcessRecord>(); 17762 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17763 } 17764 if (!curProcs.contains(proc)) { 17765 curProcs.add(proc); 17766 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17767 proc.info.packageName, proc.info.uid); 17768 } 17769 } else { 17770 if (curProcs != null) { 17771 if (curProcs.remove(proc)) { 17772 mBatteryStatsService.noteEvent( 17773 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17774 proc.info.packageName, proc.info.uid); 17775 if (curProcs.size() <= 0) { 17776 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17777 } 17778 } 17779 } 17780 } 17781 if (oomAdj) { 17782 updateOomAdjLocked(); 17783 } 17784 } 17785 } 17786 17787 private final ActivityRecord resumedAppLocked() { 17788 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17789 String pkg; 17790 int uid; 17791 if (act != null) { 17792 pkg = act.packageName; 17793 uid = act.info.applicationInfo.uid; 17794 } else { 17795 pkg = null; 17796 uid = -1; 17797 } 17798 // Has the UID or resumed package name changed? 17799 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17800 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17801 if (mCurResumedPackage != null) { 17802 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17803 mCurResumedPackage, mCurResumedUid); 17804 } 17805 mCurResumedPackage = pkg; 17806 mCurResumedUid = uid; 17807 if (mCurResumedPackage != null) { 17808 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17809 mCurResumedPackage, mCurResumedUid); 17810 } 17811 } 17812 return act; 17813 } 17814 17815 final boolean updateOomAdjLocked(ProcessRecord app) { 17816 final ActivityRecord TOP_ACT = resumedAppLocked(); 17817 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17818 final boolean wasCached = app.cached; 17819 17820 mAdjSeq++; 17821 17822 // This is the desired cached adjusment we want to tell it to use. 17823 // If our app is currently cached, we know it, and that is it. Otherwise, 17824 // we don't know it yet, and it needs to now be cached we will then 17825 // need to do a complete oom adj. 17826 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17827 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17828 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17829 SystemClock.uptimeMillis()); 17830 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17831 // Changed to/from cached state, so apps after it in the LRU 17832 // list may also be changed. 17833 updateOomAdjLocked(); 17834 } 17835 return success; 17836 } 17837 17838 final void updateOomAdjLocked() { 17839 final ActivityRecord TOP_ACT = resumedAppLocked(); 17840 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17841 final long now = SystemClock.uptimeMillis(); 17842 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17843 final int N = mLruProcesses.size(); 17844 17845 if (false) { 17846 RuntimeException e = new RuntimeException(); 17847 e.fillInStackTrace(); 17848 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17849 } 17850 17851 mAdjSeq++; 17852 mNewNumServiceProcs = 0; 17853 mNewNumAServiceProcs = 0; 17854 17855 final int emptyProcessLimit; 17856 final int cachedProcessLimit; 17857 if (mProcessLimit <= 0) { 17858 emptyProcessLimit = cachedProcessLimit = 0; 17859 } else if (mProcessLimit == 1) { 17860 emptyProcessLimit = 1; 17861 cachedProcessLimit = 0; 17862 } else { 17863 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17864 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17865 } 17866 17867 // Let's determine how many processes we have running vs. 17868 // how many slots we have for background processes; we may want 17869 // to put multiple processes in a slot of there are enough of 17870 // them. 17871 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17872 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17873 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17874 if (numEmptyProcs > cachedProcessLimit) { 17875 // If there are more empty processes than our limit on cached 17876 // processes, then use the cached process limit for the factor. 17877 // This ensures that the really old empty processes get pushed 17878 // down to the bottom, so if we are running low on memory we will 17879 // have a better chance at keeping around more cached processes 17880 // instead of a gazillion empty processes. 17881 numEmptyProcs = cachedProcessLimit; 17882 } 17883 int emptyFactor = numEmptyProcs/numSlots; 17884 if (emptyFactor < 1) emptyFactor = 1; 17885 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17886 if (cachedFactor < 1) cachedFactor = 1; 17887 int stepCached = 0; 17888 int stepEmpty = 0; 17889 int numCached = 0; 17890 int numEmpty = 0; 17891 int numTrimming = 0; 17892 17893 mNumNonCachedProcs = 0; 17894 mNumCachedHiddenProcs = 0; 17895 17896 // First update the OOM adjustment for each of the 17897 // application processes based on their current state. 17898 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17899 int nextCachedAdj = curCachedAdj+1; 17900 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17901 int nextEmptyAdj = curEmptyAdj+2; 17902 for (int i=N-1; i>=0; i--) { 17903 ProcessRecord app = mLruProcesses.get(i); 17904 if (!app.killedByAm && app.thread != null) { 17905 app.procStateChanged = false; 17906 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17907 17908 // If we haven't yet assigned the final cached adj 17909 // to the process, do that now. 17910 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17911 switch (app.curProcState) { 17912 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17913 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17914 // This process is a cached process holding activities... 17915 // assign it the next cached value for that type, and then 17916 // step that cached level. 17917 app.curRawAdj = curCachedAdj; 17918 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17919 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17920 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17921 + ")"); 17922 if (curCachedAdj != nextCachedAdj) { 17923 stepCached++; 17924 if (stepCached >= cachedFactor) { 17925 stepCached = 0; 17926 curCachedAdj = nextCachedAdj; 17927 nextCachedAdj += 2; 17928 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17929 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17930 } 17931 } 17932 } 17933 break; 17934 default: 17935 // For everything else, assign next empty cached process 17936 // level and bump that up. Note that this means that 17937 // long-running services that have dropped down to the 17938 // cached level will be treated as empty (since their process 17939 // state is still as a service), which is what we want. 17940 app.curRawAdj = curEmptyAdj; 17941 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17942 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17943 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17944 + ")"); 17945 if (curEmptyAdj != nextEmptyAdj) { 17946 stepEmpty++; 17947 if (stepEmpty >= emptyFactor) { 17948 stepEmpty = 0; 17949 curEmptyAdj = nextEmptyAdj; 17950 nextEmptyAdj += 2; 17951 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17952 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17953 } 17954 } 17955 } 17956 break; 17957 } 17958 } 17959 17960 applyOomAdjLocked(app, TOP_APP, true, now); 17961 17962 // Count the number of process types. 17963 switch (app.curProcState) { 17964 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17965 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17966 mNumCachedHiddenProcs++; 17967 numCached++; 17968 if (numCached > cachedProcessLimit) { 17969 app.kill("cached #" + numCached, true); 17970 } 17971 break; 17972 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17973 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17974 && app.lastActivityTime < oldTime) { 17975 app.kill("empty for " 17976 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17977 / 1000) + "s", true); 17978 } else { 17979 numEmpty++; 17980 if (numEmpty > emptyProcessLimit) { 17981 app.kill("empty #" + numEmpty, true); 17982 } 17983 } 17984 break; 17985 default: 17986 mNumNonCachedProcs++; 17987 break; 17988 } 17989 17990 if (app.isolated && app.services.size() <= 0) { 17991 // If this is an isolated process, and there are no 17992 // services running in it, then the process is no longer 17993 // needed. We agressively kill these because we can by 17994 // definition not re-use the same process again, and it is 17995 // good to avoid having whatever code was running in them 17996 // left sitting around after no longer needed. 17997 app.kill("isolated not needed", true); 17998 } 17999 18000 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18001 && !app.killedByAm) { 18002 numTrimming++; 18003 } 18004 } 18005 } 18006 18007 mNumServiceProcs = mNewNumServiceProcs; 18008 18009 // Now determine the memory trimming level of background processes. 18010 // Unfortunately we need to start at the back of the list to do this 18011 // properly. We only do this if the number of background apps we 18012 // are managing to keep around is less than half the maximum we desire; 18013 // if we are keeping a good number around, we'll let them use whatever 18014 // memory they want. 18015 final int numCachedAndEmpty = numCached + numEmpty; 18016 int memFactor; 18017 if (numCached <= ProcessList.TRIM_CACHED_APPS 18018 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18019 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18020 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18021 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18022 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18023 } else { 18024 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18025 } 18026 } else { 18027 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18028 } 18029 // We always allow the memory level to go up (better). We only allow it to go 18030 // down if we are in a state where that is allowed, *and* the total number of processes 18031 // has gone down since last time. 18032 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18033 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18034 + " last=" + mLastNumProcesses); 18035 if (memFactor > mLastMemoryLevel) { 18036 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18037 memFactor = mLastMemoryLevel; 18038 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18039 } 18040 } 18041 mLastMemoryLevel = memFactor; 18042 mLastNumProcesses = mLruProcesses.size(); 18043 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18044 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18045 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18046 if (mLowRamStartTime == 0) { 18047 mLowRamStartTime = now; 18048 } 18049 int step = 0; 18050 int fgTrimLevel; 18051 switch (memFactor) { 18052 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18053 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18054 break; 18055 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18056 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18057 break; 18058 default: 18059 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18060 break; 18061 } 18062 int factor = numTrimming/3; 18063 int minFactor = 2; 18064 if (mHomeProcess != null) minFactor++; 18065 if (mPreviousProcess != null) minFactor++; 18066 if (factor < minFactor) factor = minFactor; 18067 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18068 for (int i=N-1; i>=0; i--) { 18069 ProcessRecord app = mLruProcesses.get(i); 18070 if (allChanged || app.procStateChanged) { 18071 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18072 app.procStateChanged = false; 18073 } 18074 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18075 && !app.killedByAm) { 18076 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18077 try { 18078 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18079 "Trimming memory of " + app.processName 18080 + " to " + curLevel); 18081 app.thread.scheduleTrimMemory(curLevel); 18082 } catch (RemoteException e) { 18083 } 18084 if (false) { 18085 // For now we won't do this; our memory trimming seems 18086 // to be good enough at this point that destroying 18087 // activities causes more harm than good. 18088 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18089 && app != mHomeProcess && app != mPreviousProcess) { 18090 // Need to do this on its own message because the stack may not 18091 // be in a consistent state at this point. 18092 // For these apps we will also finish their activities 18093 // to help them free memory. 18094 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18095 } 18096 } 18097 } 18098 app.trimMemoryLevel = curLevel; 18099 step++; 18100 if (step >= factor) { 18101 step = 0; 18102 switch (curLevel) { 18103 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18104 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18105 break; 18106 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18107 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18108 break; 18109 } 18110 } 18111 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18112 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18113 && app.thread != null) { 18114 try { 18115 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18116 "Trimming memory of heavy-weight " + app.processName 18117 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18118 app.thread.scheduleTrimMemory( 18119 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18120 } catch (RemoteException e) { 18121 } 18122 } 18123 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18124 } else { 18125 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18126 || app.systemNoUi) && app.pendingUiClean) { 18127 // If this application is now in the background and it 18128 // had done UI, then give it the special trim level to 18129 // have it free UI resources. 18130 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18131 if (app.trimMemoryLevel < level && app.thread != null) { 18132 try { 18133 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18134 "Trimming memory of bg-ui " + app.processName 18135 + " to " + level); 18136 app.thread.scheduleTrimMemory(level); 18137 } catch (RemoteException e) { 18138 } 18139 } 18140 app.pendingUiClean = false; 18141 } 18142 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18143 try { 18144 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18145 "Trimming memory of fg " + app.processName 18146 + " to " + fgTrimLevel); 18147 app.thread.scheduleTrimMemory(fgTrimLevel); 18148 } catch (RemoteException e) { 18149 } 18150 } 18151 app.trimMemoryLevel = fgTrimLevel; 18152 } 18153 } 18154 } else { 18155 if (mLowRamStartTime != 0) { 18156 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18157 mLowRamStartTime = 0; 18158 } 18159 for (int i=N-1; i>=0; i--) { 18160 ProcessRecord app = mLruProcesses.get(i); 18161 if (allChanged || app.procStateChanged) { 18162 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18163 app.procStateChanged = false; 18164 } 18165 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18166 || app.systemNoUi) && app.pendingUiClean) { 18167 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18168 && app.thread != null) { 18169 try { 18170 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18171 "Trimming memory of ui hidden " + app.processName 18172 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18173 app.thread.scheduleTrimMemory( 18174 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18175 } catch (RemoteException e) { 18176 } 18177 } 18178 app.pendingUiClean = false; 18179 } 18180 app.trimMemoryLevel = 0; 18181 } 18182 } 18183 18184 if (mAlwaysFinishActivities) { 18185 // Need to do this on its own message because the stack may not 18186 // be in a consistent state at this point. 18187 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18188 } 18189 18190 if (allChanged) { 18191 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18192 } 18193 18194 if (mProcessStats.shouldWriteNowLocked(now)) { 18195 mHandler.post(new Runnable() { 18196 @Override public void run() { 18197 synchronized (ActivityManagerService.this) { 18198 mProcessStats.writeStateAsyncLocked(); 18199 } 18200 } 18201 }); 18202 } 18203 18204 if (DEBUG_OOM_ADJ) { 18205 if (false) { 18206 RuntimeException here = new RuntimeException("here"); 18207 here.fillInStackTrace(); 18208 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18209 } else { 18210 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18211 } 18212 } 18213 } 18214 18215 final void trimApplications() { 18216 synchronized (this) { 18217 int i; 18218 18219 // First remove any unused application processes whose package 18220 // has been removed. 18221 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18222 final ProcessRecord app = mRemovedProcesses.get(i); 18223 if (app.activities.size() == 0 18224 && app.curReceiver == null && app.services.size() == 0) { 18225 Slog.i( 18226 TAG, "Exiting empty application process " 18227 + app.processName + " (" 18228 + (app.thread != null ? app.thread.asBinder() : null) 18229 + ")\n"); 18230 if (app.pid > 0 && app.pid != MY_PID) { 18231 app.kill("empty", false); 18232 } else { 18233 try { 18234 app.thread.scheduleExit(); 18235 } catch (Exception e) { 18236 // Ignore exceptions. 18237 } 18238 } 18239 cleanUpApplicationRecordLocked(app, false, true, -1); 18240 mRemovedProcesses.remove(i); 18241 18242 if (app.persistent) { 18243 addAppLocked(app.info, false, null /* ABI override */); 18244 } 18245 } 18246 } 18247 18248 // Now update the oom adj for all processes. 18249 updateOomAdjLocked(); 18250 } 18251 } 18252 18253 /** This method sends the specified signal to each of the persistent apps */ 18254 public void signalPersistentProcesses(int sig) throws RemoteException { 18255 if (sig != Process.SIGNAL_USR1) { 18256 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18257 } 18258 18259 synchronized (this) { 18260 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18261 != PackageManager.PERMISSION_GRANTED) { 18262 throw new SecurityException("Requires permission " 18263 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18264 } 18265 18266 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18267 ProcessRecord r = mLruProcesses.get(i); 18268 if (r.thread != null && r.persistent) { 18269 Process.sendSignal(r.pid, sig); 18270 } 18271 } 18272 } 18273 } 18274 18275 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18276 if (proc == null || proc == mProfileProc) { 18277 proc = mProfileProc; 18278 profileType = mProfileType; 18279 clearProfilerLocked(); 18280 } 18281 if (proc == null) { 18282 return; 18283 } 18284 try { 18285 proc.thread.profilerControl(false, null, profileType); 18286 } catch (RemoteException e) { 18287 throw new IllegalStateException("Process disappeared"); 18288 } 18289 } 18290 18291 private void clearProfilerLocked() { 18292 if (mProfileFd != null) { 18293 try { 18294 mProfileFd.close(); 18295 } catch (IOException e) { 18296 } 18297 } 18298 mProfileApp = null; 18299 mProfileProc = null; 18300 mProfileFile = null; 18301 mProfileType = 0; 18302 mAutoStopProfiler = false; 18303 mSamplingInterval = 0; 18304 } 18305 18306 public boolean profileControl(String process, int userId, boolean start, 18307 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18308 18309 try { 18310 synchronized (this) { 18311 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18312 // its own permission. 18313 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18314 != PackageManager.PERMISSION_GRANTED) { 18315 throw new SecurityException("Requires permission " 18316 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18317 } 18318 18319 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18320 throw new IllegalArgumentException("null profile info or fd"); 18321 } 18322 18323 ProcessRecord proc = null; 18324 if (process != null) { 18325 proc = findProcessLocked(process, userId, "profileControl"); 18326 } 18327 18328 if (start && (proc == null || proc.thread == null)) { 18329 throw new IllegalArgumentException("Unknown process: " + process); 18330 } 18331 18332 if (start) { 18333 stopProfilerLocked(null, 0); 18334 setProfileApp(proc.info, proc.processName, profilerInfo); 18335 mProfileProc = proc; 18336 mProfileType = profileType; 18337 ParcelFileDescriptor fd = profilerInfo.profileFd; 18338 try { 18339 fd = fd.dup(); 18340 } catch (IOException e) { 18341 fd = null; 18342 } 18343 profilerInfo.profileFd = fd; 18344 proc.thread.profilerControl(start, profilerInfo, profileType); 18345 fd = null; 18346 mProfileFd = null; 18347 } else { 18348 stopProfilerLocked(proc, profileType); 18349 if (profilerInfo != null && profilerInfo.profileFd != null) { 18350 try { 18351 profilerInfo.profileFd.close(); 18352 } catch (IOException e) { 18353 } 18354 } 18355 } 18356 18357 return true; 18358 } 18359 } catch (RemoteException e) { 18360 throw new IllegalStateException("Process disappeared"); 18361 } finally { 18362 if (profilerInfo != null && profilerInfo.profileFd != null) { 18363 try { 18364 profilerInfo.profileFd.close(); 18365 } catch (IOException e) { 18366 } 18367 } 18368 } 18369 } 18370 18371 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18372 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18373 userId, true, ALLOW_FULL_ONLY, callName, null); 18374 ProcessRecord proc = null; 18375 try { 18376 int pid = Integer.parseInt(process); 18377 synchronized (mPidsSelfLocked) { 18378 proc = mPidsSelfLocked.get(pid); 18379 } 18380 } catch (NumberFormatException e) { 18381 } 18382 18383 if (proc == null) { 18384 ArrayMap<String, SparseArray<ProcessRecord>> all 18385 = mProcessNames.getMap(); 18386 SparseArray<ProcessRecord> procs = all.get(process); 18387 if (procs != null && procs.size() > 0) { 18388 proc = procs.valueAt(0); 18389 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18390 for (int i=1; i<procs.size(); i++) { 18391 ProcessRecord thisProc = procs.valueAt(i); 18392 if (thisProc.userId == userId) { 18393 proc = thisProc; 18394 break; 18395 } 18396 } 18397 } 18398 } 18399 } 18400 18401 return proc; 18402 } 18403 18404 public boolean dumpHeap(String process, int userId, boolean managed, 18405 String path, ParcelFileDescriptor fd) throws RemoteException { 18406 18407 try { 18408 synchronized (this) { 18409 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18410 // its own permission (same as profileControl). 18411 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18412 != PackageManager.PERMISSION_GRANTED) { 18413 throw new SecurityException("Requires permission " 18414 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18415 } 18416 18417 if (fd == null) { 18418 throw new IllegalArgumentException("null fd"); 18419 } 18420 18421 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18422 if (proc == null || proc.thread == null) { 18423 throw new IllegalArgumentException("Unknown process: " + process); 18424 } 18425 18426 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18427 if (!isDebuggable) { 18428 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18429 throw new SecurityException("Process not debuggable: " + proc); 18430 } 18431 } 18432 18433 proc.thread.dumpHeap(managed, path, fd); 18434 fd = null; 18435 return true; 18436 } 18437 } catch (RemoteException e) { 18438 throw new IllegalStateException("Process disappeared"); 18439 } finally { 18440 if (fd != null) { 18441 try { 18442 fd.close(); 18443 } catch (IOException e) { 18444 } 18445 } 18446 } 18447 } 18448 18449 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18450 public void monitor() { 18451 synchronized (this) { } 18452 } 18453 18454 void onCoreSettingsChange(Bundle settings) { 18455 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18456 ProcessRecord processRecord = mLruProcesses.get(i); 18457 try { 18458 if (processRecord.thread != null) { 18459 processRecord.thread.setCoreSettings(settings); 18460 } 18461 } catch (RemoteException re) { 18462 /* ignore */ 18463 } 18464 } 18465 } 18466 18467 // Multi-user methods 18468 18469 /** 18470 * Start user, if its not already running, but don't bring it to foreground. 18471 */ 18472 @Override 18473 public boolean startUserInBackground(final int userId) { 18474 return startUser(userId, /* foreground */ false); 18475 } 18476 18477 /** 18478 * Start user, if its not already running, and bring it to foreground. 18479 */ 18480 boolean startUserInForeground(final int userId, Dialog dlg) { 18481 boolean result = startUser(userId, /* foreground */ true); 18482 dlg.dismiss(); 18483 return result; 18484 } 18485 18486 /** 18487 * Refreshes the list of users related to the current user when either a 18488 * user switch happens or when a new related user is started in the 18489 * background. 18490 */ 18491 private void updateCurrentProfileIdsLocked() { 18492 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18493 mCurrentUserId, false /* enabledOnly */); 18494 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18495 for (int i = 0; i < currentProfileIds.length; i++) { 18496 currentProfileIds[i] = profiles.get(i).id; 18497 } 18498 mCurrentProfileIds = currentProfileIds; 18499 18500 synchronized (mUserProfileGroupIdsSelfLocked) { 18501 mUserProfileGroupIdsSelfLocked.clear(); 18502 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18503 for (int i = 0; i < users.size(); i++) { 18504 UserInfo user = users.get(i); 18505 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18506 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18507 } 18508 } 18509 } 18510 } 18511 18512 private Set getProfileIdsLocked(int userId) { 18513 Set userIds = new HashSet<Integer>(); 18514 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18515 userId, false /* enabledOnly */); 18516 for (UserInfo user : profiles) { 18517 userIds.add(Integer.valueOf(user.id)); 18518 } 18519 return userIds; 18520 } 18521 18522 @Override 18523 public boolean switchUser(final int userId) { 18524 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18525 String userName; 18526 synchronized (this) { 18527 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18528 if (userInfo == null) { 18529 Slog.w(TAG, "No user info for user #" + userId); 18530 return false; 18531 } 18532 if (userInfo.isManagedProfile()) { 18533 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18534 return false; 18535 } 18536 userName = userInfo.name; 18537 mTargetUserId = userId; 18538 } 18539 mHandler.removeMessages(START_USER_SWITCH_MSG); 18540 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18541 return true; 18542 } 18543 18544 private void showUserSwitchDialog(int userId, String userName) { 18545 // The dialog will show and then initiate the user switch by calling startUserInForeground 18546 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18547 true /* above system */); 18548 d.show(); 18549 } 18550 18551 private boolean startUser(final int userId, final boolean foreground) { 18552 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18553 != PackageManager.PERMISSION_GRANTED) { 18554 String msg = "Permission Denial: switchUser() from pid=" 18555 + Binder.getCallingPid() 18556 + ", uid=" + Binder.getCallingUid() 18557 + " requires " + INTERACT_ACROSS_USERS_FULL; 18558 Slog.w(TAG, msg); 18559 throw new SecurityException(msg); 18560 } 18561 18562 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18563 18564 final long ident = Binder.clearCallingIdentity(); 18565 try { 18566 synchronized (this) { 18567 final int oldUserId = mCurrentUserId; 18568 if (oldUserId == userId) { 18569 return true; 18570 } 18571 18572 mStackSupervisor.setLockTaskModeLocked(null, false); 18573 18574 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18575 if (userInfo == null) { 18576 Slog.w(TAG, "No user info for user #" + userId); 18577 return false; 18578 } 18579 if (foreground && userInfo.isManagedProfile()) { 18580 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18581 return false; 18582 } 18583 18584 if (foreground) { 18585 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18586 R.anim.screen_user_enter); 18587 } 18588 18589 boolean needStart = false; 18590 18591 // If the user we are switching to is not currently started, then 18592 // we need to start it now. 18593 if (mStartedUsers.get(userId) == null) { 18594 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18595 updateStartedUserArrayLocked(); 18596 needStart = true; 18597 } 18598 18599 final Integer userIdInt = Integer.valueOf(userId); 18600 mUserLru.remove(userIdInt); 18601 mUserLru.add(userIdInt); 18602 18603 if (foreground) { 18604 mCurrentUserId = userId; 18605 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18606 updateCurrentProfileIdsLocked(); 18607 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18608 // Once the internal notion of the active user has switched, we lock the device 18609 // with the option to show the user switcher on the keyguard. 18610 mWindowManager.lockNow(null); 18611 } else { 18612 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18613 updateCurrentProfileIdsLocked(); 18614 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18615 mUserLru.remove(currentUserIdInt); 18616 mUserLru.add(currentUserIdInt); 18617 } 18618 18619 final UserStartedState uss = mStartedUsers.get(userId); 18620 18621 // Make sure user is in the started state. If it is currently 18622 // stopping, we need to knock that off. 18623 if (uss.mState == UserStartedState.STATE_STOPPING) { 18624 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18625 // so we can just fairly silently bring the user back from 18626 // the almost-dead. 18627 uss.mState = UserStartedState.STATE_RUNNING; 18628 updateStartedUserArrayLocked(); 18629 needStart = true; 18630 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18631 // This means ACTION_SHUTDOWN has been sent, so we will 18632 // need to treat this as a new boot of the user. 18633 uss.mState = UserStartedState.STATE_BOOTING; 18634 updateStartedUserArrayLocked(); 18635 needStart = true; 18636 } 18637 18638 if (uss.mState == UserStartedState.STATE_BOOTING) { 18639 // Booting up a new user, need to tell system services about it. 18640 // Note that this is on the same handler as scheduling of broadcasts, 18641 // which is important because it needs to go first. 18642 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18643 } 18644 18645 if (foreground) { 18646 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18647 oldUserId)); 18648 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18649 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18650 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18651 oldUserId, userId, uss)); 18652 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18653 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18654 } 18655 18656 if (needStart) { 18657 // Send USER_STARTED broadcast 18658 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18659 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18660 | Intent.FLAG_RECEIVER_FOREGROUND); 18661 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18662 broadcastIntentLocked(null, null, intent, 18663 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18664 false, false, MY_PID, Process.SYSTEM_UID, userId); 18665 } 18666 18667 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18668 if (userId != UserHandle.USER_OWNER) { 18669 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18670 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18671 broadcastIntentLocked(null, null, intent, null, 18672 new IIntentReceiver.Stub() { 18673 public void performReceive(Intent intent, int resultCode, 18674 String data, Bundle extras, boolean ordered, 18675 boolean sticky, int sendingUser) { 18676 onUserInitialized(uss, foreground, oldUserId, userId); 18677 } 18678 }, 0, null, null, null, AppOpsManager.OP_NONE, 18679 true, false, MY_PID, Process.SYSTEM_UID, 18680 userId); 18681 uss.initializing = true; 18682 } else { 18683 getUserManagerLocked().makeInitialized(userInfo.id); 18684 } 18685 } 18686 18687 if (foreground) { 18688 if (!uss.initializing) { 18689 moveUserToForeground(uss, oldUserId, userId); 18690 } 18691 } else { 18692 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18693 } 18694 18695 if (needStart) { 18696 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18697 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18698 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18699 broadcastIntentLocked(null, null, intent, 18700 null, new IIntentReceiver.Stub() { 18701 @Override 18702 public void performReceive(Intent intent, int resultCode, String data, 18703 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18704 throws RemoteException { 18705 } 18706 }, 0, null, null, 18707 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18708 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18709 } 18710 } 18711 } finally { 18712 Binder.restoreCallingIdentity(ident); 18713 } 18714 18715 return true; 18716 } 18717 18718 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18719 long ident = Binder.clearCallingIdentity(); 18720 try { 18721 Intent intent; 18722 if (oldUserId >= 0) { 18723 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18724 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18725 int count = profiles.size(); 18726 for (int i = 0; i < count; i++) { 18727 int profileUserId = profiles.get(i).id; 18728 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18729 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18730 | Intent.FLAG_RECEIVER_FOREGROUND); 18731 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18732 broadcastIntentLocked(null, null, intent, 18733 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18734 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18735 } 18736 } 18737 if (newUserId >= 0) { 18738 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18739 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18740 int count = profiles.size(); 18741 for (int i = 0; i < count; i++) { 18742 int profileUserId = profiles.get(i).id; 18743 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18744 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18745 | Intent.FLAG_RECEIVER_FOREGROUND); 18746 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18747 broadcastIntentLocked(null, null, intent, 18748 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18749 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18750 } 18751 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18752 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18753 | Intent.FLAG_RECEIVER_FOREGROUND); 18754 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18755 broadcastIntentLocked(null, null, intent, 18756 null, null, 0, null, null, 18757 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18758 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18759 } 18760 } finally { 18761 Binder.restoreCallingIdentity(ident); 18762 } 18763 } 18764 18765 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18766 final int newUserId) { 18767 final int N = mUserSwitchObservers.beginBroadcast(); 18768 if (N > 0) { 18769 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18770 int mCount = 0; 18771 @Override 18772 public void sendResult(Bundle data) throws RemoteException { 18773 synchronized (ActivityManagerService.this) { 18774 if (mCurUserSwitchCallback == this) { 18775 mCount++; 18776 if (mCount == N) { 18777 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18778 } 18779 } 18780 } 18781 } 18782 }; 18783 synchronized (this) { 18784 uss.switching = true; 18785 mCurUserSwitchCallback = callback; 18786 } 18787 for (int i=0; i<N; i++) { 18788 try { 18789 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18790 newUserId, callback); 18791 } catch (RemoteException e) { 18792 } 18793 } 18794 } else { 18795 synchronized (this) { 18796 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18797 } 18798 } 18799 mUserSwitchObservers.finishBroadcast(); 18800 } 18801 18802 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18803 synchronized (this) { 18804 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18805 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18806 } 18807 } 18808 18809 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18810 mCurUserSwitchCallback = null; 18811 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18812 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18813 oldUserId, newUserId, uss)); 18814 } 18815 18816 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18817 synchronized (this) { 18818 if (foreground) { 18819 moveUserToForeground(uss, oldUserId, newUserId); 18820 } 18821 } 18822 18823 completeSwitchAndInitalize(uss, newUserId, true, false); 18824 } 18825 18826 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18827 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18828 if (homeInFront) { 18829 startHomeActivityLocked(newUserId); 18830 } else { 18831 mStackSupervisor.resumeTopActivitiesLocked(); 18832 } 18833 EventLogTags.writeAmSwitchUser(newUserId); 18834 getUserManagerLocked().userForeground(newUserId); 18835 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18836 } 18837 18838 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18839 completeSwitchAndInitalize(uss, newUserId, false, true); 18840 } 18841 18842 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18843 boolean clearInitializing, boolean clearSwitching) { 18844 boolean unfrozen = false; 18845 synchronized (this) { 18846 if (clearInitializing) { 18847 uss.initializing = false; 18848 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18849 } 18850 if (clearSwitching) { 18851 uss.switching = false; 18852 } 18853 if (!uss.switching && !uss.initializing) { 18854 mWindowManager.stopFreezingScreen(); 18855 unfrozen = true; 18856 } 18857 } 18858 if (unfrozen) { 18859 final int N = mUserSwitchObservers.beginBroadcast(); 18860 for (int i=0; i<N; i++) { 18861 try { 18862 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18863 } catch (RemoteException e) { 18864 } 18865 } 18866 mUserSwitchObservers.finishBroadcast(); 18867 } 18868 } 18869 18870 void scheduleStartProfilesLocked() { 18871 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18872 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18873 DateUtils.SECOND_IN_MILLIS); 18874 } 18875 } 18876 18877 void startProfilesLocked() { 18878 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18879 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18880 mCurrentUserId, false /* enabledOnly */); 18881 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18882 for (UserInfo user : profiles) { 18883 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18884 && user.id != mCurrentUserId) { 18885 toStart.add(user); 18886 } 18887 } 18888 final int n = toStart.size(); 18889 int i = 0; 18890 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18891 startUserInBackground(toStart.get(i).id); 18892 } 18893 if (i < n) { 18894 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18895 } 18896 } 18897 18898 void finishUserBoot(UserStartedState uss) { 18899 synchronized (this) { 18900 if (uss.mState == UserStartedState.STATE_BOOTING 18901 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18902 uss.mState = UserStartedState.STATE_RUNNING; 18903 final int userId = uss.mHandle.getIdentifier(); 18904 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18905 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18906 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18907 broadcastIntentLocked(null, null, intent, 18908 null, null, 0, null, null, 18909 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18910 true, false, MY_PID, Process.SYSTEM_UID, userId); 18911 } 18912 } 18913 } 18914 18915 void finishUserSwitch(UserStartedState uss) { 18916 synchronized (this) { 18917 finishUserBoot(uss); 18918 18919 startProfilesLocked(); 18920 18921 int num = mUserLru.size(); 18922 int i = 0; 18923 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18924 Integer oldUserId = mUserLru.get(i); 18925 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18926 if (oldUss == null) { 18927 // Shouldn't happen, but be sane if it does. 18928 mUserLru.remove(i); 18929 num--; 18930 continue; 18931 } 18932 if (oldUss.mState == UserStartedState.STATE_STOPPING 18933 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18934 // This user is already stopping, doesn't count. 18935 num--; 18936 i++; 18937 continue; 18938 } 18939 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18940 // Owner and current can't be stopped, but count as running. 18941 i++; 18942 continue; 18943 } 18944 // This is a user to be stopped. 18945 stopUserLocked(oldUserId, null); 18946 num--; 18947 i++; 18948 } 18949 } 18950 } 18951 18952 @Override 18953 public int stopUser(final int userId, final IStopUserCallback callback) { 18954 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18955 != PackageManager.PERMISSION_GRANTED) { 18956 String msg = "Permission Denial: switchUser() from pid=" 18957 + Binder.getCallingPid() 18958 + ", uid=" + Binder.getCallingUid() 18959 + " requires " + INTERACT_ACROSS_USERS_FULL; 18960 Slog.w(TAG, msg); 18961 throw new SecurityException(msg); 18962 } 18963 if (userId <= 0) { 18964 throw new IllegalArgumentException("Can't stop primary user " + userId); 18965 } 18966 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18967 synchronized (this) { 18968 return stopUserLocked(userId, callback); 18969 } 18970 } 18971 18972 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18973 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18974 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18975 return ActivityManager.USER_OP_IS_CURRENT; 18976 } 18977 18978 final UserStartedState uss = mStartedUsers.get(userId); 18979 if (uss == null) { 18980 // User is not started, nothing to do... but we do need to 18981 // callback if requested. 18982 if (callback != null) { 18983 mHandler.post(new Runnable() { 18984 @Override 18985 public void run() { 18986 try { 18987 callback.userStopped(userId); 18988 } catch (RemoteException e) { 18989 } 18990 } 18991 }); 18992 } 18993 return ActivityManager.USER_OP_SUCCESS; 18994 } 18995 18996 if (callback != null) { 18997 uss.mStopCallbacks.add(callback); 18998 } 18999 19000 if (uss.mState != UserStartedState.STATE_STOPPING 19001 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19002 uss.mState = UserStartedState.STATE_STOPPING; 19003 updateStartedUserArrayLocked(); 19004 19005 long ident = Binder.clearCallingIdentity(); 19006 try { 19007 // We are going to broadcast ACTION_USER_STOPPING and then 19008 // once that is done send a final ACTION_SHUTDOWN and then 19009 // stop the user. 19010 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19011 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19012 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19013 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19014 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19015 // This is the result receiver for the final shutdown broadcast. 19016 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19017 @Override 19018 public void performReceive(Intent intent, int resultCode, String data, 19019 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19020 finishUserStop(uss); 19021 } 19022 }; 19023 // This is the result receiver for the initial stopping broadcast. 19024 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19025 @Override 19026 public void performReceive(Intent intent, int resultCode, String data, 19027 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19028 // On to the next. 19029 synchronized (ActivityManagerService.this) { 19030 if (uss.mState != UserStartedState.STATE_STOPPING) { 19031 // Whoops, we are being started back up. Abort, abort! 19032 return; 19033 } 19034 uss.mState = UserStartedState.STATE_SHUTDOWN; 19035 } 19036 mBatteryStatsService.noteEvent( 19037 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19038 Integer.toString(userId), userId); 19039 mSystemServiceManager.stopUser(userId); 19040 broadcastIntentLocked(null, null, shutdownIntent, 19041 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19042 true, false, MY_PID, Process.SYSTEM_UID, userId); 19043 } 19044 }; 19045 // Kick things off. 19046 broadcastIntentLocked(null, null, stoppingIntent, 19047 null, stoppingReceiver, 0, null, null, 19048 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19049 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19050 } finally { 19051 Binder.restoreCallingIdentity(ident); 19052 } 19053 } 19054 19055 return ActivityManager.USER_OP_SUCCESS; 19056 } 19057 19058 void finishUserStop(UserStartedState uss) { 19059 final int userId = uss.mHandle.getIdentifier(); 19060 boolean stopped; 19061 ArrayList<IStopUserCallback> callbacks; 19062 synchronized (this) { 19063 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19064 if (mStartedUsers.get(userId) != uss) { 19065 stopped = false; 19066 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19067 stopped = false; 19068 } else { 19069 stopped = true; 19070 // User can no longer run. 19071 mStartedUsers.remove(userId); 19072 mUserLru.remove(Integer.valueOf(userId)); 19073 updateStartedUserArrayLocked(); 19074 19075 // Clean up all state and processes associated with the user. 19076 // Kill all the processes for the user. 19077 forceStopUserLocked(userId, "finish user"); 19078 } 19079 19080 // Explicitly remove the old information in mRecentTasks. 19081 removeRecentTasksForUserLocked(userId); 19082 } 19083 19084 for (int i=0; i<callbacks.size(); i++) { 19085 try { 19086 if (stopped) callbacks.get(i).userStopped(userId); 19087 else callbacks.get(i).userStopAborted(userId); 19088 } catch (RemoteException e) { 19089 } 19090 } 19091 19092 if (stopped) { 19093 mSystemServiceManager.cleanupUser(userId); 19094 synchronized (this) { 19095 mStackSupervisor.removeUserLocked(userId); 19096 } 19097 } 19098 } 19099 19100 @Override 19101 public UserInfo getCurrentUser() { 19102 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19103 != PackageManager.PERMISSION_GRANTED) && ( 19104 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19105 != PackageManager.PERMISSION_GRANTED)) { 19106 String msg = "Permission Denial: getCurrentUser() from pid=" 19107 + Binder.getCallingPid() 19108 + ", uid=" + Binder.getCallingUid() 19109 + " requires " + INTERACT_ACROSS_USERS; 19110 Slog.w(TAG, msg); 19111 throw new SecurityException(msg); 19112 } 19113 synchronized (this) { 19114 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19115 return getUserManagerLocked().getUserInfo(userId); 19116 } 19117 } 19118 19119 int getCurrentUserIdLocked() { 19120 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19121 } 19122 19123 @Override 19124 public boolean isUserRunning(int userId, boolean orStopped) { 19125 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19126 != PackageManager.PERMISSION_GRANTED) { 19127 String msg = "Permission Denial: isUserRunning() from pid=" 19128 + Binder.getCallingPid() 19129 + ", uid=" + Binder.getCallingUid() 19130 + " requires " + INTERACT_ACROSS_USERS; 19131 Slog.w(TAG, msg); 19132 throw new SecurityException(msg); 19133 } 19134 synchronized (this) { 19135 return isUserRunningLocked(userId, orStopped); 19136 } 19137 } 19138 19139 boolean isUserRunningLocked(int userId, boolean orStopped) { 19140 UserStartedState state = mStartedUsers.get(userId); 19141 if (state == null) { 19142 return false; 19143 } 19144 if (orStopped) { 19145 return true; 19146 } 19147 return state.mState != UserStartedState.STATE_STOPPING 19148 && state.mState != UserStartedState.STATE_SHUTDOWN; 19149 } 19150 19151 @Override 19152 public int[] getRunningUserIds() { 19153 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19154 != PackageManager.PERMISSION_GRANTED) { 19155 String msg = "Permission Denial: isUserRunning() from pid=" 19156 + Binder.getCallingPid() 19157 + ", uid=" + Binder.getCallingUid() 19158 + " requires " + INTERACT_ACROSS_USERS; 19159 Slog.w(TAG, msg); 19160 throw new SecurityException(msg); 19161 } 19162 synchronized (this) { 19163 return mStartedUserArray; 19164 } 19165 } 19166 19167 private void updateStartedUserArrayLocked() { 19168 int num = 0; 19169 for (int i=0; i<mStartedUsers.size(); i++) { 19170 UserStartedState uss = mStartedUsers.valueAt(i); 19171 // This list does not include stopping users. 19172 if (uss.mState != UserStartedState.STATE_STOPPING 19173 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19174 num++; 19175 } 19176 } 19177 mStartedUserArray = new int[num]; 19178 num = 0; 19179 for (int i=0; i<mStartedUsers.size(); i++) { 19180 UserStartedState uss = mStartedUsers.valueAt(i); 19181 if (uss.mState != UserStartedState.STATE_STOPPING 19182 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19183 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19184 num++; 19185 } 19186 } 19187 } 19188 19189 @Override 19190 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19191 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19192 != PackageManager.PERMISSION_GRANTED) { 19193 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19194 + Binder.getCallingPid() 19195 + ", uid=" + Binder.getCallingUid() 19196 + " requires " + INTERACT_ACROSS_USERS_FULL; 19197 Slog.w(TAG, msg); 19198 throw new SecurityException(msg); 19199 } 19200 19201 mUserSwitchObservers.register(observer); 19202 } 19203 19204 @Override 19205 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19206 mUserSwitchObservers.unregister(observer); 19207 } 19208 19209 private boolean userExists(int userId) { 19210 if (userId == 0) { 19211 return true; 19212 } 19213 UserManagerService ums = getUserManagerLocked(); 19214 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19215 } 19216 19217 int[] getUsersLocked() { 19218 UserManagerService ums = getUserManagerLocked(); 19219 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19220 } 19221 19222 UserManagerService getUserManagerLocked() { 19223 if (mUserManager == null) { 19224 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19225 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19226 } 19227 return mUserManager; 19228 } 19229 19230 private int applyUserId(int uid, int userId) { 19231 return UserHandle.getUid(userId, uid); 19232 } 19233 19234 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19235 if (info == null) return null; 19236 ApplicationInfo newInfo = new ApplicationInfo(info); 19237 newInfo.uid = applyUserId(info.uid, userId); 19238 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19239 + info.packageName; 19240 return newInfo; 19241 } 19242 19243 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19244 if (aInfo == null 19245 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19246 return aInfo; 19247 } 19248 19249 ActivityInfo info = new ActivityInfo(aInfo); 19250 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19251 return info; 19252 } 19253 19254 private final class LocalService extends ActivityManagerInternal { 19255 @Override 19256 public void onWakefulnessChanged(int wakefulness) { 19257 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19258 } 19259 19260 @Override 19261 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19262 String processName, String abiOverride, int uid, Runnable crashHandler) { 19263 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19264 processName, abiOverride, uid, crashHandler); 19265 } 19266 } 19267 19268 /** 19269 * An implementation of IAppTask, that allows an app to manage its own tasks via 19270 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19271 * only the process that calls getAppTasks() can call the AppTask methods. 19272 */ 19273 class AppTaskImpl extends IAppTask.Stub { 19274 private int mTaskId; 19275 private int mCallingUid; 19276 19277 public AppTaskImpl(int taskId, int callingUid) { 19278 mTaskId = taskId; 19279 mCallingUid = callingUid; 19280 } 19281 19282 private void checkCaller() { 19283 if (mCallingUid != Binder.getCallingUid()) { 19284 throw new SecurityException("Caller " + mCallingUid 19285 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19286 } 19287 } 19288 19289 @Override 19290 public void finishAndRemoveTask() { 19291 checkCaller(); 19292 19293 synchronized (ActivityManagerService.this) { 19294 long origId = Binder.clearCallingIdentity(); 19295 try { 19296 if (!removeTaskByIdLocked(mTaskId, false)) { 19297 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19298 } 19299 } finally { 19300 Binder.restoreCallingIdentity(origId); 19301 } 19302 } 19303 } 19304 19305 @Override 19306 public ActivityManager.RecentTaskInfo getTaskInfo() { 19307 checkCaller(); 19308 19309 synchronized (ActivityManagerService.this) { 19310 long origId = Binder.clearCallingIdentity(); 19311 try { 19312 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19313 if (tr == null) { 19314 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19315 } 19316 return createRecentTaskInfoFromTaskRecord(tr); 19317 } finally { 19318 Binder.restoreCallingIdentity(origId); 19319 } 19320 } 19321 } 19322 19323 @Override 19324 public void moveToFront() { 19325 checkCaller(); 19326 19327 final TaskRecord tr; 19328 synchronized (ActivityManagerService.this) { 19329 tr = recentTaskForIdLocked(mTaskId); 19330 if (tr == null) { 19331 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19332 } 19333 if (tr.getRootActivity() != null) { 19334 moveTaskToFrontLocked(tr.taskId, 0, null); 19335 return; 19336 } 19337 } 19338 19339 startActivityFromRecentsInner(tr.taskId, null); 19340 } 19341 19342 @Override 19343 public int startActivity(IBinder whoThread, String callingPackage, 19344 Intent intent, String resolvedType, Bundle options) { 19345 checkCaller(); 19346 19347 int callingUser = UserHandle.getCallingUserId(); 19348 TaskRecord tr; 19349 IApplicationThread appThread; 19350 synchronized (ActivityManagerService.this) { 19351 tr = recentTaskForIdLocked(mTaskId); 19352 if (tr == null) { 19353 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19354 } 19355 appThread = ApplicationThreadNative.asInterface(whoThread); 19356 if (appThread == null) { 19357 throw new IllegalArgumentException("Bad app thread " + appThread); 19358 } 19359 } 19360 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19361 resolvedType, null, null, null, null, 0, 0, null, null, 19362 null, options, callingUser, null, tr); 19363 } 19364 19365 @Override 19366 public void setExcludeFromRecents(boolean exclude) { 19367 checkCaller(); 19368 19369 synchronized (ActivityManagerService.this) { 19370 long origId = Binder.clearCallingIdentity(); 19371 try { 19372 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19373 if (tr == null) { 19374 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19375 } 19376 Intent intent = tr.getBaseIntent(); 19377 if (exclude) { 19378 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19379 } else { 19380 intent.setFlags(intent.getFlags() 19381 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19382 } 19383 } finally { 19384 Binder.restoreCallingIdentity(origId); 19385 } 19386 } 19387 } 19388 } 19389} 19390