1 /* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.am; 18 19 import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23 import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24 import static com.android.internal.util.XmlUtils.readIntAttribute; 25 import static com.android.internal.util.XmlUtils.readLongAttribute; 26 import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27 import static com.android.internal.util.XmlUtils.writeIntAttribute; 28 import static com.android.internal.util.XmlUtils.writeLongAttribute; 29 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31 import static org.xmlpull.v1.XmlPullParser.START_TAG; 32 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 34 35 import android.Manifest; 36 import android.app.AppOpsManager; 37 import android.app.ApplicationThreadNative; 38 import android.app.IActivityContainer; 39 import android.app.IActivityContainerCallback; 40 import android.app.IAppTask; 41 import android.app.ITaskStackListener; 42 import android.app.ProfilerInfo; 43 import android.app.admin.DevicePolicyManager; 44 import android.app.usage.UsageEvents; 45 import android.app.usage.UsageStatsManagerInternal; 46 import android.appwidget.AppWidgetManager; 47 import android.content.res.Resources; 48 import android.graphics.Bitmap; 49 import android.graphics.Point; 50 import android.graphics.Rect; 51 import android.os.BatteryStats; 52 import android.os.PersistableBundle; 53 import android.os.storage.IMountService; 54 import android.os.storage.StorageManager; 55 import android.service.voice.IVoiceInteractionSession; 56 import android.util.ArrayMap; 57 import android.util.ArraySet; 58 import android.util.SparseIntArray; 59 60 import android.view.Display; 61 import com.android.internal.R; 62 import com.android.internal.annotations.GuardedBy; 63 import com.android.internal.app.IAppOpsService; 64 import com.android.internal.app.IVoiceInteractor; 65 import com.android.internal.app.ProcessMap; 66 import com.android.internal.app.ProcessStats; 67 import com.android.internal.os.BackgroundThread; 68 import com.android.internal.os.BatteryStatsImpl; 69 import com.android.internal.os.ProcessCpuTracker; 70 import com.android.internal.os.TransferPipe; 71 import com.android.internal.os.Zygote; 72 import com.android.internal.util.FastPrintWriter; 73 import com.android.internal.util.FastXmlSerializer; 74 import com.android.internal.util.MemInfoReader; 75 import com.android.internal.util.Preconditions; 76 import com.android.server.AppOpsService; 77 import com.android.server.AttributeCache; 78 import com.android.server.IntentResolver; 79 import com.android.server.LocalServices; 80 import com.android.server.ServiceThread; 81 import com.android.server.SystemService; 82 import com.android.server.SystemServiceManager; 83 import com.android.server.Watchdog; 84 import com.android.server.am.ActivityStack.ActivityState; 85 import com.android.server.firewall.IntentFirewall; 86 import com.android.server.pm.Installer; 87 import com.android.server.pm.UserManagerService; 88 import com.android.server.statusbar.StatusBarManagerInternal; 89 import com.android.server.wm.AppTransition; 90 import com.android.server.wm.WindowManagerService; 91 import com.google.android.collect.Lists; 92 import com.google.android.collect.Maps; 93 94 import libcore.io.IoUtils; 95 96 import org.xmlpull.v1.XmlPullParser; 97 import org.xmlpull.v1.XmlPullParserException; 98 import org.xmlpull.v1.XmlSerializer; 99 100 import android.app.Activity; 101 import android.app.ActivityManager; 102 import android.app.ActivityManager.RunningTaskInfo; 103 import android.app.ActivityManager.StackInfo; 104 import android.app.ActivityManagerInternal; 105 import android.app.ActivityManagerNative; 106 import android.app.ActivityOptions; 107 import android.app.ActivityThread; 108 import android.app.AlertDialog; 109 import android.app.AppGlobals; 110 import android.app.ApplicationErrorReport; 111 import android.app.Dialog; 112 import android.app.IActivityController; 113 import android.app.IApplicationThread; 114 import android.app.IInstrumentationWatcher; 115 import android.app.INotificationManager; 116 import android.app.IProcessObserver; 117 import android.app.IServiceConnection; 118 import android.app.IStopUserCallback; 119 import android.app.IUiAutomationConnection; 120 import android.app.IUserSwitchObserver; 121 import android.app.Instrumentation; 122 import android.app.Notification; 123 import android.app.NotificationManager; 124 import android.app.PendingIntent; 125 import android.app.backup.IBackupManager; 126 import android.content.ActivityNotFoundException; 127 import android.content.BroadcastReceiver; 128 import android.content.ClipData; 129 import android.content.ComponentCallbacks2; 130 import android.content.ComponentName; 131 import android.content.ContentProvider; 132 import android.content.ContentResolver; 133 import android.content.Context; 134 import android.content.DialogInterface; 135 import android.content.IContentProvider; 136 import android.content.IIntentReceiver; 137 import android.content.IIntentSender; 138 import android.content.Intent; 139 import android.content.IntentFilter; 140 import android.content.IntentSender; 141 import android.content.pm.ActivityInfo; 142 import android.content.pm.ApplicationInfo; 143 import android.content.pm.ConfigurationInfo; 144 import android.content.pm.IPackageDataObserver; 145 import android.content.pm.IPackageManager; 146 import android.content.pm.InstrumentationInfo; 147 import android.content.pm.PackageInfo; 148 import android.content.pm.PackageManager; 149 import android.content.pm.ParceledListSlice; 150 import android.content.pm.UserInfo; 151 import android.content.pm.PackageManager.NameNotFoundException; 152 import android.content.pm.PathPermission; 153 import android.content.pm.ProviderInfo; 154 import android.content.pm.ResolveInfo; 155 import android.content.pm.ServiceInfo; 156 import android.content.res.CompatibilityInfo; 157 import android.content.res.Configuration; 158 import android.net.Proxy; 159 import android.net.ProxyInfo; 160 import android.net.Uri; 161 import android.os.Binder; 162 import android.os.Build; 163 import android.os.Bundle; 164 import android.os.Debug; 165 import android.os.DropBoxManager; 166 import android.os.Environment; 167 import android.os.FactoryTest; 168 import android.os.FileObserver; 169 import android.os.FileUtils; 170 import android.os.Handler; 171 import android.os.IBinder; 172 import android.os.IPermissionController; 173 import android.os.IRemoteCallback; 174 import android.os.IUserManager; 175 import android.os.Looper; 176 import android.os.Message; 177 import android.os.Parcel; 178 import android.os.ParcelFileDescriptor; 179 import android.os.PowerManagerInternal; 180 import android.os.Process; 181 import android.os.RemoteCallbackList; 182 import android.os.RemoteException; 183 import android.os.SELinux; 184 import android.os.ServiceManager; 185 import android.os.StrictMode; 186 import android.os.SystemClock; 187 import android.os.SystemProperties; 188 import android.os.UpdateLock; 189 import android.os.UserHandle; 190 import android.os.UserManager; 191 import android.provider.Settings; 192 import android.text.format.DateUtils; 193 import android.text.format.Time; 194 import android.util.AtomicFile; 195 import android.util.EventLog; 196 import android.util.Log; 197 import android.util.Pair; 198 import android.util.PrintWriterPrinter; 199 import android.util.Slog; 200 import android.util.SparseArray; 201 import android.util.TimeUtils; 202 import android.util.Xml; 203 import android.view.Gravity; 204 import android.view.LayoutInflater; 205 import android.view.View; 206 import android.view.WindowManager; 207 208 import dalvik.system.VMRuntime; 209 210 import java.io.BufferedInputStream; 211 import java.io.BufferedOutputStream; 212 import java.io.DataInputStream; 213 import java.io.DataOutputStream; 214 import java.io.File; 215 import java.io.FileDescriptor; 216 import java.io.FileInputStream; 217 import java.io.FileNotFoundException; 218 import java.io.FileOutputStream; 219 import java.io.IOException; 220 import java.io.InputStreamReader; 221 import java.io.PrintWriter; 222 import java.io.StringWriter; 223 import java.lang.ref.WeakReference; 224 import java.util.ArrayList; 225 import java.util.Arrays; 226 import java.util.Collections; 227 import java.util.Comparator; 228 import java.util.HashMap; 229 import java.util.HashSet; 230 import java.util.Iterator; 231 import java.util.List; 232 import java.util.Locale; 233 import java.util.Map; 234 import java.util.Set; 235 import java.util.concurrent.atomic.AtomicBoolean; 236 import java.util.concurrent.atomic.AtomicLong; 237 238 public final class ActivityManagerService extends ActivityManagerNative 239 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 240 241 private static final String USER_DATA_DIR = "/data/user/"; 242 // File that stores last updated system version and called preboot receivers 243 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 244 245 static final String TAG = "ActivityManager"; 246 static final String TAG_MU = "ActivityManagerServiceMU"; 247 static final boolean DEBUG = false; 248 static final boolean localLOGV = DEBUG; 249 static final boolean DEBUG_BACKUP = localLOGV || false; 250 static final boolean DEBUG_BROADCAST = localLOGV || false; 251 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 252 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 253 static final boolean DEBUG_CLEANUP = localLOGV || false; 254 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 255 static final boolean DEBUG_FOCUS = false; 256 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 257 static final boolean DEBUG_MU = localLOGV || false; 258 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 259 static final boolean DEBUG_LRU = localLOGV || false; 260 static final boolean DEBUG_PAUSE = localLOGV || false; 261 static final boolean DEBUG_POWER = localLOGV || false; 262 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 263 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 264 static final boolean DEBUG_PROCESSES = localLOGV || false; 265 static final boolean DEBUG_PROVIDER = localLOGV || false; 266 static final boolean DEBUG_RESULTS = localLOGV || false; 267 static final boolean DEBUG_SERVICE = localLOGV || false; 268 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 269 static final boolean DEBUG_STACK = localLOGV || false; 270 static final boolean DEBUG_SWITCH = localLOGV || false; 271 static final boolean DEBUG_TASKS = localLOGV || false; 272 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 273 static final boolean DEBUG_TRANSITION = localLOGV || false; 274 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 275 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 276 static final boolean DEBUG_VISBILITY = localLOGV || false; 277 static final boolean DEBUG_PSS = localLOGV || false; 278 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 279 static final boolean DEBUG_RECENTS = localLOGV || false; 280 static final boolean VALIDATE_TOKENS = false; 281 static final boolean SHOW_ACTIVITY_START_TIME = true; 282 283 // Control over CPU and battery monitoring. 284 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 285 static final boolean MONITOR_CPU_USAGE = true; 286 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 287 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 288 static final boolean MONITOR_THREAD_CPU_USAGE = false; 289 290 // The flags that are set for all calls we make to the package manager. 291 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 292 293 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 294 295 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 296 297 // Maximum number recent bitmaps to keep in memory. 298 static final int MAX_RECENT_BITMAPS = 3; 299 300 // Amount of time after a call to stopAppSwitches() during which we will 301 // prevent further untrusted switches from happening. 302 static final long APP_SWITCH_DELAY_TIME = 5*1000; 303 304 // How long we wait for a launched process to attach to the activity manager 305 // before we decide it's never going to come up for real. 306 static final int PROC_START_TIMEOUT = 10*1000; 307 308 // How long we wait for a launched process to attach to the activity manager 309 // before we decide it's never going to come up for real, when the process was 310 // started with a wrapper for instrumentation (such as Valgrind) because it 311 // could take much longer than usual. 312 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 313 314 // How long to wait after going idle before forcing apps to GC. 315 static final int GC_TIMEOUT = 5*1000; 316 317 // The minimum amount of time between successive GC requests for a process. 318 static final int GC_MIN_INTERVAL = 60*1000; 319 320 // The minimum amount of time between successive PSS requests for a process. 321 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 322 323 // The minimum amount of time between successive PSS requests for a process 324 // when the request is due to the memory state being lowered. 325 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 326 327 // The rate at which we check for apps using excessive power -- 15 mins. 328 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 329 330 // The minimum sample duration we will allow before deciding we have 331 // enough data on wake locks to start killing things. 332 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 333 334 // The minimum sample duration we will allow before deciding we have 335 // enough data on CPU usage to start killing things. 336 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 337 338 // How long we allow a receiver to run before giving up on it. 339 static final int BROADCAST_FG_TIMEOUT = 10*1000; 340 static final int BROADCAST_BG_TIMEOUT = 60*1000; 341 342 // How long we wait until we timeout on key dispatching. 343 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 344 345 // How long we wait until we timeout on key dispatching during instrumentation. 346 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 347 348 // Amount of time we wait for observers to handle a user switch before 349 // giving up on them and unfreezing the screen. 350 static final int USER_SWITCH_TIMEOUT = 2*1000; 351 352 // Maximum number of users we allow to be running at a time. 353 static final int MAX_RUNNING_USERS = 3; 354 355 // How long to wait in getAssistContextExtras for the activity and foreground services 356 // to respond with the result. 357 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 358 359 // Maximum number of persisted Uri grants a package is allowed 360 static final int MAX_PERSISTED_URI_GRANTS = 128; 361 362 static final int MY_PID = Process.myPid(); 363 364 static final String[] EMPTY_STRING_ARRAY = new String[0]; 365 366 // How many bytes to write into the dropbox log before truncating 367 static final int DROPBOX_MAX_SIZE = 256 * 1024; 368 369 // Access modes for handleIncomingUser. 370 static final int ALLOW_NON_FULL = 0; 371 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 372 static final int ALLOW_FULL_ONLY = 2; 373 374 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 375 376 // Delay in notifying task stack change listeners (in millis) 377 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000; 378 379 /** All system services */ 380 SystemServiceManager mSystemServiceManager; 381 382 private Installer mInstaller; 383 384 /** Run all ActivityStacks through this */ 385 ActivityStackSupervisor mStackSupervisor; 386 387 /** Task stack change listeners. */ 388 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = 389 new RemoteCallbackList<ITaskStackListener>(); 390 391 public IntentFirewall mIntentFirewall; 392 393 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 394 // default actuion automatically. Important for devices without direct input 395 // devices. 396 private boolean mShowDialogs = true; 397 398 BroadcastQueue mFgBroadcastQueue; 399 BroadcastQueue mBgBroadcastQueue; 400 // Convenient for easy iteration over the queues. Foreground is first 401 // so that dispatch of foreground broadcasts gets precedence. 402 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 403 broadcastQueueForIntent(Intent intent)404 BroadcastQueue broadcastQueueForIntent(Intent intent) { 405 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 406 if (DEBUG_BACKGROUND_BROADCAST) { 407 Slog.i(TAG, "Broadcast intent " + intent + " on " 408 + (isFg ? "foreground" : "background") 409 + " queue"); 410 } 411 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 412 } 413 broadcastRecordForReceiverLocked(IBinder receiver)414 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 415 for (BroadcastQueue queue : mBroadcastQueues) { 416 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 417 if (r != null) { 418 return r; 419 } 420 } 421 return null; 422 } 423 424 /** 425 * Activity we have told the window manager to have key focus. 426 */ 427 ActivityRecord mFocusedActivity = null; 428 429 /** 430 * List of intents that were used to start the most recent tasks. 431 */ 432 ArrayList<TaskRecord> mRecentTasks; 433 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 434 435 /** 436 * For addAppTask: cached of the last activity component that was added. 437 */ 438 ComponentName mLastAddedTaskComponent; 439 440 /** 441 * For addAppTask: cached of the last activity uid that was added. 442 */ 443 int mLastAddedTaskUid; 444 445 /** 446 * For addAppTask: cached of the last ActivityInfo that was added. 447 */ 448 ActivityInfo mLastAddedTaskActivity; 449 450 public class PendingAssistExtras extends Binder implements Runnable { 451 public final ActivityRecord activity; 452 public final Bundle extras; 453 public final Intent intent; 454 public final String hint; 455 public final int userHandle; 456 public boolean haveResult = false; 457 public Bundle result = null; PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, String _hint, int _userHandle)458 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 459 String _hint, int _userHandle) { 460 activity = _activity; 461 extras = _extras; 462 intent = _intent; 463 hint = _hint; 464 userHandle = _userHandle; 465 } 466 @Override run()467 public void run() { 468 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 469 synchronized (this) { 470 haveResult = true; 471 notifyAll(); 472 } 473 } 474 } 475 476 final ArrayList<PendingAssistExtras> mPendingAssistExtras 477 = new ArrayList<PendingAssistExtras>(); 478 479 /** 480 * Process management. 481 */ 482 final ProcessList mProcessList = new ProcessList(); 483 484 /** 485 * All of the applications we currently have running organized by name. 486 * The keys are strings of the application package name (as 487 * returned by the package manager), and the keys are ApplicationRecord 488 * objects. 489 */ 490 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 491 492 /** 493 * Tracking long-term execution of processes to look for abuse and other 494 * bad app behavior. 495 */ 496 final ProcessStatsService mProcessStats; 497 498 /** 499 * The currently running isolated processes. 500 */ 501 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 502 503 /** 504 * Counter for assigning isolated process uids, to avoid frequently reusing the 505 * same ones. 506 */ 507 int mNextIsolatedProcessUid = 0; 508 509 /** 510 * The currently running heavy-weight process, if any. 511 */ 512 ProcessRecord mHeavyWeightProcess = null; 513 514 /** 515 * The last time that various processes have crashed. 516 */ 517 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 518 519 /** 520 * Information about a process that is currently marked as bad. 521 */ 522 static final class BadProcessInfo { BadProcessInfo(long time, String shortMsg, String longMsg, String stack)523 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 524 this.time = time; 525 this.shortMsg = shortMsg; 526 this.longMsg = longMsg; 527 this.stack = stack; 528 } 529 530 final long time; 531 final String shortMsg; 532 final String longMsg; 533 final String stack; 534 } 535 536 /** 537 * Set of applications that we consider to be bad, and will reject 538 * incoming broadcasts from (which the user has no control over). 539 * Processes are added to this set when they have crashed twice within 540 * a minimum amount of time; they are removed from it when they are 541 * later restarted (hopefully due to some user action). The value is the 542 * time it was added to the list. 543 */ 544 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 545 546 /** 547 * All of the processes we currently have running organized by pid. 548 * The keys are the pid running the application. 549 * 550 * <p>NOTE: This object is protected by its own lock, NOT the global 551 * activity manager lock! 552 */ 553 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 554 555 /** 556 * All of the processes that have been forced to be foreground. The key 557 * is the pid of the caller who requested it (we hold a death 558 * link on it). 559 */ 560 abstract class ForegroundToken implements IBinder.DeathRecipient { 561 int pid; 562 IBinder token; 563 } 564 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 565 566 /** 567 * List of records for processes that someone had tried to start before the 568 * system was ready. We don't start them at that point, but ensure they 569 * are started by the time booting is complete. 570 */ 571 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 572 573 /** 574 * List of persistent applications that are in the process 575 * of being started. 576 */ 577 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Processes that are being forcibly torn down. 581 */ 582 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 583 584 /** 585 * List of running applications, sorted by recent usage. 586 * The first entry in the list is the least recently used. 587 */ 588 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 589 590 /** 591 * Where in mLruProcesses that the processes hosting activities start. 592 */ 593 int mLruProcessActivityStart = 0; 594 595 /** 596 * Where in mLruProcesses that the processes hosting services start. 597 * This is after (lower index) than mLruProcessesActivityStart. 598 */ 599 int mLruProcessServiceStart = 0; 600 601 /** 602 * List of processes that should gc as soon as things are idle. 603 */ 604 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 605 606 /** 607 * Processes we want to collect PSS data from. 608 */ 609 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 610 611 /** 612 * Last time we requested PSS data of all processes. 613 */ 614 long mLastFullPssTime = SystemClock.uptimeMillis(); 615 616 /** 617 * If set, the next time we collect PSS data we should do a full collection 618 * with data from native processes and the kernel. 619 */ 620 boolean mFullPssPending = false; 621 622 /** 623 * This is the process holding what we currently consider to be 624 * the "home" activity. 625 */ 626 ProcessRecord mHomeProcess; 627 628 /** 629 * This is the process holding the activity the user last visited that 630 * is in a different process from the one they are currently in. 631 */ 632 ProcessRecord mPreviousProcess; 633 634 /** 635 * The time at which the previous process was last visible. 636 */ 637 long mPreviousProcessVisibleTime; 638 639 /** 640 * Which uses have been started, so are allowed to run code. 641 */ 642 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 643 644 /** 645 * LRU list of history of current users. Most recently current is at the end. 646 */ 647 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 648 649 /** 650 * Constant array of the users that are currently started. 651 */ 652 int[] mStartedUserArray = new int[] { 0 }; 653 654 /** 655 * Registered observers of the user switching mechanics. 656 */ 657 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 658 = new RemoteCallbackList<IUserSwitchObserver>(); 659 660 /** 661 * Currently active user switch. 662 */ 663 Object mCurUserSwitchCallback; 664 665 /** 666 * Packages that the user has asked to have run in screen size 667 * compatibility mode instead of filling the screen. 668 */ 669 final CompatModePackages mCompatModePackages; 670 671 /** 672 * Set of IntentSenderRecord objects that are currently active. 673 */ 674 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 675 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 676 677 /** 678 * Fingerprints (hashCode()) of stack traces that we've 679 * already logged DropBox entries for. Guarded by itself. If 680 * something (rogue user app) forces this over 681 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 682 */ 683 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 684 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 685 686 /** 687 * Strict Mode background batched logging state. 688 * 689 * The string buffer is guarded by itself, and its lock is also 690 * used to determine if another batched write is already 691 * in-flight. 692 */ 693 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 694 695 /** 696 * Keeps track of all IIntentReceivers that have been registered for 697 * broadcasts. Hash keys are the receiver IBinder, hash value is 698 * a ReceiverList. 699 */ 700 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 701 new HashMap<IBinder, ReceiverList>(); 702 703 /** 704 * Resolver for broadcast intents to registered receivers. 705 * Holds BroadcastFilter (subclass of IntentFilter). 706 */ 707 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 708 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 709 @Override 710 protected boolean allowFilterResult( 711 BroadcastFilter filter, List<BroadcastFilter> dest) { 712 IBinder target = filter.receiverList.receiver.asBinder(); 713 for (int i=dest.size()-1; i>=0; i--) { 714 if (dest.get(i).receiverList.receiver.asBinder() == target) { 715 return false; 716 } 717 } 718 return true; 719 } 720 721 @Override 722 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 723 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 724 || userId == filter.owningUserId) { 725 return super.newResult(filter, match, userId); 726 } 727 return null; 728 } 729 730 @Override 731 protected BroadcastFilter[] newArray(int size) { 732 return new BroadcastFilter[size]; 733 } 734 735 @Override 736 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 737 return packageName.equals(filter.packageName); 738 } 739 }; 740 741 /** 742 * State of all active sticky broadcasts per user. Keys are the action of the 743 * sticky Intent, values are an ArrayList of all broadcasted intents with 744 * that action (which should usually be one). The SparseArray is keyed 745 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 746 * for stickies that are sent to all users. 747 */ 748 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 749 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 750 751 final ActiveServices mServices; 752 753 final static class Association { 754 final int mSourceUid; 755 final String mSourceProcess; 756 final int mTargetUid; 757 final ComponentName mTargetComponent; 758 final String mTargetProcess; 759 760 int mCount; 761 long mTime; 762 763 int mNesting; 764 long mStartTime; 765 Association(int sourceUid, String sourceProcess, int targetUid, ComponentName targetComponent, String targetProcess)766 Association(int sourceUid, String sourceProcess, int targetUid, 767 ComponentName targetComponent, String targetProcess) { 768 mSourceUid = sourceUid; 769 mSourceProcess = sourceProcess; 770 mTargetUid = targetUid; 771 mTargetComponent = targetComponent; 772 mTargetProcess = targetProcess; 773 } 774 } 775 776 /** 777 * When service association tracking is enabled, this is all of the associations we 778 * have seen. Mapping is target uid -> target component -> source uid -> source process name 779 * -> association data. 780 */ 781 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 782 mAssociations = new SparseArray<>(); 783 boolean mTrackingAssociations; 784 785 /** 786 * Backup/restore process management 787 */ 788 String mBackupAppName = null; 789 BackupRecord mBackupTarget = null; 790 791 final ProviderMap mProviderMap; 792 793 /** 794 * List of content providers who have clients waiting for them. The 795 * application is currently being launched and the provider will be 796 * removed from this list once it is published. 797 */ 798 final ArrayList<ContentProviderRecord> mLaunchingProviders 799 = new ArrayList<ContentProviderRecord>(); 800 801 /** 802 * File storing persisted {@link #mGrantedUriPermissions}. 803 */ 804 private final AtomicFile mGrantFile; 805 806 /** XML constants used in {@link #mGrantFile} */ 807 private static final String TAG_URI_GRANTS = "uri-grants"; 808 private static final String TAG_URI_GRANT = "uri-grant"; 809 private static final String ATTR_USER_HANDLE = "userHandle"; 810 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 811 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 812 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 813 private static final String ATTR_TARGET_PKG = "targetPkg"; 814 private static final String ATTR_URI = "uri"; 815 private static final String ATTR_MODE_FLAGS = "modeFlags"; 816 private static final String ATTR_CREATED_TIME = "createdTime"; 817 private static final String ATTR_PREFIX = "prefix"; 818 819 /** 820 * Global set of specific {@link Uri} permissions that have been granted. 821 * This optimized lookup structure maps from {@link UriPermission#targetUid} 822 * to {@link UriPermission#uri} to {@link UriPermission}. 823 */ 824 @GuardedBy("this") 825 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 826 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 827 828 public static class GrantUri { 829 public final int sourceUserId; 830 public final Uri uri; 831 public boolean prefix; 832 GrantUri(int sourceUserId, Uri uri, boolean prefix)833 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 834 this.sourceUserId = sourceUserId; 835 this.uri = uri; 836 this.prefix = prefix; 837 } 838 839 @Override hashCode()840 public int hashCode() { 841 int hashCode = 1; 842 hashCode = 31 * hashCode + sourceUserId; 843 hashCode = 31 * hashCode + uri.hashCode(); 844 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 845 return hashCode; 846 } 847 848 @Override equals(Object o)849 public boolean equals(Object o) { 850 if (o instanceof GrantUri) { 851 GrantUri other = (GrantUri) o; 852 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 853 && prefix == other.prefix; 854 } 855 return false; 856 } 857 858 @Override toString()859 public String toString() { 860 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 861 if (prefix) result += " [prefix]"; 862 return result; 863 } 864 toSafeString()865 public String toSafeString() { 866 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 867 if (prefix) result += " [prefix]"; 868 return result; 869 } 870 resolve(int defaultSourceUserHandle, Uri uri)871 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 872 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 873 ContentProvider.getUriWithoutUserId(uri), false); 874 } 875 } 876 877 CoreSettingsObserver mCoreSettingsObserver; 878 879 /** 880 * Thread-local storage used to carry caller permissions over through 881 * indirect content-provider access. 882 */ 883 private class Identity { 884 public final IBinder token; 885 public final int pid; 886 public final int uid; 887 Identity(IBinder _token, int _pid, int _uid)888 Identity(IBinder _token, int _pid, int _uid) { 889 token = _token; 890 pid = _pid; 891 uid = _uid; 892 } 893 } 894 895 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 896 897 /** 898 * All information we have collected about the runtime performance of 899 * any user id that can impact battery performance. 900 */ 901 final BatteryStatsService mBatteryStatsService; 902 903 /** 904 * Information about component usage 905 */ 906 UsageStatsManagerInternal mUsageStatsService; 907 908 /** 909 * Information about and control over application operations 910 */ 911 final AppOpsService mAppOpsService; 912 913 /** 914 * Save recent tasks information across reboots. 915 */ 916 final TaskPersister mTaskPersister; 917 918 /** 919 * Current configuration information. HistoryRecord objects are given 920 * a reference to this object to indicate which configuration they are 921 * currently running in, so this object must be kept immutable. 922 */ 923 Configuration mConfiguration = new Configuration(); 924 925 /** 926 * Current sequencing integer of the configuration, for skipping old 927 * configurations. 928 */ 929 int mConfigurationSeq = 0; 930 931 /** 932 * Hardware-reported OpenGLES version. 933 */ 934 final int GL_ES_VERSION; 935 936 /** 937 * List of initialization arguments to pass to all processes when binding applications to them. 938 * For example, references to the commonly used services. 939 */ 940 HashMap<String, IBinder> mAppBindArgs; 941 942 /** 943 * Temporary to avoid allocations. Protected by main lock. 944 */ 945 final StringBuilder mStringBuilder = new StringBuilder(256); 946 947 /** 948 * Used to control how we initialize the service. 949 */ 950 ComponentName mTopComponent; 951 String mTopAction = Intent.ACTION_MAIN; 952 String mTopData; 953 boolean mProcessesReady = false; 954 boolean mSystemReady = false; 955 boolean mBooting = false; 956 boolean mCallFinishBooting = false; 957 boolean mBootAnimationComplete = false; 958 boolean mWaitingUpdate = false; 959 boolean mDidUpdate = false; 960 boolean mOnBattery = false; 961 boolean mLaunchWarningShown = false; 962 963 Context mContext; 964 965 int mFactoryTest; 966 967 boolean mCheckedForSetup; 968 969 /** 970 * The time at which we will allow normal application switches again, 971 * after a call to {@link #stopAppSwitches()}. 972 */ 973 long mAppSwitchesAllowedTime; 974 975 /** 976 * This is set to true after the first switch after mAppSwitchesAllowedTime 977 * is set; any switches after that will clear the time. 978 */ 979 boolean mDidAppSwitch; 980 981 /** 982 * Last time (in realtime) at which we checked for power usage. 983 */ 984 long mLastPowerCheckRealtime; 985 986 /** 987 * Last time (in uptime) at which we checked for power usage. 988 */ 989 long mLastPowerCheckUptime; 990 991 /** 992 * Set while we are wanting to sleep, to prevent any 993 * activities from being started/resumed. 994 */ 995 private boolean mSleeping = false; 996 997 /** 998 * Set while we are running a voice interaction. This overrides 999 * sleeping while it is active. 1000 */ 1001 private boolean mRunningVoice = false; 1002 1003 /** 1004 * State of external calls telling us if the device is awake or asleep. 1005 */ 1006 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 1007 1008 static final int LOCK_SCREEN_HIDDEN = 0; 1009 static final int LOCK_SCREEN_LEAVING = 1; 1010 static final int LOCK_SCREEN_SHOWN = 2; 1011 /** 1012 * State of external call telling us if the lock screen is shown. 1013 */ 1014 int mLockScreenShown = LOCK_SCREEN_HIDDEN; 1015 1016 /** 1017 * Set if we are shutting down the system, similar to sleeping. 1018 */ 1019 boolean mShuttingDown = false; 1020 1021 /** 1022 * Current sequence id for oom_adj computation traversal. 1023 */ 1024 int mAdjSeq = 0; 1025 1026 /** 1027 * Current sequence id for process LRU updating. 1028 */ 1029 int mLruSeq = 0; 1030 1031 /** 1032 * Keep track of the non-cached/empty process we last found, to help 1033 * determine how to distribute cached/empty processes next time. 1034 */ 1035 int mNumNonCachedProcs = 0; 1036 1037 /** 1038 * Keep track of the number of cached hidden procs, to balance oom adj 1039 * distribution between those and empty procs. 1040 */ 1041 int mNumCachedHiddenProcs = 0; 1042 1043 /** 1044 * Keep track of the number of service processes we last found, to 1045 * determine on the next iteration which should be B services. 1046 */ 1047 int mNumServiceProcs = 0; 1048 int mNewNumAServiceProcs = 0; 1049 int mNewNumServiceProcs = 0; 1050 1051 /** 1052 * Allow the current computed overall memory level of the system to go down? 1053 * This is set to false when we are killing processes for reasons other than 1054 * memory management, so that the now smaller process list will not be taken as 1055 * an indication that memory is tighter. 1056 */ 1057 boolean mAllowLowerMemLevel = false; 1058 1059 /** 1060 * The last computed memory level, for holding when we are in a state that 1061 * processes are going away for other reasons. 1062 */ 1063 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1064 1065 /** 1066 * The last total number of process we have, to determine if changes actually look 1067 * like a shrinking number of process due to lower RAM. 1068 */ 1069 int mLastNumProcesses; 1070 1071 /** 1072 * The uptime of the last time we performed idle maintenance. 1073 */ 1074 long mLastIdleTime = SystemClock.uptimeMillis(); 1075 1076 /** 1077 * Total time spent with RAM that has been added in the past since the last idle time. 1078 */ 1079 long mLowRamTimeSinceLastIdle = 0; 1080 1081 /** 1082 * If RAM is currently low, when that horrible situation started. 1083 */ 1084 long mLowRamStartTime = 0; 1085 1086 /** 1087 * For reporting to battery stats the current top application. 1088 */ 1089 private String mCurResumedPackage = null; 1090 private int mCurResumedUid = -1; 1091 1092 /** 1093 * For reporting to battery stats the apps currently running foreground 1094 * service. The ProcessMap is package/uid tuples; each of these contain 1095 * an array of the currently foreground processes. 1096 */ 1097 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1098 = new ProcessMap<ArrayList<ProcessRecord>>(); 1099 1100 /** 1101 * This is set if we had to do a delayed dexopt of an app before launching 1102 * it, to increase the ANR timeouts in that case. 1103 */ 1104 boolean mDidDexOpt; 1105 1106 /** 1107 * Set if the systemServer made a call to enterSafeMode. 1108 */ 1109 boolean mSafeMode; 1110 1111 /** 1112 * If true, we are running under a test environment so will sample PSS from processes 1113 * much more rapidly to try to collect better data when the tests are rapidly 1114 * running through apps. 1115 */ 1116 boolean mTestPssMode = false; 1117 1118 String mDebugApp = null; 1119 boolean mWaitForDebugger = false; 1120 boolean mDebugTransient = false; 1121 String mOrigDebugApp = null; 1122 boolean mOrigWaitForDebugger = false; 1123 boolean mAlwaysFinishActivities = false; 1124 IActivityController mController = null; 1125 String mProfileApp = null; 1126 ProcessRecord mProfileProc = null; 1127 String mProfileFile; 1128 ParcelFileDescriptor mProfileFd; 1129 int mSamplingInterval = 0; 1130 boolean mAutoStopProfiler = false; 1131 int mProfileType = 0; 1132 String mOpenGlTraceApp = null; 1133 1134 final long[] mTmpLong = new long[1]; 1135 1136 static class ProcessChangeItem { 1137 static final int CHANGE_ACTIVITIES = 1<<0; 1138 static final int CHANGE_PROCESS_STATE = 1<<1; 1139 int changes; 1140 int uid; 1141 int pid; 1142 int processState; 1143 boolean foregroundActivities; 1144 } 1145 1146 final RemoteCallbackList<IProcessObserver> mProcessObservers 1147 = new RemoteCallbackList<IProcessObserver>(); 1148 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1149 1150 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1151 = new ArrayList<ProcessChangeItem>(); 1152 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1153 = new ArrayList<ProcessChangeItem>(); 1154 1155 /** 1156 * Runtime CPU use collection thread. This object's lock is used to 1157 * perform synchronization with the thread (notifying it to run). 1158 */ 1159 final Thread mProcessCpuThread; 1160 1161 /** 1162 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1163 * Must acquire this object's lock when accessing it. 1164 * NOTE: this lock will be held while doing long operations (trawling 1165 * through all processes in /proc), so it should never be acquired by 1166 * any critical paths such as when holding the main activity manager lock. 1167 */ 1168 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1169 MONITOR_THREAD_CPU_USAGE); 1170 final AtomicLong mLastCpuTime = new AtomicLong(0); 1171 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1172 1173 long mLastWriteTime = 0; 1174 1175 /** 1176 * Used to retain an update lock when the foreground activity is in 1177 * immersive mode. 1178 */ 1179 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1180 1181 /** 1182 * Set to true after the system has finished booting. 1183 */ 1184 boolean mBooted = false; 1185 1186 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1187 int mProcessLimitOverride = -1; 1188 1189 WindowManagerService mWindowManager; 1190 1191 final ActivityThread mSystemThread; 1192 1193 // Holds the current foreground user's id 1194 int mCurrentUserId = 0; 1195 // Holds the target user's id during a user switch 1196 int mTargetUserId = UserHandle.USER_NULL; 1197 // If there are multiple profiles for the current user, their ids are here 1198 // Currently only the primary user can have managed profiles 1199 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1200 1201 /** 1202 * Mapping from each known user ID to the profile group ID it is associated with. 1203 */ 1204 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1205 1206 private UserManagerService mUserManager; 1207 1208 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1209 final ProcessRecord mApp; 1210 final int mPid; 1211 final IApplicationThread mAppThread; 1212 AppDeathRecipient(ProcessRecord app, int pid, IApplicationThread thread)1213 AppDeathRecipient(ProcessRecord app, int pid, 1214 IApplicationThread thread) { 1215 if (localLOGV) Slog.v( 1216 TAG, "New death recipient " + this 1217 + " for thread " + thread.asBinder()); 1218 mApp = app; 1219 mPid = pid; 1220 mAppThread = thread; 1221 } 1222 1223 @Override binderDied()1224 public void binderDied() { 1225 if (localLOGV) Slog.v( 1226 TAG, "Death received in " + this 1227 + " for thread " + mAppThread.asBinder()); 1228 synchronized(ActivityManagerService.this) { 1229 appDiedLocked(mApp, mPid, mAppThread); 1230 } 1231 } 1232 } 1233 1234 static final int SHOW_ERROR_MSG = 1; 1235 static final int SHOW_NOT_RESPONDING_MSG = 2; 1236 static final int SHOW_FACTORY_ERROR_MSG = 3; 1237 static final int UPDATE_CONFIGURATION_MSG = 4; 1238 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1239 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1240 static final int SERVICE_TIMEOUT_MSG = 12; 1241 static final int UPDATE_TIME_ZONE = 13; 1242 static final int SHOW_UID_ERROR_MSG = 14; 1243 static final int SHOW_FINGERPRINT_ERROR_MSG = 15; 1244 static final int PROC_START_TIMEOUT_MSG = 20; 1245 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1246 static final int KILL_APPLICATION_MSG = 22; 1247 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1248 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1249 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1250 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1251 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1252 static final int CLEAR_DNS_CACHE_MSG = 28; 1253 static final int UPDATE_HTTP_PROXY_MSG = 29; 1254 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1255 static final int DISPATCH_PROCESSES_CHANGED = 31; 1256 static final int DISPATCH_PROCESS_DIED = 32; 1257 static final int REPORT_MEM_USAGE_MSG = 33; 1258 static final int REPORT_USER_SWITCH_MSG = 34; 1259 static final int CONTINUE_USER_SWITCH_MSG = 35; 1260 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1261 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1262 static final int PERSIST_URI_GRANTS_MSG = 38; 1263 static final int REQUEST_ALL_PSS_MSG = 39; 1264 static final int START_PROFILES_MSG = 40; 1265 static final int UPDATE_TIME = 41; 1266 static final int SYSTEM_USER_START_MSG = 42; 1267 static final int SYSTEM_USER_CURRENT_MSG = 43; 1268 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1269 static final int FINISH_BOOTING_MSG = 45; 1270 static final int START_USER_SWITCH_MSG = 46; 1271 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1272 static final int DISMISS_DIALOG_MSG = 48; 1273 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49; 1274 1275 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1276 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1277 static final int FIRST_COMPAT_MODE_MSG = 300; 1278 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1279 1280 CompatModeDialog mCompatModeDialog; 1281 long mLastMemUsageReportTime = 0; 1282 1283 /** 1284 * Flag whether the current user is a "monkey", i.e. whether 1285 * the UI is driven by a UI automation tool. 1286 */ 1287 private boolean mUserIsMonkey; 1288 1289 /** Flag whether the device has a Recents UI */ 1290 boolean mHasRecents; 1291 1292 /** The dimensions of the thumbnails in the Recents UI. */ 1293 int mThumbnailWidth; 1294 int mThumbnailHeight; 1295 1296 final ServiceThread mHandlerThread; 1297 final MainHandler mHandler; 1298 1299 final class MainHandler extends Handler { MainHandler(Looper looper)1300 public MainHandler(Looper looper) { 1301 super(looper, null, true); 1302 } 1303 1304 @Override handleMessage(Message msg)1305 public void handleMessage(Message msg) { 1306 switch (msg.what) { 1307 case SHOW_ERROR_MSG: { 1308 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1309 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1310 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1311 synchronized (ActivityManagerService.this) { 1312 ProcessRecord proc = (ProcessRecord)data.get("app"); 1313 AppErrorResult res = (AppErrorResult) data.get("result"); 1314 if (proc != null && proc.crashDialog != null) { 1315 Slog.e(TAG, "App already has crash dialog: " + proc); 1316 if (res != null) { 1317 res.set(0); 1318 } 1319 return; 1320 } 1321 boolean isBackground = (UserHandle.getAppId(proc.uid) 1322 >= Process.FIRST_APPLICATION_UID 1323 && proc.pid != MY_PID); 1324 for (int userId : mCurrentProfileIds) { 1325 isBackground &= (proc.userId != userId); 1326 } 1327 if (isBackground && !showBackground) { 1328 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1329 if (res != null) { 1330 res.set(0); 1331 } 1332 return; 1333 } 1334 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1335 Dialog d = new AppErrorDialog(mContext, 1336 ActivityManagerService.this, res, proc); 1337 d.show(); 1338 proc.crashDialog = d; 1339 } else { 1340 // The device is asleep, so just pretend that the user 1341 // saw a crash dialog and hit "force quit". 1342 if (res != null) { 1343 res.set(0); 1344 } 1345 } 1346 } 1347 1348 ensureBootCompleted(); 1349 } break; 1350 case SHOW_NOT_RESPONDING_MSG: { 1351 synchronized (ActivityManagerService.this) { 1352 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1353 ProcessRecord proc = (ProcessRecord)data.get("app"); 1354 if (proc != null && proc.anrDialog != null) { 1355 Slog.e(TAG, "App already has anr dialog: " + proc); 1356 return; 1357 } 1358 1359 Intent intent = new Intent("android.intent.action.ANR"); 1360 if (!mProcessesReady) { 1361 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1362 | Intent.FLAG_RECEIVER_FOREGROUND); 1363 } 1364 broadcastIntentLocked(null, null, intent, 1365 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1366 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1367 1368 if (mShowDialogs) { 1369 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1370 mContext, proc, (ActivityRecord)data.get("activity"), 1371 msg.arg1 != 0); 1372 d.show(); 1373 proc.anrDialog = d; 1374 } else { 1375 // Just kill the app if there is no dialog to be shown. 1376 killAppAtUsersRequest(proc, null); 1377 } 1378 } 1379 1380 ensureBootCompleted(); 1381 } break; 1382 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1383 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1384 synchronized (ActivityManagerService.this) { 1385 ProcessRecord proc = (ProcessRecord) data.get("app"); 1386 if (proc == null) { 1387 Slog.e(TAG, "App not found when showing strict mode dialog."); 1388 break; 1389 } 1390 if (proc.crashDialog != null) { 1391 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1392 return; 1393 } 1394 AppErrorResult res = (AppErrorResult) data.get("result"); 1395 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1396 Dialog d = new StrictModeViolationDialog(mContext, 1397 ActivityManagerService.this, res, proc); 1398 d.show(); 1399 proc.crashDialog = d; 1400 } else { 1401 // The device is asleep, so just pretend that the user 1402 // saw a crash dialog and hit "force quit". 1403 res.set(0); 1404 } 1405 } 1406 ensureBootCompleted(); 1407 } break; 1408 case SHOW_FACTORY_ERROR_MSG: { 1409 Dialog d = new FactoryErrorDialog( 1410 mContext, msg.getData().getCharSequence("msg")); 1411 d.show(); 1412 ensureBootCompleted(); 1413 } break; 1414 case UPDATE_CONFIGURATION_MSG: { 1415 final ContentResolver resolver = mContext.getContentResolver(); 1416 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1417 } break; 1418 case GC_BACKGROUND_PROCESSES_MSG: { 1419 synchronized (ActivityManagerService.this) { 1420 performAppGcsIfAppropriateLocked(); 1421 } 1422 } break; 1423 case WAIT_FOR_DEBUGGER_MSG: { 1424 synchronized (ActivityManagerService.this) { 1425 ProcessRecord app = (ProcessRecord)msg.obj; 1426 if (msg.arg1 != 0) { 1427 if (!app.waitedForDebugger) { 1428 Dialog d = new AppWaitingForDebuggerDialog( 1429 ActivityManagerService.this, 1430 mContext, app); 1431 app.waitDialog = d; 1432 app.waitedForDebugger = true; 1433 d.show(); 1434 } 1435 } else { 1436 if (app.waitDialog != null) { 1437 app.waitDialog.dismiss(); 1438 app.waitDialog = null; 1439 } 1440 } 1441 } 1442 } break; 1443 case SERVICE_TIMEOUT_MSG: { 1444 if (mDidDexOpt) { 1445 mDidDexOpt = false; 1446 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1447 nmsg.obj = msg.obj; 1448 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1449 return; 1450 } 1451 mServices.serviceTimeout((ProcessRecord)msg.obj); 1452 } break; 1453 case UPDATE_TIME_ZONE: { 1454 synchronized (ActivityManagerService.this) { 1455 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1456 ProcessRecord r = mLruProcesses.get(i); 1457 if (r.thread != null) { 1458 try { 1459 r.thread.updateTimeZone(); 1460 } catch (RemoteException ex) { 1461 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1462 } 1463 } 1464 } 1465 } 1466 } break; 1467 case CLEAR_DNS_CACHE_MSG: { 1468 synchronized (ActivityManagerService.this) { 1469 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1470 ProcessRecord r = mLruProcesses.get(i); 1471 if (r.thread != null) { 1472 try { 1473 r.thread.clearDnsCache(); 1474 } catch (RemoteException ex) { 1475 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1476 } 1477 } 1478 } 1479 } 1480 } break; 1481 case UPDATE_HTTP_PROXY_MSG: { 1482 ProxyInfo proxy = (ProxyInfo)msg.obj; 1483 String host = ""; 1484 String port = ""; 1485 String exclList = ""; 1486 Uri pacFileUrl = Uri.EMPTY; 1487 if (proxy != null) { 1488 host = proxy.getHost(); 1489 port = Integer.toString(proxy.getPort()); 1490 exclList = proxy.getExclusionListAsString(); 1491 pacFileUrl = proxy.getPacFileUrl(); 1492 } 1493 synchronized (ActivityManagerService.this) { 1494 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1495 ProcessRecord r = mLruProcesses.get(i); 1496 if (r.thread != null) { 1497 try { 1498 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1499 } catch (RemoteException ex) { 1500 Slog.w(TAG, "Failed to update http proxy for: " + 1501 r.info.processName); 1502 } 1503 } 1504 } 1505 } 1506 } break; 1507 case SHOW_UID_ERROR_MSG: { 1508 if (mShowDialogs) { 1509 AlertDialog d = new BaseErrorDialog(mContext); 1510 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1511 d.setCancelable(false); 1512 d.setTitle(mContext.getText(R.string.android_system_label)); 1513 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1514 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1515 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1516 d.show(); 1517 } 1518 } break; 1519 case SHOW_FINGERPRINT_ERROR_MSG: { 1520 if (mShowDialogs) { 1521 AlertDialog d = new BaseErrorDialog(mContext); 1522 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1523 d.setCancelable(false); 1524 d.setTitle(mContext.getText(R.string.android_system_label)); 1525 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1526 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1527 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d)); 1528 d.show(); 1529 } 1530 } break; 1531 case PROC_START_TIMEOUT_MSG: { 1532 if (mDidDexOpt) { 1533 mDidDexOpt = false; 1534 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1535 nmsg.obj = msg.obj; 1536 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1537 return; 1538 } 1539 ProcessRecord app = (ProcessRecord)msg.obj; 1540 synchronized (ActivityManagerService.this) { 1541 processStartTimedOutLocked(app); 1542 } 1543 } break; 1544 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1545 synchronized (ActivityManagerService.this) { 1546 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1547 } 1548 } break; 1549 case KILL_APPLICATION_MSG: { 1550 synchronized (ActivityManagerService.this) { 1551 int appid = msg.arg1; 1552 boolean restart = (msg.arg2 == 1); 1553 Bundle bundle = (Bundle)msg.obj; 1554 String pkg = bundle.getString("pkg"); 1555 String reason = bundle.getString("reason"); 1556 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1557 false, UserHandle.USER_ALL, reason); 1558 } 1559 } break; 1560 case FINALIZE_PENDING_INTENT_MSG: { 1561 ((PendingIntentRecord)msg.obj).completeFinalize(); 1562 } break; 1563 case POST_HEAVY_NOTIFICATION_MSG: { 1564 INotificationManager inm = NotificationManager.getService(); 1565 if (inm == null) { 1566 return; 1567 } 1568 1569 ActivityRecord root = (ActivityRecord)msg.obj; 1570 ProcessRecord process = root.app; 1571 if (process == null) { 1572 return; 1573 } 1574 1575 try { 1576 Context context = mContext.createPackageContext(process.info.packageName, 0); 1577 String text = mContext.getString(R.string.heavy_weight_notification, 1578 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1579 Notification notification = new Notification(); 1580 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1581 notification.when = 0; 1582 notification.flags = Notification.FLAG_ONGOING_EVENT; 1583 notification.tickerText = text; 1584 notification.defaults = 0; // please be quiet 1585 notification.sound = null; 1586 notification.vibrate = null; 1587 notification.color = mContext.getResources().getColor( 1588 com.android.internal.R.color.system_notification_accent_color); 1589 notification.setLatestEventInfo(context, text, 1590 mContext.getText(R.string.heavy_weight_notification_detail), 1591 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1592 PendingIntent.FLAG_CANCEL_CURRENT, null, 1593 new UserHandle(root.userId))); 1594 1595 try { 1596 int[] outId = new int[1]; 1597 inm.enqueueNotificationWithTag("android", "android", null, 1598 R.string.heavy_weight_notification, 1599 notification, outId, root.userId); 1600 } catch (RuntimeException e) { 1601 Slog.w(ActivityManagerService.TAG, 1602 "Error showing notification for heavy-weight app", e); 1603 } catch (RemoteException e) { 1604 } 1605 } catch (NameNotFoundException e) { 1606 Slog.w(TAG, "Unable to create context for heavy notification", e); 1607 } 1608 } break; 1609 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1610 INotificationManager inm = NotificationManager.getService(); 1611 if (inm == null) { 1612 return; 1613 } 1614 try { 1615 inm.cancelNotificationWithTag("android", null, 1616 R.string.heavy_weight_notification, msg.arg1); 1617 } catch (RuntimeException e) { 1618 Slog.w(ActivityManagerService.TAG, 1619 "Error canceling notification for service", e); 1620 } catch (RemoteException e) { 1621 } 1622 } break; 1623 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1624 synchronized (ActivityManagerService.this) { 1625 checkExcessivePowerUsageLocked(true); 1626 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1627 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1628 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1629 } 1630 } break; 1631 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1632 synchronized (ActivityManagerService.this) { 1633 ActivityRecord ar = (ActivityRecord)msg.obj; 1634 if (mCompatModeDialog != null) { 1635 if (mCompatModeDialog.mAppInfo.packageName.equals( 1636 ar.info.applicationInfo.packageName)) { 1637 return; 1638 } 1639 mCompatModeDialog.dismiss(); 1640 mCompatModeDialog = null; 1641 } 1642 if (ar != null && false) { 1643 if (mCompatModePackages.getPackageAskCompatModeLocked( 1644 ar.packageName)) { 1645 int mode = mCompatModePackages.computeCompatModeLocked( 1646 ar.info.applicationInfo); 1647 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1648 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1649 mCompatModeDialog = new CompatModeDialog( 1650 ActivityManagerService.this, mContext, 1651 ar.info.applicationInfo); 1652 mCompatModeDialog.show(); 1653 } 1654 } 1655 } 1656 } 1657 break; 1658 } 1659 case DISPATCH_PROCESSES_CHANGED: { 1660 dispatchProcessesChanged(); 1661 break; 1662 } 1663 case DISPATCH_PROCESS_DIED: { 1664 final int pid = msg.arg1; 1665 final int uid = msg.arg2; 1666 dispatchProcessDied(pid, uid); 1667 break; 1668 } 1669 case REPORT_MEM_USAGE_MSG: { 1670 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1671 Thread thread = new Thread() { 1672 @Override public void run() { 1673 reportMemUsage(memInfos); 1674 } 1675 }; 1676 thread.start(); 1677 break; 1678 } 1679 case START_USER_SWITCH_MSG: { 1680 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1681 break; 1682 } 1683 case REPORT_USER_SWITCH_MSG: { 1684 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1685 break; 1686 } 1687 case CONTINUE_USER_SWITCH_MSG: { 1688 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1689 break; 1690 } 1691 case USER_SWITCH_TIMEOUT_MSG: { 1692 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1693 break; 1694 } 1695 case IMMERSIVE_MODE_LOCK_MSG: { 1696 final boolean nextState = (msg.arg1 != 0); 1697 if (mUpdateLock.isHeld() != nextState) { 1698 if (DEBUG_IMMERSIVE) { 1699 final ActivityRecord r = (ActivityRecord) msg.obj; 1700 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1701 } 1702 if (nextState) { 1703 mUpdateLock.acquire(); 1704 } else { 1705 mUpdateLock.release(); 1706 } 1707 } 1708 break; 1709 } 1710 case PERSIST_URI_GRANTS_MSG: { 1711 writeGrantedUriPermissions(); 1712 break; 1713 } 1714 case REQUEST_ALL_PSS_MSG: { 1715 synchronized (ActivityManagerService.this) { 1716 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1717 } 1718 break; 1719 } 1720 case START_PROFILES_MSG: { 1721 synchronized (ActivityManagerService.this) { 1722 startProfilesLocked(); 1723 } 1724 break; 1725 } 1726 case UPDATE_TIME: { 1727 synchronized (ActivityManagerService.this) { 1728 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1729 ProcessRecord r = mLruProcesses.get(i); 1730 if (r.thread != null) { 1731 try { 1732 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1733 } catch (RemoteException ex) { 1734 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1735 } 1736 } 1737 } 1738 } 1739 break; 1740 } 1741 case SYSTEM_USER_START_MSG: { 1742 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1743 Integer.toString(msg.arg1), msg.arg1); 1744 mSystemServiceManager.startUser(msg.arg1); 1745 break; 1746 } 1747 case SYSTEM_USER_CURRENT_MSG: { 1748 mBatteryStatsService.noteEvent( 1749 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1750 Integer.toString(msg.arg2), msg.arg2); 1751 mBatteryStatsService.noteEvent( 1752 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1753 Integer.toString(msg.arg1), msg.arg1); 1754 mSystemServiceManager.switchUser(msg.arg1); 1755 break; 1756 } 1757 case ENTER_ANIMATION_COMPLETE_MSG: { 1758 synchronized (ActivityManagerService.this) { 1759 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1760 if (r != null && r.app != null && r.app.thread != null) { 1761 try { 1762 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1763 } catch (RemoteException e) { 1764 } 1765 } 1766 } 1767 break; 1768 } 1769 case FINISH_BOOTING_MSG: { 1770 if (msg.arg1 != 0) { 1771 finishBooting(); 1772 } 1773 if (msg.arg2 != 0) { 1774 enableScreenAfterBoot(); 1775 } 1776 break; 1777 } 1778 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1779 try { 1780 Locale l = (Locale) msg.obj; 1781 IBinder service = ServiceManager.getService("mount"); 1782 IMountService mountService = IMountService.Stub.asInterface(service); 1783 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1784 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1785 } catch (RemoteException e) { 1786 Log.e(TAG, "Error storing locale for decryption UI", e); 1787 } 1788 break; 1789 } 1790 case DISMISS_DIALOG_MSG: { 1791 final Dialog d = (Dialog) msg.obj; 1792 d.dismiss(); 1793 break; 1794 } 1795 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: { 1796 synchronized (ActivityManagerService.this) { 1797 int i = mTaskStackListeners.beginBroadcast(); 1798 while (i > 0) { 1799 i--; 1800 try { 1801 // Make a one-way callback to the listener 1802 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged(); 1803 } catch (RemoteException e){ 1804 // Handled by the RemoteCallbackList 1805 } 1806 } 1807 mTaskStackListeners.finishBroadcast(); 1808 } 1809 break; 1810 } 1811 } 1812 } 1813 }; 1814 1815 static final int COLLECT_PSS_BG_MSG = 1; 1816 1817 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1818 @Override 1819 public void handleMessage(Message msg) { 1820 switch (msg.what) { 1821 case COLLECT_PSS_BG_MSG: { 1822 long start = SystemClock.uptimeMillis(); 1823 MemInfoReader memInfo = null; 1824 synchronized (ActivityManagerService.this) { 1825 if (mFullPssPending) { 1826 mFullPssPending = false; 1827 memInfo = new MemInfoReader(); 1828 } 1829 } 1830 if (memInfo != null) { 1831 updateCpuStatsNow(); 1832 long nativeTotalPss = 0; 1833 synchronized (mProcessCpuTracker) { 1834 final int N = mProcessCpuTracker.countStats(); 1835 for (int j=0; j<N; j++) { 1836 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1837 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1838 // This is definitely an application process; skip it. 1839 continue; 1840 } 1841 synchronized (mPidsSelfLocked) { 1842 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1843 // This is one of our own processes; skip it. 1844 continue; 1845 } 1846 } 1847 nativeTotalPss += Debug.getPss(st.pid, null, null); 1848 } 1849 } 1850 memInfo.readMemInfo(); 1851 synchronized (ActivityManagerService.this) { 1852 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1853 + (SystemClock.uptimeMillis()-start) + "ms"); 1854 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1855 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1856 memInfo.getKernelUsedSizeKb(), nativeTotalPss); 1857 } 1858 } 1859 1860 int num = 0; 1861 long[] tmp = new long[1]; 1862 do { 1863 ProcessRecord proc; 1864 int procState; 1865 int pid; 1866 long lastPssTime; 1867 synchronized (ActivityManagerService.this) { 1868 if (mPendingPssProcesses.size() <= 0) { 1869 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num 1870 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1871 mPendingPssProcesses.clear(); 1872 return; 1873 } 1874 proc = mPendingPssProcesses.remove(0); 1875 procState = proc.pssProcState; 1876 lastPssTime = proc.lastPssTime; 1877 if (proc.thread != null && procState == proc.setProcState 1878 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 1879 < SystemClock.uptimeMillis()) { 1880 pid = proc.pid; 1881 } else { 1882 proc = null; 1883 pid = 0; 1884 } 1885 } 1886 if (proc != null) { 1887 long pss = Debug.getPss(pid, tmp, null); 1888 synchronized (ActivityManagerService.this) { 1889 if (pss != 0 && proc.thread != null && proc.setProcState == procState 1890 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 1891 num++; 1892 recordPssSample(proc, procState, pss, tmp[0], 1893 SystemClock.uptimeMillis()); 1894 } 1895 } 1896 } 1897 } while (true); 1898 } 1899 } 1900 } 1901 }; 1902 setSystemProcess()1903 public void setSystemProcess() { 1904 try { 1905 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1906 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1907 ServiceManager.addService("meminfo", new MemBinder(this)); 1908 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1909 ServiceManager.addService("dbinfo", new DbBinder(this)); 1910 if (MONITOR_CPU_USAGE) { 1911 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1912 } 1913 ServiceManager.addService("permission", new PermissionController(this)); 1914 1915 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1916 "android", STOCK_PM_FLAGS); 1917 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 1918 1919 synchronized (this) { 1920 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 1921 app.persistent = true; 1922 app.pid = MY_PID; 1923 app.maxAdj = ProcessList.SYSTEM_ADJ; 1924 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1925 mProcessNames.put(app.processName, app.uid, app); 1926 synchronized (mPidsSelfLocked) { 1927 mPidsSelfLocked.put(app.pid, app); 1928 } 1929 updateLruProcessLocked(app, false, null); 1930 updateOomAdjLocked(); 1931 } 1932 } catch (PackageManager.NameNotFoundException e) { 1933 throw new RuntimeException( 1934 "Unable to find android system package", e); 1935 } 1936 } 1937 setWindowManager(WindowManagerService wm)1938 public void setWindowManager(WindowManagerService wm) { 1939 mWindowManager = wm; 1940 mStackSupervisor.setWindowManager(wm); 1941 } 1942 setUsageStatsManager(UsageStatsManagerInternal usageStatsManager)1943 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1944 mUsageStatsService = usageStatsManager; 1945 } 1946 startObservingNativeCrashes()1947 public void startObservingNativeCrashes() { 1948 final NativeCrashListener ncl = new NativeCrashListener(this); 1949 ncl.start(); 1950 } 1951 getAppOpsService()1952 public IAppOpsService getAppOpsService() { 1953 return mAppOpsService; 1954 } 1955 1956 static class MemBinder extends Binder { 1957 ActivityManagerService mActivityManagerService; MemBinder(ActivityManagerService activityManagerService)1958 MemBinder(ActivityManagerService activityManagerService) { 1959 mActivityManagerService = activityManagerService; 1960 } 1961 1962 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1963 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1964 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1965 != PackageManager.PERMISSION_GRANTED) { 1966 pw.println("Permission Denial: can't dump meminfo from from pid=" 1967 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1968 + " without permission " + android.Manifest.permission.DUMP); 1969 return; 1970 } 1971 1972 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1973 } 1974 } 1975 1976 static class GraphicsBinder extends Binder { 1977 ActivityManagerService mActivityManagerService; GraphicsBinder(ActivityManagerService activityManagerService)1978 GraphicsBinder(ActivityManagerService activityManagerService) { 1979 mActivityManagerService = activityManagerService; 1980 } 1981 1982 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1983 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1984 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1985 != PackageManager.PERMISSION_GRANTED) { 1986 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1987 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1988 + " without permission " + android.Manifest.permission.DUMP); 1989 return; 1990 } 1991 1992 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1993 } 1994 } 1995 1996 static class DbBinder extends Binder { 1997 ActivityManagerService mActivityManagerService; DbBinder(ActivityManagerService activityManagerService)1998 DbBinder(ActivityManagerService activityManagerService) { 1999 mActivityManagerService = activityManagerService; 2000 } 2001 2002 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)2003 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2004 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2005 != PackageManager.PERMISSION_GRANTED) { 2006 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2007 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2008 + " without permission " + android.Manifest.permission.DUMP); 2009 return; 2010 } 2011 2012 mActivityManagerService.dumpDbInfo(fd, pw, args); 2013 } 2014 } 2015 2016 static class CpuBinder extends Binder { 2017 ActivityManagerService mActivityManagerService; CpuBinder(ActivityManagerService activityManagerService)2018 CpuBinder(ActivityManagerService activityManagerService) { 2019 mActivityManagerService = activityManagerService; 2020 } 2021 2022 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)2023 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2024 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2025 != PackageManager.PERMISSION_GRANTED) { 2026 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2027 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2028 + " without permission " + android.Manifest.permission.DUMP); 2029 return; 2030 } 2031 2032 synchronized (mActivityManagerService.mProcessCpuTracker) { 2033 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2034 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2035 SystemClock.uptimeMillis())); 2036 } 2037 } 2038 } 2039 2040 public static final class Lifecycle extends SystemService { 2041 private final ActivityManagerService mService; 2042 Lifecycle(Context context)2043 public Lifecycle(Context context) { 2044 super(context); 2045 mService = new ActivityManagerService(context); 2046 } 2047 2048 @Override onStart()2049 public void onStart() { 2050 mService.start(); 2051 } 2052 getService()2053 public ActivityManagerService getService() { 2054 return mService; 2055 } 2056 } 2057 2058 // Note: This method is invoked on the main thread but may need to attach various 2059 // handlers to other threads. So take care to be explicit about the looper. ActivityManagerService(Context systemContext)2060 public ActivityManagerService(Context systemContext) { 2061 mContext = systemContext; 2062 mFactoryTest = FactoryTest.getMode(); 2063 mSystemThread = ActivityThread.currentActivityThread(); 2064 2065 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2066 2067 mHandlerThread = new ServiceThread(TAG, 2068 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2069 mHandlerThread.start(); 2070 mHandler = new MainHandler(mHandlerThread.getLooper()); 2071 2072 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2073 "foreground", BROADCAST_FG_TIMEOUT, false); 2074 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2075 "background", BROADCAST_BG_TIMEOUT, true); 2076 mBroadcastQueues[0] = mFgBroadcastQueue; 2077 mBroadcastQueues[1] = mBgBroadcastQueue; 2078 2079 mServices = new ActiveServices(this); 2080 mProviderMap = new ProviderMap(this); 2081 2082 // TODO: Move creation of battery stats service outside of activity manager service. 2083 File dataDir = Environment.getDataDirectory(); 2084 File systemDir = new File(dataDir, "system"); 2085 systemDir.mkdirs(); 2086 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2087 mBatteryStatsService.getActiveStatistics().readLocked(); 2088 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2089 mOnBattery = DEBUG_POWER ? true 2090 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2091 mBatteryStatsService.getActiveStatistics().setCallback(this); 2092 2093 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2094 2095 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2096 2097 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2098 2099 // User 0 is the first and only user that runs at boot. 2100 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2101 mUserLru.add(Integer.valueOf(0)); 2102 updateStartedUserArrayLocked(); 2103 2104 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2105 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2106 2107 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2108 2109 mConfiguration.setToDefaults(); 2110 mConfiguration.locale = Locale.getDefault(); 2111 2112 mConfigurationSeq = mConfiguration.seq = 1; 2113 mProcessCpuTracker.init(); 2114 2115 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2116 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2117 mStackSupervisor = new ActivityStackSupervisor(this); 2118 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2119 2120 mProcessCpuThread = new Thread("CpuTracker") { 2121 @Override 2122 public void run() { 2123 while (true) { 2124 try { 2125 try { 2126 synchronized(this) { 2127 final long now = SystemClock.uptimeMillis(); 2128 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2129 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2130 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2131 // + ", write delay=" + nextWriteDelay); 2132 if (nextWriteDelay < nextCpuDelay) { 2133 nextCpuDelay = nextWriteDelay; 2134 } 2135 if (nextCpuDelay > 0) { 2136 mProcessCpuMutexFree.set(true); 2137 this.wait(nextCpuDelay); 2138 } 2139 } 2140 } catch (InterruptedException e) { 2141 } 2142 updateCpuStatsNow(); 2143 } catch (Exception e) { 2144 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2145 } 2146 } 2147 } 2148 }; 2149 2150 Watchdog.getInstance().addMonitor(this); 2151 Watchdog.getInstance().addThread(mHandler); 2152 } 2153 setSystemServiceManager(SystemServiceManager mgr)2154 public void setSystemServiceManager(SystemServiceManager mgr) { 2155 mSystemServiceManager = mgr; 2156 } 2157 setInstaller(Installer installer)2158 public void setInstaller(Installer installer) { 2159 mInstaller = installer; 2160 } 2161 start()2162 private void start() { 2163 Process.removeAllProcessGroups(); 2164 mProcessCpuThread.start(); 2165 2166 mBatteryStatsService.publish(mContext); 2167 mAppOpsService.publish(mContext); 2168 Slog.d("AppOps", "AppOpsService published"); 2169 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2170 } 2171 initPowerManagement()2172 public void initPowerManagement() { 2173 mStackSupervisor.initPowerManagement(); 2174 mBatteryStatsService.initPowerManagement(); 2175 } 2176 2177 @Override onTransact(int code, Parcel data, Parcel reply, int flags)2178 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2179 throws RemoteException { 2180 if (code == SYSPROPS_TRANSACTION) { 2181 // We need to tell all apps about the system property change. 2182 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2183 synchronized(this) { 2184 final int NP = mProcessNames.getMap().size(); 2185 for (int ip=0; ip<NP; ip++) { 2186 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2187 final int NA = apps.size(); 2188 for (int ia=0; ia<NA; ia++) { 2189 ProcessRecord app = apps.valueAt(ia); 2190 if (app.thread != null) { 2191 procs.add(app.thread.asBinder()); 2192 } 2193 } 2194 } 2195 } 2196 2197 int N = procs.size(); 2198 for (int i=0; i<N; i++) { 2199 Parcel data2 = Parcel.obtain(); 2200 try { 2201 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2202 } catch (RemoteException e) { 2203 } 2204 data2.recycle(); 2205 } 2206 } 2207 try { 2208 return super.onTransact(code, data, reply, flags); 2209 } catch (RuntimeException e) { 2210 // The activity manager only throws security exceptions, so let's 2211 // log all others. 2212 if (!(e instanceof SecurityException)) { 2213 Slog.wtf(TAG, "Activity Manager Crash", e); 2214 } 2215 throw e; 2216 } 2217 } 2218 updateCpuStats()2219 void updateCpuStats() { 2220 final long now = SystemClock.uptimeMillis(); 2221 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2222 return; 2223 } 2224 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2225 synchronized (mProcessCpuThread) { 2226 mProcessCpuThread.notify(); 2227 } 2228 } 2229 } 2230 updateCpuStatsNow()2231 void updateCpuStatsNow() { 2232 synchronized (mProcessCpuTracker) { 2233 mProcessCpuMutexFree.set(false); 2234 final long now = SystemClock.uptimeMillis(); 2235 boolean haveNewCpuStats = false; 2236 2237 if (MONITOR_CPU_USAGE && 2238 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2239 mLastCpuTime.set(now); 2240 haveNewCpuStats = true; 2241 mProcessCpuTracker.update(); 2242 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2243 //Slog.i(TAG, "Total CPU usage: " 2244 // + mProcessCpu.getTotalCpuPercent() + "%"); 2245 2246 // Slog the cpu usage if the property is set. 2247 if ("true".equals(SystemProperties.get("events.cpu"))) { 2248 int user = mProcessCpuTracker.getLastUserTime(); 2249 int system = mProcessCpuTracker.getLastSystemTime(); 2250 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2251 int irq = mProcessCpuTracker.getLastIrqTime(); 2252 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2253 int idle = mProcessCpuTracker.getLastIdleTime(); 2254 2255 int total = user + system + iowait + irq + softIrq + idle; 2256 if (total == 0) total = 1; 2257 2258 EventLog.writeEvent(EventLogTags.CPU, 2259 ((user+system+iowait+irq+softIrq) * 100) / total, 2260 (user * 100) / total, 2261 (system * 100) / total, 2262 (iowait * 100) / total, 2263 (irq * 100) / total, 2264 (softIrq * 100) / total); 2265 } 2266 } 2267 2268 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2269 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2270 synchronized(bstats) { 2271 synchronized(mPidsSelfLocked) { 2272 if (haveNewCpuStats) { 2273 if (mOnBattery) { 2274 int perc = bstats.startAddingCpuLocked(); 2275 int totalUTime = 0; 2276 int totalSTime = 0; 2277 final int N = mProcessCpuTracker.countStats(); 2278 for (int i=0; i<N; i++) { 2279 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2280 if (!st.working) { 2281 continue; 2282 } 2283 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2284 int otherUTime = (st.rel_utime*perc)/100; 2285 int otherSTime = (st.rel_stime*perc)/100; 2286 totalUTime += otherUTime; 2287 totalSTime += otherSTime; 2288 if (pr != null) { 2289 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2290 if (ps == null || !ps.isActive()) { 2291 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2292 pr.info.uid, pr.processName); 2293 } 2294 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2295 st.rel_stime-otherSTime); 2296 ps.addSpeedStepTimes(cpuSpeedTimes); 2297 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2298 } else { 2299 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2300 if (ps == null || !ps.isActive()) { 2301 st.batteryStats = ps = bstats.getProcessStatsLocked( 2302 bstats.mapUid(st.uid), st.name); 2303 } 2304 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2305 st.rel_stime-otherSTime); 2306 ps.addSpeedStepTimes(cpuSpeedTimes); 2307 } 2308 } 2309 bstats.finishAddingCpuLocked(perc, totalUTime, 2310 totalSTime, cpuSpeedTimes); 2311 } 2312 } 2313 } 2314 2315 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2316 mLastWriteTime = now; 2317 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2318 } 2319 } 2320 } 2321 } 2322 2323 @Override batteryNeedsCpuUpdate()2324 public void batteryNeedsCpuUpdate() { 2325 updateCpuStatsNow(); 2326 } 2327 2328 @Override batteryPowerChanged(boolean onBattery)2329 public void batteryPowerChanged(boolean onBattery) { 2330 // When plugging in, update the CPU stats first before changing 2331 // the plug state. 2332 updateCpuStatsNow(); 2333 synchronized (this) { 2334 synchronized(mPidsSelfLocked) { 2335 mOnBattery = DEBUG_POWER ? true : onBattery; 2336 } 2337 } 2338 } 2339 2340 /** 2341 * Initialize the application bind args. These are passed to each 2342 * process when the bindApplication() IPC is sent to the process. They're 2343 * lazily setup to make sure the services are running when they're asked for. 2344 */ getCommonServicesLocked(boolean isolated)2345 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 2346 if (mAppBindArgs == null) { 2347 mAppBindArgs = new HashMap<>(); 2348 2349 // Isolated processes won't get this optimization, so that we don't 2350 // violate the rules about which services they have access to. 2351 if (!isolated) { 2352 // Setup the application init args 2353 mAppBindArgs.put("package", ServiceManager.getService("package")); 2354 mAppBindArgs.put("window", ServiceManager.getService("window")); 2355 mAppBindArgs.put(Context.ALARM_SERVICE, 2356 ServiceManager.getService(Context.ALARM_SERVICE)); 2357 } 2358 } 2359 return mAppBindArgs; 2360 } 2361 setFocusedActivityLocked(ActivityRecord r, String reason)2362 final void setFocusedActivityLocked(ActivityRecord r, String reason) { 2363 if (mFocusedActivity != r) { 2364 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2365 mFocusedActivity = r; 2366 if (r.task != null && r.task.voiceInteractor != null) { 2367 startRunningVoiceLocked(); 2368 } else { 2369 finishRunningVoiceLocked(); 2370 } 2371 mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity"); 2372 if (r != null) { 2373 mWindowManager.setFocusedApp(r.appToken, true); 2374 } 2375 applyUpdateLockStateLocked(r); 2376 } 2377 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId, 2378 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName); 2379 } 2380 clearFocusedActivity(ActivityRecord r)2381 final void clearFocusedActivity(ActivityRecord r) { 2382 if (mFocusedActivity == r) { 2383 mFocusedActivity = null; 2384 } 2385 } 2386 2387 @Override setFocusedStack(int stackId)2388 public void setFocusedStack(int stackId) { 2389 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2390 synchronized (ActivityManagerService.this) { 2391 ActivityStack stack = mStackSupervisor.getStack(stackId); 2392 if (stack != null) { 2393 ActivityRecord r = stack.topRunningActivityLocked(null); 2394 if (r != null) { 2395 setFocusedActivityLocked(r, "setFocusedStack"); 2396 } 2397 } 2398 } 2399 } 2400 2401 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 2402 @Override registerTaskStackListener(ITaskStackListener listener)2403 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 2404 synchronized (ActivityManagerService.this) { 2405 if (listener != null) { 2406 mTaskStackListeners.register(listener); 2407 } 2408 } 2409 } 2410 2411 @Override notifyActivityDrawn(IBinder token)2412 public void notifyActivityDrawn(IBinder token) { 2413 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2414 synchronized (this) { 2415 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2416 if (r != null) { 2417 r.task.stack.notifyActivityDrawnLocked(r); 2418 } 2419 } 2420 } 2421 applyUpdateLockStateLocked(ActivityRecord r)2422 final void applyUpdateLockStateLocked(ActivityRecord r) { 2423 // Modifications to the UpdateLock state are done on our handler, outside 2424 // the activity manager's locks. The new state is determined based on the 2425 // state *now* of the relevant activity record. The object is passed to 2426 // the handler solely for logging detail, not to be consulted/modified. 2427 final boolean nextState = r != null && r.immersive; 2428 mHandler.sendMessage( 2429 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2430 } 2431 showAskCompatModeDialogLocked(ActivityRecord r)2432 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2433 Message msg = Message.obtain(); 2434 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2435 msg.obj = r.task.askedCompatMode ? null : r; 2436 mHandler.sendMessage(msg); 2437 } 2438 updateLruProcessInternalLocked(ProcessRecord app, long now, int index, String what, Object obj, ProcessRecord srcApp)2439 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2440 String what, Object obj, ProcessRecord srcApp) { 2441 app.lastActivityTime = now; 2442 2443 if (app.activities.size() > 0) { 2444 // Don't want to touch dependent processes that are hosting activities. 2445 return index; 2446 } 2447 2448 int lrui = mLruProcesses.lastIndexOf(app); 2449 if (lrui < 0) { 2450 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2451 + what + " " + obj + " from " + srcApp); 2452 return index; 2453 } 2454 2455 if (lrui >= index) { 2456 // Don't want to cause this to move dependent processes *back* in the 2457 // list as if they were less frequently used. 2458 return index; 2459 } 2460 2461 if (lrui >= mLruProcessActivityStart) { 2462 // Don't want to touch dependent processes that are hosting activities. 2463 return index; 2464 } 2465 2466 mLruProcesses.remove(lrui); 2467 if (index > 0) { 2468 index--; 2469 } 2470 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2471 + " in LRU list: " + app); 2472 mLruProcesses.add(index, app); 2473 return index; 2474 } 2475 removeLruProcessLocked(ProcessRecord app)2476 final void removeLruProcessLocked(ProcessRecord app) { 2477 int lrui = mLruProcesses.lastIndexOf(app); 2478 if (lrui >= 0) { 2479 if (!app.killed) { 2480 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2481 Process.killProcessQuiet(app.pid); 2482 Process.killProcessGroup(app.info.uid, app.pid); 2483 } 2484 if (lrui <= mLruProcessActivityStart) { 2485 mLruProcessActivityStart--; 2486 } 2487 if (lrui <= mLruProcessServiceStart) { 2488 mLruProcessServiceStart--; 2489 } 2490 mLruProcesses.remove(lrui); 2491 } 2492 } 2493 updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client)2494 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2495 ProcessRecord client) { 2496 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2497 || app.treatLikeActivity; 2498 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2499 if (!activityChange && hasActivity) { 2500 // The process has activities, so we are only allowing activity-based adjustments 2501 // to move it. It should be kept in the front of the list with other 2502 // processes that have activities, and we don't want those to change their 2503 // order except due to activity operations. 2504 return; 2505 } 2506 2507 mLruSeq++; 2508 final long now = SystemClock.uptimeMillis(); 2509 app.lastActivityTime = now; 2510 2511 // First a quick reject: if the app is already at the position we will 2512 // put it, then there is nothing to do. 2513 if (hasActivity) { 2514 final int N = mLruProcesses.size(); 2515 if (N > 0 && mLruProcesses.get(N-1) == app) { 2516 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2517 return; 2518 } 2519 } else { 2520 if (mLruProcessServiceStart > 0 2521 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2522 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2523 return; 2524 } 2525 } 2526 2527 int lrui = mLruProcesses.lastIndexOf(app); 2528 2529 if (app.persistent && lrui >= 0) { 2530 // We don't care about the position of persistent processes, as long as 2531 // they are in the list. 2532 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2533 return; 2534 } 2535 2536 /* In progress: compute new position first, so we can avoid doing work 2537 if the process is not actually going to move. Not yet working. 2538 int addIndex; 2539 int nextIndex; 2540 boolean inActivity = false, inService = false; 2541 if (hasActivity) { 2542 // Process has activities, put it at the very tipsy-top. 2543 addIndex = mLruProcesses.size(); 2544 nextIndex = mLruProcessServiceStart; 2545 inActivity = true; 2546 } else if (hasService) { 2547 // Process has services, put it at the top of the service list. 2548 addIndex = mLruProcessActivityStart; 2549 nextIndex = mLruProcessServiceStart; 2550 inActivity = true; 2551 inService = true; 2552 } else { 2553 // Process not otherwise of interest, it goes to the top of the non-service area. 2554 addIndex = mLruProcessServiceStart; 2555 if (client != null) { 2556 int clientIndex = mLruProcesses.lastIndexOf(client); 2557 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2558 + app); 2559 if (clientIndex >= 0 && addIndex > clientIndex) { 2560 addIndex = clientIndex; 2561 } 2562 } 2563 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2564 } 2565 2566 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2567 + mLruProcessActivityStart + "): " + app); 2568 */ 2569 2570 if (lrui >= 0) { 2571 if (lrui < mLruProcessActivityStart) { 2572 mLruProcessActivityStart--; 2573 } 2574 if (lrui < mLruProcessServiceStart) { 2575 mLruProcessServiceStart--; 2576 } 2577 /* 2578 if (addIndex > lrui) { 2579 addIndex--; 2580 } 2581 if (nextIndex > lrui) { 2582 nextIndex--; 2583 } 2584 */ 2585 mLruProcesses.remove(lrui); 2586 } 2587 2588 /* 2589 mLruProcesses.add(addIndex, app); 2590 if (inActivity) { 2591 mLruProcessActivityStart++; 2592 } 2593 if (inService) { 2594 mLruProcessActivityStart++; 2595 } 2596 */ 2597 2598 int nextIndex; 2599 if (hasActivity) { 2600 final int N = mLruProcesses.size(); 2601 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2602 // Process doesn't have activities, but has clients with 2603 // activities... move it up, but one below the top (the top 2604 // should always have a real activity). 2605 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2606 mLruProcesses.add(N-1, app); 2607 // To keep it from spamming the LRU list (by making a bunch of clients), 2608 // we will push down any other entries owned by the app. 2609 final int uid = app.info.uid; 2610 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2611 ProcessRecord subProc = mLruProcesses.get(i); 2612 if (subProc.info.uid == uid) { 2613 // We want to push this one down the list. If the process after 2614 // it is for the same uid, however, don't do so, because we don't 2615 // want them internally to be re-ordered. 2616 if (mLruProcesses.get(i-1).info.uid != uid) { 2617 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2618 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2619 ProcessRecord tmp = mLruProcesses.get(i); 2620 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2621 mLruProcesses.set(i-1, tmp); 2622 i--; 2623 } 2624 } else { 2625 // A gap, we can stop here. 2626 break; 2627 } 2628 } 2629 } else { 2630 // Process has activities, put it at the very tipsy-top. 2631 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2632 mLruProcesses.add(app); 2633 } 2634 nextIndex = mLruProcessServiceStart; 2635 } else if (hasService) { 2636 // Process has services, put it at the top of the service list. 2637 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2638 mLruProcesses.add(mLruProcessActivityStart, app); 2639 nextIndex = mLruProcessServiceStart; 2640 mLruProcessActivityStart++; 2641 } else { 2642 // Process not otherwise of interest, it goes to the top of the non-service area. 2643 int index = mLruProcessServiceStart; 2644 if (client != null) { 2645 // If there is a client, don't allow the process to be moved up higher 2646 // in the list than that client. 2647 int clientIndex = mLruProcesses.lastIndexOf(client); 2648 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2649 + " when updating " + app); 2650 if (clientIndex <= lrui) { 2651 // Don't allow the client index restriction to push it down farther in the 2652 // list than it already is. 2653 clientIndex = lrui; 2654 } 2655 if (clientIndex >= 0 && index > clientIndex) { 2656 index = clientIndex; 2657 } 2658 } 2659 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2660 mLruProcesses.add(index, app); 2661 nextIndex = index-1; 2662 mLruProcessActivityStart++; 2663 mLruProcessServiceStart++; 2664 } 2665 2666 // If the app is currently using a content provider or service, 2667 // bump those processes as well. 2668 for (int j=app.connections.size()-1; j>=0; j--) { 2669 ConnectionRecord cr = app.connections.valueAt(j); 2670 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2671 && cr.binding.service.app != null 2672 && cr.binding.service.app.lruSeq != mLruSeq 2673 && !cr.binding.service.app.persistent) { 2674 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2675 "service connection", cr, app); 2676 } 2677 } 2678 for (int j=app.conProviders.size()-1; j>=0; j--) { 2679 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2680 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2681 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2682 "provider reference", cpr, app); 2683 } 2684 } 2685 } 2686 getProcessRecordLocked(String processName, int uid, boolean keepIfLarge)2687 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2688 if (uid == Process.SYSTEM_UID) { 2689 // The system gets to run in any process. If there are multiple 2690 // processes with the same uid, just pick the first (this 2691 // should never happen). 2692 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2693 if (procs == null) return null; 2694 final int N = procs.size(); 2695 for (int i = 0; i < N; i++) { 2696 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2697 } 2698 } 2699 ProcessRecord proc = mProcessNames.get(processName, uid); 2700 if (false && proc != null && !keepIfLarge 2701 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2702 && proc.lastCachedPss >= 4000) { 2703 // Turn this condition on to cause killing to happen regularly, for testing. 2704 if (proc.baseProcessTracker != null) { 2705 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2706 } 2707 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2708 } else if (proc != null && !keepIfLarge 2709 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2710 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2711 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2712 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2713 if (proc.baseProcessTracker != null) { 2714 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2715 } 2716 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2717 } 2718 } 2719 return proc; 2720 } 2721 ensurePackageDexOpt(String packageName)2722 void ensurePackageDexOpt(String packageName) { 2723 IPackageManager pm = AppGlobals.getPackageManager(); 2724 try { 2725 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2726 mDidDexOpt = true; 2727 } 2728 } catch (RemoteException e) { 2729 } 2730 } 2731 isNextTransitionForward()2732 boolean isNextTransitionForward() { 2733 int transit = mWindowManager.getPendingAppTransition(); 2734 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2735 || transit == AppTransition.TRANSIT_TASK_OPEN 2736 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2737 } 2738 startIsolatedProcess(String entryPoint, String[] entryPointArgs, String processName, String abiOverride, int uid, Runnable crashHandler)2739 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2740 String processName, String abiOverride, int uid, Runnable crashHandler) { 2741 synchronized(this) { 2742 ApplicationInfo info = new ApplicationInfo(); 2743 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2744 // For isolated processes, the former contains the parent's uid and the latter the 2745 // actual uid of the isolated process. 2746 // In the special case introduced by this method (which is, starting an isolated 2747 // process directly from the SystemServer without an actual parent app process) the 2748 // closest thing to a parent's uid is SYSTEM_UID. 2749 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2750 // the |isolated| logic in the ProcessRecord constructor. 2751 info.uid = Process.SYSTEM_UID; 2752 info.processName = processName; 2753 info.className = entryPoint; 2754 info.packageName = "android"; 2755 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2756 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2757 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2758 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2759 crashHandler); 2760 return proc != null ? proc.pid : 0; 2761 } 2762 } 2763 startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, boolean keepIfLarge)2764 final ProcessRecord startProcessLocked(String processName, 2765 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2766 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2767 boolean isolated, boolean keepIfLarge) { 2768 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2769 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2770 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2771 null /* crashHandler */); 2772 } 2773 startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler)2774 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2775 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2776 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2777 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2778 long startTime = SystemClock.elapsedRealtime(); 2779 ProcessRecord app; 2780 if (!isolated) { 2781 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2782 checkTime(startTime, "startProcess: after getProcessRecord"); 2783 } else { 2784 // If this is an isolated process, it can't re-use an existing process. 2785 app = null; 2786 } 2787 // We don't have to do anything more if: 2788 // (1) There is an existing application record; and 2789 // (2) The caller doesn't think it is dead, OR there is no thread 2790 // object attached to it so we know it couldn't have crashed; and 2791 // (3) There is a pid assigned to it, so it is either starting or 2792 // already running. 2793 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2794 + " app=" + app + " knownToBeDead=" + knownToBeDead 2795 + " thread=" + (app != null ? app.thread : null) 2796 + " pid=" + (app != null ? app.pid : -1)); 2797 if (app != null && app.pid > 0) { 2798 if (!knownToBeDead || app.thread == null) { 2799 // We already have the app running, or are waiting for it to 2800 // come up (we have a pid but not yet its thread), so keep it. 2801 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2802 // If this is a new package in the process, add the package to the list 2803 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2804 checkTime(startTime, "startProcess: done, added package to proc"); 2805 return app; 2806 } 2807 2808 // An application record is attached to a previous process, 2809 // clean it up now. 2810 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2811 checkTime(startTime, "startProcess: bad proc running, killing"); 2812 Process.killProcessGroup(app.info.uid, app.pid); 2813 handleAppDiedLocked(app, true, true); 2814 checkTime(startTime, "startProcess: done killing old proc"); 2815 } 2816 2817 String hostingNameStr = hostingName != null 2818 ? hostingName.flattenToShortString() : null; 2819 2820 if (!isolated) { 2821 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2822 // If we are in the background, then check to see if this process 2823 // is bad. If so, we will just silently fail. 2824 if (mBadProcesses.get(info.processName, info.uid) != null) { 2825 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2826 + "/" + info.processName); 2827 return null; 2828 } 2829 } else { 2830 // When the user is explicitly starting a process, then clear its 2831 // crash count so that we won't make it bad until they see at 2832 // least one crash dialog again, and make the process good again 2833 // if it had been bad. 2834 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2835 + "/" + info.processName); 2836 mProcessCrashTimes.remove(info.processName, info.uid); 2837 if (mBadProcesses.get(info.processName, info.uid) != null) { 2838 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2839 UserHandle.getUserId(info.uid), info.uid, 2840 info.processName); 2841 mBadProcesses.remove(info.processName, info.uid); 2842 if (app != null) { 2843 app.bad = false; 2844 } 2845 } 2846 } 2847 } 2848 2849 if (app == null) { 2850 checkTime(startTime, "startProcess: creating new process record"); 2851 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2852 if (app == null) { 2853 Slog.w(TAG, "Failed making new process record for " 2854 + processName + "/" + info.uid + " isolated=" + isolated); 2855 return null; 2856 } 2857 app.crashHandler = crashHandler; 2858 mProcessNames.put(processName, app.uid, app); 2859 if (isolated) { 2860 mIsolatedProcesses.put(app.uid, app); 2861 } 2862 checkTime(startTime, "startProcess: done creating new process record"); 2863 } else { 2864 // If this is a new package in the process, add the package to the list 2865 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2866 checkTime(startTime, "startProcess: added package to existing proc"); 2867 } 2868 2869 // If the system is not ready yet, then hold off on starting this 2870 // process until it is. 2871 if (!mProcessesReady 2872 && !isAllowedWhileBooting(info) 2873 && !allowWhileBooting) { 2874 if (!mProcessesOnHold.contains(app)) { 2875 mProcessesOnHold.add(app); 2876 } 2877 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2878 checkTime(startTime, "startProcess: returning with proc on hold"); 2879 return app; 2880 } 2881 2882 checkTime(startTime, "startProcess: stepping in to startProcess"); 2883 startProcessLocked( 2884 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2885 checkTime(startTime, "startProcess: done starting proc!"); 2886 return (app.pid != 0) ? app : null; 2887 } 2888 isAllowedWhileBooting(ApplicationInfo ai)2889 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2890 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2891 } 2892 startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr)2893 private final void startProcessLocked(ProcessRecord app, 2894 String hostingType, String hostingNameStr) { 2895 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2896 null /* entryPoint */, null /* entryPointArgs */); 2897 } 2898 startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)2899 private final void startProcessLocked(ProcessRecord app, String hostingType, 2900 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2901 long startTime = SystemClock.elapsedRealtime(); 2902 if (app.pid > 0 && app.pid != MY_PID) { 2903 checkTime(startTime, "startProcess: removing from pids map"); 2904 synchronized (mPidsSelfLocked) { 2905 mPidsSelfLocked.remove(app.pid); 2906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2907 } 2908 checkTime(startTime, "startProcess: done removing from pids map"); 2909 app.setPid(0); 2910 } 2911 2912 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2913 "startProcessLocked removing on hold: " + app); 2914 mProcessesOnHold.remove(app); 2915 2916 checkTime(startTime, "startProcess: starting to update cpu stats"); 2917 updateCpuStats(); 2918 checkTime(startTime, "startProcess: done updating cpu stats"); 2919 2920 try { 2921 int uid = app.uid; 2922 2923 int[] gids = null; 2924 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2925 if (!app.isolated) { 2926 int[] permGids = null; 2927 try { 2928 checkTime(startTime, "startProcess: getting gids from package manager"); 2929 final PackageManager pm = mContext.getPackageManager(); 2930 permGids = pm.getPackageGids(app.info.packageName); 2931 2932 if (Environment.isExternalStorageEmulated()) { 2933 checkTime(startTime, "startProcess: checking external storage perm"); 2934 if (pm.checkPermission( 2935 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2936 app.info.packageName) == PERMISSION_GRANTED) { 2937 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2938 } else { 2939 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2940 } 2941 } 2942 } catch (PackageManager.NameNotFoundException e) { 2943 Slog.w(TAG, "Unable to retrieve gids", e); 2944 } 2945 2946 /* 2947 * Add shared application and profile GIDs so applications can share some 2948 * resources like shared libraries and access user-wide resources 2949 */ 2950 if (permGids == null) { 2951 gids = new int[2]; 2952 } else { 2953 gids = new int[permGids.length + 2]; 2954 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2955 } 2956 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2957 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2958 } 2959 checkTime(startTime, "startProcess: building args"); 2960 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2961 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2962 && mTopComponent != null 2963 && app.processName.equals(mTopComponent.getPackageName())) { 2964 uid = 0; 2965 } 2966 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2967 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2968 uid = 0; 2969 } 2970 } 2971 int debugFlags = 0; 2972 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2973 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2974 // Also turn on CheckJNI for debuggable apps. It's quite 2975 // awkward to turn on otherwise. 2976 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2977 } 2978 // Run the app in safe mode if its manifest requests so or the 2979 // system is booted in safe mode. 2980 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2981 mSafeMode == true) { 2982 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2983 } 2984 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2985 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2986 } 2987 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2988 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2989 } 2990 if ("1".equals(SystemProperties.get("debug.assert"))) { 2991 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2992 } 2993 2994 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 2995 if (requiredAbi == null) { 2996 requiredAbi = Build.SUPPORTED_ABIS[0]; 2997 } 2998 2999 String instructionSet = null; 3000 if (app.info.primaryCpuAbi != null) { 3001 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3002 } 3003 3004 app.gids = gids; 3005 app.requiredAbi = requiredAbi; 3006 app.instructionSet = instructionSet; 3007 3008 // Start the process. It will either succeed and return a result containing 3009 // the PID of the new process, or else throw a RuntimeException. 3010 boolean isActivityProcess = (entryPoint == null); 3011 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3012 checkTime(startTime, "startProcess: asking zygote to start proc"); 3013 Process.ProcessStartResult startResult = Process.start(entryPoint, 3014 app.processName, uid, uid, gids, debugFlags, mountExternal, 3015 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3016 app.info.dataDir, entryPointArgs); 3017 checkTime(startTime, "startProcess: returned from zygote!"); 3018 3019 if (app.isolated) { 3020 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3021 } 3022 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3023 checkTime(startTime, "startProcess: done updating battery stats"); 3024 3025 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3026 UserHandle.getUserId(uid), startResult.pid, uid, 3027 app.processName, hostingType, 3028 hostingNameStr != null ? hostingNameStr : ""); 3029 3030 if (app.persistent) { 3031 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3032 } 3033 3034 checkTime(startTime, "startProcess: building log message"); 3035 StringBuilder buf = mStringBuilder; 3036 buf.setLength(0); 3037 buf.append("Start proc "); 3038 buf.append(startResult.pid); 3039 buf.append(':'); 3040 buf.append(app.processName); 3041 buf.append('/'); 3042 UserHandle.formatUid(buf, uid); 3043 if (!isActivityProcess) { 3044 buf.append(" ["); 3045 buf.append(entryPoint); 3046 buf.append("]"); 3047 } 3048 buf.append(" for "); 3049 buf.append(hostingType); 3050 if (hostingNameStr != null) { 3051 buf.append(" "); 3052 buf.append(hostingNameStr); 3053 } 3054 Slog.i(TAG, buf.toString()); 3055 app.setPid(startResult.pid); 3056 app.usingWrapper = startResult.usingWrapper; 3057 app.removed = false; 3058 app.killed = false; 3059 app.killedByAm = false; 3060 checkTime(startTime, "startProcess: starting to update pids map"); 3061 synchronized (mPidsSelfLocked) { 3062 this.mPidsSelfLocked.put(startResult.pid, app); 3063 if (isActivityProcess) { 3064 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3065 msg.obj = app; 3066 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3067 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3068 } 3069 } 3070 checkTime(startTime, "startProcess: done updating pids map"); 3071 } catch (RuntimeException e) { 3072 // XXX do better error recovery. 3073 app.setPid(0); 3074 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3075 if (app.isolated) { 3076 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3077 } 3078 Slog.e(TAG, "Failure starting process " + app.processName, e); 3079 } 3080 } 3081 updateUsageStats(ActivityRecord component, boolean resumed)3082 void updateUsageStats(ActivityRecord component, boolean resumed) { 3083 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3084 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3085 if (resumed) { 3086 if (mUsageStatsService != null) { 3087 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3088 UsageEvents.Event.MOVE_TO_FOREGROUND); 3089 } 3090 synchronized (stats) { 3091 stats.noteActivityResumedLocked(component.app.uid); 3092 } 3093 } else { 3094 if (mUsageStatsService != null) { 3095 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3096 UsageEvents.Event.MOVE_TO_BACKGROUND); 3097 } 3098 synchronized (stats) { 3099 stats.noteActivityPausedLocked(component.app.uid); 3100 } 3101 } 3102 } 3103 getHomeIntent()3104 Intent getHomeIntent() { 3105 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3106 intent.setComponent(mTopComponent); 3107 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3108 intent.addCategory(Intent.CATEGORY_HOME); 3109 } 3110 return intent; 3111 } 3112 startHomeActivityLocked(int userId, String reason)3113 boolean startHomeActivityLocked(int userId, String reason) { 3114 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3115 && mTopAction == null) { 3116 // We are running in factory test mode, but unable to find 3117 // the factory test app, so just sit around displaying the 3118 // error message and don't try to start anything. 3119 return false; 3120 } 3121 Intent intent = getHomeIntent(); 3122 ActivityInfo aInfo = 3123 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3124 if (aInfo != null) { 3125 intent.setComponent(new ComponentName( 3126 aInfo.applicationInfo.packageName, aInfo.name)); 3127 // Don't do this if the home app is currently being 3128 // instrumented. 3129 aInfo = new ActivityInfo(aInfo); 3130 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3131 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3132 aInfo.applicationInfo.uid, true); 3133 if (app == null || app.instrumentationClass == null) { 3134 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3135 mStackSupervisor.startHomeActivity(intent, aInfo, reason); 3136 } 3137 } 3138 3139 return true; 3140 } 3141 resolveActivityInfo(Intent intent, int flags, int userId)3142 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3143 ActivityInfo ai = null; 3144 ComponentName comp = intent.getComponent(); 3145 try { 3146 if (comp != null) { 3147 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3148 } else { 3149 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3150 intent, 3151 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3152 flags, userId); 3153 3154 if (info != null) { 3155 ai = info.activityInfo; 3156 } 3157 } 3158 } catch (RemoteException e) { 3159 // ignore 3160 } 3161 3162 return ai; 3163 } 3164 3165 /** 3166 * Starts the "new version setup screen" if appropriate. 3167 */ startSetupActivityLocked()3168 void startSetupActivityLocked() { 3169 // Only do this once per boot. 3170 if (mCheckedForSetup) { 3171 return; 3172 } 3173 3174 // We will show this screen if the current one is a different 3175 // version than the last one shown, and we are not running in 3176 // low-level factory test mode. 3177 final ContentResolver resolver = mContext.getContentResolver(); 3178 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3179 Settings.Global.getInt(resolver, 3180 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3181 mCheckedForSetup = true; 3182 3183 // See if we should be showing the platform update setup UI. 3184 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3185 List<ResolveInfo> ris = mContext.getPackageManager() 3186 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3187 3188 // We don't allow third party apps to replace this. 3189 ResolveInfo ri = null; 3190 for (int i=0; ris != null && i<ris.size(); i++) { 3191 if ((ris.get(i).activityInfo.applicationInfo.flags 3192 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3193 ri = ris.get(i); 3194 break; 3195 } 3196 } 3197 3198 if (ri != null) { 3199 String vers = ri.activityInfo.metaData != null 3200 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3201 : null; 3202 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3203 vers = ri.activityInfo.applicationInfo.metaData.getString( 3204 Intent.METADATA_SETUP_VERSION); 3205 } 3206 String lastVers = Settings.Secure.getString( 3207 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3208 if (vers != null && !vers.equals(lastVers)) { 3209 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3210 intent.setComponent(new ComponentName( 3211 ri.activityInfo.packageName, ri.activityInfo.name)); 3212 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3213 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3214 null); 3215 } 3216 } 3217 } 3218 } 3219 compatibilityInfoForPackageLocked(ApplicationInfo ai)3220 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3221 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3222 } 3223 enforceNotIsolatedCaller(String caller)3224 void enforceNotIsolatedCaller(String caller) { 3225 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3226 throw new SecurityException("Isolated process not allowed to call " + caller); 3227 } 3228 } 3229 enforceShellRestriction(String restriction, int userHandle)3230 void enforceShellRestriction(String restriction, int userHandle) { 3231 if (Binder.getCallingUid() == Process.SHELL_UID) { 3232 if (userHandle < 0 3233 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3234 throw new SecurityException("Shell does not have permission to access user " 3235 + userHandle); 3236 } 3237 } 3238 } 3239 3240 @Override getFrontActivityScreenCompatMode()3241 public int getFrontActivityScreenCompatMode() { 3242 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3243 synchronized (this) { 3244 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3245 } 3246 } 3247 3248 @Override setFrontActivityScreenCompatMode(int mode)3249 public void setFrontActivityScreenCompatMode(int mode) { 3250 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3251 "setFrontActivityScreenCompatMode"); 3252 synchronized (this) { 3253 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3254 } 3255 } 3256 3257 @Override getPackageScreenCompatMode(String packageName)3258 public int getPackageScreenCompatMode(String packageName) { 3259 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3260 synchronized (this) { 3261 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3262 } 3263 } 3264 3265 @Override setPackageScreenCompatMode(String packageName, int mode)3266 public void setPackageScreenCompatMode(String packageName, int mode) { 3267 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3268 "setPackageScreenCompatMode"); 3269 synchronized (this) { 3270 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3271 } 3272 } 3273 3274 @Override getPackageAskScreenCompat(String packageName)3275 public boolean getPackageAskScreenCompat(String packageName) { 3276 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3277 synchronized (this) { 3278 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3279 } 3280 } 3281 3282 @Override setPackageAskScreenCompat(String packageName, boolean ask)3283 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3284 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3285 "setPackageAskScreenCompat"); 3286 synchronized (this) { 3287 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3288 } 3289 } 3290 dispatchProcessesChanged()3291 private void dispatchProcessesChanged() { 3292 int N; 3293 synchronized (this) { 3294 N = mPendingProcessChanges.size(); 3295 if (mActiveProcessChanges.length < N) { 3296 mActiveProcessChanges = new ProcessChangeItem[N]; 3297 } 3298 mPendingProcessChanges.toArray(mActiveProcessChanges); 3299 mAvailProcessChanges.addAll(mPendingProcessChanges); 3300 mPendingProcessChanges.clear(); 3301 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3302 } 3303 3304 int i = mProcessObservers.beginBroadcast(); 3305 while (i > 0) { 3306 i--; 3307 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3308 if (observer != null) { 3309 try { 3310 for (int j=0; j<N; j++) { 3311 ProcessChangeItem item = mActiveProcessChanges[j]; 3312 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3313 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3314 + item.pid + " uid=" + item.uid + ": " 3315 + item.foregroundActivities); 3316 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3317 item.foregroundActivities); 3318 } 3319 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3320 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3321 + item.pid + " uid=" + item.uid + ": " + item.processState); 3322 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3323 } 3324 } 3325 } catch (RemoteException e) { 3326 } 3327 } 3328 } 3329 mProcessObservers.finishBroadcast(); 3330 } 3331 dispatchProcessDied(int pid, int uid)3332 private void dispatchProcessDied(int pid, int uid) { 3333 int i = mProcessObservers.beginBroadcast(); 3334 while (i > 0) { 3335 i--; 3336 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3337 if (observer != null) { 3338 try { 3339 observer.onProcessDied(pid, uid); 3340 } catch (RemoteException e) { 3341 } 3342 } 3343 } 3344 mProcessObservers.finishBroadcast(); 3345 } 3346 3347 @Override startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options)3348 public final int startActivity(IApplicationThread caller, String callingPackage, 3349 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3350 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3351 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3352 resultWho, requestCode, startFlags, profilerInfo, options, 3353 UserHandle.getCallingUserId()); 3354 } 3355 3356 @Override startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId)3357 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3358 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3359 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3360 enforceNotIsolatedCaller("startActivity"); 3361 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3362 false, ALLOW_FULL_ONLY, "startActivity", null); 3363 // TODO: Switch to user app stacks here. 3364 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3365 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3366 profilerInfo, null, null, options, userId, null, null); 3367 } 3368 3369 @Override startActivityAsCaller(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId)3370 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3371 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3372 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3373 3374 // This is very dangerous -- it allows you to perform a start activity (including 3375 // permission grants) as any app that may launch one of your own activities. So 3376 // we will only allow this to be done from activities that are part of the core framework, 3377 // and then only when they are running as the system. 3378 final ActivityRecord sourceRecord; 3379 final int targetUid; 3380 final String targetPackage; 3381 synchronized (this) { 3382 if (resultTo == null) { 3383 throw new SecurityException("Must be called from an activity"); 3384 } 3385 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3386 if (sourceRecord == null) { 3387 throw new SecurityException("Called with bad activity token: " + resultTo); 3388 } 3389 if (!sourceRecord.info.packageName.equals("android")) { 3390 throw new SecurityException( 3391 "Must be called from an activity that is declared in the android package"); 3392 } 3393 if (sourceRecord.app == null) { 3394 throw new SecurityException("Called without a process attached to activity"); 3395 } 3396 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3397 // This is still okay, as long as this activity is running under the 3398 // uid of the original calling activity. 3399 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3400 throw new SecurityException( 3401 "Calling activity in uid " + sourceRecord.app.uid 3402 + " must be system uid or original calling uid " 3403 + sourceRecord.launchedFromUid); 3404 } 3405 } 3406 targetUid = sourceRecord.launchedFromUid; 3407 targetPackage = sourceRecord.launchedFromPackage; 3408 } 3409 3410 if (userId == UserHandle.USER_NULL) { 3411 userId = UserHandle.getUserId(sourceRecord.app.uid); 3412 } 3413 3414 // TODO: Switch to user app stacks here. 3415 try { 3416 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3417 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3418 null, null, options, userId, null, null); 3419 return ret; 3420 } catch (SecurityException e) { 3421 // XXX need to figure out how to propagate to original app. 3422 // A SecurityException here is generally actually a fault of the original 3423 // calling activity (such as a fairly granting permissions), so propagate it 3424 // back to them. 3425 /* 3426 StringBuilder msg = new StringBuilder(); 3427 msg.append("While launching"); 3428 msg.append(intent.toString()); 3429 msg.append(": "); 3430 msg.append(e.getMessage()); 3431 */ 3432 throw e; 3433 } 3434 } 3435 3436 @Override startActivityAndWait(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId)3437 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3438 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3439 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3440 enforceNotIsolatedCaller("startActivityAndWait"); 3441 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3442 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3443 WaitResult res = new WaitResult(); 3444 // TODO: Switch to user app stacks here. 3445 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3446 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3447 options, userId, null, null); 3448 return res; 3449 } 3450 3451 @Override startActivityWithConfig(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration config, Bundle options, int userId)3452 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3453 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3454 int startFlags, Configuration config, Bundle options, int userId) { 3455 enforceNotIsolatedCaller("startActivityWithConfig"); 3456 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3457 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3458 // TODO: Switch to user app stacks here. 3459 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3460 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3461 null, null, config, options, userId, null, null); 3462 return ret; 3463 } 3464 3465 @Override startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options)3466 public int startActivityIntentSender(IApplicationThread caller, 3467 IntentSender intent, Intent fillInIntent, String resolvedType, 3468 IBinder resultTo, String resultWho, int requestCode, 3469 int flagsMask, int flagsValues, Bundle options) { 3470 enforceNotIsolatedCaller("startActivityIntentSender"); 3471 // Refuse possible leaked file descriptors 3472 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3473 throw new IllegalArgumentException("File descriptors passed in Intent"); 3474 } 3475 3476 IIntentSender sender = intent.getTarget(); 3477 if (!(sender instanceof PendingIntentRecord)) { 3478 throw new IllegalArgumentException("Bad PendingIntent object"); 3479 } 3480 3481 PendingIntentRecord pir = (PendingIntentRecord)sender; 3482 3483 synchronized (this) { 3484 // If this is coming from the currently resumed activity, it is 3485 // effectively saying that app switches are allowed at this point. 3486 final ActivityStack stack = getFocusedStack(); 3487 if (stack.mResumedActivity != null && 3488 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3489 mAppSwitchesAllowedTime = 0; 3490 } 3491 } 3492 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3493 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3494 return ret; 3495 } 3496 3497 @Override startVoiceActivity(String callingPackage, int callingPid, int callingUid, Intent intent, String resolvedType, IVoiceInteractionSession session, IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId)3498 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3499 Intent intent, String resolvedType, IVoiceInteractionSession session, 3500 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3501 Bundle options, int userId) { 3502 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3503 != PackageManager.PERMISSION_GRANTED) { 3504 String msg = "Permission Denial: startVoiceActivity() from pid=" 3505 + Binder.getCallingPid() 3506 + ", uid=" + Binder.getCallingUid() 3507 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3508 Slog.w(TAG, msg); 3509 throw new SecurityException(msg); 3510 } 3511 if (session == null || interactor == null) { 3512 throw new NullPointerException("null session or interactor"); 3513 } 3514 userId = handleIncomingUser(callingPid, callingUid, userId, 3515 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3516 // TODO: Switch to user app stacks here. 3517 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3518 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3519 null, options, userId, null, null); 3520 } 3521 3522 @Override startNextMatchingActivity(IBinder callingActivity, Intent intent, Bundle options)3523 public boolean startNextMatchingActivity(IBinder callingActivity, 3524 Intent intent, Bundle options) { 3525 // Refuse possible leaked file descriptors 3526 if (intent != null && intent.hasFileDescriptors() == true) { 3527 throw new IllegalArgumentException("File descriptors passed in Intent"); 3528 } 3529 3530 synchronized (this) { 3531 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3532 if (r == null) { 3533 ActivityOptions.abort(options); 3534 return false; 3535 } 3536 if (r.app == null || r.app.thread == null) { 3537 // The caller is not running... d'oh! 3538 ActivityOptions.abort(options); 3539 return false; 3540 } 3541 intent = new Intent(intent); 3542 // The caller is not allowed to change the data. 3543 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3544 // And we are resetting to find the next component... 3545 intent.setComponent(null); 3546 3547 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3548 3549 ActivityInfo aInfo = null; 3550 try { 3551 List<ResolveInfo> resolves = 3552 AppGlobals.getPackageManager().queryIntentActivities( 3553 intent, r.resolvedType, 3554 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3555 UserHandle.getCallingUserId()); 3556 3557 // Look for the original activity in the list... 3558 final int N = resolves != null ? resolves.size() : 0; 3559 for (int i=0; i<N; i++) { 3560 ResolveInfo rInfo = resolves.get(i); 3561 if (rInfo.activityInfo.packageName.equals(r.packageName) 3562 && rInfo.activityInfo.name.equals(r.info.name)) { 3563 // We found the current one... the next matching is 3564 // after it. 3565 i++; 3566 if (i<N) { 3567 aInfo = resolves.get(i).activityInfo; 3568 } 3569 if (debug) { 3570 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3571 + "/" + r.info.name); 3572 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3573 + "/" + aInfo.name); 3574 } 3575 break; 3576 } 3577 } 3578 } catch (RemoteException e) { 3579 } 3580 3581 if (aInfo == null) { 3582 // Nobody who is next! 3583 ActivityOptions.abort(options); 3584 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3585 return false; 3586 } 3587 3588 intent.setComponent(new ComponentName( 3589 aInfo.applicationInfo.packageName, aInfo.name)); 3590 intent.setFlags(intent.getFlags()&~( 3591 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3592 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3593 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3594 Intent.FLAG_ACTIVITY_NEW_TASK)); 3595 3596 // Okay now we need to start the new activity, replacing the 3597 // currently running activity. This is a little tricky because 3598 // we want to start the new one as if the current one is finished, 3599 // but not finish the current one first so that there is no flicker. 3600 // And thus... 3601 final boolean wasFinishing = r.finishing; 3602 r.finishing = true; 3603 3604 // Propagate reply information over to the new activity. 3605 final ActivityRecord resultTo = r.resultTo; 3606 final String resultWho = r.resultWho; 3607 final int requestCode = r.requestCode; 3608 r.resultTo = null; 3609 if (resultTo != null) { 3610 resultTo.removeResultsLocked(r, resultWho, requestCode); 3611 } 3612 3613 final long origId = Binder.clearCallingIdentity(); 3614 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3615 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3616 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3617 -1, r.launchedFromUid, 0, options, false, null, null, null); 3618 Binder.restoreCallingIdentity(origId); 3619 3620 r.finishing = wasFinishing; 3621 if (res != ActivityManager.START_SUCCESS) { 3622 return false; 3623 } 3624 return true; 3625 } 3626 } 3627 3628 @Override startActivityFromRecents(int taskId, Bundle options)3629 public final int startActivityFromRecents(int taskId, Bundle options) { 3630 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3631 String msg = "Permission Denial: startActivityFromRecents called without " + 3632 START_TASKS_FROM_RECENTS; 3633 Slog.w(TAG, msg); 3634 throw new SecurityException(msg); 3635 } 3636 return startActivityFromRecentsInner(taskId, options); 3637 } 3638 startActivityFromRecentsInner(int taskId, Bundle options)3639 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3640 final TaskRecord task; 3641 final int callingUid; 3642 final String callingPackage; 3643 final Intent intent; 3644 final int userId; 3645 synchronized (this) { 3646 task = recentTaskForIdLocked(taskId); 3647 if (task == null) { 3648 throw new IllegalArgumentException("Task " + taskId + " not found."); 3649 } 3650 if (task.getRootActivity() != null) { 3651 moveTaskToFrontLocked(task.taskId, 0, null); 3652 return ActivityManager.START_TASK_TO_FRONT; 3653 } 3654 callingUid = task.mCallingUid; 3655 callingPackage = task.mCallingPackage; 3656 intent = task.intent; 3657 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3658 userId = task.userId; 3659 } 3660 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3661 options, userId, null, task); 3662 } 3663 startActivityInPackage(int uid, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Bundle options, int userId, IActivityContainer container, TaskRecord inTask)3664 final int startActivityInPackage(int uid, String callingPackage, 3665 Intent intent, String resolvedType, IBinder resultTo, 3666 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3667 IActivityContainer container, TaskRecord inTask) { 3668 3669 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3670 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3671 3672 // TODO: Switch to user app stacks here. 3673 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3674 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3675 null, null, null, options, userId, container, inTask); 3676 return ret; 3677 } 3678 3679 @Override startActivities(IApplicationThread caller, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId)3680 public final int startActivities(IApplicationThread caller, String callingPackage, 3681 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3682 int userId) { 3683 enforceNotIsolatedCaller("startActivities"); 3684 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3685 false, ALLOW_FULL_ONLY, "startActivity", null); 3686 // TODO: Switch to user app stacks here. 3687 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3688 resolvedTypes, resultTo, options, userId); 3689 return ret; 3690 } 3691 startActivitiesInPackage(int uid, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, int userId)3692 final int startActivitiesInPackage(int uid, String callingPackage, 3693 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3694 Bundle options, int userId) { 3695 3696 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3697 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3698 // TODO: Switch to user app stacks here. 3699 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3700 resultTo, options, userId); 3701 return ret; 3702 } 3703 3704 //explicitly remove thd old information in mRecentTasks when removing existing user. removeRecentTasksForUserLocked(int userId)3705 private void removeRecentTasksForUserLocked(int userId) { 3706 if(userId <= 0) { 3707 Slog.i(TAG, "Can't remove recent task on user " + userId); 3708 return; 3709 } 3710 3711 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3712 TaskRecord tr = mRecentTasks.get(i); 3713 if (tr.userId == userId) { 3714 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3715 + " when finishing user" + userId); 3716 mRecentTasks.remove(i); 3717 tr.removedFromRecents(); 3718 } 3719 } 3720 3721 // Remove tasks from persistent storage. 3722 notifyTaskPersisterLocked(null, true); 3723 } 3724 3725 // Sort by taskId 3726 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3727 @Override 3728 public int compare(TaskRecord lhs, TaskRecord rhs) { 3729 return rhs.taskId - lhs.taskId; 3730 } 3731 }; 3732 3733 // Extract the affiliates of the chain containing mRecentTasks[start]. processNextAffiliateChainLocked(int start)3734 private int processNextAffiliateChainLocked(int start) { 3735 final TaskRecord startTask = mRecentTasks.get(start); 3736 final int affiliateId = startTask.mAffiliatedTaskId; 3737 3738 // Quick identification of isolated tasks. I.e. those not launched behind. 3739 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3740 startTask.mNextAffiliate == null) { 3741 // There is still a slim chance that there are other tasks that point to this task 3742 // and that the chain is so messed up that this task no longer points to them but 3743 // the gain of this optimization outweighs the risk. 3744 startTask.inRecents = true; 3745 return start + 1; 3746 } 3747 3748 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3749 mTmpRecents.clear(); 3750 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3751 final TaskRecord task = mRecentTasks.get(i); 3752 if (task.mAffiliatedTaskId == affiliateId) { 3753 mRecentTasks.remove(i); 3754 mTmpRecents.add(task); 3755 } 3756 } 3757 3758 // Sort them all by taskId. That is the order they were create in and that order will 3759 // always be correct. 3760 Collections.sort(mTmpRecents, mTaskRecordComparator); 3761 3762 // Go through and fix up the linked list. 3763 // The first one is the end of the chain and has no next. 3764 final TaskRecord first = mTmpRecents.get(0); 3765 first.inRecents = true; 3766 if (first.mNextAffiliate != null) { 3767 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3768 first.setNextAffiliate(null); 3769 notifyTaskPersisterLocked(first, false); 3770 } 3771 // Everything in the middle is doubly linked from next to prev. 3772 final int tmpSize = mTmpRecents.size(); 3773 for (int i = 0; i < tmpSize - 1; ++i) { 3774 final TaskRecord next = mTmpRecents.get(i); 3775 final TaskRecord prev = mTmpRecents.get(i + 1); 3776 if (next.mPrevAffiliate != prev) { 3777 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3778 " setting prev=" + prev); 3779 next.setPrevAffiliate(prev); 3780 notifyTaskPersisterLocked(next, false); 3781 } 3782 if (prev.mNextAffiliate != next) { 3783 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3784 " setting next=" + next); 3785 prev.setNextAffiliate(next); 3786 notifyTaskPersisterLocked(prev, false); 3787 } 3788 prev.inRecents = true; 3789 } 3790 // The last one is the beginning of the list and has no prev. 3791 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3792 if (last.mPrevAffiliate != null) { 3793 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3794 last.setPrevAffiliate(null); 3795 notifyTaskPersisterLocked(last, false); 3796 } 3797 3798 // Insert the group back into mRecentTasks at start. 3799 mRecentTasks.addAll(start, mTmpRecents); 3800 3801 // Let the caller know where we left off. 3802 return start + tmpSize; 3803 } 3804 3805 /** 3806 * Update the recent tasks lists: make sure tasks should still be here (their 3807 * applications / activities still exist), update their availability, fixup ordering 3808 * of affiliations. 3809 */ cleanupRecentTasksLocked(int userId)3810 void cleanupRecentTasksLocked(int userId) { 3811 if (mRecentTasks == null) { 3812 // Happens when called from the packagemanager broadcast before boot. 3813 return; 3814 } 3815 3816 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3817 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3818 final IPackageManager pm = AppGlobals.getPackageManager(); 3819 final ActivityInfo dummyAct = new ActivityInfo(); 3820 final ApplicationInfo dummyApp = new ApplicationInfo(); 3821 3822 int N = mRecentTasks.size(); 3823 3824 int[] users = userId == UserHandle.USER_ALL 3825 ? getUsersLocked() : new int[] { userId }; 3826 for (int user : users) { 3827 for (int i = 0; i < N; i++) { 3828 TaskRecord task = mRecentTasks.get(i); 3829 if (task.userId != user) { 3830 // Only look at tasks for the user ID of interest. 3831 continue; 3832 } 3833 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3834 // This situation is broken, and we should just get rid of it now. 3835 mRecentTasks.remove(i); 3836 task.removedFromRecents(); 3837 i--; 3838 N--; 3839 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3840 continue; 3841 } 3842 // Check whether this activity is currently available. 3843 if (task.realActivity != null) { 3844 ActivityInfo ai = availActCache.get(task.realActivity); 3845 if (ai == null) { 3846 try { 3847 ai = pm.getActivityInfo(task.realActivity, 3848 PackageManager.GET_UNINSTALLED_PACKAGES 3849 | PackageManager.GET_DISABLED_COMPONENTS, user); 3850 } catch (RemoteException e) { 3851 // Will never happen. 3852 continue; 3853 } 3854 if (ai == null) { 3855 ai = dummyAct; 3856 } 3857 availActCache.put(task.realActivity, ai); 3858 } 3859 if (ai == dummyAct) { 3860 // This could be either because the activity no longer exists, or the 3861 // app is temporarily gone. For the former we want to remove the recents 3862 // entry; for the latter we want to mark it as unavailable. 3863 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3864 if (app == null) { 3865 try { 3866 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3867 PackageManager.GET_UNINSTALLED_PACKAGES 3868 | PackageManager.GET_DISABLED_COMPONENTS, user); 3869 } catch (RemoteException e) { 3870 // Will never happen. 3871 continue; 3872 } 3873 if (app == null) { 3874 app = dummyApp; 3875 } 3876 availAppCache.put(task.realActivity.getPackageName(), app); 3877 } 3878 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3879 // Doesn't exist any more! Good-bye. 3880 mRecentTasks.remove(i); 3881 task.removedFromRecents(); 3882 i--; 3883 N--; 3884 Slog.w(TAG, "Removing no longer valid recent: " + task); 3885 continue; 3886 } else { 3887 // Otherwise just not available for now. 3888 if (task.isAvailable) { 3889 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3890 + task); 3891 } 3892 task.isAvailable = false; 3893 } 3894 } else { 3895 if (!ai.enabled || !ai.applicationInfo.enabled 3896 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3897 if (task.isAvailable) { 3898 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3899 + task + " (enabled=" + ai.enabled + "/" 3900 + ai.applicationInfo.enabled + " flags=" 3901 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3902 } 3903 task.isAvailable = false; 3904 } else { 3905 if (!task.isAvailable) { 3906 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3907 + task); 3908 } 3909 task.isAvailable = true; 3910 } 3911 } 3912 } 3913 } 3914 } 3915 3916 // Verify the affiliate chain for each task. 3917 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3918 } 3919 3920 mTmpRecents.clear(); 3921 // mRecentTasks is now in sorted, affiliated order. 3922 } 3923 moveAffiliatedTasksToFront(TaskRecord task, int taskIndex)3924 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3925 int N = mRecentTasks.size(); 3926 TaskRecord top = task; 3927 int topIndex = taskIndex; 3928 while (top.mNextAffiliate != null && topIndex > 0) { 3929 top = top.mNextAffiliate; 3930 topIndex--; 3931 } 3932 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3933 + topIndex + " from intial " + taskIndex); 3934 // Find the end of the chain, doing a sanity check along the way. 3935 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3936 int endIndex = topIndex; 3937 TaskRecord prev = top; 3938 while (endIndex < N) { 3939 TaskRecord cur = mRecentTasks.get(endIndex); 3940 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3941 + endIndex + " " + cur); 3942 if (cur == top) { 3943 // Verify start of the chain. 3944 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3945 Slog.wtf(TAG, "Bad chain @" + endIndex 3946 + ": first task has next affiliate: " + prev); 3947 sane = false; 3948 break; 3949 } 3950 } else { 3951 // Verify middle of the chain's next points back to the one before. 3952 if (cur.mNextAffiliate != prev 3953 || cur.mNextAffiliateTaskId != prev.taskId) { 3954 Slog.wtf(TAG, "Bad chain @" + endIndex 3955 + ": middle task " + cur + " @" + endIndex 3956 + " has bad next affiliate " 3957 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3958 + ", expected " + prev); 3959 sane = false; 3960 break; 3961 } 3962 } 3963 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3964 // Chain ends here. 3965 if (cur.mPrevAffiliate != null) { 3966 Slog.wtf(TAG, "Bad chain @" + endIndex 3967 + ": last task " + cur + " has previous affiliate " 3968 + cur.mPrevAffiliate); 3969 sane = false; 3970 } 3971 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3972 break; 3973 } else { 3974 // Verify middle of the chain's prev points to a valid item. 3975 if (cur.mPrevAffiliate == null) { 3976 Slog.wtf(TAG, "Bad chain @" + endIndex 3977 + ": task " + cur + " has previous affiliate " 3978 + cur.mPrevAffiliate + " but should be id " 3979 + cur.mPrevAffiliate); 3980 sane = false; 3981 break; 3982 } 3983 } 3984 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3985 Slog.wtf(TAG, "Bad chain @" + endIndex 3986 + ": task " + cur + " has affiliated id " 3987 + cur.mAffiliatedTaskId + " but should be " 3988 + task.mAffiliatedTaskId); 3989 sane = false; 3990 break; 3991 } 3992 prev = cur; 3993 endIndex++; 3994 if (endIndex >= N) { 3995 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 3996 + ": last task " + prev); 3997 sane = false; 3998 break; 3999 } 4000 } 4001 if (sane) { 4002 if (endIndex < taskIndex) { 4003 Slog.wtf(TAG, "Bad chain @" + endIndex 4004 + ": did not extend to task " + task + " @" + taskIndex); 4005 sane = false; 4006 } 4007 } 4008 if (sane) { 4009 // All looks good, we can just move all of the affiliated tasks 4010 // to the top. 4011 for (int i=topIndex; i<=endIndex; i++) { 4012 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4013 + " from " + i + " to " + (i-topIndex)); 4014 TaskRecord cur = mRecentTasks.remove(i); 4015 mRecentTasks.add(i-topIndex, cur); 4016 } 4017 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4018 + " to " + endIndex); 4019 return true; 4020 } 4021 4022 // Whoops, couldn't do it. 4023 return false; 4024 } 4025 addRecentTaskLocked(TaskRecord task)4026 final void addRecentTaskLocked(TaskRecord task) { 4027 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4028 || task.mNextAffiliateTaskId != INVALID_TASK_ID 4029 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 4030 4031 int N = mRecentTasks.size(); 4032 // Quick case: check if the top-most recent task is the same. 4033 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4034 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4035 return; 4036 } 4037 // Another quick case: check if this is part of a set of affiliated 4038 // tasks that are at the top. 4039 if (isAffiliated && N > 0 && task.inRecents 4040 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4041 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4042 + " at top when adding " + task); 4043 return; 4044 } 4045 // Another quick case: never add voice sessions. 4046 if (task.voiceSession != null) { 4047 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4048 return; 4049 } 4050 4051 boolean needAffiliationFix = false; 4052 4053 // Slightly less quick case: the task is already in recents, so all we need 4054 // to do is move it. 4055 if (task.inRecents) { 4056 int taskIndex = mRecentTasks.indexOf(task); 4057 if (taskIndex >= 0) { 4058 if (!isAffiliated) { 4059 // Simple case: this is not an affiliated task, so we just move it to the front. 4060 mRecentTasks.remove(taskIndex); 4061 mRecentTasks.add(0, task); 4062 notifyTaskPersisterLocked(task, false); 4063 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4064 + " from " + taskIndex); 4065 return; 4066 } else { 4067 // More complicated: need to keep all affiliated tasks together. 4068 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4069 // All went well. 4070 return; 4071 } 4072 4073 // Uh oh... something bad in the affiliation chain, try to rebuild 4074 // everything and then go through our general path of adding a new task. 4075 needAffiliationFix = true; 4076 } 4077 } else { 4078 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4079 needAffiliationFix = true; 4080 } 4081 } 4082 4083 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4084 trimRecentsForTaskLocked(task, true); 4085 4086 N = mRecentTasks.size(); 4087 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4088 final TaskRecord tr = mRecentTasks.remove(N - 1); 4089 tr.removedFromRecents(); 4090 N--; 4091 } 4092 task.inRecents = true; 4093 if (!isAffiliated || needAffiliationFix) { 4094 // If this is a simple non-affiliated task, or we had some failure trying to 4095 // handle it as part of an affilated task, then just place it at the top. 4096 mRecentTasks.add(0, task); 4097 } else if (isAffiliated) { 4098 // If this is a new affiliated task, then move all of the affiliated tasks 4099 // to the front and insert this new one. 4100 TaskRecord other = task.mNextAffiliate; 4101 if (other == null) { 4102 other = task.mPrevAffiliate; 4103 } 4104 if (other != null) { 4105 int otherIndex = mRecentTasks.indexOf(other); 4106 if (otherIndex >= 0) { 4107 // Insert new task at appropriate location. 4108 int taskIndex; 4109 if (other == task.mNextAffiliate) { 4110 // We found the index of our next affiliation, which is who is 4111 // before us in the list, so add after that point. 4112 taskIndex = otherIndex+1; 4113 } else { 4114 // We found the index of our previous affiliation, which is who is 4115 // after us in the list, so add at their position. 4116 taskIndex = otherIndex; 4117 } 4118 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4119 + taskIndex + ": " + task); 4120 mRecentTasks.add(taskIndex, task); 4121 4122 // Now move everything to the front. 4123 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4124 // All went well. 4125 return; 4126 } 4127 4128 // Uh oh... something bad in the affiliation chain, try to rebuild 4129 // everything and then go through our general path of adding a new task. 4130 needAffiliationFix = true; 4131 } else { 4132 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4133 + other); 4134 needAffiliationFix = true; 4135 } 4136 } else { 4137 if (DEBUG_RECENTS) Slog.d(TAG, 4138 "addRecent: adding affiliated task without next/prev:" + task); 4139 needAffiliationFix = true; 4140 } 4141 } 4142 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4143 4144 if (needAffiliationFix) { 4145 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4146 cleanupRecentTasksLocked(task.userId); 4147 } 4148 } 4149 4150 /** 4151 * If needed, remove oldest existing entries in recents that are for the same kind 4152 * of task as the given one. 4153 */ trimRecentsForTaskLocked(TaskRecord task, boolean doTrim)4154 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4155 int N = mRecentTasks.size(); 4156 final Intent intent = task.intent; 4157 final boolean document = intent != null && intent.isDocument(); 4158 4159 int maxRecents = task.maxRecents - 1; 4160 for (int i=0; i<N; i++) { 4161 final TaskRecord tr = mRecentTasks.get(i); 4162 if (task != tr) { 4163 if (task.userId != tr.userId) { 4164 continue; 4165 } 4166 if (i > MAX_RECENT_BITMAPS) { 4167 tr.freeLastThumbnail(); 4168 } 4169 final Intent trIntent = tr.intent; 4170 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4171 (intent == null || !intent.filterEquals(trIntent))) { 4172 continue; 4173 } 4174 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4175 if (document && trIsDocument) { 4176 // These are the same document activity (not necessarily the same doc). 4177 if (maxRecents > 0) { 4178 --maxRecents; 4179 continue; 4180 } 4181 // Hit the maximum number of documents for this task. Fall through 4182 // and remove this document from recents. 4183 } else if (document || trIsDocument) { 4184 // Only one of these is a document. Not the droid we're looking for. 4185 continue; 4186 } 4187 } 4188 4189 if (!doTrim) { 4190 // If the caller is not actually asking for a trim, just tell them we reached 4191 // a point where the trim would happen. 4192 return i; 4193 } 4194 4195 // Either task and tr are the same or, their affinities match or their intents match 4196 // and neither of them is a document, or they are documents using the same activity 4197 // and their maxRecents has been reached. 4198 tr.disposeThumbnail(); 4199 mRecentTasks.remove(i); 4200 if (task != tr) { 4201 tr.removedFromRecents(); 4202 } 4203 i--; 4204 N--; 4205 if (task.intent == null) { 4206 // If the new recent task we are adding is not fully 4207 // specified, then replace it with the existing recent task. 4208 task = tr; 4209 } 4210 notifyTaskPersisterLocked(tr, false); 4211 } 4212 4213 return -1; 4214 } 4215 4216 @Override reportActivityFullyDrawn(IBinder token)4217 public void reportActivityFullyDrawn(IBinder token) { 4218 synchronized (this) { 4219 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4220 if (r == null) { 4221 return; 4222 } 4223 r.reportFullyDrawnLocked(); 4224 } 4225 } 4226 4227 @Override setRequestedOrientation(IBinder token, int requestedOrientation)4228 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4229 synchronized (this) { 4230 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4231 if (r == null) { 4232 return; 4233 } 4234 final long origId = Binder.clearCallingIdentity(); 4235 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4236 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4237 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4238 if (config != null) { 4239 r.frozenBeforeDestroy = true; 4240 if (!updateConfigurationLocked(config, r, false, false)) { 4241 mStackSupervisor.resumeTopActivitiesLocked(); 4242 } 4243 } 4244 Binder.restoreCallingIdentity(origId); 4245 } 4246 } 4247 4248 @Override getRequestedOrientation(IBinder token)4249 public int getRequestedOrientation(IBinder token) { 4250 synchronized (this) { 4251 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4252 if (r == null) { 4253 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4254 } 4255 return mWindowManager.getAppOrientation(r.appToken); 4256 } 4257 } 4258 4259 /** 4260 * This is the internal entry point for handling Activity.finish(). 4261 * 4262 * @param token The Binder token referencing the Activity we want to finish. 4263 * @param resultCode Result code, if any, from this Activity. 4264 * @param resultData Result data (Intent), if any, from this Activity. 4265 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4266 * the root Activity in the task. 4267 * 4268 * @return Returns true if the activity successfully finished, or false if it is still running. 4269 */ 4270 @Override finishActivity(IBinder token, int resultCode, Intent resultData, boolean finishTask)4271 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4272 boolean finishTask) { 4273 // Refuse possible leaked file descriptors 4274 if (resultData != null && resultData.hasFileDescriptors() == true) { 4275 throw new IllegalArgumentException("File descriptors passed in Intent"); 4276 } 4277 4278 synchronized(this) { 4279 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4280 if (r == null) { 4281 return true; 4282 } 4283 // Keep track of the root activity of the task before we finish it 4284 TaskRecord tr = r.task; 4285 ActivityRecord rootR = tr.getRootActivity(); 4286 if (rootR == null) { 4287 Slog.w(TAG, "Finishing task with all activities already finished"); 4288 } 4289 // Do not allow task to finish in Lock Task mode. 4290 if (tr == mStackSupervisor.mLockTaskModeTask) { 4291 if (rootR == r) { 4292 Slog.i(TAG, "Not finishing task in lock task mode"); 4293 mStackSupervisor.showLockTaskToast(); 4294 return false; 4295 } 4296 } 4297 if (mController != null) { 4298 // Find the first activity that is not finishing. 4299 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4300 if (next != null) { 4301 // ask watcher if this is allowed 4302 boolean resumeOK = true; 4303 try { 4304 resumeOK = mController.activityResuming(next.packageName); 4305 } catch (RemoteException e) { 4306 mController = null; 4307 Watchdog.getInstance().setActivityController(null); 4308 } 4309 4310 if (!resumeOK) { 4311 Slog.i(TAG, "Not finishing activity because controller resumed"); 4312 return false; 4313 } 4314 } 4315 } 4316 final long origId = Binder.clearCallingIdentity(); 4317 try { 4318 boolean res; 4319 if (finishTask && r == rootR) { 4320 // If requested, remove the task that is associated to this activity only if it 4321 // was the root activity in the task. The result code and data is ignored 4322 // because we don't support returning them across task boundaries. 4323 res = removeTaskByIdLocked(tr.taskId, false); 4324 if (!res) { 4325 Slog.i(TAG, "Removing task failed to finish activity"); 4326 } 4327 } else { 4328 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4329 resultData, "app-request", true); 4330 if (!res) { 4331 Slog.i(TAG, "Failed to finish by app-request"); 4332 } 4333 } 4334 return res; 4335 } finally { 4336 Binder.restoreCallingIdentity(origId); 4337 } 4338 } 4339 } 4340 4341 @Override finishHeavyWeightApp()4342 public final void finishHeavyWeightApp() { 4343 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4344 != PackageManager.PERMISSION_GRANTED) { 4345 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4346 + Binder.getCallingPid() 4347 + ", uid=" + Binder.getCallingUid() 4348 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4349 Slog.w(TAG, msg); 4350 throw new SecurityException(msg); 4351 } 4352 4353 synchronized(this) { 4354 if (mHeavyWeightProcess == null) { 4355 return; 4356 } 4357 4358 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4359 mHeavyWeightProcess.activities); 4360 for (int i=0; i<activities.size(); i++) { 4361 ActivityRecord r = activities.get(i); 4362 if (!r.finishing) { 4363 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4364 null, "finish-heavy", true); 4365 } 4366 } 4367 4368 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4369 mHeavyWeightProcess.userId, 0)); 4370 mHeavyWeightProcess = null; 4371 } 4372 } 4373 4374 @Override crashApplication(int uid, int initialPid, String packageName, String message)4375 public void crashApplication(int uid, int initialPid, String packageName, 4376 String message) { 4377 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4378 != PackageManager.PERMISSION_GRANTED) { 4379 String msg = "Permission Denial: crashApplication() from pid=" 4380 + Binder.getCallingPid() 4381 + ", uid=" + Binder.getCallingUid() 4382 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4383 Slog.w(TAG, msg); 4384 throw new SecurityException(msg); 4385 } 4386 4387 synchronized(this) { 4388 ProcessRecord proc = null; 4389 4390 // Figure out which process to kill. We don't trust that initialPid 4391 // still has any relation to current pids, so must scan through the 4392 // list. 4393 synchronized (mPidsSelfLocked) { 4394 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4395 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4396 if (p.uid != uid) { 4397 continue; 4398 } 4399 if (p.pid == initialPid) { 4400 proc = p; 4401 break; 4402 } 4403 if (p.pkgList.containsKey(packageName)) { 4404 proc = p; 4405 } 4406 } 4407 } 4408 4409 if (proc == null) { 4410 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4411 + " initialPid=" + initialPid 4412 + " packageName=" + packageName); 4413 return; 4414 } 4415 4416 if (proc.thread != null) { 4417 if (proc.pid == Process.myPid()) { 4418 Log.w(TAG, "crashApplication: trying to crash self!"); 4419 return; 4420 } 4421 long ident = Binder.clearCallingIdentity(); 4422 try { 4423 proc.thread.scheduleCrash(message); 4424 } catch (RemoteException e) { 4425 } 4426 Binder.restoreCallingIdentity(ident); 4427 } 4428 } 4429 } 4430 4431 @Override finishSubActivity(IBinder token, String resultWho, int requestCode)4432 public final void finishSubActivity(IBinder token, String resultWho, 4433 int requestCode) { 4434 synchronized(this) { 4435 final long origId = Binder.clearCallingIdentity(); 4436 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4437 if (r != null) { 4438 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4439 } 4440 Binder.restoreCallingIdentity(origId); 4441 } 4442 } 4443 4444 @Override finishActivityAffinity(IBinder token)4445 public boolean finishActivityAffinity(IBinder token) { 4446 synchronized(this) { 4447 final long origId = Binder.clearCallingIdentity(); 4448 try { 4449 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4450 4451 ActivityRecord rootR = r.task.getRootActivity(); 4452 // Do not allow task to finish in Lock Task mode. 4453 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4454 if (rootR == r) { 4455 mStackSupervisor.showLockTaskToast(); 4456 return false; 4457 } 4458 } 4459 boolean res = false; 4460 if (r != null) { 4461 res = r.task.stack.finishActivityAffinityLocked(r); 4462 } 4463 return res; 4464 } finally { 4465 Binder.restoreCallingIdentity(origId); 4466 } 4467 } 4468 } 4469 4470 @Override finishVoiceTask(IVoiceInteractionSession session)4471 public void finishVoiceTask(IVoiceInteractionSession session) { 4472 synchronized(this) { 4473 final long origId = Binder.clearCallingIdentity(); 4474 try { 4475 mStackSupervisor.finishVoiceTask(session); 4476 } finally { 4477 Binder.restoreCallingIdentity(origId); 4478 } 4479 } 4480 4481 } 4482 4483 @Override releaseActivityInstance(IBinder token)4484 public boolean releaseActivityInstance(IBinder token) { 4485 synchronized(this) { 4486 final long origId = Binder.clearCallingIdentity(); 4487 try { 4488 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4489 if (r.task == null || r.task.stack == null) { 4490 return false; 4491 } 4492 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4493 } finally { 4494 Binder.restoreCallingIdentity(origId); 4495 } 4496 } 4497 } 4498 4499 @Override releaseSomeActivities(IApplicationThread appInt)4500 public void releaseSomeActivities(IApplicationThread appInt) { 4501 synchronized(this) { 4502 final long origId = Binder.clearCallingIdentity(); 4503 try { 4504 ProcessRecord app = getRecordForAppLocked(appInt); 4505 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4506 } finally { 4507 Binder.restoreCallingIdentity(origId); 4508 } 4509 } 4510 } 4511 4512 @Override willActivityBeVisible(IBinder token)4513 public boolean willActivityBeVisible(IBinder token) { 4514 synchronized(this) { 4515 ActivityStack stack = ActivityRecord.getStackLocked(token); 4516 if (stack != null) { 4517 return stack.willActivityBeVisibleLocked(token); 4518 } 4519 return false; 4520 } 4521 } 4522 4523 @Override overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim)4524 public void overridePendingTransition(IBinder token, String packageName, 4525 int enterAnim, int exitAnim) { 4526 synchronized(this) { 4527 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4528 if (self == null) { 4529 return; 4530 } 4531 4532 final long origId = Binder.clearCallingIdentity(); 4533 4534 if (self.state == ActivityState.RESUMED 4535 || self.state == ActivityState.PAUSING) { 4536 mWindowManager.overridePendingAppTransition(packageName, 4537 enterAnim, exitAnim, null); 4538 } 4539 4540 Binder.restoreCallingIdentity(origId); 4541 } 4542 } 4543 4544 /** 4545 * Main function for removing an existing process from the activity manager 4546 * as a result of that process going away. Clears out all connections 4547 * to the process. 4548 */ handleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart)4549 private final void handleAppDiedLocked(ProcessRecord app, 4550 boolean restarting, boolean allowRestart) { 4551 int pid = app.pid; 4552 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4553 if (!kept && !restarting) { 4554 removeLruProcessLocked(app); 4555 if (pid > 0) { 4556 ProcessList.remove(pid); 4557 } 4558 } 4559 4560 if (mProfileProc == app) { 4561 clearProfilerLocked(); 4562 } 4563 4564 // Remove this application's activities from active lists. 4565 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4566 4567 app.activities.clear(); 4568 4569 if (app.instrumentationClass != null) { 4570 Slog.w(TAG, "Crash of app " + app.processName 4571 + " running instrumentation " + app.instrumentationClass); 4572 Bundle info = new Bundle(); 4573 info.putString("shortMsg", "Process crashed."); 4574 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4575 } 4576 4577 if (!restarting) { 4578 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4579 // If there was nothing to resume, and we are not already 4580 // restarting this process, but there is a visible activity that 4581 // is hosted by the process... then make sure all visible 4582 // activities are running, taking care of restarting this 4583 // process. 4584 if (hasVisibleActivities) { 4585 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4586 } 4587 } 4588 } 4589 } 4590 getLRURecordIndexForAppLocked(IApplicationThread thread)4591 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4592 IBinder threadBinder = thread.asBinder(); 4593 // Find the application record. 4594 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4595 ProcessRecord rec = mLruProcesses.get(i); 4596 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4597 return i; 4598 } 4599 } 4600 return -1; 4601 } 4602 getRecordForAppLocked( IApplicationThread thread)4603 final ProcessRecord getRecordForAppLocked( 4604 IApplicationThread thread) { 4605 if (thread == null) { 4606 return null; 4607 } 4608 4609 int appIndex = getLRURecordIndexForAppLocked(thread); 4610 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4611 } 4612 doLowMemReportIfNeededLocked(ProcessRecord dyingProc)4613 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4614 // If there are no longer any background processes running, 4615 // and the app that died was not running instrumentation, 4616 // then tell everyone we are now low on memory. 4617 boolean haveBg = false; 4618 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4619 ProcessRecord rec = mLruProcesses.get(i); 4620 if (rec.thread != null 4621 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4622 haveBg = true; 4623 break; 4624 } 4625 } 4626 4627 if (!haveBg) { 4628 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4629 if (doReport) { 4630 long now = SystemClock.uptimeMillis(); 4631 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4632 doReport = false; 4633 } else { 4634 mLastMemUsageReportTime = now; 4635 } 4636 } 4637 final ArrayList<ProcessMemInfo> memInfos 4638 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4639 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4640 long now = SystemClock.uptimeMillis(); 4641 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4642 ProcessRecord rec = mLruProcesses.get(i); 4643 if (rec == dyingProc || rec.thread == null) { 4644 continue; 4645 } 4646 if (doReport) { 4647 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4648 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4649 } 4650 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4651 // The low memory report is overriding any current 4652 // state for a GC request. Make sure to do 4653 // heavy/important/visible/foreground processes first. 4654 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4655 rec.lastRequestedGc = 0; 4656 } else { 4657 rec.lastRequestedGc = rec.lastLowMemory; 4658 } 4659 rec.reportLowMemory = true; 4660 rec.lastLowMemory = now; 4661 mProcessesToGc.remove(rec); 4662 addProcessToGcListLocked(rec); 4663 } 4664 } 4665 if (doReport) { 4666 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4667 mHandler.sendMessage(msg); 4668 } 4669 scheduleAppGcsLocked(); 4670 } 4671 } 4672 appDiedLocked(ProcessRecord app)4673 final void appDiedLocked(ProcessRecord app) { 4674 appDiedLocked(app, app.pid, app.thread); 4675 } 4676 appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread)4677 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4678 // First check if this ProcessRecord is actually active for the pid. 4679 synchronized (mPidsSelfLocked) { 4680 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4681 if (curProc != app) { 4682 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4683 return; 4684 } 4685 } 4686 4687 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4688 synchronized (stats) { 4689 stats.noteProcessDiedLocked(app.info.uid, pid); 4690 } 4691 4692 if (!app.killed) { 4693 Process.killProcessQuiet(pid); 4694 Process.killProcessGroup(app.info.uid, pid); 4695 app.killed = true; 4696 } 4697 4698 // Clean up already done if the process has been re-started. 4699 if (app.pid == pid && app.thread != null && 4700 app.thread.asBinder() == thread.asBinder()) { 4701 boolean doLowMem = app.instrumentationClass == null; 4702 boolean doOomAdj = doLowMem; 4703 if (!app.killedByAm) { 4704 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4705 + ") has died"); 4706 mAllowLowerMemLevel = true; 4707 } else { 4708 // Note that we always want to do oom adj to update our state with the 4709 // new number of procs. 4710 mAllowLowerMemLevel = false; 4711 doLowMem = false; 4712 } 4713 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4714 if (DEBUG_CLEANUP) Slog.v( 4715 TAG, "Dying app: " + app + ", pid: " + pid 4716 + ", thread: " + thread.asBinder()); 4717 handleAppDiedLocked(app, false, true); 4718 4719 if (doOomAdj) { 4720 updateOomAdjLocked(); 4721 } 4722 if (doLowMem) { 4723 doLowMemReportIfNeededLocked(app); 4724 } 4725 } else if (app.pid != pid) { 4726 // A new process has already been started. 4727 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4728 + ") has died and restarted (pid " + app.pid + ")."); 4729 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4730 } else if (DEBUG_PROCESSES) { 4731 Slog.d(TAG, "Received spurious death notification for thread " 4732 + thread.asBinder()); 4733 } 4734 } 4735 4736 /** 4737 * If a stack trace dump file is configured, dump process stack traces. 4738 * @param clearTraces causes the dump file to be erased prior to the new 4739 * traces being written, if true; when false, the new traces will be 4740 * appended to any existing file content. 4741 * @param firstPids of dalvik VM processes to dump stack traces for first 4742 * @param lastPids of dalvik VM processes to dump stack traces for last 4743 * @param nativeProcs optional list of native process names to dump stack crawls 4744 * @return file containing stack traces, or null if no dump file is configured 4745 */ dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs)4746 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4747 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4748 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4749 if (tracesPath == null || tracesPath.length() == 0) { 4750 return null; 4751 } 4752 4753 File tracesFile = new File(tracesPath); 4754 try { 4755 File tracesDir = tracesFile.getParentFile(); 4756 if (!tracesDir.exists()) { 4757 tracesDir.mkdirs(); 4758 if (!SELinux.restorecon(tracesDir)) { 4759 return null; 4760 } 4761 } 4762 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4763 4764 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4765 tracesFile.createNewFile(); 4766 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4767 } catch (IOException e) { 4768 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4769 return null; 4770 } 4771 4772 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4773 return tracesFile; 4774 } 4775 dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs)4776 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4777 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4778 // Use a FileObserver to detect when traces finish writing. 4779 // The order of traces is considered important to maintain for legibility. 4780 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4781 @Override 4782 public synchronized void onEvent(int event, String path) { notify(); } 4783 }; 4784 4785 try { 4786 observer.startWatching(); 4787 4788 // First collect all of the stacks of the most important pids. 4789 if (firstPids != null) { 4790 try { 4791 int num = firstPids.size(); 4792 for (int i = 0; i < num; i++) { 4793 synchronized (observer) { 4794 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4795 observer.wait(200); // Wait for write-close, give up after 200msec 4796 } 4797 } 4798 } catch (InterruptedException e) { 4799 Slog.wtf(TAG, e); 4800 } 4801 } 4802 4803 // Next collect the stacks of the native pids 4804 if (nativeProcs != null) { 4805 int[] pids = Process.getPidsForCommands(nativeProcs); 4806 if (pids != null) { 4807 for (int pid : pids) { 4808 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4809 } 4810 } 4811 } 4812 4813 // Lastly, measure CPU usage. 4814 if (processCpuTracker != null) { 4815 processCpuTracker.init(); 4816 System.gc(); 4817 processCpuTracker.update(); 4818 try { 4819 synchronized (processCpuTracker) { 4820 processCpuTracker.wait(500); // measure over 1/2 second. 4821 } 4822 } catch (InterruptedException e) { 4823 } 4824 processCpuTracker.update(); 4825 4826 // We'll take the stack crawls of just the top apps using CPU. 4827 final int N = processCpuTracker.countWorkingStats(); 4828 int numProcs = 0; 4829 for (int i=0; i<N && numProcs<5; i++) { 4830 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4831 if (lastPids.indexOfKey(stats.pid) >= 0) { 4832 numProcs++; 4833 try { 4834 synchronized (observer) { 4835 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4836 observer.wait(200); // Wait for write-close, give up after 200msec 4837 } 4838 } catch (InterruptedException e) { 4839 Slog.wtf(TAG, e); 4840 } 4841 4842 } 4843 } 4844 } 4845 } finally { 4846 observer.stopWatching(); 4847 } 4848 } 4849 logAppTooSlow(ProcessRecord app, long startTime, String msg)4850 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4851 if (true || IS_USER_BUILD) { 4852 return; 4853 } 4854 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4855 if (tracesPath == null || tracesPath.length() == 0) { 4856 return; 4857 } 4858 4859 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4860 StrictMode.allowThreadDiskWrites(); 4861 try { 4862 final File tracesFile = new File(tracesPath); 4863 final File tracesDir = tracesFile.getParentFile(); 4864 final File tracesTmp = new File(tracesDir, "__tmp__"); 4865 try { 4866 if (!tracesDir.exists()) { 4867 tracesDir.mkdirs(); 4868 if (!SELinux.restorecon(tracesDir.getPath())) { 4869 return; 4870 } 4871 } 4872 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4873 4874 if (tracesFile.exists()) { 4875 tracesTmp.delete(); 4876 tracesFile.renameTo(tracesTmp); 4877 } 4878 StringBuilder sb = new StringBuilder(); 4879 Time tobj = new Time(); 4880 tobj.set(System.currentTimeMillis()); 4881 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4882 sb.append(": "); 4883 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4884 sb.append(" since "); 4885 sb.append(msg); 4886 FileOutputStream fos = new FileOutputStream(tracesFile); 4887 fos.write(sb.toString().getBytes()); 4888 if (app == null) { 4889 fos.write("\n*** No application process!".getBytes()); 4890 } 4891 fos.close(); 4892 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4893 } catch (IOException e) { 4894 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4895 return; 4896 } 4897 4898 if (app != null) { 4899 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4900 firstPids.add(app.pid); 4901 dumpStackTraces(tracesPath, firstPids, null, null, null); 4902 } 4903 4904 File lastTracesFile = null; 4905 File curTracesFile = null; 4906 for (int i=9; i>=0; i--) { 4907 String name = String.format(Locale.US, "slow%02d.txt", i); 4908 curTracesFile = new File(tracesDir, name); 4909 if (curTracesFile.exists()) { 4910 if (lastTracesFile != null) { 4911 curTracesFile.renameTo(lastTracesFile); 4912 } else { 4913 curTracesFile.delete(); 4914 } 4915 } 4916 lastTracesFile = curTracesFile; 4917 } 4918 tracesFile.renameTo(curTracesFile); 4919 if (tracesTmp.exists()) { 4920 tracesTmp.renameTo(tracesFile); 4921 } 4922 } finally { 4923 StrictMode.setThreadPolicy(oldPolicy); 4924 } 4925 } 4926 appNotResponding(ProcessRecord app, ActivityRecord activity, ActivityRecord parent, boolean aboveSystem, final String annotation)4927 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4928 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4929 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4930 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4931 4932 if (mController != null) { 4933 try { 4934 // 0 == continue, -1 = kill process immediately 4935 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4936 if (res < 0 && app.pid != MY_PID) { 4937 app.kill("anr", true); 4938 } 4939 } catch (RemoteException e) { 4940 mController = null; 4941 Watchdog.getInstance().setActivityController(null); 4942 } 4943 } 4944 4945 long anrTime = SystemClock.uptimeMillis(); 4946 if (MONITOR_CPU_USAGE) { 4947 updateCpuStatsNow(); 4948 } 4949 4950 synchronized (this) { 4951 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4952 if (mShuttingDown) { 4953 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4954 return; 4955 } else if (app.notResponding) { 4956 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4957 return; 4958 } else if (app.crashing) { 4959 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4960 return; 4961 } 4962 4963 // In case we come through here for the same app before completing 4964 // this one, mark as anring now so we will bail out. 4965 app.notResponding = true; 4966 4967 // Log the ANR to the event log. 4968 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4969 app.processName, app.info.flags, annotation); 4970 4971 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4972 firstPids.add(app.pid); 4973 4974 int parentPid = app.pid; 4975 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4976 if (parentPid != app.pid) firstPids.add(parentPid); 4977 4978 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4979 4980 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4981 ProcessRecord r = mLruProcesses.get(i); 4982 if (r != null && r.thread != null) { 4983 int pid = r.pid; 4984 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4985 if (r.persistent) { 4986 firstPids.add(pid); 4987 } else { 4988 lastPids.put(pid, Boolean.TRUE); 4989 } 4990 } 4991 } 4992 } 4993 } 4994 4995 // Log the ANR to the main log. 4996 StringBuilder info = new StringBuilder(); 4997 info.setLength(0); 4998 info.append("ANR in ").append(app.processName); 4999 if (activity != null && activity.shortComponentName != null) { 5000 info.append(" (").append(activity.shortComponentName).append(")"); 5001 } 5002 info.append("\n"); 5003 info.append("PID: ").append(app.pid).append("\n"); 5004 if (annotation != null) { 5005 info.append("Reason: ").append(annotation).append("\n"); 5006 } 5007 if (parent != null && parent != activity) { 5008 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5009 } 5010 5011 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5012 5013 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5014 NATIVE_STACKS_OF_INTEREST); 5015 5016 String cpuInfo = null; 5017 if (MONITOR_CPU_USAGE) { 5018 updateCpuStatsNow(); 5019 synchronized (mProcessCpuTracker) { 5020 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5021 } 5022 info.append(processCpuTracker.printCurrentLoad()); 5023 info.append(cpuInfo); 5024 } 5025 5026 info.append(processCpuTracker.printCurrentState(anrTime)); 5027 5028 Slog.e(TAG, info.toString()); 5029 if (tracesFile == null) { 5030 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5031 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5032 } 5033 5034 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5035 cpuInfo, tracesFile, null); 5036 5037 if (mController != null) { 5038 try { 5039 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5040 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5041 if (res != 0) { 5042 if (res < 0 && app.pid != MY_PID) { 5043 app.kill("anr", true); 5044 } else { 5045 synchronized (this) { 5046 mServices.scheduleServiceTimeoutLocked(app); 5047 } 5048 } 5049 return; 5050 } 5051 } catch (RemoteException e) { 5052 mController = null; 5053 Watchdog.getInstance().setActivityController(null); 5054 } 5055 } 5056 5057 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5058 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5059 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5060 5061 synchronized (this) { 5062 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5063 5064 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5065 app.kill("bg anr", true); 5066 return; 5067 } 5068 5069 // Set the app's notResponding state, and look up the errorReportReceiver 5070 makeAppNotRespondingLocked(app, 5071 activity != null ? activity.shortComponentName : null, 5072 annotation != null ? "ANR " + annotation : "ANR", 5073 info.toString()); 5074 5075 // Bring up the infamous App Not Responding dialog 5076 Message msg = Message.obtain(); 5077 HashMap<String, Object> map = new HashMap<String, Object>(); 5078 msg.what = SHOW_NOT_RESPONDING_MSG; 5079 msg.obj = map; 5080 msg.arg1 = aboveSystem ? 1 : 0; 5081 map.put("app", app); 5082 if (activity != null) { 5083 map.put("activity", activity); 5084 } 5085 5086 mHandler.sendMessage(msg); 5087 } 5088 } 5089 showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next)5090 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5091 if (!mLaunchWarningShown) { 5092 mLaunchWarningShown = true; 5093 mHandler.post(new Runnable() { 5094 @Override 5095 public void run() { 5096 synchronized (ActivityManagerService.this) { 5097 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5098 d.show(); 5099 mHandler.postDelayed(new Runnable() { 5100 @Override 5101 public void run() { 5102 synchronized (ActivityManagerService.this) { 5103 d.dismiss(); 5104 mLaunchWarningShown = false; 5105 } 5106 } 5107 }, 4000); 5108 } 5109 } 5110 }); 5111 } 5112 } 5113 5114 @Override clearApplicationUserData(final String packageName, final IPackageDataObserver observer, int userId)5115 public boolean clearApplicationUserData(final String packageName, 5116 final IPackageDataObserver observer, int userId) { 5117 enforceNotIsolatedCaller("clearApplicationUserData"); 5118 int uid = Binder.getCallingUid(); 5119 int pid = Binder.getCallingPid(); 5120 userId = handleIncomingUser(pid, uid, 5121 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5122 long callingId = Binder.clearCallingIdentity(); 5123 try { 5124 IPackageManager pm = AppGlobals.getPackageManager(); 5125 int pkgUid = -1; 5126 synchronized(this) { 5127 try { 5128 pkgUid = pm.getPackageUid(packageName, userId); 5129 } catch (RemoteException e) { 5130 } 5131 if (pkgUid == -1) { 5132 Slog.w(TAG, "Invalid packageName: " + packageName); 5133 if (observer != null) { 5134 try { 5135 observer.onRemoveCompleted(packageName, false); 5136 } catch (RemoteException e) { 5137 Slog.i(TAG, "Observer no longer exists."); 5138 } 5139 } 5140 return false; 5141 } 5142 if (uid == pkgUid || checkComponentPermission( 5143 android.Manifest.permission.CLEAR_APP_USER_DATA, 5144 pid, uid, -1, true) 5145 == PackageManager.PERMISSION_GRANTED) { 5146 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5147 } else { 5148 throw new SecurityException("PID " + pid + " does not have permission " 5149 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5150 + " of package " + packageName); 5151 } 5152 5153 // Remove all tasks match the cleared application package and user 5154 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5155 final TaskRecord tr = mRecentTasks.get(i); 5156 final String taskPackageName = 5157 tr.getBaseIntent().getComponent().getPackageName(); 5158 if (tr.userId != userId) continue; 5159 if (!taskPackageName.equals(packageName)) continue; 5160 removeTaskByIdLocked(tr.taskId, false); 5161 } 5162 } 5163 5164 try { 5165 // Clear application user data 5166 pm.clearApplicationUserData(packageName, observer, userId); 5167 5168 synchronized(this) { 5169 // Remove all permissions granted from/to this package 5170 removeUriPermissionsForPackageLocked(packageName, userId, true); 5171 } 5172 5173 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5174 Uri.fromParts("package", packageName, null)); 5175 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5176 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5177 null, null, 0, null, null, null, false, false, userId); 5178 } catch (RemoteException e) { 5179 } 5180 } finally { 5181 Binder.restoreCallingIdentity(callingId); 5182 } 5183 return true; 5184 } 5185 5186 @Override killBackgroundProcesses(final String packageName, int userId)5187 public void killBackgroundProcesses(final String packageName, int userId) { 5188 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5189 != PackageManager.PERMISSION_GRANTED && 5190 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5191 != PackageManager.PERMISSION_GRANTED) { 5192 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5193 + Binder.getCallingPid() 5194 + ", uid=" + Binder.getCallingUid() 5195 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5196 Slog.w(TAG, msg); 5197 throw new SecurityException(msg); 5198 } 5199 5200 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5201 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5202 long callingId = Binder.clearCallingIdentity(); 5203 try { 5204 IPackageManager pm = AppGlobals.getPackageManager(); 5205 synchronized(this) { 5206 int appId = -1; 5207 try { 5208 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5209 } catch (RemoteException e) { 5210 } 5211 if (appId == -1) { 5212 Slog.w(TAG, "Invalid packageName: " + packageName); 5213 return; 5214 } 5215 killPackageProcessesLocked(packageName, appId, userId, 5216 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5217 } 5218 } finally { 5219 Binder.restoreCallingIdentity(callingId); 5220 } 5221 } 5222 5223 @Override killAllBackgroundProcesses()5224 public void killAllBackgroundProcesses() { 5225 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5226 != PackageManager.PERMISSION_GRANTED) { 5227 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5228 + Binder.getCallingPid() 5229 + ", uid=" + Binder.getCallingUid() 5230 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5231 Slog.w(TAG, msg); 5232 throw new SecurityException(msg); 5233 } 5234 5235 long callingId = Binder.clearCallingIdentity(); 5236 try { 5237 synchronized(this) { 5238 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5239 final int NP = mProcessNames.getMap().size(); 5240 for (int ip=0; ip<NP; ip++) { 5241 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5242 final int NA = apps.size(); 5243 for (int ia=0; ia<NA; ia++) { 5244 ProcessRecord app = apps.valueAt(ia); 5245 if (app.persistent) { 5246 // we don't kill persistent processes 5247 continue; 5248 } 5249 if (app.removed) { 5250 procs.add(app); 5251 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5252 app.removed = true; 5253 procs.add(app); 5254 } 5255 } 5256 } 5257 5258 int N = procs.size(); 5259 for (int i=0; i<N; i++) { 5260 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5261 } 5262 mAllowLowerMemLevel = true; 5263 updateOomAdjLocked(); 5264 doLowMemReportIfNeededLocked(null); 5265 } 5266 } finally { 5267 Binder.restoreCallingIdentity(callingId); 5268 } 5269 } 5270 5271 @Override forceStopPackage(final String packageName, int userId)5272 public void forceStopPackage(final String packageName, int userId) { 5273 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5274 != PackageManager.PERMISSION_GRANTED) { 5275 String msg = "Permission Denial: forceStopPackage() from pid=" 5276 + Binder.getCallingPid() 5277 + ", uid=" + Binder.getCallingUid() 5278 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5279 Slog.w(TAG, msg); 5280 throw new SecurityException(msg); 5281 } 5282 final int callingPid = Binder.getCallingPid(); 5283 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5284 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5285 long callingId = Binder.clearCallingIdentity(); 5286 try { 5287 IPackageManager pm = AppGlobals.getPackageManager(); 5288 synchronized(this) { 5289 int[] users = userId == UserHandle.USER_ALL 5290 ? getUsersLocked() : new int[] { userId }; 5291 for (int user : users) { 5292 int pkgUid = -1; 5293 try { 5294 pkgUid = pm.getPackageUid(packageName, user); 5295 } catch (RemoteException e) { 5296 } 5297 if (pkgUid == -1) { 5298 Slog.w(TAG, "Invalid packageName: " + packageName); 5299 continue; 5300 } 5301 try { 5302 pm.setPackageStoppedState(packageName, true, user); 5303 } catch (RemoteException e) { 5304 } catch (IllegalArgumentException e) { 5305 Slog.w(TAG, "Failed trying to unstop package " 5306 + packageName + ": " + e); 5307 } 5308 if (isUserRunningLocked(user, false)) { 5309 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5310 } 5311 } 5312 } 5313 } finally { 5314 Binder.restoreCallingIdentity(callingId); 5315 } 5316 } 5317 5318 @Override addPackageDependency(String packageName)5319 public void addPackageDependency(String packageName) { 5320 synchronized (this) { 5321 int callingPid = Binder.getCallingPid(); 5322 if (callingPid == Process.myPid()) { 5323 // Yeah, um, no. 5324 return; 5325 } 5326 ProcessRecord proc; 5327 synchronized (mPidsSelfLocked) { 5328 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5329 } 5330 if (proc != null) { 5331 if (proc.pkgDeps == null) { 5332 proc.pkgDeps = new ArraySet<String>(1); 5333 } 5334 proc.pkgDeps.add(packageName); 5335 } 5336 } 5337 } 5338 5339 /* 5340 * The pkg name and app id have to be specified. 5341 */ 5342 @Override killApplicationWithAppId(String pkg, int appid, String reason)5343 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5344 if (pkg == null) { 5345 return; 5346 } 5347 // Make sure the uid is valid. 5348 if (appid < 0) { 5349 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5350 return; 5351 } 5352 int callerUid = Binder.getCallingUid(); 5353 // Only the system server can kill an application 5354 if (callerUid == Process.SYSTEM_UID) { 5355 // Post an aysnc message to kill the application 5356 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5357 msg.arg1 = appid; 5358 msg.arg2 = 0; 5359 Bundle bundle = new Bundle(); 5360 bundle.putString("pkg", pkg); 5361 bundle.putString("reason", reason); 5362 msg.obj = bundle; 5363 mHandler.sendMessage(msg); 5364 } else { 5365 throw new SecurityException(callerUid + " cannot kill pkg: " + 5366 pkg); 5367 } 5368 } 5369 5370 @Override closeSystemDialogs(String reason)5371 public void closeSystemDialogs(String reason) { 5372 enforceNotIsolatedCaller("closeSystemDialogs"); 5373 5374 final int pid = Binder.getCallingPid(); 5375 final int uid = Binder.getCallingUid(); 5376 final long origId = Binder.clearCallingIdentity(); 5377 try { 5378 synchronized (this) { 5379 // Only allow this from foreground processes, so that background 5380 // applications can't abuse it to prevent system UI from being shown. 5381 if (uid >= Process.FIRST_APPLICATION_UID) { 5382 ProcessRecord proc; 5383 synchronized (mPidsSelfLocked) { 5384 proc = mPidsSelfLocked.get(pid); 5385 } 5386 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5387 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5388 + " from background process " + proc); 5389 return; 5390 } 5391 } 5392 closeSystemDialogsLocked(reason); 5393 } 5394 } finally { 5395 Binder.restoreCallingIdentity(origId); 5396 } 5397 } 5398 closeSystemDialogsLocked(String reason)5399 void closeSystemDialogsLocked(String reason) { 5400 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5401 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5402 | Intent.FLAG_RECEIVER_FOREGROUND); 5403 if (reason != null) { 5404 intent.putExtra("reason", reason); 5405 } 5406 mWindowManager.closeSystemDialogs(reason); 5407 5408 mStackSupervisor.closeSystemDialogsLocked(); 5409 5410 broadcastIntentLocked(null, null, intent, null, 5411 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5412 Process.SYSTEM_UID, UserHandle.USER_ALL); 5413 } 5414 5415 @Override getProcessMemoryInfo(int[] pids)5416 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5417 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5418 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5419 for (int i=pids.length-1; i>=0; i--) { 5420 ProcessRecord proc; 5421 int oomAdj; 5422 synchronized (this) { 5423 synchronized (mPidsSelfLocked) { 5424 proc = mPidsSelfLocked.get(pids[i]); 5425 oomAdj = proc != null ? proc.setAdj : 0; 5426 } 5427 } 5428 infos[i] = new Debug.MemoryInfo(); 5429 Debug.getMemoryInfo(pids[i], infos[i]); 5430 if (proc != null) { 5431 synchronized (this) { 5432 if (proc.thread != null && proc.setAdj == oomAdj) { 5433 // Record this for posterity if the process has been stable. 5434 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5435 infos[i].getTotalUss(), false, proc.pkgList); 5436 } 5437 } 5438 } 5439 } 5440 return infos; 5441 } 5442 5443 @Override getProcessPss(int[] pids)5444 public long[] getProcessPss(int[] pids) { 5445 enforceNotIsolatedCaller("getProcessPss"); 5446 long[] pss = new long[pids.length]; 5447 for (int i=pids.length-1; i>=0; i--) { 5448 ProcessRecord proc; 5449 int oomAdj; 5450 synchronized (this) { 5451 synchronized (mPidsSelfLocked) { 5452 proc = mPidsSelfLocked.get(pids[i]); 5453 oomAdj = proc != null ? proc.setAdj : 0; 5454 } 5455 } 5456 long[] tmpUss = new long[1]; 5457 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5458 if (proc != null) { 5459 synchronized (this) { 5460 if (proc.thread != null && proc.setAdj == oomAdj) { 5461 // Record this for posterity if the process has been stable. 5462 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5463 } 5464 } 5465 } 5466 } 5467 return pss; 5468 } 5469 5470 @Override killApplicationProcess(String processName, int uid)5471 public void killApplicationProcess(String processName, int uid) { 5472 if (processName == null) { 5473 return; 5474 } 5475 5476 int callerUid = Binder.getCallingUid(); 5477 // Only the system server can kill an application 5478 if (callerUid == Process.SYSTEM_UID) { 5479 synchronized (this) { 5480 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5481 if (app != null && app.thread != null) { 5482 try { 5483 app.thread.scheduleSuicide(); 5484 } catch (RemoteException e) { 5485 // If the other end already died, then our work here is done. 5486 } 5487 } else { 5488 Slog.w(TAG, "Process/uid not found attempting kill of " 5489 + processName + " / " + uid); 5490 } 5491 } 5492 } else { 5493 throw new SecurityException(callerUid + " cannot kill app process: " + 5494 processName); 5495 } 5496 } 5497 forceStopPackageLocked(final String packageName, int uid, String reason)5498 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5499 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5500 false, true, false, false, UserHandle.getUserId(uid), reason); 5501 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5502 Uri.fromParts("package", packageName, null)); 5503 if (!mProcessesReady) { 5504 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5505 | Intent.FLAG_RECEIVER_FOREGROUND); 5506 } 5507 intent.putExtra(Intent.EXTRA_UID, uid); 5508 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5509 broadcastIntentLocked(null, null, intent, 5510 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5511 false, false, 5512 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5513 } 5514 forceStopUserLocked(int userId, String reason)5515 private void forceStopUserLocked(int userId, String reason) { 5516 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5517 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5518 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5519 | Intent.FLAG_RECEIVER_FOREGROUND); 5520 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5521 broadcastIntentLocked(null, null, intent, 5522 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5523 false, false, 5524 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5525 } 5526 killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, String reason)5527 private final boolean killPackageProcessesLocked(String packageName, int appId, 5528 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5529 boolean doit, boolean evenPersistent, String reason) { 5530 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5531 5532 // Remove all processes this package may have touched: all with the 5533 // same UID (except for the system or root user), and all whose name 5534 // matches the package name. 5535 final int NP = mProcessNames.getMap().size(); 5536 for (int ip=0; ip<NP; ip++) { 5537 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5538 final int NA = apps.size(); 5539 for (int ia=0; ia<NA; ia++) { 5540 ProcessRecord app = apps.valueAt(ia); 5541 if (app.persistent && !evenPersistent) { 5542 // we don't kill persistent processes 5543 continue; 5544 } 5545 if (app.removed) { 5546 if (doit) { 5547 procs.add(app); 5548 } 5549 continue; 5550 } 5551 5552 // Skip process if it doesn't meet our oom adj requirement. 5553 if (app.setAdj < minOomAdj) { 5554 continue; 5555 } 5556 5557 // If no package is specified, we call all processes under the 5558 // give user id. 5559 if (packageName == null) { 5560 if (app.userId != userId) { 5561 continue; 5562 } 5563 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5564 continue; 5565 } 5566 // Package has been specified, we want to hit all processes 5567 // that match it. We need to qualify this by the processes 5568 // that are running under the specified app and user ID. 5569 } else { 5570 final boolean isDep = app.pkgDeps != null 5571 && app.pkgDeps.contains(packageName); 5572 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5573 continue; 5574 } 5575 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5576 continue; 5577 } 5578 if (!app.pkgList.containsKey(packageName) && !isDep) { 5579 continue; 5580 } 5581 } 5582 5583 // Process has passed all conditions, kill it! 5584 if (!doit) { 5585 return true; 5586 } 5587 app.removed = true; 5588 procs.add(app); 5589 } 5590 } 5591 5592 int N = procs.size(); 5593 for (int i=0; i<N; i++) { 5594 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5595 } 5596 updateOomAdjLocked(); 5597 return N > 0; 5598 } 5599 forceStopPackageLocked(String name, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, boolean uninstalling, int userId, String reason)5600 private final boolean forceStopPackageLocked(String name, int appId, 5601 boolean callerWillRestart, boolean purgeCache, boolean doit, 5602 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5603 int i; 5604 int N; 5605 5606 if (userId == UserHandle.USER_ALL && name == null) { 5607 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5608 } 5609 5610 if (appId < 0 && name != null) { 5611 try { 5612 appId = UserHandle.getAppId( 5613 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5614 } catch (RemoteException e) { 5615 } 5616 } 5617 5618 if (doit) { 5619 if (name != null) { 5620 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5621 + " user=" + userId + ": " + reason); 5622 } else { 5623 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5624 } 5625 5626 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5627 for (int ip=pmap.size()-1; ip>=0; ip--) { 5628 SparseArray<Long> ba = pmap.valueAt(ip); 5629 for (i=ba.size()-1; i>=0; i--) { 5630 boolean remove = false; 5631 final int entUid = ba.keyAt(i); 5632 if (name != null) { 5633 if (userId == UserHandle.USER_ALL) { 5634 if (UserHandle.getAppId(entUid) == appId) { 5635 remove = true; 5636 } 5637 } else { 5638 if (entUid == UserHandle.getUid(userId, appId)) { 5639 remove = true; 5640 } 5641 } 5642 } else if (UserHandle.getUserId(entUid) == userId) { 5643 remove = true; 5644 } 5645 if (remove) { 5646 ba.removeAt(i); 5647 } 5648 } 5649 if (ba.size() == 0) { 5650 pmap.removeAt(ip); 5651 } 5652 } 5653 } 5654 5655 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5656 -100, callerWillRestart, true, doit, evenPersistent, 5657 name == null ? ("stop user " + userId) : ("stop " + name)); 5658 5659 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5660 if (!doit) { 5661 return true; 5662 } 5663 didSomething = true; 5664 } 5665 5666 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5667 if (!doit) { 5668 return true; 5669 } 5670 didSomething = true; 5671 } 5672 5673 if (name == null) { 5674 // Remove all sticky broadcasts from this user. 5675 mStickyBroadcasts.remove(userId); 5676 } 5677 5678 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5679 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5680 userId, providers)) { 5681 if (!doit) { 5682 return true; 5683 } 5684 didSomething = true; 5685 } 5686 N = providers.size(); 5687 for (i=0; i<N; i++) { 5688 removeDyingProviderLocked(null, providers.get(i), true); 5689 } 5690 5691 // Remove transient permissions granted from/to this package/user 5692 removeUriPermissionsForPackageLocked(name, userId, false); 5693 5694 if (name == null || uninstalling) { 5695 // Remove pending intents. For now we only do this when force 5696 // stopping users, because we have some problems when doing this 5697 // for packages -- app widgets are not currently cleaned up for 5698 // such packages, so they can be left with bad pending intents. 5699 if (mIntentSenderRecords.size() > 0) { 5700 Iterator<WeakReference<PendingIntentRecord>> it 5701 = mIntentSenderRecords.values().iterator(); 5702 while (it.hasNext()) { 5703 WeakReference<PendingIntentRecord> wpir = it.next(); 5704 if (wpir == null) { 5705 it.remove(); 5706 continue; 5707 } 5708 PendingIntentRecord pir = wpir.get(); 5709 if (pir == null) { 5710 it.remove(); 5711 continue; 5712 } 5713 if (name == null) { 5714 // Stopping user, remove all objects for the user. 5715 if (pir.key.userId != userId) { 5716 // Not the same user, skip it. 5717 continue; 5718 } 5719 } else { 5720 if (UserHandle.getAppId(pir.uid) != appId) { 5721 // Different app id, skip it. 5722 continue; 5723 } 5724 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5725 // Different user, skip it. 5726 continue; 5727 } 5728 if (!pir.key.packageName.equals(name)) { 5729 // Different package, skip it. 5730 continue; 5731 } 5732 } 5733 if (!doit) { 5734 return true; 5735 } 5736 didSomething = true; 5737 it.remove(); 5738 pir.canceled = true; 5739 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5740 pir.key.activity.pendingResults.remove(pir.ref); 5741 } 5742 } 5743 } 5744 } 5745 5746 if (doit) { 5747 if (purgeCache && name != null) { 5748 AttributeCache ac = AttributeCache.instance(); 5749 if (ac != null) { 5750 ac.removePackage(name); 5751 } 5752 } 5753 if (mBooted) { 5754 mStackSupervisor.resumeTopActivitiesLocked(); 5755 mStackSupervisor.scheduleIdleLocked(); 5756 } 5757 } 5758 5759 return didSomething; 5760 } 5761 removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, String reason)5762 private final boolean removeProcessLocked(ProcessRecord app, 5763 boolean callerWillRestart, boolean allowRestart, String reason) { 5764 final String name = app.processName; 5765 final int uid = app.uid; 5766 if (DEBUG_PROCESSES) Slog.d( 5767 TAG, "Force removing proc " + app.toShortString() + " (" + name 5768 + "/" + uid + ")"); 5769 5770 mProcessNames.remove(name, uid); 5771 mIsolatedProcesses.remove(app.uid); 5772 if (mHeavyWeightProcess == app) { 5773 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5774 mHeavyWeightProcess.userId, 0)); 5775 mHeavyWeightProcess = null; 5776 } 5777 boolean needRestart = false; 5778 if (app.pid > 0 && app.pid != MY_PID) { 5779 int pid = app.pid; 5780 synchronized (mPidsSelfLocked) { 5781 mPidsSelfLocked.remove(pid); 5782 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5783 } 5784 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5785 if (app.isolated) { 5786 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5787 } 5788 app.kill(reason, true); 5789 handleAppDiedLocked(app, true, allowRestart); 5790 removeLruProcessLocked(app); 5791 5792 if (app.persistent && !app.isolated) { 5793 if (!callerWillRestart) { 5794 addAppLocked(app.info, false, null /* ABI override */); 5795 } else { 5796 needRestart = true; 5797 } 5798 } 5799 } else { 5800 mRemovedProcesses.add(app); 5801 } 5802 5803 return needRestart; 5804 } 5805 processStartTimedOutLocked(ProcessRecord app)5806 private final void processStartTimedOutLocked(ProcessRecord app) { 5807 final int pid = app.pid; 5808 boolean gone = false; 5809 synchronized (mPidsSelfLocked) { 5810 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5811 if (knownApp != null && knownApp.thread == null) { 5812 mPidsSelfLocked.remove(pid); 5813 gone = true; 5814 } 5815 } 5816 5817 if (gone) { 5818 Slog.w(TAG, "Process " + app + " failed to attach"); 5819 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5820 pid, app.uid, app.processName); 5821 mProcessNames.remove(app.processName, app.uid); 5822 mIsolatedProcesses.remove(app.uid); 5823 if (mHeavyWeightProcess == app) { 5824 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5825 mHeavyWeightProcess.userId, 0)); 5826 mHeavyWeightProcess = null; 5827 } 5828 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5829 if (app.isolated) { 5830 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5831 } 5832 // Take care of any launching providers waiting for this process. 5833 checkAppInLaunchingProvidersLocked(app, true); 5834 // Take care of any services that are waiting for the process. 5835 mServices.processStartTimedOutLocked(app); 5836 app.kill("start timeout", true); 5837 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5838 Slog.w(TAG, "Unattached app died before backup, skipping"); 5839 try { 5840 IBackupManager bm = IBackupManager.Stub.asInterface( 5841 ServiceManager.getService(Context.BACKUP_SERVICE)); 5842 bm.agentDisconnected(app.info.packageName); 5843 } catch (RemoteException e) { 5844 // Can't happen; the backup manager is local 5845 } 5846 } 5847 if (isPendingBroadcastProcessLocked(pid)) { 5848 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5849 skipPendingBroadcastLocked(pid); 5850 } 5851 } else { 5852 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5853 } 5854 } 5855 attachApplicationLocked(IApplicationThread thread, int pid)5856 private final boolean attachApplicationLocked(IApplicationThread thread, 5857 int pid) { 5858 5859 // Find the application record that is being attached... either via 5860 // the pid if we are running in multiple processes, or just pull the 5861 // next app record if we are emulating process with anonymous threads. 5862 ProcessRecord app; 5863 if (pid != MY_PID && pid >= 0) { 5864 synchronized (mPidsSelfLocked) { 5865 app = mPidsSelfLocked.get(pid); 5866 } 5867 } else { 5868 app = null; 5869 } 5870 5871 if (app == null) { 5872 Slog.w(TAG, "No pending application record for pid " + pid 5873 + " (IApplicationThread " + thread + "); dropping process"); 5874 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5875 if (pid > 0 && pid != MY_PID) { 5876 Process.killProcessQuiet(pid); 5877 //TODO: Process.killProcessGroup(app.info.uid, pid); 5878 } else { 5879 try { 5880 thread.scheduleExit(); 5881 } catch (Exception e) { 5882 // Ignore exceptions. 5883 } 5884 } 5885 return false; 5886 } 5887 5888 // If this application record is still attached to a previous 5889 // process, clean it up now. 5890 if (app.thread != null) { 5891 handleAppDiedLocked(app, true, true); 5892 } 5893 5894 // Tell the process all about itself. 5895 5896 if (localLOGV) Slog.v( 5897 TAG, "Binding process pid " + pid + " to record " + app); 5898 5899 final String processName = app.processName; 5900 try { 5901 AppDeathRecipient adr = new AppDeathRecipient( 5902 app, pid, thread); 5903 thread.asBinder().linkToDeath(adr, 0); 5904 app.deathRecipient = adr; 5905 } catch (RemoteException e) { 5906 app.resetPackageList(mProcessStats); 5907 startProcessLocked(app, "link fail", processName); 5908 return false; 5909 } 5910 5911 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5912 5913 app.makeActive(thread, mProcessStats); 5914 app.curAdj = app.setAdj = -100; 5915 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5916 app.forcingToForeground = null; 5917 updateProcessForegroundLocked(app, false, false); 5918 app.hasShownUi = false; 5919 app.debugging = false; 5920 app.cached = false; 5921 app.killedByAm = false; 5922 5923 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5924 5925 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5926 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5927 5928 if (!normalMode) { 5929 Slog.i(TAG, "Launching preboot mode app: " + app); 5930 } 5931 5932 if (localLOGV) Slog.v( 5933 TAG, "New app record " + app 5934 + " thread=" + thread.asBinder() + " pid=" + pid); 5935 try { 5936 int testMode = IApplicationThread.DEBUG_OFF; 5937 if (mDebugApp != null && mDebugApp.equals(processName)) { 5938 testMode = mWaitForDebugger 5939 ? IApplicationThread.DEBUG_WAIT 5940 : IApplicationThread.DEBUG_ON; 5941 app.debugging = true; 5942 if (mDebugTransient) { 5943 mDebugApp = mOrigDebugApp; 5944 mWaitForDebugger = mOrigWaitForDebugger; 5945 } 5946 } 5947 String profileFile = app.instrumentationProfileFile; 5948 ParcelFileDescriptor profileFd = null; 5949 int samplingInterval = 0; 5950 boolean profileAutoStop = false; 5951 if (mProfileApp != null && mProfileApp.equals(processName)) { 5952 mProfileProc = app; 5953 profileFile = mProfileFile; 5954 profileFd = mProfileFd; 5955 samplingInterval = mSamplingInterval; 5956 profileAutoStop = mAutoStopProfiler; 5957 } 5958 boolean enableOpenGlTrace = false; 5959 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5960 enableOpenGlTrace = true; 5961 mOpenGlTraceApp = null; 5962 } 5963 5964 // If the app is being launched for restore or full backup, set it up specially 5965 boolean isRestrictedBackupMode = false; 5966 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5967 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5968 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5969 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5970 } 5971 5972 ensurePackageDexOpt(app.instrumentationInfo != null 5973 ? app.instrumentationInfo.packageName 5974 : app.info.packageName); 5975 if (app.instrumentationClass != null) { 5976 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5977 } 5978 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5979 + processName + " with config " + mConfiguration); 5980 ApplicationInfo appInfo = app.instrumentationInfo != null 5981 ? app.instrumentationInfo : app.info; 5982 app.compat = compatibilityInfoForPackageLocked(appInfo); 5983 if (profileFd != null) { 5984 profileFd = profileFd.dup(); 5985 } 5986 ProfilerInfo profilerInfo = profileFile == null ? null 5987 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5988 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5989 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5990 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5991 isRestrictedBackupMode || !normalMode, app.persistent, 5992 new Configuration(mConfiguration), app.compat, 5993 getCommonServicesLocked(app.isolated), 5994 mCoreSettingsObserver.getCoreSettingsLocked()); 5995 updateLruProcessLocked(app, false, null); 5996 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5997 } catch (Exception e) { 5998 // todo: Yikes! What should we do? For now we will try to 5999 // start another process, but that could easily get us in 6000 // an infinite loop of restarting processes... 6001 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6002 6003 app.resetPackageList(mProcessStats); 6004 app.unlinkDeathRecipient(); 6005 startProcessLocked(app, "bind fail", processName); 6006 return false; 6007 } 6008 6009 // Remove this record from the list of starting applications. 6010 mPersistentStartingProcesses.remove(app); 6011 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6012 "Attach application locked removing on hold: " + app); 6013 mProcessesOnHold.remove(app); 6014 6015 boolean badApp = false; 6016 boolean didSomething = false; 6017 6018 // See if the top visible activity is waiting to run in this process... 6019 if (normalMode) { 6020 try { 6021 if (mStackSupervisor.attachApplicationLocked(app)) { 6022 didSomething = true; 6023 } 6024 } catch (Exception e) { 6025 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6026 badApp = true; 6027 } 6028 } 6029 6030 // Find any services that should be running in this process... 6031 if (!badApp) { 6032 try { 6033 didSomething |= mServices.attachApplicationLocked(app, processName); 6034 } catch (Exception e) { 6035 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6036 badApp = true; 6037 } 6038 } 6039 6040 // Check if a next-broadcast receiver is in this process... 6041 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6042 try { 6043 didSomething |= sendPendingBroadcastsLocked(app); 6044 } catch (Exception e) { 6045 // If the app died trying to launch the receiver we declare it 'bad' 6046 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6047 badApp = true; 6048 } 6049 } 6050 6051 // Check whether the next backup agent is in this process... 6052 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6053 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6054 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6055 try { 6056 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6057 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6058 mBackupTarget.backupMode); 6059 } catch (Exception e) { 6060 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6061 badApp = true; 6062 } 6063 } 6064 6065 if (badApp) { 6066 app.kill("error during init", true); 6067 handleAppDiedLocked(app, false, true); 6068 return false; 6069 } 6070 6071 if (!didSomething) { 6072 updateOomAdjLocked(); 6073 } 6074 6075 return true; 6076 } 6077 6078 @Override attachApplication(IApplicationThread thread)6079 public final void attachApplication(IApplicationThread thread) { 6080 synchronized (this) { 6081 int callingPid = Binder.getCallingPid(); 6082 final long origId = Binder.clearCallingIdentity(); 6083 attachApplicationLocked(thread, callingPid); 6084 Binder.restoreCallingIdentity(origId); 6085 } 6086 } 6087 6088 @Override activityIdle(IBinder token, Configuration config, boolean stopProfiling)6089 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6090 final long origId = Binder.clearCallingIdentity(); 6091 synchronized (this) { 6092 ActivityStack stack = ActivityRecord.getStackLocked(token); 6093 if (stack != null) { 6094 ActivityRecord r = 6095 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6096 if (stopProfiling) { 6097 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6098 try { 6099 mProfileFd.close(); 6100 } catch (IOException e) { 6101 } 6102 clearProfilerLocked(); 6103 } 6104 } 6105 } 6106 } 6107 Binder.restoreCallingIdentity(origId); 6108 } 6109 postFinishBooting(boolean finishBooting, boolean enableScreen)6110 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6111 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6112 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6113 } 6114 enableScreenAfterBoot()6115 void enableScreenAfterBoot() { 6116 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6117 SystemClock.uptimeMillis()); 6118 mWindowManager.enableScreenAfterBoot(); 6119 6120 synchronized (this) { 6121 updateEventDispatchingLocked(); 6122 } 6123 } 6124 6125 @Override showBootMessage(final CharSequence msg, final boolean always)6126 public void showBootMessage(final CharSequence msg, final boolean always) { 6127 enforceNotIsolatedCaller("showBootMessage"); 6128 mWindowManager.showBootMessage(msg, always); 6129 } 6130 6131 @Override keyguardWaitingForActivityDrawn()6132 public void keyguardWaitingForActivityDrawn() { 6133 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6134 final long token = Binder.clearCallingIdentity(); 6135 try { 6136 synchronized (this) { 6137 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6138 mWindowManager.keyguardWaitingForActivityDrawn(); 6139 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6140 mLockScreenShown = LOCK_SCREEN_LEAVING; 6141 updateSleepIfNeededLocked(); 6142 } 6143 } 6144 } finally { 6145 Binder.restoreCallingIdentity(token); 6146 } 6147 } 6148 finishBooting()6149 final void finishBooting() { 6150 synchronized (this) { 6151 if (!mBootAnimationComplete) { 6152 mCallFinishBooting = true; 6153 return; 6154 } 6155 mCallFinishBooting = false; 6156 } 6157 6158 ArraySet<String> completedIsas = new ArraySet<String>(); 6159 for (String abi : Build.SUPPORTED_ABIS) { 6160 Process.establishZygoteConnectionForAbi(abi); 6161 final String instructionSet = VMRuntime.getInstructionSet(abi); 6162 if (!completedIsas.contains(instructionSet)) { 6163 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6164 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6165 } 6166 completedIsas.add(instructionSet); 6167 } 6168 } 6169 6170 IntentFilter pkgFilter = new IntentFilter(); 6171 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6172 pkgFilter.addDataScheme("package"); 6173 mContext.registerReceiver(new BroadcastReceiver() { 6174 @Override 6175 public void onReceive(Context context, Intent intent) { 6176 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6177 if (pkgs != null) { 6178 for (String pkg : pkgs) { 6179 synchronized (ActivityManagerService.this) { 6180 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6181 0, "finished booting")) { 6182 setResultCode(Activity.RESULT_OK); 6183 return; 6184 } 6185 } 6186 } 6187 } 6188 } 6189 }, pkgFilter); 6190 6191 // Let system services know. 6192 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6193 6194 synchronized (this) { 6195 // Ensure that any processes we had put on hold are now started 6196 // up. 6197 final int NP = mProcessesOnHold.size(); 6198 if (NP > 0) { 6199 ArrayList<ProcessRecord> procs = 6200 new ArrayList<ProcessRecord>(mProcessesOnHold); 6201 for (int ip=0; ip<NP; ip++) { 6202 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6203 + procs.get(ip)); 6204 startProcessLocked(procs.get(ip), "on-hold", null); 6205 } 6206 } 6207 6208 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6209 // Start looking for apps that are abusing wake locks. 6210 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6211 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6212 // Tell anyone interested that we are done booting! 6213 SystemProperties.set("sys.boot_completed", "1"); 6214 6215 // And trigger dev.bootcomplete if we are not showing encryption progress 6216 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6217 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6218 SystemProperties.set("dev.bootcomplete", "1"); 6219 } 6220 for (int i=0; i<mStartedUsers.size(); i++) { 6221 UserStartedState uss = mStartedUsers.valueAt(i); 6222 if (uss.mState == UserStartedState.STATE_BOOTING) { 6223 uss.mState = UserStartedState.STATE_RUNNING; 6224 final int userId = mStartedUsers.keyAt(i); 6225 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6226 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6227 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6228 broadcastIntentLocked(null, null, intent, null, 6229 new IIntentReceiver.Stub() { 6230 @Override 6231 public void performReceive(Intent intent, int resultCode, 6232 String data, Bundle extras, boolean ordered, 6233 boolean sticky, int sendingUser) { 6234 synchronized (ActivityManagerService.this) { 6235 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6236 true, false); 6237 } 6238 } 6239 }, 6240 0, null, null, 6241 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6242 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6243 userId); 6244 } 6245 } 6246 scheduleStartProfilesLocked(); 6247 } 6248 } 6249 } 6250 6251 @Override bootAnimationComplete()6252 public void bootAnimationComplete() { 6253 final boolean callFinishBooting; 6254 synchronized (this) { 6255 callFinishBooting = mCallFinishBooting; 6256 mBootAnimationComplete = true; 6257 } 6258 if (callFinishBooting) { 6259 finishBooting(); 6260 } 6261 } 6262 6263 @Override systemBackupRestored()6264 public void systemBackupRestored() { 6265 synchronized (this) { 6266 if (mSystemReady) { 6267 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6268 } else { 6269 Slog.w(TAG, "System backup restored before system is ready"); 6270 } 6271 } 6272 } 6273 ensureBootCompleted()6274 final void ensureBootCompleted() { 6275 boolean booting; 6276 boolean enableScreen; 6277 synchronized (this) { 6278 booting = mBooting; 6279 mBooting = false; 6280 enableScreen = !mBooted; 6281 mBooted = true; 6282 } 6283 6284 if (booting) { 6285 finishBooting(); 6286 } 6287 6288 if (enableScreen) { 6289 enableScreenAfterBoot(); 6290 } 6291 } 6292 6293 @Override activityResumed(IBinder token)6294 public final void activityResumed(IBinder token) { 6295 final long origId = Binder.clearCallingIdentity(); 6296 synchronized(this) { 6297 ActivityStack stack = ActivityRecord.getStackLocked(token); 6298 if (stack != null) { 6299 ActivityRecord.activityResumedLocked(token); 6300 } 6301 } 6302 Binder.restoreCallingIdentity(origId); 6303 } 6304 6305 @Override activityPaused(IBinder token)6306 public final void activityPaused(IBinder token) { 6307 final long origId = Binder.clearCallingIdentity(); 6308 synchronized(this) { 6309 ActivityStack stack = ActivityRecord.getStackLocked(token); 6310 if (stack != null) { 6311 stack.activityPausedLocked(token, false); 6312 } 6313 } 6314 Binder.restoreCallingIdentity(origId); 6315 } 6316 6317 @Override activityStopped(IBinder token, Bundle icicle, PersistableBundle persistentState, CharSequence description)6318 public final void activityStopped(IBinder token, Bundle icicle, 6319 PersistableBundle persistentState, CharSequence description) { 6320 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6321 6322 // Refuse possible leaked file descriptors 6323 if (icicle != null && icicle.hasFileDescriptors()) { 6324 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6325 } 6326 6327 final long origId = Binder.clearCallingIdentity(); 6328 6329 synchronized (this) { 6330 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6331 if (r != null) { 6332 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6333 } 6334 } 6335 6336 trimApplications(); 6337 6338 Binder.restoreCallingIdentity(origId); 6339 } 6340 6341 @Override activityDestroyed(IBinder token)6342 public final void activityDestroyed(IBinder token) { 6343 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6344 synchronized (this) { 6345 ActivityStack stack = ActivityRecord.getStackLocked(token); 6346 if (stack != null) { 6347 stack.activityDestroyedLocked(token, "activityDestroyed"); 6348 } 6349 } 6350 } 6351 6352 @Override backgroundResourcesReleased(IBinder token)6353 public final void backgroundResourcesReleased(IBinder token) { 6354 final long origId = Binder.clearCallingIdentity(); 6355 try { 6356 synchronized (this) { 6357 ActivityStack stack = ActivityRecord.getStackLocked(token); 6358 if (stack != null) { 6359 stack.backgroundResourcesReleased(); 6360 } 6361 } 6362 } finally { 6363 Binder.restoreCallingIdentity(origId); 6364 } 6365 } 6366 6367 @Override notifyLaunchTaskBehindComplete(IBinder token)6368 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6369 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6370 } 6371 6372 @Override notifyEnterAnimationComplete(IBinder token)6373 public final void notifyEnterAnimationComplete(IBinder token) { 6374 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6375 } 6376 6377 @Override getCallingPackage(IBinder token)6378 public String getCallingPackage(IBinder token) { 6379 synchronized (this) { 6380 ActivityRecord r = getCallingRecordLocked(token); 6381 return r != null ? r.info.packageName : null; 6382 } 6383 } 6384 6385 @Override getCallingActivity(IBinder token)6386 public ComponentName getCallingActivity(IBinder token) { 6387 synchronized (this) { 6388 ActivityRecord r = getCallingRecordLocked(token); 6389 return r != null ? r.intent.getComponent() : null; 6390 } 6391 } 6392 getCallingRecordLocked(IBinder token)6393 private ActivityRecord getCallingRecordLocked(IBinder token) { 6394 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6395 if (r == null) { 6396 return null; 6397 } 6398 return r.resultTo; 6399 } 6400 6401 @Override getActivityClassForToken(IBinder token)6402 public ComponentName getActivityClassForToken(IBinder token) { 6403 synchronized(this) { 6404 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6405 if (r == null) { 6406 return null; 6407 } 6408 return r.intent.getComponent(); 6409 } 6410 } 6411 6412 @Override getPackageForToken(IBinder token)6413 public String getPackageForToken(IBinder token) { 6414 synchronized(this) { 6415 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6416 if (r == null) { 6417 return null; 6418 } 6419 return r.packageName; 6420 } 6421 } 6422 6423 @Override getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle options, int userId)6424 public IIntentSender getIntentSender(int type, 6425 String packageName, IBinder token, String resultWho, 6426 int requestCode, Intent[] intents, String[] resolvedTypes, 6427 int flags, Bundle options, int userId) { 6428 enforceNotIsolatedCaller("getIntentSender"); 6429 // Refuse possible leaked file descriptors 6430 if (intents != null) { 6431 if (intents.length < 1) { 6432 throw new IllegalArgumentException("Intents array length must be >= 1"); 6433 } 6434 for (int i=0; i<intents.length; i++) { 6435 Intent intent = intents[i]; 6436 if (intent != null) { 6437 if (intent.hasFileDescriptors()) { 6438 throw new IllegalArgumentException("File descriptors passed in Intent"); 6439 } 6440 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6441 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6442 throw new IllegalArgumentException( 6443 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6444 } 6445 intents[i] = new Intent(intent); 6446 } 6447 } 6448 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6449 throw new IllegalArgumentException( 6450 "Intent array length does not match resolvedTypes length"); 6451 } 6452 } 6453 if (options != null) { 6454 if (options.hasFileDescriptors()) { 6455 throw new IllegalArgumentException("File descriptors passed in options"); 6456 } 6457 } 6458 6459 synchronized(this) { 6460 int callingUid = Binder.getCallingUid(); 6461 int origUserId = userId; 6462 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6463 type == ActivityManager.INTENT_SENDER_BROADCAST, 6464 ALLOW_NON_FULL, "getIntentSender", null); 6465 if (origUserId == UserHandle.USER_CURRENT) { 6466 // We don't want to evaluate this until the pending intent is 6467 // actually executed. However, we do want to always do the 6468 // security checking for it above. 6469 userId = UserHandle.USER_CURRENT; 6470 } 6471 try { 6472 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6473 int uid = AppGlobals.getPackageManager() 6474 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6475 if (!UserHandle.isSameApp(callingUid, uid)) { 6476 String msg = "Permission Denial: getIntentSender() from pid=" 6477 + Binder.getCallingPid() 6478 + ", uid=" + Binder.getCallingUid() 6479 + ", (need uid=" + uid + ")" 6480 + " is not allowed to send as package " + packageName; 6481 Slog.w(TAG, msg); 6482 throw new SecurityException(msg); 6483 } 6484 } 6485 6486 return getIntentSenderLocked(type, packageName, callingUid, userId, 6487 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6488 6489 } catch (RemoteException e) { 6490 throw new SecurityException(e); 6491 } 6492 } 6493 } 6494 getIntentSenderLocked(int type, String packageName, int callingUid, int userId, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle options)6495 IIntentSender getIntentSenderLocked(int type, String packageName, 6496 int callingUid, int userId, IBinder token, String resultWho, 6497 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6498 Bundle options) { 6499 if (DEBUG_MU) 6500 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6501 ActivityRecord activity = null; 6502 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6503 activity = ActivityRecord.isInStackLocked(token); 6504 if (activity == null) { 6505 return null; 6506 } 6507 if (activity.finishing) { 6508 return null; 6509 } 6510 } 6511 6512 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6513 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6514 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6515 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6516 |PendingIntent.FLAG_UPDATE_CURRENT); 6517 6518 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6519 type, packageName, activity, resultWho, 6520 requestCode, intents, resolvedTypes, flags, options, userId); 6521 WeakReference<PendingIntentRecord> ref; 6522 ref = mIntentSenderRecords.get(key); 6523 PendingIntentRecord rec = ref != null ? ref.get() : null; 6524 if (rec != null) { 6525 if (!cancelCurrent) { 6526 if (updateCurrent) { 6527 if (rec.key.requestIntent != null) { 6528 rec.key.requestIntent.replaceExtras(intents != null ? 6529 intents[intents.length - 1] : null); 6530 } 6531 if (intents != null) { 6532 intents[intents.length-1] = rec.key.requestIntent; 6533 rec.key.allIntents = intents; 6534 rec.key.allResolvedTypes = resolvedTypes; 6535 } else { 6536 rec.key.allIntents = null; 6537 rec.key.allResolvedTypes = null; 6538 } 6539 } 6540 return rec; 6541 } 6542 rec.canceled = true; 6543 mIntentSenderRecords.remove(key); 6544 } 6545 if (noCreate) { 6546 return rec; 6547 } 6548 rec = new PendingIntentRecord(this, key, callingUid); 6549 mIntentSenderRecords.put(key, rec.ref); 6550 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6551 if (activity.pendingResults == null) { 6552 activity.pendingResults 6553 = new HashSet<WeakReference<PendingIntentRecord>>(); 6554 } 6555 activity.pendingResults.add(rec.ref); 6556 } 6557 return rec; 6558 } 6559 6560 @Override cancelIntentSender(IIntentSender sender)6561 public void cancelIntentSender(IIntentSender sender) { 6562 if (!(sender instanceof PendingIntentRecord)) { 6563 return; 6564 } 6565 synchronized(this) { 6566 PendingIntentRecord rec = (PendingIntentRecord)sender; 6567 try { 6568 int uid = AppGlobals.getPackageManager() 6569 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6570 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6571 String msg = "Permission Denial: cancelIntentSender() from pid=" 6572 + Binder.getCallingPid() 6573 + ", uid=" + Binder.getCallingUid() 6574 + " is not allowed to cancel packges " 6575 + rec.key.packageName; 6576 Slog.w(TAG, msg); 6577 throw new SecurityException(msg); 6578 } 6579 } catch (RemoteException e) { 6580 throw new SecurityException(e); 6581 } 6582 cancelIntentSenderLocked(rec, true); 6583 } 6584 } 6585 cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity)6586 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6587 rec.canceled = true; 6588 mIntentSenderRecords.remove(rec.key); 6589 if (cleanActivity && rec.key.activity != null) { 6590 rec.key.activity.pendingResults.remove(rec.ref); 6591 } 6592 } 6593 6594 @Override getPackageForIntentSender(IIntentSender pendingResult)6595 public String getPackageForIntentSender(IIntentSender pendingResult) { 6596 if (!(pendingResult instanceof PendingIntentRecord)) { 6597 return null; 6598 } 6599 try { 6600 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6601 return res.key.packageName; 6602 } catch (ClassCastException e) { 6603 } 6604 return null; 6605 } 6606 6607 @Override getUidForIntentSender(IIntentSender sender)6608 public int getUidForIntentSender(IIntentSender sender) { 6609 if (sender instanceof PendingIntentRecord) { 6610 try { 6611 PendingIntentRecord res = (PendingIntentRecord)sender; 6612 return res.uid; 6613 } catch (ClassCastException e) { 6614 } 6615 } 6616 return -1; 6617 } 6618 6619 @Override isIntentSenderTargetedToPackage(IIntentSender pendingResult)6620 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6621 if (!(pendingResult instanceof PendingIntentRecord)) { 6622 return false; 6623 } 6624 try { 6625 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6626 if (res.key.allIntents == null) { 6627 return false; 6628 } 6629 for (int i=0; i<res.key.allIntents.length; i++) { 6630 Intent intent = res.key.allIntents[i]; 6631 if (intent.getPackage() != null && intent.getComponent() != null) { 6632 return false; 6633 } 6634 } 6635 return true; 6636 } catch (ClassCastException e) { 6637 } 6638 return false; 6639 } 6640 6641 @Override isIntentSenderAnActivity(IIntentSender pendingResult)6642 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6643 if (!(pendingResult instanceof PendingIntentRecord)) { 6644 return false; 6645 } 6646 try { 6647 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6648 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6649 return true; 6650 } 6651 return false; 6652 } catch (ClassCastException e) { 6653 } 6654 return false; 6655 } 6656 6657 @Override getIntentForIntentSender(IIntentSender pendingResult)6658 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6659 if (!(pendingResult instanceof PendingIntentRecord)) { 6660 return null; 6661 } 6662 try { 6663 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6664 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6665 } catch (ClassCastException e) { 6666 } 6667 return null; 6668 } 6669 6670 @Override getTagForIntentSender(IIntentSender pendingResult, String prefix)6671 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6672 if (!(pendingResult instanceof PendingIntentRecord)) { 6673 return null; 6674 } 6675 try { 6676 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6677 Intent intent = res.key.requestIntent; 6678 if (intent != null) { 6679 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6680 || res.lastTagPrefix.equals(prefix))) { 6681 return res.lastTag; 6682 } 6683 res.lastTagPrefix = prefix; 6684 StringBuilder sb = new StringBuilder(128); 6685 if (prefix != null) { 6686 sb.append(prefix); 6687 } 6688 if (intent.getAction() != null) { 6689 sb.append(intent.getAction()); 6690 } else if (intent.getComponent() != null) { 6691 intent.getComponent().appendShortString(sb); 6692 } else { 6693 sb.append("?"); 6694 } 6695 return res.lastTag = sb.toString(); 6696 } 6697 } catch (ClassCastException e) { 6698 } 6699 return null; 6700 } 6701 6702 @Override setProcessLimit(int max)6703 public void setProcessLimit(int max) { 6704 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6705 "setProcessLimit()"); 6706 synchronized (this) { 6707 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6708 mProcessLimitOverride = max; 6709 } 6710 trimApplications(); 6711 } 6712 6713 @Override 6714 public int getProcessLimit() { 6715 synchronized (this) { 6716 return mProcessLimitOverride; 6717 } 6718 } 6719 6720 void foregroundTokenDied(ForegroundToken token) { 6721 synchronized (ActivityManagerService.this) { 6722 synchronized (mPidsSelfLocked) { 6723 ForegroundToken cur 6724 = mForegroundProcesses.get(token.pid); 6725 if (cur != token) { 6726 return; 6727 } 6728 mForegroundProcesses.remove(token.pid); 6729 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6730 if (pr == null) { 6731 return; 6732 } 6733 pr.forcingToForeground = null; 6734 updateProcessForegroundLocked(pr, false, false); 6735 } 6736 updateOomAdjLocked(); 6737 } 6738 } 6739 6740 @Override 6741 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6742 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6743 "setProcessForeground()"); 6744 synchronized(this) { 6745 boolean changed = false; 6746 6747 synchronized (mPidsSelfLocked) { 6748 ProcessRecord pr = mPidsSelfLocked.get(pid); 6749 if (pr == null && isForeground) { 6750 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6751 return; 6752 } 6753 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6754 if (oldToken != null) { 6755 oldToken.token.unlinkToDeath(oldToken, 0); 6756 mForegroundProcesses.remove(pid); 6757 if (pr != null) { 6758 pr.forcingToForeground = null; 6759 } 6760 changed = true; 6761 } 6762 if (isForeground && token != null) { 6763 ForegroundToken newToken = new ForegroundToken() { 6764 @Override 6765 public void binderDied() { 6766 foregroundTokenDied(this); 6767 } 6768 }; 6769 newToken.pid = pid; 6770 newToken.token = token; 6771 try { 6772 token.linkToDeath(newToken, 0); 6773 mForegroundProcesses.put(pid, newToken); 6774 pr.forcingToForeground = token; 6775 changed = true; 6776 } catch (RemoteException e) { 6777 // If the process died while doing this, we will later 6778 // do the cleanup with the process death link. 6779 } 6780 } 6781 } 6782 6783 if (changed) { 6784 updateOomAdjLocked(); 6785 } 6786 } 6787 } 6788 6789 // ========================================================= 6790 // PERMISSIONS 6791 // ========================================================= 6792 6793 static class PermissionController extends IPermissionController.Stub { 6794 ActivityManagerService mActivityManagerService; 6795 PermissionController(ActivityManagerService activityManagerService) { 6796 mActivityManagerService = activityManagerService; 6797 } 6798 6799 @Override 6800 public boolean checkPermission(String permission, int pid, int uid) { 6801 return mActivityManagerService.checkPermission(permission, pid, 6802 uid) == PackageManager.PERMISSION_GRANTED; 6803 } 6804 } 6805 6806 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6807 @Override 6808 public int checkComponentPermission(String permission, int pid, int uid, 6809 int owningUid, boolean exported) { 6810 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6811 owningUid, exported); 6812 } 6813 6814 @Override 6815 public Object getAMSLock() { 6816 return ActivityManagerService.this; 6817 } 6818 } 6819 6820 /** 6821 * This can be called with or without the global lock held. 6822 */ 6823 int checkComponentPermission(String permission, int pid, int uid, 6824 int owningUid, boolean exported) { 6825 if (pid == MY_PID) { 6826 return PackageManager.PERMISSION_GRANTED; 6827 } 6828 return ActivityManager.checkComponentPermission(permission, uid, 6829 owningUid, exported); 6830 } 6831 6832 /** 6833 * As the only public entry point for permissions checking, this method 6834 * can enforce the semantic that requesting a check on a null global 6835 * permission is automatically denied. (Internally a null permission 6836 * string is used when calling {@link #checkComponentPermission} in cases 6837 * when only uid-based security is needed.) 6838 * 6839 * This can be called with or without the global lock held. 6840 */ 6841 @Override 6842 public int checkPermission(String permission, int pid, int uid) { 6843 if (permission == null) { 6844 return PackageManager.PERMISSION_DENIED; 6845 } 6846 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6847 } 6848 6849 @Override 6850 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6851 if (permission == null) { 6852 return PackageManager.PERMISSION_DENIED; 6853 } 6854 6855 // We might be performing an operation on behalf of an indirect binder 6856 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6857 // client identity accordingly before proceeding. 6858 Identity tlsIdentity = sCallerIdentity.get(); 6859 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6860 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6861 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6862 uid = tlsIdentity.uid; 6863 pid = tlsIdentity.pid; 6864 } 6865 6866 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6867 } 6868 6869 /** 6870 * Binder IPC calls go through the public entry point. 6871 * This can be called with or without the global lock held. 6872 */ 6873 int checkCallingPermission(String permission) { 6874 return checkPermission(permission, 6875 Binder.getCallingPid(), 6876 UserHandle.getAppId(Binder.getCallingUid())); 6877 } 6878 6879 /** 6880 * This can be called with or without the global lock held. 6881 */ 6882 void enforceCallingPermission(String permission, String func) { 6883 if (checkCallingPermission(permission) 6884 == PackageManager.PERMISSION_GRANTED) { 6885 return; 6886 } 6887 6888 String msg = "Permission Denial: " + func + " from pid=" 6889 + Binder.getCallingPid() 6890 + ", uid=" + Binder.getCallingUid() 6891 + " requires " + permission; 6892 Slog.w(TAG, msg); 6893 throw new SecurityException(msg); 6894 } 6895 6896 /** 6897 * Determine if UID is holding permissions required to access {@link Uri} in 6898 * the given {@link ProviderInfo}. Final permission checking is always done 6899 * in {@link ContentProvider}. 6900 */ 6901 private final boolean checkHoldingPermissionsLocked( 6902 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6903 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6904 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6905 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6906 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6907 != PERMISSION_GRANTED) { 6908 return false; 6909 } 6910 } 6911 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6912 } 6913 6914 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6915 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6916 if (pi.applicationInfo.uid == uid) { 6917 return true; 6918 } else if (!pi.exported) { 6919 return false; 6920 } 6921 6922 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6923 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6924 try { 6925 // check if target holds top-level <provider> permissions 6926 if (!readMet && pi.readPermission != null && considerUidPermissions 6927 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6928 readMet = true; 6929 } 6930 if (!writeMet && pi.writePermission != null && considerUidPermissions 6931 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6932 writeMet = true; 6933 } 6934 6935 // track if unprotected read/write is allowed; any denied 6936 // <path-permission> below removes this ability 6937 boolean allowDefaultRead = pi.readPermission == null; 6938 boolean allowDefaultWrite = pi.writePermission == null; 6939 6940 // check if target holds any <path-permission> that match uri 6941 final PathPermission[] pps = pi.pathPermissions; 6942 if (pps != null) { 6943 final String path = grantUri.uri.getPath(); 6944 int i = pps.length; 6945 while (i > 0 && (!readMet || !writeMet)) { 6946 i--; 6947 PathPermission pp = pps[i]; 6948 if (pp.match(path)) { 6949 if (!readMet) { 6950 final String pprperm = pp.getReadPermission(); 6951 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6952 + pprperm + " for " + pp.getPath() 6953 + ": match=" + pp.match(path) 6954 + " check=" + pm.checkUidPermission(pprperm, uid)); 6955 if (pprperm != null) { 6956 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6957 == PERMISSION_GRANTED) { 6958 readMet = true; 6959 } else { 6960 allowDefaultRead = false; 6961 } 6962 } 6963 } 6964 if (!writeMet) { 6965 final String ppwperm = pp.getWritePermission(); 6966 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6967 + ppwperm + " for " + pp.getPath() 6968 + ": match=" + pp.match(path) 6969 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6970 if (ppwperm != null) { 6971 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6972 == PERMISSION_GRANTED) { 6973 writeMet = true; 6974 } else { 6975 allowDefaultWrite = false; 6976 } 6977 } 6978 } 6979 } 6980 } 6981 } 6982 6983 // grant unprotected <provider> read/write, if not blocked by 6984 // <path-permission> above 6985 if (allowDefaultRead) readMet = true; 6986 if (allowDefaultWrite) writeMet = true; 6987 6988 } catch (RemoteException e) { 6989 return false; 6990 } 6991 6992 return readMet && writeMet; 6993 } 6994 getProviderInfoLocked(String authority, int userHandle)6995 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6996 ProviderInfo pi = null; 6997 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6998 if (cpr != null) { 6999 pi = cpr.info; 7000 } else { 7001 try { 7002 pi = AppGlobals.getPackageManager().resolveContentProvider( 7003 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7004 } catch (RemoteException ex) { 7005 } 7006 } 7007 return pi; 7008 } 7009 findUriPermissionLocked(int targetUid, GrantUri grantUri)7010 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7011 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7012 if (targetUris != null) { 7013 return targetUris.get(grantUri); 7014 } 7015 return null; 7016 } 7017 findOrCreateUriPermissionLocked(String sourcePkg, String targetPkg, int targetUid, GrantUri grantUri)7018 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7019 String targetPkg, int targetUid, GrantUri grantUri) { 7020 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7021 if (targetUris == null) { 7022 targetUris = Maps.newArrayMap(); 7023 mGrantedUriPermissions.put(targetUid, targetUris); 7024 } 7025 7026 UriPermission perm = targetUris.get(grantUri); 7027 if (perm == null) { 7028 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7029 targetUris.put(grantUri, perm); 7030 } 7031 7032 return perm; 7033 } 7034 checkUriPermissionLocked(GrantUri grantUri, int uid, final int modeFlags)7035 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7036 final int modeFlags) { 7037 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7038 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7039 : UriPermission.STRENGTH_OWNED; 7040 7041 // Root gets to do everything. 7042 if (uid == 0) { 7043 return true; 7044 } 7045 7046 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7047 if (perms == null) return false; 7048 7049 // First look for exact match 7050 final UriPermission exactPerm = perms.get(grantUri); 7051 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7052 return true; 7053 } 7054 7055 // No exact match, look for prefixes 7056 final int N = perms.size(); 7057 for (int i = 0; i < N; i++) { 7058 final UriPermission perm = perms.valueAt(i); 7059 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7060 && perm.getStrength(modeFlags) >= minStrength) { 7061 return true; 7062 } 7063 } 7064 7065 return false; 7066 } 7067 7068 /** 7069 * @param uri This uri must NOT contain an embedded userId. 7070 * @param userId The userId in which the uri is to be resolved. 7071 */ 7072 @Override checkUriPermission(Uri uri, int pid, int uid, final int modeFlags, int userId, IBinder callerToken)7073 public int checkUriPermission(Uri uri, int pid, int uid, 7074 final int modeFlags, int userId, IBinder callerToken) { 7075 enforceNotIsolatedCaller("checkUriPermission"); 7076 7077 // Another redirected-binder-call permissions check as in 7078 // {@link checkPermissionWithToken}. 7079 Identity tlsIdentity = sCallerIdentity.get(); 7080 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7081 uid = tlsIdentity.uid; 7082 pid = tlsIdentity.pid; 7083 } 7084 7085 // Our own process gets to do everything. 7086 if (pid == MY_PID) { 7087 return PackageManager.PERMISSION_GRANTED; 7088 } 7089 synchronized (this) { 7090 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7091 ? PackageManager.PERMISSION_GRANTED 7092 : PackageManager.PERMISSION_DENIED; 7093 } 7094 } 7095 7096 /** 7097 * Check if the targetPkg can be granted permission to access uri by 7098 * the callingUid using the given modeFlags. Throws a security exception 7099 * if callingUid is not allowed to do this. Returns the uid of the target 7100 * if the URI permission grant should be performed; returns -1 if it is not 7101 * needed (for example targetPkg already has permission to access the URI). 7102 * If you already know the uid of the target, you can supply it in 7103 * lastTargetUid else set that to -1. 7104 */ checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, final int modeFlags, int lastTargetUid)7105 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7106 final int modeFlags, int lastTargetUid) { 7107 if (!Intent.isAccessUriMode(modeFlags)) { 7108 return -1; 7109 } 7110 7111 if (targetPkg != null) { 7112 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7113 "Checking grant " + targetPkg + " permission to " + grantUri); 7114 } 7115 7116 final IPackageManager pm = AppGlobals.getPackageManager(); 7117 7118 // If this is not a content: uri, we can't do anything with it. 7119 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7120 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7121 "Can't grant URI permission for non-content URI: " + grantUri); 7122 return -1; 7123 } 7124 7125 final String authority = grantUri.uri.getAuthority(); 7126 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7127 if (pi == null) { 7128 Slog.w(TAG, "No content provider found for permission check: " + 7129 grantUri.uri.toSafeString()); 7130 return -1; 7131 } 7132 7133 int targetUid = lastTargetUid; 7134 if (targetUid < 0 && targetPkg != null) { 7135 try { 7136 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7137 if (targetUid < 0) { 7138 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7139 "Can't grant URI permission no uid for: " + targetPkg); 7140 return -1; 7141 } 7142 } catch (RemoteException ex) { 7143 return -1; 7144 } 7145 } 7146 7147 if (targetUid >= 0) { 7148 // First... does the target actually need this permission? 7149 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7150 // No need to grant the target this permission. 7151 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7152 "Target " + targetPkg + " already has full permission to " + grantUri); 7153 return -1; 7154 } 7155 } else { 7156 // First... there is no target package, so can anyone access it? 7157 boolean allowed = pi.exported; 7158 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7159 if (pi.readPermission != null) { 7160 allowed = false; 7161 } 7162 } 7163 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7164 if (pi.writePermission != null) { 7165 allowed = false; 7166 } 7167 } 7168 if (allowed) { 7169 return -1; 7170 } 7171 } 7172 7173 /* There is a special cross user grant if: 7174 * - The target is on another user. 7175 * - Apps on the current user can access the uri without any uid permissions. 7176 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7177 * grant uri permissions. 7178 */ 7179 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7180 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7181 modeFlags, false /*without considering the uid permissions*/); 7182 7183 // Second... is the provider allowing granting of URI permissions? 7184 if (!specialCrossUserGrant) { 7185 if (!pi.grantUriPermissions) { 7186 throw new SecurityException("Provider " + pi.packageName 7187 + "/" + pi.name 7188 + " does not allow granting of Uri permissions (uri " 7189 + grantUri + ")"); 7190 } 7191 if (pi.uriPermissionPatterns != null) { 7192 final int N = pi.uriPermissionPatterns.length; 7193 boolean allowed = false; 7194 for (int i=0; i<N; i++) { 7195 if (pi.uriPermissionPatterns[i] != null 7196 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7197 allowed = true; 7198 break; 7199 } 7200 } 7201 if (!allowed) { 7202 throw new SecurityException("Provider " + pi.packageName 7203 + "/" + pi.name 7204 + " does not allow granting of permission to path of Uri " 7205 + grantUri); 7206 } 7207 } 7208 } 7209 7210 // Third... does the caller itself have permission to access 7211 // this uri? 7212 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7213 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7214 // Require they hold a strong enough Uri permission 7215 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7216 throw new SecurityException("Uid " + callingUid 7217 + " does not have permission to uri " + grantUri); 7218 } 7219 } 7220 } 7221 return targetUid; 7222 } 7223 7224 /** 7225 * @param uri This uri must NOT contain an embedded userId. 7226 * @param userId The userId in which the uri is to be resolved. 7227 */ 7228 @Override checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, final int modeFlags, int userId)7229 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7230 final int modeFlags, int userId) { 7231 enforceNotIsolatedCaller("checkGrantUriPermission"); 7232 synchronized(this) { 7233 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7234 new GrantUri(userId, uri, false), modeFlags, -1); 7235 } 7236 } 7237 grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, final int modeFlags, UriPermissionOwner owner)7238 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7239 final int modeFlags, UriPermissionOwner owner) { 7240 if (!Intent.isAccessUriMode(modeFlags)) { 7241 return; 7242 } 7243 7244 // So here we are: the caller has the assumed permission 7245 // to the uri, and the target doesn't. Let's now give this to 7246 // the target. 7247 7248 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7249 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7250 7251 final String authority = grantUri.uri.getAuthority(); 7252 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7253 if (pi == null) { 7254 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7255 return; 7256 } 7257 7258 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7259 grantUri.prefix = true; 7260 } 7261 final UriPermission perm = findOrCreateUriPermissionLocked( 7262 pi.packageName, targetPkg, targetUid, grantUri); 7263 perm.grantModes(modeFlags, owner); 7264 } 7265 grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, final int modeFlags, UriPermissionOwner owner, int targetUserId)7266 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7267 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7268 if (targetPkg == null) { 7269 throw new NullPointerException("targetPkg"); 7270 } 7271 int targetUid; 7272 final IPackageManager pm = AppGlobals.getPackageManager(); 7273 try { 7274 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7275 } catch (RemoteException ex) { 7276 return; 7277 } 7278 7279 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7280 targetUid); 7281 if (targetUid < 0) { 7282 return; 7283 } 7284 7285 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7286 owner); 7287 } 7288 7289 static class NeededUriGrants extends ArrayList<GrantUri> { 7290 final String targetPkg; 7291 final int targetUid; 7292 final int flags; 7293 NeededUriGrants(String targetPkg, int targetUid, int flags)7294 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7295 this.targetPkg = targetPkg; 7296 this.targetUid = targetUid; 7297 this.flags = flags; 7298 } 7299 } 7300 7301 /** 7302 * Like checkGrantUriPermissionLocked, but takes an Intent. 7303 */ checkGrantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId)7304 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7305 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7306 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7307 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7308 + " clip=" + (intent != null ? intent.getClipData() : null) 7309 + " from " + intent + "; flags=0x" 7310 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7311 7312 if (targetPkg == null) { 7313 throw new NullPointerException("targetPkg"); 7314 } 7315 7316 if (intent == null) { 7317 return null; 7318 } 7319 Uri data = intent.getData(); 7320 ClipData clip = intent.getClipData(); 7321 if (data == null && clip == null) { 7322 return null; 7323 } 7324 // Default userId for uris in the intent (if they don't specify it themselves) 7325 int contentUserHint = intent.getContentUserHint(); 7326 if (contentUserHint == UserHandle.USER_CURRENT) { 7327 contentUserHint = UserHandle.getUserId(callingUid); 7328 } 7329 final IPackageManager pm = AppGlobals.getPackageManager(); 7330 int targetUid; 7331 if (needed != null) { 7332 targetUid = needed.targetUid; 7333 } else { 7334 try { 7335 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7336 } catch (RemoteException ex) { 7337 return null; 7338 } 7339 if (targetUid < 0) { 7340 if (DEBUG_URI_PERMISSION) { 7341 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7342 + " on user " + targetUserId); 7343 } 7344 return null; 7345 } 7346 } 7347 if (data != null) { 7348 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7349 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7350 targetUid); 7351 if (targetUid > 0) { 7352 if (needed == null) { 7353 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7354 } 7355 needed.add(grantUri); 7356 } 7357 } 7358 if (clip != null) { 7359 for (int i=0; i<clip.getItemCount(); i++) { 7360 Uri uri = clip.getItemAt(i).getUri(); 7361 if (uri != null) { 7362 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7363 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7364 targetUid); 7365 if (targetUid > 0) { 7366 if (needed == null) { 7367 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7368 } 7369 needed.add(grantUri); 7370 } 7371 } else { 7372 Intent clipIntent = clip.getItemAt(i).getIntent(); 7373 if (clipIntent != null) { 7374 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7375 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7376 if (newNeeded != null) { 7377 needed = newNeeded; 7378 } 7379 } 7380 } 7381 } 7382 } 7383 7384 return needed; 7385 } 7386 7387 /** 7388 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7389 */ grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, UriPermissionOwner owner)7390 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7391 UriPermissionOwner owner) { 7392 if (needed != null) { 7393 for (int i=0; i<needed.size(); i++) { 7394 GrantUri grantUri = needed.get(i); 7395 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7396 grantUri, needed.flags, owner); 7397 } 7398 } 7399 } 7400 grantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId)7401 void grantUriPermissionFromIntentLocked(int callingUid, 7402 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7403 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7404 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7405 if (needed == null) { 7406 return; 7407 } 7408 7409 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7410 } 7411 7412 /** 7413 * @param uri This uri must NOT contain an embedded userId. 7414 * @param userId The userId in which the uri is to be resolved. 7415 */ 7416 @Override grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, final int modeFlags, int userId)7417 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7418 final int modeFlags, int userId) { 7419 enforceNotIsolatedCaller("grantUriPermission"); 7420 GrantUri grantUri = new GrantUri(userId, uri, false); 7421 synchronized(this) { 7422 final ProcessRecord r = getRecordForAppLocked(caller); 7423 if (r == null) { 7424 throw new SecurityException("Unable to find app for caller " 7425 + caller 7426 + " when granting permission to uri " + grantUri); 7427 } 7428 if (targetPkg == null) { 7429 throw new IllegalArgumentException("null target"); 7430 } 7431 if (grantUri == null) { 7432 throw new IllegalArgumentException("null uri"); 7433 } 7434 7435 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7436 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7437 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7438 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7439 7440 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7441 UserHandle.getUserId(r.uid)); 7442 } 7443 } 7444 removeUriPermissionIfNeededLocked(UriPermission perm)7445 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7446 if (perm.modeFlags == 0) { 7447 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7448 perm.targetUid); 7449 if (perms != null) { 7450 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7451 "Removing " + perm.targetUid + " permission to " + perm.uri); 7452 7453 perms.remove(perm.uri); 7454 if (perms.isEmpty()) { 7455 mGrantedUriPermissions.remove(perm.targetUid); 7456 } 7457 } 7458 } 7459 } 7460 revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags)7461 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7462 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7463 7464 final IPackageManager pm = AppGlobals.getPackageManager(); 7465 final String authority = grantUri.uri.getAuthority(); 7466 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7467 if (pi == null) { 7468 Slog.w(TAG, "No content provider found for permission revoke: " 7469 + grantUri.toSafeString()); 7470 return; 7471 } 7472 7473 // Does the caller have this permission on the URI? 7474 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7475 // If they don't have direct access to the URI, then revoke any 7476 // ownerless URI permissions that have been granted to them. 7477 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7478 if (perms != null) { 7479 boolean persistChanged = false; 7480 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7481 final UriPermission perm = it.next(); 7482 if (perm.uri.sourceUserId == grantUri.sourceUserId 7483 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7484 if (DEBUG_URI_PERMISSION) 7485 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7486 " permission to " + perm.uri); 7487 persistChanged |= perm.revokeModes( 7488 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7489 if (perm.modeFlags == 0) { 7490 it.remove(); 7491 } 7492 } 7493 } 7494 if (perms.isEmpty()) { 7495 mGrantedUriPermissions.remove(callingUid); 7496 } 7497 if (persistChanged) { 7498 schedulePersistUriGrants(); 7499 } 7500 } 7501 return; 7502 } 7503 7504 boolean persistChanged = false; 7505 7506 // Go through all of the permissions and remove any that match. 7507 int N = mGrantedUriPermissions.size(); 7508 for (int i = 0; i < N; i++) { 7509 final int targetUid = mGrantedUriPermissions.keyAt(i); 7510 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7511 7512 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7513 final UriPermission perm = it.next(); 7514 if (perm.uri.sourceUserId == grantUri.sourceUserId 7515 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7516 if (DEBUG_URI_PERMISSION) 7517 Slog.v(TAG, 7518 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7519 persistChanged |= perm.revokeModes( 7520 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7521 if (perm.modeFlags == 0) { 7522 it.remove(); 7523 } 7524 } 7525 } 7526 7527 if (perms.isEmpty()) { 7528 mGrantedUriPermissions.remove(targetUid); 7529 N--; 7530 i--; 7531 } 7532 } 7533 7534 if (persistChanged) { 7535 schedulePersistUriGrants(); 7536 } 7537 } 7538 7539 /** 7540 * @param uri This uri must NOT contain an embedded userId. 7541 * @param userId The userId in which the uri is to be resolved. 7542 */ 7543 @Override revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, int userId)7544 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7545 int userId) { 7546 enforceNotIsolatedCaller("revokeUriPermission"); 7547 synchronized(this) { 7548 final ProcessRecord r = getRecordForAppLocked(caller); 7549 if (r == null) { 7550 throw new SecurityException("Unable to find app for caller " 7551 + caller 7552 + " when revoking permission to uri " + uri); 7553 } 7554 if (uri == null) { 7555 Slog.w(TAG, "revokeUriPermission: null uri"); 7556 return; 7557 } 7558 7559 if (!Intent.isAccessUriMode(modeFlags)) { 7560 return; 7561 } 7562 7563 final IPackageManager pm = AppGlobals.getPackageManager(); 7564 final String authority = uri.getAuthority(); 7565 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7566 if (pi == null) { 7567 Slog.w(TAG, "No content provider found for permission revoke: " 7568 + uri.toSafeString()); 7569 return; 7570 } 7571 7572 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7573 } 7574 } 7575 7576 /** 7577 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7578 * given package. 7579 * 7580 * @param packageName Package name to match, or {@code null} to apply to all 7581 * packages. 7582 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7583 * to all users. 7584 * @param persistable If persistable grants should be removed. 7585 */ removeUriPermissionsForPackageLocked( String packageName, int userHandle, boolean persistable)7586 private void removeUriPermissionsForPackageLocked( 7587 String packageName, int userHandle, boolean persistable) { 7588 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7589 throw new IllegalArgumentException("Must narrow by either package or user"); 7590 } 7591 7592 boolean persistChanged = false; 7593 7594 int N = mGrantedUriPermissions.size(); 7595 for (int i = 0; i < N; i++) { 7596 final int targetUid = mGrantedUriPermissions.keyAt(i); 7597 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7598 7599 // Only inspect grants matching user 7600 if (userHandle == UserHandle.USER_ALL 7601 || userHandle == UserHandle.getUserId(targetUid)) { 7602 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7603 final UriPermission perm = it.next(); 7604 7605 // Only inspect grants matching package 7606 if (packageName == null || perm.sourcePkg.equals(packageName) 7607 || perm.targetPkg.equals(packageName)) { 7608 persistChanged |= perm.revokeModes(persistable 7609 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7610 7611 // Only remove when no modes remain; any persisted grants 7612 // will keep this alive. 7613 if (perm.modeFlags == 0) { 7614 it.remove(); 7615 } 7616 } 7617 } 7618 7619 if (perms.isEmpty()) { 7620 mGrantedUriPermissions.remove(targetUid); 7621 N--; 7622 i--; 7623 } 7624 } 7625 } 7626 7627 if (persistChanged) { 7628 schedulePersistUriGrants(); 7629 } 7630 } 7631 7632 @Override newUriPermissionOwner(String name)7633 public IBinder newUriPermissionOwner(String name) { 7634 enforceNotIsolatedCaller("newUriPermissionOwner"); 7635 synchronized(this) { 7636 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7637 return owner.getExternalTokenLocked(); 7638 } 7639 } 7640 7641 /** 7642 * @param uri This uri must NOT contain an embedded userId. 7643 * @param sourceUserId The userId in which the uri is to be resolved. 7644 * @param targetUserId The userId of the app that receives the grant. 7645 */ 7646 @Override grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, final int modeFlags, int sourceUserId, int targetUserId)7647 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7648 final int modeFlags, int sourceUserId, int targetUserId) { 7649 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7650 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7651 synchronized(this) { 7652 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7653 if (owner == null) { 7654 throw new IllegalArgumentException("Unknown owner: " + token); 7655 } 7656 if (fromUid != Binder.getCallingUid()) { 7657 if (Binder.getCallingUid() != Process.myUid()) { 7658 // Only system code can grant URI permissions on behalf 7659 // of other users. 7660 throw new SecurityException("nice try"); 7661 } 7662 } 7663 if (targetPkg == null) { 7664 throw new IllegalArgumentException("null target"); 7665 } 7666 if (uri == null) { 7667 throw new IllegalArgumentException("null uri"); 7668 } 7669 7670 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7671 modeFlags, owner, targetUserId); 7672 } 7673 } 7674 7675 /** 7676 * @param uri This uri must NOT contain an embedded userId. 7677 * @param userId The userId in which the uri is to be resolved. 7678 */ 7679 @Override revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId)7680 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7681 synchronized(this) { 7682 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7683 if (owner == null) { 7684 throw new IllegalArgumentException("Unknown owner: " + token); 7685 } 7686 7687 if (uri == null) { 7688 owner.removeUriPermissionsLocked(mode); 7689 } else { 7690 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7691 } 7692 } 7693 } 7694 schedulePersistUriGrants()7695 private void schedulePersistUriGrants() { 7696 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7697 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7698 10 * DateUtils.SECOND_IN_MILLIS); 7699 } 7700 } 7701 writeGrantedUriPermissions()7702 private void writeGrantedUriPermissions() { 7703 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7704 7705 // Snapshot permissions so we can persist without lock 7706 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7707 synchronized (this) { 7708 final int size = mGrantedUriPermissions.size(); 7709 for (int i = 0; i < size; i++) { 7710 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7711 for (UriPermission perm : perms.values()) { 7712 if (perm.persistedModeFlags != 0) { 7713 persist.add(perm.snapshot()); 7714 } 7715 } 7716 } 7717 } 7718 7719 FileOutputStream fos = null; 7720 try { 7721 fos = mGrantFile.startWrite(); 7722 7723 XmlSerializer out = new FastXmlSerializer(); 7724 out.setOutput(fos, "utf-8"); 7725 out.startDocument(null, true); 7726 out.startTag(null, TAG_URI_GRANTS); 7727 for (UriPermission.Snapshot perm : persist) { 7728 out.startTag(null, TAG_URI_GRANT); 7729 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7730 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7731 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7732 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7733 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7734 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7735 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7736 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7737 out.endTag(null, TAG_URI_GRANT); 7738 } 7739 out.endTag(null, TAG_URI_GRANTS); 7740 out.endDocument(); 7741 7742 mGrantFile.finishWrite(fos); 7743 } catch (IOException e) { 7744 if (fos != null) { 7745 mGrantFile.failWrite(fos); 7746 } 7747 } 7748 } 7749 readGrantedUriPermissionsLocked()7750 private void readGrantedUriPermissionsLocked() { 7751 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7752 7753 final long now = System.currentTimeMillis(); 7754 7755 FileInputStream fis = null; 7756 try { 7757 fis = mGrantFile.openRead(); 7758 final XmlPullParser in = Xml.newPullParser(); 7759 in.setInput(fis, null); 7760 7761 int type; 7762 while ((type = in.next()) != END_DOCUMENT) { 7763 final String tag = in.getName(); 7764 if (type == START_TAG) { 7765 if (TAG_URI_GRANT.equals(tag)) { 7766 final int sourceUserId; 7767 final int targetUserId; 7768 final int userHandle = readIntAttribute(in, 7769 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7770 if (userHandle != UserHandle.USER_NULL) { 7771 // For backwards compatibility. 7772 sourceUserId = userHandle; 7773 targetUserId = userHandle; 7774 } else { 7775 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7776 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7777 } 7778 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7779 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7780 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7781 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7782 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7783 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7784 7785 // Sanity check that provider still belongs to source package 7786 final ProviderInfo pi = getProviderInfoLocked( 7787 uri.getAuthority(), sourceUserId); 7788 if (pi != null && sourcePkg.equals(pi.packageName)) { 7789 int targetUid = -1; 7790 try { 7791 targetUid = AppGlobals.getPackageManager() 7792 .getPackageUid(targetPkg, targetUserId); 7793 } catch (RemoteException e) { 7794 } 7795 if (targetUid != -1) { 7796 final UriPermission perm = findOrCreateUriPermissionLocked( 7797 sourcePkg, targetPkg, targetUid, 7798 new GrantUri(sourceUserId, uri, prefix)); 7799 perm.initPersistedModes(modeFlags, createdTime); 7800 } 7801 } else { 7802 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7803 + " but instead found " + pi); 7804 } 7805 } 7806 } 7807 } 7808 } catch (FileNotFoundException e) { 7809 // Missing grants is okay 7810 } catch (IOException e) { 7811 Slog.wtf(TAG, "Failed reading Uri grants", e); 7812 } catch (XmlPullParserException e) { 7813 Slog.wtf(TAG, "Failed reading Uri grants", e); 7814 } finally { 7815 IoUtils.closeQuietly(fis); 7816 } 7817 } 7818 7819 /** 7820 * @param uri This uri must NOT contain an embedded userId. 7821 * @param userId The userId in which the uri is to be resolved. 7822 */ 7823 @Override takePersistableUriPermission(Uri uri, final int modeFlags, int userId)7824 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7825 enforceNotIsolatedCaller("takePersistableUriPermission"); 7826 7827 Preconditions.checkFlagsArgument(modeFlags, 7828 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7829 7830 synchronized (this) { 7831 final int callingUid = Binder.getCallingUid(); 7832 boolean persistChanged = false; 7833 GrantUri grantUri = new GrantUri(userId, uri, false); 7834 7835 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7836 new GrantUri(userId, uri, false)); 7837 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7838 new GrantUri(userId, uri, true)); 7839 7840 final boolean exactValid = (exactPerm != null) 7841 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7842 final boolean prefixValid = (prefixPerm != null) 7843 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7844 7845 if (!(exactValid || prefixValid)) { 7846 throw new SecurityException("No persistable permission grants found for UID " 7847 + callingUid + " and Uri " + grantUri.toSafeString()); 7848 } 7849 7850 if (exactValid) { 7851 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7852 } 7853 if (prefixValid) { 7854 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7855 } 7856 7857 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7858 7859 if (persistChanged) { 7860 schedulePersistUriGrants(); 7861 } 7862 } 7863 } 7864 7865 /** 7866 * @param uri This uri must NOT contain an embedded userId. 7867 * @param userId The userId in which the uri is to be resolved. 7868 */ 7869 @Override releasePersistableUriPermission(Uri uri, final int modeFlags, int userId)7870 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7871 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7872 7873 Preconditions.checkFlagsArgument(modeFlags, 7874 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7875 7876 synchronized (this) { 7877 final int callingUid = Binder.getCallingUid(); 7878 boolean persistChanged = false; 7879 7880 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7881 new GrantUri(userId, uri, false)); 7882 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7883 new GrantUri(userId, uri, true)); 7884 if (exactPerm == null && prefixPerm == null) { 7885 throw new SecurityException("No permission grants found for UID " + callingUid 7886 + " and Uri " + uri.toSafeString()); 7887 } 7888 7889 if (exactPerm != null) { 7890 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7891 removeUriPermissionIfNeededLocked(exactPerm); 7892 } 7893 if (prefixPerm != null) { 7894 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7895 removeUriPermissionIfNeededLocked(prefixPerm); 7896 } 7897 7898 if (persistChanged) { 7899 schedulePersistUriGrants(); 7900 } 7901 } 7902 } 7903 7904 /** 7905 * Prune any older {@link UriPermission} for the given UID until outstanding 7906 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7907 * 7908 * @return if any mutations occured that require persisting. 7909 */ maybePrunePersistedUriGrantsLocked(int uid)7910 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7911 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7912 if (perms == null) return false; 7913 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7914 7915 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7916 for (UriPermission perm : perms.values()) { 7917 if (perm.persistedModeFlags != 0) { 7918 persisted.add(perm); 7919 } 7920 } 7921 7922 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7923 if (trimCount <= 0) return false; 7924 7925 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7926 for (int i = 0; i < trimCount; i++) { 7927 final UriPermission perm = persisted.get(i); 7928 7929 if (DEBUG_URI_PERMISSION) { 7930 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7931 } 7932 7933 perm.releasePersistableModes(~0); 7934 removeUriPermissionIfNeededLocked(perm); 7935 } 7936 7937 return true; 7938 } 7939 7940 @Override getPersistedUriPermissions( String packageName, boolean incoming)7941 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7942 String packageName, boolean incoming) { 7943 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7944 Preconditions.checkNotNull(packageName, "packageName"); 7945 7946 final int callingUid = Binder.getCallingUid(); 7947 final IPackageManager pm = AppGlobals.getPackageManager(); 7948 try { 7949 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7950 if (packageUid != callingUid) { 7951 throw new SecurityException( 7952 "Package " + packageName + " does not belong to calling UID " + callingUid); 7953 } 7954 } catch (RemoteException e) { 7955 throw new SecurityException("Failed to verify package name ownership"); 7956 } 7957 7958 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7959 synchronized (this) { 7960 if (incoming) { 7961 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7962 callingUid); 7963 if (perms == null) { 7964 Slog.w(TAG, "No permission grants found for " + packageName); 7965 } else { 7966 for (UriPermission perm : perms.values()) { 7967 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7968 result.add(perm.buildPersistedPublicApiObject()); 7969 } 7970 } 7971 } 7972 } else { 7973 final int size = mGrantedUriPermissions.size(); 7974 for (int i = 0; i < size; i++) { 7975 final ArrayMap<GrantUri, UriPermission> perms = 7976 mGrantedUriPermissions.valueAt(i); 7977 for (UriPermission perm : perms.values()) { 7978 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7979 result.add(perm.buildPersistedPublicApiObject()); 7980 } 7981 } 7982 } 7983 } 7984 } 7985 return new ParceledListSlice<android.content.UriPermission>(result); 7986 } 7987 7988 @Override showWaitingForDebugger(IApplicationThread who, boolean waiting)7989 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7990 synchronized (this) { 7991 ProcessRecord app = 7992 who != null ? getRecordForAppLocked(who) : null; 7993 if (app == null) return; 7994 7995 Message msg = Message.obtain(); 7996 msg.what = WAIT_FOR_DEBUGGER_MSG; 7997 msg.obj = app; 7998 msg.arg1 = waiting ? 1 : 0; 7999 mHandler.sendMessage(msg); 8000 } 8001 } 8002 8003 @Override getMemoryInfo(ActivityManager.MemoryInfo outInfo)8004 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8005 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8006 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8007 outInfo.availMem = Process.getFreeMemory(); 8008 outInfo.totalMem = Process.getTotalMemory(); 8009 outInfo.threshold = homeAppMem; 8010 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8011 outInfo.hiddenAppThreshold = cachedAppMem; 8012 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8013 ProcessList.SERVICE_ADJ); 8014 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8015 ProcessList.VISIBLE_APP_ADJ); 8016 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8017 ProcessList.FOREGROUND_APP_ADJ); 8018 } 8019 8020 // ========================================================= 8021 // TASK MANAGEMENT 8022 // ========================================================= 8023 8024 @Override 8025 public List<IAppTask> getAppTasks(String callingPackage) { 8026 int callingUid = Binder.getCallingUid(); 8027 long ident = Binder.clearCallingIdentity(); 8028 8029 synchronized(this) { 8030 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8031 try { 8032 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8033 8034 final int N = mRecentTasks.size(); 8035 for (int i = 0; i < N; i++) { 8036 TaskRecord tr = mRecentTasks.get(i); 8037 // Skip tasks that do not match the caller. We don't need to verify 8038 // callingPackage, because we are also limiting to callingUid and know 8039 // that will limit to the correct security sandbox. 8040 if (tr.effectiveUid != callingUid) { 8041 continue; 8042 } 8043 Intent intent = tr.getBaseIntent(); 8044 if (intent == null || 8045 !callingPackage.equals(intent.getComponent().getPackageName())) { 8046 continue; 8047 } 8048 ActivityManager.RecentTaskInfo taskInfo = 8049 createRecentTaskInfoFromTaskRecord(tr); 8050 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8051 list.add(taskImpl); 8052 } 8053 } finally { 8054 Binder.restoreCallingIdentity(ident); 8055 } 8056 return list; 8057 } 8058 } 8059 8060 @Override 8061 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8062 final int callingUid = Binder.getCallingUid(); 8063 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8064 8065 synchronized(this) { 8066 if (localLOGV) Slog.v( 8067 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8068 8069 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8070 callingUid); 8071 8072 // TODO: Improve with MRU list from all ActivityStacks. 8073 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8074 } 8075 8076 return list; 8077 } 8078 8079 /** 8080 * Creates a new RecentTaskInfo from a TaskRecord. 8081 */ 8082 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8083 // Update the task description to reflect any changes in the task stack 8084 tr.updateTaskDescription(); 8085 8086 // Compose the recent task info 8087 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8088 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8089 rti.persistentId = tr.taskId; 8090 rti.baseIntent = new Intent(tr.getBaseIntent()); 8091 rti.origActivity = tr.origActivity; 8092 rti.description = tr.lastDescription; 8093 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8094 rti.userId = tr.userId; 8095 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8096 rti.firstActiveTime = tr.firstActiveTime; 8097 rti.lastActiveTime = tr.lastActiveTime; 8098 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8099 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8100 return rti; 8101 } 8102 8103 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8104 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8105 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8106 if (!allowed) { 8107 if (checkPermission(android.Manifest.permission.GET_TASKS, 8108 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8109 // Temporary compatibility: some existing apps on the system image may 8110 // still be requesting the old permission and not switched to the new 8111 // one; if so, we'll still allow them full access. This means we need 8112 // to see if they are holding the old permission and are a system app. 8113 try { 8114 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8115 allowed = true; 8116 Slog.w(TAG, caller + ": caller " + callingUid 8117 + " is using old GET_TASKS but privileged; allowing"); 8118 } 8119 } catch (RemoteException e) { 8120 } 8121 } 8122 } 8123 if (!allowed) { 8124 Slog.w(TAG, caller + ": caller " + callingUid 8125 + " does not hold GET_TASKS; limiting output"); 8126 } 8127 return allowed; 8128 } 8129 8130 @Override 8131 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8132 final int callingUid = Binder.getCallingUid(); 8133 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8134 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8135 8136 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8137 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8138 synchronized (this) { 8139 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8140 callingUid); 8141 final boolean detailed = checkCallingPermission( 8142 android.Manifest.permission.GET_DETAILED_TASKS) 8143 == PackageManager.PERMISSION_GRANTED; 8144 8145 final int N = mRecentTasks.size(); 8146 ArrayList<ActivityManager.RecentTaskInfo> res 8147 = new ArrayList<ActivityManager.RecentTaskInfo>( 8148 maxNum < N ? maxNum : N); 8149 8150 final Set<Integer> includedUsers; 8151 if (includeProfiles) { 8152 includedUsers = getProfileIdsLocked(userId); 8153 } else { 8154 includedUsers = new HashSet<Integer>(); 8155 } 8156 includedUsers.add(Integer.valueOf(userId)); 8157 8158 for (int i=0; i<N && maxNum > 0; i++) { 8159 TaskRecord tr = mRecentTasks.get(i); 8160 // Only add calling user or related users recent tasks 8161 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8162 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8163 continue; 8164 } 8165 8166 // Return the entry if desired by the caller. We always return 8167 // the first entry, because callers always expect this to be the 8168 // foreground app. We may filter others if the caller has 8169 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8170 // we should exclude the entry. 8171 8172 if (i == 0 8173 || withExcluded 8174 || (tr.intent == null) 8175 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8176 == 0)) { 8177 if (!allowed) { 8178 // If the caller doesn't have the GET_TASKS permission, then only 8179 // allow them to see a small subset of tasks -- their own and home. 8180 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8181 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8182 continue; 8183 } 8184 } 8185 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8186 if (tr.stack != null && tr.stack.isHomeStack()) { 8187 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8188 continue; 8189 } 8190 } 8191 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8192 // Don't include auto remove tasks that are finished or finishing. 8193 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8194 + tr); 8195 continue; 8196 } 8197 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8198 && !tr.isAvailable) { 8199 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8200 continue; 8201 } 8202 8203 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8204 if (!detailed) { 8205 rti.baseIntent.replaceExtras((Bundle)null); 8206 } 8207 8208 res.add(rti); 8209 maxNum--; 8210 } 8211 } 8212 return res; 8213 } 8214 } 8215 8216 TaskRecord recentTaskForIdLocked(int id) { 8217 final int N = mRecentTasks.size(); 8218 for (int i=0; i<N; i++) { 8219 TaskRecord tr = mRecentTasks.get(i); 8220 if (tr.taskId == id) { 8221 return tr; 8222 } 8223 } 8224 return null; 8225 } 8226 8227 @Override 8228 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8229 synchronized (this) { 8230 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8231 "getTaskThumbnail()"); 8232 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8233 if (tr != null) { 8234 return tr.getTaskThumbnailLocked(); 8235 } 8236 } 8237 return null; 8238 } 8239 8240 @Override 8241 public int addAppTask(IBinder activityToken, Intent intent, 8242 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8243 final int callingUid = Binder.getCallingUid(); 8244 final long callingIdent = Binder.clearCallingIdentity(); 8245 8246 try { 8247 synchronized (this) { 8248 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8249 if (r == null) { 8250 throw new IllegalArgumentException("Activity does not exist; token=" 8251 + activityToken); 8252 } 8253 ComponentName comp = intent.getComponent(); 8254 if (comp == null) { 8255 throw new IllegalArgumentException("Intent " + intent 8256 + " must specify explicit component"); 8257 } 8258 if (thumbnail.getWidth() != mThumbnailWidth 8259 || thumbnail.getHeight() != mThumbnailHeight) { 8260 throw new IllegalArgumentException("Bad thumbnail size: got " 8261 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8262 + mThumbnailWidth + "x" + mThumbnailHeight); 8263 } 8264 if (intent.getSelector() != null) { 8265 intent.setSelector(null); 8266 } 8267 if (intent.getSourceBounds() != null) { 8268 intent.setSourceBounds(null); 8269 } 8270 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8271 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8272 // The caller has added this as an auto-remove task... that makes no 8273 // sense, so turn off auto-remove. 8274 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8275 } 8276 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8277 // Must be a new task. 8278 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8279 } 8280 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8281 mLastAddedTaskActivity = null; 8282 } 8283 ActivityInfo ainfo = mLastAddedTaskActivity; 8284 if (ainfo == null) { 8285 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8286 comp, 0, UserHandle.getUserId(callingUid)); 8287 if (ainfo.applicationInfo.uid != callingUid) { 8288 throw new SecurityException( 8289 "Can't add task for another application: target uid=" 8290 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8291 } 8292 } 8293 8294 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8295 intent, description); 8296 8297 int trimIdx = trimRecentsForTaskLocked(task, false); 8298 if (trimIdx >= 0) { 8299 // If this would have caused a trim, then we'll abort because that 8300 // means it would be added at the end of the list but then just removed. 8301 return INVALID_TASK_ID; 8302 } 8303 8304 final int N = mRecentTasks.size(); 8305 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8306 final TaskRecord tr = mRecentTasks.remove(N - 1); 8307 tr.removedFromRecents(); 8308 } 8309 8310 task.inRecents = true; 8311 mRecentTasks.add(task); 8312 r.task.stack.addTask(task, false, false); 8313 8314 task.setLastThumbnail(thumbnail); 8315 task.freeLastThumbnail(); 8316 8317 return task.taskId; 8318 } 8319 } finally { 8320 Binder.restoreCallingIdentity(callingIdent); 8321 } 8322 } 8323 8324 @Override 8325 public Point getAppTaskThumbnailSize() { 8326 synchronized (this) { 8327 return new Point(mThumbnailWidth, mThumbnailHeight); 8328 } 8329 } 8330 8331 @Override 8332 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8333 synchronized (this) { 8334 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8335 if (r != null) { 8336 r.setTaskDescription(td); 8337 r.task.updateTaskDescription(); 8338 } 8339 } 8340 } 8341 8342 @Override 8343 public Bitmap getTaskDescriptionIcon(String filename) { 8344 if (!FileUtils.isValidExtFilename(filename) 8345 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8346 throw new IllegalArgumentException("Bad filename: " + filename); 8347 } 8348 return mTaskPersister.getTaskDescriptionIcon(filename); 8349 } 8350 8351 @Override 8352 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8353 throws RemoteException { 8354 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8355 opts.getCustomInPlaceResId() == 0) { 8356 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8357 "with valid animation"); 8358 } 8359 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8360 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8361 opts.getCustomInPlaceResId()); 8362 mWindowManager.executeAppTransition(); 8363 } 8364 8365 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8366 mRecentTasks.remove(tr); 8367 tr.removedFromRecents(); 8368 ComponentName component = tr.getBaseIntent().getComponent(); 8369 if (component == null) { 8370 Slog.w(TAG, "No component for base intent of task: " + tr); 8371 return; 8372 } 8373 8374 if (!killProcess) { 8375 return; 8376 } 8377 8378 // Determine if the process(es) for this task should be killed. 8379 final String pkg = component.getPackageName(); 8380 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8381 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8382 for (int i = 0; i < pmap.size(); i++) { 8383 8384 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8385 for (int j = 0; j < uids.size(); j++) { 8386 ProcessRecord proc = uids.valueAt(j); 8387 if (proc.userId != tr.userId) { 8388 // Don't kill process for a different user. 8389 continue; 8390 } 8391 if (proc == mHomeProcess) { 8392 // Don't kill the home process along with tasks from the same package. 8393 continue; 8394 } 8395 if (!proc.pkgList.containsKey(pkg)) { 8396 // Don't kill process that is not associated with this task. 8397 continue; 8398 } 8399 8400 for (int k = 0; k < proc.activities.size(); k++) { 8401 TaskRecord otherTask = proc.activities.get(k).task; 8402 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8403 // Don't kill process(es) that has an activity in a different task that is 8404 // also in recents. 8405 return; 8406 } 8407 } 8408 8409 // Add process to kill list. 8410 procsToKill.add(proc); 8411 } 8412 } 8413 8414 // Find any running services associated with this app and stop if needed. 8415 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8416 8417 // Kill the running processes. 8418 for (int i = 0; i < procsToKill.size(); i++) { 8419 ProcessRecord pr = procsToKill.get(i); 8420 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8421 pr.kill("remove task", true); 8422 } else { 8423 pr.waitingToKill = "remove task"; 8424 } 8425 } 8426 } 8427 8428 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8429 // Remove all tasks with activities in the specified package from the list of recent tasks 8430 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8431 TaskRecord tr = mRecentTasks.get(i); 8432 if (tr.userId != userId) continue; 8433 8434 ComponentName cn = tr.intent.getComponent(); 8435 if (cn != null && cn.getPackageName().equals(packageName)) { 8436 // If the package name matches, remove the task. 8437 removeTaskByIdLocked(tr.taskId, true); 8438 } 8439 } 8440 } 8441 8442 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8443 final IPackageManager pm = AppGlobals.getPackageManager(); 8444 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8445 8446 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8447 TaskRecord tr = mRecentTasks.get(i); 8448 if (tr.userId != userId) continue; 8449 8450 ComponentName cn = tr.intent.getComponent(); 8451 if (cn != null && cn.getPackageName().equals(packageName)) { 8452 // Skip if component still exists in the package. 8453 if (componentsKnownToExist.contains(cn)) continue; 8454 8455 try { 8456 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8457 if (info != null) { 8458 componentsKnownToExist.add(cn); 8459 } else { 8460 removeTaskByIdLocked(tr.taskId, false); 8461 } 8462 } catch (RemoteException e) { 8463 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8464 } 8465 } 8466 } 8467 } 8468 8469 /** 8470 * Removes the task with the specified task id. 8471 * 8472 * @param taskId Identifier of the task to be removed. 8473 * @param killProcess Kill any process associated with the task if possible. 8474 * @return Returns true if the given task was found and removed. 8475 */ 8476 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8477 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8478 if (tr != null) { 8479 tr.removeTaskActivitiesLocked(); 8480 cleanUpRemovedTaskLocked(tr, killProcess); 8481 if (tr.isPersistable) { 8482 notifyTaskPersisterLocked(null, true); 8483 } 8484 return true; 8485 } 8486 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8487 return false; 8488 } 8489 8490 @Override 8491 public boolean removeTask(int taskId) { 8492 synchronized (this) { 8493 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8494 "removeTask()"); 8495 long ident = Binder.clearCallingIdentity(); 8496 try { 8497 return removeTaskByIdLocked(taskId, true); 8498 } finally { 8499 Binder.restoreCallingIdentity(ident); 8500 } 8501 } 8502 } 8503 8504 /** 8505 * TODO: Add mController hook 8506 */ 8507 @Override 8508 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8509 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8510 "moveTaskToFront()"); 8511 8512 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8513 synchronized(this) { 8514 moveTaskToFrontLocked(taskId, flags, options); 8515 } 8516 } 8517 8518 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8519 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8520 Binder.getCallingUid(), -1, -1, "Task to front")) { 8521 ActivityOptions.abort(options); 8522 return; 8523 } 8524 final long origId = Binder.clearCallingIdentity(); 8525 try { 8526 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8527 if (task == null) { 8528 Slog.d(TAG, "Could not find task for id: "+ taskId); 8529 return; 8530 } 8531 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8532 mStackSupervisor.showLockTaskToast(); 8533 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8534 return; 8535 } 8536 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8537 if (prev != null && prev.isRecentsActivity()) { 8538 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8539 } 8540 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront"); 8541 } finally { 8542 Binder.restoreCallingIdentity(origId); 8543 } 8544 ActivityOptions.abort(options); 8545 } 8546 8547 @Override 8548 public void moveTaskToBack(int taskId) { 8549 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8550 "moveTaskToBack()"); 8551 8552 synchronized(this) { 8553 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8554 if (tr != null) { 8555 if (tr == mStackSupervisor.mLockTaskModeTask) { 8556 mStackSupervisor.showLockTaskToast(); 8557 return; 8558 } 8559 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8560 ActivityStack stack = tr.stack; 8561 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8562 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8563 Binder.getCallingUid(), -1, -1, "Task to back")) { 8564 return; 8565 } 8566 } 8567 final long origId = Binder.clearCallingIdentity(); 8568 try { 8569 stack.moveTaskToBackLocked(taskId); 8570 } finally { 8571 Binder.restoreCallingIdentity(origId); 8572 } 8573 } 8574 } 8575 } 8576 8577 /** 8578 * Moves an activity, and all of the other activities within the same task, to the bottom 8579 * of the history stack. The activity's order within the task is unchanged. 8580 * 8581 * @param token A reference to the activity we wish to move 8582 * @param nonRoot If false then this only works if the activity is the root 8583 * of a task; if true it will work for any activity in a task. 8584 * @return Returns true if the move completed, false if not. 8585 */ 8586 @Override 8587 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8588 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8589 synchronized(this) { 8590 final long origId = Binder.clearCallingIdentity(); 8591 try { 8592 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8593 if (taskId >= 0) { 8594 if ((mStackSupervisor.mLockTaskModeTask != null) 8595 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8596 mStackSupervisor.showLockTaskToast(); 8597 return false; 8598 } 8599 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId); 8600 } 8601 } finally { 8602 Binder.restoreCallingIdentity(origId); 8603 } 8604 } 8605 return false; 8606 } 8607 8608 @Override 8609 public void moveTaskBackwards(int task) { 8610 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8611 "moveTaskBackwards()"); 8612 8613 synchronized(this) { 8614 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8615 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8616 return; 8617 } 8618 final long origId = Binder.clearCallingIdentity(); 8619 moveTaskBackwardsLocked(task); 8620 Binder.restoreCallingIdentity(origId); 8621 } 8622 } 8623 8624 private final void moveTaskBackwardsLocked(int task) { 8625 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8626 } 8627 8628 @Override 8629 public IBinder getHomeActivityToken() throws RemoteException { 8630 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8631 "getHomeActivityToken()"); 8632 synchronized (this) { 8633 return mStackSupervisor.getHomeActivityToken(); 8634 } 8635 } 8636 8637 @Override 8638 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8639 IActivityContainerCallback callback) throws RemoteException { 8640 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8641 "createActivityContainer()"); 8642 synchronized (this) { 8643 if (parentActivityToken == null) { 8644 throw new IllegalArgumentException("parent token must not be null"); 8645 } 8646 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8647 if (r == null) { 8648 return null; 8649 } 8650 if (callback == null) { 8651 throw new IllegalArgumentException("callback must not be null"); 8652 } 8653 return mStackSupervisor.createActivityContainer(r, callback); 8654 } 8655 } 8656 8657 @Override 8658 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8659 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8660 "deleteActivityContainer()"); 8661 synchronized (this) { 8662 mStackSupervisor.deleteActivityContainer(container); 8663 } 8664 } 8665 8666 @Override 8667 public int getActivityDisplayId(IBinder activityToken) throws RemoteException { 8668 synchronized (this) { 8669 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8670 if (stack != null && stack.mActivityContainer.isAttachedLocked()) { 8671 return stack.mActivityContainer.getDisplayId(); 8672 } 8673 return Display.DEFAULT_DISPLAY; 8674 } 8675 } 8676 8677 @Override 8678 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8679 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8680 "moveTaskToStack()"); 8681 if (stackId == HOME_STACK_ID) { 8682 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8683 new RuntimeException("here").fillInStackTrace()); 8684 } 8685 synchronized (this) { 8686 long ident = Binder.clearCallingIdentity(); 8687 try { 8688 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8689 + stackId + " toTop=" + toTop); 8690 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop); 8691 } finally { 8692 Binder.restoreCallingIdentity(ident); 8693 } 8694 } 8695 } 8696 8697 @Override 8698 public void resizeStack(int stackBoxId, Rect bounds) { 8699 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8700 "resizeStackBox()"); 8701 long ident = Binder.clearCallingIdentity(); 8702 try { 8703 mWindowManager.resizeStack(stackBoxId, bounds); 8704 } finally { 8705 Binder.restoreCallingIdentity(ident); 8706 } 8707 } 8708 8709 @Override 8710 public List<StackInfo> getAllStackInfos() { 8711 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8712 "getAllStackInfos()"); 8713 long ident = Binder.clearCallingIdentity(); 8714 try { 8715 synchronized (this) { 8716 return mStackSupervisor.getAllStackInfosLocked(); 8717 } 8718 } finally { 8719 Binder.restoreCallingIdentity(ident); 8720 } 8721 } 8722 8723 @Override 8724 public StackInfo getStackInfo(int stackId) { 8725 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8726 "getStackInfo()"); 8727 long ident = Binder.clearCallingIdentity(); 8728 try { 8729 synchronized (this) { 8730 return mStackSupervisor.getStackInfoLocked(stackId); 8731 } 8732 } finally { 8733 Binder.restoreCallingIdentity(ident); 8734 } 8735 } 8736 8737 @Override 8738 public boolean isInHomeStack(int taskId) { 8739 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8740 "getStackInfo()"); 8741 long ident = Binder.clearCallingIdentity(); 8742 try { 8743 synchronized (this) { 8744 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8745 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8746 } 8747 } finally { 8748 Binder.restoreCallingIdentity(ident); 8749 } 8750 } 8751 8752 @Override 8753 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8754 synchronized(this) { 8755 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8756 } 8757 } 8758 8759 private boolean isLockTaskAuthorized(String pkg) { 8760 final DevicePolicyManager dpm = (DevicePolicyManager) 8761 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8762 try { 8763 int uid = mContext.getPackageManager().getPackageUid(pkg, 8764 Binder.getCallingUserHandle().getIdentifier()); 8765 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8766 } catch (NameNotFoundException e) { 8767 return false; 8768 } 8769 } 8770 8771 void startLockTaskMode(TaskRecord task) { 8772 final String pkg; 8773 synchronized (this) { 8774 pkg = task.intent.getComponent().getPackageName(); 8775 } 8776 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8777 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8778 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8779 StatusBarManagerInternal.class); 8780 if (statusBarManager != null) { 8781 statusBarManager.showScreenPinningRequest(); 8782 } 8783 return; 8784 } 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 synchronized (this) { 8788 // Since we lost lock on task, make sure it is still there. 8789 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8790 if (task != null) { 8791 if (!isSystemInitiated 8792 && ((mStackSupervisor.getFocusedStack() == null) 8793 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8794 throw new IllegalArgumentException("Invalid task, not in foreground"); 8795 } 8796 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated, 8797 "startLockTask"); 8798 } 8799 } 8800 } finally { 8801 Binder.restoreCallingIdentity(ident); 8802 } 8803 } 8804 8805 @Override 8806 public void startLockTaskMode(int taskId) { 8807 final TaskRecord task; 8808 long ident = Binder.clearCallingIdentity(); 8809 try { 8810 synchronized (this) { 8811 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8812 } 8813 } finally { 8814 Binder.restoreCallingIdentity(ident); 8815 } 8816 if (task != null) { 8817 startLockTaskMode(task); 8818 } 8819 } 8820 8821 @Override 8822 public void startLockTaskMode(IBinder token) { 8823 final TaskRecord task; 8824 long ident = Binder.clearCallingIdentity(); 8825 try { 8826 synchronized (this) { 8827 final ActivityRecord r = ActivityRecord.forToken(token); 8828 if (r == null) { 8829 return; 8830 } 8831 task = r.task; 8832 } 8833 } finally { 8834 Binder.restoreCallingIdentity(ident); 8835 } 8836 if (task != null) { 8837 startLockTaskMode(task); 8838 } 8839 } 8840 8841 @Override 8842 public void startLockTaskModeOnCurrent() throws RemoteException { 8843 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8844 "startLockTaskModeOnCurrent"); 8845 long ident = Binder.clearCallingIdentity(); 8846 try { 8847 ActivityRecord r = null; 8848 synchronized (this) { 8849 r = mStackSupervisor.topRunningActivityLocked(); 8850 } 8851 startLockTaskMode(r.task); 8852 } finally { 8853 Binder.restoreCallingIdentity(ident); 8854 } 8855 } 8856 8857 @Override 8858 public void stopLockTaskMode() { 8859 // Verify that the user matches the package of the intent for the TaskRecord 8860 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8861 // and stopLockTaskMode. 8862 final int callingUid = Binder.getCallingUid(); 8863 if (callingUid != Process.SYSTEM_UID) { 8864 try { 8865 String pkg = 8866 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8867 int uid = mContext.getPackageManager().getPackageUid(pkg, 8868 Binder.getCallingUserHandle().getIdentifier()); 8869 if (uid != callingUid) { 8870 throw new SecurityException("Invalid uid, expected " + uid); 8871 } 8872 } catch (NameNotFoundException e) { 8873 Log.d(TAG, "stopLockTaskMode " + e); 8874 return; 8875 } 8876 } 8877 long ident = Binder.clearCallingIdentity(); 8878 try { 8879 Log.d(TAG, "stopLockTaskMode"); 8880 // Stop lock task 8881 synchronized (this) { 8882 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask"); 8883 } 8884 } finally { 8885 Binder.restoreCallingIdentity(ident); 8886 } 8887 } 8888 8889 @Override 8890 public void stopLockTaskModeOnCurrent() throws RemoteException { 8891 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8892 "stopLockTaskModeOnCurrent"); 8893 long ident = Binder.clearCallingIdentity(); 8894 try { 8895 stopLockTaskMode(); 8896 } finally { 8897 Binder.restoreCallingIdentity(ident); 8898 } 8899 } 8900 8901 @Override 8902 public boolean isInLockTaskMode() { 8903 synchronized (this) { 8904 return mStackSupervisor.isInLockTaskMode(); 8905 } 8906 } 8907 8908 // ========================================================= 8909 // CONTENT PROVIDERS 8910 // ========================================================= 8911 8912 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8913 List<ProviderInfo> providers = null; 8914 try { 8915 providers = AppGlobals.getPackageManager(). 8916 queryContentProviders(app.processName, app.uid, 8917 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8918 } catch (RemoteException ex) { 8919 } 8920 if (DEBUG_MU) 8921 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8922 int userId = app.userId; 8923 if (providers != null) { 8924 int N = providers.size(); 8925 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8926 for (int i=0; i<N; i++) { 8927 ProviderInfo cpi = 8928 (ProviderInfo)providers.get(i); 8929 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8930 cpi.name, cpi.flags); 8931 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8932 // This is a singleton provider, but a user besides the 8933 // default user is asking to initialize a process it runs 8934 // in... well, no, it doesn't actually run in this process, 8935 // it runs in the process of the default user. Get rid of it. 8936 providers.remove(i); 8937 N--; 8938 i--; 8939 continue; 8940 } 8941 8942 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8943 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8944 if (cpr == null) { 8945 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8946 mProviderMap.putProviderByClass(comp, cpr); 8947 } 8948 if (DEBUG_MU) 8949 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8950 app.pubProviders.put(cpi.name, cpr); 8951 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8952 // Don't add this if it is a platform component that is marked 8953 // to run in multiple processes, because this is actually 8954 // part of the framework so doesn't make sense to track as a 8955 // separate apk in the process. 8956 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8957 mProcessStats); 8958 } 8959 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8960 } 8961 } 8962 return providers; 8963 } 8964 8965 /** 8966 * Check if {@link ProcessRecord} has a possible chance at accessing the 8967 * given {@link ProviderInfo}. Final permission checking is always done 8968 * in {@link ContentProvider}. 8969 */ 8970 private final String checkContentProviderPermissionLocked( 8971 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8972 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8973 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8974 boolean checkedGrants = false; 8975 if (checkUser) { 8976 // Looking for cross-user grants before enforcing the typical cross-users permissions 8977 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8978 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8979 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8980 return null; 8981 } 8982 checkedGrants = true; 8983 } 8984 userId = handleIncomingUser(callingPid, callingUid, userId, 8985 false, ALLOW_NON_FULL, 8986 "checkContentProviderPermissionLocked " + cpi.authority, null); 8987 if (userId != tmpTargetUserId) { 8988 // When we actually went to determine the final targer user ID, this ended 8989 // up different than our initial check for the authority. This is because 8990 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8991 // SELF. So we need to re-check the grants again. 8992 checkedGrants = false; 8993 } 8994 } 8995 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8996 cpi.applicationInfo.uid, cpi.exported) 8997 == PackageManager.PERMISSION_GRANTED) { 8998 return null; 8999 } 9000 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9001 cpi.applicationInfo.uid, cpi.exported) 9002 == PackageManager.PERMISSION_GRANTED) { 9003 return null; 9004 } 9005 9006 PathPermission[] pps = cpi.pathPermissions; 9007 if (pps != null) { 9008 int i = pps.length; 9009 while (i > 0) { 9010 i--; 9011 PathPermission pp = pps[i]; 9012 String pprperm = pp.getReadPermission(); 9013 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9014 cpi.applicationInfo.uid, cpi.exported) 9015 == PackageManager.PERMISSION_GRANTED) { 9016 return null; 9017 } 9018 String ppwperm = pp.getWritePermission(); 9019 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9020 cpi.applicationInfo.uid, cpi.exported) 9021 == PackageManager.PERMISSION_GRANTED) { 9022 return null; 9023 } 9024 } 9025 } 9026 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9027 return null; 9028 } 9029 9030 String msg; 9031 if (!cpi.exported) { 9032 msg = "Permission Denial: opening provider " + cpi.name 9033 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9034 + ", uid=" + callingUid + ") that is not exported from uid " 9035 + cpi.applicationInfo.uid; 9036 } else { 9037 msg = "Permission Denial: opening provider " + cpi.name 9038 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9039 + ", uid=" + callingUid + ") requires " 9040 + cpi.readPermission + " or " + cpi.writePermission; 9041 } 9042 Slog.w(TAG, msg); 9043 return msg; 9044 } 9045 9046 /** 9047 * Returns if the ContentProvider has granted a uri to callingUid 9048 */ 9049 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9050 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9051 if (perms != null) { 9052 for (int i=perms.size()-1; i>=0; i--) { 9053 GrantUri grantUri = perms.keyAt(i); 9054 if (grantUri.sourceUserId == userId || !checkUser) { 9055 if (matchesProvider(grantUri.uri, cpi)) { 9056 return true; 9057 } 9058 } 9059 } 9060 } 9061 return false; 9062 } 9063 9064 /** 9065 * Returns true if the uri authority is one of the authorities specified in the provider. 9066 */ 9067 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9068 String uriAuth = uri.getAuthority(); 9069 String cpiAuth = cpi.authority; 9070 if (cpiAuth.indexOf(';') == -1) { 9071 return cpiAuth.equals(uriAuth); 9072 } 9073 String[] cpiAuths = cpiAuth.split(";"); 9074 int length = cpiAuths.length; 9075 for (int i = 0; i < length; i++) { 9076 if (cpiAuths[i].equals(uriAuth)) return true; 9077 } 9078 return false; 9079 } 9080 9081 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9082 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9083 if (r != null) { 9084 for (int i=0; i<r.conProviders.size(); i++) { 9085 ContentProviderConnection conn = r.conProviders.get(i); 9086 if (conn.provider == cpr) { 9087 if (DEBUG_PROVIDER) Slog.v(TAG, 9088 "Adding provider requested by " 9089 + r.processName + " from process " 9090 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9091 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9092 if (stable) { 9093 conn.stableCount++; 9094 conn.numStableIncs++; 9095 } else { 9096 conn.unstableCount++; 9097 conn.numUnstableIncs++; 9098 } 9099 return conn; 9100 } 9101 } 9102 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9103 if (stable) { 9104 conn.stableCount = 1; 9105 conn.numStableIncs = 1; 9106 } else { 9107 conn.unstableCount = 1; 9108 conn.numUnstableIncs = 1; 9109 } 9110 cpr.connections.add(conn); 9111 r.conProviders.add(conn); 9112 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); 9113 return conn; 9114 } 9115 cpr.addExternalProcessHandleLocked(externalProcessToken); 9116 return null; 9117 } 9118 9119 boolean decProviderCountLocked(ContentProviderConnection conn, 9120 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9121 if (conn != null) { 9122 cpr = conn.provider; 9123 if (DEBUG_PROVIDER) Slog.v(TAG, 9124 "Removing provider requested by " 9125 + conn.client.processName + " from process " 9126 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9127 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9128 if (stable) { 9129 conn.stableCount--; 9130 } else { 9131 conn.unstableCount--; 9132 } 9133 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9134 cpr.connections.remove(conn); 9135 conn.client.conProviders.remove(conn); 9136 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 9137 return true; 9138 } 9139 return false; 9140 } 9141 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9142 return false; 9143 } 9144 9145 private void checkTime(long startTime, String where) { 9146 long now = SystemClock.elapsedRealtime(); 9147 if ((now-startTime) > 1000) { 9148 // If we are taking more than a second, log about it. 9149 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9150 } 9151 } 9152 9153 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9154 String name, IBinder token, boolean stable, int userId) { 9155 ContentProviderRecord cpr; 9156 ContentProviderConnection conn = null; 9157 ProviderInfo cpi = null; 9158 9159 synchronized(this) { 9160 long startTime = SystemClock.elapsedRealtime(); 9161 9162 ProcessRecord r = null; 9163 if (caller != null) { 9164 r = getRecordForAppLocked(caller); 9165 if (r == null) { 9166 throw new SecurityException( 9167 "Unable to find app for caller " + caller 9168 + " (pid=" + Binder.getCallingPid() 9169 + ") when getting content provider " + name); 9170 } 9171 } 9172 9173 boolean checkCrossUser = true; 9174 9175 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9176 9177 // First check if this content provider has been published... 9178 cpr = mProviderMap.getProviderByName(name, userId); 9179 // If that didn't work, check if it exists for user 0 and then 9180 // verify that it's a singleton provider before using it. 9181 if (cpr == null && userId != UserHandle.USER_OWNER) { 9182 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9183 if (cpr != null) { 9184 cpi = cpr.info; 9185 if (isSingleton(cpi.processName, cpi.applicationInfo, 9186 cpi.name, cpi.flags) 9187 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9188 userId = UserHandle.USER_OWNER; 9189 checkCrossUser = false; 9190 } else { 9191 cpr = null; 9192 cpi = null; 9193 } 9194 } 9195 } 9196 9197 boolean providerRunning = cpr != null; 9198 if (providerRunning) { 9199 cpi = cpr.info; 9200 String msg; 9201 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9202 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9203 != null) { 9204 throw new SecurityException(msg); 9205 } 9206 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9207 9208 if (r != null && cpr.canRunHere(r)) { 9209 // This provider has been published or is in the process 9210 // of being published... but it is also allowed to run 9211 // in the caller's process, so don't make a connection 9212 // and just let the caller instantiate its own instance. 9213 ContentProviderHolder holder = cpr.newHolder(null); 9214 // don't give caller the provider object, it needs 9215 // to make its own. 9216 holder.provider = null; 9217 return holder; 9218 } 9219 9220 final long origId = Binder.clearCallingIdentity(); 9221 9222 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9223 9224 // In this case the provider instance already exists, so we can 9225 // return it right away. 9226 conn = incProviderCountLocked(r, cpr, token, stable); 9227 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9228 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9229 // If this is a perceptible app accessing the provider, 9230 // make sure to count it as being accessed and thus 9231 // back up on the LRU list. This is good because 9232 // content providers are often expensive to start. 9233 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9234 updateLruProcessLocked(cpr.proc, false, null); 9235 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9236 } 9237 } 9238 9239 if (cpr.proc != null) { 9240 if (false) { 9241 if (cpr.name.flattenToShortString().equals( 9242 "com.android.providers.calendar/.CalendarProvider2")) { 9243 Slog.v(TAG, "****************** KILLING " 9244 + cpr.name.flattenToShortString()); 9245 Process.killProcess(cpr.proc.pid); 9246 } 9247 } 9248 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9249 boolean success = updateOomAdjLocked(cpr.proc); 9250 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9251 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9252 // NOTE: there is still a race here where a signal could be 9253 // pending on the process even though we managed to update its 9254 // adj level. Not sure what to do about this, but at least 9255 // the race is now smaller. 9256 if (!success) { 9257 // Uh oh... it looks like the provider's process 9258 // has been killed on us. We need to wait for a new 9259 // process to be started, and make sure its death 9260 // doesn't kill our process. 9261 Slog.i(TAG, 9262 "Existing provider " + cpr.name.flattenToShortString() 9263 + " is crashing; detaching " + r); 9264 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9265 checkTime(startTime, "getContentProviderImpl: before appDied"); 9266 appDiedLocked(cpr.proc); 9267 checkTime(startTime, "getContentProviderImpl: after appDied"); 9268 if (!lastRef) { 9269 // This wasn't the last ref our process had on 9270 // the provider... we have now been killed, bail. 9271 return null; 9272 } 9273 providerRunning = false; 9274 conn = null; 9275 } 9276 } 9277 9278 Binder.restoreCallingIdentity(origId); 9279 } 9280 9281 boolean singleton; 9282 if (!providerRunning) { 9283 try { 9284 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9285 cpi = AppGlobals.getPackageManager(). 9286 resolveContentProvider(name, 9287 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9288 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9289 } catch (RemoteException ex) { 9290 } 9291 if (cpi == null) { 9292 return null; 9293 } 9294 // If the provider is a singleton AND 9295 // (it's a call within the same user || the provider is a 9296 // privileged app) 9297 // Then allow connecting to the singleton provider 9298 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9299 cpi.name, cpi.flags) 9300 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9301 if (singleton) { 9302 userId = UserHandle.USER_OWNER; 9303 } 9304 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9305 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9306 9307 String msg; 9308 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9309 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9310 != null) { 9311 throw new SecurityException(msg); 9312 } 9313 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9314 9315 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9316 && !cpi.processName.equals("system")) { 9317 // If this content provider does not run in the system 9318 // process, and the system is not yet ready to run other 9319 // processes, then fail fast instead of hanging. 9320 throw new IllegalArgumentException( 9321 "Attempt to launch content provider before system ready"); 9322 } 9323 9324 // Make sure that the user who owns this provider is running. If not, 9325 // we don't want to allow it to run. 9326 if (!isUserRunningLocked(userId, false)) { 9327 Slog.w(TAG, "Unable to launch app " 9328 + cpi.applicationInfo.packageName + "/" 9329 + cpi.applicationInfo.uid + " for provider " 9330 + name + ": user " + userId + " is stopped"); 9331 return null; 9332 } 9333 9334 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9335 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9336 cpr = mProviderMap.getProviderByClass(comp, userId); 9337 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9338 final boolean firstClass = cpr == null; 9339 if (firstClass) { 9340 final long ident = Binder.clearCallingIdentity(); 9341 try { 9342 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9343 ApplicationInfo ai = 9344 AppGlobals.getPackageManager(). 9345 getApplicationInfo( 9346 cpi.applicationInfo.packageName, 9347 STOCK_PM_FLAGS, userId); 9348 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9349 if (ai == null) { 9350 Slog.w(TAG, "No package info for content provider " 9351 + cpi.name); 9352 return null; 9353 } 9354 ai = getAppInfoForUser(ai, userId); 9355 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9356 } catch (RemoteException ex) { 9357 // pm is in same process, this will never happen. 9358 } finally { 9359 Binder.restoreCallingIdentity(ident); 9360 } 9361 } 9362 9363 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9364 9365 if (r != null && cpr.canRunHere(r)) { 9366 // If this is a multiprocess provider, then just return its 9367 // info and allow the caller to instantiate it. Only do 9368 // this if the provider is the same user as the caller's 9369 // process, or can run as root (so can be in any process). 9370 return cpr.newHolder(null); 9371 } 9372 9373 if (DEBUG_PROVIDER) { 9374 RuntimeException e = new RuntimeException("here"); 9375 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9376 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9377 } 9378 9379 // This is single process, and our app is now connecting to it. 9380 // See if we are already in the process of launching this 9381 // provider. 9382 final int N = mLaunchingProviders.size(); 9383 int i; 9384 for (i=0; i<N; i++) { 9385 if (mLaunchingProviders.get(i) == cpr) { 9386 break; 9387 } 9388 } 9389 9390 // If the provider is not already being launched, then get it 9391 // started. 9392 if (i >= N) { 9393 final long origId = Binder.clearCallingIdentity(); 9394 9395 try { 9396 // Content provider is now in use, its package can't be stopped. 9397 try { 9398 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9399 AppGlobals.getPackageManager().setPackageStoppedState( 9400 cpr.appInfo.packageName, false, userId); 9401 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9402 } catch (RemoteException e) { 9403 } catch (IllegalArgumentException e) { 9404 Slog.w(TAG, "Failed trying to unstop package " 9405 + cpr.appInfo.packageName + ": " + e); 9406 } 9407 9408 // Use existing process if already started 9409 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9410 ProcessRecord proc = getProcessRecordLocked( 9411 cpi.processName, cpr.appInfo.uid, false); 9412 if (proc != null && proc.thread != null) { 9413 if (DEBUG_PROVIDER) { 9414 Slog.d(TAG, "Installing in existing process " + proc); 9415 } 9416 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9417 proc.pubProviders.put(cpi.name, cpr); 9418 try { 9419 proc.thread.scheduleInstallProvider(cpi); 9420 } catch (RemoteException e) { 9421 } 9422 } else { 9423 checkTime(startTime, "getContentProviderImpl: before start process"); 9424 proc = startProcessLocked(cpi.processName, 9425 cpr.appInfo, false, 0, "content provider", 9426 new ComponentName(cpi.applicationInfo.packageName, 9427 cpi.name), false, false, false); 9428 checkTime(startTime, "getContentProviderImpl: after start process"); 9429 if (proc == null) { 9430 Slog.w(TAG, "Unable to launch app " 9431 + cpi.applicationInfo.packageName + "/" 9432 + cpi.applicationInfo.uid + " for provider " 9433 + name + ": process is bad"); 9434 return null; 9435 } 9436 } 9437 cpr.launchingApp = proc; 9438 mLaunchingProviders.add(cpr); 9439 } finally { 9440 Binder.restoreCallingIdentity(origId); 9441 } 9442 } 9443 9444 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9445 9446 // Make sure the provider is published (the same provider class 9447 // may be published under multiple names). 9448 if (firstClass) { 9449 mProviderMap.putProviderByClass(comp, cpr); 9450 } 9451 9452 mProviderMap.putProviderByName(name, cpr); 9453 conn = incProviderCountLocked(r, cpr, token, stable); 9454 if (conn != null) { 9455 conn.waiting = true; 9456 } 9457 } 9458 checkTime(startTime, "getContentProviderImpl: done!"); 9459 } 9460 9461 // Wait for the provider to be published... 9462 synchronized (cpr) { 9463 while (cpr.provider == null) { 9464 if (cpr.launchingApp == null) { 9465 Slog.w(TAG, "Unable to launch app " 9466 + cpi.applicationInfo.packageName + "/" 9467 + cpi.applicationInfo.uid + " for provider " 9468 + name + ": launching app became null"); 9469 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9470 UserHandle.getUserId(cpi.applicationInfo.uid), 9471 cpi.applicationInfo.packageName, 9472 cpi.applicationInfo.uid, name); 9473 return null; 9474 } 9475 try { 9476 if (DEBUG_MU) { 9477 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9478 + cpr.launchingApp); 9479 } 9480 if (conn != null) { 9481 conn.waiting = true; 9482 } 9483 cpr.wait(); 9484 } catch (InterruptedException ex) { 9485 } finally { 9486 if (conn != null) { 9487 conn.waiting = false; 9488 } 9489 } 9490 } 9491 } 9492 return cpr != null ? cpr.newHolder(conn) : null; 9493 } 9494 9495 @Override 9496 public final ContentProviderHolder getContentProvider( 9497 IApplicationThread caller, String name, int userId, boolean stable) { 9498 enforceNotIsolatedCaller("getContentProvider"); 9499 if (caller == null) { 9500 String msg = "null IApplicationThread when getting content provider " 9501 + name; 9502 Slog.w(TAG, msg); 9503 throw new SecurityException(msg); 9504 } 9505 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9506 // with cross-user grant. 9507 return getContentProviderImpl(caller, name, null, stable, userId); 9508 } 9509 9510 public ContentProviderHolder getContentProviderExternal( 9511 String name, int userId, IBinder token) { 9512 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9513 "Do not have permission in call getContentProviderExternal()"); 9514 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9515 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9516 return getContentProviderExternalUnchecked(name, token, userId); 9517 } 9518 9519 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9520 IBinder token, int userId) { 9521 return getContentProviderImpl(null, name, token, true, userId); 9522 } 9523 9524 /** 9525 * Drop a content provider from a ProcessRecord's bookkeeping 9526 */ 9527 public void removeContentProvider(IBinder connection, boolean stable) { 9528 enforceNotIsolatedCaller("removeContentProvider"); 9529 long ident = Binder.clearCallingIdentity(); 9530 try { 9531 synchronized (this) { 9532 ContentProviderConnection conn; 9533 try { 9534 conn = (ContentProviderConnection)connection; 9535 } catch (ClassCastException e) { 9536 String msg ="removeContentProvider: " + connection 9537 + " not a ContentProviderConnection"; 9538 Slog.w(TAG, msg); 9539 throw new IllegalArgumentException(msg); 9540 } 9541 if (conn == null) { 9542 throw new NullPointerException("connection is null"); 9543 } 9544 if (decProviderCountLocked(conn, null, null, stable)) { 9545 updateOomAdjLocked(); 9546 } 9547 } 9548 } finally { 9549 Binder.restoreCallingIdentity(ident); 9550 } 9551 } 9552 9553 public void removeContentProviderExternal(String name, IBinder token) { 9554 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9555 "Do not have permission in call removeContentProviderExternal()"); 9556 int userId = UserHandle.getCallingUserId(); 9557 long ident = Binder.clearCallingIdentity(); 9558 try { 9559 removeContentProviderExternalUnchecked(name, token, userId); 9560 } finally { 9561 Binder.restoreCallingIdentity(ident); 9562 } 9563 } 9564 9565 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9566 synchronized (this) { 9567 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9568 if(cpr == null) { 9569 //remove from mProvidersByClass 9570 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9571 return; 9572 } 9573 9574 //update content provider record entry info 9575 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9576 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9577 if (localCpr.hasExternalProcessHandles()) { 9578 if (localCpr.removeExternalProcessHandleLocked(token)) { 9579 updateOomAdjLocked(); 9580 } else { 9581 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9582 + " with no external reference for token: " 9583 + token + "."); 9584 } 9585 } else { 9586 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9587 + " with no external references."); 9588 } 9589 } 9590 } 9591 9592 public final void publishContentProviders(IApplicationThread caller, 9593 List<ContentProviderHolder> providers) { 9594 if (providers == null) { 9595 return; 9596 } 9597 9598 enforceNotIsolatedCaller("publishContentProviders"); 9599 synchronized (this) { 9600 final ProcessRecord r = getRecordForAppLocked(caller); 9601 if (DEBUG_MU) 9602 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9603 if (r == null) { 9604 throw new SecurityException( 9605 "Unable to find app for caller " + caller 9606 + " (pid=" + Binder.getCallingPid() 9607 + ") when publishing content providers"); 9608 } 9609 9610 final long origId = Binder.clearCallingIdentity(); 9611 9612 final int N = providers.size(); 9613 for (int i=0; i<N; i++) { 9614 ContentProviderHolder src = providers.get(i); 9615 if (src == null || src.info == null || src.provider == null) { 9616 continue; 9617 } 9618 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9619 if (DEBUG_MU) 9620 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9621 if (dst != null) { 9622 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9623 mProviderMap.putProviderByClass(comp, dst); 9624 String names[] = dst.info.authority.split(";"); 9625 for (int j = 0; j < names.length; j++) { 9626 mProviderMap.putProviderByName(names[j], dst); 9627 } 9628 9629 int NL = mLaunchingProviders.size(); 9630 int j; 9631 for (j=0; j<NL; j++) { 9632 if (mLaunchingProviders.get(j) == dst) { 9633 mLaunchingProviders.remove(j); 9634 j--; 9635 NL--; 9636 } 9637 } 9638 synchronized (dst) { 9639 dst.provider = src.provider; 9640 dst.proc = r; 9641 dst.notifyAll(); 9642 } 9643 updateOomAdjLocked(r); 9644 } 9645 } 9646 9647 Binder.restoreCallingIdentity(origId); 9648 } 9649 } 9650 9651 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9652 ContentProviderConnection conn; 9653 try { 9654 conn = (ContentProviderConnection)connection; 9655 } catch (ClassCastException e) { 9656 String msg ="refContentProvider: " + connection 9657 + " not a ContentProviderConnection"; 9658 Slog.w(TAG, msg); 9659 throw new IllegalArgumentException(msg); 9660 } 9661 if (conn == null) { 9662 throw new NullPointerException("connection is null"); 9663 } 9664 9665 synchronized (this) { 9666 if (stable > 0) { 9667 conn.numStableIncs += stable; 9668 } 9669 stable = conn.stableCount + stable; 9670 if (stable < 0) { 9671 throw new IllegalStateException("stableCount < 0: " + stable); 9672 } 9673 9674 if (unstable > 0) { 9675 conn.numUnstableIncs += unstable; 9676 } 9677 unstable = conn.unstableCount + unstable; 9678 if (unstable < 0) { 9679 throw new IllegalStateException("unstableCount < 0: " + unstable); 9680 } 9681 9682 if ((stable+unstable) <= 0) { 9683 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9684 + stable + " unstable=" + unstable); 9685 } 9686 conn.stableCount = stable; 9687 conn.unstableCount = unstable; 9688 return !conn.dead; 9689 } 9690 } 9691 9692 public void unstableProviderDied(IBinder connection) { 9693 ContentProviderConnection conn; 9694 try { 9695 conn = (ContentProviderConnection)connection; 9696 } catch (ClassCastException e) { 9697 String msg ="refContentProvider: " + connection 9698 + " not a ContentProviderConnection"; 9699 Slog.w(TAG, msg); 9700 throw new IllegalArgumentException(msg); 9701 } 9702 if (conn == null) { 9703 throw new NullPointerException("connection is null"); 9704 } 9705 9706 // Safely retrieve the content provider associated with the connection. 9707 IContentProvider provider; 9708 synchronized (this) { 9709 provider = conn.provider.provider; 9710 } 9711 9712 if (provider == null) { 9713 // Um, yeah, we're way ahead of you. 9714 return; 9715 } 9716 9717 // Make sure the caller is being honest with us. 9718 if (provider.asBinder().pingBinder()) { 9719 // Er, no, still looks good to us. 9720 synchronized (this) { 9721 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9722 + " says " + conn + " died, but we don't agree"); 9723 return; 9724 } 9725 } 9726 9727 // Well look at that! It's dead! 9728 synchronized (this) { 9729 if (conn.provider.provider != provider) { 9730 // But something changed... good enough. 9731 return; 9732 } 9733 9734 ProcessRecord proc = conn.provider.proc; 9735 if (proc == null || proc.thread == null) { 9736 // Seems like the process is already cleaned up. 9737 return; 9738 } 9739 9740 // As far as we're concerned, this is just like receiving a 9741 // death notification... just a bit prematurely. 9742 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9743 + ") early provider death"); 9744 final long ident = Binder.clearCallingIdentity(); 9745 try { 9746 appDiedLocked(proc); 9747 } finally { 9748 Binder.restoreCallingIdentity(ident); 9749 } 9750 } 9751 } 9752 9753 @Override 9754 public void appNotRespondingViaProvider(IBinder connection) { 9755 enforceCallingPermission( 9756 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9757 9758 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9759 if (conn == null) { 9760 Slog.w(TAG, "ContentProviderConnection is null"); 9761 return; 9762 } 9763 9764 final ProcessRecord host = conn.provider.proc; 9765 if (host == null) { 9766 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9767 return; 9768 } 9769 9770 final long token = Binder.clearCallingIdentity(); 9771 try { 9772 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9773 } finally { 9774 Binder.restoreCallingIdentity(token); 9775 } 9776 } 9777 9778 public final void installSystemProviders() { 9779 List<ProviderInfo> providers; 9780 synchronized (this) { 9781 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9782 providers = generateApplicationProvidersLocked(app); 9783 if (providers != null) { 9784 for (int i=providers.size()-1; i>=0; i--) { 9785 ProviderInfo pi = (ProviderInfo)providers.get(i); 9786 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9787 Slog.w(TAG, "Not installing system proc provider " + pi.name 9788 + ": not system .apk"); 9789 providers.remove(i); 9790 } 9791 } 9792 } 9793 } 9794 if (providers != null) { 9795 mSystemThread.installSystemProviders(providers); 9796 } 9797 9798 mCoreSettingsObserver = new CoreSettingsObserver(this); 9799 9800 //mUsageStatsService.monitorPackages(); 9801 } 9802 9803 /** 9804 * Allows apps to retrieve the MIME type of a URI. 9805 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9806 * users, then it does not need permission to access the ContentProvider. 9807 * Either, it needs cross-user uri grants. 9808 * 9809 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9810 * 9811 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9812 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9813 */ 9814 public String getProviderMimeType(Uri uri, int userId) { 9815 enforceNotIsolatedCaller("getProviderMimeType"); 9816 final String name = uri.getAuthority(); 9817 int callingUid = Binder.getCallingUid(); 9818 int callingPid = Binder.getCallingPid(); 9819 long ident = 0; 9820 boolean clearedIdentity = false; 9821 userId = unsafeConvertIncomingUser(userId); 9822 if (canClearIdentity(callingPid, callingUid, userId)) { 9823 clearedIdentity = true; 9824 ident = Binder.clearCallingIdentity(); 9825 } 9826 ContentProviderHolder holder = null; 9827 try { 9828 holder = getContentProviderExternalUnchecked(name, null, userId); 9829 if (holder != null) { 9830 return holder.provider.getType(uri); 9831 } 9832 } catch (RemoteException e) { 9833 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9834 return null; 9835 } finally { 9836 // We need to clear the identity to call removeContentProviderExternalUnchecked 9837 if (!clearedIdentity) { 9838 ident = Binder.clearCallingIdentity(); 9839 } 9840 try { 9841 if (holder != null) { 9842 removeContentProviderExternalUnchecked(name, null, userId); 9843 } 9844 } finally { 9845 Binder.restoreCallingIdentity(ident); 9846 } 9847 } 9848 9849 return null; 9850 } 9851 9852 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9853 if (UserHandle.getUserId(callingUid) == userId) { 9854 return true; 9855 } 9856 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9857 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9858 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9859 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9860 return true; 9861 } 9862 return false; 9863 } 9864 9865 // ========================================================= 9866 // GLOBAL MANAGEMENT 9867 // ========================================================= 9868 9869 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9870 boolean isolated, int isolatedUid) { 9871 String proc = customProcess != null ? customProcess : info.processName; 9872 BatteryStatsImpl.Uid.Proc ps = null; 9873 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9874 int uid = info.uid; 9875 if (isolated) { 9876 if (isolatedUid == 0) { 9877 int userId = UserHandle.getUserId(uid); 9878 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9879 while (true) { 9880 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9881 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9882 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9883 } 9884 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9885 mNextIsolatedProcessUid++; 9886 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9887 // No process for this uid, use it. 9888 break; 9889 } 9890 stepsLeft--; 9891 if (stepsLeft <= 0) { 9892 return null; 9893 } 9894 } 9895 } else { 9896 // Special case for startIsolatedProcess (internal only), where 9897 // the uid of the isolated process is specified by the caller. 9898 uid = isolatedUid; 9899 } 9900 } 9901 return new ProcessRecord(stats, info, proc, uid); 9902 } 9903 9904 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9905 String abiOverride) { 9906 ProcessRecord app; 9907 if (!isolated) { 9908 app = getProcessRecordLocked(info.processName, info.uid, true); 9909 } else { 9910 app = null; 9911 } 9912 9913 if (app == null) { 9914 app = newProcessRecordLocked(info, null, isolated, 0); 9915 mProcessNames.put(info.processName, app.uid, app); 9916 if (isolated) { 9917 mIsolatedProcesses.put(app.uid, app); 9918 } 9919 updateLruProcessLocked(app, false, null); 9920 updateOomAdjLocked(); 9921 } 9922 9923 // This package really, really can not be stopped. 9924 try { 9925 AppGlobals.getPackageManager().setPackageStoppedState( 9926 info.packageName, false, UserHandle.getUserId(app.uid)); 9927 } catch (RemoteException e) { 9928 } catch (IllegalArgumentException e) { 9929 Slog.w(TAG, "Failed trying to unstop package " 9930 + info.packageName + ": " + e); 9931 } 9932 9933 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9934 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9935 app.persistent = true; 9936 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9937 } 9938 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9939 mPersistentStartingProcesses.add(app); 9940 startProcessLocked(app, "added application", app.processName, abiOverride, 9941 null /* entryPoint */, null /* entryPointArgs */); 9942 } 9943 9944 return app; 9945 } 9946 9947 public void unhandledBack() { 9948 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9949 "unhandledBack()"); 9950 9951 synchronized(this) { 9952 final long origId = Binder.clearCallingIdentity(); 9953 try { 9954 getFocusedStack().unhandledBackLocked(); 9955 } finally { 9956 Binder.restoreCallingIdentity(origId); 9957 } 9958 } 9959 } 9960 9961 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9962 enforceNotIsolatedCaller("openContentUri"); 9963 final int userId = UserHandle.getCallingUserId(); 9964 String name = uri.getAuthority(); 9965 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9966 ParcelFileDescriptor pfd = null; 9967 if (cph != null) { 9968 // We record the binder invoker's uid in thread-local storage before 9969 // going to the content provider to open the file. Later, in the code 9970 // that handles all permissions checks, we look for this uid and use 9971 // that rather than the Activity Manager's own uid. The effect is that 9972 // we do the check against the caller's permissions even though it looks 9973 // to the content provider like the Activity Manager itself is making 9974 // the request. 9975 Binder token = new Binder(); 9976 sCallerIdentity.set(new Identity( 9977 token, Binder.getCallingPid(), Binder.getCallingUid())); 9978 try { 9979 pfd = cph.provider.openFile(null, uri, "r", null, token); 9980 } catch (FileNotFoundException e) { 9981 // do nothing; pfd will be returned null 9982 } finally { 9983 // Ensure that whatever happens, we clean up the identity state 9984 sCallerIdentity.remove(); 9985 } 9986 9987 // We've got the fd now, so we're done with the provider. 9988 removeContentProviderExternalUnchecked(name, null, userId); 9989 } else { 9990 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9991 } 9992 return pfd; 9993 } 9994 9995 // Actually is sleeping or shutting down or whatever else in the future 9996 // is an inactive state. 9997 public boolean isSleepingOrShuttingDown() { 9998 return isSleeping() || mShuttingDown; 9999 } 10000 10001 public boolean isSleeping() { 10002 return mSleeping; 10003 } 10004 10005 void onWakefulnessChanged(int wakefulness) { 10006 synchronized(this) { 10007 mWakefulness = wakefulness; 10008 updateSleepIfNeededLocked(); 10009 } 10010 } 10011 10012 void finishRunningVoiceLocked() { 10013 if (mRunningVoice) { 10014 mRunningVoice = false; 10015 updateSleepIfNeededLocked(); 10016 } 10017 } 10018 10019 void updateSleepIfNeededLocked() { 10020 if (mSleeping && !shouldSleepLocked()) { 10021 mSleeping = false; 10022 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10023 } else if (!mSleeping && shouldSleepLocked()) { 10024 mSleeping = true; 10025 mStackSupervisor.goingToSleepLocked(); 10026 10027 // Initialize the wake times of all processes. 10028 checkExcessivePowerUsageLocked(false); 10029 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10030 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10031 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10032 } 10033 } 10034 10035 private boolean shouldSleepLocked() { 10036 // Resume applications while running a voice interactor. 10037 if (mRunningVoice) { 10038 return false; 10039 } 10040 10041 switch (mWakefulness) { 10042 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10043 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10044 // If we're interactive but applications are already paused then defer 10045 // resuming them until the lock screen is hidden. 10046 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10047 case PowerManagerInternal.WAKEFULNESS_DOZING: 10048 // If we're dozing then pause applications whenever the lock screen is shown. 10049 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10050 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10051 default: 10052 // If we're asleep then pause applications unconditionally. 10053 return true; 10054 } 10055 } 10056 10057 /** Pokes the task persister. */ 10058 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10059 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10060 // Never persist the home stack. 10061 return; 10062 } 10063 mTaskPersister.wakeup(task, flush); 10064 } 10065 10066 /** Notifies all listeners when the task stack has changed. */ 10067 void notifyTaskStackChangedLocked() { 10068 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10069 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10070 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10071 } 10072 10073 @Override 10074 public boolean shutdown(int timeout) { 10075 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10076 != PackageManager.PERMISSION_GRANTED) { 10077 throw new SecurityException("Requires permission " 10078 + android.Manifest.permission.SHUTDOWN); 10079 } 10080 10081 boolean timedout = false; 10082 10083 synchronized(this) { 10084 mShuttingDown = true; 10085 updateEventDispatchingLocked(); 10086 timedout = mStackSupervisor.shutdownLocked(timeout); 10087 } 10088 10089 mAppOpsService.shutdown(); 10090 if (mUsageStatsService != null) { 10091 mUsageStatsService.prepareShutdown(); 10092 } 10093 mBatteryStatsService.shutdown(); 10094 synchronized (this) { 10095 mProcessStats.shutdownLocked(); 10096 notifyTaskPersisterLocked(null, true); 10097 } 10098 10099 return timedout; 10100 } 10101 10102 public final void activitySlept(IBinder token) { 10103 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10104 10105 final long origId = Binder.clearCallingIdentity(); 10106 10107 synchronized (this) { 10108 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10109 if (r != null) { 10110 mStackSupervisor.activitySleptLocked(r); 10111 } 10112 } 10113 10114 Binder.restoreCallingIdentity(origId); 10115 } 10116 10117 private String lockScreenShownToString() { 10118 switch (mLockScreenShown) { 10119 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10120 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10121 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10122 default: return "Unknown=" + mLockScreenShown; 10123 } 10124 } 10125 10126 void logLockScreen(String msg) { 10127 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10128 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10129 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10130 + " mSleeping=" + mSleeping); 10131 } 10132 10133 void startRunningVoiceLocked() { 10134 if (!mRunningVoice) { 10135 mRunningVoice = true; 10136 updateSleepIfNeededLocked(); 10137 } 10138 } 10139 10140 private void updateEventDispatchingLocked() { 10141 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10142 } 10143 10144 public void setLockScreenShown(boolean shown) { 10145 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10146 != PackageManager.PERMISSION_GRANTED) { 10147 throw new SecurityException("Requires permission " 10148 + android.Manifest.permission.DEVICE_POWER); 10149 } 10150 10151 synchronized(this) { 10152 long ident = Binder.clearCallingIdentity(); 10153 try { 10154 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10155 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10156 updateSleepIfNeededLocked(); 10157 } finally { 10158 Binder.restoreCallingIdentity(ident); 10159 } 10160 } 10161 } 10162 10163 @Override 10164 public void stopAppSwitches() { 10165 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10166 != PackageManager.PERMISSION_GRANTED) { 10167 throw new SecurityException("Requires permission " 10168 + android.Manifest.permission.STOP_APP_SWITCHES); 10169 } 10170 10171 synchronized(this) { 10172 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10173 + APP_SWITCH_DELAY_TIME; 10174 mDidAppSwitch = false; 10175 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10176 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10177 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10178 } 10179 } 10180 10181 public void resumeAppSwitches() { 10182 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10183 != PackageManager.PERMISSION_GRANTED) { 10184 throw new SecurityException("Requires permission " 10185 + android.Manifest.permission.STOP_APP_SWITCHES); 10186 } 10187 10188 synchronized(this) { 10189 // Note that we don't execute any pending app switches... we will 10190 // let those wait until either the timeout, or the next start 10191 // activity request. 10192 mAppSwitchesAllowedTime = 0; 10193 } 10194 } 10195 10196 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10197 int callingPid, int callingUid, String name) { 10198 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10199 return true; 10200 } 10201 10202 int perm = checkComponentPermission( 10203 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10204 sourceUid, -1, true); 10205 if (perm == PackageManager.PERMISSION_GRANTED) { 10206 return true; 10207 } 10208 10209 // If the actual IPC caller is different from the logical source, then 10210 // also see if they are allowed to control app switches. 10211 if (callingUid != -1 && callingUid != sourceUid) { 10212 perm = checkComponentPermission( 10213 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10214 callingUid, -1, true); 10215 if (perm == PackageManager.PERMISSION_GRANTED) { 10216 return true; 10217 } 10218 } 10219 10220 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10221 return false; 10222 } 10223 10224 public void setDebugApp(String packageName, boolean waitForDebugger, 10225 boolean persistent) { 10226 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10227 "setDebugApp()"); 10228 10229 long ident = Binder.clearCallingIdentity(); 10230 try { 10231 // Note that this is not really thread safe if there are multiple 10232 // callers into it at the same time, but that's not a situation we 10233 // care about. 10234 if (persistent) { 10235 final ContentResolver resolver = mContext.getContentResolver(); 10236 Settings.Global.putString( 10237 resolver, Settings.Global.DEBUG_APP, 10238 packageName); 10239 Settings.Global.putInt( 10240 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10241 waitForDebugger ? 1 : 0); 10242 } 10243 10244 synchronized (this) { 10245 if (!persistent) { 10246 mOrigDebugApp = mDebugApp; 10247 mOrigWaitForDebugger = mWaitForDebugger; 10248 } 10249 mDebugApp = packageName; 10250 mWaitForDebugger = waitForDebugger; 10251 mDebugTransient = !persistent; 10252 if (packageName != null) { 10253 forceStopPackageLocked(packageName, -1, false, false, true, true, 10254 false, UserHandle.USER_ALL, "set debug app"); 10255 } 10256 } 10257 } finally { 10258 Binder.restoreCallingIdentity(ident); 10259 } 10260 } 10261 10262 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10263 synchronized (this) { 10264 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10265 if (!isDebuggable) { 10266 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10267 throw new SecurityException("Process not debuggable: " + app.packageName); 10268 } 10269 } 10270 10271 mOpenGlTraceApp = processName; 10272 } 10273 } 10274 10275 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10276 synchronized (this) { 10277 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10278 if (!isDebuggable) { 10279 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10280 throw new SecurityException("Process not debuggable: " + app.packageName); 10281 } 10282 } 10283 mProfileApp = processName; 10284 mProfileFile = profilerInfo.profileFile; 10285 if (mProfileFd != null) { 10286 try { 10287 mProfileFd.close(); 10288 } catch (IOException e) { 10289 } 10290 mProfileFd = null; 10291 } 10292 mProfileFd = profilerInfo.profileFd; 10293 mSamplingInterval = profilerInfo.samplingInterval; 10294 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10295 mProfileType = 0; 10296 } 10297 } 10298 10299 @Override 10300 public void setAlwaysFinish(boolean enabled) { 10301 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10302 "setAlwaysFinish()"); 10303 10304 Settings.Global.putInt( 10305 mContext.getContentResolver(), 10306 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10307 10308 synchronized (this) { 10309 mAlwaysFinishActivities = enabled; 10310 } 10311 } 10312 10313 @Override 10314 public void setActivityController(IActivityController controller) { 10315 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10316 "setActivityController()"); 10317 synchronized (this) { 10318 mController = controller; 10319 Watchdog.getInstance().setActivityController(controller); 10320 } 10321 } 10322 10323 @Override 10324 public void setUserIsMonkey(boolean userIsMonkey) { 10325 synchronized (this) { 10326 synchronized (mPidsSelfLocked) { 10327 final int callingPid = Binder.getCallingPid(); 10328 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10329 if (precessRecord == null) { 10330 throw new SecurityException("Unknown process: " + callingPid); 10331 } 10332 if (precessRecord.instrumentationUiAutomationConnection == null) { 10333 throw new SecurityException("Only an instrumentation process " 10334 + "with a UiAutomation can call setUserIsMonkey"); 10335 } 10336 } 10337 mUserIsMonkey = userIsMonkey; 10338 } 10339 } 10340 10341 @Override 10342 public boolean isUserAMonkey() { 10343 synchronized (this) { 10344 // If there is a controller also implies the user is a monkey. 10345 return (mUserIsMonkey || mController != null); 10346 } 10347 } 10348 10349 public void requestBugReport() { 10350 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10351 SystemProperties.set("ctl.start", "bugreport"); 10352 } 10353 10354 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10355 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10356 } 10357 10358 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10359 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10360 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10361 } 10362 return KEY_DISPATCHING_TIMEOUT; 10363 } 10364 10365 @Override 10366 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10367 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10368 != PackageManager.PERMISSION_GRANTED) { 10369 throw new SecurityException("Requires permission " 10370 + android.Manifest.permission.FILTER_EVENTS); 10371 } 10372 ProcessRecord proc; 10373 long timeout; 10374 synchronized (this) { 10375 synchronized (mPidsSelfLocked) { 10376 proc = mPidsSelfLocked.get(pid); 10377 } 10378 timeout = getInputDispatchingTimeoutLocked(proc); 10379 } 10380 10381 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10382 return -1; 10383 } 10384 10385 return timeout; 10386 } 10387 10388 /** 10389 * Handle input dispatching timeouts. 10390 * Returns whether input dispatching should be aborted or not. 10391 */ 10392 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10393 final ActivityRecord activity, final ActivityRecord parent, 10394 final boolean aboveSystem, String reason) { 10395 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10396 != PackageManager.PERMISSION_GRANTED) { 10397 throw new SecurityException("Requires permission " 10398 + android.Manifest.permission.FILTER_EVENTS); 10399 } 10400 10401 final String annotation; 10402 if (reason == null) { 10403 annotation = "Input dispatching timed out"; 10404 } else { 10405 annotation = "Input dispatching timed out (" + reason + ")"; 10406 } 10407 10408 if (proc != null) { 10409 synchronized (this) { 10410 if (proc.debugging) { 10411 return false; 10412 } 10413 10414 if (mDidDexOpt) { 10415 // Give more time since we were dexopting. 10416 mDidDexOpt = false; 10417 return false; 10418 } 10419 10420 if (proc.instrumentationClass != null) { 10421 Bundle info = new Bundle(); 10422 info.putString("shortMsg", "keyDispatchingTimedOut"); 10423 info.putString("longMsg", annotation); 10424 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10425 return true; 10426 } 10427 } 10428 mHandler.post(new Runnable() { 10429 @Override 10430 public void run() { 10431 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10432 } 10433 }); 10434 } 10435 10436 return true; 10437 } 10438 10439 public Bundle getAssistContextExtras(int requestType) { 10440 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10441 UserHandle.getCallingUserId()); 10442 if (pae == null) { 10443 return null; 10444 } 10445 synchronized (pae) { 10446 while (!pae.haveResult) { 10447 try { 10448 pae.wait(); 10449 } catch (InterruptedException e) { 10450 } 10451 } 10452 if (pae.result != null) { 10453 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10454 } 10455 } 10456 synchronized (this) { 10457 mPendingAssistExtras.remove(pae); 10458 mHandler.removeCallbacks(pae); 10459 } 10460 return pae.extras; 10461 } 10462 10463 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10464 int userHandle) { 10465 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10466 "getAssistContextExtras()"); 10467 PendingAssistExtras pae; 10468 Bundle extras = new Bundle(); 10469 synchronized (this) { 10470 ActivityRecord activity = getFocusedStack().mResumedActivity; 10471 if (activity == null) { 10472 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10473 return null; 10474 } 10475 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10476 if (activity.app == null || activity.app.thread == null) { 10477 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10478 return null; 10479 } 10480 if (activity.app.pid == Binder.getCallingPid()) { 10481 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10482 return null; 10483 } 10484 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10485 try { 10486 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10487 requestType); 10488 mPendingAssistExtras.add(pae); 10489 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10490 } catch (RemoteException e) { 10491 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10492 return null; 10493 } 10494 return pae; 10495 } 10496 } 10497 10498 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10499 PendingAssistExtras pae = (PendingAssistExtras)token; 10500 synchronized (pae) { 10501 pae.result = extras; 10502 pae.haveResult = true; 10503 pae.notifyAll(); 10504 if (pae.intent == null) { 10505 // Caller is just waiting for the result. 10506 return; 10507 } 10508 } 10509 10510 // We are now ready to launch the assist activity. 10511 synchronized (this) { 10512 boolean exists = mPendingAssistExtras.remove(pae); 10513 mHandler.removeCallbacks(pae); 10514 if (!exists) { 10515 // Timed out. 10516 return; 10517 } 10518 } 10519 pae.intent.replaceExtras(extras); 10520 if (pae.hint != null) { 10521 pae.intent.putExtra(pae.hint, true); 10522 } 10523 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10524 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10525 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10526 closeSystemDialogs("assist"); 10527 try { 10528 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10529 } catch (ActivityNotFoundException e) { 10530 Slog.w(TAG, "No activity to handle assist action.", e); 10531 } 10532 } 10533 10534 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10535 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10536 } 10537 10538 public void registerProcessObserver(IProcessObserver observer) { 10539 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10540 "registerProcessObserver()"); 10541 synchronized (this) { 10542 mProcessObservers.register(observer); 10543 } 10544 } 10545 10546 @Override 10547 public void unregisterProcessObserver(IProcessObserver observer) { 10548 synchronized (this) { 10549 mProcessObservers.unregister(observer); 10550 } 10551 } 10552 10553 @Override 10554 public boolean convertFromTranslucent(IBinder token) { 10555 final long origId = Binder.clearCallingIdentity(); 10556 try { 10557 synchronized (this) { 10558 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10559 if (r == null) { 10560 return false; 10561 } 10562 final boolean translucentChanged = r.changeWindowTranslucency(true); 10563 if (translucentChanged) { 10564 r.task.stack.releaseBackgroundResources(); 10565 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10566 } 10567 mWindowManager.setAppFullscreen(token, true); 10568 return translucentChanged; 10569 } 10570 } finally { 10571 Binder.restoreCallingIdentity(origId); 10572 } 10573 } 10574 10575 @Override 10576 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10577 final long origId = Binder.clearCallingIdentity(); 10578 try { 10579 synchronized (this) { 10580 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10581 if (r == null) { 10582 return false; 10583 } 10584 int index = r.task.mActivities.lastIndexOf(r); 10585 if (index > 0) { 10586 ActivityRecord under = r.task.mActivities.get(index - 1); 10587 under.returningOptions = options; 10588 } 10589 final boolean translucentChanged = r.changeWindowTranslucency(false); 10590 if (translucentChanged) { 10591 r.task.stack.convertToTranslucent(r); 10592 } 10593 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10594 mWindowManager.setAppFullscreen(token, false); 10595 return translucentChanged; 10596 } 10597 } finally { 10598 Binder.restoreCallingIdentity(origId); 10599 } 10600 } 10601 10602 @Override 10603 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10604 final long origId = Binder.clearCallingIdentity(); 10605 try { 10606 synchronized (this) { 10607 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10608 if (r != null) { 10609 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10610 } 10611 } 10612 return false; 10613 } finally { 10614 Binder.restoreCallingIdentity(origId); 10615 } 10616 } 10617 10618 @Override 10619 public boolean isBackgroundVisibleBehind(IBinder token) { 10620 final long origId = Binder.clearCallingIdentity(); 10621 try { 10622 synchronized (this) { 10623 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10624 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10625 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10626 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10627 return visible; 10628 } 10629 } finally { 10630 Binder.restoreCallingIdentity(origId); 10631 } 10632 } 10633 10634 @Override 10635 public ActivityOptions getActivityOptions(IBinder token) { 10636 final long origId = Binder.clearCallingIdentity(); 10637 try { 10638 synchronized (this) { 10639 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10640 if (r != null) { 10641 final ActivityOptions activityOptions = r.pendingOptions; 10642 r.pendingOptions = null; 10643 return activityOptions; 10644 } 10645 return null; 10646 } 10647 } finally { 10648 Binder.restoreCallingIdentity(origId); 10649 } 10650 } 10651 10652 @Override 10653 public void setImmersive(IBinder token, boolean immersive) { 10654 synchronized(this) { 10655 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10656 if (r == null) { 10657 throw new IllegalArgumentException(); 10658 } 10659 r.immersive = immersive; 10660 10661 // update associated state if we're frontmost 10662 if (r == mFocusedActivity) { 10663 if (DEBUG_IMMERSIVE) { 10664 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10665 } 10666 applyUpdateLockStateLocked(r); 10667 } 10668 } 10669 } 10670 10671 @Override 10672 public boolean isImmersive(IBinder token) { 10673 synchronized (this) { 10674 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10675 if (r == null) { 10676 throw new IllegalArgumentException(); 10677 } 10678 return r.immersive; 10679 } 10680 } 10681 10682 public boolean isTopActivityImmersive() { 10683 enforceNotIsolatedCaller("startActivity"); 10684 synchronized (this) { 10685 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10686 return (r != null) ? r.immersive : false; 10687 } 10688 } 10689 10690 @Override 10691 public boolean isTopOfTask(IBinder token) { 10692 synchronized (this) { 10693 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10694 if (r == null) { 10695 throw new IllegalArgumentException(); 10696 } 10697 return r.task.getTopActivity() == r; 10698 } 10699 } 10700 10701 public final void enterSafeMode() { 10702 synchronized(this) { 10703 // It only makes sense to do this before the system is ready 10704 // and started launching other packages. 10705 if (!mSystemReady) { 10706 try { 10707 AppGlobals.getPackageManager().enterSafeMode(); 10708 } catch (RemoteException e) { 10709 } 10710 } 10711 10712 mSafeMode = true; 10713 } 10714 } 10715 10716 public final void showSafeModeOverlay() { 10717 View v = LayoutInflater.from(mContext).inflate( 10718 com.android.internal.R.layout.safe_mode, null); 10719 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10720 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10721 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10722 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10723 lp.gravity = Gravity.BOTTOM | Gravity.START; 10724 lp.format = v.getBackground().getOpacity(); 10725 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10726 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10727 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10728 ((WindowManager)mContext.getSystemService( 10729 Context.WINDOW_SERVICE)).addView(v, lp); 10730 } 10731 10732 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10733 if (!(sender instanceof PendingIntentRecord)) { 10734 return; 10735 } 10736 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10737 synchronized (stats) { 10738 if (mBatteryStatsService.isOnBattery()) { 10739 mBatteryStatsService.enforceCallingPermission(); 10740 PendingIntentRecord rec = (PendingIntentRecord)sender; 10741 int MY_UID = Binder.getCallingUid(); 10742 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10743 BatteryStatsImpl.Uid.Pkg pkg = 10744 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10745 sourcePkg != null ? sourcePkg : rec.key.packageName); 10746 pkg.incWakeupsLocked(); 10747 } 10748 } 10749 } 10750 10751 public boolean killPids(int[] pids, String pReason, boolean secure) { 10752 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10753 throw new SecurityException("killPids only available to the system"); 10754 } 10755 String reason = (pReason == null) ? "Unknown" : pReason; 10756 // XXX Note: don't acquire main activity lock here, because the window 10757 // manager calls in with its locks held. 10758 10759 boolean killed = false; 10760 synchronized (mPidsSelfLocked) { 10761 int[] types = new int[pids.length]; 10762 int worstType = 0; 10763 for (int i=0; i<pids.length; i++) { 10764 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10765 if (proc != null) { 10766 int type = proc.setAdj; 10767 types[i] = type; 10768 if (type > worstType) { 10769 worstType = type; 10770 } 10771 } 10772 } 10773 10774 // If the worst oom_adj is somewhere in the cached proc LRU range, 10775 // then constrain it so we will kill all cached procs. 10776 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10777 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10778 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10779 } 10780 10781 // If this is not a secure call, don't let it kill processes that 10782 // are important. 10783 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10784 worstType = ProcessList.SERVICE_ADJ; 10785 } 10786 10787 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10788 for (int i=0; i<pids.length; i++) { 10789 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10790 if (proc == null) { 10791 continue; 10792 } 10793 int adj = proc.setAdj; 10794 if (adj >= worstType && !proc.killedByAm) { 10795 proc.kill(reason, true); 10796 killed = true; 10797 } 10798 } 10799 } 10800 return killed; 10801 } 10802 10803 @Override 10804 public void killUid(int uid, String reason) { 10805 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10806 throw new SecurityException("killUid only available to the system"); 10807 } 10808 synchronized (this) { 10809 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10810 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10811 reason != null ? reason : "kill uid"); 10812 } 10813 } 10814 10815 @Override 10816 public boolean killProcessesBelowForeground(String reason) { 10817 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10818 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10819 } 10820 10821 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10822 } 10823 10824 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10825 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10826 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10827 } 10828 10829 boolean killed = false; 10830 synchronized (mPidsSelfLocked) { 10831 final int size = mPidsSelfLocked.size(); 10832 for (int i = 0; i < size; i++) { 10833 final int pid = mPidsSelfLocked.keyAt(i); 10834 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10835 if (proc == null) continue; 10836 10837 final int adj = proc.setAdj; 10838 if (adj > belowAdj && !proc.killedByAm) { 10839 proc.kill(reason, true); 10840 killed = true; 10841 } 10842 } 10843 } 10844 return killed; 10845 } 10846 10847 @Override 10848 public void hang(final IBinder who, boolean allowRestart) { 10849 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10850 != PackageManager.PERMISSION_GRANTED) { 10851 throw new SecurityException("Requires permission " 10852 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10853 } 10854 10855 final IBinder.DeathRecipient death = new DeathRecipient() { 10856 @Override 10857 public void binderDied() { 10858 synchronized (this) { 10859 notifyAll(); 10860 } 10861 } 10862 }; 10863 10864 try { 10865 who.linkToDeath(death, 0); 10866 } catch (RemoteException e) { 10867 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10868 return; 10869 } 10870 10871 synchronized (this) { 10872 Watchdog.getInstance().setAllowRestart(allowRestart); 10873 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10874 synchronized (death) { 10875 while (who.isBinderAlive()) { 10876 try { 10877 death.wait(); 10878 } catch (InterruptedException e) { 10879 } 10880 } 10881 } 10882 Watchdog.getInstance().setAllowRestart(true); 10883 } 10884 } 10885 10886 @Override 10887 public void restart() { 10888 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10889 != PackageManager.PERMISSION_GRANTED) { 10890 throw new SecurityException("Requires permission " 10891 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10892 } 10893 10894 Log.i(TAG, "Sending shutdown broadcast..."); 10895 10896 BroadcastReceiver br = new BroadcastReceiver() { 10897 @Override public void onReceive(Context context, Intent intent) { 10898 // Now the broadcast is done, finish up the low-level shutdown. 10899 Log.i(TAG, "Shutting down activity manager..."); 10900 shutdown(10000); 10901 Log.i(TAG, "Shutdown complete, restarting!"); 10902 Process.killProcess(Process.myPid()); 10903 System.exit(10); 10904 } 10905 }; 10906 10907 // First send the high-level shut down broadcast. 10908 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10909 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10910 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10911 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10912 mContext.sendOrderedBroadcastAsUser(intent, 10913 UserHandle.ALL, null, br, mHandler, 0, null, null); 10914 */ 10915 br.onReceive(mContext, intent); 10916 } 10917 10918 private long getLowRamTimeSinceIdle(long now) { 10919 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10920 } 10921 10922 @Override 10923 public void performIdleMaintenance() { 10924 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10925 != PackageManager.PERMISSION_GRANTED) { 10926 throw new SecurityException("Requires permission " 10927 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10928 } 10929 10930 synchronized (this) { 10931 final long now = SystemClock.uptimeMillis(); 10932 final long timeSinceLastIdle = now - mLastIdleTime; 10933 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10934 mLastIdleTime = now; 10935 mLowRamTimeSinceLastIdle = 0; 10936 if (mLowRamStartTime != 0) { 10937 mLowRamStartTime = now; 10938 } 10939 10940 StringBuilder sb = new StringBuilder(128); 10941 sb.append("Idle maintenance over "); 10942 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10943 sb.append(" low RAM for "); 10944 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10945 Slog.i(TAG, sb.toString()); 10946 10947 // If at least 1/3 of our time since the last idle period has been spent 10948 // with RAM low, then we want to kill processes. 10949 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10950 10951 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10952 ProcessRecord proc = mLruProcesses.get(i); 10953 if (proc.notCachedSinceIdle) { 10954 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10955 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10956 if (doKilling && proc.initialIdlePss != 0 10957 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10958 sb = new StringBuilder(128); 10959 sb.append("Kill"); 10960 sb.append(proc.processName); 10961 sb.append(" in idle maint: pss="); 10962 sb.append(proc.lastPss); 10963 sb.append(", initialPss="); 10964 sb.append(proc.initialIdlePss); 10965 sb.append(", period="); 10966 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10967 sb.append(", lowRamPeriod="); 10968 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10969 Slog.wtfQuiet(TAG, sb.toString()); 10970 proc.kill("idle maint (pss " + proc.lastPss 10971 + " from " + proc.initialIdlePss + ")", true); 10972 } 10973 } 10974 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10975 proc.notCachedSinceIdle = true; 10976 proc.initialIdlePss = 0; 10977 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10978 mTestPssMode, isSleeping(), now); 10979 } 10980 } 10981 10982 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10983 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10984 } 10985 } 10986 10987 private void retrieveSettings() { 10988 final ContentResolver resolver = mContext.getContentResolver(); 10989 String debugApp = Settings.Global.getString( 10990 resolver, Settings.Global.DEBUG_APP); 10991 boolean waitForDebugger = Settings.Global.getInt( 10992 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10993 boolean alwaysFinishActivities = Settings.Global.getInt( 10994 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10995 boolean forceRtl = Settings.Global.getInt( 10996 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10997 // Transfer any global setting for forcing RTL layout, into a System Property 10998 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10999 11000 Configuration configuration = new Configuration(); 11001 Settings.System.getConfiguration(resolver, configuration); 11002 if (forceRtl) { 11003 // This will take care of setting the correct layout direction flags 11004 configuration.setLayoutDirection(configuration.locale); 11005 } 11006 11007 synchronized (this) { 11008 mDebugApp = mOrigDebugApp = debugApp; 11009 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11010 mAlwaysFinishActivities = alwaysFinishActivities; 11011 // This happens before any activities are started, so we can 11012 // change mConfiguration in-place. 11013 updateConfigurationLocked(configuration, null, false, true); 11014 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11015 } 11016 } 11017 11018 /** Loads resources after the current configuration has been set. */ 11019 private void loadResourcesOnSystemReady() { 11020 final Resources res = mContext.getResources(); 11021 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11022 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11023 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11024 } 11025 11026 public boolean testIsSystemReady() { 11027 // no need to synchronize(this) just to read & return the value 11028 return mSystemReady; 11029 } 11030 11031 private static File getCalledPreBootReceiversFile() { 11032 File dataDir = Environment.getDataDirectory(); 11033 File systemDir = new File(dataDir, "system"); 11034 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11035 return fname; 11036 } 11037 11038 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11039 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11040 File file = getCalledPreBootReceiversFile(); 11041 FileInputStream fis = null; 11042 try { 11043 fis = new FileInputStream(file); 11044 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11045 int fvers = dis.readInt(); 11046 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11047 String vers = dis.readUTF(); 11048 String codename = dis.readUTF(); 11049 String build = dis.readUTF(); 11050 if (android.os.Build.VERSION.RELEASE.equals(vers) 11051 && android.os.Build.VERSION.CODENAME.equals(codename) 11052 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11053 int num = dis.readInt(); 11054 while (num > 0) { 11055 num--; 11056 String pkg = dis.readUTF(); 11057 String cls = dis.readUTF(); 11058 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11059 } 11060 } 11061 } 11062 } catch (FileNotFoundException e) { 11063 } catch (IOException e) { 11064 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11065 } finally { 11066 if (fis != null) { 11067 try { 11068 fis.close(); 11069 } catch (IOException e) { 11070 } 11071 } 11072 } 11073 return lastDoneReceivers; 11074 } 11075 11076 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11077 File file = getCalledPreBootReceiversFile(); 11078 FileOutputStream fos = null; 11079 DataOutputStream dos = null; 11080 try { 11081 fos = new FileOutputStream(file); 11082 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11083 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11084 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11085 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11086 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11087 dos.writeInt(list.size()); 11088 for (int i=0; i<list.size(); i++) { 11089 dos.writeUTF(list.get(i).getPackageName()); 11090 dos.writeUTF(list.get(i).getClassName()); 11091 } 11092 } catch (IOException e) { 11093 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11094 file.delete(); 11095 } finally { 11096 FileUtils.sync(fos); 11097 if (dos != null) { 11098 try { 11099 dos.close(); 11100 } catch (IOException e) { 11101 // TODO Auto-generated catch block 11102 e.printStackTrace(); 11103 } 11104 } 11105 } 11106 } 11107 11108 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11109 ArrayList<ComponentName> doneReceivers, int userId) { 11110 boolean waitingUpdate = false; 11111 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11112 List<ResolveInfo> ris = null; 11113 try { 11114 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11115 intent, null, 0, userId); 11116 } catch (RemoteException e) { 11117 } 11118 if (ris != null) { 11119 for (int i=ris.size()-1; i>=0; i--) { 11120 if ((ris.get(i).activityInfo.applicationInfo.flags 11121 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11122 ris.remove(i); 11123 } 11124 } 11125 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11126 11127 // For User 0, load the version number. When delivering to a new user, deliver 11128 // to all receivers. 11129 if (userId == UserHandle.USER_OWNER) { 11130 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11131 for (int i=0; i<ris.size(); i++) { 11132 ActivityInfo ai = ris.get(i).activityInfo; 11133 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11134 if (lastDoneReceivers.contains(comp)) { 11135 // We already did the pre boot receiver for this app with the current 11136 // platform version, so don't do it again... 11137 ris.remove(i); 11138 i--; 11139 // ...however, do keep it as one that has been done, so we don't 11140 // forget about it when rewriting the file of last done receivers. 11141 doneReceivers.add(comp); 11142 } 11143 } 11144 } 11145 11146 // If primary user, send broadcast to all available users, else just to userId 11147 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11148 : new int[] { userId }; 11149 for (int i = 0; i < ris.size(); i++) { 11150 ActivityInfo ai = ris.get(i).activityInfo; 11151 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11152 doneReceivers.add(comp); 11153 intent.setComponent(comp); 11154 for (int j=0; j<users.length; j++) { 11155 IIntentReceiver finisher = null; 11156 // On last receiver and user, set up a completion callback 11157 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11158 finisher = new IIntentReceiver.Stub() { 11159 public void performReceive(Intent intent, int resultCode, 11160 String data, Bundle extras, boolean ordered, 11161 boolean sticky, int sendingUser) { 11162 // The raw IIntentReceiver interface is called 11163 // with the AM lock held, so redispatch to 11164 // execute our code without the lock. 11165 mHandler.post(onFinishCallback); 11166 } 11167 }; 11168 } 11169 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11170 + " for user " + users[j]); 11171 broadcastIntentLocked(null, null, intent, null, finisher, 11172 0, null, null, null, AppOpsManager.OP_NONE, 11173 true, false, MY_PID, Process.SYSTEM_UID, 11174 users[j]); 11175 if (finisher != null) { 11176 waitingUpdate = true; 11177 } 11178 } 11179 } 11180 } 11181 11182 return waitingUpdate; 11183 } 11184 11185 public void systemReady(final Runnable goingCallback) { 11186 synchronized(this) { 11187 if (mSystemReady) { 11188 // If we're done calling all the receivers, run the next "boot phase" passed in 11189 // by the SystemServer 11190 if (goingCallback != null) { 11191 goingCallback.run(); 11192 } 11193 return; 11194 } 11195 11196 // Make sure we have the current profile info, since it is needed for 11197 // security checks. 11198 updateCurrentProfileIdsLocked(); 11199 11200 if (mRecentTasks == null) { 11201 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11202 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11203 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11204 mTaskPersister.startPersisting(); 11205 } 11206 11207 // Check to see if there are any update receivers to run. 11208 if (!mDidUpdate) { 11209 if (mWaitingUpdate) { 11210 return; 11211 } 11212 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11213 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11214 public void run() { 11215 synchronized (ActivityManagerService.this) { 11216 mDidUpdate = true; 11217 } 11218 writeLastDonePreBootReceivers(doneReceivers); 11219 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11220 false); 11221 systemReady(goingCallback); 11222 } 11223 }, doneReceivers, UserHandle.USER_OWNER); 11224 11225 if (mWaitingUpdate) { 11226 return; 11227 } 11228 mDidUpdate = true; 11229 } 11230 11231 mAppOpsService.systemReady(); 11232 mSystemReady = true; 11233 } 11234 11235 ArrayList<ProcessRecord> procsToKill = null; 11236 synchronized(mPidsSelfLocked) { 11237 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11238 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11239 if (!isAllowedWhileBooting(proc.info)){ 11240 if (procsToKill == null) { 11241 procsToKill = new ArrayList<ProcessRecord>(); 11242 } 11243 procsToKill.add(proc); 11244 } 11245 } 11246 } 11247 11248 synchronized(this) { 11249 if (procsToKill != null) { 11250 for (int i=procsToKill.size()-1; i>=0; i--) { 11251 ProcessRecord proc = procsToKill.get(i); 11252 Slog.i(TAG, "Removing system update proc: " + proc); 11253 removeProcessLocked(proc, true, false, "system update done"); 11254 } 11255 } 11256 11257 // Now that we have cleaned up any update processes, we 11258 // are ready to start launching real processes and know that 11259 // we won't trample on them any more. 11260 mProcessesReady = true; 11261 } 11262 11263 Slog.i(TAG, "System now ready"); 11264 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11265 SystemClock.uptimeMillis()); 11266 11267 synchronized(this) { 11268 // Make sure we have no pre-ready processes sitting around. 11269 11270 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11271 ResolveInfo ri = mContext.getPackageManager() 11272 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11273 STOCK_PM_FLAGS); 11274 CharSequence errorMsg = null; 11275 if (ri != null) { 11276 ActivityInfo ai = ri.activityInfo; 11277 ApplicationInfo app = ai.applicationInfo; 11278 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11279 mTopAction = Intent.ACTION_FACTORY_TEST; 11280 mTopData = null; 11281 mTopComponent = new ComponentName(app.packageName, 11282 ai.name); 11283 } else { 11284 errorMsg = mContext.getResources().getText( 11285 com.android.internal.R.string.factorytest_not_system); 11286 } 11287 } else { 11288 errorMsg = mContext.getResources().getText( 11289 com.android.internal.R.string.factorytest_no_action); 11290 } 11291 if (errorMsg != null) { 11292 mTopAction = null; 11293 mTopData = null; 11294 mTopComponent = null; 11295 Message msg = Message.obtain(); 11296 msg.what = SHOW_FACTORY_ERROR_MSG; 11297 msg.getData().putCharSequence("msg", errorMsg); 11298 mHandler.sendMessage(msg); 11299 } 11300 } 11301 } 11302 11303 retrieveSettings(); 11304 loadResourcesOnSystemReady(); 11305 11306 synchronized (this) { 11307 readGrantedUriPermissionsLocked(); 11308 } 11309 11310 if (goingCallback != null) goingCallback.run(); 11311 11312 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11313 Integer.toString(mCurrentUserId), mCurrentUserId); 11314 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11315 Integer.toString(mCurrentUserId), mCurrentUserId); 11316 mSystemServiceManager.startUser(mCurrentUserId); 11317 11318 synchronized (this) { 11319 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11320 try { 11321 List apps = AppGlobals.getPackageManager(). 11322 getPersistentApplications(STOCK_PM_FLAGS); 11323 if (apps != null) { 11324 int N = apps.size(); 11325 int i; 11326 for (i=0; i<N; i++) { 11327 ApplicationInfo info 11328 = (ApplicationInfo)apps.get(i); 11329 if (info != null && 11330 !info.packageName.equals("android")) { 11331 addAppLocked(info, false, null /* ABI override */); 11332 } 11333 } 11334 } 11335 } catch (RemoteException ex) { 11336 // pm is in same process, this will never happen. 11337 } 11338 } 11339 11340 // Start up initial activity. 11341 mBooting = true; 11342 startHomeActivityLocked(mCurrentUserId, "systemReady"); 11343 11344 try { 11345 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11346 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11347 + " data partition or your device will be unstable."); 11348 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11349 } 11350 } catch (RemoteException e) { 11351 } 11352 11353 if (!Build.isFingerprintConsistent()) { 11354 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11355 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11356 } 11357 11358 long ident = Binder.clearCallingIdentity(); 11359 try { 11360 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11361 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11362 | Intent.FLAG_RECEIVER_FOREGROUND); 11363 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11364 broadcastIntentLocked(null, null, intent, 11365 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11366 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11367 intent = new Intent(Intent.ACTION_USER_STARTING); 11368 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11369 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11370 broadcastIntentLocked(null, null, intent, 11371 null, new IIntentReceiver.Stub() { 11372 @Override 11373 public void performReceive(Intent intent, int resultCode, String data, 11374 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11375 throws RemoteException { 11376 } 11377 }, 0, null, null, 11378 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11379 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11380 } catch (Throwable t) { 11381 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11382 } finally { 11383 Binder.restoreCallingIdentity(ident); 11384 } 11385 mStackSupervisor.resumeTopActivitiesLocked(); 11386 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11387 } 11388 } 11389 11390 private boolean makeAppCrashingLocked(ProcessRecord app, 11391 String shortMsg, String longMsg, String stackTrace) { 11392 app.crashing = true; 11393 app.crashingReport = generateProcessError(app, 11394 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11395 startAppProblemLocked(app); 11396 app.stopFreezingAllLocked(); 11397 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11398 } 11399 11400 private void makeAppNotRespondingLocked(ProcessRecord app, 11401 String activity, String shortMsg, String longMsg) { 11402 app.notResponding = true; 11403 app.notRespondingReport = generateProcessError(app, 11404 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11405 activity, shortMsg, longMsg, null); 11406 startAppProblemLocked(app); 11407 app.stopFreezingAllLocked(); 11408 } 11409 11410 /** 11411 * Generate a process error record, suitable for attachment to a ProcessRecord. 11412 * 11413 * @param app The ProcessRecord in which the error occurred. 11414 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11415 * ActivityManager.AppErrorStateInfo 11416 * @param activity The activity associated with the crash, if known. 11417 * @param shortMsg Short message describing the crash. 11418 * @param longMsg Long message describing the crash. 11419 * @param stackTrace Full crash stack trace, may be null. 11420 * 11421 * @return Returns a fully-formed AppErrorStateInfo record. 11422 */ 11423 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11424 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11425 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11426 11427 report.condition = condition; 11428 report.processName = app.processName; 11429 report.pid = app.pid; 11430 report.uid = app.info.uid; 11431 report.tag = activity; 11432 report.shortMsg = shortMsg; 11433 report.longMsg = longMsg; 11434 report.stackTrace = stackTrace; 11435 11436 return report; 11437 } 11438 11439 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11440 synchronized (this) { 11441 app.crashing = false; 11442 app.crashingReport = null; 11443 app.notResponding = false; 11444 app.notRespondingReport = null; 11445 if (app.anrDialog == fromDialog) { 11446 app.anrDialog = null; 11447 } 11448 if (app.waitDialog == fromDialog) { 11449 app.waitDialog = null; 11450 } 11451 if (app.pid > 0 && app.pid != MY_PID) { 11452 handleAppCrashLocked(app, null, null, null); 11453 app.kill("user request after error", true); 11454 } 11455 } 11456 } 11457 11458 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11459 String stackTrace) { 11460 long now = SystemClock.uptimeMillis(); 11461 11462 Long crashTime; 11463 if (!app.isolated) { 11464 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11465 } else { 11466 crashTime = null; 11467 } 11468 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11469 // This process loses! 11470 Slog.w(TAG, "Process " + app.info.processName 11471 + " has crashed too many times: killing!"); 11472 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11473 app.userId, app.info.processName, app.uid); 11474 mStackSupervisor.handleAppCrashLocked(app); 11475 if (!app.persistent) { 11476 // We don't want to start this process again until the user 11477 // explicitly does so... but for persistent process, we really 11478 // need to keep it running. If a persistent process is actually 11479 // repeatedly crashing, then badness for everyone. 11480 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11481 app.info.processName); 11482 if (!app.isolated) { 11483 // XXX We don't have a way to mark isolated processes 11484 // as bad, since they don't have a peristent identity. 11485 mBadProcesses.put(app.info.processName, app.uid, 11486 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11487 mProcessCrashTimes.remove(app.info.processName, app.uid); 11488 } 11489 app.bad = true; 11490 app.removed = true; 11491 // Don't let services in this process be restarted and potentially 11492 // annoy the user repeatedly. Unless it is persistent, since those 11493 // processes run critical code. 11494 removeProcessLocked(app, false, false, "crash"); 11495 mStackSupervisor.resumeTopActivitiesLocked(); 11496 return false; 11497 } 11498 mStackSupervisor.resumeTopActivitiesLocked(); 11499 } else { 11500 mStackSupervisor.finishTopRunningActivityLocked(app); 11501 } 11502 11503 // Bump up the crash count of any services currently running in the proc. 11504 for (int i=app.services.size()-1; i>=0; i--) { 11505 // Any services running in the application need to be placed 11506 // back in the pending list. 11507 ServiceRecord sr = app.services.valueAt(i); 11508 sr.crashCount++; 11509 } 11510 11511 // If the crashing process is what we consider to be the "home process" and it has been 11512 // replaced by a third-party app, clear the package preferred activities from packages 11513 // with a home activity running in the process to prevent a repeatedly crashing app 11514 // from blocking the user to manually clear the list. 11515 final ArrayList<ActivityRecord> activities = app.activities; 11516 if (app == mHomeProcess && activities.size() > 0 11517 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11518 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11519 final ActivityRecord r = activities.get(activityNdx); 11520 if (r.isHomeActivity()) { 11521 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11522 try { 11523 ActivityThread.getPackageManager() 11524 .clearPackagePreferredActivities(r.packageName); 11525 } catch (RemoteException c) { 11526 // pm is in same process, this will never happen. 11527 } 11528 } 11529 } 11530 } 11531 11532 if (!app.isolated) { 11533 // XXX Can't keep track of crash times for isolated processes, 11534 // because they don't have a perisistent identity. 11535 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11536 } 11537 11538 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11539 return true; 11540 } 11541 11542 void startAppProblemLocked(ProcessRecord app) { 11543 // If this app is not running under the current user, then we 11544 // can't give it a report button because that would require 11545 // launching the report UI under a different user. 11546 app.errorReportReceiver = null; 11547 11548 for (int userId : mCurrentProfileIds) { 11549 if (app.userId == userId) { 11550 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11551 mContext, app.info.packageName, app.info.flags); 11552 } 11553 } 11554 skipCurrentReceiverLocked(app); 11555 } 11556 11557 void skipCurrentReceiverLocked(ProcessRecord app) { 11558 for (BroadcastQueue queue : mBroadcastQueues) { 11559 queue.skipCurrentReceiverLocked(app); 11560 } 11561 } 11562 11563 /** 11564 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11565 * The application process will exit immediately after this call returns. 11566 * @param app object of the crashing app, null for the system server 11567 * @param crashInfo describing the exception 11568 */ 11569 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11570 ProcessRecord r = findAppProcess(app, "Crash"); 11571 final String processName = app == null ? "system_server" 11572 : (r == null ? "unknown" : r.processName); 11573 11574 handleApplicationCrashInner("crash", r, processName, crashInfo); 11575 } 11576 11577 /* Native crash reporting uses this inner version because it needs to be somewhat 11578 * decoupled from the AM-managed cleanup lifecycle 11579 */ 11580 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11581 ApplicationErrorReport.CrashInfo crashInfo) { 11582 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11583 UserHandle.getUserId(Binder.getCallingUid()), processName, 11584 r == null ? -1 : r.info.flags, 11585 crashInfo.exceptionClassName, 11586 crashInfo.exceptionMessage, 11587 crashInfo.throwFileName, 11588 crashInfo.throwLineNumber); 11589 11590 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11591 11592 crashApplication(r, crashInfo); 11593 } 11594 11595 public void handleApplicationStrictModeViolation( 11596 IBinder app, 11597 int violationMask, 11598 StrictMode.ViolationInfo info) { 11599 ProcessRecord r = findAppProcess(app, "StrictMode"); 11600 if (r == null) { 11601 return; 11602 } 11603 11604 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11605 Integer stackFingerprint = info.hashCode(); 11606 boolean logIt = true; 11607 synchronized (mAlreadyLoggedViolatedStacks) { 11608 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11609 logIt = false; 11610 // TODO: sub-sample into EventLog for these, with 11611 // the info.durationMillis? Then we'd get 11612 // the relative pain numbers, without logging all 11613 // the stack traces repeatedly. We'd want to do 11614 // likewise in the client code, which also does 11615 // dup suppression, before the Binder call. 11616 } else { 11617 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11618 mAlreadyLoggedViolatedStacks.clear(); 11619 } 11620 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11621 } 11622 } 11623 if (logIt) { 11624 logStrictModeViolationToDropBox(r, info); 11625 } 11626 } 11627 11628 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11629 AppErrorResult result = new AppErrorResult(); 11630 synchronized (this) { 11631 final long origId = Binder.clearCallingIdentity(); 11632 11633 Message msg = Message.obtain(); 11634 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11635 HashMap<String, Object> data = new HashMap<String, Object>(); 11636 data.put("result", result); 11637 data.put("app", r); 11638 data.put("violationMask", violationMask); 11639 data.put("info", info); 11640 msg.obj = data; 11641 mHandler.sendMessage(msg); 11642 11643 Binder.restoreCallingIdentity(origId); 11644 } 11645 int res = result.get(); 11646 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11647 } 11648 } 11649 11650 // Depending on the policy in effect, there could be a bunch of 11651 // these in quick succession so we try to batch these together to 11652 // minimize disk writes, number of dropbox entries, and maximize 11653 // compression, by having more fewer, larger records. 11654 private void logStrictModeViolationToDropBox( 11655 ProcessRecord process, 11656 StrictMode.ViolationInfo info) { 11657 if (info == null) { 11658 return; 11659 } 11660 final boolean isSystemApp = process == null || 11661 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11662 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11663 final String processName = process == null ? "unknown" : process.processName; 11664 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11665 final DropBoxManager dbox = (DropBoxManager) 11666 mContext.getSystemService(Context.DROPBOX_SERVICE); 11667 11668 // Exit early if the dropbox isn't configured to accept this report type. 11669 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11670 11671 boolean bufferWasEmpty; 11672 boolean needsFlush; 11673 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11674 synchronized (sb) { 11675 bufferWasEmpty = sb.length() == 0; 11676 appendDropBoxProcessHeaders(process, processName, sb); 11677 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11678 sb.append("System-App: ").append(isSystemApp).append("\n"); 11679 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11680 if (info.violationNumThisLoop != 0) { 11681 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11682 } 11683 if (info.numAnimationsRunning != 0) { 11684 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11685 } 11686 if (info.broadcastIntentAction != null) { 11687 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11688 } 11689 if (info.durationMillis != -1) { 11690 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11691 } 11692 if (info.numInstances != -1) { 11693 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11694 } 11695 if (info.tags != null) { 11696 for (String tag : info.tags) { 11697 sb.append("Span-Tag: ").append(tag).append("\n"); 11698 } 11699 } 11700 sb.append("\n"); 11701 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11702 sb.append(info.crashInfo.stackTrace); 11703 } 11704 sb.append("\n"); 11705 11706 // Only buffer up to ~64k. Various logging bits truncate 11707 // things at 128k. 11708 needsFlush = (sb.length() > 64 * 1024); 11709 } 11710 11711 // Flush immediately if the buffer's grown too large, or this 11712 // is a non-system app. Non-system apps are isolated with a 11713 // different tag & policy and not batched. 11714 // 11715 // Batching is useful during internal testing with 11716 // StrictMode settings turned up high. Without batching, 11717 // thousands of separate files could be created on boot. 11718 if (!isSystemApp || needsFlush) { 11719 new Thread("Error dump: " + dropboxTag) { 11720 @Override 11721 public void run() { 11722 String report; 11723 synchronized (sb) { 11724 report = sb.toString(); 11725 sb.delete(0, sb.length()); 11726 sb.trimToSize(); 11727 } 11728 if (report.length() != 0) { 11729 dbox.addText(dropboxTag, report); 11730 } 11731 } 11732 }.start(); 11733 return; 11734 } 11735 11736 // System app batching: 11737 if (!bufferWasEmpty) { 11738 // An existing dropbox-writing thread is outstanding, so 11739 // we don't need to start it up. The existing thread will 11740 // catch the buffer appends we just did. 11741 return; 11742 } 11743 11744 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11745 // (After this point, we shouldn't access AMS internal data structures.) 11746 new Thread("Error dump: " + dropboxTag) { 11747 @Override 11748 public void run() { 11749 // 5 second sleep to let stacks arrive and be batched together 11750 try { 11751 Thread.sleep(5000); // 5 seconds 11752 } catch (InterruptedException e) {} 11753 11754 String errorReport; 11755 synchronized (mStrictModeBuffer) { 11756 errorReport = mStrictModeBuffer.toString(); 11757 if (errorReport.length() == 0) { 11758 return; 11759 } 11760 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11761 mStrictModeBuffer.trimToSize(); 11762 } 11763 dbox.addText(dropboxTag, errorReport); 11764 } 11765 }.start(); 11766 } 11767 11768 /** 11769 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11770 * @param app object of the crashing app, null for the system server 11771 * @param tag reported by the caller 11772 * @param system whether this wtf is coming from the system 11773 * @param crashInfo describing the context of the error 11774 * @return true if the process should exit immediately (WTF is fatal) 11775 */ 11776 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11777 final ApplicationErrorReport.CrashInfo crashInfo) { 11778 final int callingUid = Binder.getCallingUid(); 11779 final int callingPid = Binder.getCallingPid(); 11780 11781 if (system) { 11782 // If this is coming from the system, we could very well have low-level 11783 // system locks held, so we want to do this all asynchronously. And we 11784 // never want this to become fatal, so there is that too. 11785 mHandler.post(new Runnable() { 11786 @Override public void run() { 11787 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11788 } 11789 }); 11790 return false; 11791 } 11792 11793 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11794 crashInfo); 11795 11796 if (r != null && r.pid != Process.myPid() && 11797 Settings.Global.getInt(mContext.getContentResolver(), 11798 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11799 crashApplication(r, crashInfo); 11800 return true; 11801 } else { 11802 return false; 11803 } 11804 } 11805 11806 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11807 final ApplicationErrorReport.CrashInfo crashInfo) { 11808 final ProcessRecord r = findAppProcess(app, "WTF"); 11809 final String processName = app == null ? "system_server" 11810 : (r == null ? "unknown" : r.processName); 11811 11812 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11813 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11814 11815 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11816 11817 return r; 11818 } 11819 11820 /** 11821 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11822 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11823 */ 11824 private ProcessRecord findAppProcess(IBinder app, String reason) { 11825 if (app == null) { 11826 return null; 11827 } 11828 11829 synchronized (this) { 11830 final int NP = mProcessNames.getMap().size(); 11831 for (int ip=0; ip<NP; ip++) { 11832 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11833 final int NA = apps.size(); 11834 for (int ia=0; ia<NA; ia++) { 11835 ProcessRecord p = apps.valueAt(ia); 11836 if (p.thread != null && p.thread.asBinder() == app) { 11837 return p; 11838 } 11839 } 11840 } 11841 11842 Slog.w(TAG, "Can't find mystery application for " + reason 11843 + " from pid=" + Binder.getCallingPid() 11844 + " uid=" + Binder.getCallingUid() + ": " + app); 11845 return null; 11846 } 11847 } 11848 11849 /** 11850 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11851 * to append various headers to the dropbox log text. 11852 */ 11853 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11854 StringBuilder sb) { 11855 // Watchdog thread ends up invoking this function (with 11856 // a null ProcessRecord) to add the stack file to dropbox. 11857 // Do not acquire a lock on this (am) in such cases, as it 11858 // could cause a potential deadlock, if and when watchdog 11859 // is invoked due to unavailability of lock on am and it 11860 // would prevent watchdog from killing system_server. 11861 if (process == null) { 11862 sb.append("Process: ").append(processName).append("\n"); 11863 return; 11864 } 11865 // Note: ProcessRecord 'process' is guarded by the service 11866 // instance. (notably process.pkgList, which could otherwise change 11867 // concurrently during execution of this method) 11868 synchronized (this) { 11869 sb.append("Process: ").append(processName).append("\n"); 11870 int flags = process.info.flags; 11871 IPackageManager pm = AppGlobals.getPackageManager(); 11872 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11873 for (int ip=0; ip<process.pkgList.size(); ip++) { 11874 String pkg = process.pkgList.keyAt(ip); 11875 sb.append("Package: ").append(pkg); 11876 try { 11877 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11878 if (pi != null) { 11879 sb.append(" v").append(pi.versionCode); 11880 if (pi.versionName != null) { 11881 sb.append(" (").append(pi.versionName).append(")"); 11882 } 11883 } 11884 } catch (RemoteException e) { 11885 Slog.e(TAG, "Error getting package info: " + pkg, e); 11886 } 11887 sb.append("\n"); 11888 } 11889 } 11890 } 11891 11892 private static String processClass(ProcessRecord process) { 11893 if (process == null || process.pid == MY_PID) { 11894 return "system_server"; 11895 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11896 return "system_app"; 11897 } else { 11898 return "data_app"; 11899 } 11900 } 11901 11902 /** 11903 * Write a description of an error (crash, WTF, ANR) to the drop box. 11904 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11905 * @param process which caused the error, null means the system server 11906 * @param activity which triggered the error, null if unknown 11907 * @param parent activity related to the error, null if unknown 11908 * @param subject line related to the error, null if absent 11909 * @param report in long form describing the error, null if absent 11910 * @param logFile to include in the report, null if none 11911 * @param crashInfo giving an application stack trace, null if absent 11912 */ 11913 public void addErrorToDropBox(String eventType, 11914 ProcessRecord process, String processName, ActivityRecord activity, 11915 ActivityRecord parent, String subject, 11916 final String report, final File logFile, 11917 final ApplicationErrorReport.CrashInfo crashInfo) { 11918 // NOTE -- this must never acquire the ActivityManagerService lock, 11919 // otherwise the watchdog may be prevented from resetting the system. 11920 11921 final String dropboxTag = processClass(process) + "_" + eventType; 11922 final DropBoxManager dbox = (DropBoxManager) 11923 mContext.getSystemService(Context.DROPBOX_SERVICE); 11924 11925 // Exit early if the dropbox isn't configured to accept this report type. 11926 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11927 11928 final StringBuilder sb = new StringBuilder(1024); 11929 appendDropBoxProcessHeaders(process, processName, sb); 11930 if (activity != null) { 11931 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11932 } 11933 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11934 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11935 } 11936 if (parent != null && parent != activity) { 11937 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11938 } 11939 if (subject != null) { 11940 sb.append("Subject: ").append(subject).append("\n"); 11941 } 11942 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11943 if (Debug.isDebuggerConnected()) { 11944 sb.append("Debugger: Connected\n"); 11945 } 11946 sb.append("\n"); 11947 11948 // Do the rest in a worker thread to avoid blocking the caller on I/O 11949 // (After this point, we shouldn't access AMS internal data structures.) 11950 Thread worker = new Thread("Error dump: " + dropboxTag) { 11951 @Override 11952 public void run() { 11953 if (report != null) { 11954 sb.append(report); 11955 } 11956 if (logFile != null) { 11957 try { 11958 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11959 "\n\n[[TRUNCATED]]")); 11960 } catch (IOException e) { 11961 Slog.e(TAG, "Error reading " + logFile, e); 11962 } 11963 } 11964 if (crashInfo != null && crashInfo.stackTrace != null) { 11965 sb.append(crashInfo.stackTrace); 11966 } 11967 11968 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11969 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11970 if (lines > 0) { 11971 sb.append("\n"); 11972 11973 // Merge several logcat streams, and take the last N lines 11974 InputStreamReader input = null; 11975 try { 11976 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11977 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11978 "-b", "crash", 11979 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11980 11981 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11982 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11983 input = new InputStreamReader(logcat.getInputStream()); 11984 11985 int num; 11986 char[] buf = new char[8192]; 11987 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11988 } catch (IOException e) { 11989 Slog.e(TAG, "Error running logcat", e); 11990 } finally { 11991 if (input != null) try { input.close(); } catch (IOException e) {} 11992 } 11993 } 11994 11995 dbox.addText(dropboxTag, sb.toString()); 11996 } 11997 }; 11998 11999 if (process == null) { 12000 // If process is null, we are being called from some internal code 12001 // and may be about to die -- run this synchronously. 12002 worker.run(); 12003 } else { 12004 worker.start(); 12005 } 12006 } 12007 12008 /** 12009 * Bring up the "unexpected error" dialog box for a crashing app. 12010 * Deal with edge cases (intercepts from instrumented applications, 12011 * ActivityController, error intent receivers, that sort of thing). 12012 * @param r the application crashing 12013 * @param crashInfo describing the failure 12014 */ 12015 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12016 long timeMillis = System.currentTimeMillis(); 12017 String shortMsg = crashInfo.exceptionClassName; 12018 String longMsg = crashInfo.exceptionMessage; 12019 String stackTrace = crashInfo.stackTrace; 12020 if (shortMsg != null && longMsg != null) { 12021 longMsg = shortMsg + ": " + longMsg; 12022 } else if (shortMsg != null) { 12023 longMsg = shortMsg; 12024 } 12025 12026 AppErrorResult result = new AppErrorResult(); 12027 synchronized (this) { 12028 if (mController != null) { 12029 try { 12030 String name = r != null ? r.processName : null; 12031 int pid = r != null ? r.pid : Binder.getCallingPid(); 12032 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12033 if (!mController.appCrashed(name, pid, 12034 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12035 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12036 && "Native crash".equals(crashInfo.exceptionClassName)) { 12037 Slog.w(TAG, "Skip killing native crashed app " + name 12038 + "(" + pid + ") during testing"); 12039 } else { 12040 Slog.w(TAG, "Force-killing crashed app " + name 12041 + " at watcher's request"); 12042 if (r != null) { 12043 r.kill("crash", true); 12044 } else { 12045 // Huh. 12046 Process.killProcess(pid); 12047 Process.killProcessGroup(uid, pid); 12048 } 12049 } 12050 return; 12051 } 12052 } catch (RemoteException e) { 12053 mController = null; 12054 Watchdog.getInstance().setActivityController(null); 12055 } 12056 } 12057 12058 final long origId = Binder.clearCallingIdentity(); 12059 12060 // If this process is running instrumentation, finish it. 12061 if (r != null && r.instrumentationClass != null) { 12062 Slog.w(TAG, "Error in app " + r.processName 12063 + " running instrumentation " + r.instrumentationClass + ":"); 12064 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12065 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12066 Bundle info = new Bundle(); 12067 info.putString("shortMsg", shortMsg); 12068 info.putString("longMsg", longMsg); 12069 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12070 Binder.restoreCallingIdentity(origId); 12071 return; 12072 } 12073 12074 // Log crash in battery stats. 12075 if (r != null) { 12076 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12077 } 12078 12079 // If we can't identify the process or it's already exceeded its crash quota, 12080 // quit right away without showing a crash dialog. 12081 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12082 Binder.restoreCallingIdentity(origId); 12083 return; 12084 } 12085 12086 Message msg = Message.obtain(); 12087 msg.what = SHOW_ERROR_MSG; 12088 HashMap data = new HashMap(); 12089 data.put("result", result); 12090 data.put("app", r); 12091 msg.obj = data; 12092 mHandler.sendMessage(msg); 12093 12094 Binder.restoreCallingIdentity(origId); 12095 } 12096 12097 int res = result.get(); 12098 12099 Intent appErrorIntent = null; 12100 synchronized (this) { 12101 if (r != null && !r.isolated) { 12102 // XXX Can't keep track of crash time for isolated processes, 12103 // since they don't have a persistent identity. 12104 mProcessCrashTimes.put(r.info.processName, r.uid, 12105 SystemClock.uptimeMillis()); 12106 } 12107 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12108 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12109 } 12110 } 12111 12112 if (appErrorIntent != null) { 12113 try { 12114 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12115 } catch (ActivityNotFoundException e) { 12116 Slog.w(TAG, "bug report receiver dissappeared", e); 12117 } 12118 } 12119 } 12120 12121 Intent createAppErrorIntentLocked(ProcessRecord r, 12122 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12123 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12124 if (report == null) { 12125 return null; 12126 } 12127 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12128 result.setComponent(r.errorReportReceiver); 12129 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12130 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12131 return result; 12132 } 12133 12134 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12135 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12136 if (r.errorReportReceiver == null) { 12137 return null; 12138 } 12139 12140 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12141 return null; 12142 } 12143 12144 ApplicationErrorReport report = new ApplicationErrorReport(); 12145 report.packageName = r.info.packageName; 12146 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12147 report.processName = r.processName; 12148 report.time = timeMillis; 12149 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12150 12151 if (r.crashing || r.forceCrashReport) { 12152 report.type = ApplicationErrorReport.TYPE_CRASH; 12153 report.crashInfo = crashInfo; 12154 } else if (r.notResponding) { 12155 report.type = ApplicationErrorReport.TYPE_ANR; 12156 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12157 12158 report.anrInfo.activity = r.notRespondingReport.tag; 12159 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12160 report.anrInfo.info = r.notRespondingReport.longMsg; 12161 } 12162 12163 return report; 12164 } 12165 12166 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12167 enforceNotIsolatedCaller("getProcessesInErrorState"); 12168 // assume our apps are happy - lazy create the list 12169 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12170 12171 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12172 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12173 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12174 12175 synchronized (this) { 12176 12177 // iterate across all processes 12178 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12179 ProcessRecord app = mLruProcesses.get(i); 12180 if (!allUsers && app.userId != userId) { 12181 continue; 12182 } 12183 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12184 // This one's in trouble, so we'll generate a report for it 12185 // crashes are higher priority (in case there's a crash *and* an anr) 12186 ActivityManager.ProcessErrorStateInfo report = null; 12187 if (app.crashing) { 12188 report = app.crashingReport; 12189 } else if (app.notResponding) { 12190 report = app.notRespondingReport; 12191 } 12192 12193 if (report != null) { 12194 if (errList == null) { 12195 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12196 } 12197 errList.add(report); 12198 } else { 12199 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12200 " crashing = " + app.crashing + 12201 " notResponding = " + app.notResponding); 12202 } 12203 } 12204 } 12205 } 12206 12207 return errList; 12208 } 12209 12210 static int procStateToImportance(int procState, int memAdj, 12211 ActivityManager.RunningAppProcessInfo currApp) { 12212 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12213 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12214 currApp.lru = memAdj; 12215 } else { 12216 currApp.lru = 0; 12217 } 12218 return imp; 12219 } 12220 12221 private void fillInProcMemInfo(ProcessRecord app, 12222 ActivityManager.RunningAppProcessInfo outInfo) { 12223 outInfo.pid = app.pid; 12224 outInfo.uid = app.info.uid; 12225 if (mHeavyWeightProcess == app) { 12226 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12227 } 12228 if (app.persistent) { 12229 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12230 } 12231 if (app.activities.size() > 0) { 12232 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12233 } 12234 outInfo.lastTrimLevel = app.trimMemoryLevel; 12235 int adj = app.curAdj; 12236 int procState = app.curProcState; 12237 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12238 outInfo.importanceReasonCode = app.adjTypeCode; 12239 outInfo.processState = app.curProcState; 12240 } 12241 12242 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12243 enforceNotIsolatedCaller("getRunningAppProcesses"); 12244 // Lazy instantiation of list 12245 List<ActivityManager.RunningAppProcessInfo> runList = null; 12246 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12247 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12248 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12249 synchronized (this) { 12250 // Iterate across all processes 12251 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12252 ProcessRecord app = mLruProcesses.get(i); 12253 if (!allUsers && app.userId != userId) { 12254 continue; 12255 } 12256 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12257 // Generate process state info for running application 12258 ActivityManager.RunningAppProcessInfo currApp = 12259 new ActivityManager.RunningAppProcessInfo(app.processName, 12260 app.pid, app.getPackageList()); 12261 fillInProcMemInfo(app, currApp); 12262 if (app.adjSource instanceof ProcessRecord) { 12263 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12264 currApp.importanceReasonImportance = 12265 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12266 app.adjSourceProcState); 12267 } else if (app.adjSource instanceof ActivityRecord) { 12268 ActivityRecord r = (ActivityRecord)app.adjSource; 12269 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12270 } 12271 if (app.adjTarget instanceof ComponentName) { 12272 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12273 } 12274 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12275 // + " lru=" + currApp.lru); 12276 if (runList == null) { 12277 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12278 } 12279 runList.add(currApp); 12280 } 12281 } 12282 } 12283 return runList; 12284 } 12285 12286 public List<ApplicationInfo> getRunningExternalApplications() { 12287 enforceNotIsolatedCaller("getRunningExternalApplications"); 12288 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12289 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12290 if (runningApps != null && runningApps.size() > 0) { 12291 Set<String> extList = new HashSet<String>(); 12292 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12293 if (app.pkgList != null) { 12294 for (String pkg : app.pkgList) { 12295 extList.add(pkg); 12296 } 12297 } 12298 } 12299 IPackageManager pm = AppGlobals.getPackageManager(); 12300 for (String pkg : extList) { 12301 try { 12302 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12303 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12304 retList.add(info); 12305 } 12306 } catch (RemoteException e) { 12307 } 12308 } 12309 } 12310 return retList; 12311 } 12312 12313 @Override getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)12314 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12315 enforceNotIsolatedCaller("getMyMemoryState"); 12316 synchronized (this) { 12317 ProcessRecord proc; 12318 synchronized (mPidsSelfLocked) { 12319 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12320 } 12321 fillInProcMemInfo(proc, outInfo); 12322 } 12323 } 12324 12325 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)12326 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12327 if (checkCallingPermission(android.Manifest.permission.DUMP) 12328 != PackageManager.PERMISSION_GRANTED) { 12329 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12330 + Binder.getCallingPid() 12331 + ", uid=" + Binder.getCallingUid() 12332 + " without permission " 12333 + android.Manifest.permission.DUMP); 12334 return; 12335 } 12336 12337 boolean dumpAll = false; 12338 boolean dumpClient = false; 12339 String dumpPackage = null; 12340 12341 int opti = 0; 12342 while (opti < args.length) { 12343 String opt = args[opti]; 12344 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12345 break; 12346 } 12347 opti++; 12348 if ("-a".equals(opt)) { 12349 dumpAll = true; 12350 } else if ("-c".equals(opt)) { 12351 dumpClient = true; 12352 } else if ("-p".equals(opt)) { 12353 if (opti < args.length) { 12354 dumpPackage = args[opti]; 12355 opti++; 12356 } else { 12357 pw.println("Error: -p option requires package argument"); 12358 return; 12359 } 12360 dumpClient = true; 12361 } else if ("-h".equals(opt)) { 12362 pw.println("Activity manager dump options:"); 12363 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ..."); 12364 pw.println(" cmd may be one of:"); 12365 pw.println(" a[ctivities]: activity stack state"); 12366 pw.println(" r[recents]: recent activities state"); 12367 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12368 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12369 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12370 pw.println(" o[om]: out of memory management"); 12371 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12372 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12373 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12374 pw.println(" as[sociations]: tracked app associations"); 12375 pw.println(" service [COMP_SPEC]: service client-side state"); 12376 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12377 pw.println(" all: dump all activities"); 12378 pw.println(" top: dump the top activity"); 12379 pw.println(" write: write all pending state to storage"); 12380 pw.println(" track-associations: enable association tracking"); 12381 pw.println(" untrack-associations: disable and clear association tracking"); 12382 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12383 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12384 pw.println(" a partial substring in a component name, a"); 12385 pw.println(" hex object identifier."); 12386 pw.println(" -a: include all available server state."); 12387 pw.println(" -c: include client state."); 12388 pw.println(" -p: limit output to given package."); 12389 return; 12390 } else { 12391 pw.println("Unknown argument: " + opt + "; use -h for help"); 12392 } 12393 } 12394 12395 long origId = Binder.clearCallingIdentity(); 12396 boolean more = false; 12397 // Is the caller requesting to dump a particular piece of data? 12398 if (opti < args.length) { 12399 String cmd = args[opti]; 12400 opti++; 12401 if ("activities".equals(cmd) || "a".equals(cmd)) { 12402 synchronized (this) { 12403 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12404 } 12405 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12406 synchronized (this) { 12407 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 12408 } 12409 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12410 String[] newArgs; 12411 String name; 12412 if (opti >= args.length) { 12413 name = null; 12414 newArgs = EMPTY_STRING_ARRAY; 12415 } else { 12416 dumpPackage = args[opti]; 12417 opti++; 12418 newArgs = new String[args.length - opti]; 12419 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12420 args.length - opti); 12421 } 12422 synchronized (this) { 12423 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 12424 } 12425 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12426 String[] newArgs; 12427 String name; 12428 if (opti >= args.length) { 12429 name = null; 12430 newArgs = EMPTY_STRING_ARRAY; 12431 } else { 12432 dumpPackage = args[opti]; 12433 opti++; 12434 newArgs = new String[args.length - opti]; 12435 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12436 args.length - opti); 12437 } 12438 synchronized (this) { 12439 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 12440 } 12441 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12442 String[] newArgs; 12443 String name; 12444 if (opti >= args.length) { 12445 name = null; 12446 newArgs = EMPTY_STRING_ARRAY; 12447 } else { 12448 dumpPackage = args[opti]; 12449 opti++; 12450 newArgs = new String[args.length - opti]; 12451 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12452 args.length - opti); 12453 } 12454 synchronized (this) { 12455 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 12456 } 12457 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12458 synchronized (this) { 12459 dumpOomLocked(fd, pw, args, opti, true); 12460 } 12461 } else if ("provider".equals(cmd)) { 12462 String[] newArgs; 12463 String name; 12464 if (opti >= args.length) { 12465 name = null; 12466 newArgs = EMPTY_STRING_ARRAY; 12467 } else { 12468 name = args[opti]; 12469 opti++; 12470 newArgs = new String[args.length - opti]; 12471 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12472 } 12473 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12474 pw.println("No providers match: " + name); 12475 pw.println("Use -h for help."); 12476 } 12477 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12478 synchronized (this) { 12479 dumpProvidersLocked(fd, pw, args, opti, true, null); 12480 } 12481 } else if ("service".equals(cmd)) { 12482 String[] newArgs; 12483 String name; 12484 if (opti >= args.length) { 12485 name = null; 12486 newArgs = EMPTY_STRING_ARRAY; 12487 } else { 12488 name = args[opti]; 12489 opti++; 12490 newArgs = new String[args.length - opti]; 12491 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12492 args.length - opti); 12493 } 12494 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12495 pw.println("No services match: " + name); 12496 pw.println("Use -h for help."); 12497 } 12498 } else if ("package".equals(cmd)) { 12499 String[] newArgs; 12500 if (opti >= args.length) { 12501 pw.println("package: no package name specified"); 12502 pw.println("Use -h for help."); 12503 } else { 12504 dumpPackage = args[opti]; 12505 opti++; 12506 newArgs = new String[args.length - opti]; 12507 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12508 args.length - opti); 12509 args = newArgs; 12510 opti = 0; 12511 more = true; 12512 } 12513 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 12514 synchronized (this) { 12515 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12516 } 12517 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12518 synchronized (this) { 12519 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12520 } 12521 } else if ("write".equals(cmd)) { 12522 mTaskPersister.flush(); 12523 pw.println("All tasks persisted."); 12524 return; 12525 } else if ("track-associations".equals(cmd)) { 12526 synchronized (this) { 12527 if (!mTrackingAssociations) { 12528 mTrackingAssociations = true; 12529 pw.println("Association tracking started."); 12530 } else { 12531 pw.println("Association tracking already enabled."); 12532 } 12533 } 12534 return; 12535 } else if ("untrack-associations".equals(cmd)) { 12536 synchronized (this) { 12537 if (mTrackingAssociations) { 12538 mTrackingAssociations = false; 12539 mAssociations.clear(); 12540 pw.println("Association tracking stopped."); 12541 } else { 12542 pw.println("Association tracking not running."); 12543 } 12544 } 12545 return; 12546 } else { 12547 // Dumping a single activity? 12548 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12549 pw.println("Bad activity command, or no activities match: " + cmd); 12550 pw.println("Use -h for help."); 12551 } 12552 } 12553 if (!more) { 12554 Binder.restoreCallingIdentity(origId); 12555 return; 12556 } 12557 } 12558 12559 // No piece of data specified, dump everything. 12560 synchronized (this) { 12561 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12562 pw.println(); 12563 if (dumpAll) { 12564 pw.println("-------------------------------------------------------------------------------"); 12565 } 12566 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12567 pw.println(); 12568 if (dumpAll) { 12569 pw.println("-------------------------------------------------------------------------------"); 12570 } 12571 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12572 pw.println(); 12573 if (dumpAll) { 12574 pw.println("-------------------------------------------------------------------------------"); 12575 } 12576 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12577 pw.println(); 12578 if (dumpAll) { 12579 pw.println("-------------------------------------------------------------------------------"); 12580 } 12581 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12582 pw.println(); 12583 if (dumpAll) { 12584 pw.println("-------------------------------------------------------------------------------"); 12585 } 12586 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12587 if (mAssociations.size() > 0) { 12588 pw.println(); 12589 if (dumpAll) { 12590 pw.println("-------------------------------------------------------------------------------"); 12591 } 12592 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12593 } 12594 pw.println(); 12595 if (dumpAll) { 12596 pw.println("-------------------------------------------------------------------------------"); 12597 } 12598 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12599 } 12600 Binder.restoreCallingIdentity(origId); 12601 } 12602 dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage)12603 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12604 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12605 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12606 12607 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12608 dumpPackage); 12609 boolean needSep = printedAnything; 12610 12611 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12612 dumpPackage, needSep, " mFocusedActivity: "); 12613 if (printed) { 12614 printedAnything = true; 12615 needSep = false; 12616 } 12617 12618 if (dumpPackage == null) { 12619 if (needSep) { 12620 pw.println(); 12621 } 12622 needSep = true; 12623 printedAnything = true; 12624 mStackSupervisor.dump(pw, " "); 12625 } 12626 12627 if (!printedAnything) { 12628 pw.println(" (nothing)"); 12629 } 12630 } 12631 dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)12632 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12633 int opti, boolean dumpAll, String dumpPackage) { 12634 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12635 12636 boolean printedAnything = false; 12637 12638 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12639 boolean printedHeader = false; 12640 12641 final int N = mRecentTasks.size(); 12642 for (int i=0; i<N; i++) { 12643 TaskRecord tr = mRecentTasks.get(i); 12644 if (dumpPackage != null) { 12645 if (tr.realActivity == null || 12646 !dumpPackage.equals(tr.realActivity)) { 12647 continue; 12648 } 12649 } 12650 if (!printedHeader) { 12651 pw.println(" Recent tasks:"); 12652 printedHeader = true; 12653 printedAnything = true; 12654 } 12655 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12656 pw.println(tr); 12657 if (dumpAll) { 12658 mRecentTasks.get(i).dump(pw, " "); 12659 } 12660 } 12661 } 12662 12663 if (!printedAnything) { 12664 pw.println(" (nothing)"); 12665 } 12666 } 12667 dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage)12668 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12669 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12670 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 12671 12672 int dumpUid = 0; 12673 if (dumpPackage != null) { 12674 IPackageManager pm = AppGlobals.getPackageManager(); 12675 try { 12676 dumpUid = pm.getPackageUid(dumpPackage, 0); 12677 } catch (RemoteException e) { 12678 } 12679 } 12680 12681 boolean printedAnything = false; 12682 12683 final long now = SystemClock.uptimeMillis(); 12684 12685 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 12686 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 12687 = mAssociations.valueAt(i1); 12688 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 12689 SparseArray<ArrayMap<String, Association>> sourceUids 12690 = targetComponents.valueAt(i2); 12691 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 12692 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 12693 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 12694 Association ass = sourceProcesses.valueAt(i4); 12695 if (dumpPackage != null) { 12696 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 12697 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 12698 continue; 12699 } 12700 } 12701 printedAnything = true; 12702 pw.print(" "); 12703 pw.print(ass.mTargetProcess); 12704 pw.print("/"); 12705 UserHandle.formatUid(pw, ass.mTargetUid); 12706 pw.print(" <- "); 12707 pw.print(ass.mSourceProcess); 12708 pw.print("/"); 12709 UserHandle.formatUid(pw, ass.mSourceUid); 12710 pw.println(); 12711 pw.print(" via "); 12712 pw.print(ass.mTargetComponent.flattenToShortString()); 12713 pw.println(); 12714 pw.print(" "); 12715 long dur = ass.mTime; 12716 if (ass.mNesting > 0) { 12717 dur += now - ass.mStartTime; 12718 } 12719 TimeUtils.formatDuration(dur, pw); 12720 pw.print(" ("); 12721 pw.print(ass.mCount); 12722 pw.println(" times)"); 12723 if (ass.mNesting > 0) { 12724 pw.print(" "); 12725 pw.print(" Currently active: "); 12726 TimeUtils.formatDuration(now - ass.mStartTime, pw); 12727 pw.println(); 12728 } 12729 } 12730 } 12731 } 12732 12733 } 12734 12735 if (!printedAnything) { 12736 pw.println(" (nothing)"); 12737 } 12738 } 12739 dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)12740 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12741 int opti, boolean dumpAll, String dumpPackage) { 12742 boolean needSep = false; 12743 boolean printedAnything = false; 12744 int numPers = 0; 12745 12746 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12747 12748 if (dumpAll) { 12749 final int NP = mProcessNames.getMap().size(); 12750 for (int ip=0; ip<NP; ip++) { 12751 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12752 final int NA = procs.size(); 12753 for (int ia=0; ia<NA; ia++) { 12754 ProcessRecord r = procs.valueAt(ia); 12755 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12756 continue; 12757 } 12758 if (!needSep) { 12759 pw.println(" All known processes:"); 12760 needSep = true; 12761 printedAnything = true; 12762 } 12763 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12764 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12765 pw.print(" "); pw.println(r); 12766 r.dump(pw, " "); 12767 if (r.persistent) { 12768 numPers++; 12769 } 12770 } 12771 } 12772 } 12773 12774 if (mIsolatedProcesses.size() > 0) { 12775 boolean printed = false; 12776 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12777 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12778 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12779 continue; 12780 } 12781 if (!printed) { 12782 if (needSep) { 12783 pw.println(); 12784 } 12785 pw.println(" Isolated process list (sorted by uid):"); 12786 printedAnything = true; 12787 printed = true; 12788 needSep = true; 12789 } 12790 pw.println(String.format("%sIsolated #%2d: %s", 12791 " ", i, r.toString())); 12792 } 12793 } 12794 12795 if (mLruProcesses.size() > 0) { 12796 if (needSep) { 12797 pw.println(); 12798 } 12799 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12800 pw.print(" total, non-act at "); 12801 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12802 pw.print(", non-svc at "); 12803 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12804 pw.println("):"); 12805 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12806 needSep = true; 12807 printedAnything = true; 12808 } 12809 12810 if (dumpAll || dumpPackage != null) { 12811 synchronized (mPidsSelfLocked) { 12812 boolean printed = false; 12813 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12814 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12815 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12816 continue; 12817 } 12818 if (!printed) { 12819 if (needSep) pw.println(); 12820 needSep = true; 12821 pw.println(" PID mappings:"); 12822 printed = true; 12823 printedAnything = true; 12824 } 12825 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12826 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12827 } 12828 } 12829 } 12830 12831 if (mForegroundProcesses.size() > 0) { 12832 synchronized (mPidsSelfLocked) { 12833 boolean printed = false; 12834 for (int i=0; i<mForegroundProcesses.size(); i++) { 12835 ProcessRecord r = mPidsSelfLocked.get( 12836 mForegroundProcesses.valueAt(i).pid); 12837 if (dumpPackage != null && (r == null 12838 || !r.pkgList.containsKey(dumpPackage))) { 12839 continue; 12840 } 12841 if (!printed) { 12842 if (needSep) pw.println(); 12843 needSep = true; 12844 pw.println(" Foreground Processes:"); 12845 printed = true; 12846 printedAnything = true; 12847 } 12848 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12849 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12850 } 12851 } 12852 } 12853 12854 if (mPersistentStartingProcesses.size() > 0) { 12855 if (needSep) pw.println(); 12856 needSep = true; 12857 printedAnything = true; 12858 pw.println(" Persisent processes that are starting:"); 12859 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12860 "Starting Norm", "Restarting PERS", dumpPackage); 12861 } 12862 12863 if (mRemovedProcesses.size() > 0) { 12864 if (needSep) pw.println(); 12865 needSep = true; 12866 printedAnything = true; 12867 pw.println(" Processes that are being removed:"); 12868 dumpProcessList(pw, this, mRemovedProcesses, " ", 12869 "Removed Norm", "Removed PERS", dumpPackage); 12870 } 12871 12872 if (mProcessesOnHold.size() > 0) { 12873 if (needSep) pw.println(); 12874 needSep = true; 12875 printedAnything = true; 12876 pw.println(" Processes that are on old until the system is ready:"); 12877 dumpProcessList(pw, this, mProcessesOnHold, " ", 12878 "OnHold Norm", "OnHold PERS", dumpPackage); 12879 } 12880 12881 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12882 12883 if (mProcessCrashTimes.getMap().size() > 0) { 12884 boolean printed = false; 12885 long now = SystemClock.uptimeMillis(); 12886 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12887 final int NP = pmap.size(); 12888 for (int ip=0; ip<NP; ip++) { 12889 String pname = pmap.keyAt(ip); 12890 SparseArray<Long> uids = pmap.valueAt(ip); 12891 final int N = uids.size(); 12892 for (int i=0; i<N; i++) { 12893 int puid = uids.keyAt(i); 12894 ProcessRecord r = mProcessNames.get(pname, puid); 12895 if (dumpPackage != null && (r == null 12896 || !r.pkgList.containsKey(dumpPackage))) { 12897 continue; 12898 } 12899 if (!printed) { 12900 if (needSep) pw.println(); 12901 needSep = true; 12902 pw.println(" Time since processes crashed:"); 12903 printed = true; 12904 printedAnything = true; 12905 } 12906 pw.print(" Process "); pw.print(pname); 12907 pw.print(" uid "); pw.print(puid); 12908 pw.print(": last crashed "); 12909 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12910 pw.println(" ago"); 12911 } 12912 } 12913 } 12914 12915 if (mBadProcesses.getMap().size() > 0) { 12916 boolean printed = false; 12917 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12918 final int NP = pmap.size(); 12919 for (int ip=0; ip<NP; ip++) { 12920 String pname = pmap.keyAt(ip); 12921 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12922 final int N = uids.size(); 12923 for (int i=0; i<N; i++) { 12924 int puid = uids.keyAt(i); 12925 ProcessRecord r = mProcessNames.get(pname, puid); 12926 if (dumpPackage != null && (r == null 12927 || !r.pkgList.containsKey(dumpPackage))) { 12928 continue; 12929 } 12930 if (!printed) { 12931 if (needSep) pw.println(); 12932 needSep = true; 12933 pw.println(" Bad processes:"); 12934 printedAnything = true; 12935 } 12936 BadProcessInfo info = uids.valueAt(i); 12937 pw.print(" Bad process "); pw.print(pname); 12938 pw.print(" uid "); pw.print(puid); 12939 pw.print(": crashed at time "); pw.println(info.time); 12940 if (info.shortMsg != null) { 12941 pw.print(" Short msg: "); pw.println(info.shortMsg); 12942 } 12943 if (info.longMsg != null) { 12944 pw.print(" Long msg: "); pw.println(info.longMsg); 12945 } 12946 if (info.stack != null) { 12947 pw.println(" Stack:"); 12948 int lastPos = 0; 12949 for (int pos=0; pos<info.stack.length(); pos++) { 12950 if (info.stack.charAt(pos) == '\n') { 12951 pw.print(" "); 12952 pw.write(info.stack, lastPos, pos-lastPos); 12953 pw.println(); 12954 lastPos = pos+1; 12955 } 12956 } 12957 if (lastPos < info.stack.length()) { 12958 pw.print(" "); 12959 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12960 pw.println(); 12961 } 12962 } 12963 } 12964 } 12965 } 12966 12967 if (dumpPackage == null) { 12968 pw.println(); 12969 needSep = false; 12970 pw.println(" mStartedUsers:"); 12971 for (int i=0; i<mStartedUsers.size(); i++) { 12972 UserStartedState uss = mStartedUsers.valueAt(i); 12973 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12974 pw.print(": "); uss.dump("", pw); 12975 } 12976 pw.print(" mStartedUserArray: ["); 12977 for (int i=0; i<mStartedUserArray.length; i++) { 12978 if (i > 0) pw.print(", "); 12979 pw.print(mStartedUserArray[i]); 12980 } 12981 pw.println("]"); 12982 pw.print(" mUserLru: ["); 12983 for (int i=0; i<mUserLru.size(); i++) { 12984 if (i > 0) pw.print(", "); 12985 pw.print(mUserLru.get(i)); 12986 } 12987 pw.println("]"); 12988 if (dumpAll) { 12989 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12990 } 12991 synchronized (mUserProfileGroupIdsSelfLocked) { 12992 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12993 pw.println(" mUserProfileGroupIds:"); 12994 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12995 pw.print(" User #"); 12996 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12997 pw.print(" -> profile #"); 12998 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12999 } 13000 } 13001 } 13002 } 13003 if (mHomeProcess != null && (dumpPackage == null 13004 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 13005 if (needSep) { 13006 pw.println(); 13007 needSep = false; 13008 } 13009 pw.println(" mHomeProcess: " + mHomeProcess); 13010 } 13011 if (mPreviousProcess != null && (dumpPackage == null 13012 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 13013 if (needSep) { 13014 pw.println(); 13015 needSep = false; 13016 } 13017 pw.println(" mPreviousProcess: " + mPreviousProcess); 13018 } 13019 if (dumpAll) { 13020 StringBuilder sb = new StringBuilder(128); 13021 sb.append(" mPreviousProcessVisibleTime: "); 13022 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 13023 pw.println(sb); 13024 } 13025 if (mHeavyWeightProcess != null && (dumpPackage == null 13026 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 13027 if (needSep) { 13028 pw.println(); 13029 needSep = false; 13030 } 13031 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13032 } 13033 if (dumpPackage == null) { 13034 pw.println(" mConfiguration: " + mConfiguration); 13035 } 13036 if (dumpAll) { 13037 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 13038 if (mCompatModePackages.getPackages().size() > 0) { 13039 boolean printed = false; 13040 for (Map.Entry<String, Integer> entry 13041 : mCompatModePackages.getPackages().entrySet()) { 13042 String pkg = entry.getKey(); 13043 int mode = entry.getValue(); 13044 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 13045 continue; 13046 } 13047 if (!printed) { 13048 pw.println(" mScreenCompatPackages:"); 13049 printed = true; 13050 } 13051 pw.print(" "); pw.print(pkg); pw.print(": "); 13052 pw.print(mode); pw.println(); 13053 } 13054 } 13055 } 13056 if (dumpPackage == null) { 13057 pw.println(" mWakefulness=" 13058 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 13059 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 13060 + lockScreenShownToString()); 13061 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 13062 + " mTestPssMode=" + mTestPssMode); 13063 } 13064 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 13065 || mOrigWaitForDebugger) { 13066 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 13067 || dumpPackage.equals(mOrigDebugApp)) { 13068 if (needSep) { 13069 pw.println(); 13070 needSep = false; 13071 } 13072 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 13073 + " mDebugTransient=" + mDebugTransient 13074 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 13075 } 13076 } 13077 if (mOpenGlTraceApp != null) { 13078 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 13079 if (needSep) { 13080 pw.println(); 13081 needSep = false; 13082 } 13083 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 13084 } 13085 } 13086 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 13087 || mProfileFd != null) { 13088 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 13089 if (needSep) { 13090 pw.println(); 13091 needSep = false; 13092 } 13093 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13094 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13095 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13096 + mAutoStopProfiler); 13097 pw.println(" mProfileType=" + mProfileType); 13098 } 13099 } 13100 if (dumpPackage == null) { 13101 if (mAlwaysFinishActivities || mController != null) { 13102 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13103 + " mController=" + mController); 13104 } 13105 if (dumpAll) { 13106 pw.println(" Total persistent processes: " + numPers); 13107 pw.println(" mProcessesReady=" + mProcessesReady 13108 + " mSystemReady=" + mSystemReady 13109 + " mBooted=" + mBooted 13110 + " mFactoryTest=" + mFactoryTest); 13111 pw.println(" mBooting=" + mBooting 13112 + " mCallFinishBooting=" + mCallFinishBooting 13113 + " mBootAnimationComplete=" + mBootAnimationComplete); 13114 pw.print(" mLastPowerCheckRealtime="); 13115 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13116 pw.println(""); 13117 pw.print(" mLastPowerCheckUptime="); 13118 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13119 pw.println(""); 13120 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13121 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13122 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13123 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13124 + " (" + mLruProcesses.size() + " total)" 13125 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13126 + " mNumServiceProcs=" + mNumServiceProcs 13127 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13128 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13129 + " mLastMemoryLevel" + mLastMemoryLevel 13130 + " mLastNumProcesses" + mLastNumProcesses); 13131 long now = SystemClock.uptimeMillis(); 13132 pw.print(" mLastIdleTime="); 13133 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13134 pw.print(" mLowRamSinceLastIdle="); 13135 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13136 pw.println(); 13137 } 13138 } 13139 13140 if (!printedAnything) { 13141 pw.println(" (nothing)"); 13142 } 13143 } 13144 dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean needSep, boolean dumpAll, String dumpPackage)13145 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13146 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13147 if (mProcessesToGc.size() > 0) { 13148 boolean printed = false; 13149 long now = SystemClock.uptimeMillis(); 13150 for (int i=0; i<mProcessesToGc.size(); i++) { 13151 ProcessRecord proc = mProcessesToGc.get(i); 13152 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13153 continue; 13154 } 13155 if (!printed) { 13156 if (needSep) pw.println(); 13157 needSep = true; 13158 pw.println(" Processes that are waiting to GC:"); 13159 printed = true; 13160 } 13161 pw.print(" Process "); pw.println(proc); 13162 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13163 pw.print(", last gced="); 13164 pw.print(now-proc.lastRequestedGc); 13165 pw.print(" ms ago, last lowMem="); 13166 pw.print(now-proc.lastLowMemory); 13167 pw.println(" ms ago"); 13168 13169 } 13170 } 13171 return needSep; 13172 } 13173 printOomLevel(PrintWriter pw, String name, int adj)13174 void printOomLevel(PrintWriter pw, String name, int adj) { 13175 pw.print(" "); 13176 if (adj >= 0) { 13177 pw.print(' '); 13178 if (adj < 10) pw.print(' '); 13179 } else { 13180 if (adj > -10) pw.print(' '); 13181 } 13182 pw.print(adj); 13183 pw.print(": "); 13184 pw.print(name); 13185 pw.print(" ("); 13186 pw.print(mProcessList.getMemLevel(adj)/1024); 13187 pw.println(" kB)"); 13188 } 13189 dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll)13190 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13191 int opti, boolean dumpAll) { 13192 boolean needSep = false; 13193 13194 if (mLruProcesses.size() > 0) { 13195 if (needSep) pw.println(); 13196 needSep = true; 13197 pw.println(" OOM levels:"); 13198 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13199 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13200 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13201 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13202 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13203 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13204 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13205 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13206 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13207 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13208 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13209 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13210 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13211 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13212 13213 if (needSep) pw.println(); 13214 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13215 pw.print(" total, non-act at "); 13216 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13217 pw.print(", non-svc at "); 13218 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13219 pw.println("):"); 13220 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13221 needSep = true; 13222 } 13223 13224 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13225 13226 pw.println(); 13227 pw.println(" mHomeProcess: " + mHomeProcess); 13228 pw.println(" mPreviousProcess: " + mPreviousProcess); 13229 if (mHeavyWeightProcess != null) { 13230 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13231 } 13232 13233 return true; 13234 } 13235 13236 /** 13237 * There are three ways to call this: 13238 * - no provider specified: dump all the providers 13239 * - a flattened component name that matched an existing provider was specified as the 13240 * first arg: dump that one provider 13241 * - the first arg isn't the flattened component name of an existing provider: 13242 * dump all providers whose component contains the first arg as a substring 13243 */ dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)13244 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13245 int opti, boolean dumpAll) { 13246 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13247 } 13248 13249 static class ItemMatcher { 13250 ArrayList<ComponentName> components; 13251 ArrayList<String> strings; 13252 ArrayList<Integer> objects; 13253 boolean all; 13254 ItemMatcher()13255 ItemMatcher() { 13256 all = true; 13257 } 13258 build(String name)13259 void build(String name) { 13260 ComponentName componentName = ComponentName.unflattenFromString(name); 13261 if (componentName != null) { 13262 if (components == null) { 13263 components = new ArrayList<ComponentName>(); 13264 } 13265 components.add(componentName); 13266 all = false; 13267 } else { 13268 int objectId = 0; 13269 // Not a '/' separated full component name; maybe an object ID? 13270 try { 13271 objectId = Integer.parseInt(name, 16); 13272 if (objects == null) { 13273 objects = new ArrayList<Integer>(); 13274 } 13275 objects.add(objectId); 13276 all = false; 13277 } catch (RuntimeException e) { 13278 // Not an integer; just do string match. 13279 if (strings == null) { 13280 strings = new ArrayList<String>(); 13281 } 13282 strings.add(name); 13283 all = false; 13284 } 13285 } 13286 } 13287 build(String[] args, int opti)13288 int build(String[] args, int opti) { 13289 for (; opti<args.length; opti++) { 13290 String name = args[opti]; 13291 if ("--".equals(name)) { 13292 return opti+1; 13293 } 13294 build(name); 13295 } 13296 return opti; 13297 } 13298 match(Object object, ComponentName comp)13299 boolean match(Object object, ComponentName comp) { 13300 if (all) { 13301 return true; 13302 } 13303 if (components != null) { 13304 for (int i=0; i<components.size(); i++) { 13305 if (components.get(i).equals(comp)) { 13306 return true; 13307 } 13308 } 13309 } 13310 if (objects != null) { 13311 for (int i=0; i<objects.size(); i++) { 13312 if (System.identityHashCode(object) == objects.get(i)) { 13313 return true; 13314 } 13315 } 13316 } 13317 if (strings != null) { 13318 String flat = comp.flattenToString(); 13319 for (int i=0; i<strings.size(); i++) { 13320 if (flat.contains(strings.get(i))) { 13321 return true; 13322 } 13323 } 13324 } 13325 return false; 13326 } 13327 } 13328 13329 /** 13330 * There are three things that cmd can be: 13331 * - a flattened component name that matches an existing activity 13332 * - the cmd arg isn't the flattened component name of an existing activity: 13333 * dump all activity whose component contains the cmd as a substring 13334 * - A hex number of the ActivityRecord object instance. 13335 */ dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)13336 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13337 int opti, boolean dumpAll) { 13338 ArrayList<ActivityRecord> activities; 13339 13340 synchronized (this) { 13341 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13342 } 13343 13344 if (activities.size() <= 0) { 13345 return false; 13346 } 13347 13348 String[] newArgs = new String[args.length - opti]; 13349 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13350 13351 TaskRecord lastTask = null; 13352 boolean needSep = false; 13353 for (int i=activities.size()-1; i>=0; i--) { 13354 ActivityRecord r = activities.get(i); 13355 if (needSep) { 13356 pw.println(); 13357 } 13358 needSep = true; 13359 synchronized (this) { 13360 if (lastTask != r.task) { 13361 lastTask = r.task; 13362 pw.print("TASK "); pw.print(lastTask.affinity); 13363 pw.print(" id="); pw.println(lastTask.taskId); 13364 if (dumpAll) { 13365 lastTask.dump(pw, " "); 13366 } 13367 } 13368 } 13369 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13370 } 13371 return true; 13372 } 13373 13374 /** 13375 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13376 * there is a thread associated with the activity. 13377 */ dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, final ActivityRecord r, String[] args, boolean dumpAll)13378 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13379 final ActivityRecord r, String[] args, boolean dumpAll) { 13380 String innerPrefix = prefix + " "; 13381 synchronized (this) { 13382 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13383 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13384 pw.print(" pid="); 13385 if (r.app != null) pw.println(r.app.pid); 13386 else pw.println("(not running)"); 13387 if (dumpAll) { 13388 r.dump(pw, innerPrefix); 13389 } 13390 } 13391 if (r.app != null && r.app.thread != null) { 13392 // flush anything that is already in the PrintWriter since the thread is going 13393 // to write to the file descriptor directly 13394 pw.flush(); 13395 try { 13396 TransferPipe tp = new TransferPipe(); 13397 try { 13398 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13399 r.appToken, innerPrefix, args); 13400 tp.go(fd); 13401 } finally { 13402 tp.kill(); 13403 } 13404 } catch (IOException e) { 13405 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13406 } catch (RemoteException e) { 13407 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13408 } 13409 } 13410 } 13411 dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)13412 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13413 int opti, boolean dumpAll, String dumpPackage) { 13414 boolean needSep = false; 13415 boolean onlyHistory = false; 13416 boolean printedAnything = false; 13417 13418 if ("history".equals(dumpPackage)) { 13419 if (opti < args.length && "-s".equals(args[opti])) { 13420 dumpAll = false; 13421 } 13422 onlyHistory = true; 13423 dumpPackage = null; 13424 } 13425 13426 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13427 if (!onlyHistory && dumpAll) { 13428 if (mRegisteredReceivers.size() > 0) { 13429 boolean printed = false; 13430 Iterator it = mRegisteredReceivers.values().iterator(); 13431 while (it.hasNext()) { 13432 ReceiverList r = (ReceiverList)it.next(); 13433 if (dumpPackage != null && (r.app == null || 13434 !dumpPackage.equals(r.app.info.packageName))) { 13435 continue; 13436 } 13437 if (!printed) { 13438 pw.println(" Registered Receivers:"); 13439 needSep = true; 13440 printed = true; 13441 printedAnything = true; 13442 } 13443 pw.print(" * "); pw.println(r); 13444 r.dump(pw, " "); 13445 } 13446 } 13447 13448 if (mReceiverResolver.dump(pw, needSep ? 13449 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13450 " ", dumpPackage, false, false)) { 13451 needSep = true; 13452 printedAnything = true; 13453 } 13454 } 13455 13456 for (BroadcastQueue q : mBroadcastQueues) { 13457 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13458 printedAnything |= needSep; 13459 } 13460 13461 needSep = true; 13462 13463 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13464 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13465 if (needSep) { 13466 pw.println(); 13467 } 13468 needSep = true; 13469 printedAnything = true; 13470 pw.print(" Sticky broadcasts for user "); 13471 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13472 StringBuilder sb = new StringBuilder(128); 13473 for (Map.Entry<String, ArrayList<Intent>> ent 13474 : mStickyBroadcasts.valueAt(user).entrySet()) { 13475 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13476 if (dumpAll) { 13477 pw.println(":"); 13478 ArrayList<Intent> intents = ent.getValue(); 13479 final int N = intents.size(); 13480 for (int i=0; i<N; i++) { 13481 sb.setLength(0); 13482 sb.append(" Intent: "); 13483 intents.get(i).toShortString(sb, false, true, false, false); 13484 pw.println(sb.toString()); 13485 Bundle bundle = intents.get(i).getExtras(); 13486 if (bundle != null) { 13487 pw.print(" "); 13488 pw.println(bundle.toString()); 13489 } 13490 } 13491 } else { 13492 pw.println(""); 13493 } 13494 } 13495 } 13496 } 13497 13498 if (!onlyHistory && dumpAll) { 13499 pw.println(); 13500 for (BroadcastQueue queue : mBroadcastQueues) { 13501 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13502 + queue.mBroadcastsScheduled); 13503 } 13504 pw.println(" mHandler:"); 13505 mHandler.dump(new PrintWriterPrinter(pw), " "); 13506 needSep = true; 13507 printedAnything = true; 13508 } 13509 13510 if (!printedAnything) { 13511 pw.println(" (nothing)"); 13512 } 13513 } 13514 dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)13515 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13516 int opti, boolean dumpAll, String dumpPackage) { 13517 boolean needSep; 13518 boolean printedAnything = false; 13519 13520 ItemMatcher matcher = new ItemMatcher(); 13521 matcher.build(args, opti); 13522 13523 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13524 13525 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13526 printedAnything |= needSep; 13527 13528 if (mLaunchingProviders.size() > 0) { 13529 boolean printed = false; 13530 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13531 ContentProviderRecord r = mLaunchingProviders.get(i); 13532 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13533 continue; 13534 } 13535 if (!printed) { 13536 if (needSep) pw.println(); 13537 needSep = true; 13538 pw.println(" Launching content providers:"); 13539 printed = true; 13540 printedAnything = true; 13541 } 13542 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13543 pw.println(r); 13544 } 13545 } 13546 13547 if (mGrantedUriPermissions.size() > 0) { 13548 boolean printed = false; 13549 int dumpUid = -2; 13550 if (dumpPackage != null) { 13551 try { 13552 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13553 } catch (NameNotFoundException e) { 13554 dumpUid = -1; 13555 } 13556 } 13557 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13558 int uid = mGrantedUriPermissions.keyAt(i); 13559 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13560 continue; 13561 } 13562 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13563 if (!printed) { 13564 if (needSep) pw.println(); 13565 needSep = true; 13566 pw.println(" Granted Uri Permissions:"); 13567 printed = true; 13568 printedAnything = true; 13569 } 13570 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13571 for (UriPermission perm : perms.values()) { 13572 pw.print(" "); pw.println(perm); 13573 if (dumpAll) { 13574 perm.dump(pw, " "); 13575 } 13576 } 13577 } 13578 } 13579 13580 if (!printedAnything) { 13581 pw.println(" (nothing)"); 13582 } 13583 } 13584 dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)13585 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13586 int opti, boolean dumpAll, String dumpPackage) { 13587 boolean printed = false; 13588 13589 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13590 13591 if (mIntentSenderRecords.size() > 0) { 13592 Iterator<WeakReference<PendingIntentRecord>> it 13593 = mIntentSenderRecords.values().iterator(); 13594 while (it.hasNext()) { 13595 WeakReference<PendingIntentRecord> ref = it.next(); 13596 PendingIntentRecord rec = ref != null ? ref.get(): null; 13597 if (dumpPackage != null && (rec == null 13598 || !dumpPackage.equals(rec.key.packageName))) { 13599 continue; 13600 } 13601 printed = true; 13602 if (rec != null) { 13603 pw.print(" * "); pw.println(rec); 13604 if (dumpAll) { 13605 rec.dump(pw, " "); 13606 } 13607 } else { 13608 pw.print(" * "); pw.println(ref); 13609 } 13610 } 13611 } 13612 13613 if (!printed) { 13614 pw.println(" (nothing)"); 13615 } 13616 } 13617 dumpProcessList(PrintWriter pw, ActivityManagerService service, List list, String prefix, String normalLabel, String persistentLabel, String dumpPackage)13618 private static final int dumpProcessList(PrintWriter pw, 13619 ActivityManagerService service, List list, 13620 String prefix, String normalLabel, String persistentLabel, 13621 String dumpPackage) { 13622 int numPers = 0; 13623 final int N = list.size()-1; 13624 for (int i=N; i>=0; i--) { 13625 ProcessRecord r = (ProcessRecord)list.get(i); 13626 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13627 continue; 13628 } 13629 pw.println(String.format("%s%s #%2d: %s", 13630 prefix, (r.persistent ? persistentLabel : normalLabel), 13631 i, r.toString())); 13632 if (r.persistent) { 13633 numPers++; 13634 } 13635 } 13636 return numPers; 13637 } 13638 dumpProcessOomList(PrintWriter pw, ActivityManagerService service, List<ProcessRecord> origList, String prefix, String normalLabel, String persistentLabel, boolean inclDetails, String dumpPackage)13639 private static final boolean dumpProcessOomList(PrintWriter pw, 13640 ActivityManagerService service, List<ProcessRecord> origList, 13641 String prefix, String normalLabel, String persistentLabel, 13642 boolean inclDetails, String dumpPackage) { 13643 13644 ArrayList<Pair<ProcessRecord, Integer>> list 13645 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13646 for (int i=0; i<origList.size(); i++) { 13647 ProcessRecord r = origList.get(i); 13648 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13649 continue; 13650 } 13651 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13652 } 13653 13654 if (list.size() <= 0) { 13655 return false; 13656 } 13657 13658 Comparator<Pair<ProcessRecord, Integer>> comparator 13659 = new Comparator<Pair<ProcessRecord, Integer>>() { 13660 @Override 13661 public int compare(Pair<ProcessRecord, Integer> object1, 13662 Pair<ProcessRecord, Integer> object2) { 13663 if (object1.first.setAdj != object2.first.setAdj) { 13664 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13665 } 13666 if (object1.second.intValue() != object2.second.intValue()) { 13667 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13668 } 13669 return 0; 13670 } 13671 }; 13672 13673 Collections.sort(list, comparator); 13674 13675 final long curRealtime = SystemClock.elapsedRealtime(); 13676 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13677 final long curUptime = SystemClock.uptimeMillis(); 13678 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13679 13680 for (int i=list.size()-1; i>=0; i--) { 13681 ProcessRecord r = list.get(i).first; 13682 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13683 char schedGroup; 13684 switch (r.setSchedGroup) { 13685 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13686 schedGroup = 'B'; 13687 break; 13688 case Process.THREAD_GROUP_DEFAULT: 13689 schedGroup = 'F'; 13690 break; 13691 default: 13692 schedGroup = '?'; 13693 break; 13694 } 13695 char foreground; 13696 if (r.foregroundActivities) { 13697 foreground = 'A'; 13698 } else if (r.foregroundServices) { 13699 foreground = 'S'; 13700 } else { 13701 foreground = ' '; 13702 } 13703 String procState = ProcessList.makeProcStateString(r.curProcState); 13704 pw.print(prefix); 13705 pw.print(r.persistent ? persistentLabel : normalLabel); 13706 pw.print(" #"); 13707 int num = (origList.size()-1)-list.get(i).second; 13708 if (num < 10) pw.print(' '); 13709 pw.print(num); 13710 pw.print(": "); 13711 pw.print(oomAdj); 13712 pw.print(' '); 13713 pw.print(schedGroup); 13714 pw.print('/'); 13715 pw.print(foreground); 13716 pw.print('/'); 13717 pw.print(procState); 13718 pw.print(" trm:"); 13719 if (r.trimMemoryLevel < 10) pw.print(' '); 13720 pw.print(r.trimMemoryLevel); 13721 pw.print(' '); 13722 pw.print(r.toShortString()); 13723 pw.print(" ("); 13724 pw.print(r.adjType); 13725 pw.println(')'); 13726 if (r.adjSource != null || r.adjTarget != null) { 13727 pw.print(prefix); 13728 pw.print(" "); 13729 if (r.adjTarget instanceof ComponentName) { 13730 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13731 } else if (r.adjTarget != null) { 13732 pw.print(r.adjTarget.toString()); 13733 } else { 13734 pw.print("{null}"); 13735 } 13736 pw.print("<="); 13737 if (r.adjSource instanceof ProcessRecord) { 13738 pw.print("Proc{"); 13739 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13740 pw.println("}"); 13741 } else if (r.adjSource != null) { 13742 pw.println(r.adjSource.toString()); 13743 } else { 13744 pw.println("{null}"); 13745 } 13746 } 13747 if (inclDetails) { 13748 pw.print(prefix); 13749 pw.print(" "); 13750 pw.print("oom: max="); pw.print(r.maxAdj); 13751 pw.print(" curRaw="); pw.print(r.curRawAdj); 13752 pw.print(" setRaw="); pw.print(r.setRawAdj); 13753 pw.print(" cur="); pw.print(r.curAdj); 13754 pw.print(" set="); pw.println(r.setAdj); 13755 pw.print(prefix); 13756 pw.print(" "); 13757 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13758 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13759 pw.print(" lastPss="); pw.print(r.lastPss); 13760 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13761 pw.print(prefix); 13762 pw.print(" "); 13763 pw.print("cached="); pw.print(r.cached); 13764 pw.print(" empty="); pw.print(r.empty); 13765 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13766 13767 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13768 if (r.lastWakeTime != 0) { 13769 long wtime; 13770 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13771 synchronized (stats) { 13772 wtime = stats.getProcessWakeTime(r.info.uid, 13773 r.pid, curRealtime); 13774 } 13775 long timeUsed = wtime - r.lastWakeTime; 13776 pw.print(prefix); 13777 pw.print(" "); 13778 pw.print("keep awake over "); 13779 TimeUtils.formatDuration(realtimeSince, pw); 13780 pw.print(" used "); 13781 TimeUtils.formatDuration(timeUsed, pw); 13782 pw.print(" ("); 13783 pw.print((timeUsed*100)/realtimeSince); 13784 pw.println("%)"); 13785 } 13786 if (r.lastCpuTime != 0) { 13787 long timeUsed = r.curCpuTime - r.lastCpuTime; 13788 pw.print(prefix); 13789 pw.print(" "); 13790 pw.print("run cpu over "); 13791 TimeUtils.formatDuration(uptimeSince, pw); 13792 pw.print(" used "); 13793 TimeUtils.formatDuration(timeUsed, pw); 13794 pw.print(" ("); 13795 pw.print((timeUsed*100)/uptimeSince); 13796 pw.println("%)"); 13797 } 13798 } 13799 } 13800 } 13801 return true; 13802 } 13803 collectProcesses(PrintWriter pw, int start, boolean allPkgs, String[] args)13804 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13805 String[] args) { 13806 ArrayList<ProcessRecord> procs; 13807 synchronized (this) { 13808 if (args != null && args.length > start 13809 && args[start].charAt(0) != '-') { 13810 procs = new ArrayList<ProcessRecord>(); 13811 int pid = -1; 13812 try { 13813 pid = Integer.parseInt(args[start]); 13814 } catch (NumberFormatException e) { 13815 } 13816 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13817 ProcessRecord proc = mLruProcesses.get(i); 13818 if (proc.pid == pid) { 13819 procs.add(proc); 13820 } else if (allPkgs && proc.pkgList != null 13821 && proc.pkgList.containsKey(args[start])) { 13822 procs.add(proc); 13823 } else if (proc.processName.equals(args[start])) { 13824 procs.add(proc); 13825 } 13826 } 13827 if (procs.size() <= 0) { 13828 return null; 13829 } 13830 } else { 13831 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13832 } 13833 } 13834 return procs; 13835 } 13836 dumpGraphicsHardwareUsage(FileDescriptor fd, PrintWriter pw, String[] args)13837 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13838 PrintWriter pw, String[] args) { 13839 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13840 if (procs == null) { 13841 pw.println("No process found for: " + args[0]); 13842 return; 13843 } 13844 13845 long uptime = SystemClock.uptimeMillis(); 13846 long realtime = SystemClock.elapsedRealtime(); 13847 pw.println("Applications Graphics Acceleration Info:"); 13848 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13849 13850 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13851 ProcessRecord r = procs.get(i); 13852 if (r.thread != null) { 13853 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13854 pw.flush(); 13855 try { 13856 TransferPipe tp = new TransferPipe(); 13857 try { 13858 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13859 tp.go(fd); 13860 } finally { 13861 tp.kill(); 13862 } 13863 } catch (IOException e) { 13864 pw.println("Failure while dumping the app: " + r); 13865 pw.flush(); 13866 } catch (RemoteException e) { 13867 pw.println("Got a RemoteException while dumping the app " + r); 13868 pw.flush(); 13869 } 13870 } 13871 } 13872 } 13873 dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args)13874 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13875 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13876 if (procs == null) { 13877 pw.println("No process found for: " + args[0]); 13878 return; 13879 } 13880 13881 pw.println("Applications Database Info:"); 13882 13883 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13884 ProcessRecord r = procs.get(i); 13885 if (r.thread != null) { 13886 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13887 pw.flush(); 13888 try { 13889 TransferPipe tp = new TransferPipe(); 13890 try { 13891 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13892 tp.go(fd); 13893 } finally { 13894 tp.kill(); 13895 } 13896 } catch (IOException e) { 13897 pw.println("Failure while dumping the app: " + r); 13898 pw.flush(); 13899 } catch (RemoteException e) { 13900 pw.println("Got a RemoteException while dumping the app " + r); 13901 pw.flush(); 13902 } 13903 } 13904 } 13905 } 13906 13907 final static class MemItem { 13908 final boolean isProc; 13909 final String label; 13910 final String shortLabel; 13911 final long pss; 13912 final int id; 13913 final boolean hasActivities; 13914 ArrayList<MemItem> subitems; 13915 MemItem(String _label, String _shortLabel, long _pss, int _id, boolean _hasActivities)13916 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13917 boolean _hasActivities) { 13918 isProc = true; 13919 label = _label; 13920 shortLabel = _shortLabel; 13921 pss = _pss; 13922 id = _id; 13923 hasActivities = _hasActivities; 13924 } 13925 MemItem(String _label, String _shortLabel, long _pss, int _id)13926 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13927 isProc = false; 13928 label = _label; 13929 shortLabel = _shortLabel; 13930 pss = _pss; 13931 id = _id; 13932 hasActivities = false; 13933 } 13934 } 13935 dumpMemItems(PrintWriter pw, String prefix, String tag, ArrayList<MemItem> items, boolean sort, boolean isCompact)13936 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13937 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13938 if (sort && !isCompact) { 13939 Collections.sort(items, new Comparator<MemItem>() { 13940 @Override 13941 public int compare(MemItem lhs, MemItem rhs) { 13942 if (lhs.pss < rhs.pss) { 13943 return 1; 13944 } else if (lhs.pss > rhs.pss) { 13945 return -1; 13946 } 13947 return 0; 13948 } 13949 }); 13950 } 13951 13952 for (int i=0; i<items.size(); i++) { 13953 MemItem mi = items.get(i); 13954 if (!isCompact) { 13955 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13956 } else if (mi.isProc) { 13957 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13958 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13959 pw.println(mi.hasActivities ? ",a" : ",e"); 13960 } else { 13961 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13962 pw.println(mi.pss); 13963 } 13964 if (mi.subitems != null) { 13965 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13966 true, isCompact); 13967 } 13968 } 13969 } 13970 13971 // These are in KB. 13972 static final long[] DUMP_MEM_BUCKETS = new long[] { 13973 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13974 120*1024, 160*1024, 200*1024, 13975 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13976 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13977 }; 13978 appendMemBucket(StringBuilder out, long memKB, String label, boolean stackLike)13979 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13980 boolean stackLike) { 13981 int start = label.lastIndexOf('.'); 13982 if (start >= 0) start++; 13983 else start = 0; 13984 int end = label.length(); 13985 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13986 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13987 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13988 out.append(bucket); 13989 out.append(stackLike ? "MB." : "MB "); 13990 out.append(label, start, end); 13991 return; 13992 } 13993 } 13994 out.append(memKB/1024); 13995 out.append(stackLike ? "MB." : "MB "); 13996 out.append(label, start, end); 13997 } 13998 13999 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 14000 ProcessList.NATIVE_ADJ, 14001 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 14002 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 14003 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 14004 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 14005 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 14006 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 14007 }; 14008 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 14009 "Native", 14010 "System", "Persistent", "Persistent Service", "Foreground", 14011 "Visible", "Perceptible", 14012 "Heavy Weight", "Backup", 14013 "A Services", "Home", 14014 "Previous", "B Services", "Cached" 14015 }; 14016 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 14017 "native", 14018 "sys", "pers", "persvc", "fore", 14019 "vis", "percept", 14020 "heavy", "backup", 14021 "servicea", "home", 14022 "prev", "serviceb", "cached" 14023 }; 14024 dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, long realtime, boolean isCheckinRequest, boolean isCompact)14025 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 14026 long realtime, boolean isCheckinRequest, boolean isCompact) { 14027 if (isCheckinRequest || isCompact) { 14028 // short checkin version 14029 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 14030 } else { 14031 pw.println("Applications Memory Usage (kB):"); 14032 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 14033 } 14034 } 14035 14036 private static final int KSM_SHARED = 0; 14037 private static final int KSM_SHARING = 1; 14038 private static final int KSM_UNSHARED = 2; 14039 private static final int KSM_VOLATILE = 3; 14040 getKsmInfo()14041 private final long[] getKsmInfo() { 14042 long[] longOut = new long[4]; 14043 final int[] SINGLE_LONG_FORMAT = new int[] { 14044 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14045 }; 14046 long[] longTmp = new long[1]; 14047 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14048 SINGLE_LONG_FORMAT, null, longTmp, null); 14049 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14050 longTmp[0] = 0; 14051 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14052 SINGLE_LONG_FORMAT, null, longTmp, null); 14053 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14054 longTmp[0] = 0; 14055 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14056 SINGLE_LONG_FORMAT, null, longTmp, null); 14057 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14058 longTmp[0] = 0; 14059 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14060 SINGLE_LONG_FORMAT, null, longTmp, null); 14061 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14062 return longOut; 14063 } 14064 dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw)14065 final void dumpApplicationMemoryUsage(FileDescriptor fd, 14066 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 14067 boolean dumpDetails = false; 14068 boolean dumpFullDetails = false; 14069 boolean dumpDalvik = false; 14070 boolean oomOnly = false; 14071 boolean isCompact = false; 14072 boolean localOnly = false; 14073 boolean packages = false; 14074 14075 int opti = 0; 14076 while (opti < args.length) { 14077 String opt = args[opti]; 14078 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14079 break; 14080 } 14081 opti++; 14082 if ("-a".equals(opt)) { 14083 dumpDetails = true; 14084 dumpFullDetails = true; 14085 dumpDalvik = true; 14086 } else if ("-d".equals(opt)) { 14087 dumpDalvik = true; 14088 } else if ("-c".equals(opt)) { 14089 isCompact = true; 14090 } else if ("--oom".equals(opt)) { 14091 oomOnly = true; 14092 } else if ("--local".equals(opt)) { 14093 localOnly = true; 14094 } else if ("--package".equals(opt)) { 14095 packages = true; 14096 } else if ("-h".equals(opt)) { 14097 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 14098 pw.println(" -a: include all available information for each process."); 14099 pw.println(" -d: include dalvik details when dumping process details."); 14100 pw.println(" -c: dump in a compact machine-parseable representation."); 14101 pw.println(" --oom: only show processes organized by oom adj."); 14102 pw.println(" --local: only collect details locally, don't call process."); 14103 pw.println(" --package: interpret process arg as package, dumping all"); 14104 pw.println(" processes that have loaded that package."); 14105 pw.println("If [process] is specified it can be the name or "); 14106 pw.println("pid of a specific process to dump."); 14107 return; 14108 } else { 14109 pw.println("Unknown argument: " + opt + "; use -h for help"); 14110 } 14111 } 14112 14113 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 14114 long uptime = SystemClock.uptimeMillis(); 14115 long realtime = SystemClock.elapsedRealtime(); 14116 final long[] tmpLong = new long[1]; 14117 14118 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 14119 if (procs == null) { 14120 // No Java processes. Maybe they want to print a native process. 14121 if (args != null && args.length > opti 14122 && args[opti].charAt(0) != '-') { 14123 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14124 = new ArrayList<ProcessCpuTracker.Stats>(); 14125 updateCpuStatsNow(); 14126 int findPid = -1; 14127 try { 14128 findPid = Integer.parseInt(args[opti]); 14129 } catch (NumberFormatException e) { 14130 } 14131 synchronized (mProcessCpuTracker) { 14132 final int N = mProcessCpuTracker.countStats(); 14133 for (int i=0; i<N; i++) { 14134 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14135 if (st.pid == findPid || (st.baseName != null 14136 && st.baseName.equals(args[opti]))) { 14137 nativeProcs.add(st); 14138 } 14139 } 14140 } 14141 if (nativeProcs.size() > 0) { 14142 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14143 isCompact); 14144 Debug.MemoryInfo mi = null; 14145 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14146 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14147 final int pid = r.pid; 14148 if (!isCheckinRequest && dumpDetails) { 14149 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14150 } 14151 if (mi == null) { 14152 mi = new Debug.MemoryInfo(); 14153 } 14154 if (dumpDetails || (!brief && !oomOnly)) { 14155 Debug.getMemoryInfo(pid, mi); 14156 } else { 14157 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14158 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14159 } 14160 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14161 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14162 if (isCheckinRequest) { 14163 pw.println(); 14164 } 14165 } 14166 return; 14167 } 14168 } 14169 pw.println("No process found for: " + args[opti]); 14170 return; 14171 } 14172 14173 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14174 dumpDetails = true; 14175 } 14176 14177 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14178 14179 String[] innerArgs = new String[args.length-opti]; 14180 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14181 14182 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14183 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14184 long nativePss = 0; 14185 long dalvikPss = 0; 14186 long otherPss = 0; 14187 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14188 14189 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14190 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14191 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14192 14193 long totalPss = 0; 14194 long cachedPss = 0; 14195 14196 Debug.MemoryInfo mi = null; 14197 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14198 final ProcessRecord r = procs.get(i); 14199 final IApplicationThread thread; 14200 final int pid; 14201 final int oomAdj; 14202 final boolean hasActivities; 14203 synchronized (this) { 14204 thread = r.thread; 14205 pid = r.pid; 14206 oomAdj = r.getSetAdjWithServices(); 14207 hasActivities = r.activities.size() > 0; 14208 } 14209 if (thread != null) { 14210 if (!isCheckinRequest && dumpDetails) { 14211 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14212 } 14213 if (mi == null) { 14214 mi = new Debug.MemoryInfo(); 14215 } 14216 if (dumpDetails || (!brief && !oomOnly)) { 14217 Debug.getMemoryInfo(pid, mi); 14218 } else { 14219 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14220 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14221 } 14222 if (dumpDetails) { 14223 if (localOnly) { 14224 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14225 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14226 if (isCheckinRequest) { 14227 pw.println(); 14228 } 14229 } else { 14230 try { 14231 pw.flush(); 14232 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14233 dumpDalvik, innerArgs); 14234 } catch (RemoteException e) { 14235 if (!isCheckinRequest) { 14236 pw.println("Got RemoteException!"); 14237 pw.flush(); 14238 } 14239 } 14240 } 14241 } 14242 14243 final long myTotalPss = mi.getTotalPss(); 14244 final long myTotalUss = mi.getTotalUss(); 14245 14246 synchronized (this) { 14247 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14248 // Record this for posterity if the process has been stable. 14249 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14250 } 14251 } 14252 14253 if (!isCheckinRequest && mi != null) { 14254 totalPss += myTotalPss; 14255 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14256 (hasActivities ? " / activities)" : ")"), 14257 r.processName, myTotalPss, pid, hasActivities); 14258 procMems.add(pssItem); 14259 procMemsMap.put(pid, pssItem); 14260 14261 nativePss += mi.nativePss; 14262 dalvikPss += mi.dalvikPss; 14263 otherPss += mi.otherPss; 14264 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14265 long mem = mi.getOtherPss(j); 14266 miscPss[j] += mem; 14267 otherPss -= mem; 14268 } 14269 14270 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14271 cachedPss += myTotalPss; 14272 } 14273 14274 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14275 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14276 || oomIndex == (oomPss.length-1)) { 14277 oomPss[oomIndex] += myTotalPss; 14278 if (oomProcs[oomIndex] == null) { 14279 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14280 } 14281 oomProcs[oomIndex].add(pssItem); 14282 break; 14283 } 14284 } 14285 } 14286 } 14287 } 14288 14289 long nativeProcTotalPss = 0; 14290 14291 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14292 // If we are showing aggregations, also look for native processes to 14293 // include so that our aggregations are more accurate. 14294 updateCpuStatsNow(); 14295 mi = null; 14296 synchronized (mProcessCpuTracker) { 14297 final int N = mProcessCpuTracker.countStats(); 14298 for (int i=0; i<N; i++) { 14299 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14300 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14301 if (mi == null) { 14302 mi = new Debug.MemoryInfo(); 14303 } 14304 if (!brief && !oomOnly) { 14305 Debug.getMemoryInfo(st.pid, mi); 14306 } else { 14307 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14308 mi.nativePrivateDirty = (int)tmpLong[0]; 14309 } 14310 14311 final long myTotalPss = mi.getTotalPss(); 14312 totalPss += myTotalPss; 14313 nativeProcTotalPss += myTotalPss; 14314 14315 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14316 st.name, myTotalPss, st.pid, false); 14317 procMems.add(pssItem); 14318 14319 nativePss += mi.nativePss; 14320 dalvikPss += mi.dalvikPss; 14321 otherPss += mi.otherPss; 14322 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14323 long mem = mi.getOtherPss(j); 14324 miscPss[j] += mem; 14325 otherPss -= mem; 14326 } 14327 oomPss[0] += myTotalPss; 14328 if (oomProcs[0] == null) { 14329 oomProcs[0] = new ArrayList<MemItem>(); 14330 } 14331 oomProcs[0].add(pssItem); 14332 } 14333 } 14334 } 14335 14336 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14337 14338 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14339 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14340 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14341 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14342 String label = Debug.MemoryInfo.getOtherLabel(j); 14343 catMems.add(new MemItem(label, label, miscPss[j], j)); 14344 } 14345 14346 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14347 for (int j=0; j<oomPss.length; j++) { 14348 if (oomPss[j] != 0) { 14349 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14350 : DUMP_MEM_OOM_LABEL[j]; 14351 MemItem item = new MemItem(label, label, oomPss[j], 14352 DUMP_MEM_OOM_ADJ[j]); 14353 item.subitems = oomProcs[j]; 14354 oomMems.add(item); 14355 } 14356 } 14357 14358 if (!brief && !oomOnly && !isCompact) { 14359 pw.println(); 14360 pw.println("Total PSS by process:"); 14361 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14362 pw.println(); 14363 } 14364 if (!isCompact) { 14365 pw.println("Total PSS by OOM adjustment:"); 14366 } 14367 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14368 if (!brief && !oomOnly) { 14369 PrintWriter out = categoryPw != null ? categoryPw : pw; 14370 if (!isCompact) { 14371 out.println(); 14372 out.println("Total PSS by category:"); 14373 } 14374 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14375 } 14376 if (!isCompact) { 14377 pw.println(); 14378 } 14379 MemInfoReader memInfo = new MemInfoReader(); 14380 memInfo.readMemInfo(); 14381 if (nativeProcTotalPss > 0) { 14382 synchronized (this) { 14383 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14384 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14385 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14386 } 14387 } 14388 if (!brief) { 14389 if (!isCompact) { 14390 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14391 pw.print(" kB (status "); 14392 switch (mLastMemoryLevel) { 14393 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14394 pw.println("normal)"); 14395 break; 14396 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14397 pw.println("moderate)"); 14398 break; 14399 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14400 pw.println("low)"); 14401 break; 14402 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14403 pw.println("critical)"); 14404 break; 14405 default: 14406 pw.print(mLastMemoryLevel); 14407 pw.println(")"); 14408 break; 14409 } 14410 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14411 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14412 pw.print(cachedPss); pw.print(" cached pss + "); 14413 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14414 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14415 } else { 14416 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14417 pw.print(cachedPss + memInfo.getCachedSizeKb() 14418 + memInfo.getFreeSizeKb()); pw.print(","); 14419 pw.println(totalPss - cachedPss); 14420 } 14421 } 14422 if (!isCompact) { 14423 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14424 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14425 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14426 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14427 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14428 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14429 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14430 } 14431 if (!brief) { 14432 if (memInfo.getZramTotalSizeKb() != 0) { 14433 if (!isCompact) { 14434 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14435 pw.print(" kB physical used for "); 14436 pw.print(memInfo.getSwapTotalSizeKb() 14437 - memInfo.getSwapFreeSizeKb()); 14438 pw.print(" kB in swap ("); 14439 pw.print(memInfo.getSwapTotalSizeKb()); 14440 pw.println(" kB total swap)"); 14441 } else { 14442 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14443 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14444 pw.println(memInfo.getSwapFreeSizeKb()); 14445 } 14446 } 14447 final long[] ksm = getKsmInfo(); 14448 if (!isCompact) { 14449 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14450 || ksm[KSM_VOLATILE] != 0) { 14451 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14452 pw.print(" kB saved from shared "); 14453 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14454 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14455 pw.print(" kB unshared; "); 14456 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14457 } 14458 pw.print(" Tuning: "); 14459 pw.print(ActivityManager.staticGetMemoryClass()); 14460 pw.print(" (large "); 14461 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14462 pw.print("), oom "); 14463 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14464 pw.print(" kB"); 14465 pw.print(", restore limit "); 14466 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14467 pw.print(" kB"); 14468 if (ActivityManager.isLowRamDeviceStatic()) { 14469 pw.print(" (low-ram)"); 14470 } 14471 if (ActivityManager.isHighEndGfx()) { 14472 pw.print(" (high-end-gfx)"); 14473 } 14474 pw.println(); 14475 } else { 14476 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14477 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14478 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14479 pw.print("tuning,"); 14480 pw.print(ActivityManager.staticGetMemoryClass()); 14481 pw.print(','); 14482 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14483 pw.print(','); 14484 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14485 if (ActivityManager.isLowRamDeviceStatic()) { 14486 pw.print(",low-ram"); 14487 } 14488 if (ActivityManager.isHighEndGfx()) { 14489 pw.print(",high-end-gfx"); 14490 } 14491 pw.println(); 14492 } 14493 } 14494 } 14495 } 14496 appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, long memtrack, String name)14497 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14498 long memtrack, String name) { 14499 sb.append(" "); 14500 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14501 sb.append(' '); 14502 sb.append(ProcessList.makeProcStateString(procState)); 14503 sb.append(' '); 14504 ProcessList.appendRamKb(sb, pss); 14505 sb.append(" kB: "); 14506 sb.append(name); 14507 if (memtrack > 0) { 14508 sb.append(" ("); 14509 sb.append(memtrack); 14510 sb.append(" kB memtrack)"); 14511 } 14512 } 14513 appendMemInfo(StringBuilder sb, ProcessMemInfo mi)14514 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14515 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14516 sb.append(" (pid "); 14517 sb.append(mi.pid); 14518 sb.append(") "); 14519 sb.append(mi.adjType); 14520 sb.append('\n'); 14521 if (mi.adjReason != null) { 14522 sb.append(" "); 14523 sb.append(mi.adjReason); 14524 sb.append('\n'); 14525 } 14526 } 14527 reportMemUsage(ArrayList<ProcessMemInfo> memInfos)14528 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14529 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14530 for (int i=0, N=memInfos.size(); i<N; i++) { 14531 ProcessMemInfo mi = memInfos.get(i); 14532 infoMap.put(mi.pid, mi); 14533 } 14534 updateCpuStatsNow(); 14535 long[] memtrackTmp = new long[1]; 14536 synchronized (mProcessCpuTracker) { 14537 final int N = mProcessCpuTracker.countStats(); 14538 for (int i=0; i<N; i++) { 14539 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14540 if (st.vsize > 0) { 14541 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14542 if (pss > 0) { 14543 if (infoMap.indexOfKey(st.pid) < 0) { 14544 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14545 ProcessList.NATIVE_ADJ, -1, "native", null); 14546 mi.pss = pss; 14547 mi.memtrack = memtrackTmp[0]; 14548 memInfos.add(mi); 14549 } 14550 } 14551 } 14552 } 14553 } 14554 14555 long totalPss = 0; 14556 long totalMemtrack = 0; 14557 for (int i=0, N=memInfos.size(); i<N; i++) { 14558 ProcessMemInfo mi = memInfos.get(i); 14559 if (mi.pss == 0) { 14560 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14561 mi.memtrack = memtrackTmp[0]; 14562 } 14563 totalPss += mi.pss; 14564 totalMemtrack += mi.memtrack; 14565 } 14566 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14567 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14568 if (lhs.oomAdj != rhs.oomAdj) { 14569 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14570 } 14571 if (lhs.pss != rhs.pss) { 14572 return lhs.pss < rhs.pss ? 1 : -1; 14573 } 14574 return 0; 14575 } 14576 }); 14577 14578 StringBuilder tag = new StringBuilder(128); 14579 StringBuilder stack = new StringBuilder(128); 14580 tag.append("Low on memory -- "); 14581 appendMemBucket(tag, totalPss, "total", false); 14582 appendMemBucket(stack, totalPss, "total", true); 14583 14584 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14585 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14586 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14587 14588 boolean firstLine = true; 14589 int lastOomAdj = Integer.MIN_VALUE; 14590 long extraNativeRam = 0; 14591 long extraNativeMemtrack = 0; 14592 long cachedPss = 0; 14593 for (int i=0, N=memInfos.size(); i<N; i++) { 14594 ProcessMemInfo mi = memInfos.get(i); 14595 14596 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14597 cachedPss += mi.pss; 14598 } 14599 14600 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14601 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14602 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14603 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14604 if (lastOomAdj != mi.oomAdj) { 14605 lastOomAdj = mi.oomAdj; 14606 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14607 tag.append(" / "); 14608 } 14609 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14610 if (firstLine) { 14611 stack.append(":"); 14612 firstLine = false; 14613 } 14614 stack.append("\n\t at "); 14615 } else { 14616 stack.append("$"); 14617 } 14618 } else { 14619 tag.append(" "); 14620 stack.append("$"); 14621 } 14622 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14623 appendMemBucket(tag, mi.pss, mi.name, false); 14624 } 14625 appendMemBucket(stack, mi.pss, mi.name, true); 14626 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14627 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14628 stack.append("("); 14629 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14630 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14631 stack.append(DUMP_MEM_OOM_LABEL[k]); 14632 stack.append(":"); 14633 stack.append(DUMP_MEM_OOM_ADJ[k]); 14634 } 14635 } 14636 stack.append(")"); 14637 } 14638 } 14639 14640 appendMemInfo(fullNativeBuilder, mi); 14641 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14642 // The short form only has native processes that are >= 512K. 14643 if (mi.pss >= 512) { 14644 appendMemInfo(shortNativeBuilder, mi); 14645 } else { 14646 extraNativeRam += mi.pss; 14647 extraNativeMemtrack += mi.memtrack; 14648 } 14649 } else { 14650 // Short form has all other details, but if we have collected RAM 14651 // from smaller native processes let's dump a summary of that. 14652 if (extraNativeRam > 0) { 14653 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14654 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14655 shortNativeBuilder.append('\n'); 14656 extraNativeRam = 0; 14657 } 14658 appendMemInfo(fullJavaBuilder, mi); 14659 } 14660 } 14661 14662 fullJavaBuilder.append(" "); 14663 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14664 fullJavaBuilder.append(" kB: TOTAL"); 14665 if (totalMemtrack > 0) { 14666 fullJavaBuilder.append(" ("); 14667 fullJavaBuilder.append(totalMemtrack); 14668 fullJavaBuilder.append(" kB memtrack)"); 14669 } else { 14670 } 14671 fullJavaBuilder.append("\n"); 14672 14673 MemInfoReader memInfo = new MemInfoReader(); 14674 memInfo.readMemInfo(); 14675 final long[] infos = memInfo.getRawInfo(); 14676 14677 StringBuilder memInfoBuilder = new StringBuilder(1024); 14678 Debug.getMemInfo(infos); 14679 memInfoBuilder.append(" MemInfo: "); 14680 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14681 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14682 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14683 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14684 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14685 memInfoBuilder.append(" "); 14686 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14687 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14688 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14689 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14690 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14691 memInfoBuilder.append(" ZRAM: "); 14692 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14693 memInfoBuilder.append(" kB RAM, "); 14694 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14695 memInfoBuilder.append(" kB swap total, "); 14696 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14697 memInfoBuilder.append(" kB swap free\n"); 14698 } 14699 final long[] ksm = getKsmInfo(); 14700 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14701 || ksm[KSM_VOLATILE] != 0) { 14702 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14703 memInfoBuilder.append(" kB saved from shared "); 14704 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14705 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14706 memInfoBuilder.append(" kB unshared; "); 14707 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14708 } 14709 memInfoBuilder.append(" Free RAM: "); 14710 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14711 + memInfo.getFreeSizeKb()); 14712 memInfoBuilder.append(" kB\n"); 14713 memInfoBuilder.append(" Used RAM: "); 14714 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14715 memInfoBuilder.append(" kB\n"); 14716 memInfoBuilder.append(" Lost RAM: "); 14717 memInfoBuilder.append(memInfo.getTotalSizeKb() 14718 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14719 - memInfo.getKernelUsedSizeKb()); 14720 memInfoBuilder.append(" kB\n"); 14721 Slog.i(TAG, "Low on memory:"); 14722 Slog.i(TAG, shortNativeBuilder.toString()); 14723 Slog.i(TAG, fullJavaBuilder.toString()); 14724 Slog.i(TAG, memInfoBuilder.toString()); 14725 14726 StringBuilder dropBuilder = new StringBuilder(1024); 14727 /* 14728 StringWriter oomSw = new StringWriter(); 14729 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14730 StringWriter catSw = new StringWriter(); 14731 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14732 String[] emptyArgs = new String[] { }; 14733 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14734 oomPw.flush(); 14735 String oomString = oomSw.toString(); 14736 */ 14737 dropBuilder.append("Low on memory:"); 14738 dropBuilder.append(stack); 14739 dropBuilder.append('\n'); 14740 dropBuilder.append(fullNativeBuilder); 14741 dropBuilder.append(fullJavaBuilder); 14742 dropBuilder.append('\n'); 14743 dropBuilder.append(memInfoBuilder); 14744 dropBuilder.append('\n'); 14745 /* 14746 dropBuilder.append(oomString); 14747 dropBuilder.append('\n'); 14748 */ 14749 StringWriter catSw = new StringWriter(); 14750 synchronized (ActivityManagerService.this) { 14751 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14752 String[] emptyArgs = new String[] { }; 14753 catPw.println(); 14754 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14755 catPw.println(); 14756 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14757 false, false, null); 14758 catPw.println(); 14759 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14760 catPw.flush(); 14761 } 14762 dropBuilder.append(catSw.toString()); 14763 addErrorToDropBox("lowmem", null, "system_server", null, 14764 null, tag.toString(), dropBuilder.toString(), null, null); 14765 //Slog.i(TAG, "Sent to dropbox:"); 14766 //Slog.i(TAG, dropBuilder.toString()); 14767 synchronized (ActivityManagerService.this) { 14768 long now = SystemClock.uptimeMillis(); 14769 if (mLastMemUsageReportTime < now) { 14770 mLastMemUsageReportTime = now; 14771 } 14772 } 14773 } 14774 14775 /** 14776 * Searches array of arguments for the specified string 14777 * @param args array of argument strings 14778 * @param value value to search for 14779 * @return true if the value is contained in the array 14780 */ scanArgs(String[] args, String value)14781 private static boolean scanArgs(String[] args, String value) { 14782 if (args != null) { 14783 for (String arg : args) { 14784 if (value.equals(arg)) { 14785 return true; 14786 } 14787 } 14788 } 14789 return false; 14790 } 14791 removeDyingProviderLocked(ProcessRecord proc, ContentProviderRecord cpr, boolean always)14792 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14793 ContentProviderRecord cpr, boolean always) { 14794 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14795 14796 if (!inLaunching || always) { 14797 synchronized (cpr) { 14798 cpr.launchingApp = null; 14799 cpr.notifyAll(); 14800 } 14801 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14802 String names[] = cpr.info.authority.split(";"); 14803 for (int j = 0; j < names.length; j++) { 14804 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14805 } 14806 } 14807 14808 for (int i=0; i<cpr.connections.size(); i++) { 14809 ContentProviderConnection conn = cpr.connections.get(i); 14810 if (conn.waiting) { 14811 // If this connection is waiting for the provider, then we don't 14812 // need to mess with its process unless we are always removing 14813 // or for some reason the provider is not currently launching. 14814 if (inLaunching && !always) { 14815 continue; 14816 } 14817 } 14818 ProcessRecord capp = conn.client; 14819 conn.dead = true; 14820 if (conn.stableCount > 0) { 14821 if (!capp.persistent && capp.thread != null 14822 && capp.pid != 0 14823 && capp.pid != MY_PID) { 14824 capp.kill("depends on provider " 14825 + cpr.name.flattenToShortString() 14826 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14827 } 14828 } else if (capp.thread != null && conn.provider.provider != null) { 14829 try { 14830 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14831 } catch (RemoteException e) { 14832 } 14833 // In the protocol here, we don't expect the client to correctly 14834 // clean up this connection, we'll just remove it. 14835 cpr.connections.remove(i); 14836 if (conn.client.conProviders.remove(conn)) { 14837 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 14838 } 14839 } 14840 } 14841 14842 if (inLaunching && always) { 14843 mLaunchingProviders.remove(cpr); 14844 } 14845 return inLaunching; 14846 } 14847 14848 /** 14849 * Main code for cleaning up a process when it has gone away. This is 14850 * called both as a result of the process dying, or directly when stopping 14851 * a process when running in single process mode. 14852 * 14853 * @return Returns true if the given process has been restarted, so the 14854 * app that was passed in must remain on the process lists. 14855 */ cleanUpApplicationRecordLocked(ProcessRecord app, boolean restarting, boolean allowRestart, int index)14856 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14857 boolean restarting, boolean allowRestart, int index) { 14858 if (index >= 0) { 14859 removeLruProcessLocked(app); 14860 ProcessList.remove(app.pid); 14861 } 14862 14863 mProcessesToGc.remove(app); 14864 mPendingPssProcesses.remove(app); 14865 14866 // Dismiss any open dialogs. 14867 if (app.crashDialog != null && !app.forceCrashReport) { 14868 app.crashDialog.dismiss(); 14869 app.crashDialog = null; 14870 } 14871 if (app.anrDialog != null) { 14872 app.anrDialog.dismiss(); 14873 app.anrDialog = null; 14874 } 14875 if (app.waitDialog != null) { 14876 app.waitDialog.dismiss(); 14877 app.waitDialog = null; 14878 } 14879 14880 app.crashing = false; 14881 app.notResponding = false; 14882 14883 app.resetPackageList(mProcessStats); 14884 app.unlinkDeathRecipient(); 14885 app.makeInactive(mProcessStats); 14886 app.waitingToKill = null; 14887 app.forcingToForeground = null; 14888 updateProcessForegroundLocked(app, false, false); 14889 app.foregroundActivities = false; 14890 app.hasShownUi = false; 14891 app.treatLikeActivity = false; 14892 app.hasAboveClient = false; 14893 app.hasClientActivities = false; 14894 14895 mServices.killServicesLocked(app, allowRestart); 14896 14897 boolean restart = false; 14898 14899 // Remove published content providers. 14900 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14901 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14902 final boolean always = app.bad || !allowRestart; 14903 if (removeDyingProviderLocked(app, cpr, always) || always) { 14904 // We left the provider in the launching list, need to 14905 // restart it. 14906 restart = true; 14907 } 14908 14909 cpr.provider = null; 14910 cpr.proc = null; 14911 } 14912 app.pubProviders.clear(); 14913 14914 // Take care of any launching providers waiting for this process. 14915 if (checkAppInLaunchingProvidersLocked(app, false)) { 14916 restart = true; 14917 } 14918 14919 // Unregister from connected content providers. 14920 if (!app.conProviders.isEmpty()) { 14921 for (int i=0; i<app.conProviders.size(); i++) { 14922 ContentProviderConnection conn = app.conProviders.get(i); 14923 conn.provider.connections.remove(conn); 14924 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 14925 conn.provider.name); 14926 } 14927 app.conProviders.clear(); 14928 } 14929 14930 // At this point there may be remaining entries in mLaunchingProviders 14931 // where we were the only one waiting, so they are no longer of use. 14932 // Look for these and clean up if found. 14933 // XXX Commented out for now. Trying to figure out a way to reproduce 14934 // the actual situation to identify what is actually going on. 14935 if (false) { 14936 for (int i=0; i<mLaunchingProviders.size(); i++) { 14937 ContentProviderRecord cpr = (ContentProviderRecord) 14938 mLaunchingProviders.get(i); 14939 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14940 synchronized (cpr) { 14941 cpr.launchingApp = null; 14942 cpr.notifyAll(); 14943 } 14944 } 14945 } 14946 } 14947 14948 skipCurrentReceiverLocked(app); 14949 14950 // Unregister any receivers. 14951 for (int i=app.receivers.size()-1; i>=0; i--) { 14952 removeReceiverLocked(app.receivers.valueAt(i)); 14953 } 14954 app.receivers.clear(); 14955 14956 // If the app is undergoing backup, tell the backup manager about it 14957 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14958 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14959 + mBackupTarget.appInfo + " died during backup"); 14960 try { 14961 IBackupManager bm = IBackupManager.Stub.asInterface( 14962 ServiceManager.getService(Context.BACKUP_SERVICE)); 14963 bm.agentDisconnected(app.info.packageName); 14964 } catch (RemoteException e) { 14965 // can't happen; backup manager is local 14966 } 14967 } 14968 14969 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14970 ProcessChangeItem item = mPendingProcessChanges.get(i); 14971 if (item.pid == app.pid) { 14972 mPendingProcessChanges.remove(i); 14973 mAvailProcessChanges.add(item); 14974 } 14975 } 14976 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14977 14978 // If the caller is restarting this app, then leave it in its 14979 // current lists and let the caller take care of it. 14980 if (restarting) { 14981 return false; 14982 } 14983 14984 if (!app.persistent || app.isolated) { 14985 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14986 "Removing non-persistent process during cleanup: " + app); 14987 mProcessNames.remove(app.processName, app.uid); 14988 mIsolatedProcesses.remove(app.uid); 14989 if (mHeavyWeightProcess == app) { 14990 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14991 mHeavyWeightProcess.userId, 0)); 14992 mHeavyWeightProcess = null; 14993 } 14994 } else if (!app.removed) { 14995 // This app is persistent, so we need to keep its record around. 14996 // If it is not already on the pending app list, add it there 14997 // and start a new process for it. 14998 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14999 mPersistentStartingProcesses.add(app); 15000 restart = true; 15001 } 15002 } 15003 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 15004 "Clean-up removing on hold: " + app); 15005 mProcessesOnHold.remove(app); 15006 15007 if (app == mHomeProcess) { 15008 mHomeProcess = null; 15009 } 15010 if (app == mPreviousProcess) { 15011 mPreviousProcess = null; 15012 } 15013 15014 if (restart && !app.isolated) { 15015 // We have components that still need to be running in the 15016 // process, so re-launch it. 15017 if (index < 0) { 15018 ProcessList.remove(app.pid); 15019 } 15020 mProcessNames.put(app.processName, app.uid, app); 15021 startProcessLocked(app, "restart", app.processName); 15022 return true; 15023 } else if (app.pid > 0 && app.pid != MY_PID) { 15024 // Goodbye! 15025 boolean removed; 15026 synchronized (mPidsSelfLocked) { 15027 mPidsSelfLocked.remove(app.pid); 15028 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 15029 } 15030 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 15031 if (app.isolated) { 15032 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 15033 } 15034 app.setPid(0); 15035 } 15036 return false; 15037 } 15038 checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad)15039 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 15040 // Look through the content providers we are waiting to have launched, 15041 // and if any run in this process then either schedule a restart of 15042 // the process or kill the client waiting for it if this process has 15043 // gone bad. 15044 int NL = mLaunchingProviders.size(); 15045 boolean restart = false; 15046 for (int i=0; i<NL; i++) { 15047 ContentProviderRecord cpr = mLaunchingProviders.get(i); 15048 if (cpr.launchingApp == app) { 15049 if (!alwaysBad && !app.bad) { 15050 restart = true; 15051 } else { 15052 removeDyingProviderLocked(app, cpr, true); 15053 // cpr should have been removed from mLaunchingProviders 15054 NL = mLaunchingProviders.size(); 15055 i--; 15056 } 15057 } 15058 } 15059 return restart; 15060 } 15061 15062 // ========================================================= 15063 // SERVICES 15064 // ========================================================= 15065 15066 @Override getServices(int maxNum, int flags)15067 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 15068 int flags) { 15069 enforceNotIsolatedCaller("getServices"); 15070 synchronized (this) { 15071 return mServices.getRunningServiceInfoLocked(maxNum, flags); 15072 } 15073 } 15074 15075 @Override getRunningServiceControlPanel(ComponentName name)15076 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 15077 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 15078 synchronized (this) { 15079 return mServices.getRunningServiceControlPanelLocked(name); 15080 } 15081 } 15082 15083 @Override startService(IApplicationThread caller, Intent service, String resolvedType, int userId)15084 public ComponentName startService(IApplicationThread caller, Intent service, 15085 String resolvedType, int userId) { 15086 enforceNotIsolatedCaller("startService"); 15087 // Refuse possible leaked file descriptors 15088 if (service != null && service.hasFileDescriptors() == true) { 15089 throw new IllegalArgumentException("File descriptors passed in Intent"); 15090 } 15091 15092 if (DEBUG_SERVICE) 15093 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 15094 synchronized(this) { 15095 final int callingPid = Binder.getCallingPid(); 15096 final int callingUid = Binder.getCallingUid(); 15097 final long origId = Binder.clearCallingIdentity(); 15098 ComponentName res = mServices.startServiceLocked(caller, service, 15099 resolvedType, callingPid, callingUid, userId); 15100 Binder.restoreCallingIdentity(origId); 15101 return res; 15102 } 15103 } 15104 startServiceInPackage(int uid, Intent service, String resolvedType, int userId)15105 ComponentName startServiceInPackage(int uid, 15106 Intent service, String resolvedType, int userId) { 15107 synchronized(this) { 15108 if (DEBUG_SERVICE) 15109 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 15110 final long origId = Binder.clearCallingIdentity(); 15111 ComponentName res = mServices.startServiceLocked(null, service, 15112 resolvedType, -1, uid, userId); 15113 Binder.restoreCallingIdentity(origId); 15114 return res; 15115 } 15116 } 15117 15118 @Override stopService(IApplicationThread caller, Intent service, String resolvedType, int userId)15119 public int stopService(IApplicationThread caller, Intent service, 15120 String resolvedType, int userId) { 15121 enforceNotIsolatedCaller("stopService"); 15122 // Refuse possible leaked file descriptors 15123 if (service != null && service.hasFileDescriptors() == true) { 15124 throw new IllegalArgumentException("File descriptors passed in Intent"); 15125 } 15126 15127 synchronized(this) { 15128 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 15129 } 15130 } 15131 15132 @Override peekService(Intent service, String resolvedType)15133 public IBinder peekService(Intent service, String resolvedType) { 15134 enforceNotIsolatedCaller("peekService"); 15135 // Refuse possible leaked file descriptors 15136 if (service != null && service.hasFileDescriptors() == true) { 15137 throw new IllegalArgumentException("File descriptors passed in Intent"); 15138 } 15139 synchronized(this) { 15140 return mServices.peekServiceLocked(service, resolvedType); 15141 } 15142 } 15143 15144 @Override stopServiceToken(ComponentName className, IBinder token, int startId)15145 public boolean stopServiceToken(ComponentName className, IBinder token, 15146 int startId) { 15147 synchronized(this) { 15148 return mServices.stopServiceTokenLocked(className, token, startId); 15149 } 15150 } 15151 15152 @Override setServiceForeground(ComponentName className, IBinder token, int id, Notification notification, boolean removeNotification)15153 public void setServiceForeground(ComponentName className, IBinder token, 15154 int id, Notification notification, boolean removeNotification) { 15155 synchronized(this) { 15156 mServices.setServiceForegroundLocked(className, token, id, notification, 15157 removeNotification); 15158 } 15159 } 15160 15161 @Override handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, boolean requireFull, String name, String callerPackage)15162 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15163 boolean requireFull, String name, String callerPackage) { 15164 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15165 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15166 } 15167 unsafeConvertIncomingUser(int userId)15168 int unsafeConvertIncomingUser(int userId) { 15169 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15170 ? mCurrentUserId : userId; 15171 } 15172 handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, int allowMode, String name, String callerPackage)15173 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15174 int allowMode, String name, String callerPackage) { 15175 final int callingUserId = UserHandle.getUserId(callingUid); 15176 if (callingUserId == userId) { 15177 return userId; 15178 } 15179 15180 // Note that we may be accessing mCurrentUserId outside of a lock... 15181 // shouldn't be a big deal, if this is being called outside 15182 // of a locked context there is intrinsically a race with 15183 // the value the caller will receive and someone else changing it. 15184 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15185 // we will switch to the calling user if access to the current user fails. 15186 int targetUserId = unsafeConvertIncomingUser(userId); 15187 15188 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15189 final boolean allow; 15190 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15191 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15192 // If the caller has this permission, they always pass go. And collect $200. 15193 allow = true; 15194 } else if (allowMode == ALLOW_FULL_ONLY) { 15195 // We require full access, sucks to be you. 15196 allow = false; 15197 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15198 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15199 // If the caller does not have either permission, they are always doomed. 15200 allow = false; 15201 } else if (allowMode == ALLOW_NON_FULL) { 15202 // We are blanket allowing non-full access, you lucky caller! 15203 allow = true; 15204 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15205 // We may or may not allow this depending on whether the two users are 15206 // in the same profile. 15207 synchronized (mUserProfileGroupIdsSelfLocked) { 15208 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15209 UserInfo.NO_PROFILE_GROUP_ID); 15210 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15211 UserInfo.NO_PROFILE_GROUP_ID); 15212 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15213 && callingProfile == targetProfile; 15214 } 15215 } else { 15216 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15217 } 15218 if (!allow) { 15219 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15220 // In this case, they would like to just execute as their 15221 // owner user instead of failing. 15222 targetUserId = callingUserId; 15223 } else { 15224 StringBuilder builder = new StringBuilder(128); 15225 builder.append("Permission Denial: "); 15226 builder.append(name); 15227 if (callerPackage != null) { 15228 builder.append(" from "); 15229 builder.append(callerPackage); 15230 } 15231 builder.append(" asks to run as user "); 15232 builder.append(userId); 15233 builder.append(" but is calling from user "); 15234 builder.append(UserHandle.getUserId(callingUid)); 15235 builder.append("; this requires "); 15236 builder.append(INTERACT_ACROSS_USERS_FULL); 15237 if (allowMode != ALLOW_FULL_ONLY) { 15238 builder.append(" or "); 15239 builder.append(INTERACT_ACROSS_USERS); 15240 } 15241 String msg = builder.toString(); 15242 Slog.w(TAG, msg); 15243 throw new SecurityException(msg); 15244 } 15245 } 15246 } 15247 if (!allowAll && targetUserId < 0) { 15248 throw new IllegalArgumentException( 15249 "Call does not support special user #" + targetUserId); 15250 } 15251 // Check shell permission 15252 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15253 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15254 targetUserId)) { 15255 throw new SecurityException("Shell does not have permission to access user " 15256 + targetUserId + "\n " + Debug.getCallers(3)); 15257 } 15258 } 15259 return targetUserId; 15260 } 15261 isSingleton(String componentProcessName, ApplicationInfo aInfo, String className, int flags)15262 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15263 String className, int flags) { 15264 boolean result = false; 15265 // For apps that don't have pre-defined UIDs, check for permission 15266 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15267 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15268 if (ActivityManager.checkUidPermission( 15269 INTERACT_ACROSS_USERS, 15270 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15271 ComponentName comp = new ComponentName(aInfo.packageName, className); 15272 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15273 + " requests FLAG_SINGLE_USER, but app does not hold " 15274 + INTERACT_ACROSS_USERS; 15275 Slog.w(TAG, msg); 15276 throw new SecurityException(msg); 15277 } 15278 // Permission passed 15279 result = true; 15280 } 15281 } else if ("system".equals(componentProcessName)) { 15282 result = true; 15283 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15284 // Phone app and persistent apps are allowed to export singleuser providers. 15285 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15286 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15287 } 15288 if (DEBUG_MU) { 15289 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15290 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15291 } 15292 return result; 15293 } 15294 15295 /** 15296 * Checks to see if the caller is in the same app as the singleton 15297 * component, or the component is in a special app. It allows special apps 15298 * to export singleton components but prevents exporting singleton 15299 * components for regular apps. 15300 */ isValidSingletonCall(int callingUid, int componentUid)15301 boolean isValidSingletonCall(int callingUid, int componentUid) { 15302 int componentAppId = UserHandle.getAppId(componentUid); 15303 return UserHandle.isSameApp(callingUid, componentUid) 15304 || componentAppId == Process.SYSTEM_UID 15305 || componentAppId == Process.PHONE_UID 15306 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15307 == PackageManager.PERMISSION_GRANTED; 15308 } 15309 bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId)15310 public int bindService(IApplicationThread caller, IBinder token, 15311 Intent service, String resolvedType, 15312 IServiceConnection connection, int flags, int userId) { 15313 enforceNotIsolatedCaller("bindService"); 15314 15315 // Refuse possible leaked file descriptors 15316 if (service != null && service.hasFileDescriptors() == true) { 15317 throw new IllegalArgumentException("File descriptors passed in Intent"); 15318 } 15319 15320 synchronized(this) { 15321 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15322 connection, flags, userId); 15323 } 15324 } 15325 unbindService(IServiceConnection connection)15326 public boolean unbindService(IServiceConnection connection) { 15327 synchronized (this) { 15328 return mServices.unbindServiceLocked(connection); 15329 } 15330 } 15331 publishService(IBinder token, Intent intent, IBinder service)15332 public void publishService(IBinder token, Intent intent, IBinder service) { 15333 // Refuse possible leaked file descriptors 15334 if (intent != null && intent.hasFileDescriptors() == true) { 15335 throw new IllegalArgumentException("File descriptors passed in Intent"); 15336 } 15337 15338 synchronized(this) { 15339 if (!(token instanceof ServiceRecord)) { 15340 throw new IllegalArgumentException("Invalid service token"); 15341 } 15342 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15343 } 15344 } 15345 unbindFinished(IBinder token, Intent intent, boolean doRebind)15346 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15347 // Refuse possible leaked file descriptors 15348 if (intent != null && intent.hasFileDescriptors() == true) { 15349 throw new IllegalArgumentException("File descriptors passed in Intent"); 15350 } 15351 15352 synchronized(this) { 15353 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15354 } 15355 } 15356 serviceDoneExecuting(IBinder token, int type, int startId, int res)15357 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15358 synchronized(this) { 15359 if (!(token instanceof ServiceRecord)) { 15360 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 15361 throw new IllegalArgumentException("Invalid service token"); 15362 } 15363 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15364 } 15365 } 15366 15367 // ========================================================= 15368 // BACKUP AND RESTORE 15369 // ========================================================= 15370 15371 // Cause the target app to be launched if necessary and its backup agent 15372 // instantiated. The backup agent will invoke backupAgentCreated() on the 15373 // activity manager to announce its creation. bindBackupAgent(ApplicationInfo app, int backupMode)15374 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15375 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15376 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15377 15378 synchronized(this) { 15379 // !!! TODO: currently no check here that we're already bound 15380 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15381 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15382 synchronized (stats) { 15383 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15384 } 15385 15386 // Backup agent is now in use, its package can't be stopped. 15387 try { 15388 AppGlobals.getPackageManager().setPackageStoppedState( 15389 app.packageName, false, UserHandle.getUserId(app.uid)); 15390 } catch (RemoteException e) { 15391 } catch (IllegalArgumentException e) { 15392 Slog.w(TAG, "Failed trying to unstop package " 15393 + app.packageName + ": " + e); 15394 } 15395 15396 BackupRecord r = new BackupRecord(ss, app, backupMode); 15397 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15398 ? new ComponentName(app.packageName, app.backupAgentName) 15399 : new ComponentName("android", "FullBackupAgent"); 15400 // startProcessLocked() returns existing proc's record if it's already running 15401 ProcessRecord proc = startProcessLocked(app.processName, app, 15402 false, 0, "backup", hostingName, false, false, false); 15403 if (proc == null) { 15404 Slog.e(TAG, "Unable to start backup agent process " + r); 15405 return false; 15406 } 15407 15408 r.app = proc; 15409 mBackupTarget = r; 15410 mBackupAppName = app.packageName; 15411 15412 // Try not to kill the process during backup 15413 updateOomAdjLocked(proc); 15414 15415 // If the process is already attached, schedule the creation of the backup agent now. 15416 // If it is not yet live, this will be done when it attaches to the framework. 15417 if (proc.thread != null) { 15418 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15419 try { 15420 proc.thread.scheduleCreateBackupAgent(app, 15421 compatibilityInfoForPackageLocked(app), backupMode); 15422 } catch (RemoteException e) { 15423 // Will time out on the backup manager side 15424 } 15425 } else { 15426 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15427 } 15428 // Invariants: at this point, the target app process exists and the application 15429 // is either already running or in the process of coming up. mBackupTarget and 15430 // mBackupAppName describe the app, so that when it binds back to the AM we 15431 // know that it's scheduled for a backup-agent operation. 15432 } 15433 15434 return true; 15435 } 15436 15437 @Override clearPendingBackup()15438 public void clearPendingBackup() { 15439 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15440 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15441 15442 synchronized (this) { 15443 mBackupTarget = null; 15444 mBackupAppName = null; 15445 } 15446 } 15447 15448 // A backup agent has just come up backupAgentCreated(String agentPackageName, IBinder agent)15449 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15450 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15451 + " = " + agent); 15452 15453 synchronized(this) { 15454 if (!agentPackageName.equals(mBackupAppName)) { 15455 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15456 return; 15457 } 15458 } 15459 15460 long oldIdent = Binder.clearCallingIdentity(); 15461 try { 15462 IBackupManager bm = IBackupManager.Stub.asInterface( 15463 ServiceManager.getService(Context.BACKUP_SERVICE)); 15464 bm.agentConnected(agentPackageName, agent); 15465 } catch (RemoteException e) { 15466 // can't happen; the backup manager service is local 15467 } catch (Exception e) { 15468 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15469 e.printStackTrace(); 15470 } finally { 15471 Binder.restoreCallingIdentity(oldIdent); 15472 } 15473 } 15474 15475 // done with this agent unbindBackupAgent(ApplicationInfo appInfo)15476 public void unbindBackupAgent(ApplicationInfo appInfo) { 15477 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15478 if (appInfo == null) { 15479 Slog.w(TAG, "unbind backup agent for null app"); 15480 return; 15481 } 15482 15483 synchronized(this) { 15484 try { 15485 if (mBackupAppName == null) { 15486 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15487 return; 15488 } 15489 15490 if (!mBackupAppName.equals(appInfo.packageName)) { 15491 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15492 return; 15493 } 15494 15495 // Not backing this app up any more; reset its OOM adjustment 15496 final ProcessRecord proc = mBackupTarget.app; 15497 updateOomAdjLocked(proc); 15498 15499 // If the app crashed during backup, 'thread' will be null here 15500 if (proc.thread != null) { 15501 try { 15502 proc.thread.scheduleDestroyBackupAgent(appInfo, 15503 compatibilityInfoForPackageLocked(appInfo)); 15504 } catch (Exception e) { 15505 Slog.e(TAG, "Exception when unbinding backup agent:"); 15506 e.printStackTrace(); 15507 } 15508 } 15509 } finally { 15510 mBackupTarget = null; 15511 mBackupAppName = null; 15512 } 15513 } 15514 } 15515 // ========================================================= 15516 // BROADCASTS 15517 // ========================================================= 15518 getStickiesLocked(String action, IntentFilter filter, List cur, int userId)15519 private final List getStickiesLocked(String action, IntentFilter filter, 15520 List cur, int userId) { 15521 final ContentResolver resolver = mContext.getContentResolver(); 15522 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15523 if (stickies == null) { 15524 return cur; 15525 } 15526 final ArrayList<Intent> list = stickies.get(action); 15527 if (list == null) { 15528 return cur; 15529 } 15530 int N = list.size(); 15531 for (int i=0; i<N; i++) { 15532 Intent intent = list.get(i); 15533 if (filter.match(resolver, intent, true, TAG) >= 0) { 15534 if (cur == null) { 15535 cur = new ArrayList<Intent>(); 15536 } 15537 cur.add(intent); 15538 } 15539 } 15540 return cur; 15541 } 15542 isPendingBroadcastProcessLocked(int pid)15543 boolean isPendingBroadcastProcessLocked(int pid) { 15544 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15545 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15546 } 15547 skipPendingBroadcastLocked(int pid)15548 void skipPendingBroadcastLocked(int pid) { 15549 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15550 for (BroadcastQueue queue : mBroadcastQueues) { 15551 queue.skipPendingBroadcastLocked(pid); 15552 } 15553 } 15554 15555 // The app just attached; send any pending broadcasts that it should receive sendPendingBroadcastsLocked(ProcessRecord app)15556 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15557 boolean didSomething = false; 15558 for (BroadcastQueue queue : mBroadcastQueues) { 15559 didSomething |= queue.sendPendingBroadcastsLocked(app); 15560 } 15561 return didSomething; 15562 } 15563 registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId)15564 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15565 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15566 enforceNotIsolatedCaller("registerReceiver"); 15567 int callingUid; 15568 int callingPid; 15569 synchronized(this) { 15570 ProcessRecord callerApp = null; 15571 if (caller != null) { 15572 callerApp = getRecordForAppLocked(caller); 15573 if (callerApp == null) { 15574 throw new SecurityException( 15575 "Unable to find app for caller " + caller 15576 + " (pid=" + Binder.getCallingPid() 15577 + ") when registering receiver " + receiver); 15578 } 15579 if (callerApp.info.uid != Process.SYSTEM_UID && 15580 !callerApp.pkgList.containsKey(callerPackage) && 15581 !"android".equals(callerPackage)) { 15582 throw new SecurityException("Given caller package " + callerPackage 15583 + " is not running in process " + callerApp); 15584 } 15585 callingUid = callerApp.info.uid; 15586 callingPid = callerApp.pid; 15587 } else { 15588 callerPackage = null; 15589 callingUid = Binder.getCallingUid(); 15590 callingPid = Binder.getCallingPid(); 15591 } 15592 15593 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15594 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15595 15596 List allSticky = null; 15597 15598 // Look for any matching sticky broadcasts... 15599 Iterator actions = filter.actionsIterator(); 15600 if (actions != null) { 15601 while (actions.hasNext()) { 15602 String action = (String)actions.next(); 15603 allSticky = getStickiesLocked(action, filter, allSticky, 15604 UserHandle.USER_ALL); 15605 allSticky = getStickiesLocked(action, filter, allSticky, 15606 UserHandle.getUserId(callingUid)); 15607 } 15608 } else { 15609 allSticky = getStickiesLocked(null, filter, allSticky, 15610 UserHandle.USER_ALL); 15611 allSticky = getStickiesLocked(null, filter, allSticky, 15612 UserHandle.getUserId(callingUid)); 15613 } 15614 15615 // The first sticky in the list is returned directly back to 15616 // the client. 15617 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15618 15619 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15620 + ": " + sticky); 15621 15622 if (receiver == null) { 15623 return sticky; 15624 } 15625 15626 ReceiverList rl 15627 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15628 if (rl == null) { 15629 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15630 userId, receiver); 15631 if (rl.app != null) { 15632 rl.app.receivers.add(rl); 15633 } else { 15634 try { 15635 receiver.asBinder().linkToDeath(rl, 0); 15636 } catch (RemoteException e) { 15637 return sticky; 15638 } 15639 rl.linkedToDeath = true; 15640 } 15641 mRegisteredReceivers.put(receiver.asBinder(), rl); 15642 } else if (rl.uid != callingUid) { 15643 throw new IllegalArgumentException( 15644 "Receiver requested to register for uid " + callingUid 15645 + " was previously registered for uid " + rl.uid); 15646 } else if (rl.pid != callingPid) { 15647 throw new IllegalArgumentException( 15648 "Receiver requested to register for pid " + callingPid 15649 + " was previously registered for pid " + rl.pid); 15650 } else if (rl.userId != userId) { 15651 throw new IllegalArgumentException( 15652 "Receiver requested to register for user " + userId 15653 + " was previously registered for user " + rl.userId); 15654 } 15655 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15656 permission, callingUid, userId); 15657 rl.add(bf); 15658 if (!bf.debugCheck()) { 15659 Slog.w(TAG, "==> For Dynamic broadast"); 15660 } 15661 mReceiverResolver.addFilter(bf); 15662 15663 // Enqueue broadcasts for all existing stickies that match 15664 // this filter. 15665 if (allSticky != null) { 15666 ArrayList receivers = new ArrayList(); 15667 receivers.add(bf); 15668 15669 int N = allSticky.size(); 15670 for (int i=0; i<N; i++) { 15671 Intent intent = (Intent)allSticky.get(i); 15672 BroadcastQueue queue = broadcastQueueForIntent(intent); 15673 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15674 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15675 null, null, false, true, true, -1); 15676 queue.enqueueParallelBroadcastLocked(r); 15677 queue.scheduleBroadcastsLocked(); 15678 } 15679 } 15680 15681 return sticky; 15682 } 15683 } 15684 unregisterReceiver(IIntentReceiver receiver)15685 public void unregisterReceiver(IIntentReceiver receiver) { 15686 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15687 15688 final long origId = Binder.clearCallingIdentity(); 15689 try { 15690 boolean doTrim = false; 15691 15692 synchronized(this) { 15693 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15694 if (rl != null) { 15695 if (rl.curBroadcast != null) { 15696 BroadcastRecord r = rl.curBroadcast; 15697 final boolean doNext = finishReceiverLocked( 15698 receiver.asBinder(), r.resultCode, r.resultData, 15699 r.resultExtras, r.resultAbort); 15700 if (doNext) { 15701 doTrim = true; 15702 r.queue.processNextBroadcast(false); 15703 } 15704 } 15705 15706 if (rl.app != null) { 15707 rl.app.receivers.remove(rl); 15708 } 15709 removeReceiverLocked(rl); 15710 if (rl.linkedToDeath) { 15711 rl.linkedToDeath = false; 15712 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15713 } 15714 } 15715 } 15716 15717 // If we actually concluded any broadcasts, we might now be able 15718 // to trim the recipients' apps from our working set 15719 if (doTrim) { 15720 trimApplications(); 15721 return; 15722 } 15723 15724 } finally { 15725 Binder.restoreCallingIdentity(origId); 15726 } 15727 } 15728 removeReceiverLocked(ReceiverList rl)15729 void removeReceiverLocked(ReceiverList rl) { 15730 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15731 int N = rl.size(); 15732 for (int i=0; i<N; i++) { 15733 mReceiverResolver.removeFilter(rl.get(i)); 15734 } 15735 } 15736 sendPackageBroadcastLocked(int cmd, String[] packages, int userId)15737 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15738 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15739 ProcessRecord r = mLruProcesses.get(i); 15740 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15741 try { 15742 r.thread.dispatchPackageBroadcast(cmd, packages); 15743 } catch (RemoteException ex) { 15744 } 15745 } 15746 } 15747 } 15748 collectReceiverComponents(Intent intent, String resolvedType, int callingUid, int[] users)15749 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15750 int callingUid, int[] users) { 15751 List<ResolveInfo> receivers = null; 15752 try { 15753 HashSet<ComponentName> singleUserReceivers = null; 15754 boolean scannedFirstReceivers = false; 15755 for (int user : users) { 15756 // Skip users that have Shell restrictions 15757 if (callingUid == Process.SHELL_UID 15758 && getUserManagerLocked().hasUserRestriction( 15759 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15760 continue; 15761 } 15762 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15763 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15764 if (user != 0 && newReceivers != null) { 15765 // If this is not the primary user, we need to check for 15766 // any receivers that should be filtered out. 15767 for (int i=0; i<newReceivers.size(); i++) { 15768 ResolveInfo ri = newReceivers.get(i); 15769 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15770 newReceivers.remove(i); 15771 i--; 15772 } 15773 } 15774 } 15775 if (newReceivers != null && newReceivers.size() == 0) { 15776 newReceivers = null; 15777 } 15778 if (receivers == null) { 15779 receivers = newReceivers; 15780 } else if (newReceivers != null) { 15781 // We need to concatenate the additional receivers 15782 // found with what we have do far. This would be easy, 15783 // but we also need to de-dup any receivers that are 15784 // singleUser. 15785 if (!scannedFirstReceivers) { 15786 // Collect any single user receivers we had already retrieved. 15787 scannedFirstReceivers = true; 15788 for (int i=0; i<receivers.size(); i++) { 15789 ResolveInfo ri = receivers.get(i); 15790 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15791 ComponentName cn = new ComponentName( 15792 ri.activityInfo.packageName, ri.activityInfo.name); 15793 if (singleUserReceivers == null) { 15794 singleUserReceivers = new HashSet<ComponentName>(); 15795 } 15796 singleUserReceivers.add(cn); 15797 } 15798 } 15799 } 15800 // Add the new results to the existing results, tracking 15801 // and de-dupping single user receivers. 15802 for (int i=0; i<newReceivers.size(); i++) { 15803 ResolveInfo ri = newReceivers.get(i); 15804 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15805 ComponentName cn = new ComponentName( 15806 ri.activityInfo.packageName, ri.activityInfo.name); 15807 if (singleUserReceivers == null) { 15808 singleUserReceivers = new HashSet<ComponentName>(); 15809 } 15810 if (!singleUserReceivers.contains(cn)) { 15811 singleUserReceivers.add(cn); 15812 receivers.add(ri); 15813 } 15814 } else { 15815 receivers.add(ri); 15816 } 15817 } 15818 } 15819 } 15820 } catch (RemoteException ex) { 15821 // pm is in same process, this will never happen. 15822 } 15823 return receivers; 15824 } 15825 broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, int appOp, boolean ordered, boolean sticky, int callingPid, int callingUid, int userId)15826 private final int broadcastIntentLocked(ProcessRecord callerApp, 15827 String callerPackage, Intent intent, String resolvedType, 15828 IIntentReceiver resultTo, int resultCode, String resultData, 15829 Bundle map, String requiredPermission, int appOp, 15830 boolean ordered, boolean sticky, int callingPid, int callingUid, 15831 int userId) { 15832 intent = new Intent(intent); 15833 15834 // By default broadcasts do not go to stopped apps. 15835 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15836 15837 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15838 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15839 + " ordered=" + ordered + " userid=" + userId); 15840 if ((resultTo != null) && !ordered) { 15841 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15842 } 15843 15844 userId = handleIncomingUser(callingPid, callingUid, userId, 15845 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15846 15847 // Make sure that the user who is receiving this broadcast is running. 15848 // If not, we will just skip it. Make an exception for shutdown broadcasts 15849 // and upgrade steps. 15850 15851 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15852 if ((callingUid != Process.SYSTEM_UID 15853 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15854 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15855 Slog.w(TAG, "Skipping broadcast of " + intent 15856 + ": user " + userId + " is stopped"); 15857 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15858 } 15859 } 15860 15861 /* 15862 * Prevent non-system code (defined here to be non-persistent 15863 * processes) from sending protected broadcasts. 15864 */ 15865 int callingAppId = UserHandle.getAppId(callingUid); 15866 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15867 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15868 || callingAppId == Process.NFC_UID || callingUid == 0) { 15869 // Always okay. 15870 } else if (callerApp == null || !callerApp.persistent) { 15871 try { 15872 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15873 intent.getAction())) { 15874 String msg = "Permission Denial: not allowed to send broadcast " 15875 + intent.getAction() + " from pid=" 15876 + callingPid + ", uid=" + callingUid; 15877 Slog.w(TAG, msg); 15878 throw new SecurityException(msg); 15879 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15880 // Special case for compatibility: we don't want apps to send this, 15881 // but historically it has not been protected and apps may be using it 15882 // to poke their own app widget. So, instead of making it protected, 15883 // just limit it to the caller. 15884 if (callerApp == null) { 15885 String msg = "Permission Denial: not allowed to send broadcast " 15886 + intent.getAction() + " from unknown caller."; 15887 Slog.w(TAG, msg); 15888 throw new SecurityException(msg); 15889 } else if (intent.getComponent() != null) { 15890 // They are good enough to send to an explicit component... verify 15891 // it is being sent to the calling app. 15892 if (!intent.getComponent().getPackageName().equals( 15893 callerApp.info.packageName)) { 15894 String msg = "Permission Denial: not allowed to send broadcast " 15895 + intent.getAction() + " to " 15896 + intent.getComponent().getPackageName() + " from " 15897 + callerApp.info.packageName; 15898 Slog.w(TAG, msg); 15899 throw new SecurityException(msg); 15900 } 15901 } else { 15902 // Limit broadcast to their own package. 15903 intent.setPackage(callerApp.info.packageName); 15904 } 15905 } 15906 } catch (RemoteException e) { 15907 Slog.w(TAG, "Remote exception", e); 15908 return ActivityManager.BROADCAST_SUCCESS; 15909 } 15910 } 15911 15912 final String action = intent.getAction(); 15913 if (action != null) { 15914 switch (action) { 15915 case Intent.ACTION_UID_REMOVED: 15916 case Intent.ACTION_PACKAGE_REMOVED: 15917 case Intent.ACTION_PACKAGE_CHANGED: 15918 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15919 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15920 // Handle special intents: if this broadcast is from the package 15921 // manager about a package being removed, we need to remove all of 15922 // its activities from the history stack. 15923 if (checkComponentPermission( 15924 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15925 callingPid, callingUid, -1, true) 15926 != PackageManager.PERMISSION_GRANTED) { 15927 String msg = "Permission Denial: " + intent.getAction() 15928 + " broadcast from " + callerPackage + " (pid=" + callingPid 15929 + ", uid=" + callingUid + ")" 15930 + " requires " 15931 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15932 Slog.w(TAG, msg); 15933 throw new SecurityException(msg); 15934 } 15935 switch (action) { 15936 case Intent.ACTION_UID_REMOVED: 15937 final Bundle intentExtras = intent.getExtras(); 15938 final int uid = intentExtras != null 15939 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15940 if (uid >= 0) { 15941 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15942 synchronized (bs) { 15943 bs.removeUidStatsLocked(uid); 15944 } 15945 mAppOpsService.uidRemoved(uid); 15946 } 15947 break; 15948 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15949 // If resources are unavailable just force stop all those packages 15950 // and flush the attribute cache as well. 15951 String list[] = 15952 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15953 if (list != null && list.length > 0) { 15954 for (int i = 0; i < list.length; i++) { 15955 forceStopPackageLocked(list[i], -1, false, true, true, 15956 false, false, userId, "storage unmount"); 15957 } 15958 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15959 sendPackageBroadcastLocked( 15960 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15961 userId); 15962 } 15963 break; 15964 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15965 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15966 break; 15967 case Intent.ACTION_PACKAGE_REMOVED: 15968 case Intent.ACTION_PACKAGE_CHANGED: 15969 Uri data = intent.getData(); 15970 String ssp; 15971 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15972 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15973 boolean fullUninstall = removed && 15974 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15975 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15976 forceStopPackageLocked(ssp, UserHandle.getAppId( 15977 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15978 false, true, true, false, fullUninstall, userId, 15979 removed ? "pkg removed" : "pkg changed"); 15980 } 15981 if (removed) { 15982 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15983 new String[] {ssp}, userId); 15984 if (fullUninstall) { 15985 mAppOpsService.packageRemoved( 15986 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15987 15988 // Remove all permissions granted from/to this package 15989 removeUriPermissionsForPackageLocked(ssp, userId, true); 15990 15991 removeTasksByPackageNameLocked(ssp, userId); 15992 if (userId == UserHandle.USER_OWNER) { 15993 mTaskPersister.removeFromPackageCache(ssp); 15994 } 15995 } 15996 } else { 15997 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 15998 if (userId == UserHandle.USER_OWNER) { 15999 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16000 } 16001 } 16002 } 16003 break; 16004 } 16005 break; 16006 case Intent.ACTION_PACKAGE_ADDED: 16007 // Special case for adding a package: by default turn on compatibility mode. 16008 Uri data = intent.getData(); 16009 String ssp; 16010 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 16011 final boolean replacing = 16012 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16013 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 16014 16015 if (replacing) { 16016 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16017 } 16018 if (userId == UserHandle.USER_OWNER) { 16019 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16020 } 16021 } 16022 break; 16023 case Intent.ACTION_TIMEZONE_CHANGED: 16024 // If this is the time zone changed action, queue up a message that will reset 16025 // the timezone of all currently running processes. This message will get 16026 // queued up before the broadcast happens. 16027 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 16028 break; 16029 case Intent.ACTION_TIME_CHANGED: 16030 // If the user set the time, let all running processes know. 16031 final int is24Hour = 16032 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 16033 : 0; 16034 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 16035 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16036 synchronized (stats) { 16037 stats.noteCurrentTimeChangedLocked(); 16038 } 16039 break; 16040 case Intent.ACTION_CLEAR_DNS_CACHE: 16041 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 16042 break; 16043 case Proxy.PROXY_CHANGE_ACTION: 16044 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 16045 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 16046 break; 16047 } 16048 } 16049 16050 // Add to the sticky list if requested. 16051 if (sticky) { 16052 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 16053 callingPid, callingUid) 16054 != PackageManager.PERMISSION_GRANTED) { 16055 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 16056 + callingPid + ", uid=" + callingUid 16057 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16058 Slog.w(TAG, msg); 16059 throw new SecurityException(msg); 16060 } 16061 if (requiredPermission != null) { 16062 Slog.w(TAG, "Can't broadcast sticky intent " + intent 16063 + " and enforce permission " + requiredPermission); 16064 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 16065 } 16066 if (intent.getComponent() != null) { 16067 throw new SecurityException( 16068 "Sticky broadcasts can't target a specific component"); 16069 } 16070 // We use userId directly here, since the "all" target is maintained 16071 // as a separate set of sticky broadcasts. 16072 if (userId != UserHandle.USER_ALL) { 16073 // But first, if this is not a broadcast to all users, then 16074 // make sure it doesn't conflict with an existing broadcast to 16075 // all users. 16076 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 16077 UserHandle.USER_ALL); 16078 if (stickies != null) { 16079 ArrayList<Intent> list = stickies.get(intent.getAction()); 16080 if (list != null) { 16081 int N = list.size(); 16082 int i; 16083 for (i=0; i<N; i++) { 16084 if (intent.filterEquals(list.get(i))) { 16085 throw new IllegalArgumentException( 16086 "Sticky broadcast " + intent + " for user " 16087 + userId + " conflicts with existing global broadcast"); 16088 } 16089 } 16090 } 16091 } 16092 } 16093 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16094 if (stickies == null) { 16095 stickies = new ArrayMap<String, ArrayList<Intent>>(); 16096 mStickyBroadcasts.put(userId, stickies); 16097 } 16098 ArrayList<Intent> list = stickies.get(intent.getAction()); 16099 if (list == null) { 16100 list = new ArrayList<Intent>(); 16101 stickies.put(intent.getAction(), list); 16102 } 16103 int N = list.size(); 16104 int i; 16105 for (i=0; i<N; i++) { 16106 if (intent.filterEquals(list.get(i))) { 16107 // This sticky already exists, replace it. 16108 list.set(i, new Intent(intent)); 16109 break; 16110 } 16111 } 16112 if (i >= N) { 16113 list.add(new Intent(intent)); 16114 } 16115 } 16116 16117 int[] users; 16118 if (userId == UserHandle.USER_ALL) { 16119 // Caller wants broadcast to go to all started users. 16120 users = mStartedUserArray; 16121 } else { 16122 // Caller wants broadcast to go to one specific user. 16123 users = new int[] {userId}; 16124 } 16125 16126 // Figure out who all will receive this broadcast. 16127 List receivers = null; 16128 List<BroadcastFilter> registeredReceivers = null; 16129 // Need to resolve the intent to interested receivers... 16130 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 16131 == 0) { 16132 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 16133 } 16134 if (intent.getComponent() == null) { 16135 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 16136 // Query one target user at a time, excluding shell-restricted users 16137 UserManagerService ums = getUserManagerLocked(); 16138 for (int i = 0; i < users.length; i++) { 16139 if (ums.hasUserRestriction( 16140 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 16141 continue; 16142 } 16143 List<BroadcastFilter> registeredReceiversForUser = 16144 mReceiverResolver.queryIntent(intent, 16145 resolvedType, false, users[i]); 16146 if (registeredReceivers == null) { 16147 registeredReceivers = registeredReceiversForUser; 16148 } else if (registeredReceiversForUser != null) { 16149 registeredReceivers.addAll(registeredReceiversForUser); 16150 } 16151 } 16152 } else { 16153 registeredReceivers = mReceiverResolver.queryIntent(intent, 16154 resolvedType, false, userId); 16155 } 16156 } 16157 16158 final boolean replacePending = 16159 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16160 16161 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16162 + " replacePending=" + replacePending); 16163 16164 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16165 if (!ordered && NR > 0) { 16166 // If we are not serializing this broadcast, then send the 16167 // registered receivers separately so they don't wait for the 16168 // components to be launched. 16169 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16170 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16171 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16172 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16173 ordered, sticky, false, userId); 16174 if (DEBUG_BROADCAST) Slog.v( 16175 TAG, "Enqueueing parallel broadcast " + r); 16176 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16177 if (!replaced) { 16178 queue.enqueueParallelBroadcastLocked(r); 16179 queue.scheduleBroadcastsLocked(); 16180 } 16181 registeredReceivers = null; 16182 NR = 0; 16183 } 16184 16185 // Merge into one list. 16186 int ir = 0; 16187 if (receivers != null) { 16188 // A special case for PACKAGE_ADDED: do not allow the package 16189 // being added to see this broadcast. This prevents them from 16190 // using this as a back door to get run as soon as they are 16191 // installed. Maybe in the future we want to have a special install 16192 // broadcast or such for apps, but we'd like to deliberately make 16193 // this decision. 16194 String skipPackages[] = null; 16195 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16196 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16197 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16198 Uri data = intent.getData(); 16199 if (data != null) { 16200 String pkgName = data.getSchemeSpecificPart(); 16201 if (pkgName != null) { 16202 skipPackages = new String[] { pkgName }; 16203 } 16204 } 16205 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16206 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16207 } 16208 if (skipPackages != null && (skipPackages.length > 0)) { 16209 for (String skipPackage : skipPackages) { 16210 if (skipPackage != null) { 16211 int NT = receivers.size(); 16212 for (int it=0; it<NT; it++) { 16213 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16214 if (curt.activityInfo.packageName.equals(skipPackage)) { 16215 receivers.remove(it); 16216 it--; 16217 NT--; 16218 } 16219 } 16220 } 16221 } 16222 } 16223 16224 int NT = receivers != null ? receivers.size() : 0; 16225 int it = 0; 16226 ResolveInfo curt = null; 16227 BroadcastFilter curr = null; 16228 while (it < NT && ir < NR) { 16229 if (curt == null) { 16230 curt = (ResolveInfo)receivers.get(it); 16231 } 16232 if (curr == null) { 16233 curr = registeredReceivers.get(ir); 16234 } 16235 if (curr.getPriority() >= curt.priority) { 16236 // Insert this broadcast record into the final list. 16237 receivers.add(it, curr); 16238 ir++; 16239 curr = null; 16240 it++; 16241 NT++; 16242 } else { 16243 // Skip to the next ResolveInfo in the final list. 16244 it++; 16245 curt = null; 16246 } 16247 } 16248 } 16249 while (ir < NR) { 16250 if (receivers == null) { 16251 receivers = new ArrayList(); 16252 } 16253 receivers.add(registeredReceivers.get(ir)); 16254 ir++; 16255 } 16256 16257 if ((receivers != null && receivers.size() > 0) 16258 || resultTo != null) { 16259 BroadcastQueue queue = broadcastQueueForIntent(intent); 16260 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16261 callerPackage, callingPid, callingUid, resolvedType, 16262 requiredPermission, appOp, receivers, resultTo, resultCode, 16263 resultData, map, ordered, sticky, false, userId); 16264 if (DEBUG_BROADCAST) Slog.v( 16265 TAG, "Enqueueing ordered broadcast " + r 16266 + ": prev had " + queue.mOrderedBroadcasts.size()); 16267 if (DEBUG_BROADCAST) { 16268 int seq = r.intent.getIntExtra("seq", -1); 16269 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16270 } 16271 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16272 if (!replaced) { 16273 queue.enqueueOrderedBroadcastLocked(r); 16274 queue.scheduleBroadcastsLocked(); 16275 } 16276 } 16277 16278 return ActivityManager.BROADCAST_SUCCESS; 16279 } 16280 verifyBroadcastLocked(Intent intent)16281 final Intent verifyBroadcastLocked(Intent intent) { 16282 // Refuse possible leaked file descriptors 16283 if (intent != null && intent.hasFileDescriptors() == true) { 16284 throw new IllegalArgumentException("File descriptors passed in Intent"); 16285 } 16286 16287 int flags = intent.getFlags(); 16288 16289 if (!mProcessesReady) { 16290 // if the caller really truly claims to know what they're doing, go 16291 // ahead and allow the broadcast without launching any receivers 16292 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16293 intent = new Intent(intent); 16294 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16295 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16296 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16297 + " before boot completion"); 16298 throw new IllegalStateException("Cannot broadcast before boot completed"); 16299 } 16300 } 16301 16302 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16303 throw new IllegalArgumentException( 16304 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16305 } 16306 16307 return intent; 16308 } 16309 broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId)16310 public final int broadcastIntent(IApplicationThread caller, 16311 Intent intent, String resolvedType, IIntentReceiver resultTo, 16312 int resultCode, String resultData, Bundle map, 16313 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16314 enforceNotIsolatedCaller("broadcastIntent"); 16315 synchronized(this) { 16316 intent = verifyBroadcastLocked(intent); 16317 16318 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16319 final int callingPid = Binder.getCallingPid(); 16320 final int callingUid = Binder.getCallingUid(); 16321 final long origId = Binder.clearCallingIdentity(); 16322 int res = broadcastIntentLocked(callerApp, 16323 callerApp != null ? callerApp.info.packageName : null, 16324 intent, resolvedType, resultTo, 16325 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16326 callingPid, callingUid, userId); 16327 Binder.restoreCallingIdentity(origId); 16328 return res; 16329 } 16330 } 16331 broadcastIntentInPackage(String packageName, int uid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle map, String requiredPermission, boolean serialized, boolean sticky, int userId)16332 int broadcastIntentInPackage(String packageName, int uid, 16333 Intent intent, String resolvedType, IIntentReceiver resultTo, 16334 int resultCode, String resultData, Bundle map, 16335 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16336 synchronized(this) { 16337 intent = verifyBroadcastLocked(intent); 16338 16339 final long origId = Binder.clearCallingIdentity(); 16340 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16341 resultTo, resultCode, resultData, map, requiredPermission, 16342 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16343 Binder.restoreCallingIdentity(origId); 16344 return res; 16345 } 16346 } 16347 unbroadcastIntent(IApplicationThread caller, Intent intent, int userId)16348 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16349 // Refuse possible leaked file descriptors 16350 if (intent != null && intent.hasFileDescriptors() == true) { 16351 throw new IllegalArgumentException("File descriptors passed in Intent"); 16352 } 16353 16354 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16355 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16356 16357 synchronized(this) { 16358 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16359 != PackageManager.PERMISSION_GRANTED) { 16360 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16361 + Binder.getCallingPid() 16362 + ", uid=" + Binder.getCallingUid() 16363 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16364 Slog.w(TAG, msg); 16365 throw new SecurityException(msg); 16366 } 16367 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16368 if (stickies != null) { 16369 ArrayList<Intent> list = stickies.get(intent.getAction()); 16370 if (list != null) { 16371 int N = list.size(); 16372 int i; 16373 for (i=0; i<N; i++) { 16374 if (intent.filterEquals(list.get(i))) { 16375 list.remove(i); 16376 break; 16377 } 16378 } 16379 if (list.size() <= 0) { 16380 stickies.remove(intent.getAction()); 16381 } 16382 } 16383 if (stickies.size() <= 0) { 16384 mStickyBroadcasts.remove(userId); 16385 } 16386 } 16387 } 16388 } 16389 finishReceiverLocked(IBinder receiver, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort)16390 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16391 String resultData, Bundle resultExtras, boolean resultAbort) { 16392 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16393 if (r == null) { 16394 Slog.w(TAG, "finishReceiver called but not found on queue"); 16395 return false; 16396 } 16397 16398 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16399 } 16400 backgroundServicesFinishedLocked(int userId)16401 void backgroundServicesFinishedLocked(int userId) { 16402 for (BroadcastQueue queue : mBroadcastQueues) { 16403 queue.backgroundServicesFinishedLocked(userId); 16404 } 16405 } 16406 finishReceiver(IBinder who, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort)16407 public void finishReceiver(IBinder who, int resultCode, String resultData, 16408 Bundle resultExtras, boolean resultAbort) { 16409 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16410 16411 // Refuse possible leaked file descriptors 16412 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16413 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16414 } 16415 16416 final long origId = Binder.clearCallingIdentity(); 16417 try { 16418 boolean doNext = false; 16419 BroadcastRecord r; 16420 16421 synchronized(this) { 16422 r = broadcastRecordForReceiverLocked(who); 16423 if (r != null) { 16424 doNext = r.queue.finishReceiverLocked(r, resultCode, 16425 resultData, resultExtras, resultAbort, true); 16426 } 16427 } 16428 16429 if (doNext) { 16430 r.queue.processNextBroadcast(false); 16431 } 16432 trimApplications(); 16433 } finally { 16434 Binder.restoreCallingIdentity(origId); 16435 } 16436 } 16437 16438 // ========================================================= 16439 // INSTRUMENTATION 16440 // ========================================================= 16441 startInstrumentation(ComponentName className, String profileFile, int flags, Bundle arguments, IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, int userId, String abiOverride)16442 public boolean startInstrumentation(ComponentName className, 16443 String profileFile, int flags, Bundle arguments, 16444 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16445 int userId, String abiOverride) { 16446 enforceNotIsolatedCaller("startInstrumentation"); 16447 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16448 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16449 // Refuse possible leaked file descriptors 16450 if (arguments != null && arguments.hasFileDescriptors()) { 16451 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16452 } 16453 16454 synchronized(this) { 16455 InstrumentationInfo ii = null; 16456 ApplicationInfo ai = null; 16457 try { 16458 ii = mContext.getPackageManager().getInstrumentationInfo( 16459 className, STOCK_PM_FLAGS); 16460 ai = AppGlobals.getPackageManager().getApplicationInfo( 16461 ii.targetPackage, STOCK_PM_FLAGS, userId); 16462 } catch (PackageManager.NameNotFoundException e) { 16463 } catch (RemoteException e) { 16464 } 16465 if (ii == null) { 16466 reportStartInstrumentationFailure(watcher, className, 16467 "Unable to find instrumentation info for: " + className); 16468 return false; 16469 } 16470 if (ai == null) { 16471 reportStartInstrumentationFailure(watcher, className, 16472 "Unable to find instrumentation target package: " + ii.targetPackage); 16473 return false; 16474 } 16475 16476 int match = mContext.getPackageManager().checkSignatures( 16477 ii.targetPackage, ii.packageName); 16478 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16479 String msg = "Permission Denial: starting instrumentation " 16480 + className + " from pid=" 16481 + Binder.getCallingPid() 16482 + ", uid=" + Binder.getCallingPid() 16483 + " not allowed because package " + ii.packageName 16484 + " does not have a signature matching the target " 16485 + ii.targetPackage; 16486 reportStartInstrumentationFailure(watcher, className, msg); 16487 throw new SecurityException(msg); 16488 } 16489 16490 final long origId = Binder.clearCallingIdentity(); 16491 // Instrumentation can kill and relaunch even persistent processes 16492 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16493 "start instr"); 16494 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16495 app.instrumentationClass = className; 16496 app.instrumentationInfo = ai; 16497 app.instrumentationProfileFile = profileFile; 16498 app.instrumentationArguments = arguments; 16499 app.instrumentationWatcher = watcher; 16500 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16501 app.instrumentationResultClass = className; 16502 Binder.restoreCallingIdentity(origId); 16503 } 16504 16505 return true; 16506 } 16507 16508 /** 16509 * Report errors that occur while attempting to start Instrumentation. Always writes the 16510 * error to the logs, but if somebody is watching, send the report there too. This enables 16511 * the "am" command to report errors with more information. 16512 * 16513 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16514 * @param cn The component name of the instrumentation. 16515 * @param report The error report. 16516 */ reportStartInstrumentationFailure(IInstrumentationWatcher watcher, ComponentName cn, String report)16517 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16518 ComponentName cn, String report) { 16519 Slog.w(TAG, report); 16520 try { 16521 if (watcher != null) { 16522 Bundle results = new Bundle(); 16523 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16524 results.putString("Error", report); 16525 watcher.instrumentationStatus(cn, -1, results); 16526 } 16527 } catch (RemoteException e) { 16528 Slog.w(TAG, e); 16529 } 16530 } 16531 finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results)16532 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16533 if (app.instrumentationWatcher != null) { 16534 try { 16535 // NOTE: IInstrumentationWatcher *must* be oneway here 16536 app.instrumentationWatcher.instrumentationFinished( 16537 app.instrumentationClass, 16538 resultCode, 16539 results); 16540 } catch (RemoteException e) { 16541 } 16542 } 16543 if (app.instrumentationUiAutomationConnection != null) { 16544 try { 16545 app.instrumentationUiAutomationConnection.shutdown(); 16546 } catch (RemoteException re) { 16547 /* ignore */ 16548 } 16549 // Only a UiAutomation can set this flag and now that 16550 // it is finished we make sure it is reset to its default. 16551 mUserIsMonkey = false; 16552 } 16553 app.instrumentationWatcher = null; 16554 app.instrumentationUiAutomationConnection = null; 16555 app.instrumentationClass = null; 16556 app.instrumentationInfo = null; 16557 app.instrumentationProfileFile = null; 16558 app.instrumentationArguments = null; 16559 16560 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16561 "finished inst"); 16562 } 16563 finishInstrumentation(IApplicationThread target, int resultCode, Bundle results)16564 public void finishInstrumentation(IApplicationThread target, 16565 int resultCode, Bundle results) { 16566 int userId = UserHandle.getCallingUserId(); 16567 // Refuse possible leaked file descriptors 16568 if (results != null && results.hasFileDescriptors()) { 16569 throw new IllegalArgumentException("File descriptors passed in Intent"); 16570 } 16571 16572 synchronized(this) { 16573 ProcessRecord app = getRecordForAppLocked(target); 16574 if (app == null) { 16575 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16576 return; 16577 } 16578 final long origId = Binder.clearCallingIdentity(); 16579 finishInstrumentationLocked(app, resultCode, results); 16580 Binder.restoreCallingIdentity(origId); 16581 } 16582 } 16583 16584 // ========================================================= 16585 // CONFIGURATION 16586 // ========================================================= 16587 getDeviceConfigurationInfo()16588 public ConfigurationInfo getDeviceConfigurationInfo() { 16589 ConfigurationInfo config = new ConfigurationInfo(); 16590 synchronized (this) { 16591 config.reqTouchScreen = mConfiguration.touchscreen; 16592 config.reqKeyboardType = mConfiguration.keyboard; 16593 config.reqNavigation = mConfiguration.navigation; 16594 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16595 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16596 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16597 } 16598 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16599 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16600 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16601 } 16602 config.reqGlEsVersion = GL_ES_VERSION; 16603 } 16604 return config; 16605 } 16606 getFocusedStack()16607 ActivityStack getFocusedStack() { 16608 return mStackSupervisor.getFocusedStack(); 16609 } 16610 getConfiguration()16611 public Configuration getConfiguration() { 16612 Configuration ci; 16613 synchronized(this) { 16614 ci = new Configuration(mConfiguration); 16615 ci.userSetLocale = false; 16616 } 16617 return ci; 16618 } 16619 updatePersistentConfiguration(Configuration values)16620 public void updatePersistentConfiguration(Configuration values) { 16621 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16622 "updateConfiguration()"); 16623 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16624 "updateConfiguration()"); 16625 if (values == null) { 16626 throw new NullPointerException("Configuration must not be null"); 16627 } 16628 16629 synchronized(this) { 16630 final long origId = Binder.clearCallingIdentity(); 16631 updateConfigurationLocked(values, null, true, false); 16632 Binder.restoreCallingIdentity(origId); 16633 } 16634 } 16635 updateConfiguration(Configuration values)16636 public void updateConfiguration(Configuration values) { 16637 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16638 "updateConfiguration()"); 16639 16640 synchronized(this) { 16641 if (values == null && mWindowManager != null) { 16642 // sentinel: fetch the current configuration from the window manager 16643 values = mWindowManager.computeNewConfiguration(); 16644 } 16645 16646 if (mWindowManager != null) { 16647 mProcessList.applyDisplaySize(mWindowManager); 16648 } 16649 16650 final long origId = Binder.clearCallingIdentity(); 16651 if (values != null) { 16652 Settings.System.clearConfiguration(values); 16653 } 16654 updateConfigurationLocked(values, null, false, false); 16655 Binder.restoreCallingIdentity(origId); 16656 } 16657 } 16658 16659 /** 16660 * Do either or both things: (1) change the current configuration, and (2) 16661 * make sure the given activity is running with the (now) current 16662 * configuration. Returns true if the activity has been left running, or 16663 * false if <var>starting</var> is being destroyed to match the new 16664 * configuration. 16665 * @param persistent TODO 16666 */ updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean persistent, boolean initLocale)16667 boolean updateConfigurationLocked(Configuration values, 16668 ActivityRecord starting, boolean persistent, boolean initLocale) { 16669 int changes = 0; 16670 16671 if (values != null) { 16672 Configuration newConfig = new Configuration(mConfiguration); 16673 changes = newConfig.updateFrom(values); 16674 if (changes != 0) { 16675 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16676 Slog.i(TAG, "Updating configuration to: " + values); 16677 } 16678 16679 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16680 16681 if (values.locale != null && !initLocale) { 16682 saveLocaleLocked(values.locale, 16683 !values.locale.equals(mConfiguration.locale), 16684 values.userSetLocale); 16685 } 16686 16687 mConfigurationSeq++; 16688 if (mConfigurationSeq <= 0) { 16689 mConfigurationSeq = 1; 16690 } 16691 newConfig.seq = mConfigurationSeq; 16692 mConfiguration = newConfig; 16693 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16694 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16695 //mUsageStatsService.noteStartConfig(newConfig); 16696 16697 final Configuration configCopy = new Configuration(mConfiguration); 16698 16699 // TODO: If our config changes, should we auto dismiss any currently 16700 // showing dialogs? 16701 mShowDialogs = shouldShowDialogs(newConfig); 16702 16703 AttributeCache ac = AttributeCache.instance(); 16704 if (ac != null) { 16705 ac.updateConfiguration(configCopy); 16706 } 16707 16708 // Make sure all resources in our process are updated 16709 // right now, so that anyone who is going to retrieve 16710 // resource values after we return will be sure to get 16711 // the new ones. This is especially important during 16712 // boot, where the first config change needs to guarantee 16713 // all resources have that config before following boot 16714 // code is executed. 16715 mSystemThread.applyConfigurationToResources(configCopy); 16716 16717 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16718 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16719 msg.obj = new Configuration(configCopy); 16720 mHandler.sendMessage(msg); 16721 } 16722 16723 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16724 ProcessRecord app = mLruProcesses.get(i); 16725 try { 16726 if (app.thread != null) { 16727 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16728 + app.processName + " new config " + mConfiguration); 16729 app.thread.scheduleConfigurationChanged(configCopy); 16730 } 16731 } catch (Exception e) { 16732 } 16733 } 16734 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16735 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16736 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16737 | Intent.FLAG_RECEIVER_FOREGROUND); 16738 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16739 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16740 Process.SYSTEM_UID, UserHandle.USER_ALL); 16741 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16742 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16743 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16744 broadcastIntentLocked(null, null, intent, 16745 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16746 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16747 } 16748 } 16749 } 16750 16751 boolean kept = true; 16752 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16753 // mainStack is null during startup. 16754 if (mainStack != null) { 16755 if (changes != 0 && starting == null) { 16756 // If the configuration changed, and the caller is not already 16757 // in the process of starting an activity, then find the top 16758 // activity to check if its configuration needs to change. 16759 starting = mainStack.topRunningActivityLocked(null); 16760 } 16761 16762 if (starting != null) { 16763 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16764 // And we need to make sure at this point that all other activities 16765 // are made visible with the correct configuration. 16766 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16767 } 16768 } 16769 16770 if (values != null && mWindowManager != null) { 16771 mWindowManager.setNewConfiguration(mConfiguration); 16772 } 16773 16774 return kept; 16775 } 16776 16777 /** 16778 * Decide based on the configuration whether we should shouw the ANR, 16779 * crash, etc dialogs. The idea is that if there is no affordnace to 16780 * press the on-screen buttons, we shouldn't show the dialog. 16781 * 16782 * A thought: SystemUI might also want to get told about this, the Power 16783 * dialog / global actions also might want different behaviors. 16784 */ shouldShowDialogs(Configuration config)16785 private static final boolean shouldShowDialogs(Configuration config) { 16786 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16787 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16788 } 16789 16790 /** 16791 * Save the locale. You must be inside a synchronized (this) block. 16792 */ saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist)16793 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16794 if(isDiff) { 16795 SystemProperties.set("user.language", l.getLanguage()); 16796 SystemProperties.set("user.region", l.getCountry()); 16797 } 16798 16799 if(isPersist) { 16800 SystemProperties.set("persist.sys.language", l.getLanguage()); 16801 SystemProperties.set("persist.sys.country", l.getCountry()); 16802 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16803 16804 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16805 } 16806 } 16807 16808 @Override shouldUpRecreateTask(IBinder token, String destAffinity)16809 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16810 synchronized (this) { 16811 ActivityRecord srec = ActivityRecord.forToken(token); 16812 if (srec.task != null && srec.task.stack != null) { 16813 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16814 } 16815 } 16816 return false; 16817 } 16818 navigateUpTo(IBinder token, Intent destIntent, int resultCode, Intent resultData)16819 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16820 Intent resultData) { 16821 16822 synchronized (this) { 16823 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16824 if (stack != null) { 16825 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16826 } 16827 return false; 16828 } 16829 } 16830 getLaunchedFromUid(IBinder activityToken)16831 public int getLaunchedFromUid(IBinder activityToken) { 16832 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16833 if (srec == null) { 16834 return -1; 16835 } 16836 return srec.launchedFromUid; 16837 } 16838 getLaunchedFromPackage(IBinder activityToken)16839 public String getLaunchedFromPackage(IBinder activityToken) { 16840 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16841 if (srec == null) { 16842 return null; 16843 } 16844 return srec.launchedFromPackage; 16845 } 16846 16847 // ========================================================= 16848 // LIFETIME MANAGEMENT 16849 // ========================================================= 16850 16851 // Returns which broadcast queue the app is the current [or imminent] receiver 16852 // on, or 'null' if the app is not an active broadcast recipient. isReceivingBroadcast(ProcessRecord app)16853 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16854 BroadcastRecord r = app.curReceiver; 16855 if (r != null) { 16856 return r.queue; 16857 } 16858 16859 // It's not the current receiver, but it might be starting up to become one 16860 synchronized (this) { 16861 for (BroadcastQueue queue : mBroadcastQueues) { 16862 r = queue.mPendingBroadcast; 16863 if (r != null && r.curApp == app) { 16864 // found it; report which queue it's in 16865 return queue; 16866 } 16867 } 16868 } 16869 16870 return null; 16871 } 16872 startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, ComponentName targetComponent, String targetProcess)16873 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16874 ComponentName targetComponent, String targetProcess) { 16875 if (!mTrackingAssociations) { 16876 return null; 16877 } 16878 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16879 = mAssociations.get(targetUid); 16880 if (components == null) { 16881 components = new ArrayMap<>(); 16882 mAssociations.put(targetUid, components); 16883 } 16884 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16885 if (sourceUids == null) { 16886 sourceUids = new SparseArray<>(); 16887 components.put(targetComponent, sourceUids); 16888 } 16889 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16890 if (sourceProcesses == null) { 16891 sourceProcesses = new ArrayMap<>(); 16892 sourceUids.put(sourceUid, sourceProcesses); 16893 } 16894 Association ass = sourceProcesses.get(sourceProcess); 16895 if (ass == null) { 16896 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 16897 targetProcess); 16898 sourceProcesses.put(sourceProcess, ass); 16899 } 16900 ass.mCount++; 16901 ass.mNesting++; 16902 if (ass.mNesting == 1) { 16903 ass.mStartTime = SystemClock.uptimeMillis(); 16904 } 16905 return ass; 16906 } 16907 stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, ComponentName targetComponent)16908 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16909 ComponentName targetComponent) { 16910 if (!mTrackingAssociations) { 16911 return; 16912 } 16913 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16914 = mAssociations.get(targetUid); 16915 if (components == null) { 16916 return; 16917 } 16918 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16919 if (sourceUids == null) { 16920 return; 16921 } 16922 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16923 if (sourceProcesses == null) { 16924 return; 16925 } 16926 Association ass = sourceProcesses.get(sourceProcess); 16927 if (ass == null || ass.mNesting <= 0) { 16928 return; 16929 } 16930 ass.mNesting--; 16931 if (ass.mNesting == 0) { 16932 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; 16933 } 16934 } 16935 computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, long now)16936 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16937 boolean doingAll, long now) { 16938 if (mAdjSeq == app.adjSeq) { 16939 // This adjustment has already been computed. 16940 return app.curRawAdj; 16941 } 16942 16943 if (app.thread == null) { 16944 app.adjSeq = mAdjSeq; 16945 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16946 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16947 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16948 } 16949 16950 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16951 app.adjSource = null; 16952 app.adjTarget = null; 16953 app.empty = false; 16954 app.cached = false; 16955 16956 final int activitiesSize = app.activities.size(); 16957 16958 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16959 // The max adjustment doesn't allow this app to be anything 16960 // below foreground, so it is not worth doing work for it. 16961 app.adjType = "fixed"; 16962 app.adjSeq = mAdjSeq; 16963 app.curRawAdj = app.maxAdj; 16964 app.foregroundActivities = false; 16965 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16966 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16967 // System processes can do UI, and when they do we want to have 16968 // them trim their memory after the user leaves the UI. To 16969 // facilitate this, here we need to determine whether or not it 16970 // is currently showing UI. 16971 app.systemNoUi = true; 16972 if (app == TOP_APP) { 16973 app.systemNoUi = false; 16974 } else if (activitiesSize > 0) { 16975 for (int j = 0; j < activitiesSize; j++) { 16976 final ActivityRecord r = app.activities.get(j); 16977 if (r.visible) { 16978 app.systemNoUi = false; 16979 } 16980 } 16981 } 16982 if (!app.systemNoUi) { 16983 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16984 } 16985 return (app.curAdj=app.maxAdj); 16986 } 16987 16988 app.systemNoUi = false; 16989 16990 // Determine the importance of the process, starting with most 16991 // important to least, and assign an appropriate OOM adjustment. 16992 int adj; 16993 int schedGroup; 16994 int procState; 16995 boolean foregroundActivities = false; 16996 BroadcastQueue queue; 16997 if (app == TOP_APP) { 16998 // The last app on the list is the foreground app. 16999 adj = ProcessList.FOREGROUND_APP_ADJ; 17000 schedGroup = Process.THREAD_GROUP_DEFAULT; 17001 app.adjType = "top-activity"; 17002 foregroundActivities = true; 17003 procState = ActivityManager.PROCESS_STATE_TOP; 17004 } else if (app.instrumentationClass != null) { 17005 // Don't want to kill running instrumentation. 17006 adj = ProcessList.FOREGROUND_APP_ADJ; 17007 schedGroup = Process.THREAD_GROUP_DEFAULT; 17008 app.adjType = "instrumentation"; 17009 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17010 } else if ((queue = isReceivingBroadcast(app)) != null) { 17011 // An app that is currently receiving a broadcast also 17012 // counts as being in the foreground for OOM killer purposes. 17013 // It's placed in a sched group based on the nature of the 17014 // broadcast as reflected by which queue it's active in. 17015 adj = ProcessList.FOREGROUND_APP_ADJ; 17016 schedGroup = (queue == mFgBroadcastQueue) 17017 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17018 app.adjType = "broadcast"; 17019 procState = ActivityManager.PROCESS_STATE_RECEIVER; 17020 } else if (app.executingServices.size() > 0) { 17021 // An app that is currently executing a service callback also 17022 // counts as being in the foreground. 17023 adj = ProcessList.FOREGROUND_APP_ADJ; 17024 schedGroup = app.execServicesFg ? 17025 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17026 app.adjType = "exec-service"; 17027 procState = ActivityManager.PROCESS_STATE_SERVICE; 17028 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 17029 } else { 17030 // As far as we know the process is empty. We may change our mind later. 17031 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17032 // At this point we don't actually know the adjustment. Use the cached adj 17033 // value that the caller wants us to. 17034 adj = cachedAdj; 17035 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17036 app.cached = true; 17037 app.empty = true; 17038 app.adjType = "cch-empty"; 17039 } 17040 17041 // Examine all activities if not already foreground. 17042 if (!foregroundActivities && activitiesSize > 0) { 17043 for (int j = 0; j < activitiesSize; j++) { 17044 final ActivityRecord r = app.activities.get(j); 17045 if (r.app != app) { 17046 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 17047 + app + "?!?"); 17048 continue; 17049 } 17050 if (r.visible) { 17051 // App has a visible activity; only upgrade adjustment. 17052 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17053 adj = ProcessList.VISIBLE_APP_ADJ; 17054 app.adjType = "visible"; 17055 } 17056 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17057 procState = ActivityManager.PROCESS_STATE_TOP; 17058 } 17059 schedGroup = Process.THREAD_GROUP_DEFAULT; 17060 app.cached = false; 17061 app.empty = false; 17062 foregroundActivities = true; 17063 break; 17064 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 17065 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17066 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17067 app.adjType = "pausing"; 17068 } 17069 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17070 procState = ActivityManager.PROCESS_STATE_TOP; 17071 } 17072 schedGroup = Process.THREAD_GROUP_DEFAULT; 17073 app.cached = false; 17074 app.empty = false; 17075 foregroundActivities = true; 17076 } else if (r.state == ActivityState.STOPPING) { 17077 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17078 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17079 app.adjType = "stopping"; 17080 } 17081 // For the process state, we will at this point consider the 17082 // process to be cached. It will be cached either as an activity 17083 // or empty depending on whether the activity is finishing. We do 17084 // this so that we can treat the process as cached for purposes of 17085 // memory trimming (determing current memory level, trim command to 17086 // send to process) since there can be an arbitrary number of stopping 17087 // processes and they should soon all go into the cached state. 17088 if (!r.finishing) { 17089 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17090 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17091 } 17092 } 17093 app.cached = false; 17094 app.empty = false; 17095 foregroundActivities = true; 17096 } else { 17097 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17098 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17099 app.adjType = "cch-act"; 17100 } 17101 } 17102 } 17103 } 17104 17105 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17106 if (app.foregroundServices) { 17107 // The user is aware of this app, so make it visible. 17108 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17109 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17110 app.cached = false; 17111 app.adjType = "fg-service"; 17112 schedGroup = Process.THREAD_GROUP_DEFAULT; 17113 } else if (app.forcingToForeground != null) { 17114 // The user is aware of this app, so make it visible. 17115 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17116 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17117 app.cached = false; 17118 app.adjType = "force-fg"; 17119 app.adjSource = app.forcingToForeground; 17120 schedGroup = Process.THREAD_GROUP_DEFAULT; 17121 } 17122 } 17123 17124 if (app == mHeavyWeightProcess) { 17125 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 17126 // We don't want to kill the current heavy-weight process. 17127 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 17128 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17129 app.cached = false; 17130 app.adjType = "heavy"; 17131 } 17132 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17133 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 17134 } 17135 } 17136 17137 if (app == mHomeProcess) { 17138 if (adj > ProcessList.HOME_APP_ADJ) { 17139 // This process is hosting what we currently consider to be the 17140 // home app, so we don't want to let it go into the background. 17141 adj = ProcessList.HOME_APP_ADJ; 17142 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17143 app.cached = false; 17144 app.adjType = "home"; 17145 } 17146 if (procState > ActivityManager.PROCESS_STATE_HOME) { 17147 procState = ActivityManager.PROCESS_STATE_HOME; 17148 } 17149 } 17150 17151 if (app == mPreviousProcess && app.activities.size() > 0) { 17152 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 17153 // This was the previous process that showed UI to the user. 17154 // We want to try to keep it around more aggressively, to give 17155 // a good experience around switching between two apps. 17156 adj = ProcessList.PREVIOUS_APP_ADJ; 17157 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17158 app.cached = false; 17159 app.adjType = "previous"; 17160 } 17161 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17162 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17163 } 17164 } 17165 17166 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 17167 + " reason=" + app.adjType); 17168 17169 // By default, we use the computed adjustment. It may be changed if 17170 // there are applications dependent on our services or providers, but 17171 // this gives us a baseline and makes sure we don't get into an 17172 // infinite recursion. 17173 app.adjSeq = mAdjSeq; 17174 app.curRawAdj = adj; 17175 app.hasStartedServices = false; 17176 17177 if (mBackupTarget != null && app == mBackupTarget.app) { 17178 // If possible we want to avoid killing apps while they're being backed up 17179 if (adj > ProcessList.BACKUP_APP_ADJ) { 17180 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 17181 adj = ProcessList.BACKUP_APP_ADJ; 17182 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17183 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17184 } 17185 app.adjType = "backup"; 17186 app.cached = false; 17187 } 17188 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 17189 procState = ActivityManager.PROCESS_STATE_BACKUP; 17190 } 17191 } 17192 17193 boolean mayBeTop = false; 17194 17195 for (int is = app.services.size()-1; 17196 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17197 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17198 || procState > ActivityManager.PROCESS_STATE_TOP); 17199 is--) { 17200 ServiceRecord s = app.services.valueAt(is); 17201 if (s.startRequested) { 17202 app.hasStartedServices = true; 17203 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 17204 procState = ActivityManager.PROCESS_STATE_SERVICE; 17205 } 17206 if (app.hasShownUi && app != mHomeProcess) { 17207 // If this process has shown some UI, let it immediately 17208 // go to the LRU list because it may be pretty heavy with 17209 // UI stuff. We'll tag it with a label just to help 17210 // debug and understand what is going on. 17211 if (adj > ProcessList.SERVICE_ADJ) { 17212 app.adjType = "cch-started-ui-services"; 17213 } 17214 } else { 17215 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17216 // This service has seen some activity within 17217 // recent memory, so we will keep its process ahead 17218 // of the background processes. 17219 if (adj > ProcessList.SERVICE_ADJ) { 17220 adj = ProcessList.SERVICE_ADJ; 17221 app.adjType = "started-services"; 17222 app.cached = false; 17223 } 17224 } 17225 // If we have let the service slide into the background 17226 // state, still have some text describing what it is doing 17227 // even though the service no longer has an impact. 17228 if (adj > ProcessList.SERVICE_ADJ) { 17229 app.adjType = "cch-started-services"; 17230 } 17231 } 17232 } 17233 for (int conni = s.connections.size()-1; 17234 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17235 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17236 || procState > ActivityManager.PROCESS_STATE_TOP); 17237 conni--) { 17238 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17239 for (int i = 0; 17240 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17241 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17242 || procState > ActivityManager.PROCESS_STATE_TOP); 17243 i++) { 17244 // XXX should compute this based on the max of 17245 // all connected clients. 17246 ConnectionRecord cr = clist.get(i); 17247 if (cr.binding.client == app) { 17248 // Binding to ourself is not interesting. 17249 continue; 17250 } 17251 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17252 ProcessRecord client = cr.binding.client; 17253 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17254 TOP_APP, doingAll, now); 17255 int clientProcState = client.curProcState; 17256 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17257 // If the other app is cached for any reason, for purposes here 17258 // we are going to consider it empty. The specific cached state 17259 // doesn't propagate except under certain conditions. 17260 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17261 } 17262 String adjType = null; 17263 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17264 // Not doing bind OOM management, so treat 17265 // this guy more like a started service. 17266 if (app.hasShownUi && app != mHomeProcess) { 17267 // If this process has shown some UI, let it immediately 17268 // go to the LRU list because it may be pretty heavy with 17269 // UI stuff. We'll tag it with a label just to help 17270 // debug and understand what is going on. 17271 if (adj > clientAdj) { 17272 adjType = "cch-bound-ui-services"; 17273 } 17274 app.cached = false; 17275 clientAdj = adj; 17276 clientProcState = procState; 17277 } else { 17278 if (now >= (s.lastActivity 17279 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17280 // This service has not seen activity within 17281 // recent memory, so allow it to drop to the 17282 // LRU list if there is no other reason to keep 17283 // it around. We'll also tag it with a label just 17284 // to help debug and undertand what is going on. 17285 if (adj > clientAdj) { 17286 adjType = "cch-bound-services"; 17287 } 17288 clientAdj = adj; 17289 } 17290 } 17291 } 17292 if (adj > clientAdj) { 17293 // If this process has recently shown UI, and 17294 // the process that is binding to it is less 17295 // important than being visible, then we don't 17296 // care about the binding as much as we care 17297 // about letting this process get into the LRU 17298 // list to be killed and restarted if needed for 17299 // memory. 17300 if (app.hasShownUi && app != mHomeProcess 17301 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17302 adjType = "cch-bound-ui-services"; 17303 } else { 17304 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17305 |Context.BIND_IMPORTANT)) != 0) { 17306 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17307 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17308 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17309 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17310 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17311 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17312 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17313 adj = clientAdj; 17314 } else { 17315 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17316 adj = ProcessList.VISIBLE_APP_ADJ; 17317 } 17318 } 17319 if (!client.cached) { 17320 app.cached = false; 17321 } 17322 adjType = "service"; 17323 } 17324 } 17325 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17326 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17327 schedGroup = Process.THREAD_GROUP_DEFAULT; 17328 } 17329 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17330 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17331 // Special handling of clients who are in the top state. 17332 // We *may* want to consider this process to be in the 17333 // top state as well, but only if there is not another 17334 // reason for it to be running. Being on the top is a 17335 // special state, meaning you are specifically running 17336 // for the current top app. If the process is already 17337 // running in the background for some other reason, it 17338 // is more important to continue considering it to be 17339 // in the background state. 17340 mayBeTop = true; 17341 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17342 } else { 17343 // Special handling for above-top states (persistent 17344 // processes). These should not bring the current process 17345 // into the top state, since they are not on top. Instead 17346 // give them the best state after that. 17347 clientProcState = 17348 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17349 } 17350 } 17351 } else { 17352 if (clientProcState < 17353 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17354 clientProcState = 17355 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17356 } 17357 } 17358 if (procState > clientProcState) { 17359 procState = clientProcState; 17360 } 17361 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17362 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17363 app.pendingUiClean = true; 17364 } 17365 if (adjType != null) { 17366 app.adjType = adjType; 17367 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17368 .REASON_SERVICE_IN_USE; 17369 app.adjSource = cr.binding.client; 17370 app.adjSourceProcState = clientProcState; 17371 app.adjTarget = s.name; 17372 } 17373 } 17374 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17375 app.treatLikeActivity = true; 17376 } 17377 final ActivityRecord a = cr.activity; 17378 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17379 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17380 (a.visible || a.state == ActivityState.RESUMED 17381 || a.state == ActivityState.PAUSING)) { 17382 adj = ProcessList.FOREGROUND_APP_ADJ; 17383 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17384 schedGroup = Process.THREAD_GROUP_DEFAULT; 17385 } 17386 app.cached = false; 17387 app.adjType = "service"; 17388 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17389 .REASON_SERVICE_IN_USE; 17390 app.adjSource = a; 17391 app.adjSourceProcState = procState; 17392 app.adjTarget = s.name; 17393 } 17394 } 17395 } 17396 } 17397 } 17398 17399 for (int provi = app.pubProviders.size()-1; 17400 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17401 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17402 || procState > ActivityManager.PROCESS_STATE_TOP); 17403 provi--) { 17404 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17405 for (int i = cpr.connections.size()-1; 17406 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17407 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17408 || procState > ActivityManager.PROCESS_STATE_TOP); 17409 i--) { 17410 ContentProviderConnection conn = cpr.connections.get(i); 17411 ProcessRecord client = conn.client; 17412 if (client == app) { 17413 // Being our own client is not interesting. 17414 continue; 17415 } 17416 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17417 int clientProcState = client.curProcState; 17418 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17419 // If the other app is cached for any reason, for purposes here 17420 // we are going to consider it empty. 17421 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17422 } 17423 if (adj > clientAdj) { 17424 if (app.hasShownUi && app != mHomeProcess 17425 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17426 app.adjType = "cch-ui-provider"; 17427 } else { 17428 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17429 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17430 app.adjType = "provider"; 17431 } 17432 app.cached &= client.cached; 17433 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17434 .REASON_PROVIDER_IN_USE; 17435 app.adjSource = client; 17436 app.adjSourceProcState = clientProcState; 17437 app.adjTarget = cpr.name; 17438 } 17439 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17440 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17441 // Special handling of clients who are in the top state. 17442 // We *may* want to consider this process to be in the 17443 // top state as well, but only if there is not another 17444 // reason for it to be running. Being on the top is a 17445 // special state, meaning you are specifically running 17446 // for the current top app. If the process is already 17447 // running in the background for some other reason, it 17448 // is more important to continue considering it to be 17449 // in the background state. 17450 mayBeTop = true; 17451 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17452 } else { 17453 // Special handling for above-top states (persistent 17454 // processes). These should not bring the current process 17455 // into the top state, since they are not on top. Instead 17456 // give them the best state after that. 17457 clientProcState = 17458 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17459 } 17460 } 17461 if (procState > clientProcState) { 17462 procState = clientProcState; 17463 } 17464 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17465 schedGroup = Process.THREAD_GROUP_DEFAULT; 17466 } 17467 } 17468 // If the provider has external (non-framework) process 17469 // dependencies, ensure that its adjustment is at least 17470 // FOREGROUND_APP_ADJ. 17471 if (cpr.hasExternalProcessHandles()) { 17472 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17473 adj = ProcessList.FOREGROUND_APP_ADJ; 17474 schedGroup = Process.THREAD_GROUP_DEFAULT; 17475 app.cached = false; 17476 app.adjType = "provider"; 17477 app.adjTarget = cpr.name; 17478 } 17479 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17480 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17481 } 17482 } 17483 } 17484 17485 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17486 // A client of one of our services or providers is in the top state. We 17487 // *may* want to be in the top state, but not if we are already running in 17488 // the background for some other reason. For the decision here, we are going 17489 // to pick out a few specific states that we want to remain in when a client 17490 // is top (states that tend to be longer-term) and otherwise allow it to go 17491 // to the top state. 17492 switch (procState) { 17493 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17494 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17495 case ActivityManager.PROCESS_STATE_SERVICE: 17496 // These all are longer-term states, so pull them up to the top 17497 // of the background states, but not all the way to the top state. 17498 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17499 break; 17500 default: 17501 // Otherwise, top is a better choice, so take it. 17502 procState = ActivityManager.PROCESS_STATE_TOP; 17503 break; 17504 } 17505 } 17506 17507 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17508 if (app.hasClientActivities) { 17509 // This is a cached process, but with client activities. Mark it so. 17510 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17511 app.adjType = "cch-client-act"; 17512 } else if (app.treatLikeActivity) { 17513 // This is a cached process, but somebody wants us to treat it like it has 17514 // an activity, okay! 17515 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17516 app.adjType = "cch-as-act"; 17517 } 17518 } 17519 17520 if (adj == ProcessList.SERVICE_ADJ) { 17521 if (doingAll) { 17522 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17523 mNewNumServiceProcs++; 17524 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17525 if (!app.serviceb) { 17526 // This service isn't far enough down on the LRU list to 17527 // normally be a B service, but if we are low on RAM and it 17528 // is large we want to force it down since we would prefer to 17529 // keep launcher over it. 17530 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17531 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17532 app.serviceHighRam = true; 17533 app.serviceb = true; 17534 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17535 } else { 17536 mNewNumAServiceProcs++; 17537 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17538 } 17539 } else { 17540 app.serviceHighRam = false; 17541 } 17542 } 17543 if (app.serviceb) { 17544 adj = ProcessList.SERVICE_B_ADJ; 17545 } 17546 } 17547 17548 app.curRawAdj = adj; 17549 17550 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17551 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17552 if (adj > app.maxAdj) { 17553 adj = app.maxAdj; 17554 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17555 schedGroup = Process.THREAD_GROUP_DEFAULT; 17556 } 17557 } 17558 17559 // Do final modification to adj. Everything we do between here and applying 17560 // the final setAdj must be done in this function, because we will also use 17561 // it when computing the final cached adj later. Note that we don't need to 17562 // worry about this for max adj above, since max adj will always be used to 17563 // keep it out of the cached vaues. 17564 app.curAdj = app.modifyRawOomAdj(adj); 17565 app.curSchedGroup = schedGroup; 17566 app.curProcState = procState; 17567 app.foregroundActivities = foregroundActivities; 17568 17569 return app.curRawAdj; 17570 } 17571 17572 /** 17573 * Record new PSS sample for a process. 17574 */ recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now)17575 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17576 proc.lastPssTime = now; 17577 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17578 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17579 + ": " + pss + " lastPss=" + proc.lastPss 17580 + " state=" + ProcessList.makeProcStateString(procState)); 17581 if (proc.initialIdlePss == 0) { 17582 proc.initialIdlePss = pss; 17583 } 17584 proc.lastPss = pss; 17585 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17586 proc.lastCachedPss = pss; 17587 } 17588 } 17589 17590 /** 17591 * Schedule PSS collection of a process. 17592 */ requestPssLocked(ProcessRecord proc, int procState)17593 void requestPssLocked(ProcessRecord proc, int procState) { 17594 if (mPendingPssProcesses.contains(proc)) { 17595 return; 17596 } 17597 if (mPendingPssProcesses.size() == 0) { 17598 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17599 } 17600 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17601 proc.pssProcState = procState; 17602 mPendingPssProcesses.add(proc); 17603 } 17604 17605 /** 17606 * Schedule PSS collection of all processes. 17607 */ requestPssAllProcsLocked(long now, boolean always, boolean memLowered)17608 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17609 if (!always) { 17610 if (now < (mLastFullPssTime + 17611 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17612 return; 17613 } 17614 } 17615 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17616 mLastFullPssTime = now; 17617 mFullPssPending = true; 17618 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17619 mPendingPssProcesses.clear(); 17620 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17621 ProcessRecord app = mLruProcesses.get(i); 17622 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17623 app.pssProcState = app.setProcState; 17624 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17625 mTestPssMode, isSleeping(), now); 17626 mPendingPssProcesses.add(app); 17627 } 17628 } 17629 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17630 } 17631 setTestPssMode(boolean enabled)17632 public void setTestPssMode(boolean enabled) { 17633 synchronized (this) { 17634 mTestPssMode = enabled; 17635 if (enabled) { 17636 // Whenever we enable the mode, we want to take a snapshot all of current 17637 // process mem use. 17638 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17639 } 17640 } 17641 } 17642 17643 /** 17644 * Ask a given process to GC right now. 17645 */ performAppGcLocked(ProcessRecord app)17646 final void performAppGcLocked(ProcessRecord app) { 17647 try { 17648 app.lastRequestedGc = SystemClock.uptimeMillis(); 17649 if (app.thread != null) { 17650 if (app.reportLowMemory) { 17651 app.reportLowMemory = false; 17652 app.thread.scheduleLowMemory(); 17653 } else { 17654 app.thread.processInBackground(); 17655 } 17656 } 17657 } catch (Exception e) { 17658 // whatever. 17659 } 17660 } 17661 17662 /** 17663 * Returns true if things are idle enough to perform GCs. 17664 */ canGcNowLocked()17665 private final boolean canGcNowLocked() { 17666 boolean processingBroadcasts = false; 17667 for (BroadcastQueue q : mBroadcastQueues) { 17668 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17669 processingBroadcasts = true; 17670 } 17671 } 17672 return !processingBroadcasts 17673 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17674 } 17675 17676 /** 17677 * Perform GCs on all processes that are waiting for it, but only 17678 * if things are idle. 17679 */ performAppGcsLocked()17680 final void performAppGcsLocked() { 17681 final int N = mProcessesToGc.size(); 17682 if (N <= 0) { 17683 return; 17684 } 17685 if (canGcNowLocked()) { 17686 while (mProcessesToGc.size() > 0) { 17687 ProcessRecord proc = mProcessesToGc.remove(0); 17688 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17689 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17690 <= SystemClock.uptimeMillis()) { 17691 // To avoid spamming the system, we will GC processes one 17692 // at a time, waiting a few seconds between each. 17693 performAppGcLocked(proc); 17694 scheduleAppGcsLocked(); 17695 return; 17696 } else { 17697 // It hasn't been long enough since we last GCed this 17698 // process... put it in the list to wait for its time. 17699 addProcessToGcListLocked(proc); 17700 break; 17701 } 17702 } 17703 } 17704 17705 scheduleAppGcsLocked(); 17706 } 17707 } 17708 17709 /** 17710 * If all looks good, perform GCs on all processes waiting for them. 17711 */ performAppGcsIfAppropriateLocked()17712 final void performAppGcsIfAppropriateLocked() { 17713 if (canGcNowLocked()) { 17714 performAppGcsLocked(); 17715 return; 17716 } 17717 // Still not idle, wait some more. 17718 scheduleAppGcsLocked(); 17719 } 17720 17721 /** 17722 * Schedule the execution of all pending app GCs. 17723 */ scheduleAppGcsLocked()17724 final void scheduleAppGcsLocked() { 17725 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17726 17727 if (mProcessesToGc.size() > 0) { 17728 // Schedule a GC for the time to the next process. 17729 ProcessRecord proc = mProcessesToGc.get(0); 17730 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17731 17732 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17733 long now = SystemClock.uptimeMillis(); 17734 if (when < (now+GC_TIMEOUT)) { 17735 when = now + GC_TIMEOUT; 17736 } 17737 mHandler.sendMessageAtTime(msg, when); 17738 } 17739 } 17740 17741 /** 17742 * Add a process to the array of processes waiting to be GCed. Keeps the 17743 * list in sorted order by the last GC time. The process can't already be 17744 * on the list. 17745 */ addProcessToGcListLocked(ProcessRecord proc)17746 final void addProcessToGcListLocked(ProcessRecord proc) { 17747 boolean added = false; 17748 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17749 if (mProcessesToGc.get(i).lastRequestedGc < 17750 proc.lastRequestedGc) { 17751 added = true; 17752 mProcessesToGc.add(i+1, proc); 17753 break; 17754 } 17755 } 17756 if (!added) { 17757 mProcessesToGc.add(0, proc); 17758 } 17759 } 17760 17761 /** 17762 * Set up to ask a process to GC itself. This will either do it 17763 * immediately, or put it on the list of processes to gc the next 17764 * time things are idle. 17765 */ scheduleAppGcLocked(ProcessRecord app)17766 final void scheduleAppGcLocked(ProcessRecord app) { 17767 long now = SystemClock.uptimeMillis(); 17768 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17769 return; 17770 } 17771 if (!mProcessesToGc.contains(app)) { 17772 addProcessToGcListLocked(app); 17773 scheduleAppGcsLocked(); 17774 } 17775 } 17776 checkExcessivePowerUsageLocked(boolean doKills)17777 final void checkExcessivePowerUsageLocked(boolean doKills) { 17778 updateCpuStatsNow(); 17779 17780 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17781 boolean doWakeKills = doKills; 17782 boolean doCpuKills = doKills; 17783 if (mLastPowerCheckRealtime == 0) { 17784 doWakeKills = false; 17785 } 17786 if (mLastPowerCheckUptime == 0) { 17787 doCpuKills = false; 17788 } 17789 if (stats.isScreenOn()) { 17790 doWakeKills = false; 17791 } 17792 final long curRealtime = SystemClock.elapsedRealtime(); 17793 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17794 final long curUptime = SystemClock.uptimeMillis(); 17795 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17796 mLastPowerCheckRealtime = curRealtime; 17797 mLastPowerCheckUptime = curUptime; 17798 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17799 doWakeKills = false; 17800 } 17801 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17802 doCpuKills = false; 17803 } 17804 int i = mLruProcesses.size(); 17805 while (i > 0) { 17806 i--; 17807 ProcessRecord app = mLruProcesses.get(i); 17808 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17809 long wtime; 17810 synchronized (stats) { 17811 wtime = stats.getProcessWakeTime(app.info.uid, 17812 app.pid, curRealtime); 17813 } 17814 long wtimeUsed = wtime - app.lastWakeTime; 17815 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17816 if (DEBUG_POWER) { 17817 StringBuilder sb = new StringBuilder(128); 17818 sb.append("Wake for "); 17819 app.toShortString(sb); 17820 sb.append(": over "); 17821 TimeUtils.formatDuration(realtimeSince, sb); 17822 sb.append(" used "); 17823 TimeUtils.formatDuration(wtimeUsed, sb); 17824 sb.append(" ("); 17825 sb.append((wtimeUsed*100)/realtimeSince); 17826 sb.append("%)"); 17827 Slog.i(TAG, sb.toString()); 17828 sb.setLength(0); 17829 sb.append("CPU for "); 17830 app.toShortString(sb); 17831 sb.append(": over "); 17832 TimeUtils.formatDuration(uptimeSince, sb); 17833 sb.append(" used "); 17834 TimeUtils.formatDuration(cputimeUsed, sb); 17835 sb.append(" ("); 17836 sb.append((cputimeUsed*100)/uptimeSince); 17837 sb.append("%)"); 17838 Slog.i(TAG, sb.toString()); 17839 } 17840 // If a process has held a wake lock for more 17841 // than 50% of the time during this period, 17842 // that sounds bad. Kill! 17843 if (doWakeKills && realtimeSince > 0 17844 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17845 synchronized (stats) { 17846 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17847 realtimeSince, wtimeUsed); 17848 } 17849 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17850 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17851 } else if (doCpuKills && uptimeSince > 0 17852 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17853 synchronized (stats) { 17854 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17855 uptimeSince, cputimeUsed); 17856 } 17857 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17858 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17859 } else { 17860 app.lastWakeTime = wtime; 17861 app.lastCpuTime = app.curCpuTime; 17862 } 17863 } 17864 } 17865 } 17866 applyOomAdjLocked(ProcessRecord app, ProcessRecord TOP_APP, boolean doingAll, long now)17867 private final boolean applyOomAdjLocked(ProcessRecord app, 17868 ProcessRecord TOP_APP, boolean doingAll, long now) { 17869 boolean success = true; 17870 17871 if (app.curRawAdj != app.setRawAdj) { 17872 app.setRawAdj = app.curRawAdj; 17873 } 17874 17875 int changes = 0; 17876 17877 if (app.curAdj != app.setAdj) { 17878 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17879 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17880 TAG, "Set " + app.pid + " " + app.processName + 17881 " adj " + app.curAdj + ": " + app.adjType); 17882 app.setAdj = app.curAdj; 17883 } 17884 17885 if (app.setSchedGroup != app.curSchedGroup) { 17886 app.setSchedGroup = app.curSchedGroup; 17887 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17888 "Setting process group of " + app.processName 17889 + " to " + app.curSchedGroup); 17890 if (app.waitingToKill != null && 17891 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17892 app.kill(app.waitingToKill, true); 17893 success = false; 17894 } else { 17895 if (true) { 17896 long oldId = Binder.clearCallingIdentity(); 17897 try { 17898 Process.setProcessGroup(app.pid, app.curSchedGroup); 17899 } catch (Exception e) { 17900 Slog.w(TAG, "Failed setting process group of " + app.pid 17901 + " to " + app.curSchedGroup); 17902 e.printStackTrace(); 17903 } finally { 17904 Binder.restoreCallingIdentity(oldId); 17905 } 17906 } else { 17907 if (app.thread != null) { 17908 try { 17909 app.thread.setSchedulingGroup(app.curSchedGroup); 17910 } catch (RemoteException e) { 17911 } 17912 } 17913 } 17914 Process.setSwappiness(app.pid, 17915 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17916 } 17917 } 17918 if (app.repForegroundActivities != app.foregroundActivities) { 17919 app.repForegroundActivities = app.foregroundActivities; 17920 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17921 } 17922 if (app.repProcState != app.curProcState) { 17923 app.repProcState = app.curProcState; 17924 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17925 if (app.thread != null) { 17926 try { 17927 if (false) { 17928 //RuntimeException h = new RuntimeException("here"); 17929 Slog.i(TAG, "Sending new process state " + app.repProcState 17930 + " to " + app /*, h*/); 17931 } 17932 app.thread.setProcessState(app.repProcState); 17933 } catch (RemoteException e) { 17934 } 17935 } 17936 } 17937 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17938 app.setProcState)) { 17939 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17940 // Experimental code to more aggressively collect pss while 17941 // running test... the problem is that this tends to collect 17942 // the data right when a process is transitioning between process 17943 // states, which well tend to give noisy data. 17944 long start = SystemClock.uptimeMillis(); 17945 long pss = Debug.getPss(app.pid, mTmpLong, null); 17946 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17947 mPendingPssProcesses.remove(app); 17948 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17949 + " to " + app.curProcState + ": " 17950 + (SystemClock.uptimeMillis()-start) + "ms"); 17951 } 17952 app.lastStateTime = now; 17953 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17954 mTestPssMode, isSleeping(), now); 17955 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17956 + ProcessList.makeProcStateString(app.setProcState) + " to " 17957 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17958 + (app.nextPssTime-now) + ": " + app); 17959 } else { 17960 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17961 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17962 mTestPssMode)))) { 17963 requestPssLocked(app, app.setProcState); 17964 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17965 mTestPssMode, isSleeping(), now); 17966 } else if (false && DEBUG_PSS) { 17967 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17968 } 17969 } 17970 if (app.setProcState != app.curProcState) { 17971 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17972 "Proc state change of " + app.processName 17973 + " to " + app.curProcState); 17974 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17975 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17976 if (setImportant && !curImportant) { 17977 // This app is no longer something we consider important enough to allow to 17978 // use arbitrary amounts of battery power. Note 17979 // its current wake lock time to later know to kill it if 17980 // it is not behaving well. 17981 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17982 synchronized (stats) { 17983 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17984 app.pid, SystemClock.elapsedRealtime()); 17985 } 17986 app.lastCpuTime = app.curCpuTime; 17987 17988 } 17989 app.setProcState = app.curProcState; 17990 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17991 app.notCachedSinceIdle = false; 17992 } 17993 if (!doingAll) { 17994 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17995 } else { 17996 app.procStateChanged = true; 17997 } 17998 } 17999 18000 if (changes != 0) { 18001 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 18002 int i = mPendingProcessChanges.size()-1; 18003 ProcessChangeItem item = null; 18004 while (i >= 0) { 18005 item = mPendingProcessChanges.get(i); 18006 if (item.pid == app.pid) { 18007 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 18008 break; 18009 } 18010 i--; 18011 } 18012 if (i < 0) { 18013 // No existing item in pending changes; need a new one. 18014 final int NA = mAvailProcessChanges.size(); 18015 if (NA > 0) { 18016 item = mAvailProcessChanges.remove(NA-1); 18017 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 18018 } else { 18019 item = new ProcessChangeItem(); 18020 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 18021 } 18022 item.changes = 0; 18023 item.pid = app.pid; 18024 item.uid = app.info.uid; 18025 if (mPendingProcessChanges.size() == 0) { 18026 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 18027 "*** Enqueueing dispatch processes changed!"); 18028 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 18029 } 18030 mPendingProcessChanges.add(item); 18031 } 18032 item.changes |= changes; 18033 item.processState = app.repProcState; 18034 item.foregroundActivities = app.repForegroundActivities; 18035 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 18036 + Integer.toHexString(System.identityHashCode(item)) 18037 + " " + app.toShortString() + ": changes=" + item.changes 18038 + " procState=" + item.processState 18039 + " foreground=" + item.foregroundActivities 18040 + " type=" + app.adjType + " source=" + app.adjSource 18041 + " target=" + app.adjTarget); 18042 } 18043 18044 return success; 18045 } 18046 setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now)18047 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 18048 if (proc.thread != null) { 18049 if (proc.baseProcessTracker != null) { 18050 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 18051 } 18052 if (proc.repProcState >= 0) { 18053 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 18054 proc.repProcState); 18055 } 18056 } 18057 } 18058 updateOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, long now)18059 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 18060 ProcessRecord TOP_APP, boolean doingAll, long now) { 18061 if (app.thread == null) { 18062 return false; 18063 } 18064 18065 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 18066 18067 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 18068 } 18069 updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, boolean oomAdj)18070 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 18071 boolean oomAdj) { 18072 if (isForeground != proc.foregroundServices) { 18073 proc.foregroundServices = isForeground; 18074 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 18075 proc.info.uid); 18076 if (isForeground) { 18077 if (curProcs == null) { 18078 curProcs = new ArrayList<ProcessRecord>(); 18079 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 18080 } 18081 if (!curProcs.contains(proc)) { 18082 curProcs.add(proc); 18083 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 18084 proc.info.packageName, proc.info.uid); 18085 } 18086 } else { 18087 if (curProcs != null) { 18088 if (curProcs.remove(proc)) { 18089 mBatteryStatsService.noteEvent( 18090 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 18091 proc.info.packageName, proc.info.uid); 18092 if (curProcs.size() <= 0) { 18093 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 18094 } 18095 } 18096 } 18097 } 18098 if (oomAdj) { 18099 updateOomAdjLocked(); 18100 } 18101 } 18102 } 18103 resumedAppLocked()18104 private final ActivityRecord resumedAppLocked() { 18105 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 18106 String pkg; 18107 int uid; 18108 if (act != null) { 18109 pkg = act.packageName; 18110 uid = act.info.applicationInfo.uid; 18111 } else { 18112 pkg = null; 18113 uid = -1; 18114 } 18115 // Has the UID or resumed package name changed? 18116 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 18117 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 18118 if (mCurResumedPackage != null) { 18119 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 18120 mCurResumedPackage, mCurResumedUid); 18121 } 18122 mCurResumedPackage = pkg; 18123 mCurResumedUid = uid; 18124 if (mCurResumedPackage != null) { 18125 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 18126 mCurResumedPackage, mCurResumedUid); 18127 } 18128 } 18129 return act; 18130 } 18131 updateOomAdjLocked(ProcessRecord app)18132 final boolean updateOomAdjLocked(ProcessRecord app) { 18133 final ActivityRecord TOP_ACT = resumedAppLocked(); 18134 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18135 final boolean wasCached = app.cached; 18136 18137 mAdjSeq++; 18138 18139 // This is the desired cached adjusment we want to tell it to use. 18140 // If our app is currently cached, we know it, and that is it. Otherwise, 18141 // we don't know it yet, and it needs to now be cached we will then 18142 // need to do a complete oom adj. 18143 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 18144 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 18145 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 18146 SystemClock.uptimeMillis()); 18147 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 18148 // Changed to/from cached state, so apps after it in the LRU 18149 // list may also be changed. 18150 updateOomAdjLocked(); 18151 } 18152 return success; 18153 } 18154 updateOomAdjLocked()18155 final void updateOomAdjLocked() { 18156 final ActivityRecord TOP_ACT = resumedAppLocked(); 18157 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18158 final long now = SystemClock.uptimeMillis(); 18159 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 18160 final int N = mLruProcesses.size(); 18161 18162 if (false) { 18163 RuntimeException e = new RuntimeException(); 18164 e.fillInStackTrace(); 18165 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 18166 } 18167 18168 mAdjSeq++; 18169 mNewNumServiceProcs = 0; 18170 mNewNumAServiceProcs = 0; 18171 18172 final int emptyProcessLimit; 18173 final int cachedProcessLimit; 18174 if (mProcessLimit <= 0) { 18175 emptyProcessLimit = cachedProcessLimit = 0; 18176 } else if (mProcessLimit == 1) { 18177 emptyProcessLimit = 1; 18178 cachedProcessLimit = 0; 18179 } else { 18180 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 18181 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 18182 } 18183 18184 // Let's determine how many processes we have running vs. 18185 // how many slots we have for background processes; we may want 18186 // to put multiple processes in a slot of there are enough of 18187 // them. 18188 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 18189 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 18190 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 18191 if (numEmptyProcs > cachedProcessLimit) { 18192 // If there are more empty processes than our limit on cached 18193 // processes, then use the cached process limit for the factor. 18194 // This ensures that the really old empty processes get pushed 18195 // down to the bottom, so if we are running low on memory we will 18196 // have a better chance at keeping around more cached processes 18197 // instead of a gazillion empty processes. 18198 numEmptyProcs = cachedProcessLimit; 18199 } 18200 int emptyFactor = numEmptyProcs/numSlots; 18201 if (emptyFactor < 1) emptyFactor = 1; 18202 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 18203 if (cachedFactor < 1) cachedFactor = 1; 18204 int stepCached = 0; 18205 int stepEmpty = 0; 18206 int numCached = 0; 18207 int numEmpty = 0; 18208 int numTrimming = 0; 18209 18210 mNumNonCachedProcs = 0; 18211 mNumCachedHiddenProcs = 0; 18212 18213 // First update the OOM adjustment for each of the 18214 // application processes based on their current state. 18215 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18216 int nextCachedAdj = curCachedAdj+1; 18217 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18218 int nextEmptyAdj = curEmptyAdj+2; 18219 for (int i=N-1; i>=0; i--) { 18220 ProcessRecord app = mLruProcesses.get(i); 18221 if (!app.killedByAm && app.thread != null) { 18222 app.procStateChanged = false; 18223 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18224 18225 // If we haven't yet assigned the final cached adj 18226 // to the process, do that now. 18227 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18228 switch (app.curProcState) { 18229 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18230 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18231 // This process is a cached process holding activities... 18232 // assign it the next cached value for that type, and then 18233 // step that cached level. 18234 app.curRawAdj = curCachedAdj; 18235 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18236 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18237 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18238 + ")"); 18239 if (curCachedAdj != nextCachedAdj) { 18240 stepCached++; 18241 if (stepCached >= cachedFactor) { 18242 stepCached = 0; 18243 curCachedAdj = nextCachedAdj; 18244 nextCachedAdj += 2; 18245 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18246 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18247 } 18248 } 18249 } 18250 break; 18251 default: 18252 // For everything else, assign next empty cached process 18253 // level and bump that up. Note that this means that 18254 // long-running services that have dropped down to the 18255 // cached level will be treated as empty (since their process 18256 // state is still as a service), which is what we want. 18257 app.curRawAdj = curEmptyAdj; 18258 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18259 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18260 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18261 + ")"); 18262 if (curEmptyAdj != nextEmptyAdj) { 18263 stepEmpty++; 18264 if (stepEmpty >= emptyFactor) { 18265 stepEmpty = 0; 18266 curEmptyAdj = nextEmptyAdj; 18267 nextEmptyAdj += 2; 18268 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18269 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18270 } 18271 } 18272 } 18273 break; 18274 } 18275 } 18276 18277 applyOomAdjLocked(app, TOP_APP, true, now); 18278 18279 // Count the number of process types. 18280 switch (app.curProcState) { 18281 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18282 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18283 mNumCachedHiddenProcs++; 18284 numCached++; 18285 if (numCached > cachedProcessLimit) { 18286 app.kill("cached #" + numCached, true); 18287 } 18288 break; 18289 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18290 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18291 && app.lastActivityTime < oldTime) { 18292 app.kill("empty for " 18293 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18294 / 1000) + "s", true); 18295 } else { 18296 numEmpty++; 18297 if (numEmpty > emptyProcessLimit) { 18298 app.kill("empty #" + numEmpty, true); 18299 } 18300 } 18301 break; 18302 default: 18303 mNumNonCachedProcs++; 18304 break; 18305 } 18306 18307 if (app.isolated && app.services.size() <= 0) { 18308 // If this is an isolated process, and there are no 18309 // services running in it, then the process is no longer 18310 // needed. We agressively kill these because we can by 18311 // definition not re-use the same process again, and it is 18312 // good to avoid having whatever code was running in them 18313 // left sitting around after no longer needed. 18314 app.kill("isolated not needed", true); 18315 } 18316 18317 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18318 && !app.killedByAm) { 18319 numTrimming++; 18320 } 18321 } 18322 } 18323 18324 mNumServiceProcs = mNewNumServiceProcs; 18325 18326 // Now determine the memory trimming level of background processes. 18327 // Unfortunately we need to start at the back of the list to do this 18328 // properly. We only do this if the number of background apps we 18329 // are managing to keep around is less than half the maximum we desire; 18330 // if we are keeping a good number around, we'll let them use whatever 18331 // memory they want. 18332 final int numCachedAndEmpty = numCached + numEmpty; 18333 int memFactor; 18334 if (numCached <= ProcessList.TRIM_CACHED_APPS 18335 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18336 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18337 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18338 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18339 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18340 } else { 18341 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18342 } 18343 } else { 18344 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18345 } 18346 // We always allow the memory level to go up (better). We only allow it to go 18347 // down if we are in a state where that is allowed, *and* the total number of processes 18348 // has gone down since last time. 18349 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18350 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18351 + " last=" + mLastNumProcesses); 18352 if (memFactor > mLastMemoryLevel) { 18353 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18354 memFactor = mLastMemoryLevel; 18355 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18356 } 18357 } 18358 mLastMemoryLevel = memFactor; 18359 mLastNumProcesses = mLruProcesses.size(); 18360 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18361 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18362 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18363 if (mLowRamStartTime == 0) { 18364 mLowRamStartTime = now; 18365 } 18366 int step = 0; 18367 int fgTrimLevel; 18368 switch (memFactor) { 18369 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18370 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18371 break; 18372 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18373 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18374 break; 18375 default: 18376 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18377 break; 18378 } 18379 int factor = numTrimming/3; 18380 int minFactor = 2; 18381 if (mHomeProcess != null) minFactor++; 18382 if (mPreviousProcess != null) minFactor++; 18383 if (factor < minFactor) factor = minFactor; 18384 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18385 for (int i=N-1; i>=0; i--) { 18386 ProcessRecord app = mLruProcesses.get(i); 18387 if (allChanged || app.procStateChanged) { 18388 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18389 app.procStateChanged = false; 18390 } 18391 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18392 && !app.killedByAm) { 18393 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18394 try { 18395 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18396 "Trimming memory of " + app.processName 18397 + " to " + curLevel); 18398 app.thread.scheduleTrimMemory(curLevel); 18399 } catch (RemoteException e) { 18400 } 18401 if (false) { 18402 // For now we won't do this; our memory trimming seems 18403 // to be good enough at this point that destroying 18404 // activities causes more harm than good. 18405 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18406 && app != mHomeProcess && app != mPreviousProcess) { 18407 // Need to do this on its own message because the stack may not 18408 // be in a consistent state at this point. 18409 // For these apps we will also finish their activities 18410 // to help them free memory. 18411 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18412 } 18413 } 18414 } 18415 app.trimMemoryLevel = curLevel; 18416 step++; 18417 if (step >= factor) { 18418 step = 0; 18419 switch (curLevel) { 18420 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18421 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18422 break; 18423 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18424 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18425 break; 18426 } 18427 } 18428 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18429 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18430 && app.thread != null) { 18431 try { 18432 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18433 "Trimming memory of heavy-weight " + app.processName 18434 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18435 app.thread.scheduleTrimMemory( 18436 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18437 } catch (RemoteException e) { 18438 } 18439 } 18440 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18441 } else { 18442 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18443 || app.systemNoUi) && app.pendingUiClean) { 18444 // If this application is now in the background and it 18445 // had done UI, then give it the special trim level to 18446 // have it free UI resources. 18447 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18448 if (app.trimMemoryLevel < level && app.thread != null) { 18449 try { 18450 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18451 "Trimming memory of bg-ui " + app.processName 18452 + " to " + level); 18453 app.thread.scheduleTrimMemory(level); 18454 } catch (RemoteException e) { 18455 } 18456 } 18457 app.pendingUiClean = false; 18458 } 18459 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18460 try { 18461 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18462 "Trimming memory of fg " + app.processName 18463 + " to " + fgTrimLevel); 18464 app.thread.scheduleTrimMemory(fgTrimLevel); 18465 } catch (RemoteException e) { 18466 } 18467 } 18468 app.trimMemoryLevel = fgTrimLevel; 18469 } 18470 } 18471 } else { 18472 if (mLowRamStartTime != 0) { 18473 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18474 mLowRamStartTime = 0; 18475 } 18476 for (int i=N-1; i>=0; i--) { 18477 ProcessRecord app = mLruProcesses.get(i); 18478 if (allChanged || app.procStateChanged) { 18479 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18480 app.procStateChanged = false; 18481 } 18482 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18483 || app.systemNoUi) && app.pendingUiClean) { 18484 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18485 && app.thread != null) { 18486 try { 18487 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18488 "Trimming memory of ui hidden " + app.processName 18489 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18490 app.thread.scheduleTrimMemory( 18491 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18492 } catch (RemoteException e) { 18493 } 18494 } 18495 app.pendingUiClean = false; 18496 } 18497 app.trimMemoryLevel = 0; 18498 } 18499 } 18500 18501 if (mAlwaysFinishActivities) { 18502 // Need to do this on its own message because the stack may not 18503 // be in a consistent state at this point. 18504 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18505 } 18506 18507 if (allChanged) { 18508 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18509 } 18510 18511 if (mProcessStats.shouldWriteNowLocked(now)) { 18512 mHandler.post(new Runnable() { 18513 @Override public void run() { 18514 synchronized (ActivityManagerService.this) { 18515 mProcessStats.writeStateAsyncLocked(); 18516 } 18517 } 18518 }); 18519 } 18520 18521 if (DEBUG_OOM_ADJ) { 18522 if (false) { 18523 RuntimeException here = new RuntimeException("here"); 18524 here.fillInStackTrace(); 18525 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18526 } else { 18527 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18528 } 18529 } 18530 } 18531 trimApplications()18532 final void trimApplications() { 18533 synchronized (this) { 18534 int i; 18535 18536 // First remove any unused application processes whose package 18537 // has been removed. 18538 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18539 final ProcessRecord app = mRemovedProcesses.get(i); 18540 if (app.activities.size() == 0 18541 && app.curReceiver == null && app.services.size() == 0) { 18542 Slog.i( 18543 TAG, "Exiting empty application process " 18544 + app.processName + " (" 18545 + (app.thread != null ? app.thread.asBinder() : null) 18546 + ")\n"); 18547 if (app.pid > 0 && app.pid != MY_PID) { 18548 app.kill("empty", false); 18549 } else { 18550 try { 18551 app.thread.scheduleExit(); 18552 } catch (Exception e) { 18553 // Ignore exceptions. 18554 } 18555 } 18556 cleanUpApplicationRecordLocked(app, false, true, -1); 18557 mRemovedProcesses.remove(i); 18558 18559 if (app.persistent) { 18560 addAppLocked(app.info, false, null /* ABI override */); 18561 } 18562 } 18563 } 18564 18565 // Now update the oom adj for all processes. 18566 updateOomAdjLocked(); 18567 } 18568 } 18569 18570 /** This method sends the specified signal to each of the persistent apps */ signalPersistentProcesses(int sig)18571 public void signalPersistentProcesses(int sig) throws RemoteException { 18572 if (sig != Process.SIGNAL_USR1) { 18573 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18574 } 18575 18576 synchronized (this) { 18577 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18578 != PackageManager.PERMISSION_GRANTED) { 18579 throw new SecurityException("Requires permission " 18580 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18581 } 18582 18583 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18584 ProcessRecord r = mLruProcesses.get(i); 18585 if (r.thread != null && r.persistent) { 18586 Process.sendSignal(r.pid, sig); 18587 } 18588 } 18589 } 18590 } 18591 stopProfilerLocked(ProcessRecord proc, int profileType)18592 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18593 if (proc == null || proc == mProfileProc) { 18594 proc = mProfileProc; 18595 profileType = mProfileType; 18596 clearProfilerLocked(); 18597 } 18598 if (proc == null) { 18599 return; 18600 } 18601 try { 18602 proc.thread.profilerControl(false, null, profileType); 18603 } catch (RemoteException e) { 18604 throw new IllegalStateException("Process disappeared"); 18605 } 18606 } 18607 clearProfilerLocked()18608 private void clearProfilerLocked() { 18609 if (mProfileFd != null) { 18610 try { 18611 mProfileFd.close(); 18612 } catch (IOException e) { 18613 } 18614 } 18615 mProfileApp = null; 18616 mProfileProc = null; 18617 mProfileFile = null; 18618 mProfileType = 0; 18619 mAutoStopProfiler = false; 18620 mSamplingInterval = 0; 18621 } 18622 profileControl(String process, int userId, boolean start, ProfilerInfo profilerInfo, int profileType)18623 public boolean profileControl(String process, int userId, boolean start, 18624 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18625 18626 try { 18627 synchronized (this) { 18628 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18629 // its own permission. 18630 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18631 != PackageManager.PERMISSION_GRANTED) { 18632 throw new SecurityException("Requires permission " 18633 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18634 } 18635 18636 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18637 throw new IllegalArgumentException("null profile info or fd"); 18638 } 18639 18640 ProcessRecord proc = null; 18641 if (process != null) { 18642 proc = findProcessLocked(process, userId, "profileControl"); 18643 } 18644 18645 if (start && (proc == null || proc.thread == null)) { 18646 throw new IllegalArgumentException("Unknown process: " + process); 18647 } 18648 18649 if (start) { 18650 stopProfilerLocked(null, 0); 18651 setProfileApp(proc.info, proc.processName, profilerInfo); 18652 mProfileProc = proc; 18653 mProfileType = profileType; 18654 ParcelFileDescriptor fd = profilerInfo.profileFd; 18655 try { 18656 fd = fd.dup(); 18657 } catch (IOException e) { 18658 fd = null; 18659 } 18660 profilerInfo.profileFd = fd; 18661 proc.thread.profilerControl(start, profilerInfo, profileType); 18662 fd = null; 18663 mProfileFd = null; 18664 } else { 18665 stopProfilerLocked(proc, profileType); 18666 if (profilerInfo != null && profilerInfo.profileFd != null) { 18667 try { 18668 profilerInfo.profileFd.close(); 18669 } catch (IOException e) { 18670 } 18671 } 18672 } 18673 18674 return true; 18675 } 18676 } catch (RemoteException e) { 18677 throw new IllegalStateException("Process disappeared"); 18678 } finally { 18679 if (profilerInfo != null && profilerInfo.profileFd != null) { 18680 try { 18681 profilerInfo.profileFd.close(); 18682 } catch (IOException e) { 18683 } 18684 } 18685 } 18686 } 18687 findProcessLocked(String process, int userId, String callName)18688 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18689 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18690 userId, true, ALLOW_FULL_ONLY, callName, null); 18691 ProcessRecord proc = null; 18692 try { 18693 int pid = Integer.parseInt(process); 18694 synchronized (mPidsSelfLocked) { 18695 proc = mPidsSelfLocked.get(pid); 18696 } 18697 } catch (NumberFormatException e) { 18698 } 18699 18700 if (proc == null) { 18701 ArrayMap<String, SparseArray<ProcessRecord>> all 18702 = mProcessNames.getMap(); 18703 SparseArray<ProcessRecord> procs = all.get(process); 18704 if (procs != null && procs.size() > 0) { 18705 proc = procs.valueAt(0); 18706 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18707 for (int i=1; i<procs.size(); i++) { 18708 ProcessRecord thisProc = procs.valueAt(i); 18709 if (thisProc.userId == userId) { 18710 proc = thisProc; 18711 break; 18712 } 18713 } 18714 } 18715 } 18716 } 18717 18718 return proc; 18719 } 18720 dumpHeap(String process, int userId, boolean managed, String path, ParcelFileDescriptor fd)18721 public boolean dumpHeap(String process, int userId, boolean managed, 18722 String path, ParcelFileDescriptor fd) throws RemoteException { 18723 18724 try { 18725 synchronized (this) { 18726 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18727 // its own permission (same as profileControl). 18728 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18729 != PackageManager.PERMISSION_GRANTED) { 18730 throw new SecurityException("Requires permission " 18731 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18732 } 18733 18734 if (fd == null) { 18735 throw new IllegalArgumentException("null fd"); 18736 } 18737 18738 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18739 if (proc == null || proc.thread == null) { 18740 throw new IllegalArgumentException("Unknown process: " + process); 18741 } 18742 18743 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18744 if (!isDebuggable) { 18745 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18746 throw new SecurityException("Process not debuggable: " + proc); 18747 } 18748 } 18749 18750 proc.thread.dumpHeap(managed, path, fd); 18751 fd = null; 18752 return true; 18753 } 18754 } catch (RemoteException e) { 18755 throw new IllegalStateException("Process disappeared"); 18756 } finally { 18757 if (fd != null) { 18758 try { 18759 fd.close(); 18760 } catch (IOException e) { 18761 } 18762 } 18763 } 18764 } 18765 18766 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ monitor()18767 public void monitor() { 18768 synchronized (this) { } 18769 } 18770 onCoreSettingsChange(Bundle settings)18771 void onCoreSettingsChange(Bundle settings) { 18772 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18773 ProcessRecord processRecord = mLruProcesses.get(i); 18774 try { 18775 if (processRecord.thread != null) { 18776 processRecord.thread.setCoreSettings(settings); 18777 } 18778 } catch (RemoteException re) { 18779 /* ignore */ 18780 } 18781 } 18782 } 18783 18784 // Multi-user methods 18785 18786 /** 18787 * Start user, if its not already running, but don't bring it to foreground. 18788 */ 18789 @Override startUserInBackground(final int userId)18790 public boolean startUserInBackground(final int userId) { 18791 return startUser(userId, /* foreground */ false); 18792 } 18793 18794 /** 18795 * Start user, if its not already running, and bring it to foreground. 18796 */ startUserInForeground(final int userId, Dialog dlg)18797 boolean startUserInForeground(final int userId, Dialog dlg) { 18798 boolean result = startUser(userId, /* foreground */ true); 18799 dlg.dismiss(); 18800 return result; 18801 } 18802 18803 /** 18804 * Refreshes the list of users related to the current user when either a 18805 * user switch happens or when a new related user is started in the 18806 * background. 18807 */ updateCurrentProfileIdsLocked()18808 private void updateCurrentProfileIdsLocked() { 18809 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18810 mCurrentUserId, false /* enabledOnly */); 18811 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18812 for (int i = 0; i < currentProfileIds.length; i++) { 18813 currentProfileIds[i] = profiles.get(i).id; 18814 } 18815 mCurrentProfileIds = currentProfileIds; 18816 18817 synchronized (mUserProfileGroupIdsSelfLocked) { 18818 mUserProfileGroupIdsSelfLocked.clear(); 18819 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18820 for (int i = 0; i < users.size(); i++) { 18821 UserInfo user = users.get(i); 18822 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18823 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18824 } 18825 } 18826 } 18827 } 18828 getProfileIdsLocked(int userId)18829 private Set getProfileIdsLocked(int userId) { 18830 Set userIds = new HashSet<Integer>(); 18831 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18832 userId, false /* enabledOnly */); 18833 for (UserInfo user : profiles) { 18834 userIds.add(Integer.valueOf(user.id)); 18835 } 18836 return userIds; 18837 } 18838 18839 @Override switchUser(final int userId)18840 public boolean switchUser(final int userId) { 18841 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18842 String userName; 18843 synchronized (this) { 18844 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18845 if (userInfo == null) { 18846 Slog.w(TAG, "No user info for user #" + userId); 18847 return false; 18848 } 18849 if (userInfo.isManagedProfile()) { 18850 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18851 return false; 18852 } 18853 userName = userInfo.name; 18854 mTargetUserId = userId; 18855 } 18856 mHandler.removeMessages(START_USER_SWITCH_MSG); 18857 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18858 return true; 18859 } 18860 showUserSwitchDialog(int userId, String userName)18861 private void showUserSwitchDialog(int userId, String userName) { 18862 // The dialog will show and then initiate the user switch by calling startUserInForeground 18863 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18864 true /* above system */); 18865 d.show(); 18866 } 18867 startUser(final int userId, final boolean foreground)18868 private boolean startUser(final int userId, final boolean foreground) { 18869 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18870 != PackageManager.PERMISSION_GRANTED) { 18871 String msg = "Permission Denial: switchUser() from pid=" 18872 + Binder.getCallingPid() 18873 + ", uid=" + Binder.getCallingUid() 18874 + " requires " + INTERACT_ACROSS_USERS_FULL; 18875 Slog.w(TAG, msg); 18876 throw new SecurityException(msg); 18877 } 18878 18879 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18880 18881 final long ident = Binder.clearCallingIdentity(); 18882 try { 18883 synchronized (this) { 18884 final int oldUserId = mCurrentUserId; 18885 if (oldUserId == userId) { 18886 return true; 18887 } 18888 18889 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser"); 18890 18891 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18892 if (userInfo == null) { 18893 Slog.w(TAG, "No user info for user #" + userId); 18894 return false; 18895 } 18896 if (foreground && userInfo.isManagedProfile()) { 18897 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18898 return false; 18899 } 18900 18901 if (foreground) { 18902 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18903 R.anim.screen_user_enter); 18904 } 18905 18906 boolean needStart = false; 18907 18908 // If the user we are switching to is not currently started, then 18909 // we need to start it now. 18910 if (mStartedUsers.get(userId) == null) { 18911 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18912 updateStartedUserArrayLocked(); 18913 needStart = true; 18914 } 18915 18916 final Integer userIdInt = Integer.valueOf(userId); 18917 mUserLru.remove(userIdInt); 18918 mUserLru.add(userIdInt); 18919 18920 if (foreground) { 18921 mCurrentUserId = userId; 18922 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18923 updateCurrentProfileIdsLocked(); 18924 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18925 // Once the internal notion of the active user has switched, we lock the device 18926 // with the option to show the user switcher on the keyguard. 18927 mWindowManager.lockNow(null); 18928 } else { 18929 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18930 updateCurrentProfileIdsLocked(); 18931 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18932 mUserLru.remove(currentUserIdInt); 18933 mUserLru.add(currentUserIdInt); 18934 } 18935 18936 final UserStartedState uss = mStartedUsers.get(userId); 18937 18938 // Make sure user is in the started state. If it is currently 18939 // stopping, we need to knock that off. 18940 if (uss.mState == UserStartedState.STATE_STOPPING) { 18941 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18942 // so we can just fairly silently bring the user back from 18943 // the almost-dead. 18944 uss.mState = UserStartedState.STATE_RUNNING; 18945 updateStartedUserArrayLocked(); 18946 needStart = true; 18947 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18948 // This means ACTION_SHUTDOWN has been sent, so we will 18949 // need to treat this as a new boot of the user. 18950 uss.mState = UserStartedState.STATE_BOOTING; 18951 updateStartedUserArrayLocked(); 18952 needStart = true; 18953 } 18954 18955 if (uss.mState == UserStartedState.STATE_BOOTING) { 18956 // Booting up a new user, need to tell system services about it. 18957 // Note that this is on the same handler as scheduling of broadcasts, 18958 // which is important because it needs to go first. 18959 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18960 } 18961 18962 if (foreground) { 18963 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18964 oldUserId)); 18965 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18966 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18967 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18968 oldUserId, userId, uss)); 18969 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18970 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18971 } 18972 18973 if (needStart) { 18974 // Send USER_STARTED broadcast 18975 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18976 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18977 | Intent.FLAG_RECEIVER_FOREGROUND); 18978 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18979 broadcastIntentLocked(null, null, intent, 18980 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18981 false, false, MY_PID, Process.SYSTEM_UID, userId); 18982 } 18983 18984 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18985 if (userId != UserHandle.USER_OWNER) { 18986 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18987 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18988 broadcastIntentLocked(null, null, intent, null, 18989 new IIntentReceiver.Stub() { 18990 public void performReceive(Intent intent, int resultCode, 18991 String data, Bundle extras, boolean ordered, 18992 boolean sticky, int sendingUser) { 18993 onUserInitialized(uss, foreground, oldUserId, userId); 18994 } 18995 }, 0, null, null, null, AppOpsManager.OP_NONE, 18996 true, false, MY_PID, Process.SYSTEM_UID, 18997 userId); 18998 uss.initializing = true; 18999 } else { 19000 getUserManagerLocked().makeInitialized(userInfo.id); 19001 } 19002 } 19003 19004 if (foreground) { 19005 if (!uss.initializing) { 19006 moveUserToForeground(uss, oldUserId, userId); 19007 } 19008 } else { 19009 mStackSupervisor.startBackgroundUserLocked(userId, uss); 19010 } 19011 19012 if (needStart) { 19013 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 19014 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19015 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19016 broadcastIntentLocked(null, null, intent, 19017 null, new IIntentReceiver.Stub() { 19018 @Override 19019 public void performReceive(Intent intent, int resultCode, String data, 19020 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 19021 throws RemoteException { 19022 } 19023 }, 0, null, null, 19024 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19025 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19026 } 19027 } 19028 } finally { 19029 Binder.restoreCallingIdentity(ident); 19030 } 19031 19032 return true; 19033 } 19034 sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId)19035 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 19036 long ident = Binder.clearCallingIdentity(); 19037 try { 19038 Intent intent; 19039 if (oldUserId >= 0) { 19040 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 19041 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 19042 int count = profiles.size(); 19043 for (int i = 0; i < count; i++) { 19044 int profileUserId = profiles.get(i).id; 19045 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 19046 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19047 | Intent.FLAG_RECEIVER_FOREGROUND); 19048 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19049 broadcastIntentLocked(null, null, intent, 19050 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19051 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19052 } 19053 } 19054 if (newUserId >= 0) { 19055 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 19056 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 19057 int count = profiles.size(); 19058 for (int i = 0; i < count; i++) { 19059 int profileUserId = profiles.get(i).id; 19060 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 19061 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19062 | Intent.FLAG_RECEIVER_FOREGROUND); 19063 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19064 broadcastIntentLocked(null, null, intent, 19065 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19066 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19067 } 19068 intent = new Intent(Intent.ACTION_USER_SWITCHED); 19069 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19070 | Intent.FLAG_RECEIVER_FOREGROUND); 19071 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 19072 broadcastIntentLocked(null, null, intent, 19073 null, null, 0, null, null, 19074 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 19075 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19076 } 19077 } finally { 19078 Binder.restoreCallingIdentity(ident); 19079 } 19080 } 19081 dispatchUserSwitch(final UserStartedState uss, final int oldUserId, final int newUserId)19082 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 19083 final int newUserId) { 19084 final int N = mUserSwitchObservers.beginBroadcast(); 19085 if (N > 0) { 19086 final IRemoteCallback callback = new IRemoteCallback.Stub() { 19087 int mCount = 0; 19088 @Override 19089 public void sendResult(Bundle data) throws RemoteException { 19090 synchronized (ActivityManagerService.this) { 19091 if (mCurUserSwitchCallback == this) { 19092 mCount++; 19093 if (mCount == N) { 19094 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19095 } 19096 } 19097 } 19098 } 19099 }; 19100 synchronized (this) { 19101 uss.switching = true; 19102 mCurUserSwitchCallback = callback; 19103 } 19104 for (int i=0; i<N; i++) { 19105 try { 19106 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 19107 newUserId, callback); 19108 } catch (RemoteException e) { 19109 } 19110 } 19111 } else { 19112 synchronized (this) { 19113 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19114 } 19115 } 19116 mUserSwitchObservers.finishBroadcast(); 19117 } 19118 timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId)19119 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19120 synchronized (this) { 19121 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 19122 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19123 } 19124 } 19125 sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId)19126 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 19127 mCurUserSwitchCallback = null; 19128 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 19129 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 19130 oldUserId, newUserId, uss)); 19131 } 19132 onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId)19133 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 19134 synchronized (this) { 19135 if (foreground) { 19136 moveUserToForeground(uss, oldUserId, newUserId); 19137 } 19138 } 19139 19140 completeSwitchAndInitalize(uss, newUserId, true, false); 19141 } 19142 moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId)19143 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 19144 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 19145 if (homeInFront) { 19146 startHomeActivityLocked(newUserId, "moveUserToFroreground"); 19147 } else { 19148 mStackSupervisor.resumeTopActivitiesLocked(); 19149 } 19150 EventLogTags.writeAmSwitchUser(newUserId); 19151 getUserManagerLocked().userForeground(newUserId); 19152 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 19153 } 19154 continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId)19155 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19156 completeSwitchAndInitalize(uss, newUserId, false, true); 19157 } 19158 completeSwitchAndInitalize(UserStartedState uss, int newUserId, boolean clearInitializing, boolean clearSwitching)19159 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 19160 boolean clearInitializing, boolean clearSwitching) { 19161 boolean unfrozen = false; 19162 synchronized (this) { 19163 if (clearInitializing) { 19164 uss.initializing = false; 19165 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 19166 } 19167 if (clearSwitching) { 19168 uss.switching = false; 19169 } 19170 if (!uss.switching && !uss.initializing) { 19171 mWindowManager.stopFreezingScreen(); 19172 unfrozen = true; 19173 } 19174 } 19175 if (unfrozen) { 19176 final int N = mUserSwitchObservers.beginBroadcast(); 19177 for (int i=0; i<N; i++) { 19178 try { 19179 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 19180 } catch (RemoteException e) { 19181 } 19182 } 19183 mUserSwitchObservers.finishBroadcast(); 19184 } 19185 stopGuestUserIfBackground(); 19186 } 19187 19188 /** 19189 * Stops the guest user if it has gone to the background. 19190 */ stopGuestUserIfBackground()19191 private void stopGuestUserIfBackground() { 19192 synchronized (this) { 19193 final int num = mUserLru.size(); 19194 for (int i = 0; i < num; i++) { 19195 Integer oldUserId = mUserLru.get(i); 19196 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19197 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 19198 || oldUss.mState == UserStartedState.STATE_STOPPING 19199 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19200 continue; 19201 } 19202 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 19203 if (userInfo.isGuest()) { 19204 // This is a user to be stopped. 19205 stopUserLocked(oldUserId, null); 19206 break; 19207 } 19208 } 19209 } 19210 } 19211 scheduleStartProfilesLocked()19212 void scheduleStartProfilesLocked() { 19213 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 19214 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 19215 DateUtils.SECOND_IN_MILLIS); 19216 } 19217 } 19218 startProfilesLocked()19219 void startProfilesLocked() { 19220 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 19221 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19222 mCurrentUserId, false /* enabledOnly */); 19223 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19224 for (UserInfo user : profiles) { 19225 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19226 && user.id != mCurrentUserId) { 19227 toStart.add(user); 19228 } 19229 } 19230 final int n = toStart.size(); 19231 int i = 0; 19232 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19233 startUserInBackground(toStart.get(i).id); 19234 } 19235 if (i < n) { 19236 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19237 } 19238 } 19239 finishUserBoot(UserStartedState uss)19240 void finishUserBoot(UserStartedState uss) { 19241 synchronized (this) { 19242 if (uss.mState == UserStartedState.STATE_BOOTING 19243 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19244 uss.mState = UserStartedState.STATE_RUNNING; 19245 final int userId = uss.mHandle.getIdentifier(); 19246 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19247 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19248 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19249 broadcastIntentLocked(null, null, intent, 19250 null, null, 0, null, null, 19251 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19252 true, false, MY_PID, Process.SYSTEM_UID, userId); 19253 } 19254 } 19255 } 19256 finishUserSwitch(UserStartedState uss)19257 void finishUserSwitch(UserStartedState uss) { 19258 synchronized (this) { 19259 finishUserBoot(uss); 19260 19261 startProfilesLocked(); 19262 19263 int num = mUserLru.size(); 19264 int i = 0; 19265 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19266 Integer oldUserId = mUserLru.get(i); 19267 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19268 if (oldUss == null) { 19269 // Shouldn't happen, but be sane if it does. 19270 mUserLru.remove(i); 19271 num--; 19272 continue; 19273 } 19274 if (oldUss.mState == UserStartedState.STATE_STOPPING 19275 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19276 // This user is already stopping, doesn't count. 19277 num--; 19278 i++; 19279 continue; 19280 } 19281 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19282 // Owner and current can't be stopped, but count as running. 19283 i++; 19284 continue; 19285 } 19286 // This is a user to be stopped. 19287 stopUserLocked(oldUserId, null); 19288 num--; 19289 i++; 19290 } 19291 } 19292 } 19293 19294 @Override stopUser(final int userId, final IStopUserCallback callback)19295 public int stopUser(final int userId, final IStopUserCallback callback) { 19296 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19297 != PackageManager.PERMISSION_GRANTED) { 19298 String msg = "Permission Denial: switchUser() from pid=" 19299 + Binder.getCallingPid() 19300 + ", uid=" + Binder.getCallingUid() 19301 + " requires " + INTERACT_ACROSS_USERS_FULL; 19302 Slog.w(TAG, msg); 19303 throw new SecurityException(msg); 19304 } 19305 if (userId <= 0) { 19306 throw new IllegalArgumentException("Can't stop primary user " + userId); 19307 } 19308 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19309 synchronized (this) { 19310 return stopUserLocked(userId, callback); 19311 } 19312 } 19313 stopUserLocked(final int userId, final IStopUserCallback callback)19314 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19315 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19316 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19317 return ActivityManager.USER_OP_IS_CURRENT; 19318 } 19319 19320 final UserStartedState uss = mStartedUsers.get(userId); 19321 if (uss == null) { 19322 // User is not started, nothing to do... but we do need to 19323 // callback if requested. 19324 if (callback != null) { 19325 mHandler.post(new Runnable() { 19326 @Override 19327 public void run() { 19328 try { 19329 callback.userStopped(userId); 19330 } catch (RemoteException e) { 19331 } 19332 } 19333 }); 19334 } 19335 return ActivityManager.USER_OP_SUCCESS; 19336 } 19337 19338 if (callback != null) { 19339 uss.mStopCallbacks.add(callback); 19340 } 19341 19342 if (uss.mState != UserStartedState.STATE_STOPPING 19343 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19344 uss.mState = UserStartedState.STATE_STOPPING; 19345 updateStartedUserArrayLocked(); 19346 19347 long ident = Binder.clearCallingIdentity(); 19348 try { 19349 // We are going to broadcast ACTION_USER_STOPPING and then 19350 // once that is done send a final ACTION_SHUTDOWN and then 19351 // stop the user. 19352 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19353 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19354 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19355 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19356 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19357 // This is the result receiver for the final shutdown broadcast. 19358 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19359 @Override 19360 public void performReceive(Intent intent, int resultCode, String data, 19361 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19362 finishUserStop(uss); 19363 } 19364 }; 19365 // This is the result receiver for the initial stopping broadcast. 19366 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19367 @Override 19368 public void performReceive(Intent intent, int resultCode, String data, 19369 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19370 // On to the next. 19371 synchronized (ActivityManagerService.this) { 19372 if (uss.mState != UserStartedState.STATE_STOPPING) { 19373 // Whoops, we are being started back up. Abort, abort! 19374 return; 19375 } 19376 uss.mState = UserStartedState.STATE_SHUTDOWN; 19377 } 19378 mBatteryStatsService.noteEvent( 19379 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19380 Integer.toString(userId), userId); 19381 mSystemServiceManager.stopUser(userId); 19382 broadcastIntentLocked(null, null, shutdownIntent, 19383 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19384 true, false, MY_PID, Process.SYSTEM_UID, userId); 19385 } 19386 }; 19387 // Kick things off. 19388 broadcastIntentLocked(null, null, stoppingIntent, 19389 null, stoppingReceiver, 0, null, null, 19390 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19391 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19392 } finally { 19393 Binder.restoreCallingIdentity(ident); 19394 } 19395 } 19396 19397 return ActivityManager.USER_OP_SUCCESS; 19398 } 19399 finishUserStop(UserStartedState uss)19400 void finishUserStop(UserStartedState uss) { 19401 final int userId = uss.mHandle.getIdentifier(); 19402 boolean stopped; 19403 ArrayList<IStopUserCallback> callbacks; 19404 synchronized (this) { 19405 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19406 if (mStartedUsers.get(userId) != uss) { 19407 stopped = false; 19408 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19409 stopped = false; 19410 } else { 19411 stopped = true; 19412 // User can no longer run. 19413 mStartedUsers.remove(userId); 19414 mUserLru.remove(Integer.valueOf(userId)); 19415 updateStartedUserArrayLocked(); 19416 19417 // Clean up all state and processes associated with the user. 19418 // Kill all the processes for the user. 19419 forceStopUserLocked(userId, "finish user"); 19420 } 19421 19422 // Explicitly remove the old information in mRecentTasks. 19423 removeRecentTasksForUserLocked(userId); 19424 } 19425 19426 for (int i=0; i<callbacks.size(); i++) { 19427 try { 19428 if (stopped) callbacks.get(i).userStopped(userId); 19429 else callbacks.get(i).userStopAborted(userId); 19430 } catch (RemoteException e) { 19431 } 19432 } 19433 19434 if (stopped) { 19435 mSystemServiceManager.cleanupUser(userId); 19436 synchronized (this) { 19437 mStackSupervisor.removeUserLocked(userId); 19438 } 19439 } 19440 } 19441 19442 @Override getCurrentUser()19443 public UserInfo getCurrentUser() { 19444 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19445 != PackageManager.PERMISSION_GRANTED) && ( 19446 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19447 != PackageManager.PERMISSION_GRANTED)) { 19448 String msg = "Permission Denial: getCurrentUser() from pid=" 19449 + Binder.getCallingPid() 19450 + ", uid=" + Binder.getCallingUid() 19451 + " requires " + INTERACT_ACROSS_USERS; 19452 Slog.w(TAG, msg); 19453 throw new SecurityException(msg); 19454 } 19455 synchronized (this) { 19456 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19457 return getUserManagerLocked().getUserInfo(userId); 19458 } 19459 } 19460 getCurrentUserIdLocked()19461 int getCurrentUserIdLocked() { 19462 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19463 } 19464 19465 @Override isUserRunning(int userId, boolean orStopped)19466 public boolean isUserRunning(int userId, boolean orStopped) { 19467 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19468 != PackageManager.PERMISSION_GRANTED) { 19469 String msg = "Permission Denial: isUserRunning() from pid=" 19470 + Binder.getCallingPid() 19471 + ", uid=" + Binder.getCallingUid() 19472 + " requires " + INTERACT_ACROSS_USERS; 19473 Slog.w(TAG, msg); 19474 throw new SecurityException(msg); 19475 } 19476 synchronized (this) { 19477 return isUserRunningLocked(userId, orStopped); 19478 } 19479 } 19480 isUserRunningLocked(int userId, boolean orStopped)19481 boolean isUserRunningLocked(int userId, boolean orStopped) { 19482 UserStartedState state = mStartedUsers.get(userId); 19483 if (state == null) { 19484 return false; 19485 } 19486 if (orStopped) { 19487 return true; 19488 } 19489 return state.mState != UserStartedState.STATE_STOPPING 19490 && state.mState != UserStartedState.STATE_SHUTDOWN; 19491 } 19492 19493 @Override getRunningUserIds()19494 public int[] getRunningUserIds() { 19495 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19496 != PackageManager.PERMISSION_GRANTED) { 19497 String msg = "Permission Denial: isUserRunning() from pid=" 19498 + Binder.getCallingPid() 19499 + ", uid=" + Binder.getCallingUid() 19500 + " requires " + INTERACT_ACROSS_USERS; 19501 Slog.w(TAG, msg); 19502 throw new SecurityException(msg); 19503 } 19504 synchronized (this) { 19505 return mStartedUserArray; 19506 } 19507 } 19508 updateStartedUserArrayLocked()19509 private void updateStartedUserArrayLocked() { 19510 int num = 0; 19511 for (int i=0; i<mStartedUsers.size(); i++) { 19512 UserStartedState uss = mStartedUsers.valueAt(i); 19513 // This list does not include stopping users. 19514 if (uss.mState != UserStartedState.STATE_STOPPING 19515 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19516 num++; 19517 } 19518 } 19519 mStartedUserArray = new int[num]; 19520 num = 0; 19521 for (int i=0; i<mStartedUsers.size(); i++) { 19522 UserStartedState uss = mStartedUsers.valueAt(i); 19523 if (uss.mState != UserStartedState.STATE_STOPPING 19524 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19525 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19526 num++; 19527 } 19528 } 19529 } 19530 19531 @Override registerUserSwitchObserver(IUserSwitchObserver observer)19532 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19533 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19534 != PackageManager.PERMISSION_GRANTED) { 19535 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19536 + Binder.getCallingPid() 19537 + ", uid=" + Binder.getCallingUid() 19538 + " requires " + INTERACT_ACROSS_USERS_FULL; 19539 Slog.w(TAG, msg); 19540 throw new SecurityException(msg); 19541 } 19542 19543 mUserSwitchObservers.register(observer); 19544 } 19545 19546 @Override unregisterUserSwitchObserver(IUserSwitchObserver observer)19547 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19548 mUserSwitchObservers.unregister(observer); 19549 } 19550 userExists(int userId)19551 private boolean userExists(int userId) { 19552 if (userId == 0) { 19553 return true; 19554 } 19555 UserManagerService ums = getUserManagerLocked(); 19556 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19557 } 19558 getUsersLocked()19559 int[] getUsersLocked() { 19560 UserManagerService ums = getUserManagerLocked(); 19561 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19562 } 19563 getUserManagerLocked()19564 UserManagerService getUserManagerLocked() { 19565 if (mUserManager == null) { 19566 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19567 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19568 } 19569 return mUserManager; 19570 } 19571 applyUserId(int uid, int userId)19572 private int applyUserId(int uid, int userId) { 19573 return UserHandle.getUid(userId, uid); 19574 } 19575 getAppInfoForUser(ApplicationInfo info, int userId)19576 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19577 if (info == null) return null; 19578 ApplicationInfo newInfo = new ApplicationInfo(info); 19579 newInfo.uid = applyUserId(info.uid, userId); 19580 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19581 + info.packageName; 19582 return newInfo; 19583 } 19584 getActivityInfoForUser(ActivityInfo aInfo, int userId)19585 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19586 if (aInfo == null 19587 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19588 return aInfo; 19589 } 19590 19591 ActivityInfo info = new ActivityInfo(aInfo); 19592 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19593 return info; 19594 } 19595 19596 private final class LocalService extends ActivityManagerInternal { 19597 @Override onWakefulnessChanged(int wakefulness)19598 public void onWakefulnessChanged(int wakefulness) { 19599 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19600 } 19601 19602 @Override startIsolatedProcess(String entryPoint, String[] entryPointArgs, String processName, String abiOverride, int uid, Runnable crashHandler)19603 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19604 String processName, String abiOverride, int uid, Runnable crashHandler) { 19605 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19606 processName, abiOverride, uid, crashHandler); 19607 } 19608 } 19609 19610 /** 19611 * An implementation of IAppTask, that allows an app to manage its own tasks via 19612 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19613 * only the process that calls getAppTasks() can call the AppTask methods. 19614 */ 19615 class AppTaskImpl extends IAppTask.Stub { 19616 private int mTaskId; 19617 private int mCallingUid; 19618 AppTaskImpl(int taskId, int callingUid)19619 public AppTaskImpl(int taskId, int callingUid) { 19620 mTaskId = taskId; 19621 mCallingUid = callingUid; 19622 } 19623 checkCaller()19624 private void checkCaller() { 19625 if (mCallingUid != Binder.getCallingUid()) { 19626 throw new SecurityException("Caller " + mCallingUid 19627 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19628 } 19629 } 19630 19631 @Override finishAndRemoveTask()19632 public void finishAndRemoveTask() { 19633 checkCaller(); 19634 19635 synchronized (ActivityManagerService.this) { 19636 long origId = Binder.clearCallingIdentity(); 19637 try { 19638 if (!removeTaskByIdLocked(mTaskId, false)) { 19639 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19640 } 19641 } finally { 19642 Binder.restoreCallingIdentity(origId); 19643 } 19644 } 19645 } 19646 19647 @Override getTaskInfo()19648 public ActivityManager.RecentTaskInfo getTaskInfo() { 19649 checkCaller(); 19650 19651 synchronized (ActivityManagerService.this) { 19652 long origId = Binder.clearCallingIdentity(); 19653 try { 19654 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19655 if (tr == null) { 19656 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19657 } 19658 return createRecentTaskInfoFromTaskRecord(tr); 19659 } finally { 19660 Binder.restoreCallingIdentity(origId); 19661 } 19662 } 19663 } 19664 19665 @Override moveToFront()19666 public void moveToFront() { 19667 checkCaller(); 19668 // Will bring task to front if it already has a root activity. 19669 startActivityFromRecentsInner(mTaskId, null); 19670 } 19671 19672 @Override startActivity(IBinder whoThread, String callingPackage, Intent intent, String resolvedType, Bundle options)19673 public int startActivity(IBinder whoThread, String callingPackage, 19674 Intent intent, String resolvedType, Bundle options) { 19675 checkCaller(); 19676 19677 int callingUser = UserHandle.getCallingUserId(); 19678 TaskRecord tr; 19679 IApplicationThread appThread; 19680 synchronized (ActivityManagerService.this) { 19681 tr = recentTaskForIdLocked(mTaskId); 19682 if (tr == null) { 19683 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19684 } 19685 appThread = ApplicationThreadNative.asInterface(whoThread); 19686 if (appThread == null) { 19687 throw new IllegalArgumentException("Bad app thread " + appThread); 19688 } 19689 } 19690 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19691 resolvedType, null, null, null, null, 0, 0, null, null, 19692 null, options, callingUser, null, tr); 19693 } 19694 19695 @Override setExcludeFromRecents(boolean exclude)19696 public void setExcludeFromRecents(boolean exclude) { 19697 checkCaller(); 19698 19699 synchronized (ActivityManagerService.this) { 19700 long origId = Binder.clearCallingIdentity(); 19701 try { 19702 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19703 if (tr == null) { 19704 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19705 } 19706 Intent intent = tr.getBaseIntent(); 19707 if (exclude) { 19708 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19709 } else { 19710 intent.setFlags(intent.getFlags() 19711 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19712 } 19713 } finally { 19714 Binder.restoreCallingIdentity(origId); 19715 } 19716 } 19717 } 19718 } 19719 } 19720