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 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 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; 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 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 { 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 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 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 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 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 859 public String toString() { 860 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 861 if (prefix) result += " [prefix]"; 862 return result; 863 } 864 865 public String toSafeString() { 866 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 867 if (prefix) result += " [prefix]"; 868 return result; 869 } 870 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 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 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 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 { 1300 public MainHandler(Looper looper) { 1301 super(looper, null, true); 1302 } 1303 1304 @Override 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 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 1938 public void setWindowManager(WindowManagerService wm) { 1939 mWindowManager = wm; 1940 mStackSupervisor.setWindowManager(wm); 1941 } 1942 1943 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 1944 mUsageStatsService = usageStatsManager; 1945 } 1946 1947 public void startObservingNativeCrashes() { 1948 final NativeCrashListener ncl = new NativeCrashListener(this); 1949 ncl.start(); 1950 } 1951 1952 public IAppOpsService getAppOpsService() { 1953 return mAppOpsService; 1954 } 1955 1956 static class MemBinder extends Binder { 1957 ActivityManagerService mActivityManagerService; 1958 MemBinder(ActivityManagerService activityManagerService) { 1959 mActivityManagerService = activityManagerService; 1960 } 1961 1962 @Override 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; 1978 GraphicsBinder(ActivityManagerService activityManagerService) { 1979 mActivityManagerService = activityManagerService; 1980 } 1981 1982 @Override 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; 1998 DbBinder(ActivityManagerService activityManagerService) { 1999 mActivityManagerService = activityManagerService; 2000 } 2001 2002 @Override 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; 2018 CpuBinder(ActivityManagerService activityManagerService) { 2019 mActivityManagerService = activityManagerService; 2020 } 2021 2022 @Override 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 2043 public Lifecycle(Context context) { 2044 super(context); 2045 mService = new ActivityManagerService(context); 2046 } 2047 2048 @Override 2049 public void onStart() { 2050 mService.start(); 2051 } 2052 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. 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 2154 public void setSystemServiceManager(SystemServiceManager mgr) { 2155 mSystemServiceManager = mgr; 2156 } 2157 2158 public void setInstaller(Installer installer) { 2159 mInstaller = installer; 2160 } 2161 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 2172 public void initPowerManagement() { 2173 mStackSupervisor.initPowerManagement(); 2174 mBatteryStatsService.initPowerManagement(); 2175 } 2176 2177 @Override 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 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 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 2324 public void batteryNeedsCpuUpdate() { 2325 updateCpuStatsNow(); 2326 } 2327 2328 @Override 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 */ 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 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 2381 final void clearFocusedActivity(ActivityRecord r) { 2382 if (mFocusedActivity == r) { 2383 mFocusedActivity = null; 2384 } 2385 } 2386 2387 @Override 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 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 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 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 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 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 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 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 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 procCount = procs.size(); 2695 for (int i = 0; i < procCount; i++) { 2696 final int procUid = procs.keyAt(i); 2697 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) { 2698 // Don't use an app process or different user process for system component. 2699 continue; 2700 } 2701 return procs.valueAt(i); 2702 } 2703 } 2704 ProcessRecord proc = mProcessNames.get(processName, uid); 2705 if (false && proc != null && !keepIfLarge 2706 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2707 && proc.lastCachedPss >= 4000) { 2708 // Turn this condition on to cause killing to happen regularly, for testing. 2709 if (proc.baseProcessTracker != null) { 2710 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2711 } 2712 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2713 } else if (proc != null && !keepIfLarge 2714 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2715 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2716 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2717 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2718 if (proc.baseProcessTracker != null) { 2719 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2720 } 2721 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2722 } 2723 } 2724 return proc; 2725 } 2726 2727 void ensurePackageDexOpt(String packageName) { 2728 IPackageManager pm = AppGlobals.getPackageManager(); 2729 try { 2730 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2731 mDidDexOpt = true; 2732 } 2733 } catch (RemoteException e) { 2734 } 2735 } 2736 2737 boolean isNextTransitionForward() { 2738 int transit = mWindowManager.getPendingAppTransition(); 2739 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2740 || transit == AppTransition.TRANSIT_TASK_OPEN 2741 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2742 } 2743 2744 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2745 String processName, String abiOverride, int uid, Runnable crashHandler) { 2746 synchronized(this) { 2747 ApplicationInfo info = new ApplicationInfo(); 2748 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2749 // For isolated processes, the former contains the parent's uid and the latter the 2750 // actual uid of the isolated process. 2751 // In the special case introduced by this method (which is, starting an isolated 2752 // process directly from the SystemServer without an actual parent app process) the 2753 // closest thing to a parent's uid is SYSTEM_UID. 2754 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2755 // the |isolated| logic in the ProcessRecord constructor. 2756 info.uid = Process.SYSTEM_UID; 2757 info.processName = processName; 2758 info.className = entryPoint; 2759 info.packageName = "android"; 2760 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2761 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2762 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2763 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2764 crashHandler); 2765 return proc != null ? proc.pid : 0; 2766 } 2767 } 2768 2769 final ProcessRecord startProcessLocked(String processName, 2770 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2771 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2772 boolean isolated, boolean keepIfLarge) { 2773 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2774 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2775 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2776 null /* crashHandler */); 2777 } 2778 2779 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2780 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2781 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2782 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2783 long startTime = SystemClock.elapsedRealtime(); 2784 ProcessRecord app; 2785 if (!isolated) { 2786 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2787 checkTime(startTime, "startProcess: after getProcessRecord"); 2788 } else { 2789 // If this is an isolated process, it can't re-use an existing process. 2790 app = null; 2791 } 2792 // We don't have to do anything more if: 2793 // (1) There is an existing application record; and 2794 // (2) The caller doesn't think it is dead, OR there is no thread 2795 // object attached to it so we know it couldn't have crashed; and 2796 // (3) There is a pid assigned to it, so it is either starting or 2797 // already running. 2798 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2799 + " app=" + app + " knownToBeDead=" + knownToBeDead 2800 + " thread=" + (app != null ? app.thread : null) 2801 + " pid=" + (app != null ? app.pid : -1)); 2802 if (app != null && app.pid > 0) { 2803 if (!knownToBeDead || app.thread == null) { 2804 // We already have the app running, or are waiting for it to 2805 // come up (we have a pid but not yet its thread), so keep it. 2806 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2807 // If this is a new package in the process, add the package to the list 2808 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2809 checkTime(startTime, "startProcess: done, added package to proc"); 2810 return app; 2811 } 2812 2813 // An application record is attached to a previous process, 2814 // clean it up now. 2815 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2816 checkTime(startTime, "startProcess: bad proc running, killing"); 2817 Process.killProcessGroup(app.info.uid, app.pid); 2818 handleAppDiedLocked(app, true, true); 2819 checkTime(startTime, "startProcess: done killing old proc"); 2820 } 2821 2822 String hostingNameStr = hostingName != null 2823 ? hostingName.flattenToShortString() : null; 2824 2825 if (!isolated) { 2826 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2827 // If we are in the background, then check to see if this process 2828 // is bad. If so, we will just silently fail. 2829 if (mBadProcesses.get(info.processName, info.uid) != null) { 2830 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2831 + "/" + info.processName); 2832 return null; 2833 } 2834 } else { 2835 // When the user is explicitly starting a process, then clear its 2836 // crash count so that we won't make it bad until they see at 2837 // least one crash dialog again, and make the process good again 2838 // if it had been bad. 2839 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2840 + "/" + info.processName); 2841 mProcessCrashTimes.remove(info.processName, info.uid); 2842 if (mBadProcesses.get(info.processName, info.uid) != null) { 2843 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2844 UserHandle.getUserId(info.uid), info.uid, 2845 info.processName); 2846 mBadProcesses.remove(info.processName, info.uid); 2847 if (app != null) { 2848 app.bad = false; 2849 } 2850 } 2851 } 2852 } 2853 2854 if (app == null) { 2855 checkTime(startTime, "startProcess: creating new process record"); 2856 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2857 if (app == null) { 2858 Slog.w(TAG, "Failed making new process record for " 2859 + processName + "/" + info.uid + " isolated=" + isolated); 2860 return null; 2861 } 2862 app.crashHandler = crashHandler; 2863 mProcessNames.put(processName, app.uid, app); 2864 if (isolated) { 2865 mIsolatedProcesses.put(app.uid, app); 2866 } 2867 checkTime(startTime, "startProcess: done creating new process record"); 2868 } else { 2869 // If this is a new package in the process, add the package to the list 2870 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2871 checkTime(startTime, "startProcess: added package to existing proc"); 2872 } 2873 2874 // If the system is not ready yet, then hold off on starting this 2875 // process until it is. 2876 if (!mProcessesReady 2877 && !isAllowedWhileBooting(info) 2878 && !allowWhileBooting) { 2879 if (!mProcessesOnHold.contains(app)) { 2880 mProcessesOnHold.add(app); 2881 } 2882 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2883 checkTime(startTime, "startProcess: returning with proc on hold"); 2884 return app; 2885 } 2886 2887 checkTime(startTime, "startProcess: stepping in to startProcess"); 2888 startProcessLocked( 2889 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 2890 checkTime(startTime, "startProcess: done starting proc!"); 2891 return (app.pid != 0) ? app : null; 2892 } 2893 2894 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2895 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2896 } 2897 2898 private final void startProcessLocked(ProcessRecord app, 2899 String hostingType, String hostingNameStr) { 2900 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 2901 null /* entryPoint */, null /* entryPointArgs */); 2902 } 2903 2904 private final void startProcessLocked(ProcessRecord app, String hostingType, 2905 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 2906 long startTime = SystemClock.elapsedRealtime(); 2907 if (app.pid > 0 && app.pid != MY_PID) { 2908 checkTime(startTime, "startProcess: removing from pids map"); 2909 synchronized (mPidsSelfLocked) { 2910 mPidsSelfLocked.remove(app.pid); 2911 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2912 } 2913 checkTime(startTime, "startProcess: done removing from pids map"); 2914 app.setPid(0); 2915 } 2916 2917 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2918 "startProcessLocked removing on hold: " + app); 2919 mProcessesOnHold.remove(app); 2920 2921 checkTime(startTime, "startProcess: starting to update cpu stats"); 2922 updateCpuStats(); 2923 checkTime(startTime, "startProcess: done updating cpu stats"); 2924 2925 try { 2926 int uid = app.uid; 2927 2928 int[] gids = null; 2929 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2930 if (!app.isolated) { 2931 int[] permGids = null; 2932 try { 2933 checkTime(startTime, "startProcess: getting gids from package manager"); 2934 final PackageManager pm = mContext.getPackageManager(); 2935 permGids = pm.getPackageGids(app.info.packageName); 2936 2937 if (Environment.isExternalStorageEmulated()) { 2938 checkTime(startTime, "startProcess: checking external storage perm"); 2939 if (pm.checkPermission( 2940 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2941 app.info.packageName) == PERMISSION_GRANTED) { 2942 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2943 } else { 2944 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2945 } 2946 } 2947 } catch (PackageManager.NameNotFoundException e) { 2948 Slog.w(TAG, "Unable to retrieve gids", e); 2949 } 2950 2951 /* 2952 * Add shared application and profile GIDs so applications can share some 2953 * resources like shared libraries and access user-wide resources 2954 */ 2955 if (permGids == null) { 2956 gids = new int[2]; 2957 } else { 2958 gids = new int[permGids.length + 2]; 2959 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2960 } 2961 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2962 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2963 } 2964 checkTime(startTime, "startProcess: building args"); 2965 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2966 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2967 && mTopComponent != null 2968 && app.processName.equals(mTopComponent.getPackageName())) { 2969 uid = 0; 2970 } 2971 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2972 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2973 uid = 0; 2974 } 2975 } 2976 int debugFlags = 0; 2977 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2978 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2979 // Also turn on CheckJNI for debuggable apps. It's quite 2980 // awkward to turn on otherwise. 2981 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2982 } 2983 // Run the app in safe mode if its manifest requests so or the 2984 // system is booted in safe mode. 2985 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2986 mSafeMode == true) { 2987 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2988 } 2989 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2990 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2991 } 2992 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2993 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2994 } 2995 if ("1".equals(SystemProperties.get("debug.assert"))) { 2996 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2997 } 2998 2999 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3000 if (requiredAbi == null) { 3001 requiredAbi = Build.SUPPORTED_ABIS[0]; 3002 } 3003 3004 String instructionSet = null; 3005 if (app.info.primaryCpuAbi != null) { 3006 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3007 } 3008 3009 app.gids = gids; 3010 app.requiredAbi = requiredAbi; 3011 app.instructionSet = instructionSet; 3012 3013 // Start the process. It will either succeed and return a result containing 3014 // the PID of the new process, or else throw a RuntimeException. 3015 boolean isActivityProcess = (entryPoint == null); 3016 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3017 checkTime(startTime, "startProcess: asking zygote to start proc"); 3018 Process.ProcessStartResult startResult = Process.start(entryPoint, 3019 app.processName, uid, uid, gids, debugFlags, mountExternal, 3020 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3021 app.info.dataDir, entryPointArgs); 3022 checkTime(startTime, "startProcess: returned from zygote!"); 3023 3024 if (app.isolated) { 3025 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3026 } 3027 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3028 checkTime(startTime, "startProcess: done updating battery stats"); 3029 3030 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3031 UserHandle.getUserId(uid), startResult.pid, uid, 3032 app.processName, hostingType, 3033 hostingNameStr != null ? hostingNameStr : ""); 3034 3035 if (app.persistent) { 3036 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3037 } 3038 3039 checkTime(startTime, "startProcess: building log message"); 3040 StringBuilder buf = mStringBuilder; 3041 buf.setLength(0); 3042 buf.append("Start proc "); 3043 buf.append(startResult.pid); 3044 buf.append(':'); 3045 buf.append(app.processName); 3046 buf.append('/'); 3047 UserHandle.formatUid(buf, uid); 3048 if (!isActivityProcess) { 3049 buf.append(" ["); 3050 buf.append(entryPoint); 3051 buf.append("]"); 3052 } 3053 buf.append(" for "); 3054 buf.append(hostingType); 3055 if (hostingNameStr != null) { 3056 buf.append(" "); 3057 buf.append(hostingNameStr); 3058 } 3059 Slog.i(TAG, buf.toString()); 3060 app.setPid(startResult.pid); 3061 app.usingWrapper = startResult.usingWrapper; 3062 app.removed = false; 3063 app.killed = false; 3064 app.killedByAm = false; 3065 checkTime(startTime, "startProcess: starting to update pids map"); 3066 synchronized (mPidsSelfLocked) { 3067 this.mPidsSelfLocked.put(startResult.pid, app); 3068 if (isActivityProcess) { 3069 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3070 msg.obj = app; 3071 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3072 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3073 } 3074 } 3075 checkTime(startTime, "startProcess: done updating pids map"); 3076 } catch (RuntimeException e) { 3077 // XXX do better error recovery. 3078 app.setPid(0); 3079 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3080 if (app.isolated) { 3081 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3082 } 3083 Slog.e(TAG, "Failure starting process " + app.processName, e); 3084 } 3085 } 3086 3087 void updateUsageStats(ActivityRecord component, boolean resumed) { 3088 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3089 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3090 if (resumed) { 3091 if (mUsageStatsService != null) { 3092 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3093 UsageEvents.Event.MOVE_TO_FOREGROUND); 3094 } 3095 synchronized (stats) { 3096 stats.noteActivityResumedLocked(component.app.uid); 3097 } 3098 } else { 3099 if (mUsageStatsService != null) { 3100 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3101 UsageEvents.Event.MOVE_TO_BACKGROUND); 3102 } 3103 synchronized (stats) { 3104 stats.noteActivityPausedLocked(component.app.uid); 3105 } 3106 } 3107 } 3108 3109 Intent getHomeIntent() { 3110 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3111 intent.setComponent(mTopComponent); 3112 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3113 intent.addCategory(Intent.CATEGORY_HOME); 3114 } 3115 return intent; 3116 } 3117 3118 boolean startHomeActivityLocked(int userId, String reason) { 3119 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3120 && mTopAction == null) { 3121 // We are running in factory test mode, but unable to find 3122 // the factory test app, so just sit around displaying the 3123 // error message and don't try to start anything. 3124 return false; 3125 } 3126 Intent intent = getHomeIntent(); 3127 ActivityInfo aInfo = 3128 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3129 if (aInfo != null) { 3130 intent.setComponent(new ComponentName( 3131 aInfo.applicationInfo.packageName, aInfo.name)); 3132 // Don't do this if the home app is currently being 3133 // instrumented. 3134 aInfo = new ActivityInfo(aInfo); 3135 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3136 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3137 aInfo.applicationInfo.uid, true); 3138 if (app == null || app.instrumentationClass == null) { 3139 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3140 mStackSupervisor.startHomeActivity(intent, aInfo, reason); 3141 } 3142 } 3143 3144 return true; 3145 } 3146 3147 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3148 ActivityInfo ai = null; 3149 ComponentName comp = intent.getComponent(); 3150 try { 3151 if (comp != null) { 3152 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3153 } else { 3154 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3155 intent, 3156 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3157 flags, userId); 3158 3159 if (info != null) { 3160 ai = info.activityInfo; 3161 } 3162 } 3163 } catch (RemoteException e) { 3164 // ignore 3165 } 3166 3167 return ai; 3168 } 3169 3170 /** 3171 * Starts the "new version setup screen" if appropriate. 3172 */ 3173 void startSetupActivityLocked() { 3174 // Only do this once per boot. 3175 if (mCheckedForSetup) { 3176 return; 3177 } 3178 3179 // We will show this screen if the current one is a different 3180 // version than the last one shown, and we are not running in 3181 // low-level factory test mode. 3182 final ContentResolver resolver = mContext.getContentResolver(); 3183 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3184 Settings.Global.getInt(resolver, 3185 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3186 mCheckedForSetup = true; 3187 3188 // See if we should be showing the platform update setup UI. 3189 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3190 List<ResolveInfo> ris = mContext.getPackageManager() 3191 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3192 3193 // We don't allow third party apps to replace this. 3194 ResolveInfo ri = null; 3195 for (int i=0; ris != null && i<ris.size(); i++) { 3196 if ((ris.get(i).activityInfo.applicationInfo.flags 3197 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3198 ri = ris.get(i); 3199 break; 3200 } 3201 } 3202 3203 if (ri != null) { 3204 String vers = ri.activityInfo.metaData != null 3205 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3206 : null; 3207 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3208 vers = ri.activityInfo.applicationInfo.metaData.getString( 3209 Intent.METADATA_SETUP_VERSION); 3210 } 3211 String lastVers = Settings.Secure.getString( 3212 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3213 if (vers != null && !vers.equals(lastVers)) { 3214 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3215 intent.setComponent(new ComponentName( 3216 ri.activityInfo.packageName, ri.activityInfo.name)); 3217 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3218 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3219 null); 3220 } 3221 } 3222 } 3223 } 3224 3225 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3226 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3227 } 3228 3229 void enforceNotIsolatedCaller(String caller) { 3230 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3231 throw new SecurityException("Isolated process not allowed to call " + caller); 3232 } 3233 } 3234 3235 void enforceShellRestriction(String restriction, int userHandle) { 3236 if (Binder.getCallingUid() == Process.SHELL_UID) { 3237 if (userHandle < 0 3238 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3239 throw new SecurityException("Shell does not have permission to access user " 3240 + userHandle); 3241 } 3242 } 3243 } 3244 3245 @Override 3246 public int getFrontActivityScreenCompatMode() { 3247 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3248 synchronized (this) { 3249 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3250 } 3251 } 3252 3253 @Override 3254 public void setFrontActivityScreenCompatMode(int mode) { 3255 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3256 "setFrontActivityScreenCompatMode"); 3257 synchronized (this) { 3258 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3259 } 3260 } 3261 3262 @Override 3263 public int getPackageScreenCompatMode(String packageName) { 3264 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3265 synchronized (this) { 3266 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3267 } 3268 } 3269 3270 @Override 3271 public void setPackageScreenCompatMode(String packageName, int mode) { 3272 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3273 "setPackageScreenCompatMode"); 3274 synchronized (this) { 3275 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3276 } 3277 } 3278 3279 @Override 3280 public boolean getPackageAskScreenCompat(String packageName) { 3281 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3282 synchronized (this) { 3283 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3284 } 3285 } 3286 3287 @Override 3288 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3289 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3290 "setPackageAskScreenCompat"); 3291 synchronized (this) { 3292 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3293 } 3294 } 3295 3296 private void dispatchProcessesChanged() { 3297 int N; 3298 synchronized (this) { 3299 N = mPendingProcessChanges.size(); 3300 if (mActiveProcessChanges.length < N) { 3301 mActiveProcessChanges = new ProcessChangeItem[N]; 3302 } 3303 mPendingProcessChanges.toArray(mActiveProcessChanges); 3304 mAvailProcessChanges.addAll(mPendingProcessChanges); 3305 mPendingProcessChanges.clear(); 3306 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3307 } 3308 3309 int i = mProcessObservers.beginBroadcast(); 3310 while (i > 0) { 3311 i--; 3312 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3313 if (observer != null) { 3314 try { 3315 for (int j=0; j<N; j++) { 3316 ProcessChangeItem item = mActiveProcessChanges[j]; 3317 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3318 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3319 + item.pid + " uid=" + item.uid + ": " 3320 + item.foregroundActivities); 3321 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3322 item.foregroundActivities); 3323 } 3324 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3325 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3326 + item.pid + " uid=" + item.uid + ": " + item.processState); 3327 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3328 } 3329 } 3330 } catch (RemoteException e) { 3331 } 3332 } 3333 } 3334 mProcessObservers.finishBroadcast(); 3335 } 3336 3337 private void dispatchProcessDied(int pid, int uid) { 3338 int i = mProcessObservers.beginBroadcast(); 3339 while (i > 0) { 3340 i--; 3341 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3342 if (observer != null) { 3343 try { 3344 observer.onProcessDied(pid, uid); 3345 } catch (RemoteException e) { 3346 } 3347 } 3348 } 3349 mProcessObservers.finishBroadcast(); 3350 } 3351 3352 @Override 3353 public final int startActivity(IApplicationThread caller, String callingPackage, 3354 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3355 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3356 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3357 resultWho, requestCode, startFlags, profilerInfo, options, 3358 UserHandle.getCallingUserId()); 3359 } 3360 3361 @Override 3362 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3363 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3364 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3365 enforceNotIsolatedCaller("startActivity"); 3366 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3367 false, ALLOW_FULL_ONLY, "startActivity", null); 3368 // TODO: Switch to user app stacks here. 3369 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3370 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3371 profilerInfo, null, null, options, userId, null, null); 3372 } 3373 3374 @Override 3375 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3376 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3377 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3378 3379 // This is very dangerous -- it allows you to perform a start activity (including 3380 // permission grants) as any app that may launch one of your own activities. So 3381 // we will only allow this to be done from activities that are part of the core framework, 3382 // and then only when they are running as the system. 3383 final ActivityRecord sourceRecord; 3384 final int targetUid; 3385 final String targetPackage; 3386 synchronized (this) { 3387 if (resultTo == null) { 3388 throw new SecurityException("Must be called from an activity"); 3389 } 3390 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3391 if (sourceRecord == null) { 3392 throw new SecurityException("Called with bad activity token: " + resultTo); 3393 } 3394 if (!sourceRecord.info.packageName.equals("android")) { 3395 throw new SecurityException( 3396 "Must be called from an activity that is declared in the android package"); 3397 } 3398 if (sourceRecord.app == null) { 3399 throw new SecurityException("Called without a process attached to activity"); 3400 } 3401 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3402 // This is still okay, as long as this activity is running under the 3403 // uid of the original calling activity. 3404 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3405 throw new SecurityException( 3406 "Calling activity in uid " + sourceRecord.app.uid 3407 + " must be system uid or original calling uid " 3408 + sourceRecord.launchedFromUid); 3409 } 3410 } 3411 targetUid = sourceRecord.launchedFromUid; 3412 targetPackage = sourceRecord.launchedFromPackage; 3413 } 3414 3415 if (userId == UserHandle.USER_NULL) { 3416 userId = UserHandle.getUserId(sourceRecord.app.uid); 3417 } 3418 3419 // TODO: Switch to user app stacks here. 3420 try { 3421 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3422 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3423 null, null, options, userId, null, null); 3424 return ret; 3425 } catch (SecurityException e) { 3426 // XXX need to figure out how to propagate to original app. 3427 // A SecurityException here is generally actually a fault of the original 3428 // calling activity (such as a fairly granting permissions), so propagate it 3429 // back to them. 3430 /* 3431 StringBuilder msg = new StringBuilder(); 3432 msg.append("While launching"); 3433 msg.append(intent.toString()); 3434 msg.append(": "); 3435 msg.append(e.getMessage()); 3436 */ 3437 throw e; 3438 } 3439 } 3440 3441 @Override 3442 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3443 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3444 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3445 enforceNotIsolatedCaller("startActivityAndWait"); 3446 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3447 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3448 WaitResult res = new WaitResult(); 3449 // TODO: Switch to user app stacks here. 3450 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3451 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3452 options, userId, null, null); 3453 return res; 3454 } 3455 3456 @Override 3457 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3458 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3459 int startFlags, Configuration config, Bundle options, int userId) { 3460 enforceNotIsolatedCaller("startActivityWithConfig"); 3461 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3462 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3463 // TODO: Switch to user app stacks here. 3464 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3465 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3466 null, null, config, options, userId, null, null); 3467 return ret; 3468 } 3469 3470 @Override 3471 public int startActivityIntentSender(IApplicationThread caller, 3472 IntentSender intent, Intent fillInIntent, String resolvedType, 3473 IBinder resultTo, String resultWho, int requestCode, 3474 int flagsMask, int flagsValues, Bundle options) { 3475 enforceNotIsolatedCaller("startActivityIntentSender"); 3476 // Refuse possible leaked file descriptors 3477 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3478 throw new IllegalArgumentException("File descriptors passed in Intent"); 3479 } 3480 3481 IIntentSender sender = intent.getTarget(); 3482 if (!(sender instanceof PendingIntentRecord)) { 3483 throw new IllegalArgumentException("Bad PendingIntent object"); 3484 } 3485 3486 PendingIntentRecord pir = (PendingIntentRecord)sender; 3487 3488 synchronized (this) { 3489 // If this is coming from the currently resumed activity, it is 3490 // effectively saying that app switches are allowed at this point. 3491 final ActivityStack stack = getFocusedStack(); 3492 if (stack.mResumedActivity != null && 3493 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3494 mAppSwitchesAllowedTime = 0; 3495 } 3496 } 3497 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3498 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3499 return ret; 3500 } 3501 3502 @Override 3503 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3504 Intent intent, String resolvedType, IVoiceInteractionSession session, 3505 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3506 Bundle options, int userId) { 3507 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3508 != PackageManager.PERMISSION_GRANTED) { 3509 String msg = "Permission Denial: startVoiceActivity() from pid=" 3510 + Binder.getCallingPid() 3511 + ", uid=" + Binder.getCallingUid() 3512 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3513 Slog.w(TAG, msg); 3514 throw new SecurityException(msg); 3515 } 3516 if (session == null || interactor == null) { 3517 throw new NullPointerException("null session or interactor"); 3518 } 3519 userId = handleIncomingUser(callingPid, callingUid, userId, 3520 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3521 // TODO: Switch to user app stacks here. 3522 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3523 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3524 null, options, userId, null, null); 3525 } 3526 3527 @Override 3528 public boolean startNextMatchingActivity(IBinder callingActivity, 3529 Intent intent, Bundle options) { 3530 // Refuse possible leaked file descriptors 3531 if (intent != null && intent.hasFileDescriptors() == true) { 3532 throw new IllegalArgumentException("File descriptors passed in Intent"); 3533 } 3534 3535 synchronized (this) { 3536 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3537 if (r == null) { 3538 ActivityOptions.abort(options); 3539 return false; 3540 } 3541 if (r.app == null || r.app.thread == null) { 3542 // The caller is not running... d'oh! 3543 ActivityOptions.abort(options); 3544 return false; 3545 } 3546 intent = new Intent(intent); 3547 // The caller is not allowed to change the data. 3548 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3549 // And we are resetting to find the next component... 3550 intent.setComponent(null); 3551 3552 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3553 3554 ActivityInfo aInfo = null; 3555 try { 3556 List<ResolveInfo> resolves = 3557 AppGlobals.getPackageManager().queryIntentActivities( 3558 intent, r.resolvedType, 3559 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3560 UserHandle.getCallingUserId()); 3561 3562 // Look for the original activity in the list... 3563 final int N = resolves != null ? resolves.size() : 0; 3564 for (int i=0; i<N; i++) { 3565 ResolveInfo rInfo = resolves.get(i); 3566 if (rInfo.activityInfo.packageName.equals(r.packageName) 3567 && rInfo.activityInfo.name.equals(r.info.name)) { 3568 // We found the current one... the next matching is 3569 // after it. 3570 i++; 3571 if (i<N) { 3572 aInfo = resolves.get(i).activityInfo; 3573 } 3574 if (debug) { 3575 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3576 + "/" + r.info.name); 3577 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3578 + "/" + aInfo.name); 3579 } 3580 break; 3581 } 3582 } 3583 } catch (RemoteException e) { 3584 } 3585 3586 if (aInfo == null) { 3587 // Nobody who is next! 3588 ActivityOptions.abort(options); 3589 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3590 return false; 3591 } 3592 3593 intent.setComponent(new ComponentName( 3594 aInfo.applicationInfo.packageName, aInfo.name)); 3595 intent.setFlags(intent.getFlags()&~( 3596 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3597 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3598 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3599 Intent.FLAG_ACTIVITY_NEW_TASK)); 3600 3601 // Okay now we need to start the new activity, replacing the 3602 // currently running activity. This is a little tricky because 3603 // we want to start the new one as if the current one is finished, 3604 // but not finish the current one first so that there is no flicker. 3605 // And thus... 3606 final boolean wasFinishing = r.finishing; 3607 r.finishing = true; 3608 3609 // Propagate reply information over to the new activity. 3610 final ActivityRecord resultTo = r.resultTo; 3611 final String resultWho = r.resultWho; 3612 final int requestCode = r.requestCode; 3613 r.resultTo = null; 3614 if (resultTo != null) { 3615 resultTo.removeResultsLocked(r, resultWho, requestCode); 3616 } 3617 3618 final long origId = Binder.clearCallingIdentity(); 3619 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3620 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3621 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3622 -1, r.launchedFromUid, 0, options, false, null, null, null); 3623 Binder.restoreCallingIdentity(origId); 3624 3625 r.finishing = wasFinishing; 3626 if (res != ActivityManager.START_SUCCESS) { 3627 return false; 3628 } 3629 return true; 3630 } 3631 } 3632 3633 @Override 3634 public final int startActivityFromRecents(int taskId, Bundle options) { 3635 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3636 String msg = "Permission Denial: startActivityFromRecents called without " + 3637 START_TASKS_FROM_RECENTS; 3638 Slog.w(TAG, msg); 3639 throw new SecurityException(msg); 3640 } 3641 return startActivityFromRecentsInner(taskId, options); 3642 } 3643 3644 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3645 final TaskRecord task; 3646 final int callingUid; 3647 final String callingPackage; 3648 final Intent intent; 3649 final int userId; 3650 synchronized (this) { 3651 task = recentTaskForIdLocked(taskId); 3652 if (task == null) { 3653 throw new IllegalArgumentException("Task " + taskId + " not found."); 3654 } 3655 if (task.getRootActivity() != null) { 3656 moveTaskToFrontLocked(task.taskId, 0, null); 3657 return ActivityManager.START_TASK_TO_FRONT; 3658 } 3659 callingUid = task.mCallingUid; 3660 callingPackage = task.mCallingPackage; 3661 intent = task.intent; 3662 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3663 userId = task.userId; 3664 } 3665 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3666 options, userId, null, task); 3667 } 3668 3669 final int startActivityInPackage(int uid, String callingPackage, 3670 Intent intent, String resolvedType, IBinder resultTo, 3671 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3672 IActivityContainer container, TaskRecord inTask) { 3673 3674 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3675 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3676 3677 // TODO: Switch to user app stacks here. 3678 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3679 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3680 null, null, null, options, userId, container, inTask); 3681 return ret; 3682 } 3683 3684 @Override 3685 public final int startActivities(IApplicationThread caller, String callingPackage, 3686 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3687 int userId) { 3688 enforceNotIsolatedCaller("startActivities"); 3689 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3690 false, ALLOW_FULL_ONLY, "startActivity", null); 3691 // TODO: Switch to user app stacks here. 3692 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3693 resolvedTypes, resultTo, options, userId); 3694 return ret; 3695 } 3696 3697 final int startActivitiesInPackage(int uid, String callingPackage, 3698 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3699 Bundle options, int userId) { 3700 3701 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3702 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3703 // TODO: Switch to user app stacks here. 3704 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3705 resultTo, options, userId); 3706 return ret; 3707 } 3708 3709 //explicitly remove thd old information in mRecentTasks when removing existing user. 3710 private void removeRecentTasksForUserLocked(int userId) { 3711 if(userId <= 0) { 3712 Slog.i(TAG, "Can't remove recent task on user " + userId); 3713 return; 3714 } 3715 3716 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3717 TaskRecord tr = mRecentTasks.get(i); 3718 if (tr.userId == userId) { 3719 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3720 + " when finishing user" + userId); 3721 mRecentTasks.remove(i); 3722 tr.removedFromRecents(); 3723 } 3724 } 3725 3726 // Remove tasks from persistent storage. 3727 notifyTaskPersisterLocked(null, true); 3728 } 3729 3730 // Sort by taskId 3731 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3732 @Override 3733 public int compare(TaskRecord lhs, TaskRecord rhs) { 3734 return rhs.taskId - lhs.taskId; 3735 } 3736 }; 3737 3738 // Extract the affiliates of the chain containing mRecentTasks[start]. 3739 private int processNextAffiliateChainLocked(int start) { 3740 final TaskRecord startTask = mRecentTasks.get(start); 3741 final int affiliateId = startTask.mAffiliatedTaskId; 3742 3743 // Quick identification of isolated tasks. I.e. those not launched behind. 3744 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3745 startTask.mNextAffiliate == null) { 3746 // There is still a slim chance that there are other tasks that point to this task 3747 // and that the chain is so messed up that this task no longer points to them but 3748 // the gain of this optimization outweighs the risk. 3749 startTask.inRecents = true; 3750 return start + 1; 3751 } 3752 3753 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3754 mTmpRecents.clear(); 3755 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3756 final TaskRecord task = mRecentTasks.get(i); 3757 if (task.mAffiliatedTaskId == affiliateId) { 3758 mRecentTasks.remove(i); 3759 mTmpRecents.add(task); 3760 } 3761 } 3762 3763 // Sort them all by taskId. That is the order they were create in and that order will 3764 // always be correct. 3765 Collections.sort(mTmpRecents, mTaskRecordComparator); 3766 3767 // Go through and fix up the linked list. 3768 // The first one is the end of the chain and has no next. 3769 final TaskRecord first = mTmpRecents.get(0); 3770 first.inRecents = true; 3771 if (first.mNextAffiliate != null) { 3772 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3773 first.setNextAffiliate(null); 3774 notifyTaskPersisterLocked(first, false); 3775 } 3776 // Everything in the middle is doubly linked from next to prev. 3777 final int tmpSize = mTmpRecents.size(); 3778 for (int i = 0; i < tmpSize - 1; ++i) { 3779 final TaskRecord next = mTmpRecents.get(i); 3780 final TaskRecord prev = mTmpRecents.get(i + 1); 3781 if (next.mPrevAffiliate != prev) { 3782 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3783 " setting prev=" + prev); 3784 next.setPrevAffiliate(prev); 3785 notifyTaskPersisterLocked(next, false); 3786 } 3787 if (prev.mNextAffiliate != next) { 3788 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3789 " setting next=" + next); 3790 prev.setNextAffiliate(next); 3791 notifyTaskPersisterLocked(prev, false); 3792 } 3793 prev.inRecents = true; 3794 } 3795 // The last one is the beginning of the list and has no prev. 3796 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3797 if (last.mPrevAffiliate != null) { 3798 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3799 last.setPrevAffiliate(null); 3800 notifyTaskPersisterLocked(last, false); 3801 } 3802 3803 // Insert the group back into mRecentTasks at start. 3804 mRecentTasks.addAll(start, mTmpRecents); 3805 3806 // Let the caller know where we left off. 3807 return start + tmpSize; 3808 } 3809 3810 /** 3811 * Update the recent tasks lists: make sure tasks should still be here (their 3812 * applications / activities still exist), update their availability, fixup ordering 3813 * of affiliations. 3814 */ 3815 void cleanupRecentTasksLocked(int userId) { 3816 if (mRecentTasks == null) { 3817 // Happens when called from the packagemanager broadcast before boot. 3818 return; 3819 } 3820 3821 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3822 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3823 final IPackageManager pm = AppGlobals.getPackageManager(); 3824 final ActivityInfo dummyAct = new ActivityInfo(); 3825 final ApplicationInfo dummyApp = new ApplicationInfo(); 3826 3827 int N = mRecentTasks.size(); 3828 3829 int[] users = userId == UserHandle.USER_ALL 3830 ? getUsersLocked() : new int[] { userId }; 3831 for (int user : users) { 3832 for (int i = 0; i < N; i++) { 3833 TaskRecord task = mRecentTasks.get(i); 3834 if (task.userId != user) { 3835 // Only look at tasks for the user ID of interest. 3836 continue; 3837 } 3838 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3839 // This situation is broken, and we should just get rid of it now. 3840 mRecentTasks.remove(i); 3841 task.removedFromRecents(); 3842 i--; 3843 N--; 3844 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3845 continue; 3846 } 3847 // Check whether this activity is currently available. 3848 if (task.realActivity != null) { 3849 ActivityInfo ai = availActCache.get(task.realActivity); 3850 if (ai == null) { 3851 try { 3852 ai = pm.getActivityInfo(task.realActivity, 3853 PackageManager.GET_UNINSTALLED_PACKAGES 3854 | PackageManager.GET_DISABLED_COMPONENTS, user); 3855 } catch (RemoteException e) { 3856 // Will never happen. 3857 continue; 3858 } 3859 if (ai == null) { 3860 ai = dummyAct; 3861 } 3862 availActCache.put(task.realActivity, ai); 3863 } 3864 if (ai == dummyAct) { 3865 // This could be either because the activity no longer exists, or the 3866 // app is temporarily gone. For the former we want to remove the recents 3867 // entry; for the latter we want to mark it as unavailable. 3868 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3869 if (app == null) { 3870 try { 3871 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3872 PackageManager.GET_UNINSTALLED_PACKAGES 3873 | PackageManager.GET_DISABLED_COMPONENTS, user); 3874 } catch (RemoteException e) { 3875 // Will never happen. 3876 continue; 3877 } 3878 if (app == null) { 3879 app = dummyApp; 3880 } 3881 availAppCache.put(task.realActivity.getPackageName(), app); 3882 } 3883 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3884 // Doesn't exist any more! Good-bye. 3885 mRecentTasks.remove(i); 3886 task.removedFromRecents(); 3887 i--; 3888 N--; 3889 Slog.w(TAG, "Removing no longer valid recent: " + task); 3890 continue; 3891 } else { 3892 // Otherwise just not available for now. 3893 if (task.isAvailable) { 3894 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3895 + task); 3896 } 3897 task.isAvailable = false; 3898 } 3899 } else { 3900 if (!ai.enabled || !ai.applicationInfo.enabled 3901 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3902 if (task.isAvailable) { 3903 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3904 + task + " (enabled=" + ai.enabled + "/" 3905 + ai.applicationInfo.enabled + " flags=" 3906 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3907 } 3908 task.isAvailable = false; 3909 } else { 3910 if (!task.isAvailable) { 3911 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3912 + task); 3913 } 3914 task.isAvailable = true; 3915 } 3916 } 3917 } 3918 } 3919 } 3920 3921 // Verify the affiliate chain for each task. 3922 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) { 3923 } 3924 3925 mTmpRecents.clear(); 3926 // mRecentTasks is now in sorted, affiliated order. 3927 } 3928 3929 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3930 int N = mRecentTasks.size(); 3931 TaskRecord top = task; 3932 int topIndex = taskIndex; 3933 while (top.mNextAffiliate != null && topIndex > 0) { 3934 top = top.mNextAffiliate; 3935 topIndex--; 3936 } 3937 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3938 + topIndex + " from intial " + taskIndex); 3939 // Find the end of the chain, doing a sanity check along the way. 3940 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3941 int endIndex = topIndex; 3942 TaskRecord prev = top; 3943 while (endIndex < N) { 3944 TaskRecord cur = mRecentTasks.get(endIndex); 3945 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3946 + endIndex + " " + cur); 3947 if (cur == top) { 3948 // Verify start of the chain. 3949 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) { 3950 Slog.wtf(TAG, "Bad chain @" + endIndex 3951 + ": first task has next affiliate: " + prev); 3952 sane = false; 3953 break; 3954 } 3955 } else { 3956 // Verify middle of the chain's next points back to the one before. 3957 if (cur.mNextAffiliate != prev 3958 || cur.mNextAffiliateTaskId != prev.taskId) { 3959 Slog.wtf(TAG, "Bad chain @" + endIndex 3960 + ": middle task " + cur + " @" + endIndex 3961 + " has bad next affiliate " 3962 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 3963 + ", expected " + prev); 3964 sane = false; 3965 break; 3966 } 3967 } 3968 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) { 3969 // Chain ends here. 3970 if (cur.mPrevAffiliate != null) { 3971 Slog.wtf(TAG, "Bad chain @" + endIndex 3972 + ": last task " + cur + " has previous affiliate " 3973 + cur.mPrevAffiliate); 3974 sane = false; 3975 } 3976 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 3977 break; 3978 } else { 3979 // Verify middle of the chain's prev points to a valid item. 3980 if (cur.mPrevAffiliate == null) { 3981 Slog.wtf(TAG, "Bad chain @" + endIndex 3982 + ": task " + cur + " has previous affiliate " 3983 + cur.mPrevAffiliate + " but should be id " 3984 + cur.mPrevAffiliate); 3985 sane = false; 3986 break; 3987 } 3988 } 3989 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 3990 Slog.wtf(TAG, "Bad chain @" + endIndex 3991 + ": task " + cur + " has affiliated id " 3992 + cur.mAffiliatedTaskId + " but should be " 3993 + task.mAffiliatedTaskId); 3994 sane = false; 3995 break; 3996 } 3997 prev = cur; 3998 endIndex++; 3999 if (endIndex >= N) { 4000 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4001 + ": last task " + prev); 4002 sane = false; 4003 break; 4004 } 4005 } 4006 if (sane) { 4007 if (endIndex < taskIndex) { 4008 Slog.wtf(TAG, "Bad chain @" + endIndex 4009 + ": did not extend to task " + task + " @" + taskIndex); 4010 sane = false; 4011 } 4012 } 4013 if (sane) { 4014 // All looks good, we can just move all of the affiliated tasks 4015 // to the top. 4016 for (int i=topIndex; i<=endIndex; i++) { 4017 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4018 + " from " + i + " to " + (i-topIndex)); 4019 TaskRecord cur = mRecentTasks.remove(i); 4020 mRecentTasks.add(i-topIndex, cur); 4021 } 4022 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4023 + " to " + endIndex); 4024 return true; 4025 } 4026 4027 // Whoops, couldn't do it. 4028 return false; 4029 } 4030 4031 final void addRecentTaskLocked(TaskRecord task) { 4032 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4033 || task.mNextAffiliateTaskId != INVALID_TASK_ID 4034 || task.mPrevAffiliateTaskId != INVALID_TASK_ID; 4035 4036 int N = mRecentTasks.size(); 4037 // Quick case: check if the top-most recent task is the same. 4038 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4039 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4040 return; 4041 } 4042 // Another quick case: check if this is part of a set of affiliated 4043 // tasks that are at the top. 4044 if (isAffiliated && N > 0 && task.inRecents 4045 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4046 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4047 + " at top when adding " + task); 4048 return; 4049 } 4050 // Another quick case: never add voice sessions. 4051 if (task.voiceSession != null) { 4052 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4053 return; 4054 } 4055 4056 boolean needAffiliationFix = false; 4057 4058 // Slightly less quick case: the task is already in recents, so all we need 4059 // to do is move it. 4060 if (task.inRecents) { 4061 int taskIndex = mRecentTasks.indexOf(task); 4062 if (taskIndex >= 0) { 4063 if (!isAffiliated) { 4064 // Simple case: this is not an affiliated task, so we just move it to the front. 4065 mRecentTasks.remove(taskIndex); 4066 mRecentTasks.add(0, task); 4067 notifyTaskPersisterLocked(task, false); 4068 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4069 + " from " + taskIndex); 4070 return; 4071 } else { 4072 // More complicated: need to keep all affiliated tasks together. 4073 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4074 // All went well. 4075 return; 4076 } 4077 4078 // Uh oh... something bad in the affiliation chain, try to rebuild 4079 // everything and then go through our general path of adding a new task. 4080 needAffiliationFix = true; 4081 } 4082 } else { 4083 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4084 needAffiliationFix = true; 4085 } 4086 } 4087 4088 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4089 trimRecentsForTaskLocked(task, true); 4090 4091 N = mRecentTasks.size(); 4092 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4093 final TaskRecord tr = mRecentTasks.remove(N - 1); 4094 tr.removedFromRecents(); 4095 N--; 4096 } 4097 task.inRecents = true; 4098 if (!isAffiliated || needAffiliationFix) { 4099 // If this is a simple non-affiliated task, or we had some failure trying to 4100 // handle it as part of an affilated task, then just place it at the top. 4101 mRecentTasks.add(0, task); 4102 } else if (isAffiliated) { 4103 // If this is a new affiliated task, then move all of the affiliated tasks 4104 // to the front and insert this new one. 4105 TaskRecord other = task.mNextAffiliate; 4106 if (other == null) { 4107 other = task.mPrevAffiliate; 4108 } 4109 if (other != null) { 4110 int otherIndex = mRecentTasks.indexOf(other); 4111 if (otherIndex >= 0) { 4112 // Insert new task at appropriate location. 4113 int taskIndex; 4114 if (other == task.mNextAffiliate) { 4115 // We found the index of our next affiliation, which is who is 4116 // before us in the list, so add after that point. 4117 taskIndex = otherIndex+1; 4118 } else { 4119 // We found the index of our previous affiliation, which is who is 4120 // after us in the list, so add at their position. 4121 taskIndex = otherIndex; 4122 } 4123 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4124 + taskIndex + ": " + task); 4125 mRecentTasks.add(taskIndex, task); 4126 4127 // Now move everything to the front. 4128 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4129 // All went well. 4130 return; 4131 } 4132 4133 // Uh oh... something bad in the affiliation chain, try to rebuild 4134 // everything and then go through our general path of adding a new task. 4135 needAffiliationFix = true; 4136 } else { 4137 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4138 + other); 4139 needAffiliationFix = true; 4140 } 4141 } else { 4142 if (DEBUG_RECENTS) Slog.d(TAG, 4143 "addRecent: adding affiliated task without next/prev:" + task); 4144 needAffiliationFix = true; 4145 } 4146 } 4147 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4148 4149 if (needAffiliationFix) { 4150 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4151 cleanupRecentTasksLocked(task.userId); 4152 } 4153 } 4154 4155 /** 4156 * If needed, remove oldest existing entries in recents that are for the same kind 4157 * of task as the given one. 4158 */ 4159 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) { 4160 int N = mRecentTasks.size(); 4161 final Intent intent = task.intent; 4162 final boolean document = intent != null && intent.isDocument(); 4163 4164 int maxRecents = task.maxRecents - 1; 4165 for (int i=0; i<N; i++) { 4166 final TaskRecord tr = mRecentTasks.get(i); 4167 if (task != tr) { 4168 if (task.userId != tr.userId) { 4169 continue; 4170 } 4171 if (i > MAX_RECENT_BITMAPS) { 4172 tr.freeLastThumbnail(); 4173 } 4174 final Intent trIntent = tr.intent; 4175 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4176 (intent == null || !intent.filterEquals(trIntent))) { 4177 continue; 4178 } 4179 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4180 if (document && trIsDocument) { 4181 // These are the same document activity (not necessarily the same doc). 4182 if (maxRecents > 0) { 4183 --maxRecents; 4184 continue; 4185 } 4186 // Hit the maximum number of documents for this task. Fall through 4187 // and remove this document from recents. 4188 } else if (document || trIsDocument) { 4189 // Only one of these is a document. Not the droid we're looking for. 4190 continue; 4191 } 4192 } 4193 4194 if (!doTrim) { 4195 // If the caller is not actually asking for a trim, just tell them we reached 4196 // a point where the trim would happen. 4197 return i; 4198 } 4199 4200 // Either task and tr are the same or, their affinities match or their intents match 4201 // and neither of them is a document, or they are documents using the same activity 4202 // and their maxRecents has been reached. 4203 tr.disposeThumbnail(); 4204 mRecentTasks.remove(i); 4205 if (task != tr) { 4206 tr.removedFromRecents(); 4207 } 4208 i--; 4209 N--; 4210 if (task.intent == null) { 4211 // If the new recent task we are adding is not fully 4212 // specified, then replace it with the existing recent task. 4213 task = tr; 4214 } 4215 notifyTaskPersisterLocked(tr, false); 4216 } 4217 4218 return -1; 4219 } 4220 4221 @Override 4222 public void reportActivityFullyDrawn(IBinder token) { 4223 synchronized (this) { 4224 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4225 if (r == null) { 4226 return; 4227 } 4228 r.reportFullyDrawnLocked(); 4229 } 4230 } 4231 4232 @Override 4233 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4234 synchronized (this) { 4235 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4236 if (r == null) { 4237 return; 4238 } 4239 final long origId = Binder.clearCallingIdentity(); 4240 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4241 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4242 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4243 if (config != null) { 4244 r.frozenBeforeDestroy = true; 4245 if (!updateConfigurationLocked(config, r, false, false)) { 4246 mStackSupervisor.resumeTopActivitiesLocked(); 4247 } 4248 } 4249 Binder.restoreCallingIdentity(origId); 4250 } 4251 } 4252 4253 @Override 4254 public int getRequestedOrientation(IBinder token) { 4255 synchronized (this) { 4256 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4257 if (r == null) { 4258 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4259 } 4260 return mWindowManager.getAppOrientation(r.appToken); 4261 } 4262 } 4263 4264 /** 4265 * This is the internal entry point for handling Activity.finish(). 4266 * 4267 * @param token The Binder token referencing the Activity we want to finish. 4268 * @param resultCode Result code, if any, from this Activity. 4269 * @param resultData Result data (Intent), if any, from this Activity. 4270 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4271 * the root Activity in the task. 4272 * 4273 * @return Returns true if the activity successfully finished, or false if it is still running. 4274 */ 4275 @Override 4276 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4277 boolean finishTask) { 4278 // Refuse possible leaked file descriptors 4279 if (resultData != null && resultData.hasFileDescriptors() == true) { 4280 throw new IllegalArgumentException("File descriptors passed in Intent"); 4281 } 4282 4283 synchronized(this) { 4284 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4285 if (r == null) { 4286 return true; 4287 } 4288 // Keep track of the root activity of the task before we finish it 4289 TaskRecord tr = r.task; 4290 ActivityRecord rootR = tr.getRootActivity(); 4291 if (rootR == null) { 4292 Slog.w(TAG, "Finishing task with all activities already finished"); 4293 } 4294 // Do not allow task to finish in Lock Task mode. 4295 if (tr == mStackSupervisor.mLockTaskModeTask) { 4296 if (rootR == r) { 4297 Slog.i(TAG, "Not finishing task in lock task mode"); 4298 mStackSupervisor.showLockTaskToast(); 4299 return false; 4300 } 4301 } 4302 if (mController != null) { 4303 // Find the first activity that is not finishing. 4304 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4305 if (next != null) { 4306 // ask watcher if this is allowed 4307 boolean resumeOK = true; 4308 try { 4309 resumeOK = mController.activityResuming(next.packageName); 4310 } catch (RemoteException e) { 4311 mController = null; 4312 Watchdog.getInstance().setActivityController(null); 4313 } 4314 4315 if (!resumeOK) { 4316 Slog.i(TAG, "Not finishing activity because controller resumed"); 4317 return false; 4318 } 4319 } 4320 } 4321 final long origId = Binder.clearCallingIdentity(); 4322 try { 4323 boolean res; 4324 if (finishTask && r == rootR) { 4325 // If requested, remove the task that is associated to this activity only if it 4326 // was the root activity in the task. The result code and data is ignored 4327 // because we don't support returning them across task boundaries. 4328 res = removeTaskByIdLocked(tr.taskId, false); 4329 if (!res) { 4330 Slog.i(TAG, "Removing task failed to finish activity"); 4331 } 4332 } else { 4333 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4334 resultData, "app-request", true); 4335 if (!res) { 4336 Slog.i(TAG, "Failed to finish by app-request"); 4337 } 4338 } 4339 return res; 4340 } finally { 4341 Binder.restoreCallingIdentity(origId); 4342 } 4343 } 4344 } 4345 4346 @Override 4347 public final void finishHeavyWeightApp() { 4348 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4349 != PackageManager.PERMISSION_GRANTED) { 4350 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4351 + Binder.getCallingPid() 4352 + ", uid=" + Binder.getCallingUid() 4353 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4354 Slog.w(TAG, msg); 4355 throw new SecurityException(msg); 4356 } 4357 4358 synchronized(this) { 4359 if (mHeavyWeightProcess == null) { 4360 return; 4361 } 4362 4363 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4364 mHeavyWeightProcess.activities); 4365 for (int i=0; i<activities.size(); i++) { 4366 ActivityRecord r = activities.get(i); 4367 if (!r.finishing) { 4368 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4369 null, "finish-heavy", true); 4370 } 4371 } 4372 4373 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4374 mHeavyWeightProcess.userId, 0)); 4375 mHeavyWeightProcess = null; 4376 } 4377 } 4378 4379 @Override 4380 public void crashApplication(int uid, int initialPid, String packageName, 4381 String message) { 4382 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4383 != PackageManager.PERMISSION_GRANTED) { 4384 String msg = "Permission Denial: crashApplication() from pid=" 4385 + Binder.getCallingPid() 4386 + ", uid=" + Binder.getCallingUid() 4387 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4388 Slog.w(TAG, msg); 4389 throw new SecurityException(msg); 4390 } 4391 4392 synchronized(this) { 4393 ProcessRecord proc = null; 4394 4395 // Figure out which process to kill. We don't trust that initialPid 4396 // still has any relation to current pids, so must scan through the 4397 // list. 4398 synchronized (mPidsSelfLocked) { 4399 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4400 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4401 if (p.uid != uid) { 4402 continue; 4403 } 4404 if (p.pid == initialPid) { 4405 proc = p; 4406 break; 4407 } 4408 if (p.pkgList.containsKey(packageName)) { 4409 proc = p; 4410 } 4411 } 4412 } 4413 4414 if (proc == null) { 4415 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4416 + " initialPid=" + initialPid 4417 + " packageName=" + packageName); 4418 return; 4419 } 4420 4421 if (proc.thread != null) { 4422 if (proc.pid == Process.myPid()) { 4423 Log.w(TAG, "crashApplication: trying to crash self!"); 4424 return; 4425 } 4426 long ident = Binder.clearCallingIdentity(); 4427 try { 4428 proc.thread.scheduleCrash(message); 4429 } catch (RemoteException e) { 4430 } 4431 Binder.restoreCallingIdentity(ident); 4432 } 4433 } 4434 } 4435 4436 @Override 4437 public final void finishSubActivity(IBinder token, String resultWho, 4438 int requestCode) { 4439 synchronized(this) { 4440 final long origId = Binder.clearCallingIdentity(); 4441 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4442 if (r != null) { 4443 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4444 } 4445 Binder.restoreCallingIdentity(origId); 4446 } 4447 } 4448 4449 @Override 4450 public boolean finishActivityAffinity(IBinder token) { 4451 synchronized(this) { 4452 final long origId = Binder.clearCallingIdentity(); 4453 try { 4454 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4455 4456 ActivityRecord rootR = r.task.getRootActivity(); 4457 // Do not allow task to finish in Lock Task mode. 4458 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4459 if (rootR == r) { 4460 mStackSupervisor.showLockTaskToast(); 4461 return false; 4462 } 4463 } 4464 boolean res = false; 4465 if (r != null) { 4466 res = r.task.stack.finishActivityAffinityLocked(r); 4467 } 4468 return res; 4469 } finally { 4470 Binder.restoreCallingIdentity(origId); 4471 } 4472 } 4473 } 4474 4475 @Override 4476 public void finishVoiceTask(IVoiceInteractionSession session) { 4477 synchronized(this) { 4478 final long origId = Binder.clearCallingIdentity(); 4479 try { 4480 mStackSupervisor.finishVoiceTask(session); 4481 } finally { 4482 Binder.restoreCallingIdentity(origId); 4483 } 4484 } 4485 4486 } 4487 4488 @Override 4489 public boolean releaseActivityInstance(IBinder token) { 4490 synchronized(this) { 4491 final long origId = Binder.clearCallingIdentity(); 4492 try { 4493 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4494 if (r.task == null || r.task.stack == null) { 4495 return false; 4496 } 4497 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4498 } finally { 4499 Binder.restoreCallingIdentity(origId); 4500 } 4501 } 4502 } 4503 4504 @Override 4505 public void releaseSomeActivities(IApplicationThread appInt) { 4506 synchronized(this) { 4507 final long origId = Binder.clearCallingIdentity(); 4508 try { 4509 ProcessRecord app = getRecordForAppLocked(appInt); 4510 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4511 } finally { 4512 Binder.restoreCallingIdentity(origId); 4513 } 4514 } 4515 } 4516 4517 @Override 4518 public boolean willActivityBeVisible(IBinder token) { 4519 synchronized(this) { 4520 ActivityStack stack = ActivityRecord.getStackLocked(token); 4521 if (stack != null) { 4522 return stack.willActivityBeVisibleLocked(token); 4523 } 4524 return false; 4525 } 4526 } 4527 4528 @Override 4529 public void overridePendingTransition(IBinder token, String packageName, 4530 int enterAnim, int exitAnim) { 4531 synchronized(this) { 4532 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4533 if (self == null) { 4534 return; 4535 } 4536 4537 final long origId = Binder.clearCallingIdentity(); 4538 4539 if (self.state == ActivityState.RESUMED 4540 || self.state == ActivityState.PAUSING) { 4541 mWindowManager.overridePendingAppTransition(packageName, 4542 enterAnim, exitAnim, null); 4543 } 4544 4545 Binder.restoreCallingIdentity(origId); 4546 } 4547 } 4548 4549 /** 4550 * Main function for removing an existing process from the activity manager 4551 * as a result of that process going away. Clears out all connections 4552 * to the process. 4553 */ 4554 private final void handleAppDiedLocked(ProcessRecord app, 4555 boolean restarting, boolean allowRestart) { 4556 int pid = app.pid; 4557 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4558 if (!kept && !restarting) { 4559 removeLruProcessLocked(app); 4560 if (pid > 0) { 4561 ProcessList.remove(pid); 4562 } 4563 } 4564 4565 if (mProfileProc == app) { 4566 clearProfilerLocked(); 4567 } 4568 4569 // Remove this application's activities from active lists. 4570 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4571 4572 app.activities.clear(); 4573 4574 if (app.instrumentationClass != null) { 4575 Slog.w(TAG, "Crash of app " + app.processName 4576 + " running instrumentation " + app.instrumentationClass); 4577 Bundle info = new Bundle(); 4578 info.putString("shortMsg", "Process crashed."); 4579 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4580 } 4581 4582 if (!restarting) { 4583 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4584 // If there was nothing to resume, and we are not already 4585 // restarting this process, but there is a visible activity that 4586 // is hosted by the process... then make sure all visible 4587 // activities are running, taking care of restarting this 4588 // process. 4589 if (hasVisibleActivities) { 4590 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4591 } 4592 } 4593 } 4594 } 4595 4596 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4597 IBinder threadBinder = thread.asBinder(); 4598 // Find the application record. 4599 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4600 ProcessRecord rec = mLruProcesses.get(i); 4601 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4602 return i; 4603 } 4604 } 4605 return -1; 4606 } 4607 4608 final ProcessRecord getRecordForAppLocked( 4609 IApplicationThread thread) { 4610 if (thread == null) { 4611 return null; 4612 } 4613 4614 int appIndex = getLRURecordIndexForAppLocked(thread); 4615 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4616 } 4617 4618 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4619 // If there are no longer any background processes running, 4620 // and the app that died was not running instrumentation, 4621 // then tell everyone we are now low on memory. 4622 boolean haveBg = false; 4623 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4624 ProcessRecord rec = mLruProcesses.get(i); 4625 if (rec.thread != null 4626 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4627 haveBg = true; 4628 break; 4629 } 4630 } 4631 4632 if (!haveBg) { 4633 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4634 if (doReport) { 4635 long now = SystemClock.uptimeMillis(); 4636 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4637 doReport = false; 4638 } else { 4639 mLastMemUsageReportTime = now; 4640 } 4641 } 4642 final ArrayList<ProcessMemInfo> memInfos 4643 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4644 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4645 long now = SystemClock.uptimeMillis(); 4646 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4647 ProcessRecord rec = mLruProcesses.get(i); 4648 if (rec == dyingProc || rec.thread == null) { 4649 continue; 4650 } 4651 if (doReport) { 4652 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4653 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4654 } 4655 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4656 // The low memory report is overriding any current 4657 // state for a GC request. Make sure to do 4658 // heavy/important/visible/foreground processes first. 4659 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4660 rec.lastRequestedGc = 0; 4661 } else { 4662 rec.lastRequestedGc = rec.lastLowMemory; 4663 } 4664 rec.reportLowMemory = true; 4665 rec.lastLowMemory = now; 4666 mProcessesToGc.remove(rec); 4667 addProcessToGcListLocked(rec); 4668 } 4669 } 4670 if (doReport) { 4671 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4672 mHandler.sendMessage(msg); 4673 } 4674 scheduleAppGcsLocked(); 4675 } 4676 } 4677 4678 final void appDiedLocked(ProcessRecord app) { 4679 appDiedLocked(app, app.pid, app.thread); 4680 } 4681 4682 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4683 // First check if this ProcessRecord is actually active for the pid. 4684 synchronized (mPidsSelfLocked) { 4685 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4686 if (curProc != app) { 4687 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4688 return; 4689 } 4690 } 4691 4692 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4693 synchronized (stats) { 4694 stats.noteProcessDiedLocked(app.info.uid, pid); 4695 } 4696 4697 if (!app.killed) { 4698 Process.killProcessQuiet(pid); 4699 Process.killProcessGroup(app.info.uid, pid); 4700 app.killed = true; 4701 } 4702 4703 // Clean up already done if the process has been re-started. 4704 if (app.pid == pid && app.thread != null && 4705 app.thread.asBinder() == thread.asBinder()) { 4706 boolean doLowMem = app.instrumentationClass == null; 4707 boolean doOomAdj = doLowMem; 4708 if (!app.killedByAm) { 4709 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4710 + ") has died"); 4711 mAllowLowerMemLevel = true; 4712 } else { 4713 // Note that we always want to do oom adj to update our state with the 4714 // new number of procs. 4715 mAllowLowerMemLevel = false; 4716 doLowMem = false; 4717 } 4718 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4719 if (DEBUG_CLEANUP) Slog.v( 4720 TAG, "Dying app: " + app + ", pid: " + pid 4721 + ", thread: " + thread.asBinder()); 4722 handleAppDiedLocked(app, false, true); 4723 4724 if (doOomAdj) { 4725 updateOomAdjLocked(); 4726 } 4727 if (doLowMem) { 4728 doLowMemReportIfNeededLocked(app); 4729 } 4730 } else if (app.pid != pid) { 4731 // A new process has already been started. 4732 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4733 + ") has died and restarted (pid " + app.pid + ")."); 4734 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4735 } else if (DEBUG_PROCESSES) { 4736 Slog.d(TAG, "Received spurious death notification for thread " 4737 + thread.asBinder()); 4738 } 4739 } 4740 4741 /** 4742 * If a stack trace dump file is configured, dump process stack traces. 4743 * @param clearTraces causes the dump file to be erased prior to the new 4744 * traces being written, if true; when false, the new traces will be 4745 * appended to any existing file content. 4746 * @param firstPids of dalvik VM processes to dump stack traces for first 4747 * @param lastPids of dalvik VM processes to dump stack traces for last 4748 * @param nativeProcs optional list of native process names to dump stack crawls 4749 * @return file containing stack traces, or null if no dump file is configured 4750 */ 4751 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4752 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4753 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4754 if (tracesPath == null || tracesPath.length() == 0) { 4755 return null; 4756 } 4757 4758 File tracesFile = new File(tracesPath); 4759 try { 4760 File tracesDir = tracesFile.getParentFile(); 4761 if (!tracesDir.exists()) { 4762 tracesDir.mkdirs(); 4763 if (!SELinux.restorecon(tracesDir)) { 4764 return null; 4765 } 4766 } 4767 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4768 4769 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4770 tracesFile.createNewFile(); 4771 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4772 } catch (IOException e) { 4773 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4774 return null; 4775 } 4776 4777 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4778 return tracesFile; 4779 } 4780 4781 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4782 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4783 // Use a FileObserver to detect when traces finish writing. 4784 // The order of traces is considered important to maintain for legibility. 4785 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4786 @Override 4787 public synchronized void onEvent(int event, String path) { notify(); } 4788 }; 4789 4790 try { 4791 observer.startWatching(); 4792 4793 // First collect all of the stacks of the most important pids. 4794 if (firstPids != null) { 4795 try { 4796 int num = firstPids.size(); 4797 for (int i = 0; i < num; i++) { 4798 synchronized (observer) { 4799 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4800 observer.wait(200); // Wait for write-close, give up after 200msec 4801 } 4802 } 4803 } catch (InterruptedException e) { 4804 Slog.wtf(TAG, e); 4805 } 4806 } 4807 4808 // Next collect the stacks of the native pids 4809 if (nativeProcs != null) { 4810 int[] pids = Process.getPidsForCommands(nativeProcs); 4811 if (pids != null) { 4812 for (int pid : pids) { 4813 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4814 } 4815 } 4816 } 4817 4818 // Lastly, measure CPU usage. 4819 if (processCpuTracker != null) { 4820 processCpuTracker.init(); 4821 System.gc(); 4822 processCpuTracker.update(); 4823 try { 4824 synchronized (processCpuTracker) { 4825 processCpuTracker.wait(500); // measure over 1/2 second. 4826 } 4827 } catch (InterruptedException e) { 4828 } 4829 processCpuTracker.update(); 4830 4831 // We'll take the stack crawls of just the top apps using CPU. 4832 final int N = processCpuTracker.countWorkingStats(); 4833 int numProcs = 0; 4834 for (int i=0; i<N && numProcs<5; i++) { 4835 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4836 if (lastPids.indexOfKey(stats.pid) >= 0) { 4837 numProcs++; 4838 try { 4839 synchronized (observer) { 4840 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4841 observer.wait(200); // Wait for write-close, give up after 200msec 4842 } 4843 } catch (InterruptedException e) { 4844 Slog.wtf(TAG, e); 4845 } 4846 4847 } 4848 } 4849 } 4850 } finally { 4851 observer.stopWatching(); 4852 } 4853 } 4854 4855 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4856 if (true || IS_USER_BUILD) { 4857 return; 4858 } 4859 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4860 if (tracesPath == null || tracesPath.length() == 0) { 4861 return; 4862 } 4863 4864 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4865 StrictMode.allowThreadDiskWrites(); 4866 try { 4867 final File tracesFile = new File(tracesPath); 4868 final File tracesDir = tracesFile.getParentFile(); 4869 final File tracesTmp = new File(tracesDir, "__tmp__"); 4870 try { 4871 if (!tracesDir.exists()) { 4872 tracesDir.mkdirs(); 4873 if (!SELinux.restorecon(tracesDir.getPath())) { 4874 return; 4875 } 4876 } 4877 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4878 4879 if (tracesFile.exists()) { 4880 tracesTmp.delete(); 4881 tracesFile.renameTo(tracesTmp); 4882 } 4883 StringBuilder sb = new StringBuilder(); 4884 Time tobj = new Time(); 4885 tobj.set(System.currentTimeMillis()); 4886 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4887 sb.append(": "); 4888 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4889 sb.append(" since "); 4890 sb.append(msg); 4891 FileOutputStream fos = new FileOutputStream(tracesFile); 4892 fos.write(sb.toString().getBytes()); 4893 if (app == null) { 4894 fos.write("\n*** No application process!".getBytes()); 4895 } 4896 fos.close(); 4897 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4898 } catch (IOException e) { 4899 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4900 return; 4901 } 4902 4903 if (app != null) { 4904 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4905 firstPids.add(app.pid); 4906 dumpStackTraces(tracesPath, firstPids, null, null, null); 4907 } 4908 4909 File lastTracesFile = null; 4910 File curTracesFile = null; 4911 for (int i=9; i>=0; i--) { 4912 String name = String.format(Locale.US, "slow%02d.txt", i); 4913 curTracesFile = new File(tracesDir, name); 4914 if (curTracesFile.exists()) { 4915 if (lastTracesFile != null) { 4916 curTracesFile.renameTo(lastTracesFile); 4917 } else { 4918 curTracesFile.delete(); 4919 } 4920 } 4921 lastTracesFile = curTracesFile; 4922 } 4923 tracesFile.renameTo(curTracesFile); 4924 if (tracesTmp.exists()) { 4925 tracesTmp.renameTo(tracesFile); 4926 } 4927 } finally { 4928 StrictMode.setThreadPolicy(oldPolicy); 4929 } 4930 } 4931 4932 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4933 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4934 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4935 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4936 4937 if (mController != null) { 4938 try { 4939 // 0 == continue, -1 = kill process immediately 4940 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4941 if (res < 0 && app.pid != MY_PID) { 4942 app.kill("anr", true); 4943 } 4944 } catch (RemoteException e) { 4945 mController = null; 4946 Watchdog.getInstance().setActivityController(null); 4947 } 4948 } 4949 4950 long anrTime = SystemClock.uptimeMillis(); 4951 if (MONITOR_CPU_USAGE) { 4952 updateCpuStatsNow(); 4953 } 4954 4955 synchronized (this) { 4956 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4957 if (mShuttingDown) { 4958 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4959 return; 4960 } else if (app.notResponding) { 4961 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4962 return; 4963 } else if (app.crashing) { 4964 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4965 return; 4966 } 4967 4968 // In case we come through here for the same app before completing 4969 // this one, mark as anring now so we will bail out. 4970 app.notResponding = true; 4971 4972 // Log the ANR to the event log. 4973 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4974 app.processName, app.info.flags, annotation); 4975 4976 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4977 firstPids.add(app.pid); 4978 4979 int parentPid = app.pid; 4980 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4981 if (parentPid != app.pid) firstPids.add(parentPid); 4982 4983 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4984 4985 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4986 ProcessRecord r = mLruProcesses.get(i); 4987 if (r != null && r.thread != null) { 4988 int pid = r.pid; 4989 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4990 if (r.persistent) { 4991 firstPids.add(pid); 4992 } else { 4993 lastPids.put(pid, Boolean.TRUE); 4994 } 4995 } 4996 } 4997 } 4998 } 4999 5000 // Log the ANR to the main log. 5001 StringBuilder info = new StringBuilder(); 5002 info.setLength(0); 5003 info.append("ANR in ").append(app.processName); 5004 if (activity != null && activity.shortComponentName != null) { 5005 info.append(" (").append(activity.shortComponentName).append(")"); 5006 } 5007 info.append("\n"); 5008 info.append("PID: ").append(app.pid).append("\n"); 5009 if (annotation != null) { 5010 info.append("Reason: ").append(annotation).append("\n"); 5011 } 5012 if (parent != null && parent != activity) { 5013 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5014 } 5015 5016 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5017 5018 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5019 NATIVE_STACKS_OF_INTEREST); 5020 5021 String cpuInfo = null; 5022 if (MONITOR_CPU_USAGE) { 5023 updateCpuStatsNow(); 5024 synchronized (mProcessCpuTracker) { 5025 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5026 } 5027 info.append(processCpuTracker.printCurrentLoad()); 5028 info.append(cpuInfo); 5029 } 5030 5031 info.append(processCpuTracker.printCurrentState(anrTime)); 5032 5033 Slog.e(TAG, info.toString()); 5034 if (tracesFile == null) { 5035 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5036 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5037 } 5038 5039 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5040 cpuInfo, tracesFile, null); 5041 5042 if (mController != null) { 5043 try { 5044 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5045 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5046 if (res != 0) { 5047 if (res < 0 && app.pid != MY_PID) { 5048 app.kill("anr", true); 5049 } else { 5050 synchronized (this) { 5051 mServices.scheduleServiceTimeoutLocked(app); 5052 } 5053 } 5054 return; 5055 } 5056 } catch (RemoteException e) { 5057 mController = null; 5058 Watchdog.getInstance().setActivityController(null); 5059 } 5060 } 5061 5062 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5063 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5064 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5065 5066 synchronized (this) { 5067 mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 5068 5069 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5070 app.kill("bg anr", true); 5071 return; 5072 } 5073 5074 // Set the app's notResponding state, and look up the errorReportReceiver 5075 makeAppNotRespondingLocked(app, 5076 activity != null ? activity.shortComponentName : null, 5077 annotation != null ? "ANR " + annotation : "ANR", 5078 info.toString()); 5079 5080 // Bring up the infamous App Not Responding dialog 5081 Message msg = Message.obtain(); 5082 HashMap<String, Object> map = new HashMap<String, Object>(); 5083 msg.what = SHOW_NOT_RESPONDING_MSG; 5084 msg.obj = map; 5085 msg.arg1 = aboveSystem ? 1 : 0; 5086 map.put("app", app); 5087 if (activity != null) { 5088 map.put("activity", activity); 5089 } 5090 5091 mHandler.sendMessage(msg); 5092 } 5093 } 5094 5095 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5096 if (!mLaunchWarningShown) { 5097 mLaunchWarningShown = true; 5098 mHandler.post(new Runnable() { 5099 @Override 5100 public void run() { 5101 synchronized (ActivityManagerService.this) { 5102 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5103 d.show(); 5104 mHandler.postDelayed(new Runnable() { 5105 @Override 5106 public void run() { 5107 synchronized (ActivityManagerService.this) { 5108 d.dismiss(); 5109 mLaunchWarningShown = false; 5110 } 5111 } 5112 }, 4000); 5113 } 5114 } 5115 }); 5116 } 5117 } 5118 5119 @Override 5120 public boolean clearApplicationUserData(final String packageName, 5121 final IPackageDataObserver observer, int userId) { 5122 enforceNotIsolatedCaller("clearApplicationUserData"); 5123 int uid = Binder.getCallingUid(); 5124 int pid = Binder.getCallingPid(); 5125 userId = handleIncomingUser(pid, uid, 5126 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5127 long callingId = Binder.clearCallingIdentity(); 5128 try { 5129 IPackageManager pm = AppGlobals.getPackageManager(); 5130 int pkgUid = -1; 5131 synchronized(this) { 5132 try { 5133 pkgUid = pm.getPackageUid(packageName, userId); 5134 } catch (RemoteException e) { 5135 } 5136 if (pkgUid == -1) { 5137 Slog.w(TAG, "Invalid packageName: " + packageName); 5138 if (observer != null) { 5139 try { 5140 observer.onRemoveCompleted(packageName, false); 5141 } catch (RemoteException e) { 5142 Slog.i(TAG, "Observer no longer exists."); 5143 } 5144 } 5145 return false; 5146 } 5147 if (uid == pkgUid || checkComponentPermission( 5148 android.Manifest.permission.CLEAR_APP_USER_DATA, 5149 pid, uid, -1, true) 5150 == PackageManager.PERMISSION_GRANTED) { 5151 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5152 } else { 5153 throw new SecurityException("PID " + pid + " does not have permission " 5154 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5155 + " of package " + packageName); 5156 } 5157 5158 // Remove all tasks match the cleared application package and user 5159 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5160 final TaskRecord tr = mRecentTasks.get(i); 5161 final String taskPackageName = 5162 tr.getBaseIntent().getComponent().getPackageName(); 5163 if (tr.userId != userId) continue; 5164 if (!taskPackageName.equals(packageName)) continue; 5165 removeTaskByIdLocked(tr.taskId, false); 5166 } 5167 } 5168 5169 try { 5170 // Clear application user data 5171 pm.clearApplicationUserData(packageName, observer, userId); 5172 5173 synchronized(this) { 5174 // Remove all permissions granted from/to this package 5175 removeUriPermissionsForPackageLocked(packageName, userId, true); 5176 } 5177 5178 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5179 Uri.fromParts("package", packageName, null)); 5180 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5181 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5182 null, null, 0, null, null, null, false, false, userId); 5183 } catch (RemoteException e) { 5184 } 5185 } finally { 5186 Binder.restoreCallingIdentity(callingId); 5187 } 5188 return true; 5189 } 5190 5191 @Override 5192 public void killBackgroundProcesses(final String packageName, int userId) { 5193 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5194 != PackageManager.PERMISSION_GRANTED && 5195 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5196 != PackageManager.PERMISSION_GRANTED) { 5197 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5198 + Binder.getCallingPid() 5199 + ", uid=" + Binder.getCallingUid() 5200 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5201 Slog.w(TAG, msg); 5202 throw new SecurityException(msg); 5203 } 5204 5205 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5206 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5207 long callingId = Binder.clearCallingIdentity(); 5208 try { 5209 IPackageManager pm = AppGlobals.getPackageManager(); 5210 synchronized(this) { 5211 int appId = -1; 5212 try { 5213 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5214 } catch (RemoteException e) { 5215 } 5216 if (appId == -1) { 5217 Slog.w(TAG, "Invalid packageName: " + packageName); 5218 return; 5219 } 5220 killPackageProcessesLocked(packageName, appId, userId, 5221 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5222 } 5223 } finally { 5224 Binder.restoreCallingIdentity(callingId); 5225 } 5226 } 5227 5228 @Override 5229 public void killAllBackgroundProcesses() { 5230 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5231 != PackageManager.PERMISSION_GRANTED) { 5232 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5233 + Binder.getCallingPid() 5234 + ", uid=" + Binder.getCallingUid() 5235 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5236 Slog.w(TAG, msg); 5237 throw new SecurityException(msg); 5238 } 5239 5240 long callingId = Binder.clearCallingIdentity(); 5241 try { 5242 synchronized(this) { 5243 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5244 final int NP = mProcessNames.getMap().size(); 5245 for (int ip=0; ip<NP; ip++) { 5246 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5247 final int NA = apps.size(); 5248 for (int ia=0; ia<NA; ia++) { 5249 ProcessRecord app = apps.valueAt(ia); 5250 if (app.persistent) { 5251 // we don't kill persistent processes 5252 continue; 5253 } 5254 if (app.removed) { 5255 procs.add(app); 5256 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5257 app.removed = true; 5258 procs.add(app); 5259 } 5260 } 5261 } 5262 5263 int N = procs.size(); 5264 for (int i=0; i<N; i++) { 5265 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5266 } 5267 mAllowLowerMemLevel = true; 5268 updateOomAdjLocked(); 5269 doLowMemReportIfNeededLocked(null); 5270 } 5271 } finally { 5272 Binder.restoreCallingIdentity(callingId); 5273 } 5274 } 5275 5276 @Override 5277 public void forceStopPackage(final String packageName, int userId) { 5278 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5279 != PackageManager.PERMISSION_GRANTED) { 5280 String msg = "Permission Denial: forceStopPackage() from pid=" 5281 + Binder.getCallingPid() 5282 + ", uid=" + Binder.getCallingUid() 5283 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5284 Slog.w(TAG, msg); 5285 throw new SecurityException(msg); 5286 } 5287 final int callingPid = Binder.getCallingPid(); 5288 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5289 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5290 long callingId = Binder.clearCallingIdentity(); 5291 try { 5292 IPackageManager pm = AppGlobals.getPackageManager(); 5293 synchronized(this) { 5294 int[] users = userId == UserHandle.USER_ALL 5295 ? getUsersLocked() : new int[] { userId }; 5296 for (int user : users) { 5297 int pkgUid = -1; 5298 try { 5299 pkgUid = pm.getPackageUid(packageName, user); 5300 } catch (RemoteException e) { 5301 } 5302 if (pkgUid == -1) { 5303 Slog.w(TAG, "Invalid packageName: " + packageName); 5304 continue; 5305 } 5306 try { 5307 pm.setPackageStoppedState(packageName, true, user); 5308 } catch (RemoteException e) { 5309 } catch (IllegalArgumentException e) { 5310 Slog.w(TAG, "Failed trying to unstop package " 5311 + packageName + ": " + e); 5312 } 5313 if (isUserRunningLocked(user, false)) { 5314 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5315 } 5316 } 5317 } 5318 } finally { 5319 Binder.restoreCallingIdentity(callingId); 5320 } 5321 } 5322 5323 @Override 5324 public void addPackageDependency(String packageName) { 5325 synchronized (this) { 5326 int callingPid = Binder.getCallingPid(); 5327 if (callingPid == Process.myPid()) { 5328 // Yeah, um, no. 5329 return; 5330 } 5331 ProcessRecord proc; 5332 synchronized (mPidsSelfLocked) { 5333 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5334 } 5335 if (proc != null) { 5336 if (proc.pkgDeps == null) { 5337 proc.pkgDeps = new ArraySet<String>(1); 5338 } 5339 proc.pkgDeps.add(packageName); 5340 } 5341 } 5342 } 5343 5344 /* 5345 * The pkg name and app id have to be specified. 5346 */ 5347 @Override 5348 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5349 if (pkg == null) { 5350 return; 5351 } 5352 // Make sure the uid is valid. 5353 if (appid < 0) { 5354 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5355 return; 5356 } 5357 int callerUid = Binder.getCallingUid(); 5358 // Only the system server can kill an application 5359 if (callerUid == Process.SYSTEM_UID) { 5360 // Post an aysnc message to kill the application 5361 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5362 msg.arg1 = appid; 5363 msg.arg2 = 0; 5364 Bundle bundle = new Bundle(); 5365 bundle.putString("pkg", pkg); 5366 bundle.putString("reason", reason); 5367 msg.obj = bundle; 5368 mHandler.sendMessage(msg); 5369 } else { 5370 throw new SecurityException(callerUid + " cannot kill pkg: " + 5371 pkg); 5372 } 5373 } 5374 5375 @Override 5376 public void closeSystemDialogs(String reason) { 5377 enforceNotIsolatedCaller("closeSystemDialogs"); 5378 5379 final int pid = Binder.getCallingPid(); 5380 final int uid = Binder.getCallingUid(); 5381 final long origId = Binder.clearCallingIdentity(); 5382 try { 5383 synchronized (this) { 5384 // Only allow this from foreground processes, so that background 5385 // applications can't abuse it to prevent system UI from being shown. 5386 if (uid >= Process.FIRST_APPLICATION_UID) { 5387 ProcessRecord proc; 5388 synchronized (mPidsSelfLocked) { 5389 proc = mPidsSelfLocked.get(pid); 5390 } 5391 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5392 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5393 + " from background process " + proc); 5394 return; 5395 } 5396 } 5397 closeSystemDialogsLocked(reason); 5398 } 5399 } finally { 5400 Binder.restoreCallingIdentity(origId); 5401 } 5402 } 5403 5404 void closeSystemDialogsLocked(String reason) { 5405 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5406 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5407 | Intent.FLAG_RECEIVER_FOREGROUND); 5408 if (reason != null) { 5409 intent.putExtra("reason", reason); 5410 } 5411 mWindowManager.closeSystemDialogs(reason); 5412 5413 mStackSupervisor.closeSystemDialogsLocked(); 5414 5415 broadcastIntentLocked(null, null, intent, null, 5416 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5417 Process.SYSTEM_UID, UserHandle.USER_ALL); 5418 } 5419 5420 @Override 5421 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5422 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5423 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5424 for (int i=pids.length-1; i>=0; i--) { 5425 ProcessRecord proc; 5426 int oomAdj; 5427 synchronized (this) { 5428 synchronized (mPidsSelfLocked) { 5429 proc = mPidsSelfLocked.get(pids[i]); 5430 oomAdj = proc != null ? proc.setAdj : 0; 5431 } 5432 } 5433 infos[i] = new Debug.MemoryInfo(); 5434 Debug.getMemoryInfo(pids[i], infos[i]); 5435 if (proc != null) { 5436 synchronized (this) { 5437 if (proc.thread != null && proc.setAdj == oomAdj) { 5438 // Record this for posterity if the process has been stable. 5439 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5440 infos[i].getTotalUss(), false, proc.pkgList); 5441 } 5442 } 5443 } 5444 } 5445 return infos; 5446 } 5447 5448 @Override 5449 public long[] getProcessPss(int[] pids) { 5450 enforceNotIsolatedCaller("getProcessPss"); 5451 long[] pss = new long[pids.length]; 5452 for (int i=pids.length-1; i>=0; i--) { 5453 ProcessRecord proc; 5454 int oomAdj; 5455 synchronized (this) { 5456 synchronized (mPidsSelfLocked) { 5457 proc = mPidsSelfLocked.get(pids[i]); 5458 oomAdj = proc != null ? proc.setAdj : 0; 5459 } 5460 } 5461 long[] tmpUss = new long[1]; 5462 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5463 if (proc != null) { 5464 synchronized (this) { 5465 if (proc.thread != null && proc.setAdj == oomAdj) { 5466 // Record this for posterity if the process has been stable. 5467 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5468 } 5469 } 5470 } 5471 } 5472 return pss; 5473 } 5474 5475 @Override 5476 public void killApplicationProcess(String processName, int uid) { 5477 if (processName == null) { 5478 return; 5479 } 5480 5481 int callerUid = Binder.getCallingUid(); 5482 // Only the system server can kill an application 5483 if (callerUid == Process.SYSTEM_UID) { 5484 synchronized (this) { 5485 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5486 if (app != null && app.thread != null) { 5487 try { 5488 app.thread.scheduleSuicide(); 5489 } catch (RemoteException e) { 5490 // If the other end already died, then our work here is done. 5491 } 5492 } else { 5493 Slog.w(TAG, "Process/uid not found attempting kill of " 5494 + processName + " / " + uid); 5495 } 5496 } 5497 } else { 5498 throw new SecurityException(callerUid + " cannot kill app process: " + 5499 processName); 5500 } 5501 } 5502 5503 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5504 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5505 false, true, false, false, UserHandle.getUserId(uid), reason); 5506 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5507 Uri.fromParts("package", packageName, null)); 5508 if (!mProcessesReady) { 5509 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5510 | Intent.FLAG_RECEIVER_FOREGROUND); 5511 } 5512 intent.putExtra(Intent.EXTRA_UID, uid); 5513 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5514 broadcastIntentLocked(null, null, intent, 5515 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5516 false, false, 5517 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5518 } 5519 5520 private void forceStopUserLocked(int userId, String reason) { 5521 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5522 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5523 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5524 | Intent.FLAG_RECEIVER_FOREGROUND); 5525 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5526 broadcastIntentLocked(null, null, intent, 5527 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5528 false, false, 5529 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5530 } 5531 5532 private final boolean killPackageProcessesLocked(String packageName, int appId, 5533 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5534 boolean doit, boolean evenPersistent, String reason) { 5535 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5536 5537 // Remove all processes this package may have touched: all with the 5538 // same UID (except for the system or root user), and all whose name 5539 // matches the package name. 5540 final int NP = mProcessNames.getMap().size(); 5541 for (int ip=0; ip<NP; ip++) { 5542 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5543 final int NA = apps.size(); 5544 for (int ia=0; ia<NA; ia++) { 5545 ProcessRecord app = apps.valueAt(ia); 5546 if (app.persistent && !evenPersistent) { 5547 // we don't kill persistent processes 5548 continue; 5549 } 5550 if (app.removed) { 5551 if (doit) { 5552 procs.add(app); 5553 } 5554 continue; 5555 } 5556 5557 // Skip process if it doesn't meet our oom adj requirement. 5558 if (app.setAdj < minOomAdj) { 5559 continue; 5560 } 5561 5562 // If no package is specified, we call all processes under the 5563 // give user id. 5564 if (packageName == null) { 5565 if (app.userId != userId) { 5566 continue; 5567 } 5568 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5569 continue; 5570 } 5571 // Package has been specified, we want to hit all processes 5572 // that match it. We need to qualify this by the processes 5573 // that are running under the specified app and user ID. 5574 } else { 5575 final boolean isDep = app.pkgDeps != null 5576 && app.pkgDeps.contains(packageName); 5577 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5578 continue; 5579 } 5580 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5581 continue; 5582 } 5583 if (!app.pkgList.containsKey(packageName) && !isDep) { 5584 continue; 5585 } 5586 } 5587 5588 // Process has passed all conditions, kill it! 5589 if (!doit) { 5590 return true; 5591 } 5592 app.removed = true; 5593 procs.add(app); 5594 } 5595 } 5596 5597 int N = procs.size(); 5598 for (int i=0; i<N; i++) { 5599 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5600 } 5601 updateOomAdjLocked(); 5602 return N > 0; 5603 } 5604 5605 private final boolean forceStopPackageLocked(String name, int appId, 5606 boolean callerWillRestart, boolean purgeCache, boolean doit, 5607 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5608 int i; 5609 int N; 5610 5611 if (userId == UserHandle.USER_ALL && name == null) { 5612 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5613 } 5614 5615 if (appId < 0 && name != null) { 5616 try { 5617 appId = UserHandle.getAppId( 5618 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5619 } catch (RemoteException e) { 5620 } 5621 } 5622 5623 if (doit) { 5624 if (name != null) { 5625 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5626 + " user=" + userId + ": " + reason); 5627 } else { 5628 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5629 } 5630 5631 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5632 for (int ip=pmap.size()-1; ip>=0; ip--) { 5633 SparseArray<Long> ba = pmap.valueAt(ip); 5634 for (i=ba.size()-1; i>=0; i--) { 5635 boolean remove = false; 5636 final int entUid = ba.keyAt(i); 5637 if (name != null) { 5638 if (userId == UserHandle.USER_ALL) { 5639 if (UserHandle.getAppId(entUid) == appId) { 5640 remove = true; 5641 } 5642 } else { 5643 if (entUid == UserHandle.getUid(userId, appId)) { 5644 remove = true; 5645 } 5646 } 5647 } else if (UserHandle.getUserId(entUid) == userId) { 5648 remove = true; 5649 } 5650 if (remove) { 5651 ba.removeAt(i); 5652 } 5653 } 5654 if (ba.size() == 0) { 5655 pmap.removeAt(ip); 5656 } 5657 } 5658 } 5659 5660 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5661 -100, callerWillRestart, true, doit, evenPersistent, 5662 name == null ? ("stop user " + userId) : ("stop " + name)); 5663 5664 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5665 if (!doit) { 5666 return true; 5667 } 5668 didSomething = true; 5669 } 5670 5671 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5672 if (!doit) { 5673 return true; 5674 } 5675 didSomething = true; 5676 } 5677 5678 if (name == null) { 5679 // Remove all sticky broadcasts from this user. 5680 mStickyBroadcasts.remove(userId); 5681 } 5682 5683 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5684 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5685 userId, providers)) { 5686 if (!doit) { 5687 return true; 5688 } 5689 didSomething = true; 5690 } 5691 N = providers.size(); 5692 for (i=0; i<N; i++) { 5693 removeDyingProviderLocked(null, providers.get(i), true); 5694 } 5695 5696 // Remove transient permissions granted from/to this package/user 5697 removeUriPermissionsForPackageLocked(name, userId, false); 5698 5699 if (name == null || uninstalling) { 5700 // Remove pending intents. For now we only do this when force 5701 // stopping users, because we have some problems when doing this 5702 // for packages -- app widgets are not currently cleaned up for 5703 // such packages, so they can be left with bad pending intents. 5704 if (mIntentSenderRecords.size() > 0) { 5705 Iterator<WeakReference<PendingIntentRecord>> it 5706 = mIntentSenderRecords.values().iterator(); 5707 while (it.hasNext()) { 5708 WeakReference<PendingIntentRecord> wpir = it.next(); 5709 if (wpir == null) { 5710 it.remove(); 5711 continue; 5712 } 5713 PendingIntentRecord pir = wpir.get(); 5714 if (pir == null) { 5715 it.remove(); 5716 continue; 5717 } 5718 if (name == null) { 5719 // Stopping user, remove all objects for the user. 5720 if (pir.key.userId != userId) { 5721 // Not the same user, skip it. 5722 continue; 5723 } 5724 } else { 5725 if (UserHandle.getAppId(pir.uid) != appId) { 5726 // Different app id, skip it. 5727 continue; 5728 } 5729 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5730 // Different user, skip it. 5731 continue; 5732 } 5733 if (!pir.key.packageName.equals(name)) { 5734 // Different package, skip it. 5735 continue; 5736 } 5737 } 5738 if (!doit) { 5739 return true; 5740 } 5741 didSomething = true; 5742 it.remove(); 5743 pir.canceled = true; 5744 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 5745 pir.key.activity.pendingResults.remove(pir.ref); 5746 } 5747 } 5748 } 5749 } 5750 5751 if (doit) { 5752 if (purgeCache && name != null) { 5753 AttributeCache ac = AttributeCache.instance(); 5754 if (ac != null) { 5755 ac.removePackage(name); 5756 } 5757 } 5758 if (mBooted) { 5759 mStackSupervisor.resumeTopActivitiesLocked(); 5760 mStackSupervisor.scheduleIdleLocked(); 5761 } 5762 } 5763 5764 return didSomething; 5765 } 5766 5767 private final boolean removeProcessLocked(ProcessRecord app, 5768 boolean callerWillRestart, boolean allowRestart, String reason) { 5769 final String name = app.processName; 5770 final int uid = app.uid; 5771 if (DEBUG_PROCESSES) Slog.d( 5772 TAG, "Force removing proc " + app.toShortString() + " (" + name 5773 + "/" + uid + ")"); 5774 5775 mProcessNames.remove(name, uid); 5776 mIsolatedProcesses.remove(app.uid); 5777 if (mHeavyWeightProcess == app) { 5778 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5779 mHeavyWeightProcess.userId, 0)); 5780 mHeavyWeightProcess = null; 5781 } 5782 boolean needRestart = false; 5783 if (app.pid > 0 && app.pid != MY_PID) { 5784 int pid = app.pid; 5785 synchronized (mPidsSelfLocked) { 5786 mPidsSelfLocked.remove(pid); 5787 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5788 } 5789 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5790 if (app.isolated) { 5791 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5792 } 5793 app.kill(reason, true); 5794 handleAppDiedLocked(app, true, allowRestart); 5795 removeLruProcessLocked(app); 5796 5797 if (app.persistent && !app.isolated) { 5798 if (!callerWillRestart) { 5799 addAppLocked(app.info, false, null /* ABI override */); 5800 } else { 5801 needRestart = true; 5802 } 5803 } 5804 } else { 5805 mRemovedProcesses.add(app); 5806 } 5807 5808 return needRestart; 5809 } 5810 5811 private final void processStartTimedOutLocked(ProcessRecord app) { 5812 final int pid = app.pid; 5813 boolean gone = false; 5814 synchronized (mPidsSelfLocked) { 5815 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5816 if (knownApp != null && knownApp.thread == null) { 5817 mPidsSelfLocked.remove(pid); 5818 gone = true; 5819 } 5820 } 5821 5822 if (gone) { 5823 Slog.w(TAG, "Process " + app + " failed to attach"); 5824 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5825 pid, app.uid, app.processName); 5826 mProcessNames.remove(app.processName, app.uid); 5827 mIsolatedProcesses.remove(app.uid); 5828 if (mHeavyWeightProcess == app) { 5829 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5830 mHeavyWeightProcess.userId, 0)); 5831 mHeavyWeightProcess = null; 5832 } 5833 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5834 if (app.isolated) { 5835 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5836 } 5837 // Take care of any launching providers waiting for this process. 5838 checkAppInLaunchingProvidersLocked(app, true); 5839 // Take care of any services that are waiting for the process. 5840 mServices.processStartTimedOutLocked(app); 5841 app.kill("start timeout", true); 5842 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5843 Slog.w(TAG, "Unattached app died before backup, skipping"); 5844 try { 5845 IBackupManager bm = IBackupManager.Stub.asInterface( 5846 ServiceManager.getService(Context.BACKUP_SERVICE)); 5847 bm.agentDisconnected(app.info.packageName); 5848 } catch (RemoteException e) { 5849 // Can't happen; the backup manager is local 5850 } 5851 } 5852 if (isPendingBroadcastProcessLocked(pid)) { 5853 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5854 skipPendingBroadcastLocked(pid); 5855 } 5856 } else { 5857 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5858 } 5859 } 5860 5861 private final boolean attachApplicationLocked(IApplicationThread thread, 5862 int pid) { 5863 5864 // Find the application record that is being attached... either via 5865 // the pid if we are running in multiple processes, or just pull the 5866 // next app record if we are emulating process with anonymous threads. 5867 ProcessRecord app; 5868 if (pid != MY_PID && pid >= 0) { 5869 synchronized (mPidsSelfLocked) { 5870 app = mPidsSelfLocked.get(pid); 5871 } 5872 } else { 5873 app = null; 5874 } 5875 5876 if (app == null) { 5877 Slog.w(TAG, "No pending application record for pid " + pid 5878 + " (IApplicationThread " + thread + "); dropping process"); 5879 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5880 if (pid > 0 && pid != MY_PID) { 5881 Process.killProcessQuiet(pid); 5882 //TODO: Process.killProcessGroup(app.info.uid, pid); 5883 } else { 5884 try { 5885 thread.scheduleExit(); 5886 } catch (Exception e) { 5887 // Ignore exceptions. 5888 } 5889 } 5890 return false; 5891 } 5892 5893 // If this application record is still attached to a previous 5894 // process, clean it up now. 5895 if (app.thread != null) { 5896 handleAppDiedLocked(app, true, true); 5897 } 5898 5899 // Tell the process all about itself. 5900 5901 if (localLOGV) Slog.v( 5902 TAG, "Binding process pid " + pid + " to record " + app); 5903 5904 final String processName = app.processName; 5905 try { 5906 AppDeathRecipient adr = new AppDeathRecipient( 5907 app, pid, thread); 5908 thread.asBinder().linkToDeath(adr, 0); 5909 app.deathRecipient = adr; 5910 } catch (RemoteException e) { 5911 app.resetPackageList(mProcessStats); 5912 startProcessLocked(app, "link fail", processName); 5913 return false; 5914 } 5915 5916 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5917 5918 app.makeActive(thread, mProcessStats); 5919 app.curAdj = app.setAdj = -100; 5920 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5921 app.forcingToForeground = null; 5922 updateProcessForegroundLocked(app, false, false); 5923 app.hasShownUi = false; 5924 app.debugging = false; 5925 app.cached = false; 5926 app.killedByAm = false; 5927 5928 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5929 5930 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5931 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5932 5933 if (!normalMode) { 5934 Slog.i(TAG, "Launching preboot mode app: " + app); 5935 } 5936 5937 if (localLOGV) Slog.v( 5938 TAG, "New app record " + app 5939 + " thread=" + thread.asBinder() + " pid=" + pid); 5940 try { 5941 int testMode = IApplicationThread.DEBUG_OFF; 5942 if (mDebugApp != null && mDebugApp.equals(processName)) { 5943 testMode = mWaitForDebugger 5944 ? IApplicationThread.DEBUG_WAIT 5945 : IApplicationThread.DEBUG_ON; 5946 app.debugging = true; 5947 if (mDebugTransient) { 5948 mDebugApp = mOrigDebugApp; 5949 mWaitForDebugger = mOrigWaitForDebugger; 5950 } 5951 } 5952 String profileFile = app.instrumentationProfileFile; 5953 ParcelFileDescriptor profileFd = null; 5954 int samplingInterval = 0; 5955 boolean profileAutoStop = false; 5956 if (mProfileApp != null && mProfileApp.equals(processName)) { 5957 mProfileProc = app; 5958 profileFile = mProfileFile; 5959 profileFd = mProfileFd; 5960 samplingInterval = mSamplingInterval; 5961 profileAutoStop = mAutoStopProfiler; 5962 } 5963 boolean enableOpenGlTrace = false; 5964 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5965 enableOpenGlTrace = true; 5966 mOpenGlTraceApp = null; 5967 } 5968 5969 // If the app is being launched for restore or full backup, set it up specially 5970 boolean isRestrictedBackupMode = false; 5971 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5972 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5973 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5974 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5975 } 5976 5977 ensurePackageDexOpt(app.instrumentationInfo != null 5978 ? app.instrumentationInfo.packageName 5979 : app.info.packageName); 5980 if (app.instrumentationClass != null) { 5981 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5982 } 5983 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5984 + processName + " with config " + mConfiguration); 5985 ApplicationInfo appInfo = app.instrumentationInfo != null 5986 ? app.instrumentationInfo : app.info; 5987 app.compat = compatibilityInfoForPackageLocked(appInfo); 5988 if (profileFd != null) { 5989 profileFd = profileFd.dup(); 5990 } 5991 ProfilerInfo profilerInfo = profileFile == null ? null 5992 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 5993 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 5994 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 5995 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5996 isRestrictedBackupMode || !normalMode, app.persistent, 5997 new Configuration(mConfiguration), app.compat, 5998 getCommonServicesLocked(app.isolated), 5999 mCoreSettingsObserver.getCoreSettingsLocked()); 6000 updateLruProcessLocked(app, false, null); 6001 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6002 } catch (Exception e) { 6003 // todo: Yikes! What should we do? For now we will try to 6004 // start another process, but that could easily get us in 6005 // an infinite loop of restarting processes... 6006 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6007 6008 app.resetPackageList(mProcessStats); 6009 app.unlinkDeathRecipient(); 6010 startProcessLocked(app, "bind fail", processName); 6011 return false; 6012 } 6013 6014 // Remove this record from the list of starting applications. 6015 mPersistentStartingProcesses.remove(app); 6016 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6017 "Attach application locked removing on hold: " + app); 6018 mProcessesOnHold.remove(app); 6019 6020 boolean badApp = false; 6021 boolean didSomething = false; 6022 6023 // See if the top visible activity is waiting to run in this process... 6024 if (normalMode) { 6025 try { 6026 if (mStackSupervisor.attachApplicationLocked(app)) { 6027 didSomething = true; 6028 } 6029 } catch (Exception e) { 6030 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6031 badApp = true; 6032 } 6033 } 6034 6035 // Find any services that should be running in this process... 6036 if (!badApp) { 6037 try { 6038 didSomething |= mServices.attachApplicationLocked(app, processName); 6039 } catch (Exception e) { 6040 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6041 badApp = true; 6042 } 6043 } 6044 6045 // Check if a next-broadcast receiver is in this process... 6046 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6047 try { 6048 didSomething |= sendPendingBroadcastsLocked(app); 6049 } catch (Exception e) { 6050 // If the app died trying to launch the receiver we declare it 'bad' 6051 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6052 badApp = true; 6053 } 6054 } 6055 6056 // Check whether the next backup agent is in this process... 6057 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6058 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6059 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6060 try { 6061 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6062 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6063 mBackupTarget.backupMode); 6064 } catch (Exception e) { 6065 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6066 badApp = true; 6067 } 6068 } 6069 6070 if (badApp) { 6071 app.kill("error during init", true); 6072 handleAppDiedLocked(app, false, true); 6073 return false; 6074 } 6075 6076 if (!didSomething) { 6077 updateOomAdjLocked(); 6078 } 6079 6080 return true; 6081 } 6082 6083 @Override 6084 public final void attachApplication(IApplicationThread thread) { 6085 synchronized (this) { 6086 int callingPid = Binder.getCallingPid(); 6087 final long origId = Binder.clearCallingIdentity(); 6088 attachApplicationLocked(thread, callingPid); 6089 Binder.restoreCallingIdentity(origId); 6090 } 6091 } 6092 6093 @Override 6094 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6095 final long origId = Binder.clearCallingIdentity(); 6096 synchronized (this) { 6097 ActivityStack stack = ActivityRecord.getStackLocked(token); 6098 if (stack != null) { 6099 ActivityRecord r = 6100 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6101 if (stopProfiling) { 6102 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6103 try { 6104 mProfileFd.close(); 6105 } catch (IOException e) { 6106 } 6107 clearProfilerLocked(); 6108 } 6109 } 6110 } 6111 } 6112 Binder.restoreCallingIdentity(origId); 6113 } 6114 6115 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6116 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6117 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6118 } 6119 6120 void enableScreenAfterBoot() { 6121 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6122 SystemClock.uptimeMillis()); 6123 mWindowManager.enableScreenAfterBoot(); 6124 6125 synchronized (this) { 6126 updateEventDispatchingLocked(); 6127 } 6128 } 6129 6130 @Override 6131 public void showBootMessage(final CharSequence msg, final boolean always) { 6132 enforceNotIsolatedCaller("showBootMessage"); 6133 mWindowManager.showBootMessage(msg, always); 6134 } 6135 6136 @Override 6137 public void keyguardWaitingForActivityDrawn() { 6138 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6139 final long token = Binder.clearCallingIdentity(); 6140 try { 6141 synchronized (this) { 6142 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6143 mWindowManager.keyguardWaitingForActivityDrawn(); 6144 if (mLockScreenShown == LOCK_SCREEN_SHOWN) { 6145 mLockScreenShown = LOCK_SCREEN_LEAVING; 6146 updateSleepIfNeededLocked(); 6147 } 6148 } 6149 } finally { 6150 Binder.restoreCallingIdentity(token); 6151 } 6152 } 6153 6154 final void finishBooting() { 6155 synchronized (this) { 6156 if (!mBootAnimationComplete) { 6157 mCallFinishBooting = true; 6158 return; 6159 } 6160 mCallFinishBooting = false; 6161 } 6162 6163 ArraySet<String> completedIsas = new ArraySet<String>(); 6164 for (String abi : Build.SUPPORTED_ABIS) { 6165 Process.establishZygoteConnectionForAbi(abi); 6166 final String instructionSet = VMRuntime.getInstructionSet(abi); 6167 if (!completedIsas.contains(instructionSet)) { 6168 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) { 6169 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi); 6170 } 6171 completedIsas.add(instructionSet); 6172 } 6173 } 6174 6175 IntentFilter pkgFilter = new IntentFilter(); 6176 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6177 pkgFilter.addDataScheme("package"); 6178 mContext.registerReceiver(new BroadcastReceiver() { 6179 @Override 6180 public void onReceive(Context context, Intent intent) { 6181 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6182 if (pkgs != null) { 6183 for (String pkg : pkgs) { 6184 synchronized (ActivityManagerService.this) { 6185 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6186 0, "finished booting")) { 6187 setResultCode(Activity.RESULT_OK); 6188 return; 6189 } 6190 } 6191 } 6192 } 6193 } 6194 }, pkgFilter); 6195 6196 // Let system services know. 6197 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6198 6199 synchronized (this) { 6200 // Ensure that any processes we had put on hold are now started 6201 // up. 6202 final int NP = mProcessesOnHold.size(); 6203 if (NP > 0) { 6204 ArrayList<ProcessRecord> procs = 6205 new ArrayList<ProcessRecord>(mProcessesOnHold); 6206 for (int ip=0; ip<NP; ip++) { 6207 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6208 + procs.get(ip)); 6209 startProcessLocked(procs.get(ip), "on-hold", null); 6210 } 6211 } 6212 6213 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6214 // Start looking for apps that are abusing wake locks. 6215 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6216 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6217 // Tell anyone interested that we are done booting! 6218 SystemProperties.set("sys.boot_completed", "1"); 6219 6220 // And trigger dev.bootcomplete if we are not showing encryption progress 6221 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6222 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6223 SystemProperties.set("dev.bootcomplete", "1"); 6224 } 6225 for (int i=0; i<mStartedUsers.size(); i++) { 6226 UserStartedState uss = mStartedUsers.valueAt(i); 6227 if (uss.mState == UserStartedState.STATE_BOOTING) { 6228 uss.mState = UserStartedState.STATE_RUNNING; 6229 final int userId = mStartedUsers.keyAt(i); 6230 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6231 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6232 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6233 broadcastIntentLocked(null, null, intent, null, 6234 new IIntentReceiver.Stub() { 6235 @Override 6236 public void performReceive(Intent intent, int resultCode, 6237 String data, Bundle extras, boolean ordered, 6238 boolean sticky, int sendingUser) { 6239 synchronized (ActivityManagerService.this) { 6240 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6241 true, false); 6242 } 6243 } 6244 }, 6245 0, null, null, 6246 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6247 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6248 userId); 6249 } 6250 } 6251 scheduleStartProfilesLocked(); 6252 } 6253 } 6254 } 6255 6256 @Override 6257 public void bootAnimationComplete() { 6258 final boolean callFinishBooting; 6259 synchronized (this) { 6260 callFinishBooting = mCallFinishBooting; 6261 mBootAnimationComplete = true; 6262 } 6263 if (callFinishBooting) { 6264 finishBooting(); 6265 } 6266 } 6267 6268 @Override 6269 public void systemBackupRestored() { 6270 synchronized (this) { 6271 if (mSystemReady) { 6272 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 6273 } else { 6274 Slog.w(TAG, "System backup restored before system is ready"); 6275 } 6276 } 6277 } 6278 6279 final void ensureBootCompleted() { 6280 boolean booting; 6281 boolean enableScreen; 6282 synchronized (this) { 6283 booting = mBooting; 6284 mBooting = false; 6285 enableScreen = !mBooted; 6286 mBooted = true; 6287 } 6288 6289 if (booting) { 6290 finishBooting(); 6291 } 6292 6293 if (enableScreen) { 6294 enableScreenAfterBoot(); 6295 } 6296 } 6297 6298 @Override 6299 public final void activityResumed(IBinder token) { 6300 final long origId = Binder.clearCallingIdentity(); 6301 synchronized(this) { 6302 ActivityStack stack = ActivityRecord.getStackLocked(token); 6303 if (stack != null) { 6304 ActivityRecord.activityResumedLocked(token); 6305 } 6306 } 6307 Binder.restoreCallingIdentity(origId); 6308 } 6309 6310 @Override 6311 public final void activityPaused(IBinder token) { 6312 final long origId = Binder.clearCallingIdentity(); 6313 synchronized(this) { 6314 ActivityStack stack = ActivityRecord.getStackLocked(token); 6315 if (stack != null) { 6316 stack.activityPausedLocked(token, false); 6317 } 6318 } 6319 Binder.restoreCallingIdentity(origId); 6320 } 6321 6322 @Override 6323 public final void activityStopped(IBinder token, Bundle icicle, 6324 PersistableBundle persistentState, CharSequence description) { 6325 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6326 6327 // Refuse possible leaked file descriptors 6328 if (icicle != null && icicle.hasFileDescriptors()) { 6329 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6330 } 6331 6332 final long origId = Binder.clearCallingIdentity(); 6333 6334 synchronized (this) { 6335 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6336 if (r != null) { 6337 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6338 } 6339 } 6340 6341 trimApplications(); 6342 6343 Binder.restoreCallingIdentity(origId); 6344 } 6345 6346 @Override 6347 public final void activityDestroyed(IBinder token) { 6348 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6349 synchronized (this) { 6350 ActivityStack stack = ActivityRecord.getStackLocked(token); 6351 if (stack != null) { 6352 stack.activityDestroyedLocked(token, "activityDestroyed"); 6353 } 6354 } 6355 } 6356 6357 @Override 6358 public final void backgroundResourcesReleased(IBinder token) { 6359 final long origId = Binder.clearCallingIdentity(); 6360 try { 6361 synchronized (this) { 6362 ActivityStack stack = ActivityRecord.getStackLocked(token); 6363 if (stack != null) { 6364 stack.backgroundResourcesReleased(); 6365 } 6366 } 6367 } finally { 6368 Binder.restoreCallingIdentity(origId); 6369 } 6370 } 6371 6372 @Override 6373 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6374 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6375 } 6376 6377 @Override 6378 public final void notifyEnterAnimationComplete(IBinder token) { 6379 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6380 } 6381 6382 @Override 6383 public String getCallingPackage(IBinder token) { 6384 synchronized (this) { 6385 ActivityRecord r = getCallingRecordLocked(token); 6386 return r != null ? r.info.packageName : null; 6387 } 6388 } 6389 6390 @Override 6391 public ComponentName getCallingActivity(IBinder token) { 6392 synchronized (this) { 6393 ActivityRecord r = getCallingRecordLocked(token); 6394 return r != null ? r.intent.getComponent() : null; 6395 } 6396 } 6397 6398 private ActivityRecord getCallingRecordLocked(IBinder token) { 6399 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6400 if (r == null) { 6401 return null; 6402 } 6403 return r.resultTo; 6404 } 6405 6406 @Override 6407 public ComponentName getActivityClassForToken(IBinder token) { 6408 synchronized(this) { 6409 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6410 if (r == null) { 6411 return null; 6412 } 6413 return r.intent.getComponent(); 6414 } 6415 } 6416 6417 @Override 6418 public String getPackageForToken(IBinder token) { 6419 synchronized(this) { 6420 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6421 if (r == null) { 6422 return null; 6423 } 6424 return r.packageName; 6425 } 6426 } 6427 6428 @Override 6429 public IIntentSender getIntentSender(int type, 6430 String packageName, IBinder token, String resultWho, 6431 int requestCode, Intent[] intents, String[] resolvedTypes, 6432 int flags, Bundle options, int userId) { 6433 enforceNotIsolatedCaller("getIntentSender"); 6434 // Refuse possible leaked file descriptors 6435 if (intents != null) { 6436 if (intents.length < 1) { 6437 throw new IllegalArgumentException("Intents array length must be >= 1"); 6438 } 6439 for (int i=0; i<intents.length; i++) { 6440 Intent intent = intents[i]; 6441 if (intent != null) { 6442 if (intent.hasFileDescriptors()) { 6443 throw new IllegalArgumentException("File descriptors passed in Intent"); 6444 } 6445 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6446 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6447 throw new IllegalArgumentException( 6448 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6449 } 6450 intents[i] = new Intent(intent); 6451 } 6452 } 6453 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6454 throw new IllegalArgumentException( 6455 "Intent array length does not match resolvedTypes length"); 6456 } 6457 } 6458 if (options != null) { 6459 if (options.hasFileDescriptors()) { 6460 throw new IllegalArgumentException("File descriptors passed in options"); 6461 } 6462 } 6463 6464 synchronized(this) { 6465 int callingUid = Binder.getCallingUid(); 6466 int origUserId = userId; 6467 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6468 type == ActivityManager.INTENT_SENDER_BROADCAST, 6469 ALLOW_NON_FULL, "getIntentSender", null); 6470 if (origUserId == UserHandle.USER_CURRENT) { 6471 // We don't want to evaluate this until the pending intent is 6472 // actually executed. However, we do want to always do the 6473 // security checking for it above. 6474 userId = UserHandle.USER_CURRENT; 6475 } 6476 try { 6477 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6478 int uid = AppGlobals.getPackageManager() 6479 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6480 if (!UserHandle.isSameApp(callingUid, uid)) { 6481 String msg = "Permission Denial: getIntentSender() from pid=" 6482 + Binder.getCallingPid() 6483 + ", uid=" + Binder.getCallingUid() 6484 + ", (need uid=" + uid + ")" 6485 + " is not allowed to send as package " + packageName; 6486 Slog.w(TAG, msg); 6487 throw new SecurityException(msg); 6488 } 6489 } 6490 6491 return getIntentSenderLocked(type, packageName, callingUid, userId, 6492 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6493 6494 } catch (RemoteException e) { 6495 throw new SecurityException(e); 6496 } 6497 } 6498 } 6499 6500 IIntentSender getIntentSenderLocked(int type, String packageName, 6501 int callingUid, int userId, IBinder token, String resultWho, 6502 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6503 Bundle options) { 6504 if (DEBUG_MU) 6505 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6506 ActivityRecord activity = null; 6507 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6508 activity = ActivityRecord.isInStackLocked(token); 6509 if (activity == null) { 6510 return null; 6511 } 6512 if (activity.finishing) { 6513 return null; 6514 } 6515 } 6516 6517 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6518 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6519 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6520 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6521 |PendingIntent.FLAG_UPDATE_CURRENT); 6522 6523 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6524 type, packageName, activity, resultWho, 6525 requestCode, intents, resolvedTypes, flags, options, userId); 6526 WeakReference<PendingIntentRecord> ref; 6527 ref = mIntentSenderRecords.get(key); 6528 PendingIntentRecord rec = ref != null ? ref.get() : null; 6529 if (rec != null) { 6530 if (!cancelCurrent) { 6531 if (updateCurrent) { 6532 if (rec.key.requestIntent != null) { 6533 rec.key.requestIntent.replaceExtras(intents != null ? 6534 intents[intents.length - 1] : null); 6535 } 6536 if (intents != null) { 6537 intents[intents.length-1] = rec.key.requestIntent; 6538 rec.key.allIntents = intents; 6539 rec.key.allResolvedTypes = resolvedTypes; 6540 } else { 6541 rec.key.allIntents = null; 6542 rec.key.allResolvedTypes = null; 6543 } 6544 } 6545 return rec; 6546 } 6547 rec.canceled = true; 6548 mIntentSenderRecords.remove(key); 6549 } 6550 if (noCreate) { 6551 return rec; 6552 } 6553 rec = new PendingIntentRecord(this, key, callingUid); 6554 mIntentSenderRecords.put(key, rec.ref); 6555 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6556 if (activity.pendingResults == null) { 6557 activity.pendingResults 6558 = new HashSet<WeakReference<PendingIntentRecord>>(); 6559 } 6560 activity.pendingResults.add(rec.ref); 6561 } 6562 return rec; 6563 } 6564 6565 @Override 6566 public void cancelIntentSender(IIntentSender sender) { 6567 if (!(sender instanceof PendingIntentRecord)) { 6568 return; 6569 } 6570 synchronized(this) { 6571 PendingIntentRecord rec = (PendingIntentRecord)sender; 6572 try { 6573 int uid = AppGlobals.getPackageManager() 6574 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6575 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6576 String msg = "Permission Denial: cancelIntentSender() from pid=" 6577 + Binder.getCallingPid() 6578 + ", uid=" + Binder.getCallingUid() 6579 + " is not allowed to cancel packges " 6580 + rec.key.packageName; 6581 Slog.w(TAG, msg); 6582 throw new SecurityException(msg); 6583 } 6584 } catch (RemoteException e) { 6585 throw new SecurityException(e); 6586 } 6587 cancelIntentSenderLocked(rec, true); 6588 } 6589 } 6590 6591 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6592 rec.canceled = true; 6593 mIntentSenderRecords.remove(rec.key); 6594 if (cleanActivity && rec.key.activity != null) { 6595 rec.key.activity.pendingResults.remove(rec.ref); 6596 } 6597 } 6598 6599 @Override 6600 public String getPackageForIntentSender(IIntentSender pendingResult) { 6601 if (!(pendingResult instanceof PendingIntentRecord)) { 6602 return null; 6603 } 6604 try { 6605 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6606 return res.key.packageName; 6607 } catch (ClassCastException e) { 6608 } 6609 return null; 6610 } 6611 6612 @Override 6613 public int getUidForIntentSender(IIntentSender sender) { 6614 if (sender instanceof PendingIntentRecord) { 6615 try { 6616 PendingIntentRecord res = (PendingIntentRecord)sender; 6617 return res.uid; 6618 } catch (ClassCastException e) { 6619 } 6620 } 6621 return -1; 6622 } 6623 6624 @Override 6625 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6626 if (!(pendingResult instanceof PendingIntentRecord)) { 6627 return false; 6628 } 6629 try { 6630 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6631 if (res.key.allIntents == null) { 6632 return false; 6633 } 6634 for (int i=0; i<res.key.allIntents.length; i++) { 6635 Intent intent = res.key.allIntents[i]; 6636 if (intent.getPackage() != null && intent.getComponent() != null) { 6637 return false; 6638 } 6639 } 6640 return true; 6641 } catch (ClassCastException e) { 6642 } 6643 return false; 6644 } 6645 6646 @Override 6647 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6648 if (!(pendingResult instanceof PendingIntentRecord)) { 6649 return false; 6650 } 6651 try { 6652 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6653 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6654 return true; 6655 } 6656 return false; 6657 } catch (ClassCastException e) { 6658 } 6659 return false; 6660 } 6661 6662 @Override 6663 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6664 if (!(pendingResult instanceof PendingIntentRecord)) { 6665 return null; 6666 } 6667 try { 6668 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6669 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6670 } catch (ClassCastException e) { 6671 } 6672 return null; 6673 } 6674 6675 @Override 6676 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6677 if (!(pendingResult instanceof PendingIntentRecord)) { 6678 return null; 6679 } 6680 try { 6681 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6682 Intent intent = res.key.requestIntent; 6683 if (intent != null) { 6684 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6685 || res.lastTagPrefix.equals(prefix))) { 6686 return res.lastTag; 6687 } 6688 res.lastTagPrefix = prefix; 6689 StringBuilder sb = new StringBuilder(128); 6690 if (prefix != null) { 6691 sb.append(prefix); 6692 } 6693 if (intent.getAction() != null) { 6694 sb.append(intent.getAction()); 6695 } else if (intent.getComponent() != null) { 6696 intent.getComponent().appendShortString(sb); 6697 } else { 6698 sb.append("?"); 6699 } 6700 return res.lastTag = sb.toString(); 6701 } 6702 } catch (ClassCastException e) { 6703 } 6704 return null; 6705 } 6706 6707 @Override 6708 public void setProcessLimit(int max) { 6709 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6710 "setProcessLimit()"); 6711 synchronized (this) { 6712 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6713 mProcessLimitOverride = max; 6714 } 6715 trimApplications(); 6716 } 6717 6718 @Override 6719 public int getProcessLimit() { 6720 synchronized (this) { 6721 return mProcessLimitOverride; 6722 } 6723 } 6724 6725 void foregroundTokenDied(ForegroundToken token) { 6726 synchronized (ActivityManagerService.this) { 6727 synchronized (mPidsSelfLocked) { 6728 ForegroundToken cur 6729 = mForegroundProcesses.get(token.pid); 6730 if (cur != token) { 6731 return; 6732 } 6733 mForegroundProcesses.remove(token.pid); 6734 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6735 if (pr == null) { 6736 return; 6737 } 6738 pr.forcingToForeground = null; 6739 updateProcessForegroundLocked(pr, false, false); 6740 } 6741 updateOomAdjLocked(); 6742 } 6743 } 6744 6745 @Override 6746 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6747 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6748 "setProcessForeground()"); 6749 synchronized(this) { 6750 boolean changed = false; 6751 6752 synchronized (mPidsSelfLocked) { 6753 ProcessRecord pr = mPidsSelfLocked.get(pid); 6754 if (pr == null && isForeground) { 6755 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6756 return; 6757 } 6758 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6759 if (oldToken != null) { 6760 oldToken.token.unlinkToDeath(oldToken, 0); 6761 mForegroundProcesses.remove(pid); 6762 if (pr != null) { 6763 pr.forcingToForeground = null; 6764 } 6765 changed = true; 6766 } 6767 if (isForeground && token != null) { 6768 ForegroundToken newToken = new ForegroundToken() { 6769 @Override 6770 public void binderDied() { 6771 foregroundTokenDied(this); 6772 } 6773 }; 6774 newToken.pid = pid; 6775 newToken.token = token; 6776 try { 6777 token.linkToDeath(newToken, 0); 6778 mForegroundProcesses.put(pid, newToken); 6779 pr.forcingToForeground = token; 6780 changed = true; 6781 } catch (RemoteException e) { 6782 // If the process died while doing this, we will later 6783 // do the cleanup with the process death link. 6784 } 6785 } 6786 } 6787 6788 if (changed) { 6789 updateOomAdjLocked(); 6790 } 6791 } 6792 } 6793 6794 // ========================================================= 6795 // PERMISSIONS 6796 // ========================================================= 6797 6798 static class PermissionController extends IPermissionController.Stub { 6799 ActivityManagerService mActivityManagerService; 6800 PermissionController(ActivityManagerService activityManagerService) { 6801 mActivityManagerService = activityManagerService; 6802 } 6803 6804 @Override 6805 public boolean checkPermission(String permission, int pid, int uid) { 6806 return mActivityManagerService.checkPermission(permission, pid, 6807 uid) == PackageManager.PERMISSION_GRANTED; 6808 } 6809 } 6810 6811 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6812 @Override 6813 public int checkComponentPermission(String permission, int pid, int uid, 6814 int owningUid, boolean exported) { 6815 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6816 owningUid, exported); 6817 } 6818 6819 @Override 6820 public Object getAMSLock() { 6821 return ActivityManagerService.this; 6822 } 6823 } 6824 6825 /** 6826 * This can be called with or without the global lock held. 6827 */ 6828 int checkComponentPermission(String permission, int pid, int uid, 6829 int owningUid, boolean exported) { 6830 if (pid == MY_PID) { 6831 return PackageManager.PERMISSION_GRANTED; 6832 } 6833 return ActivityManager.checkComponentPermission(permission, uid, 6834 owningUid, exported); 6835 } 6836 6837 /** 6838 * As the only public entry point for permissions checking, this method 6839 * can enforce the semantic that requesting a check on a null global 6840 * permission is automatically denied. (Internally a null permission 6841 * string is used when calling {@link #checkComponentPermission} in cases 6842 * when only uid-based security is needed.) 6843 * 6844 * This can be called with or without the global lock held. 6845 */ 6846 @Override 6847 public int checkPermission(String permission, int pid, int uid) { 6848 if (permission == null) { 6849 return PackageManager.PERMISSION_DENIED; 6850 } 6851 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6852 } 6853 6854 @Override 6855 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 6856 if (permission == null) { 6857 return PackageManager.PERMISSION_DENIED; 6858 } 6859 6860 // We might be performing an operation on behalf of an indirect binder 6861 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6862 // client identity accordingly before proceeding. 6863 Identity tlsIdentity = sCallerIdentity.get(); 6864 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 6865 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6866 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6867 uid = tlsIdentity.uid; 6868 pid = tlsIdentity.pid; 6869 } 6870 6871 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6872 } 6873 6874 /** 6875 * Binder IPC calls go through the public entry point. 6876 * This can be called with or without the global lock held. 6877 */ 6878 int checkCallingPermission(String permission) { 6879 return checkPermission(permission, 6880 Binder.getCallingPid(), 6881 UserHandle.getAppId(Binder.getCallingUid())); 6882 } 6883 6884 /** 6885 * This can be called with or without the global lock held. 6886 */ 6887 void enforceCallingPermission(String permission, String func) { 6888 if (checkCallingPermission(permission) 6889 == PackageManager.PERMISSION_GRANTED) { 6890 return; 6891 } 6892 6893 String msg = "Permission Denial: " + func + " from pid=" 6894 + Binder.getCallingPid() 6895 + ", uid=" + Binder.getCallingUid() 6896 + " requires " + permission; 6897 Slog.w(TAG, msg); 6898 throw new SecurityException(msg); 6899 } 6900 6901 /** 6902 * Determine if UID is holding permissions required to access {@link Uri} in 6903 * the given {@link ProviderInfo}. Final permission checking is always done 6904 * in {@link ContentProvider}. 6905 */ 6906 private final boolean checkHoldingPermissionsLocked( 6907 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6908 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6909 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6910 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6911 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6912 != PERMISSION_GRANTED) { 6913 return false; 6914 } 6915 } 6916 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6917 } 6918 6919 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6920 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6921 if (pi.applicationInfo.uid == uid) { 6922 return true; 6923 } else if (!pi.exported) { 6924 return false; 6925 } 6926 6927 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6928 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6929 try { 6930 // check if target holds top-level <provider> permissions 6931 if (!readMet && pi.readPermission != null && considerUidPermissions 6932 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6933 readMet = true; 6934 } 6935 if (!writeMet && pi.writePermission != null && considerUidPermissions 6936 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6937 writeMet = true; 6938 } 6939 6940 // track if unprotected read/write is allowed; any denied 6941 // <path-permission> below removes this ability 6942 boolean allowDefaultRead = pi.readPermission == null; 6943 boolean allowDefaultWrite = pi.writePermission == null; 6944 6945 // check if target holds any <path-permission> that match uri 6946 final PathPermission[] pps = pi.pathPermissions; 6947 if (pps != null) { 6948 final String path = grantUri.uri.getPath(); 6949 int i = pps.length; 6950 while (i > 0 && (!readMet || !writeMet)) { 6951 i--; 6952 PathPermission pp = pps[i]; 6953 if (pp.match(path)) { 6954 if (!readMet) { 6955 final String pprperm = pp.getReadPermission(); 6956 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6957 + pprperm + " for " + pp.getPath() 6958 + ": match=" + pp.match(path) 6959 + " check=" + pm.checkUidPermission(pprperm, uid)); 6960 if (pprperm != null) { 6961 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6962 == PERMISSION_GRANTED) { 6963 readMet = true; 6964 } else { 6965 allowDefaultRead = false; 6966 } 6967 } 6968 } 6969 if (!writeMet) { 6970 final String ppwperm = pp.getWritePermission(); 6971 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6972 + ppwperm + " for " + pp.getPath() 6973 + ": match=" + pp.match(path) 6974 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6975 if (ppwperm != null) { 6976 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6977 == PERMISSION_GRANTED) { 6978 writeMet = true; 6979 } else { 6980 allowDefaultWrite = false; 6981 } 6982 } 6983 } 6984 } 6985 } 6986 } 6987 6988 // grant unprotected <provider> read/write, if not blocked by 6989 // <path-permission> above 6990 if (allowDefaultRead) readMet = true; 6991 if (allowDefaultWrite) writeMet = true; 6992 6993 } catch (RemoteException e) { 6994 return false; 6995 } 6996 6997 return readMet && writeMet; 6998 } 6999 7000 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7001 ProviderInfo pi = null; 7002 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7003 if (cpr != null) { 7004 pi = cpr.info; 7005 } else { 7006 try { 7007 pi = AppGlobals.getPackageManager().resolveContentProvider( 7008 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7009 } catch (RemoteException ex) { 7010 } 7011 } 7012 return pi; 7013 } 7014 7015 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7016 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7017 if (targetUris != null) { 7018 return targetUris.get(grantUri); 7019 } 7020 return null; 7021 } 7022 7023 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7024 String targetPkg, int targetUid, GrantUri grantUri) { 7025 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7026 if (targetUris == null) { 7027 targetUris = Maps.newArrayMap(); 7028 mGrantedUriPermissions.put(targetUid, targetUris); 7029 } 7030 7031 UriPermission perm = targetUris.get(grantUri); 7032 if (perm == null) { 7033 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7034 targetUris.put(grantUri, perm); 7035 } 7036 7037 return perm; 7038 } 7039 7040 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7041 final int modeFlags) { 7042 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7043 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7044 : UriPermission.STRENGTH_OWNED; 7045 7046 // Root gets to do everything. 7047 if (uid == 0) { 7048 return true; 7049 } 7050 7051 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7052 if (perms == null) return false; 7053 7054 // First look for exact match 7055 final UriPermission exactPerm = perms.get(grantUri); 7056 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7057 return true; 7058 } 7059 7060 // No exact match, look for prefixes 7061 final int N = perms.size(); 7062 for (int i = 0; i < N; i++) { 7063 final UriPermission perm = perms.valueAt(i); 7064 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7065 && perm.getStrength(modeFlags) >= minStrength) { 7066 return true; 7067 } 7068 } 7069 7070 return false; 7071 } 7072 7073 /** 7074 * @param uri This uri must NOT contain an embedded userId. 7075 * @param userId The userId in which the uri is to be resolved. 7076 */ 7077 @Override 7078 public int checkUriPermission(Uri uri, int pid, int uid, 7079 final int modeFlags, int userId, IBinder callerToken) { 7080 enforceNotIsolatedCaller("checkUriPermission"); 7081 7082 // Another redirected-binder-call permissions check as in 7083 // {@link checkPermissionWithToken}. 7084 Identity tlsIdentity = sCallerIdentity.get(); 7085 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 7086 uid = tlsIdentity.uid; 7087 pid = tlsIdentity.pid; 7088 } 7089 7090 // Our own process gets to do everything. 7091 if (pid == MY_PID) { 7092 return PackageManager.PERMISSION_GRANTED; 7093 } 7094 synchronized (this) { 7095 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7096 ? PackageManager.PERMISSION_GRANTED 7097 : PackageManager.PERMISSION_DENIED; 7098 } 7099 } 7100 7101 /** 7102 * Check if the targetPkg can be granted permission to access uri by 7103 * the callingUid using the given modeFlags. Throws a security exception 7104 * if callingUid is not allowed to do this. Returns the uid of the target 7105 * if the URI permission grant should be performed; returns -1 if it is not 7106 * needed (for example targetPkg already has permission to access the URI). 7107 * If you already know the uid of the target, you can supply it in 7108 * lastTargetUid else set that to -1. 7109 */ 7110 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7111 final int modeFlags, int lastTargetUid) { 7112 if (!Intent.isAccessUriMode(modeFlags)) { 7113 return -1; 7114 } 7115 7116 if (targetPkg != null) { 7117 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7118 "Checking grant " + targetPkg + " permission to " + grantUri); 7119 } 7120 7121 final IPackageManager pm = AppGlobals.getPackageManager(); 7122 7123 // If this is not a content: uri, we can't do anything with it. 7124 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7125 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7126 "Can't grant URI permission for non-content URI: " + grantUri); 7127 return -1; 7128 } 7129 7130 final String authority = grantUri.uri.getAuthority(); 7131 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7132 if (pi == null) { 7133 Slog.w(TAG, "No content provider found for permission check: " + 7134 grantUri.uri.toSafeString()); 7135 return -1; 7136 } 7137 7138 int targetUid = lastTargetUid; 7139 if (targetUid < 0 && targetPkg != null) { 7140 try { 7141 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7142 if (targetUid < 0) { 7143 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7144 "Can't grant URI permission no uid for: " + targetPkg); 7145 return -1; 7146 } 7147 } catch (RemoteException ex) { 7148 return -1; 7149 } 7150 } 7151 7152 if (targetUid >= 0) { 7153 // First... does the target actually need this permission? 7154 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7155 // No need to grant the target this permission. 7156 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7157 "Target " + targetPkg + " already has full permission to " + grantUri); 7158 return -1; 7159 } 7160 } else { 7161 // First... there is no target package, so can anyone access it? 7162 boolean allowed = pi.exported; 7163 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7164 if (pi.readPermission != null) { 7165 allowed = false; 7166 } 7167 } 7168 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7169 if (pi.writePermission != null) { 7170 allowed = false; 7171 } 7172 } 7173 if (allowed) { 7174 return -1; 7175 } 7176 } 7177 7178 /* There is a special cross user grant if: 7179 * - The target is on another user. 7180 * - Apps on the current user can access the uri without any uid permissions. 7181 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7182 * grant uri permissions. 7183 */ 7184 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7185 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7186 modeFlags, false /*without considering the uid permissions*/); 7187 7188 // Second... is the provider allowing granting of URI permissions? 7189 if (!specialCrossUserGrant) { 7190 if (!pi.grantUriPermissions) { 7191 throw new SecurityException("Provider " + pi.packageName 7192 + "/" + pi.name 7193 + " does not allow granting of Uri permissions (uri " 7194 + grantUri + ")"); 7195 } 7196 if (pi.uriPermissionPatterns != null) { 7197 final int N = pi.uriPermissionPatterns.length; 7198 boolean allowed = false; 7199 for (int i=0; i<N; i++) { 7200 if (pi.uriPermissionPatterns[i] != null 7201 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7202 allowed = true; 7203 break; 7204 } 7205 } 7206 if (!allowed) { 7207 throw new SecurityException("Provider " + pi.packageName 7208 + "/" + pi.name 7209 + " does not allow granting of permission to path of Uri " 7210 + grantUri); 7211 } 7212 } 7213 } 7214 7215 // Third... does the caller itself have permission to access 7216 // this uri? 7217 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7218 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7219 // Require they hold a strong enough Uri permission 7220 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7221 throw new SecurityException("Uid " + callingUid 7222 + " does not have permission to uri " + grantUri); 7223 } 7224 } 7225 } 7226 return targetUid; 7227 } 7228 7229 /** 7230 * @param uri This uri must NOT contain an embedded userId. 7231 * @param userId The userId in which the uri is to be resolved. 7232 */ 7233 @Override 7234 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7235 final int modeFlags, int userId) { 7236 enforceNotIsolatedCaller("checkGrantUriPermission"); 7237 synchronized(this) { 7238 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7239 new GrantUri(userId, uri, false), modeFlags, -1); 7240 } 7241 } 7242 7243 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7244 final int modeFlags, UriPermissionOwner owner) { 7245 if (!Intent.isAccessUriMode(modeFlags)) { 7246 return; 7247 } 7248 7249 // So here we are: the caller has the assumed permission 7250 // to the uri, and the target doesn't. Let's now give this to 7251 // the target. 7252 7253 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7254 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7255 7256 final String authority = grantUri.uri.getAuthority(); 7257 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7258 if (pi == null) { 7259 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7260 return; 7261 } 7262 7263 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7264 grantUri.prefix = true; 7265 } 7266 final UriPermission perm = findOrCreateUriPermissionLocked( 7267 pi.packageName, targetPkg, targetUid, grantUri); 7268 perm.grantModes(modeFlags, owner); 7269 } 7270 7271 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7272 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7273 if (targetPkg == null) { 7274 throw new NullPointerException("targetPkg"); 7275 } 7276 int targetUid; 7277 final IPackageManager pm = AppGlobals.getPackageManager(); 7278 try { 7279 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7280 } catch (RemoteException ex) { 7281 return; 7282 } 7283 7284 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7285 targetUid); 7286 if (targetUid < 0) { 7287 return; 7288 } 7289 7290 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7291 owner); 7292 } 7293 7294 static class NeededUriGrants extends ArrayList<GrantUri> { 7295 final String targetPkg; 7296 final int targetUid; 7297 final int flags; 7298 7299 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7300 this.targetPkg = targetPkg; 7301 this.targetUid = targetUid; 7302 this.flags = flags; 7303 } 7304 } 7305 7306 /** 7307 * Like checkGrantUriPermissionLocked, but takes an Intent. 7308 */ 7309 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7310 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7311 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7312 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7313 + " clip=" + (intent != null ? intent.getClipData() : null) 7314 + " from " + intent + "; flags=0x" 7315 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7316 7317 if (targetPkg == null) { 7318 throw new NullPointerException("targetPkg"); 7319 } 7320 7321 if (intent == null) { 7322 return null; 7323 } 7324 Uri data = intent.getData(); 7325 ClipData clip = intent.getClipData(); 7326 if (data == null && clip == null) { 7327 return null; 7328 } 7329 // Default userId for uris in the intent (if they don't specify it themselves) 7330 int contentUserHint = intent.getContentUserHint(); 7331 if (contentUserHint == UserHandle.USER_CURRENT) { 7332 contentUserHint = UserHandle.getUserId(callingUid); 7333 } 7334 final IPackageManager pm = AppGlobals.getPackageManager(); 7335 int targetUid; 7336 if (needed != null) { 7337 targetUid = needed.targetUid; 7338 } else { 7339 try { 7340 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7341 } catch (RemoteException ex) { 7342 return null; 7343 } 7344 if (targetUid < 0) { 7345 if (DEBUG_URI_PERMISSION) { 7346 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7347 + " on user " + targetUserId); 7348 } 7349 return null; 7350 } 7351 } 7352 if (data != null) { 7353 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7354 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7355 targetUid); 7356 if (targetUid > 0) { 7357 if (needed == null) { 7358 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7359 } 7360 needed.add(grantUri); 7361 } 7362 } 7363 if (clip != null) { 7364 for (int i=0; i<clip.getItemCount(); i++) { 7365 Uri uri = clip.getItemAt(i).getUri(); 7366 if (uri != null) { 7367 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7368 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7369 targetUid); 7370 if (targetUid > 0) { 7371 if (needed == null) { 7372 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7373 } 7374 needed.add(grantUri); 7375 } 7376 } else { 7377 Intent clipIntent = clip.getItemAt(i).getIntent(); 7378 if (clipIntent != null) { 7379 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7380 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7381 if (newNeeded != null) { 7382 needed = newNeeded; 7383 } 7384 } 7385 } 7386 } 7387 } 7388 7389 return needed; 7390 } 7391 7392 /** 7393 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7394 */ 7395 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7396 UriPermissionOwner owner) { 7397 if (needed != null) { 7398 for (int i=0; i<needed.size(); i++) { 7399 GrantUri grantUri = needed.get(i); 7400 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7401 grantUri, needed.flags, owner); 7402 } 7403 } 7404 } 7405 7406 void grantUriPermissionFromIntentLocked(int callingUid, 7407 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7408 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7409 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7410 if (needed == null) { 7411 return; 7412 } 7413 7414 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7415 } 7416 7417 /** 7418 * @param uri This uri must NOT contain an embedded userId. 7419 * @param userId The userId in which the uri is to be resolved. 7420 */ 7421 @Override 7422 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7423 final int modeFlags, int userId) { 7424 enforceNotIsolatedCaller("grantUriPermission"); 7425 GrantUri grantUri = new GrantUri(userId, uri, false); 7426 synchronized(this) { 7427 final ProcessRecord r = getRecordForAppLocked(caller); 7428 if (r == null) { 7429 throw new SecurityException("Unable to find app for caller " 7430 + caller 7431 + " when granting permission to uri " + grantUri); 7432 } 7433 if (targetPkg == null) { 7434 throw new IllegalArgumentException("null target"); 7435 } 7436 if (grantUri == null) { 7437 throw new IllegalArgumentException("null uri"); 7438 } 7439 7440 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7441 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7442 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7443 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7444 7445 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7446 UserHandle.getUserId(r.uid)); 7447 } 7448 } 7449 7450 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7451 if (perm.modeFlags == 0) { 7452 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7453 perm.targetUid); 7454 if (perms != null) { 7455 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7456 "Removing " + perm.targetUid + " permission to " + perm.uri); 7457 7458 perms.remove(perm.uri); 7459 if (perms.isEmpty()) { 7460 mGrantedUriPermissions.remove(perm.targetUid); 7461 } 7462 } 7463 } 7464 } 7465 7466 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7467 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7468 7469 final IPackageManager pm = AppGlobals.getPackageManager(); 7470 final String authority = grantUri.uri.getAuthority(); 7471 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7472 if (pi == null) { 7473 Slog.w(TAG, "No content provider found for permission revoke: " 7474 + grantUri.toSafeString()); 7475 return; 7476 } 7477 7478 // Does the caller have this permission on the URI? 7479 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7480 // If they don't have direct access to the URI, then revoke any 7481 // ownerless URI permissions that have been granted to them. 7482 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7483 if (perms != null) { 7484 boolean persistChanged = false; 7485 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7486 final UriPermission perm = it.next(); 7487 if (perm.uri.sourceUserId == grantUri.sourceUserId 7488 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7489 if (DEBUG_URI_PERMISSION) 7490 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7491 " permission to " + perm.uri); 7492 persistChanged |= perm.revokeModes( 7493 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7494 if (perm.modeFlags == 0) { 7495 it.remove(); 7496 } 7497 } 7498 } 7499 if (perms.isEmpty()) { 7500 mGrantedUriPermissions.remove(callingUid); 7501 } 7502 if (persistChanged) { 7503 schedulePersistUriGrants(); 7504 } 7505 } 7506 return; 7507 } 7508 7509 boolean persistChanged = false; 7510 7511 // Go through all of the permissions and remove any that match. 7512 int N = mGrantedUriPermissions.size(); 7513 for (int i = 0; i < N; i++) { 7514 final int targetUid = mGrantedUriPermissions.keyAt(i); 7515 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7516 7517 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7518 final UriPermission perm = it.next(); 7519 if (perm.uri.sourceUserId == grantUri.sourceUserId 7520 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7521 if (DEBUG_URI_PERMISSION) 7522 Slog.v(TAG, 7523 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7524 persistChanged |= perm.revokeModes( 7525 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7526 if (perm.modeFlags == 0) { 7527 it.remove(); 7528 } 7529 } 7530 } 7531 7532 if (perms.isEmpty()) { 7533 mGrantedUriPermissions.remove(targetUid); 7534 N--; 7535 i--; 7536 } 7537 } 7538 7539 if (persistChanged) { 7540 schedulePersistUriGrants(); 7541 } 7542 } 7543 7544 /** 7545 * @param uri This uri must NOT contain an embedded userId. 7546 * @param userId The userId in which the uri is to be resolved. 7547 */ 7548 @Override 7549 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7550 int userId) { 7551 enforceNotIsolatedCaller("revokeUriPermission"); 7552 synchronized(this) { 7553 final ProcessRecord r = getRecordForAppLocked(caller); 7554 if (r == null) { 7555 throw new SecurityException("Unable to find app for caller " 7556 + caller 7557 + " when revoking permission to uri " + uri); 7558 } 7559 if (uri == null) { 7560 Slog.w(TAG, "revokeUriPermission: null uri"); 7561 return; 7562 } 7563 7564 if (!Intent.isAccessUriMode(modeFlags)) { 7565 return; 7566 } 7567 7568 final IPackageManager pm = AppGlobals.getPackageManager(); 7569 final String authority = uri.getAuthority(); 7570 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7571 if (pi == null) { 7572 Slog.w(TAG, "No content provider found for permission revoke: " 7573 + uri.toSafeString()); 7574 return; 7575 } 7576 7577 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7578 } 7579 } 7580 7581 /** 7582 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7583 * given package. 7584 * 7585 * @param packageName Package name to match, or {@code null} to apply to all 7586 * packages. 7587 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7588 * to all users. 7589 * @param persistable If persistable grants should be removed. 7590 */ 7591 private void removeUriPermissionsForPackageLocked( 7592 String packageName, int userHandle, boolean persistable) { 7593 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7594 throw new IllegalArgumentException("Must narrow by either package or user"); 7595 } 7596 7597 boolean persistChanged = false; 7598 7599 int N = mGrantedUriPermissions.size(); 7600 for (int i = 0; i < N; i++) { 7601 final int targetUid = mGrantedUriPermissions.keyAt(i); 7602 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7603 7604 // Only inspect grants matching user 7605 if (userHandle == UserHandle.USER_ALL 7606 || userHandle == UserHandle.getUserId(targetUid)) { 7607 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7608 final UriPermission perm = it.next(); 7609 7610 // Only inspect grants matching package 7611 if (packageName == null || perm.sourcePkg.equals(packageName) 7612 || perm.targetPkg.equals(packageName)) { 7613 persistChanged |= perm.revokeModes(persistable 7614 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7615 7616 // Only remove when no modes remain; any persisted grants 7617 // will keep this alive. 7618 if (perm.modeFlags == 0) { 7619 it.remove(); 7620 } 7621 } 7622 } 7623 7624 if (perms.isEmpty()) { 7625 mGrantedUriPermissions.remove(targetUid); 7626 N--; 7627 i--; 7628 } 7629 } 7630 } 7631 7632 if (persistChanged) { 7633 schedulePersistUriGrants(); 7634 } 7635 } 7636 7637 @Override 7638 public IBinder newUriPermissionOwner(String name) { 7639 enforceNotIsolatedCaller("newUriPermissionOwner"); 7640 synchronized(this) { 7641 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7642 return owner.getExternalTokenLocked(); 7643 } 7644 } 7645 7646 /** 7647 * @param uri This uri must NOT contain an embedded userId. 7648 * @param sourceUserId The userId in which the uri is to be resolved. 7649 * @param targetUserId The userId of the app that receives the grant. 7650 */ 7651 @Override 7652 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7653 final int modeFlags, int sourceUserId, int targetUserId) { 7654 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7655 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7656 synchronized(this) { 7657 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7658 if (owner == null) { 7659 throw new IllegalArgumentException("Unknown owner: " + token); 7660 } 7661 if (fromUid != Binder.getCallingUid()) { 7662 if (Binder.getCallingUid() != Process.myUid()) { 7663 // Only system code can grant URI permissions on behalf 7664 // of other users. 7665 throw new SecurityException("nice try"); 7666 } 7667 } 7668 if (targetPkg == null) { 7669 throw new IllegalArgumentException("null target"); 7670 } 7671 if (uri == null) { 7672 throw new IllegalArgumentException("null uri"); 7673 } 7674 7675 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7676 modeFlags, owner, targetUserId); 7677 } 7678 } 7679 7680 /** 7681 * @param uri This uri must NOT contain an embedded userId. 7682 * @param userId The userId in which the uri is to be resolved. 7683 */ 7684 @Override 7685 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7686 synchronized(this) { 7687 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7688 if (owner == null) { 7689 throw new IllegalArgumentException("Unknown owner: " + token); 7690 } 7691 7692 if (uri == null) { 7693 owner.removeUriPermissionsLocked(mode); 7694 } else { 7695 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7696 } 7697 } 7698 } 7699 7700 private void schedulePersistUriGrants() { 7701 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7702 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7703 10 * DateUtils.SECOND_IN_MILLIS); 7704 } 7705 } 7706 7707 private void writeGrantedUriPermissions() { 7708 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7709 7710 // Snapshot permissions so we can persist without lock 7711 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7712 synchronized (this) { 7713 final int size = mGrantedUriPermissions.size(); 7714 for (int i = 0; i < size; i++) { 7715 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7716 for (UriPermission perm : perms.values()) { 7717 if (perm.persistedModeFlags != 0) { 7718 persist.add(perm.snapshot()); 7719 } 7720 } 7721 } 7722 } 7723 7724 FileOutputStream fos = null; 7725 try { 7726 fos = mGrantFile.startWrite(); 7727 7728 XmlSerializer out = new FastXmlSerializer(); 7729 out.setOutput(fos, "utf-8"); 7730 out.startDocument(null, true); 7731 out.startTag(null, TAG_URI_GRANTS); 7732 for (UriPermission.Snapshot perm : persist) { 7733 out.startTag(null, TAG_URI_GRANT); 7734 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7735 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7736 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7737 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7738 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7739 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7740 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7741 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7742 out.endTag(null, TAG_URI_GRANT); 7743 } 7744 out.endTag(null, TAG_URI_GRANTS); 7745 out.endDocument(); 7746 7747 mGrantFile.finishWrite(fos); 7748 } catch (IOException e) { 7749 if (fos != null) { 7750 mGrantFile.failWrite(fos); 7751 } 7752 } 7753 } 7754 7755 private void readGrantedUriPermissionsLocked() { 7756 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7757 7758 final long now = System.currentTimeMillis(); 7759 7760 FileInputStream fis = null; 7761 try { 7762 fis = mGrantFile.openRead(); 7763 final XmlPullParser in = Xml.newPullParser(); 7764 in.setInput(fis, null); 7765 7766 int type; 7767 while ((type = in.next()) != END_DOCUMENT) { 7768 final String tag = in.getName(); 7769 if (type == START_TAG) { 7770 if (TAG_URI_GRANT.equals(tag)) { 7771 final int sourceUserId; 7772 final int targetUserId; 7773 final int userHandle = readIntAttribute(in, 7774 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7775 if (userHandle != UserHandle.USER_NULL) { 7776 // For backwards compatibility. 7777 sourceUserId = userHandle; 7778 targetUserId = userHandle; 7779 } else { 7780 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7781 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7782 } 7783 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7784 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7785 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7786 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7787 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7788 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7789 7790 // Sanity check that provider still belongs to source package 7791 final ProviderInfo pi = getProviderInfoLocked( 7792 uri.getAuthority(), sourceUserId); 7793 if (pi != null && sourcePkg.equals(pi.packageName)) { 7794 int targetUid = -1; 7795 try { 7796 targetUid = AppGlobals.getPackageManager() 7797 .getPackageUid(targetPkg, targetUserId); 7798 } catch (RemoteException e) { 7799 } 7800 if (targetUid != -1) { 7801 final UriPermission perm = findOrCreateUriPermissionLocked( 7802 sourcePkg, targetPkg, targetUid, 7803 new GrantUri(sourceUserId, uri, prefix)); 7804 perm.initPersistedModes(modeFlags, createdTime); 7805 } 7806 } else { 7807 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7808 + " but instead found " + pi); 7809 } 7810 } 7811 } 7812 } 7813 } catch (FileNotFoundException e) { 7814 // Missing grants is okay 7815 } catch (IOException e) { 7816 Slog.wtf(TAG, "Failed reading Uri grants", e); 7817 } catch (XmlPullParserException e) { 7818 Slog.wtf(TAG, "Failed reading Uri grants", e); 7819 } finally { 7820 IoUtils.closeQuietly(fis); 7821 } 7822 } 7823 7824 /** 7825 * @param uri This uri must NOT contain an embedded userId. 7826 * @param userId The userId in which the uri is to be resolved. 7827 */ 7828 @Override 7829 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7830 enforceNotIsolatedCaller("takePersistableUriPermission"); 7831 7832 Preconditions.checkFlagsArgument(modeFlags, 7833 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7834 7835 synchronized (this) { 7836 final int callingUid = Binder.getCallingUid(); 7837 boolean persistChanged = false; 7838 GrantUri grantUri = new GrantUri(userId, uri, false); 7839 7840 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7841 new GrantUri(userId, uri, false)); 7842 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7843 new GrantUri(userId, uri, true)); 7844 7845 final boolean exactValid = (exactPerm != null) 7846 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7847 final boolean prefixValid = (prefixPerm != null) 7848 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7849 7850 if (!(exactValid || prefixValid)) { 7851 throw new SecurityException("No persistable permission grants found for UID " 7852 + callingUid + " and Uri " + grantUri.toSafeString()); 7853 } 7854 7855 if (exactValid) { 7856 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7857 } 7858 if (prefixValid) { 7859 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7860 } 7861 7862 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7863 7864 if (persistChanged) { 7865 schedulePersistUriGrants(); 7866 } 7867 } 7868 } 7869 7870 /** 7871 * @param uri This uri must NOT contain an embedded userId. 7872 * @param userId The userId in which the uri is to be resolved. 7873 */ 7874 @Override 7875 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7876 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7877 7878 Preconditions.checkFlagsArgument(modeFlags, 7879 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7880 7881 synchronized (this) { 7882 final int callingUid = Binder.getCallingUid(); 7883 boolean persistChanged = false; 7884 7885 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7886 new GrantUri(userId, uri, false)); 7887 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7888 new GrantUri(userId, uri, true)); 7889 if (exactPerm == null && prefixPerm == null) { 7890 throw new SecurityException("No permission grants found for UID " + callingUid 7891 + " and Uri " + uri.toSafeString()); 7892 } 7893 7894 if (exactPerm != null) { 7895 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7896 removeUriPermissionIfNeededLocked(exactPerm); 7897 } 7898 if (prefixPerm != null) { 7899 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7900 removeUriPermissionIfNeededLocked(prefixPerm); 7901 } 7902 7903 if (persistChanged) { 7904 schedulePersistUriGrants(); 7905 } 7906 } 7907 } 7908 7909 /** 7910 * Prune any older {@link UriPermission} for the given UID until outstanding 7911 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7912 * 7913 * @return if any mutations occured that require persisting. 7914 */ 7915 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7916 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7917 if (perms == null) return false; 7918 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7919 7920 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7921 for (UriPermission perm : perms.values()) { 7922 if (perm.persistedModeFlags != 0) { 7923 persisted.add(perm); 7924 } 7925 } 7926 7927 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7928 if (trimCount <= 0) return false; 7929 7930 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7931 for (int i = 0; i < trimCount; i++) { 7932 final UriPermission perm = persisted.get(i); 7933 7934 if (DEBUG_URI_PERMISSION) { 7935 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7936 } 7937 7938 perm.releasePersistableModes(~0); 7939 removeUriPermissionIfNeededLocked(perm); 7940 } 7941 7942 return true; 7943 } 7944 7945 @Override 7946 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7947 String packageName, boolean incoming) { 7948 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7949 Preconditions.checkNotNull(packageName, "packageName"); 7950 7951 final int callingUid = Binder.getCallingUid(); 7952 final IPackageManager pm = AppGlobals.getPackageManager(); 7953 try { 7954 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7955 if (packageUid != callingUid) { 7956 throw new SecurityException( 7957 "Package " + packageName + " does not belong to calling UID " + callingUid); 7958 } 7959 } catch (RemoteException e) { 7960 throw new SecurityException("Failed to verify package name ownership"); 7961 } 7962 7963 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7964 synchronized (this) { 7965 if (incoming) { 7966 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7967 callingUid); 7968 if (perms == null) { 7969 Slog.w(TAG, "No permission grants found for " + packageName); 7970 } else { 7971 for (UriPermission perm : perms.values()) { 7972 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7973 result.add(perm.buildPersistedPublicApiObject()); 7974 } 7975 } 7976 } 7977 } else { 7978 final int size = mGrantedUriPermissions.size(); 7979 for (int i = 0; i < size; i++) { 7980 final ArrayMap<GrantUri, UriPermission> perms = 7981 mGrantedUriPermissions.valueAt(i); 7982 for (UriPermission perm : perms.values()) { 7983 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7984 result.add(perm.buildPersistedPublicApiObject()); 7985 } 7986 } 7987 } 7988 } 7989 } 7990 return new ParceledListSlice<android.content.UriPermission>(result); 7991 } 7992 7993 @Override 7994 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7995 synchronized (this) { 7996 ProcessRecord app = 7997 who != null ? getRecordForAppLocked(who) : null; 7998 if (app == null) return; 7999 8000 Message msg = Message.obtain(); 8001 msg.what = WAIT_FOR_DEBUGGER_MSG; 8002 msg.obj = app; 8003 msg.arg1 = waiting ? 1 : 0; 8004 mHandler.sendMessage(msg); 8005 } 8006 } 8007 8008 @Override 8009 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8010 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8011 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8012 outInfo.availMem = Process.getFreeMemory(); 8013 outInfo.totalMem = Process.getTotalMemory(); 8014 outInfo.threshold = homeAppMem; 8015 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8016 outInfo.hiddenAppThreshold = cachedAppMem; 8017 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8018 ProcessList.SERVICE_ADJ); 8019 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8020 ProcessList.VISIBLE_APP_ADJ); 8021 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8022 ProcessList.FOREGROUND_APP_ADJ); 8023 } 8024 8025 // ========================================================= 8026 // TASK MANAGEMENT 8027 // ========================================================= 8028 8029 @Override 8030 public List<IAppTask> getAppTasks(String callingPackage) { 8031 int callingUid = Binder.getCallingUid(); 8032 long ident = Binder.clearCallingIdentity(); 8033 8034 synchronized(this) { 8035 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8036 try { 8037 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8038 8039 final int N = mRecentTasks.size(); 8040 for (int i = 0; i < N; i++) { 8041 TaskRecord tr = mRecentTasks.get(i); 8042 // Skip tasks that do not match the caller. We don't need to verify 8043 // callingPackage, because we are also limiting to callingUid and know 8044 // that will limit to the correct security sandbox. 8045 if (tr.effectiveUid != callingUid) { 8046 continue; 8047 } 8048 Intent intent = tr.getBaseIntent(); 8049 if (intent == null || 8050 !callingPackage.equals(intent.getComponent().getPackageName())) { 8051 continue; 8052 } 8053 ActivityManager.RecentTaskInfo taskInfo = 8054 createRecentTaskInfoFromTaskRecord(tr); 8055 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8056 list.add(taskImpl); 8057 } 8058 } finally { 8059 Binder.restoreCallingIdentity(ident); 8060 } 8061 return list; 8062 } 8063 } 8064 8065 @Override 8066 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8067 final int callingUid = Binder.getCallingUid(); 8068 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8069 8070 synchronized(this) { 8071 if (localLOGV) Slog.v( 8072 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8073 8074 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8075 callingUid); 8076 8077 // TODO: Improve with MRU list from all ActivityStacks. 8078 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8079 } 8080 8081 return list; 8082 } 8083 8084 /** 8085 * Creates a new RecentTaskInfo from a TaskRecord. 8086 */ 8087 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8088 // Update the task description to reflect any changes in the task stack 8089 tr.updateTaskDescription(); 8090 8091 // Compose the recent task info 8092 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8093 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 8094 rti.persistentId = tr.taskId; 8095 rti.baseIntent = new Intent(tr.getBaseIntent()); 8096 rti.origActivity = tr.origActivity; 8097 rti.description = tr.lastDescription; 8098 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8099 rti.userId = tr.userId; 8100 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8101 rti.firstActiveTime = tr.firstActiveTime; 8102 rti.lastActiveTime = tr.lastActiveTime; 8103 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8104 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8105 return rti; 8106 } 8107 8108 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8109 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8110 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8111 if (!allowed) { 8112 if (checkPermission(android.Manifest.permission.GET_TASKS, 8113 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8114 // Temporary compatibility: some existing apps on the system image may 8115 // still be requesting the old permission and not switched to the new 8116 // one; if so, we'll still allow them full access. This means we need 8117 // to see if they are holding the old permission and are a system app. 8118 try { 8119 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8120 allowed = true; 8121 Slog.w(TAG, caller + ": caller " + callingUid 8122 + " is using old GET_TASKS but privileged; allowing"); 8123 } 8124 } catch (RemoteException e) { 8125 } 8126 } 8127 } 8128 if (!allowed) { 8129 Slog.w(TAG, caller + ": caller " + callingUid 8130 + " does not hold REAL_GET_TASKS; limiting output"); 8131 } 8132 return allowed; 8133 } 8134 8135 @Override 8136 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8137 final int callingUid = Binder.getCallingUid(); 8138 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8139 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8140 8141 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8142 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8143 synchronized (this) { 8144 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8145 callingUid); 8146 final boolean detailed = checkCallingPermission( 8147 android.Manifest.permission.GET_DETAILED_TASKS) 8148 == PackageManager.PERMISSION_GRANTED; 8149 8150 final int N = mRecentTasks.size(); 8151 ArrayList<ActivityManager.RecentTaskInfo> res 8152 = new ArrayList<ActivityManager.RecentTaskInfo>( 8153 maxNum < N ? maxNum : N); 8154 8155 final Set<Integer> includedUsers; 8156 if (includeProfiles) { 8157 includedUsers = getProfileIdsLocked(userId); 8158 } else { 8159 includedUsers = new HashSet<Integer>(); 8160 } 8161 includedUsers.add(Integer.valueOf(userId)); 8162 8163 for (int i=0; i<N && maxNum > 0; i++) { 8164 TaskRecord tr = mRecentTasks.get(i); 8165 // Only add calling user or related users recent tasks 8166 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8167 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8168 continue; 8169 } 8170 8171 // Return the entry if desired by the caller. We always return 8172 // the first entry, because callers always expect this to be the 8173 // foreground app. We may filter others if the caller has 8174 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8175 // we should exclude the entry. 8176 8177 if (i == 0 8178 || withExcluded 8179 || (tr.intent == null) 8180 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8181 == 0)) { 8182 if (!allowed) { 8183 // If the caller doesn't have the GET_TASKS permission, then only 8184 // allow them to see a small subset of tasks -- their own and home. 8185 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8186 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8187 continue; 8188 } 8189 } 8190 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8191 if (tr.stack != null && tr.stack.isHomeStack()) { 8192 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8193 continue; 8194 } 8195 } 8196 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8197 // Don't include auto remove tasks that are finished or finishing. 8198 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8199 + tr); 8200 continue; 8201 } 8202 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8203 && !tr.isAvailable) { 8204 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8205 continue; 8206 } 8207 8208 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8209 if (!detailed) { 8210 rti.baseIntent.replaceExtras((Bundle)null); 8211 } 8212 8213 res.add(rti); 8214 maxNum--; 8215 } 8216 } 8217 return res; 8218 } 8219 } 8220 8221 TaskRecord recentTaskForIdLocked(int id) { 8222 final int N = mRecentTasks.size(); 8223 for (int i=0; i<N; i++) { 8224 TaskRecord tr = mRecentTasks.get(i); 8225 if (tr.taskId == id) { 8226 return tr; 8227 } 8228 } 8229 return null; 8230 } 8231 8232 @Override 8233 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8234 synchronized (this) { 8235 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8236 "getTaskThumbnail()"); 8237 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id); 8238 if (tr != null) { 8239 return tr.getTaskThumbnailLocked(); 8240 } 8241 } 8242 return null; 8243 } 8244 8245 @Override 8246 public int addAppTask(IBinder activityToken, Intent intent, 8247 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8248 final int callingUid = Binder.getCallingUid(); 8249 final long callingIdent = Binder.clearCallingIdentity(); 8250 8251 try { 8252 synchronized (this) { 8253 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8254 if (r == null) { 8255 throw new IllegalArgumentException("Activity does not exist; token=" 8256 + activityToken); 8257 } 8258 ComponentName comp = intent.getComponent(); 8259 if (comp == null) { 8260 throw new IllegalArgumentException("Intent " + intent 8261 + " must specify explicit component"); 8262 } 8263 if (thumbnail.getWidth() != mThumbnailWidth 8264 || thumbnail.getHeight() != mThumbnailHeight) { 8265 throw new IllegalArgumentException("Bad thumbnail size: got " 8266 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8267 + mThumbnailWidth + "x" + mThumbnailHeight); 8268 } 8269 if (intent.getSelector() != null) { 8270 intent.setSelector(null); 8271 } 8272 if (intent.getSourceBounds() != null) { 8273 intent.setSourceBounds(null); 8274 } 8275 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8276 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8277 // The caller has added this as an auto-remove task... that makes no 8278 // sense, so turn off auto-remove. 8279 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8280 } 8281 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8282 // Must be a new task. 8283 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8284 } 8285 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8286 mLastAddedTaskActivity = null; 8287 } 8288 ActivityInfo ainfo = mLastAddedTaskActivity; 8289 if (ainfo == null) { 8290 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8291 comp, 0, UserHandle.getUserId(callingUid)); 8292 if (ainfo.applicationInfo.uid != callingUid) { 8293 throw new SecurityException( 8294 "Can't add task for another application: target uid=" 8295 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8296 } 8297 } 8298 8299 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8300 intent, description); 8301 8302 int trimIdx = trimRecentsForTaskLocked(task, false); 8303 if (trimIdx >= 0) { 8304 // If this would have caused a trim, then we'll abort because that 8305 // means it would be added at the end of the list but then just removed. 8306 return INVALID_TASK_ID; 8307 } 8308 8309 final int N = mRecentTasks.size(); 8310 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8311 final TaskRecord tr = mRecentTasks.remove(N - 1); 8312 tr.removedFromRecents(); 8313 } 8314 8315 task.inRecents = true; 8316 mRecentTasks.add(task); 8317 r.task.stack.addTask(task, false, false); 8318 8319 task.setLastThumbnail(thumbnail); 8320 task.freeLastThumbnail(); 8321 8322 return task.taskId; 8323 } 8324 } finally { 8325 Binder.restoreCallingIdentity(callingIdent); 8326 } 8327 } 8328 8329 @Override 8330 public Point getAppTaskThumbnailSize() { 8331 synchronized (this) { 8332 return new Point(mThumbnailWidth, mThumbnailHeight); 8333 } 8334 } 8335 8336 @Override 8337 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8338 synchronized (this) { 8339 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8340 if (r != null) { 8341 r.setTaskDescription(td); 8342 r.task.updateTaskDescription(); 8343 } 8344 } 8345 } 8346 8347 @Override 8348 public Bitmap getTaskDescriptionIcon(String filename) { 8349 if (!FileUtils.isValidExtFilename(filename) 8350 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8351 throw new IllegalArgumentException("Bad filename: " + filename); 8352 } 8353 return mTaskPersister.getTaskDescriptionIcon(filename); 8354 } 8355 8356 @Override 8357 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts) 8358 throws RemoteException { 8359 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 8360 opts.getCustomInPlaceResId() == 0) { 8361 throw new IllegalArgumentException("Expected in-place ActivityOption " + 8362 "with valid animation"); 8363 } 8364 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); 8365 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), 8366 opts.getCustomInPlaceResId()); 8367 mWindowManager.executeAppTransition(); 8368 } 8369 8370 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) { 8371 mRecentTasks.remove(tr); 8372 tr.removedFromRecents(); 8373 ComponentName component = tr.getBaseIntent().getComponent(); 8374 if (component == null) { 8375 Slog.w(TAG, "No component for base intent of task: " + tr); 8376 return; 8377 } 8378 8379 if (!killProcess) { 8380 return; 8381 } 8382 8383 // Determine if the process(es) for this task should be killed. 8384 final String pkg = component.getPackageName(); 8385 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>(); 8386 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8387 for (int i = 0; i < pmap.size(); i++) { 8388 8389 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8390 for (int j = 0; j < uids.size(); j++) { 8391 ProcessRecord proc = uids.valueAt(j); 8392 if (proc.userId != tr.userId) { 8393 // Don't kill process for a different user. 8394 continue; 8395 } 8396 if (proc == mHomeProcess) { 8397 // Don't kill the home process along with tasks from the same package. 8398 continue; 8399 } 8400 if (!proc.pkgList.containsKey(pkg)) { 8401 // Don't kill process that is not associated with this task. 8402 continue; 8403 } 8404 8405 for (int k = 0; k < proc.activities.size(); k++) { 8406 TaskRecord otherTask = proc.activities.get(k).task; 8407 if (tr.taskId != otherTask.taskId && otherTask.inRecents) { 8408 // Don't kill process(es) that has an activity in a different task that is 8409 // also in recents. 8410 return; 8411 } 8412 } 8413 8414 // Add process to kill list. 8415 procsToKill.add(proc); 8416 } 8417 } 8418 8419 // Find any running services associated with this app and stop if needed. 8420 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent())); 8421 8422 // Kill the running processes. 8423 for (int i = 0; i < procsToKill.size(); i++) { 8424 ProcessRecord pr = procsToKill.get(i); 8425 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8426 pr.kill("remove task", true); 8427 } else { 8428 pr.waitingToKill = "remove task"; 8429 } 8430 } 8431 } 8432 8433 private void removeTasksByPackageNameLocked(String packageName, int userId) { 8434 // Remove all tasks with activities in the specified package from the list of recent tasks 8435 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8436 TaskRecord tr = mRecentTasks.get(i); 8437 if (tr.userId != userId) continue; 8438 8439 ComponentName cn = tr.intent.getComponent(); 8440 if (cn != null && cn.getPackageName().equals(packageName)) { 8441 // If the package name matches, remove the task. 8442 removeTaskByIdLocked(tr.taskId, true); 8443 } 8444 } 8445 } 8446 8447 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { 8448 final IPackageManager pm = AppGlobals.getPackageManager(); 8449 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 8450 8451 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 8452 TaskRecord tr = mRecentTasks.get(i); 8453 if (tr.userId != userId) continue; 8454 8455 ComponentName cn = tr.intent.getComponent(); 8456 if (cn != null && cn.getPackageName().equals(packageName)) { 8457 // Skip if component still exists in the package. 8458 if (componentsKnownToExist.contains(cn)) continue; 8459 8460 try { 8461 ActivityInfo info = pm.getActivityInfo(cn, 0, userId); 8462 if (info != null) { 8463 componentsKnownToExist.add(cn); 8464 } else { 8465 removeTaskByIdLocked(tr.taskId, false); 8466 } 8467 } catch (RemoteException e) { 8468 Log.e(TAG, "Activity info query failed. component=" + cn, e); 8469 } 8470 } 8471 } 8472 } 8473 8474 /** 8475 * Removes the task with the specified task id. 8476 * 8477 * @param taskId Identifier of the task to be removed. 8478 * @param killProcess Kill any process associated with the task if possible. 8479 * @return Returns true if the given task was found and removed. 8480 */ 8481 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) { 8482 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8483 if (tr != null) { 8484 tr.removeTaskActivitiesLocked(); 8485 cleanUpRemovedTaskLocked(tr, killProcess); 8486 if (tr.isPersistable) { 8487 notifyTaskPersisterLocked(null, true); 8488 } 8489 return true; 8490 } 8491 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId); 8492 return false; 8493 } 8494 8495 @Override 8496 public boolean removeTask(int taskId) { 8497 synchronized (this) { 8498 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8499 "removeTask()"); 8500 long ident = Binder.clearCallingIdentity(); 8501 try { 8502 return removeTaskByIdLocked(taskId, true); 8503 } finally { 8504 Binder.restoreCallingIdentity(ident); 8505 } 8506 } 8507 } 8508 8509 /** 8510 * TODO: Add mController hook 8511 */ 8512 @Override 8513 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8514 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8515 "moveTaskToFront()"); 8516 8517 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8518 synchronized(this) { 8519 moveTaskToFrontLocked(taskId, flags, options); 8520 } 8521 } 8522 8523 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8524 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8525 Binder.getCallingUid(), -1, -1, "Task to front")) { 8526 ActivityOptions.abort(options); 8527 return; 8528 } 8529 final long origId = Binder.clearCallingIdentity(); 8530 try { 8531 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8532 if (task == null) { 8533 Slog.d(TAG, "Could not find task for id: "+ taskId); 8534 return; 8535 } 8536 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8537 mStackSupervisor.showLockTaskToast(); 8538 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8539 return; 8540 } 8541 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8542 if (prev != null && prev.isRecentsActivity()) { 8543 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8544 } 8545 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront"); 8546 } finally { 8547 Binder.restoreCallingIdentity(origId); 8548 } 8549 ActivityOptions.abort(options); 8550 } 8551 8552 @Override 8553 public void moveTaskToBack(int taskId) { 8554 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8555 "moveTaskToBack()"); 8556 8557 synchronized(this) { 8558 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8559 if (tr != null) { 8560 if (tr == mStackSupervisor.mLockTaskModeTask) { 8561 mStackSupervisor.showLockTaskToast(); 8562 return; 8563 } 8564 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8565 ActivityStack stack = tr.stack; 8566 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8567 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8568 Binder.getCallingUid(), -1, -1, "Task to back")) { 8569 return; 8570 } 8571 } 8572 final long origId = Binder.clearCallingIdentity(); 8573 try { 8574 stack.moveTaskToBackLocked(taskId); 8575 } finally { 8576 Binder.restoreCallingIdentity(origId); 8577 } 8578 } 8579 } 8580 } 8581 8582 /** 8583 * Moves an activity, and all of the other activities within the same task, to the bottom 8584 * of the history stack. The activity's order within the task is unchanged. 8585 * 8586 * @param token A reference to the activity we wish to move 8587 * @param nonRoot If false then this only works if the activity is the root 8588 * of a task; if true it will work for any activity in a task. 8589 * @return Returns true if the move completed, false if not. 8590 */ 8591 @Override 8592 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8593 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8594 synchronized(this) { 8595 final long origId = Binder.clearCallingIdentity(); 8596 try { 8597 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8598 if (taskId >= 0) { 8599 if ((mStackSupervisor.mLockTaskModeTask != null) 8600 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8601 mStackSupervisor.showLockTaskToast(); 8602 return false; 8603 } 8604 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId); 8605 } 8606 } finally { 8607 Binder.restoreCallingIdentity(origId); 8608 } 8609 } 8610 return false; 8611 } 8612 8613 @Override 8614 public void moveTaskBackwards(int task) { 8615 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8616 "moveTaskBackwards()"); 8617 8618 synchronized(this) { 8619 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8620 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8621 return; 8622 } 8623 final long origId = Binder.clearCallingIdentity(); 8624 moveTaskBackwardsLocked(task); 8625 Binder.restoreCallingIdentity(origId); 8626 } 8627 } 8628 8629 private final void moveTaskBackwardsLocked(int task) { 8630 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8631 } 8632 8633 @Override 8634 public IBinder getHomeActivityToken() throws RemoteException { 8635 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8636 "getHomeActivityToken()"); 8637 synchronized (this) { 8638 return mStackSupervisor.getHomeActivityToken(); 8639 } 8640 } 8641 8642 @Override 8643 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8644 IActivityContainerCallback callback) throws RemoteException { 8645 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8646 "createActivityContainer()"); 8647 synchronized (this) { 8648 if (parentActivityToken == null) { 8649 throw new IllegalArgumentException("parent token must not be null"); 8650 } 8651 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8652 if (r == null) { 8653 return null; 8654 } 8655 if (callback == null) { 8656 throw new IllegalArgumentException("callback must not be null"); 8657 } 8658 return mStackSupervisor.createActivityContainer(r, callback); 8659 } 8660 } 8661 8662 @Override 8663 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8664 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8665 "deleteActivityContainer()"); 8666 synchronized (this) { 8667 mStackSupervisor.deleteActivityContainer(container); 8668 } 8669 } 8670 8671 @Override 8672 public int getActivityDisplayId(IBinder activityToken) throws RemoteException { 8673 synchronized (this) { 8674 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8675 if (stack != null && stack.mActivityContainer.isAttachedLocked()) { 8676 return stack.mActivityContainer.getDisplayId(); 8677 } 8678 return Display.DEFAULT_DISPLAY; 8679 } 8680 } 8681 8682 @Override 8683 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8684 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8685 "moveTaskToStack()"); 8686 if (stackId == HOME_STACK_ID) { 8687 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8688 new RuntimeException("here").fillInStackTrace()); 8689 } 8690 synchronized (this) { 8691 long ident = Binder.clearCallingIdentity(); 8692 try { 8693 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8694 + stackId + " toTop=" + toTop); 8695 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop); 8696 } finally { 8697 Binder.restoreCallingIdentity(ident); 8698 } 8699 } 8700 } 8701 8702 @Override 8703 public void resizeStack(int stackBoxId, Rect bounds) { 8704 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8705 "resizeStackBox()"); 8706 long ident = Binder.clearCallingIdentity(); 8707 try { 8708 mWindowManager.resizeStack(stackBoxId, bounds); 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 } 8713 8714 @Override 8715 public List<StackInfo> getAllStackInfos() { 8716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8717 "getAllStackInfos()"); 8718 long ident = Binder.clearCallingIdentity(); 8719 try { 8720 synchronized (this) { 8721 return mStackSupervisor.getAllStackInfosLocked(); 8722 } 8723 } finally { 8724 Binder.restoreCallingIdentity(ident); 8725 } 8726 } 8727 8728 @Override 8729 public StackInfo getStackInfo(int stackId) { 8730 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8731 "getStackInfo()"); 8732 long ident = Binder.clearCallingIdentity(); 8733 try { 8734 synchronized (this) { 8735 return mStackSupervisor.getStackInfoLocked(stackId); 8736 } 8737 } finally { 8738 Binder.restoreCallingIdentity(ident); 8739 } 8740 } 8741 8742 @Override 8743 public boolean isInHomeStack(int taskId) { 8744 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8745 "getStackInfo()"); 8746 long ident = Binder.clearCallingIdentity(); 8747 try { 8748 synchronized (this) { 8749 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId); 8750 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8751 } 8752 } finally { 8753 Binder.restoreCallingIdentity(ident); 8754 } 8755 } 8756 8757 @Override 8758 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8759 synchronized(this) { 8760 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8761 } 8762 } 8763 8764 private boolean isLockTaskAuthorized(String pkg) { 8765 final DevicePolicyManager dpm = (DevicePolicyManager) 8766 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8767 try { 8768 int uid = mContext.getPackageManager().getPackageUid(pkg, 8769 Binder.getCallingUserHandle().getIdentifier()); 8770 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8771 } catch (NameNotFoundException e) { 8772 return false; 8773 } 8774 } 8775 8776 void startLockTaskMode(TaskRecord task) { 8777 final String pkg; 8778 synchronized (this) { 8779 pkg = task.intent.getComponent().getPackageName(); 8780 } 8781 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8782 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8783 StatusBarManagerInternal statusBarManager = LocalServices.getService( 8784 StatusBarManagerInternal.class); 8785 if (statusBarManager != null) { 8786 statusBarManager.showScreenPinningRequest(); 8787 } 8788 return; 8789 } 8790 long ident = Binder.clearCallingIdentity(); 8791 try { 8792 synchronized (this) { 8793 // Since we lost lock on task, make sure it is still there. 8794 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8795 if (task != null) { 8796 if (!isSystemInitiated 8797 && ((mStackSupervisor.getFocusedStack() == null) 8798 || (task != mStackSupervisor.getFocusedStack().topTask()))) { 8799 throw new IllegalArgumentException("Invalid task, not in foreground"); 8800 } 8801 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated, 8802 "startLockTask"); 8803 } 8804 } 8805 } finally { 8806 Binder.restoreCallingIdentity(ident); 8807 } 8808 } 8809 8810 @Override 8811 public void startLockTaskMode(int taskId) { 8812 final TaskRecord task; 8813 long ident = Binder.clearCallingIdentity(); 8814 try { 8815 synchronized (this) { 8816 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8817 } 8818 } finally { 8819 Binder.restoreCallingIdentity(ident); 8820 } 8821 if (task != null) { 8822 startLockTaskMode(task); 8823 } 8824 } 8825 8826 @Override 8827 public void startLockTaskMode(IBinder token) { 8828 final TaskRecord task; 8829 long ident = Binder.clearCallingIdentity(); 8830 try { 8831 synchronized (this) { 8832 final ActivityRecord r = ActivityRecord.forToken(token); 8833 if (r == null) { 8834 return; 8835 } 8836 task = r.task; 8837 } 8838 } finally { 8839 Binder.restoreCallingIdentity(ident); 8840 } 8841 if (task != null) { 8842 startLockTaskMode(task); 8843 } 8844 } 8845 8846 @Override 8847 public void startLockTaskModeOnCurrent() throws RemoteException { 8848 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8849 "startLockTaskModeOnCurrent"); 8850 long ident = Binder.clearCallingIdentity(); 8851 try { 8852 ActivityRecord r = null; 8853 synchronized (this) { 8854 r = mStackSupervisor.topRunningActivityLocked(); 8855 } 8856 startLockTaskMode(r.task); 8857 } finally { 8858 Binder.restoreCallingIdentity(ident); 8859 } 8860 } 8861 8862 @Override 8863 public void stopLockTaskMode() { 8864 // Verify that the user matches the package of the intent for the TaskRecord 8865 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8866 // and stopLockTaskMode. 8867 final int callingUid = Binder.getCallingUid(); 8868 if (callingUid != Process.SYSTEM_UID) { 8869 try { 8870 String pkg = 8871 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8872 int uid = mContext.getPackageManager().getPackageUid(pkg, 8873 Binder.getCallingUserHandle().getIdentifier()); 8874 if (uid != callingUid) { 8875 throw new SecurityException("Invalid uid, expected " + uid); 8876 } 8877 } catch (NameNotFoundException e) { 8878 Log.d(TAG, "stopLockTaskMode " + e); 8879 return; 8880 } 8881 } 8882 long ident = Binder.clearCallingIdentity(); 8883 try { 8884 Log.d(TAG, "stopLockTaskMode"); 8885 // Stop lock task 8886 synchronized (this) { 8887 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask"); 8888 } 8889 } finally { 8890 Binder.restoreCallingIdentity(ident); 8891 } 8892 } 8893 8894 @Override 8895 public void stopLockTaskModeOnCurrent() throws RemoteException { 8896 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8897 "stopLockTaskModeOnCurrent"); 8898 long ident = Binder.clearCallingIdentity(); 8899 try { 8900 stopLockTaskMode(); 8901 } finally { 8902 Binder.restoreCallingIdentity(ident); 8903 } 8904 } 8905 8906 @Override 8907 public boolean isInLockTaskMode() { 8908 synchronized (this) { 8909 return mStackSupervisor.isInLockTaskMode(); 8910 } 8911 } 8912 8913 // ========================================================= 8914 // CONTENT PROVIDERS 8915 // ========================================================= 8916 8917 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8918 List<ProviderInfo> providers = null; 8919 try { 8920 providers = AppGlobals.getPackageManager(). 8921 queryContentProviders(app.processName, app.uid, 8922 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8923 } catch (RemoteException ex) { 8924 } 8925 if (DEBUG_MU) 8926 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8927 int userId = app.userId; 8928 if (providers != null) { 8929 int N = providers.size(); 8930 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8931 for (int i=0; i<N; i++) { 8932 ProviderInfo cpi = 8933 (ProviderInfo)providers.get(i); 8934 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8935 cpi.name, cpi.flags); 8936 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8937 // This is a singleton provider, but a user besides the 8938 // default user is asking to initialize a process it runs 8939 // in... well, no, it doesn't actually run in this process, 8940 // it runs in the process of the default user. Get rid of it. 8941 providers.remove(i); 8942 N--; 8943 i--; 8944 continue; 8945 } 8946 8947 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8948 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8949 if (cpr == null) { 8950 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8951 mProviderMap.putProviderByClass(comp, cpr); 8952 } 8953 if (DEBUG_MU) 8954 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8955 app.pubProviders.put(cpi.name, cpr); 8956 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8957 // Don't add this if it is a platform component that is marked 8958 // to run in multiple processes, because this is actually 8959 // part of the framework so doesn't make sense to track as a 8960 // separate apk in the process. 8961 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8962 mProcessStats); 8963 } 8964 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8965 } 8966 } 8967 return providers; 8968 } 8969 8970 /** 8971 * Check if {@link ProcessRecord} has a possible chance at accessing the 8972 * given {@link ProviderInfo}. Final permission checking is always done 8973 * in {@link ContentProvider}. 8974 */ 8975 private final String checkContentProviderPermissionLocked( 8976 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8977 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8978 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8979 boolean checkedGrants = false; 8980 if (checkUser) { 8981 // Looking for cross-user grants before enforcing the typical cross-users permissions 8982 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8983 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8984 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8985 return null; 8986 } 8987 checkedGrants = true; 8988 } 8989 userId = handleIncomingUser(callingPid, callingUid, userId, 8990 false, ALLOW_NON_FULL, 8991 "checkContentProviderPermissionLocked " + cpi.authority, null); 8992 if (userId != tmpTargetUserId) { 8993 // When we actually went to determine the final targer user ID, this ended 8994 // up different than our initial check for the authority. This is because 8995 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8996 // SELF. So we need to re-check the grants again. 8997 checkedGrants = false; 8998 } 8999 } 9000 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9001 cpi.applicationInfo.uid, cpi.exported) 9002 == PackageManager.PERMISSION_GRANTED) { 9003 return null; 9004 } 9005 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9006 cpi.applicationInfo.uid, cpi.exported) 9007 == PackageManager.PERMISSION_GRANTED) { 9008 return null; 9009 } 9010 9011 PathPermission[] pps = cpi.pathPermissions; 9012 if (pps != null) { 9013 int i = pps.length; 9014 while (i > 0) { 9015 i--; 9016 PathPermission pp = pps[i]; 9017 String pprperm = pp.getReadPermission(); 9018 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9019 cpi.applicationInfo.uid, cpi.exported) 9020 == PackageManager.PERMISSION_GRANTED) { 9021 return null; 9022 } 9023 String ppwperm = pp.getWritePermission(); 9024 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9025 cpi.applicationInfo.uid, cpi.exported) 9026 == PackageManager.PERMISSION_GRANTED) { 9027 return null; 9028 } 9029 } 9030 } 9031 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9032 return null; 9033 } 9034 9035 String msg; 9036 if (!cpi.exported) { 9037 msg = "Permission Denial: opening provider " + cpi.name 9038 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9039 + ", uid=" + callingUid + ") that is not exported from uid " 9040 + cpi.applicationInfo.uid; 9041 } else { 9042 msg = "Permission Denial: opening provider " + cpi.name 9043 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9044 + ", uid=" + callingUid + ") requires " 9045 + cpi.readPermission + " or " + cpi.writePermission; 9046 } 9047 Slog.w(TAG, msg); 9048 return msg; 9049 } 9050 9051 /** 9052 * Returns if the ContentProvider has granted a uri to callingUid 9053 */ 9054 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9055 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9056 if (perms != null) { 9057 for (int i=perms.size()-1; i>=0; i--) { 9058 GrantUri grantUri = perms.keyAt(i); 9059 if (grantUri.sourceUserId == userId || !checkUser) { 9060 if (matchesProvider(grantUri.uri, cpi)) { 9061 return true; 9062 } 9063 } 9064 } 9065 } 9066 return false; 9067 } 9068 9069 /** 9070 * Returns true if the uri authority is one of the authorities specified in the provider. 9071 */ 9072 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9073 String uriAuth = uri.getAuthority(); 9074 String cpiAuth = cpi.authority; 9075 if (cpiAuth.indexOf(';') == -1) { 9076 return cpiAuth.equals(uriAuth); 9077 } 9078 String[] cpiAuths = cpiAuth.split(";"); 9079 int length = cpiAuths.length; 9080 for (int i = 0; i < length; i++) { 9081 if (cpiAuths[i].equals(uriAuth)) return true; 9082 } 9083 return false; 9084 } 9085 9086 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9087 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9088 if (r != null) { 9089 for (int i=0; i<r.conProviders.size(); i++) { 9090 ContentProviderConnection conn = r.conProviders.get(i); 9091 if (conn.provider == cpr) { 9092 if (DEBUG_PROVIDER) Slog.v(TAG, 9093 "Adding provider requested by " 9094 + r.processName + " from process " 9095 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9096 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9097 if (stable) { 9098 conn.stableCount++; 9099 conn.numStableIncs++; 9100 } else { 9101 conn.unstableCount++; 9102 conn.numUnstableIncs++; 9103 } 9104 return conn; 9105 } 9106 } 9107 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9108 if (stable) { 9109 conn.stableCount = 1; 9110 conn.numStableIncs = 1; 9111 } else { 9112 conn.unstableCount = 1; 9113 conn.numUnstableIncs = 1; 9114 } 9115 cpr.connections.add(conn); 9116 r.conProviders.add(conn); 9117 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName); 9118 return conn; 9119 } 9120 cpr.addExternalProcessHandleLocked(externalProcessToken); 9121 return null; 9122 } 9123 9124 boolean decProviderCountLocked(ContentProviderConnection conn, 9125 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9126 if (conn != null) { 9127 cpr = conn.provider; 9128 if (DEBUG_PROVIDER) Slog.v(TAG, 9129 "Removing provider requested by " 9130 + conn.client.processName + " from process " 9131 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9132 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9133 if (stable) { 9134 conn.stableCount--; 9135 } else { 9136 conn.unstableCount--; 9137 } 9138 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9139 cpr.connections.remove(conn); 9140 conn.client.conProviders.remove(conn); 9141 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 9142 return true; 9143 } 9144 return false; 9145 } 9146 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9147 return false; 9148 } 9149 9150 private void checkTime(long startTime, String where) { 9151 long now = SystemClock.elapsedRealtime(); 9152 if ((now-startTime) > 1000) { 9153 // If we are taking more than a second, log about it. 9154 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9155 } 9156 } 9157 9158 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9159 String name, IBinder token, boolean stable, int userId) { 9160 ContentProviderRecord cpr; 9161 ContentProviderConnection conn = null; 9162 ProviderInfo cpi = null; 9163 9164 synchronized(this) { 9165 long startTime = SystemClock.elapsedRealtime(); 9166 9167 ProcessRecord r = null; 9168 if (caller != null) { 9169 r = getRecordForAppLocked(caller); 9170 if (r == null) { 9171 throw new SecurityException( 9172 "Unable to find app for caller " + caller 9173 + " (pid=" + Binder.getCallingPid() 9174 + ") when getting content provider " + name); 9175 } 9176 } 9177 9178 boolean checkCrossUser = true; 9179 9180 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9181 9182 // First check if this content provider has been published... 9183 cpr = mProviderMap.getProviderByName(name, userId); 9184 // If that didn't work, check if it exists for user 0 and then 9185 // verify that it's a singleton provider before using it. 9186 if (cpr == null && userId != UserHandle.USER_OWNER) { 9187 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9188 if (cpr != null) { 9189 cpi = cpr.info; 9190 if (isSingleton(cpi.processName, cpi.applicationInfo, 9191 cpi.name, cpi.flags) 9192 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9193 userId = UserHandle.USER_OWNER; 9194 checkCrossUser = false; 9195 } else { 9196 cpr = null; 9197 cpi = null; 9198 } 9199 } 9200 } 9201 9202 boolean providerRunning = cpr != null; 9203 if (providerRunning) { 9204 cpi = cpr.info; 9205 String msg; 9206 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9207 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9208 != null) { 9209 throw new SecurityException(msg); 9210 } 9211 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9212 9213 if (r != null && cpr.canRunHere(r)) { 9214 // This provider has been published or is in the process 9215 // of being published... but it is also allowed to run 9216 // in the caller's process, so don't make a connection 9217 // and just let the caller instantiate its own instance. 9218 ContentProviderHolder holder = cpr.newHolder(null); 9219 // don't give caller the provider object, it needs 9220 // to make its own. 9221 holder.provider = null; 9222 return holder; 9223 } 9224 9225 final long origId = Binder.clearCallingIdentity(); 9226 9227 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9228 9229 // In this case the provider instance already exists, so we can 9230 // return it right away. 9231 conn = incProviderCountLocked(r, cpr, token, stable); 9232 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9233 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9234 // If this is a perceptible app accessing the provider, 9235 // make sure to count it as being accessed and thus 9236 // back up on the LRU list. This is good because 9237 // content providers are often expensive to start. 9238 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9239 updateLruProcessLocked(cpr.proc, false, null); 9240 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9241 } 9242 } 9243 9244 if (cpr.proc != null) { 9245 if (false) { 9246 if (cpr.name.flattenToShortString().equals( 9247 "com.android.providers.calendar/.CalendarProvider2")) { 9248 Slog.v(TAG, "****************** KILLING " 9249 + cpr.name.flattenToShortString()); 9250 Process.killProcess(cpr.proc.pid); 9251 } 9252 } 9253 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9254 boolean success = updateOomAdjLocked(cpr.proc); 9255 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9256 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9257 // NOTE: there is still a race here where a signal could be 9258 // pending on the process even though we managed to update its 9259 // adj level. Not sure what to do about this, but at least 9260 // the race is now smaller. 9261 if (!success) { 9262 // Uh oh... it looks like the provider's process 9263 // has been killed on us. We need to wait for a new 9264 // process to be started, and make sure its death 9265 // doesn't kill our process. 9266 Slog.i(TAG, 9267 "Existing provider " + cpr.name.flattenToShortString() 9268 + " is crashing; detaching " + r); 9269 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9270 checkTime(startTime, "getContentProviderImpl: before appDied"); 9271 appDiedLocked(cpr.proc); 9272 checkTime(startTime, "getContentProviderImpl: after appDied"); 9273 if (!lastRef) { 9274 // This wasn't the last ref our process had on 9275 // the provider... we have now been killed, bail. 9276 return null; 9277 } 9278 providerRunning = false; 9279 conn = null; 9280 } 9281 } 9282 9283 Binder.restoreCallingIdentity(origId); 9284 } 9285 9286 boolean singleton; 9287 if (!providerRunning) { 9288 try { 9289 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9290 cpi = AppGlobals.getPackageManager(). 9291 resolveContentProvider(name, 9292 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9293 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9294 } catch (RemoteException ex) { 9295 } 9296 if (cpi == null) { 9297 return null; 9298 } 9299 // If the provider is a singleton AND 9300 // (it's a call within the same user || the provider is a 9301 // privileged app) 9302 // Then allow connecting to the singleton provider 9303 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9304 cpi.name, cpi.flags) 9305 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9306 if (singleton) { 9307 userId = UserHandle.USER_OWNER; 9308 } 9309 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9310 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9311 9312 String msg; 9313 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9314 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9315 != null) { 9316 throw new SecurityException(msg); 9317 } 9318 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9319 9320 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9321 && !cpi.processName.equals("system")) { 9322 // If this content provider does not run in the system 9323 // process, and the system is not yet ready to run other 9324 // processes, then fail fast instead of hanging. 9325 throw new IllegalArgumentException( 9326 "Attempt to launch content provider before system ready"); 9327 } 9328 9329 // Make sure that the user who owns this provider is running. If not, 9330 // we don't want to allow it to run. 9331 if (!isUserRunningLocked(userId, false)) { 9332 Slog.w(TAG, "Unable to launch app " 9333 + cpi.applicationInfo.packageName + "/" 9334 + cpi.applicationInfo.uid + " for provider " 9335 + name + ": user " + userId + " is stopped"); 9336 return null; 9337 } 9338 9339 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9340 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9341 cpr = mProviderMap.getProviderByClass(comp, userId); 9342 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9343 final boolean firstClass = cpr == null; 9344 if (firstClass) { 9345 final long ident = Binder.clearCallingIdentity(); 9346 try { 9347 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9348 ApplicationInfo ai = 9349 AppGlobals.getPackageManager(). 9350 getApplicationInfo( 9351 cpi.applicationInfo.packageName, 9352 STOCK_PM_FLAGS, userId); 9353 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9354 if (ai == null) { 9355 Slog.w(TAG, "No package info for content provider " 9356 + cpi.name); 9357 return null; 9358 } 9359 ai = getAppInfoForUser(ai, userId); 9360 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9361 } catch (RemoteException ex) { 9362 // pm is in same process, this will never happen. 9363 } finally { 9364 Binder.restoreCallingIdentity(ident); 9365 } 9366 } 9367 9368 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9369 9370 if (r != null && cpr.canRunHere(r)) { 9371 // If this is a multiprocess provider, then just return its 9372 // info and allow the caller to instantiate it. Only do 9373 // this if the provider is the same user as the caller's 9374 // process, or can run as root (so can be in any process). 9375 return cpr.newHolder(null); 9376 } 9377 9378 if (DEBUG_PROVIDER) { 9379 RuntimeException e = new RuntimeException("here"); 9380 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9381 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9382 } 9383 9384 // This is single process, and our app is now connecting to it. 9385 // See if we are already in the process of launching this 9386 // provider. 9387 final int N = mLaunchingProviders.size(); 9388 int i; 9389 for (i=0; i<N; i++) { 9390 if (mLaunchingProviders.get(i) == cpr) { 9391 break; 9392 } 9393 } 9394 9395 // If the provider is not already being launched, then get it 9396 // started. 9397 if (i >= N) { 9398 final long origId = Binder.clearCallingIdentity(); 9399 9400 try { 9401 // Content provider is now in use, its package can't be stopped. 9402 try { 9403 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9404 AppGlobals.getPackageManager().setPackageStoppedState( 9405 cpr.appInfo.packageName, false, userId); 9406 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9407 } catch (RemoteException e) { 9408 } catch (IllegalArgumentException e) { 9409 Slog.w(TAG, "Failed trying to unstop package " 9410 + cpr.appInfo.packageName + ": " + e); 9411 } 9412 9413 // Use existing process if already started 9414 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9415 ProcessRecord proc = getProcessRecordLocked( 9416 cpi.processName, cpr.appInfo.uid, false); 9417 if (proc != null && proc.thread != null) { 9418 if (DEBUG_PROVIDER) { 9419 Slog.d(TAG, "Installing in existing process " + proc); 9420 } 9421 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9422 proc.pubProviders.put(cpi.name, cpr); 9423 try { 9424 proc.thread.scheduleInstallProvider(cpi); 9425 } catch (RemoteException e) { 9426 } 9427 } else { 9428 checkTime(startTime, "getContentProviderImpl: before start process"); 9429 proc = startProcessLocked(cpi.processName, 9430 cpr.appInfo, false, 0, "content provider", 9431 new ComponentName(cpi.applicationInfo.packageName, 9432 cpi.name), false, false, false); 9433 checkTime(startTime, "getContentProviderImpl: after start process"); 9434 if (proc == null) { 9435 Slog.w(TAG, "Unable to launch app " 9436 + cpi.applicationInfo.packageName + "/" 9437 + cpi.applicationInfo.uid + " for provider " 9438 + name + ": process is bad"); 9439 return null; 9440 } 9441 } 9442 cpr.launchingApp = proc; 9443 mLaunchingProviders.add(cpr); 9444 } finally { 9445 Binder.restoreCallingIdentity(origId); 9446 } 9447 } 9448 9449 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9450 9451 // Make sure the provider is published (the same provider class 9452 // may be published under multiple names). 9453 if (firstClass) { 9454 mProviderMap.putProviderByClass(comp, cpr); 9455 } 9456 9457 mProviderMap.putProviderByName(name, cpr); 9458 conn = incProviderCountLocked(r, cpr, token, stable); 9459 if (conn != null) { 9460 conn.waiting = true; 9461 } 9462 } 9463 checkTime(startTime, "getContentProviderImpl: done!"); 9464 } 9465 9466 // Wait for the provider to be published... 9467 synchronized (cpr) { 9468 while (cpr.provider == null) { 9469 if (cpr.launchingApp == null) { 9470 Slog.w(TAG, "Unable to launch app " 9471 + cpi.applicationInfo.packageName + "/" 9472 + cpi.applicationInfo.uid + " for provider " 9473 + name + ": launching app became null"); 9474 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9475 UserHandle.getUserId(cpi.applicationInfo.uid), 9476 cpi.applicationInfo.packageName, 9477 cpi.applicationInfo.uid, name); 9478 return null; 9479 } 9480 try { 9481 if (DEBUG_MU) { 9482 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9483 + cpr.launchingApp); 9484 } 9485 if (conn != null) { 9486 conn.waiting = true; 9487 } 9488 cpr.wait(); 9489 } catch (InterruptedException ex) { 9490 } finally { 9491 if (conn != null) { 9492 conn.waiting = false; 9493 } 9494 } 9495 } 9496 } 9497 return cpr != null ? cpr.newHolder(conn) : null; 9498 } 9499 9500 @Override 9501 public final ContentProviderHolder getContentProvider( 9502 IApplicationThread caller, String name, int userId, boolean stable) { 9503 enforceNotIsolatedCaller("getContentProvider"); 9504 if (caller == null) { 9505 String msg = "null IApplicationThread when getting content provider " 9506 + name; 9507 Slog.w(TAG, msg); 9508 throw new SecurityException(msg); 9509 } 9510 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9511 // with cross-user grant. 9512 return getContentProviderImpl(caller, name, null, stable, userId); 9513 } 9514 9515 public ContentProviderHolder getContentProviderExternal( 9516 String name, int userId, IBinder token) { 9517 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9518 "Do not have permission in call getContentProviderExternal()"); 9519 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9520 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9521 return getContentProviderExternalUnchecked(name, token, userId); 9522 } 9523 9524 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9525 IBinder token, int userId) { 9526 return getContentProviderImpl(null, name, token, true, userId); 9527 } 9528 9529 /** 9530 * Drop a content provider from a ProcessRecord's bookkeeping 9531 */ 9532 public void removeContentProvider(IBinder connection, boolean stable) { 9533 enforceNotIsolatedCaller("removeContentProvider"); 9534 long ident = Binder.clearCallingIdentity(); 9535 try { 9536 synchronized (this) { 9537 ContentProviderConnection conn; 9538 try { 9539 conn = (ContentProviderConnection)connection; 9540 } catch (ClassCastException e) { 9541 String msg ="removeContentProvider: " + connection 9542 + " not a ContentProviderConnection"; 9543 Slog.w(TAG, msg); 9544 throw new IllegalArgumentException(msg); 9545 } 9546 if (conn == null) { 9547 throw new NullPointerException("connection is null"); 9548 } 9549 if (decProviderCountLocked(conn, null, null, stable)) { 9550 updateOomAdjLocked(); 9551 } 9552 } 9553 } finally { 9554 Binder.restoreCallingIdentity(ident); 9555 } 9556 } 9557 9558 public void removeContentProviderExternal(String name, IBinder token) { 9559 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9560 "Do not have permission in call removeContentProviderExternal()"); 9561 int userId = UserHandle.getCallingUserId(); 9562 long ident = Binder.clearCallingIdentity(); 9563 try { 9564 removeContentProviderExternalUnchecked(name, token, userId); 9565 } finally { 9566 Binder.restoreCallingIdentity(ident); 9567 } 9568 } 9569 9570 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9571 synchronized (this) { 9572 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9573 if(cpr == null) { 9574 //remove from mProvidersByClass 9575 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9576 return; 9577 } 9578 9579 //update content provider record entry info 9580 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9581 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9582 if (localCpr.hasExternalProcessHandles()) { 9583 if (localCpr.removeExternalProcessHandleLocked(token)) { 9584 updateOomAdjLocked(); 9585 } else { 9586 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9587 + " with no external reference for token: " 9588 + token + "."); 9589 } 9590 } else { 9591 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9592 + " with no external references."); 9593 } 9594 } 9595 } 9596 9597 public final void publishContentProviders(IApplicationThread caller, 9598 List<ContentProviderHolder> providers) { 9599 if (providers == null) { 9600 return; 9601 } 9602 9603 enforceNotIsolatedCaller("publishContentProviders"); 9604 synchronized (this) { 9605 final ProcessRecord r = getRecordForAppLocked(caller); 9606 if (DEBUG_MU) 9607 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9608 if (r == null) { 9609 throw new SecurityException( 9610 "Unable to find app for caller " + caller 9611 + " (pid=" + Binder.getCallingPid() 9612 + ") when publishing content providers"); 9613 } 9614 9615 final long origId = Binder.clearCallingIdentity(); 9616 9617 final int N = providers.size(); 9618 for (int i=0; i<N; i++) { 9619 ContentProviderHolder src = providers.get(i); 9620 if (src == null || src.info == null || src.provider == null) { 9621 continue; 9622 } 9623 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9624 if (DEBUG_MU) 9625 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9626 if (dst != null) { 9627 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9628 mProviderMap.putProviderByClass(comp, dst); 9629 String names[] = dst.info.authority.split(";"); 9630 for (int j = 0; j < names.length; j++) { 9631 mProviderMap.putProviderByName(names[j], dst); 9632 } 9633 9634 int NL = mLaunchingProviders.size(); 9635 int j; 9636 for (j=0; j<NL; j++) { 9637 if (mLaunchingProviders.get(j) == dst) { 9638 mLaunchingProviders.remove(j); 9639 j--; 9640 NL--; 9641 } 9642 } 9643 synchronized (dst) { 9644 dst.provider = src.provider; 9645 dst.proc = r; 9646 dst.notifyAll(); 9647 } 9648 updateOomAdjLocked(r); 9649 } 9650 } 9651 9652 Binder.restoreCallingIdentity(origId); 9653 } 9654 } 9655 9656 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9657 ContentProviderConnection conn; 9658 try { 9659 conn = (ContentProviderConnection)connection; 9660 } catch (ClassCastException e) { 9661 String msg ="refContentProvider: " + connection 9662 + " not a ContentProviderConnection"; 9663 Slog.w(TAG, msg); 9664 throw new IllegalArgumentException(msg); 9665 } 9666 if (conn == null) { 9667 throw new NullPointerException("connection is null"); 9668 } 9669 9670 synchronized (this) { 9671 if (stable > 0) { 9672 conn.numStableIncs += stable; 9673 } 9674 stable = conn.stableCount + stable; 9675 if (stable < 0) { 9676 throw new IllegalStateException("stableCount < 0: " + stable); 9677 } 9678 9679 if (unstable > 0) { 9680 conn.numUnstableIncs += unstable; 9681 } 9682 unstable = conn.unstableCount + unstable; 9683 if (unstable < 0) { 9684 throw new IllegalStateException("unstableCount < 0: " + unstable); 9685 } 9686 9687 if ((stable+unstable) <= 0) { 9688 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9689 + stable + " unstable=" + unstable); 9690 } 9691 conn.stableCount = stable; 9692 conn.unstableCount = unstable; 9693 return !conn.dead; 9694 } 9695 } 9696 9697 public void unstableProviderDied(IBinder connection) { 9698 ContentProviderConnection conn; 9699 try { 9700 conn = (ContentProviderConnection)connection; 9701 } catch (ClassCastException e) { 9702 String msg ="refContentProvider: " + connection 9703 + " not a ContentProviderConnection"; 9704 Slog.w(TAG, msg); 9705 throw new IllegalArgumentException(msg); 9706 } 9707 if (conn == null) { 9708 throw new NullPointerException("connection is null"); 9709 } 9710 9711 // Safely retrieve the content provider associated with the connection. 9712 IContentProvider provider; 9713 synchronized (this) { 9714 provider = conn.provider.provider; 9715 } 9716 9717 if (provider == null) { 9718 // Um, yeah, we're way ahead of you. 9719 return; 9720 } 9721 9722 // Make sure the caller is being honest with us. 9723 if (provider.asBinder().pingBinder()) { 9724 // Er, no, still looks good to us. 9725 synchronized (this) { 9726 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9727 + " says " + conn + " died, but we don't agree"); 9728 return; 9729 } 9730 } 9731 9732 // Well look at that! It's dead! 9733 synchronized (this) { 9734 if (conn.provider.provider != provider) { 9735 // But something changed... good enough. 9736 return; 9737 } 9738 9739 ProcessRecord proc = conn.provider.proc; 9740 if (proc == null || proc.thread == null) { 9741 // Seems like the process is already cleaned up. 9742 return; 9743 } 9744 9745 // As far as we're concerned, this is just like receiving a 9746 // death notification... just a bit prematurely. 9747 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9748 + ") early provider death"); 9749 final long ident = Binder.clearCallingIdentity(); 9750 try { 9751 appDiedLocked(proc); 9752 } finally { 9753 Binder.restoreCallingIdentity(ident); 9754 } 9755 } 9756 } 9757 9758 @Override 9759 public void appNotRespondingViaProvider(IBinder connection) { 9760 enforceCallingPermission( 9761 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9762 9763 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9764 if (conn == null) { 9765 Slog.w(TAG, "ContentProviderConnection is null"); 9766 return; 9767 } 9768 9769 final ProcessRecord host = conn.provider.proc; 9770 if (host == null) { 9771 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9772 return; 9773 } 9774 9775 final long token = Binder.clearCallingIdentity(); 9776 try { 9777 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9778 } finally { 9779 Binder.restoreCallingIdentity(token); 9780 } 9781 } 9782 9783 public final void installSystemProviders() { 9784 List<ProviderInfo> providers; 9785 synchronized (this) { 9786 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9787 providers = generateApplicationProvidersLocked(app); 9788 if (providers != null) { 9789 for (int i=providers.size()-1; i>=0; i--) { 9790 ProviderInfo pi = (ProviderInfo)providers.get(i); 9791 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9792 Slog.w(TAG, "Not installing system proc provider " + pi.name 9793 + ": not system .apk"); 9794 providers.remove(i); 9795 } 9796 } 9797 } 9798 } 9799 if (providers != null) { 9800 mSystemThread.installSystemProviders(providers); 9801 } 9802 9803 mCoreSettingsObserver = new CoreSettingsObserver(this); 9804 9805 //mUsageStatsService.monitorPackages(); 9806 } 9807 9808 /** 9809 * Allows apps to retrieve the MIME type of a URI. 9810 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9811 * users, then it does not need permission to access the ContentProvider. 9812 * Either, it needs cross-user uri grants. 9813 * 9814 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9815 * 9816 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9817 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9818 */ 9819 public String getProviderMimeType(Uri uri, int userId) { 9820 enforceNotIsolatedCaller("getProviderMimeType"); 9821 final String name = uri.getAuthority(); 9822 int callingUid = Binder.getCallingUid(); 9823 int callingPid = Binder.getCallingPid(); 9824 long ident = 0; 9825 boolean clearedIdentity = false; 9826 userId = unsafeConvertIncomingUser(userId); 9827 if (canClearIdentity(callingPid, callingUid, userId)) { 9828 clearedIdentity = true; 9829 ident = Binder.clearCallingIdentity(); 9830 } 9831 ContentProviderHolder holder = null; 9832 try { 9833 holder = getContentProviderExternalUnchecked(name, null, userId); 9834 if (holder != null) { 9835 return holder.provider.getType(uri); 9836 } 9837 } catch (RemoteException e) { 9838 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9839 return null; 9840 } finally { 9841 // We need to clear the identity to call removeContentProviderExternalUnchecked 9842 if (!clearedIdentity) { 9843 ident = Binder.clearCallingIdentity(); 9844 } 9845 try { 9846 if (holder != null) { 9847 removeContentProviderExternalUnchecked(name, null, userId); 9848 } 9849 } finally { 9850 Binder.restoreCallingIdentity(ident); 9851 } 9852 } 9853 9854 return null; 9855 } 9856 9857 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9858 if (UserHandle.getUserId(callingUid) == userId) { 9859 return true; 9860 } 9861 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9862 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9863 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9864 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9865 return true; 9866 } 9867 return false; 9868 } 9869 9870 // ========================================================= 9871 // GLOBAL MANAGEMENT 9872 // ========================================================= 9873 9874 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9875 boolean isolated, int isolatedUid) { 9876 String proc = customProcess != null ? customProcess : info.processName; 9877 BatteryStatsImpl.Uid.Proc ps = null; 9878 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9879 int uid = info.uid; 9880 if (isolated) { 9881 if (isolatedUid == 0) { 9882 int userId = UserHandle.getUserId(uid); 9883 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9884 while (true) { 9885 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9886 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9887 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9888 } 9889 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9890 mNextIsolatedProcessUid++; 9891 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9892 // No process for this uid, use it. 9893 break; 9894 } 9895 stepsLeft--; 9896 if (stepsLeft <= 0) { 9897 return null; 9898 } 9899 } 9900 } else { 9901 // Special case for startIsolatedProcess (internal only), where 9902 // the uid of the isolated process is specified by the caller. 9903 uid = isolatedUid; 9904 } 9905 } 9906 return new ProcessRecord(stats, info, proc, uid); 9907 } 9908 9909 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9910 String abiOverride) { 9911 ProcessRecord app; 9912 if (!isolated) { 9913 app = getProcessRecordLocked(info.processName, info.uid, true); 9914 } else { 9915 app = null; 9916 } 9917 9918 if (app == null) { 9919 app = newProcessRecordLocked(info, null, isolated, 0); 9920 mProcessNames.put(info.processName, app.uid, app); 9921 if (isolated) { 9922 mIsolatedProcesses.put(app.uid, app); 9923 } 9924 updateLruProcessLocked(app, false, null); 9925 updateOomAdjLocked(); 9926 } 9927 9928 // This package really, really can not be stopped. 9929 try { 9930 AppGlobals.getPackageManager().setPackageStoppedState( 9931 info.packageName, false, UserHandle.getUserId(app.uid)); 9932 } catch (RemoteException e) { 9933 } catch (IllegalArgumentException e) { 9934 Slog.w(TAG, "Failed trying to unstop package " 9935 + info.packageName + ": " + e); 9936 } 9937 9938 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9939 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9940 app.persistent = true; 9941 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9942 } 9943 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9944 mPersistentStartingProcesses.add(app); 9945 startProcessLocked(app, "added application", app.processName, abiOverride, 9946 null /* entryPoint */, null /* entryPointArgs */); 9947 } 9948 9949 return app; 9950 } 9951 9952 public void unhandledBack() { 9953 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9954 "unhandledBack()"); 9955 9956 synchronized(this) { 9957 final long origId = Binder.clearCallingIdentity(); 9958 try { 9959 getFocusedStack().unhandledBackLocked(); 9960 } finally { 9961 Binder.restoreCallingIdentity(origId); 9962 } 9963 } 9964 } 9965 9966 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9967 enforceNotIsolatedCaller("openContentUri"); 9968 final int userId = UserHandle.getCallingUserId(); 9969 String name = uri.getAuthority(); 9970 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9971 ParcelFileDescriptor pfd = null; 9972 if (cph != null) { 9973 // We record the binder invoker's uid in thread-local storage before 9974 // going to the content provider to open the file. Later, in the code 9975 // that handles all permissions checks, we look for this uid and use 9976 // that rather than the Activity Manager's own uid. The effect is that 9977 // we do the check against the caller's permissions even though it looks 9978 // to the content provider like the Activity Manager itself is making 9979 // the request. 9980 Binder token = new Binder(); 9981 sCallerIdentity.set(new Identity( 9982 token, Binder.getCallingPid(), Binder.getCallingUid())); 9983 try { 9984 pfd = cph.provider.openFile(null, uri, "r", null, token); 9985 } catch (FileNotFoundException e) { 9986 // do nothing; pfd will be returned null 9987 } finally { 9988 // Ensure that whatever happens, we clean up the identity state 9989 sCallerIdentity.remove(); 9990 } 9991 9992 // We've got the fd now, so we're done with the provider. 9993 removeContentProviderExternalUnchecked(name, null, userId); 9994 } else { 9995 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9996 } 9997 return pfd; 9998 } 9999 10000 // Actually is sleeping or shutting down or whatever else in the future 10001 // is an inactive state. 10002 public boolean isSleepingOrShuttingDown() { 10003 return isSleeping() || mShuttingDown; 10004 } 10005 10006 public boolean isSleeping() { 10007 return mSleeping; 10008 } 10009 10010 void onWakefulnessChanged(int wakefulness) { 10011 synchronized(this) { 10012 mWakefulness = wakefulness; 10013 updateSleepIfNeededLocked(); 10014 } 10015 } 10016 10017 void finishRunningVoiceLocked() { 10018 if (mRunningVoice) { 10019 mRunningVoice = false; 10020 updateSleepIfNeededLocked(); 10021 } 10022 } 10023 10024 void updateSleepIfNeededLocked() { 10025 if (mSleeping && !shouldSleepLocked()) { 10026 mSleeping = false; 10027 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10028 } else if (!mSleeping && shouldSleepLocked()) { 10029 mSleeping = true; 10030 mStackSupervisor.goingToSleepLocked(); 10031 10032 // Initialize the wake times of all processes. 10033 checkExcessivePowerUsageLocked(false); 10034 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10035 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10036 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10037 } 10038 } 10039 10040 private boolean shouldSleepLocked() { 10041 // Resume applications while running a voice interactor. 10042 if (mRunningVoice) { 10043 return false; 10044 } 10045 10046 switch (mWakefulness) { 10047 case PowerManagerInternal.WAKEFULNESS_AWAKE: 10048 case PowerManagerInternal.WAKEFULNESS_DREAMING: 10049 // If we're interactive but applications are already paused then defer 10050 // resuming them until the lock screen is hidden. 10051 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN; 10052 case PowerManagerInternal.WAKEFULNESS_DOZING: 10053 // If we're dozing then pause applications whenever the lock screen is shown. 10054 return mLockScreenShown != LOCK_SCREEN_HIDDEN; 10055 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 10056 default: 10057 // If we're asleep then pause applications unconditionally. 10058 return true; 10059 } 10060 } 10061 10062 /** Pokes the task persister. */ 10063 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10064 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10065 // Never persist the home stack. 10066 return; 10067 } 10068 mTaskPersister.wakeup(task, flush); 10069 } 10070 10071 /** Notifies all listeners when the task stack has changed. */ 10072 void notifyTaskStackChangedLocked() { 10073 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10074 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG); 10075 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY); 10076 } 10077 10078 @Override 10079 public boolean shutdown(int timeout) { 10080 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10081 != PackageManager.PERMISSION_GRANTED) { 10082 throw new SecurityException("Requires permission " 10083 + android.Manifest.permission.SHUTDOWN); 10084 } 10085 10086 boolean timedout = false; 10087 10088 synchronized(this) { 10089 mShuttingDown = true; 10090 updateEventDispatchingLocked(); 10091 timedout = mStackSupervisor.shutdownLocked(timeout); 10092 } 10093 10094 mAppOpsService.shutdown(); 10095 if (mUsageStatsService != null) { 10096 mUsageStatsService.prepareShutdown(); 10097 } 10098 mBatteryStatsService.shutdown(); 10099 synchronized (this) { 10100 mProcessStats.shutdownLocked(); 10101 notifyTaskPersisterLocked(null, true); 10102 } 10103 10104 return timedout; 10105 } 10106 10107 public final void activitySlept(IBinder token) { 10108 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10109 10110 final long origId = Binder.clearCallingIdentity(); 10111 10112 synchronized (this) { 10113 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10114 if (r != null) { 10115 mStackSupervisor.activitySleptLocked(r); 10116 } 10117 } 10118 10119 Binder.restoreCallingIdentity(origId); 10120 } 10121 10122 private String lockScreenShownToString() { 10123 switch (mLockScreenShown) { 10124 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; 10125 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING"; 10126 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN"; 10127 default: return "Unknown=" + mLockScreenShown; 10128 } 10129 } 10130 10131 void logLockScreen(String msg) { 10132 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg 10133 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness=" 10134 + PowerManagerInternal.wakefulnessToString(mWakefulness) 10135 + " mSleeping=" + mSleeping); 10136 } 10137 10138 void startRunningVoiceLocked() { 10139 if (!mRunningVoice) { 10140 mRunningVoice = true; 10141 updateSleepIfNeededLocked(); 10142 } 10143 } 10144 10145 private void updateEventDispatchingLocked() { 10146 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10147 } 10148 10149 public void setLockScreenShown(boolean shown) { 10150 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10151 != PackageManager.PERMISSION_GRANTED) { 10152 throw new SecurityException("Requires permission " 10153 + android.Manifest.permission.DEVICE_POWER); 10154 } 10155 10156 synchronized(this) { 10157 long ident = Binder.clearCallingIdentity(); 10158 try { 10159 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10160 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN; 10161 updateSleepIfNeededLocked(); 10162 } finally { 10163 Binder.restoreCallingIdentity(ident); 10164 } 10165 } 10166 } 10167 10168 @Override 10169 public void stopAppSwitches() { 10170 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10171 != PackageManager.PERMISSION_GRANTED) { 10172 throw new SecurityException("Requires permission " 10173 + android.Manifest.permission.STOP_APP_SWITCHES); 10174 } 10175 10176 synchronized(this) { 10177 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10178 + APP_SWITCH_DELAY_TIME; 10179 mDidAppSwitch = false; 10180 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10181 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10182 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10183 } 10184 } 10185 10186 public void resumeAppSwitches() { 10187 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10188 != PackageManager.PERMISSION_GRANTED) { 10189 throw new SecurityException("Requires permission " 10190 + android.Manifest.permission.STOP_APP_SWITCHES); 10191 } 10192 10193 synchronized(this) { 10194 // Note that we don't execute any pending app switches... we will 10195 // let those wait until either the timeout, or the next start 10196 // activity request. 10197 mAppSwitchesAllowedTime = 0; 10198 } 10199 } 10200 10201 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10202 int callingPid, int callingUid, String name) { 10203 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10204 return true; 10205 } 10206 10207 int perm = checkComponentPermission( 10208 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10209 sourceUid, -1, true); 10210 if (perm == PackageManager.PERMISSION_GRANTED) { 10211 return true; 10212 } 10213 10214 // If the actual IPC caller is different from the logical source, then 10215 // also see if they are allowed to control app switches. 10216 if (callingUid != -1 && callingUid != sourceUid) { 10217 perm = checkComponentPermission( 10218 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10219 callingUid, -1, true); 10220 if (perm == PackageManager.PERMISSION_GRANTED) { 10221 return true; 10222 } 10223 } 10224 10225 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10226 return false; 10227 } 10228 10229 public void setDebugApp(String packageName, boolean waitForDebugger, 10230 boolean persistent) { 10231 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10232 "setDebugApp()"); 10233 10234 long ident = Binder.clearCallingIdentity(); 10235 try { 10236 // Note that this is not really thread safe if there are multiple 10237 // callers into it at the same time, but that's not a situation we 10238 // care about. 10239 if (persistent) { 10240 final ContentResolver resolver = mContext.getContentResolver(); 10241 Settings.Global.putString( 10242 resolver, Settings.Global.DEBUG_APP, 10243 packageName); 10244 Settings.Global.putInt( 10245 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10246 waitForDebugger ? 1 : 0); 10247 } 10248 10249 synchronized (this) { 10250 if (!persistent) { 10251 mOrigDebugApp = mDebugApp; 10252 mOrigWaitForDebugger = mWaitForDebugger; 10253 } 10254 mDebugApp = packageName; 10255 mWaitForDebugger = waitForDebugger; 10256 mDebugTransient = !persistent; 10257 if (packageName != null) { 10258 forceStopPackageLocked(packageName, -1, false, false, true, true, 10259 false, UserHandle.USER_ALL, "set debug app"); 10260 } 10261 } 10262 } finally { 10263 Binder.restoreCallingIdentity(ident); 10264 } 10265 } 10266 10267 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10268 synchronized (this) { 10269 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10270 if (!isDebuggable) { 10271 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10272 throw new SecurityException("Process not debuggable: " + app.packageName); 10273 } 10274 } 10275 10276 mOpenGlTraceApp = processName; 10277 } 10278 } 10279 10280 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10281 synchronized (this) { 10282 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10283 if (!isDebuggable) { 10284 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10285 throw new SecurityException("Process not debuggable: " + app.packageName); 10286 } 10287 } 10288 mProfileApp = processName; 10289 mProfileFile = profilerInfo.profileFile; 10290 if (mProfileFd != null) { 10291 try { 10292 mProfileFd.close(); 10293 } catch (IOException e) { 10294 } 10295 mProfileFd = null; 10296 } 10297 mProfileFd = profilerInfo.profileFd; 10298 mSamplingInterval = profilerInfo.samplingInterval; 10299 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10300 mProfileType = 0; 10301 } 10302 } 10303 10304 @Override 10305 public void setAlwaysFinish(boolean enabled) { 10306 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10307 "setAlwaysFinish()"); 10308 10309 Settings.Global.putInt( 10310 mContext.getContentResolver(), 10311 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10312 10313 synchronized (this) { 10314 mAlwaysFinishActivities = enabled; 10315 } 10316 } 10317 10318 @Override 10319 public void setActivityController(IActivityController controller) { 10320 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10321 "setActivityController()"); 10322 synchronized (this) { 10323 mController = controller; 10324 Watchdog.getInstance().setActivityController(controller); 10325 } 10326 } 10327 10328 @Override 10329 public void setUserIsMonkey(boolean userIsMonkey) { 10330 synchronized (this) { 10331 synchronized (mPidsSelfLocked) { 10332 final int callingPid = Binder.getCallingPid(); 10333 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10334 if (precessRecord == null) { 10335 throw new SecurityException("Unknown process: " + callingPid); 10336 } 10337 if (precessRecord.instrumentationUiAutomationConnection == null) { 10338 throw new SecurityException("Only an instrumentation process " 10339 + "with a UiAutomation can call setUserIsMonkey"); 10340 } 10341 } 10342 mUserIsMonkey = userIsMonkey; 10343 } 10344 } 10345 10346 @Override 10347 public boolean isUserAMonkey() { 10348 synchronized (this) { 10349 // If there is a controller also implies the user is a monkey. 10350 return (mUserIsMonkey || mController != null); 10351 } 10352 } 10353 10354 public void requestBugReport() { 10355 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10356 SystemProperties.set("ctl.start", "bugreport"); 10357 } 10358 10359 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10360 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10361 } 10362 10363 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10364 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10365 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10366 } 10367 return KEY_DISPATCHING_TIMEOUT; 10368 } 10369 10370 @Override 10371 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10372 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10373 != PackageManager.PERMISSION_GRANTED) { 10374 throw new SecurityException("Requires permission " 10375 + android.Manifest.permission.FILTER_EVENTS); 10376 } 10377 ProcessRecord proc; 10378 long timeout; 10379 synchronized (this) { 10380 synchronized (mPidsSelfLocked) { 10381 proc = mPidsSelfLocked.get(pid); 10382 } 10383 timeout = getInputDispatchingTimeoutLocked(proc); 10384 } 10385 10386 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10387 return -1; 10388 } 10389 10390 return timeout; 10391 } 10392 10393 /** 10394 * Handle input dispatching timeouts. 10395 * Returns whether input dispatching should be aborted or not. 10396 */ 10397 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10398 final ActivityRecord activity, final ActivityRecord parent, 10399 final boolean aboveSystem, String reason) { 10400 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10401 != PackageManager.PERMISSION_GRANTED) { 10402 throw new SecurityException("Requires permission " 10403 + android.Manifest.permission.FILTER_EVENTS); 10404 } 10405 10406 final String annotation; 10407 if (reason == null) { 10408 annotation = "Input dispatching timed out"; 10409 } else { 10410 annotation = "Input dispatching timed out (" + reason + ")"; 10411 } 10412 10413 if (proc != null) { 10414 synchronized (this) { 10415 if (proc.debugging) { 10416 return false; 10417 } 10418 10419 if (mDidDexOpt) { 10420 // Give more time since we were dexopting. 10421 mDidDexOpt = false; 10422 return false; 10423 } 10424 10425 if (proc.instrumentationClass != null) { 10426 Bundle info = new Bundle(); 10427 info.putString("shortMsg", "keyDispatchingTimedOut"); 10428 info.putString("longMsg", annotation); 10429 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10430 return true; 10431 } 10432 } 10433 mHandler.post(new Runnable() { 10434 @Override 10435 public void run() { 10436 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10437 } 10438 }); 10439 } 10440 10441 return true; 10442 } 10443 10444 public Bundle getAssistContextExtras(int requestType) { 10445 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10446 UserHandle.getCallingUserId()); 10447 if (pae == null) { 10448 return null; 10449 } 10450 synchronized (pae) { 10451 while (!pae.haveResult) { 10452 try { 10453 pae.wait(); 10454 } catch (InterruptedException e) { 10455 } 10456 } 10457 if (pae.result != null) { 10458 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10459 } 10460 } 10461 synchronized (this) { 10462 mPendingAssistExtras.remove(pae); 10463 mHandler.removeCallbacks(pae); 10464 } 10465 return pae.extras; 10466 } 10467 10468 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10469 int userHandle) { 10470 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10471 "getAssistContextExtras()"); 10472 PendingAssistExtras pae; 10473 Bundle extras = new Bundle(); 10474 synchronized (this) { 10475 ActivityRecord activity = getFocusedStack().mResumedActivity; 10476 if (activity == null) { 10477 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10478 return null; 10479 } 10480 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10481 if (activity.app == null || activity.app.thread == null) { 10482 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10483 return null; 10484 } 10485 if (activity.app.pid == Binder.getCallingPid()) { 10486 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10487 return null; 10488 } 10489 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10490 try { 10491 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10492 requestType); 10493 mPendingAssistExtras.add(pae); 10494 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10495 } catch (RemoteException e) { 10496 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10497 return null; 10498 } 10499 return pae; 10500 } 10501 } 10502 10503 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10504 PendingAssistExtras pae = (PendingAssistExtras)token; 10505 synchronized (pae) { 10506 pae.result = extras; 10507 pae.haveResult = true; 10508 pae.notifyAll(); 10509 if (pae.intent == null) { 10510 // Caller is just waiting for the result. 10511 return; 10512 } 10513 } 10514 10515 // We are now ready to launch the assist activity. 10516 synchronized (this) { 10517 boolean exists = mPendingAssistExtras.remove(pae); 10518 mHandler.removeCallbacks(pae); 10519 if (!exists) { 10520 // Timed out. 10521 return; 10522 } 10523 } 10524 pae.intent.replaceExtras(extras); 10525 if (pae.hint != null) { 10526 pae.intent.putExtra(pae.hint, true); 10527 } 10528 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10529 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10530 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10531 closeSystemDialogs("assist"); 10532 try { 10533 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10534 } catch (ActivityNotFoundException e) { 10535 Slog.w(TAG, "No activity to handle assist action.", e); 10536 } 10537 } 10538 10539 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10540 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10541 } 10542 10543 public void registerProcessObserver(IProcessObserver observer) { 10544 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10545 "registerProcessObserver()"); 10546 synchronized (this) { 10547 mProcessObservers.register(observer); 10548 } 10549 } 10550 10551 @Override 10552 public void unregisterProcessObserver(IProcessObserver observer) { 10553 synchronized (this) { 10554 mProcessObservers.unregister(observer); 10555 } 10556 } 10557 10558 @Override 10559 public boolean convertFromTranslucent(IBinder token) { 10560 final long origId = Binder.clearCallingIdentity(); 10561 try { 10562 synchronized (this) { 10563 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10564 if (r == null) { 10565 return false; 10566 } 10567 final boolean translucentChanged = r.changeWindowTranslucency(true); 10568 if (translucentChanged) { 10569 r.task.stack.releaseBackgroundResources(); 10570 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10571 } 10572 mWindowManager.setAppFullscreen(token, true); 10573 return translucentChanged; 10574 } 10575 } finally { 10576 Binder.restoreCallingIdentity(origId); 10577 } 10578 } 10579 10580 @Override 10581 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10582 final long origId = Binder.clearCallingIdentity(); 10583 try { 10584 synchronized (this) { 10585 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10586 if (r == null) { 10587 return false; 10588 } 10589 int index = r.task.mActivities.lastIndexOf(r); 10590 if (index > 0) { 10591 ActivityRecord under = r.task.mActivities.get(index - 1); 10592 under.returningOptions = options; 10593 } 10594 final boolean translucentChanged = r.changeWindowTranslucency(false); 10595 if (translucentChanged) { 10596 r.task.stack.convertToTranslucent(r); 10597 } 10598 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10599 mWindowManager.setAppFullscreen(token, false); 10600 return translucentChanged; 10601 } 10602 } finally { 10603 Binder.restoreCallingIdentity(origId); 10604 } 10605 } 10606 10607 @Override 10608 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10609 final long origId = Binder.clearCallingIdentity(); 10610 try { 10611 synchronized (this) { 10612 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10613 if (r != null) { 10614 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10615 } 10616 } 10617 return false; 10618 } finally { 10619 Binder.restoreCallingIdentity(origId); 10620 } 10621 } 10622 10623 @Override 10624 public boolean isBackgroundVisibleBehind(IBinder token) { 10625 final long origId = Binder.clearCallingIdentity(); 10626 try { 10627 synchronized (this) { 10628 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10629 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10630 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10631 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10632 return visible; 10633 } 10634 } finally { 10635 Binder.restoreCallingIdentity(origId); 10636 } 10637 } 10638 10639 @Override 10640 public ActivityOptions getActivityOptions(IBinder token) { 10641 final long origId = Binder.clearCallingIdentity(); 10642 try { 10643 synchronized (this) { 10644 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10645 if (r != null) { 10646 final ActivityOptions activityOptions = r.pendingOptions; 10647 r.pendingOptions = null; 10648 return activityOptions; 10649 } 10650 return null; 10651 } 10652 } finally { 10653 Binder.restoreCallingIdentity(origId); 10654 } 10655 } 10656 10657 @Override 10658 public void setImmersive(IBinder token, boolean immersive) { 10659 synchronized(this) { 10660 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10661 if (r == null) { 10662 throw new IllegalArgumentException(); 10663 } 10664 r.immersive = immersive; 10665 10666 // update associated state if we're frontmost 10667 if (r == mFocusedActivity) { 10668 if (DEBUG_IMMERSIVE) { 10669 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10670 } 10671 applyUpdateLockStateLocked(r); 10672 } 10673 } 10674 } 10675 10676 @Override 10677 public boolean isImmersive(IBinder token) { 10678 synchronized (this) { 10679 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10680 if (r == null) { 10681 throw new IllegalArgumentException(); 10682 } 10683 return r.immersive; 10684 } 10685 } 10686 10687 public boolean isTopActivityImmersive() { 10688 enforceNotIsolatedCaller("startActivity"); 10689 synchronized (this) { 10690 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10691 return (r != null) ? r.immersive : false; 10692 } 10693 } 10694 10695 @Override 10696 public boolean isTopOfTask(IBinder token) { 10697 synchronized (this) { 10698 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10699 if (r == null) { 10700 throw new IllegalArgumentException(); 10701 } 10702 return r.task.getTopActivity() == r; 10703 } 10704 } 10705 10706 public final void enterSafeMode() { 10707 synchronized(this) { 10708 // It only makes sense to do this before the system is ready 10709 // and started launching other packages. 10710 if (!mSystemReady) { 10711 try { 10712 AppGlobals.getPackageManager().enterSafeMode(); 10713 } catch (RemoteException e) { 10714 } 10715 } 10716 10717 mSafeMode = true; 10718 } 10719 } 10720 10721 public final void showSafeModeOverlay() { 10722 View v = LayoutInflater.from(mContext).inflate( 10723 com.android.internal.R.layout.safe_mode, null); 10724 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10725 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10726 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10727 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10728 lp.gravity = Gravity.BOTTOM | Gravity.START; 10729 lp.format = v.getBackground().getOpacity(); 10730 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10731 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10732 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10733 ((WindowManager)mContext.getSystemService( 10734 Context.WINDOW_SERVICE)).addView(v, lp); 10735 } 10736 10737 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10738 if (!(sender instanceof PendingIntentRecord)) { 10739 return; 10740 } 10741 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10742 synchronized (stats) { 10743 if (mBatteryStatsService.isOnBattery()) { 10744 mBatteryStatsService.enforceCallingPermission(); 10745 PendingIntentRecord rec = (PendingIntentRecord)sender; 10746 int MY_UID = Binder.getCallingUid(); 10747 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10748 BatteryStatsImpl.Uid.Pkg pkg = 10749 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10750 sourcePkg != null ? sourcePkg : rec.key.packageName); 10751 pkg.incWakeupsLocked(); 10752 } 10753 } 10754 } 10755 10756 public boolean killPids(int[] pids, String pReason, boolean secure) { 10757 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10758 throw new SecurityException("killPids only available to the system"); 10759 } 10760 String reason = (pReason == null) ? "Unknown" : pReason; 10761 // XXX Note: don't acquire main activity lock here, because the window 10762 // manager calls in with its locks held. 10763 10764 boolean killed = false; 10765 synchronized (mPidsSelfLocked) { 10766 int[] types = new int[pids.length]; 10767 int worstType = 0; 10768 for (int i=0; i<pids.length; i++) { 10769 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10770 if (proc != null) { 10771 int type = proc.setAdj; 10772 types[i] = type; 10773 if (type > worstType) { 10774 worstType = type; 10775 } 10776 } 10777 } 10778 10779 // If the worst oom_adj is somewhere in the cached proc LRU range, 10780 // then constrain it so we will kill all cached procs. 10781 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10782 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10783 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10784 } 10785 10786 // If this is not a secure call, don't let it kill processes that 10787 // are important. 10788 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10789 worstType = ProcessList.SERVICE_ADJ; 10790 } 10791 10792 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10793 for (int i=0; i<pids.length; i++) { 10794 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10795 if (proc == null) { 10796 continue; 10797 } 10798 int adj = proc.setAdj; 10799 if (adj >= worstType && !proc.killedByAm) { 10800 proc.kill(reason, true); 10801 killed = true; 10802 } 10803 } 10804 } 10805 return killed; 10806 } 10807 10808 @Override 10809 public void killUid(int uid, String reason) { 10810 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10811 throw new SecurityException("killUid only available to the system"); 10812 } 10813 synchronized (this) { 10814 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10815 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10816 reason != null ? reason : "kill uid"); 10817 } 10818 } 10819 10820 @Override 10821 public boolean killProcessesBelowForeground(String reason) { 10822 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10823 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10824 } 10825 10826 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10827 } 10828 10829 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10830 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10831 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10832 } 10833 10834 boolean killed = false; 10835 synchronized (mPidsSelfLocked) { 10836 final int size = mPidsSelfLocked.size(); 10837 for (int i = 0; i < size; i++) { 10838 final int pid = mPidsSelfLocked.keyAt(i); 10839 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10840 if (proc == null) continue; 10841 10842 final int adj = proc.setAdj; 10843 if (adj > belowAdj && !proc.killedByAm) { 10844 proc.kill(reason, true); 10845 killed = true; 10846 } 10847 } 10848 } 10849 return killed; 10850 } 10851 10852 @Override 10853 public void hang(final IBinder who, boolean allowRestart) { 10854 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10855 != PackageManager.PERMISSION_GRANTED) { 10856 throw new SecurityException("Requires permission " 10857 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10858 } 10859 10860 final IBinder.DeathRecipient death = new DeathRecipient() { 10861 @Override 10862 public void binderDied() { 10863 synchronized (this) { 10864 notifyAll(); 10865 } 10866 } 10867 }; 10868 10869 try { 10870 who.linkToDeath(death, 0); 10871 } catch (RemoteException e) { 10872 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10873 return; 10874 } 10875 10876 synchronized (this) { 10877 Watchdog.getInstance().setAllowRestart(allowRestart); 10878 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10879 synchronized (death) { 10880 while (who.isBinderAlive()) { 10881 try { 10882 death.wait(); 10883 } catch (InterruptedException e) { 10884 } 10885 } 10886 } 10887 Watchdog.getInstance().setAllowRestart(true); 10888 } 10889 } 10890 10891 @Override 10892 public void restart() { 10893 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10894 != PackageManager.PERMISSION_GRANTED) { 10895 throw new SecurityException("Requires permission " 10896 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10897 } 10898 10899 Log.i(TAG, "Sending shutdown broadcast..."); 10900 10901 BroadcastReceiver br = new BroadcastReceiver() { 10902 @Override public void onReceive(Context context, Intent intent) { 10903 // Now the broadcast is done, finish up the low-level shutdown. 10904 Log.i(TAG, "Shutting down activity manager..."); 10905 shutdown(10000); 10906 Log.i(TAG, "Shutdown complete, restarting!"); 10907 Process.killProcess(Process.myPid()); 10908 System.exit(10); 10909 } 10910 }; 10911 10912 // First send the high-level shut down broadcast. 10913 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10914 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10915 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10916 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10917 mContext.sendOrderedBroadcastAsUser(intent, 10918 UserHandle.ALL, null, br, mHandler, 0, null, null); 10919 */ 10920 br.onReceive(mContext, intent); 10921 } 10922 10923 private long getLowRamTimeSinceIdle(long now) { 10924 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10925 } 10926 10927 @Override 10928 public void performIdleMaintenance() { 10929 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10930 != PackageManager.PERMISSION_GRANTED) { 10931 throw new SecurityException("Requires permission " 10932 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10933 } 10934 10935 synchronized (this) { 10936 final long now = SystemClock.uptimeMillis(); 10937 final long timeSinceLastIdle = now - mLastIdleTime; 10938 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10939 mLastIdleTime = now; 10940 mLowRamTimeSinceLastIdle = 0; 10941 if (mLowRamStartTime != 0) { 10942 mLowRamStartTime = now; 10943 } 10944 10945 StringBuilder sb = new StringBuilder(128); 10946 sb.append("Idle maintenance over "); 10947 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10948 sb.append(" low RAM for "); 10949 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10950 Slog.i(TAG, sb.toString()); 10951 10952 // If at least 1/3 of our time since the last idle period has been spent 10953 // with RAM low, then we want to kill processes. 10954 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10955 10956 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10957 ProcessRecord proc = mLruProcesses.get(i); 10958 if (proc.notCachedSinceIdle) { 10959 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10960 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10961 if (doKilling && proc.initialIdlePss != 0 10962 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10963 sb = new StringBuilder(128); 10964 sb.append("Kill"); 10965 sb.append(proc.processName); 10966 sb.append(" in idle maint: pss="); 10967 sb.append(proc.lastPss); 10968 sb.append(", initialPss="); 10969 sb.append(proc.initialIdlePss); 10970 sb.append(", period="); 10971 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10972 sb.append(", lowRamPeriod="); 10973 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10974 Slog.wtfQuiet(TAG, sb.toString()); 10975 proc.kill("idle maint (pss " + proc.lastPss 10976 + " from " + proc.initialIdlePss + ")", true); 10977 } 10978 } 10979 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10980 proc.notCachedSinceIdle = true; 10981 proc.initialIdlePss = 0; 10982 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10983 mTestPssMode, isSleeping(), now); 10984 } 10985 } 10986 10987 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10988 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10989 } 10990 } 10991 10992 private void retrieveSettings() { 10993 final ContentResolver resolver = mContext.getContentResolver(); 10994 String debugApp = Settings.Global.getString( 10995 resolver, Settings.Global.DEBUG_APP); 10996 boolean waitForDebugger = Settings.Global.getInt( 10997 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10998 boolean alwaysFinishActivities = Settings.Global.getInt( 10999 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11000 boolean forceRtl = Settings.Global.getInt( 11001 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11002 // Transfer any global setting for forcing RTL layout, into a System Property 11003 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11004 11005 Configuration configuration = new Configuration(); 11006 Settings.System.getConfiguration(resolver, configuration); 11007 if (forceRtl) { 11008 // This will take care of setting the correct layout direction flags 11009 configuration.setLayoutDirection(configuration.locale); 11010 } 11011 11012 synchronized (this) { 11013 mDebugApp = mOrigDebugApp = debugApp; 11014 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11015 mAlwaysFinishActivities = alwaysFinishActivities; 11016 // This happens before any activities are started, so we can 11017 // change mConfiguration in-place. 11018 updateConfigurationLocked(configuration, null, false, true); 11019 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11020 } 11021 } 11022 11023 /** Loads resources after the current configuration has been set. */ 11024 private void loadResourcesOnSystemReady() { 11025 final Resources res = mContext.getResources(); 11026 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11027 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11028 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11029 } 11030 11031 public boolean testIsSystemReady() { 11032 // no need to synchronize(this) just to read & return the value 11033 return mSystemReady; 11034 } 11035 11036 private static File getCalledPreBootReceiversFile() { 11037 File dataDir = Environment.getDataDirectory(); 11038 File systemDir = new File(dataDir, "system"); 11039 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11040 return fname; 11041 } 11042 11043 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11044 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11045 File file = getCalledPreBootReceiversFile(); 11046 FileInputStream fis = null; 11047 try { 11048 fis = new FileInputStream(file); 11049 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11050 int fvers = dis.readInt(); 11051 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11052 String vers = dis.readUTF(); 11053 String codename = dis.readUTF(); 11054 String build = dis.readUTF(); 11055 if (android.os.Build.VERSION.RELEASE.equals(vers) 11056 && android.os.Build.VERSION.CODENAME.equals(codename) 11057 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11058 int num = dis.readInt(); 11059 while (num > 0) { 11060 num--; 11061 String pkg = dis.readUTF(); 11062 String cls = dis.readUTF(); 11063 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11064 } 11065 } 11066 } 11067 } catch (FileNotFoundException e) { 11068 } catch (IOException e) { 11069 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11070 } finally { 11071 if (fis != null) { 11072 try { 11073 fis.close(); 11074 } catch (IOException e) { 11075 } 11076 } 11077 } 11078 return lastDoneReceivers; 11079 } 11080 11081 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11082 File file = getCalledPreBootReceiversFile(); 11083 FileOutputStream fos = null; 11084 DataOutputStream dos = null; 11085 try { 11086 fos = new FileOutputStream(file); 11087 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11088 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11089 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11090 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11091 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11092 dos.writeInt(list.size()); 11093 for (int i=0; i<list.size(); i++) { 11094 dos.writeUTF(list.get(i).getPackageName()); 11095 dos.writeUTF(list.get(i).getClassName()); 11096 } 11097 } catch (IOException e) { 11098 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11099 file.delete(); 11100 } finally { 11101 FileUtils.sync(fos); 11102 if (dos != null) { 11103 try { 11104 dos.close(); 11105 } catch (IOException e) { 11106 // TODO Auto-generated catch block 11107 e.printStackTrace(); 11108 } 11109 } 11110 } 11111 } 11112 11113 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11114 ArrayList<ComponentName> doneReceivers, int userId) { 11115 boolean waitingUpdate = false; 11116 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11117 List<ResolveInfo> ris = null; 11118 try { 11119 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11120 intent, null, 0, userId); 11121 } catch (RemoteException e) { 11122 } 11123 if (ris != null) { 11124 for (int i=ris.size()-1; i>=0; i--) { 11125 if ((ris.get(i).activityInfo.applicationInfo.flags 11126 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11127 ris.remove(i); 11128 } 11129 } 11130 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11131 11132 // For User 0, load the version number. When delivering to a new user, deliver 11133 // to all receivers. 11134 if (userId == UserHandle.USER_OWNER) { 11135 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11136 for (int i=0; i<ris.size(); i++) { 11137 ActivityInfo ai = ris.get(i).activityInfo; 11138 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11139 if (lastDoneReceivers.contains(comp)) { 11140 // We already did the pre boot receiver for this app with the current 11141 // platform version, so don't do it again... 11142 ris.remove(i); 11143 i--; 11144 // ...however, do keep it as one that has been done, so we don't 11145 // forget about it when rewriting the file of last done receivers. 11146 doneReceivers.add(comp); 11147 } 11148 } 11149 } 11150 11151 // If primary user, send broadcast to all available users, else just to userId 11152 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11153 : new int[] { userId }; 11154 for (int i = 0; i < ris.size(); i++) { 11155 ActivityInfo ai = ris.get(i).activityInfo; 11156 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11157 doneReceivers.add(comp); 11158 intent.setComponent(comp); 11159 for (int j=0; j<users.length; j++) { 11160 IIntentReceiver finisher = null; 11161 // On last receiver and user, set up a completion callback 11162 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11163 finisher = new IIntentReceiver.Stub() { 11164 public void performReceive(Intent intent, int resultCode, 11165 String data, Bundle extras, boolean ordered, 11166 boolean sticky, int sendingUser) { 11167 // The raw IIntentReceiver interface is called 11168 // with the AM lock held, so redispatch to 11169 // execute our code without the lock. 11170 mHandler.post(onFinishCallback); 11171 } 11172 }; 11173 } 11174 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11175 + " for user " + users[j]); 11176 broadcastIntentLocked(null, null, intent, null, finisher, 11177 0, null, null, null, AppOpsManager.OP_NONE, 11178 true, false, MY_PID, Process.SYSTEM_UID, 11179 users[j]); 11180 if (finisher != null) { 11181 waitingUpdate = true; 11182 } 11183 } 11184 } 11185 } 11186 11187 return waitingUpdate; 11188 } 11189 11190 public void systemReady(final Runnable goingCallback) { 11191 synchronized(this) { 11192 if (mSystemReady) { 11193 // If we're done calling all the receivers, run the next "boot phase" passed in 11194 // by the SystemServer 11195 if (goingCallback != null) { 11196 goingCallback.run(); 11197 } 11198 return; 11199 } 11200 11201 // Make sure we have the current profile info, since it is needed for 11202 // security checks. 11203 updateCurrentProfileIdsLocked(); 11204 11205 if (mRecentTasks == null) { 11206 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11207 mTaskPersister.restoreTasksFromOtherDeviceLocked(); 11208 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11209 mTaskPersister.startPersisting(); 11210 } 11211 11212 // Check to see if there are any update receivers to run. 11213 if (!mDidUpdate) { 11214 if (mWaitingUpdate) { 11215 return; 11216 } 11217 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11218 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11219 public void run() { 11220 synchronized (ActivityManagerService.this) { 11221 mDidUpdate = true; 11222 } 11223 writeLastDonePreBootReceivers(doneReceivers); 11224 showBootMessage(mContext.getText(R.string.android_upgrading_complete), 11225 false); 11226 systemReady(goingCallback); 11227 } 11228 }, doneReceivers, UserHandle.USER_OWNER); 11229 11230 if (mWaitingUpdate) { 11231 return; 11232 } 11233 mDidUpdate = true; 11234 } 11235 11236 mAppOpsService.systemReady(); 11237 mSystemReady = true; 11238 } 11239 11240 ArrayList<ProcessRecord> procsToKill = null; 11241 synchronized(mPidsSelfLocked) { 11242 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11243 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11244 if (!isAllowedWhileBooting(proc.info)){ 11245 if (procsToKill == null) { 11246 procsToKill = new ArrayList<ProcessRecord>(); 11247 } 11248 procsToKill.add(proc); 11249 } 11250 } 11251 } 11252 11253 synchronized(this) { 11254 if (procsToKill != null) { 11255 for (int i=procsToKill.size()-1; i>=0; i--) { 11256 ProcessRecord proc = procsToKill.get(i); 11257 Slog.i(TAG, "Removing system update proc: " + proc); 11258 removeProcessLocked(proc, true, false, "system update done"); 11259 } 11260 } 11261 11262 // Now that we have cleaned up any update processes, we 11263 // are ready to start launching real processes and know that 11264 // we won't trample on them any more. 11265 mProcessesReady = true; 11266 } 11267 11268 Slog.i(TAG, "System now ready"); 11269 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11270 SystemClock.uptimeMillis()); 11271 11272 synchronized(this) { 11273 // Make sure we have no pre-ready processes sitting around. 11274 11275 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11276 ResolveInfo ri = mContext.getPackageManager() 11277 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11278 STOCK_PM_FLAGS); 11279 CharSequence errorMsg = null; 11280 if (ri != null) { 11281 ActivityInfo ai = ri.activityInfo; 11282 ApplicationInfo app = ai.applicationInfo; 11283 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11284 mTopAction = Intent.ACTION_FACTORY_TEST; 11285 mTopData = null; 11286 mTopComponent = new ComponentName(app.packageName, 11287 ai.name); 11288 } else { 11289 errorMsg = mContext.getResources().getText( 11290 com.android.internal.R.string.factorytest_not_system); 11291 } 11292 } else { 11293 errorMsg = mContext.getResources().getText( 11294 com.android.internal.R.string.factorytest_no_action); 11295 } 11296 if (errorMsg != null) { 11297 mTopAction = null; 11298 mTopData = null; 11299 mTopComponent = null; 11300 Message msg = Message.obtain(); 11301 msg.what = SHOW_FACTORY_ERROR_MSG; 11302 msg.getData().putCharSequence("msg", errorMsg); 11303 mHandler.sendMessage(msg); 11304 } 11305 } 11306 } 11307 11308 retrieveSettings(); 11309 loadResourcesOnSystemReady(); 11310 11311 synchronized (this) { 11312 readGrantedUriPermissionsLocked(); 11313 } 11314 11315 if (goingCallback != null) goingCallback.run(); 11316 11317 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11318 Integer.toString(mCurrentUserId), mCurrentUserId); 11319 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11320 Integer.toString(mCurrentUserId), mCurrentUserId); 11321 mSystemServiceManager.startUser(mCurrentUserId); 11322 11323 synchronized (this) { 11324 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11325 try { 11326 List apps = AppGlobals.getPackageManager(). 11327 getPersistentApplications(STOCK_PM_FLAGS); 11328 if (apps != null) { 11329 int N = apps.size(); 11330 int i; 11331 for (i=0; i<N; i++) { 11332 ApplicationInfo info 11333 = (ApplicationInfo)apps.get(i); 11334 if (info != null && 11335 !info.packageName.equals("android")) { 11336 addAppLocked(info, false, null /* ABI override */); 11337 } 11338 } 11339 } 11340 } catch (RemoteException ex) { 11341 // pm is in same process, this will never happen. 11342 } 11343 } 11344 11345 // Start up initial activity. 11346 mBooting = true; 11347 startHomeActivityLocked(mCurrentUserId, "systemReady"); 11348 11349 try { 11350 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11351 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 11352 + " data partition or your device will be unstable."); 11353 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); 11354 } 11355 } catch (RemoteException e) { 11356 } 11357 11358 if (!Build.isFingerprintConsistent()) { 11359 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 11360 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); 11361 } 11362 11363 long ident = Binder.clearCallingIdentity(); 11364 try { 11365 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11366 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11367 | Intent.FLAG_RECEIVER_FOREGROUND); 11368 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11369 broadcastIntentLocked(null, null, intent, 11370 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11371 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11372 intent = new Intent(Intent.ACTION_USER_STARTING); 11373 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11374 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11375 broadcastIntentLocked(null, null, intent, 11376 null, new IIntentReceiver.Stub() { 11377 @Override 11378 public void performReceive(Intent intent, int resultCode, String data, 11379 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11380 throws RemoteException { 11381 } 11382 }, 0, null, null, 11383 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11384 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11385 } catch (Throwable t) { 11386 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11387 } finally { 11388 Binder.restoreCallingIdentity(ident); 11389 } 11390 mStackSupervisor.resumeTopActivitiesLocked(); 11391 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11392 } 11393 } 11394 11395 private boolean makeAppCrashingLocked(ProcessRecord app, 11396 String shortMsg, String longMsg, String stackTrace) { 11397 app.crashing = true; 11398 app.crashingReport = generateProcessError(app, 11399 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11400 startAppProblemLocked(app); 11401 app.stopFreezingAllLocked(); 11402 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11403 } 11404 11405 private void makeAppNotRespondingLocked(ProcessRecord app, 11406 String activity, String shortMsg, String longMsg) { 11407 app.notResponding = true; 11408 app.notRespondingReport = generateProcessError(app, 11409 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11410 activity, shortMsg, longMsg, null); 11411 startAppProblemLocked(app); 11412 app.stopFreezingAllLocked(); 11413 } 11414 11415 /** 11416 * Generate a process error record, suitable for attachment to a ProcessRecord. 11417 * 11418 * @param app The ProcessRecord in which the error occurred. 11419 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11420 * ActivityManager.AppErrorStateInfo 11421 * @param activity The activity associated with the crash, if known. 11422 * @param shortMsg Short message describing the crash. 11423 * @param longMsg Long message describing the crash. 11424 * @param stackTrace Full crash stack trace, may be null. 11425 * 11426 * @return Returns a fully-formed AppErrorStateInfo record. 11427 */ 11428 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11429 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11430 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11431 11432 report.condition = condition; 11433 report.processName = app.processName; 11434 report.pid = app.pid; 11435 report.uid = app.info.uid; 11436 report.tag = activity; 11437 report.shortMsg = shortMsg; 11438 report.longMsg = longMsg; 11439 report.stackTrace = stackTrace; 11440 11441 return report; 11442 } 11443 11444 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11445 synchronized (this) { 11446 app.crashing = false; 11447 app.crashingReport = null; 11448 app.notResponding = false; 11449 app.notRespondingReport = null; 11450 if (app.anrDialog == fromDialog) { 11451 app.anrDialog = null; 11452 } 11453 if (app.waitDialog == fromDialog) { 11454 app.waitDialog = null; 11455 } 11456 if (app.pid > 0 && app.pid != MY_PID) { 11457 handleAppCrashLocked(app, null, null, null); 11458 app.kill("user request after error", true); 11459 } 11460 } 11461 } 11462 11463 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11464 String stackTrace) { 11465 long now = SystemClock.uptimeMillis(); 11466 11467 Long crashTime; 11468 if (!app.isolated) { 11469 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11470 } else { 11471 crashTime = null; 11472 } 11473 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11474 // This process loses! 11475 Slog.w(TAG, "Process " + app.info.processName 11476 + " has crashed too many times: killing!"); 11477 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11478 app.userId, app.info.processName, app.uid); 11479 mStackSupervisor.handleAppCrashLocked(app); 11480 if (!app.persistent) { 11481 // We don't want to start this process again until the user 11482 // explicitly does so... but for persistent process, we really 11483 // need to keep it running. If a persistent process is actually 11484 // repeatedly crashing, then badness for everyone. 11485 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11486 app.info.processName); 11487 if (!app.isolated) { 11488 // XXX We don't have a way to mark isolated processes 11489 // as bad, since they don't have a peristent identity. 11490 mBadProcesses.put(app.info.processName, app.uid, 11491 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11492 mProcessCrashTimes.remove(app.info.processName, app.uid); 11493 } 11494 app.bad = true; 11495 app.removed = true; 11496 // Don't let services in this process be restarted and potentially 11497 // annoy the user repeatedly. Unless it is persistent, since those 11498 // processes run critical code. 11499 removeProcessLocked(app, false, false, "crash"); 11500 mStackSupervisor.resumeTopActivitiesLocked(); 11501 return false; 11502 } 11503 mStackSupervisor.resumeTopActivitiesLocked(); 11504 } else { 11505 mStackSupervisor.finishTopRunningActivityLocked(app); 11506 } 11507 11508 // Bump up the crash count of any services currently running in the proc. 11509 for (int i=app.services.size()-1; i>=0; i--) { 11510 // Any services running in the application need to be placed 11511 // back in the pending list. 11512 ServiceRecord sr = app.services.valueAt(i); 11513 sr.crashCount++; 11514 } 11515 11516 // If the crashing process is what we consider to be the "home process" and it has been 11517 // replaced by a third-party app, clear the package preferred activities from packages 11518 // with a home activity running in the process to prevent a repeatedly crashing app 11519 // from blocking the user to manually clear the list. 11520 final ArrayList<ActivityRecord> activities = app.activities; 11521 if (app == mHomeProcess && activities.size() > 0 11522 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11523 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11524 final ActivityRecord r = activities.get(activityNdx); 11525 if (r.isHomeActivity()) { 11526 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11527 try { 11528 ActivityThread.getPackageManager() 11529 .clearPackagePreferredActivities(r.packageName); 11530 } catch (RemoteException c) { 11531 // pm is in same process, this will never happen. 11532 } 11533 } 11534 } 11535 } 11536 11537 if (!app.isolated) { 11538 // XXX Can't keep track of crash times for isolated processes, 11539 // because they don't have a perisistent identity. 11540 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11541 } 11542 11543 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11544 return true; 11545 } 11546 11547 void startAppProblemLocked(ProcessRecord app) { 11548 // If this app is not running under the current user, then we 11549 // can't give it a report button because that would require 11550 // launching the report UI under a different user. 11551 app.errorReportReceiver = null; 11552 11553 for (int userId : mCurrentProfileIds) { 11554 if (app.userId == userId) { 11555 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11556 mContext, app.info.packageName, app.info.flags); 11557 } 11558 } 11559 skipCurrentReceiverLocked(app); 11560 } 11561 11562 void skipCurrentReceiverLocked(ProcessRecord app) { 11563 for (BroadcastQueue queue : mBroadcastQueues) { 11564 queue.skipCurrentReceiverLocked(app); 11565 } 11566 } 11567 11568 /** 11569 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11570 * The application process will exit immediately after this call returns. 11571 * @param app object of the crashing app, null for the system server 11572 * @param crashInfo describing the exception 11573 */ 11574 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11575 ProcessRecord r = findAppProcess(app, "Crash"); 11576 final String processName = app == null ? "system_server" 11577 : (r == null ? "unknown" : r.processName); 11578 11579 handleApplicationCrashInner("crash", r, processName, crashInfo); 11580 } 11581 11582 /* Native crash reporting uses this inner version because it needs to be somewhat 11583 * decoupled from the AM-managed cleanup lifecycle 11584 */ 11585 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11586 ApplicationErrorReport.CrashInfo crashInfo) { 11587 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11588 UserHandle.getUserId(Binder.getCallingUid()), processName, 11589 r == null ? -1 : r.info.flags, 11590 crashInfo.exceptionClassName, 11591 crashInfo.exceptionMessage, 11592 crashInfo.throwFileName, 11593 crashInfo.throwLineNumber); 11594 11595 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11596 11597 crashApplication(r, crashInfo); 11598 } 11599 11600 public void handleApplicationStrictModeViolation( 11601 IBinder app, 11602 int violationMask, 11603 StrictMode.ViolationInfo info) { 11604 ProcessRecord r = findAppProcess(app, "StrictMode"); 11605 if (r == null) { 11606 return; 11607 } 11608 11609 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11610 Integer stackFingerprint = info.hashCode(); 11611 boolean logIt = true; 11612 synchronized (mAlreadyLoggedViolatedStacks) { 11613 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11614 logIt = false; 11615 // TODO: sub-sample into EventLog for these, with 11616 // the info.durationMillis? Then we'd get 11617 // the relative pain numbers, without logging all 11618 // the stack traces repeatedly. We'd want to do 11619 // likewise in the client code, which also does 11620 // dup suppression, before the Binder call. 11621 } else { 11622 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11623 mAlreadyLoggedViolatedStacks.clear(); 11624 } 11625 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11626 } 11627 } 11628 if (logIt) { 11629 logStrictModeViolationToDropBox(r, info); 11630 } 11631 } 11632 11633 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11634 AppErrorResult result = new AppErrorResult(); 11635 synchronized (this) { 11636 final long origId = Binder.clearCallingIdentity(); 11637 11638 Message msg = Message.obtain(); 11639 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11640 HashMap<String, Object> data = new HashMap<String, Object>(); 11641 data.put("result", result); 11642 data.put("app", r); 11643 data.put("violationMask", violationMask); 11644 data.put("info", info); 11645 msg.obj = data; 11646 mHandler.sendMessage(msg); 11647 11648 Binder.restoreCallingIdentity(origId); 11649 } 11650 int res = result.get(); 11651 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11652 } 11653 } 11654 11655 // Depending on the policy in effect, there could be a bunch of 11656 // these in quick succession so we try to batch these together to 11657 // minimize disk writes, number of dropbox entries, and maximize 11658 // compression, by having more fewer, larger records. 11659 private void logStrictModeViolationToDropBox( 11660 ProcessRecord process, 11661 StrictMode.ViolationInfo info) { 11662 if (info == null) { 11663 return; 11664 } 11665 final boolean isSystemApp = process == null || 11666 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11667 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11668 final String processName = process == null ? "unknown" : process.processName; 11669 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11670 final DropBoxManager dbox = (DropBoxManager) 11671 mContext.getSystemService(Context.DROPBOX_SERVICE); 11672 11673 // Exit early if the dropbox isn't configured to accept this report type. 11674 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11675 11676 boolean bufferWasEmpty; 11677 boolean needsFlush; 11678 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11679 synchronized (sb) { 11680 bufferWasEmpty = sb.length() == 0; 11681 appendDropBoxProcessHeaders(process, processName, sb); 11682 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11683 sb.append("System-App: ").append(isSystemApp).append("\n"); 11684 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11685 if (info.violationNumThisLoop != 0) { 11686 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11687 } 11688 if (info.numAnimationsRunning != 0) { 11689 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11690 } 11691 if (info.broadcastIntentAction != null) { 11692 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11693 } 11694 if (info.durationMillis != -1) { 11695 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11696 } 11697 if (info.numInstances != -1) { 11698 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11699 } 11700 if (info.tags != null) { 11701 for (String tag : info.tags) { 11702 sb.append("Span-Tag: ").append(tag).append("\n"); 11703 } 11704 } 11705 sb.append("\n"); 11706 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11707 sb.append(info.crashInfo.stackTrace); 11708 } 11709 sb.append("\n"); 11710 11711 // Only buffer up to ~64k. Various logging bits truncate 11712 // things at 128k. 11713 needsFlush = (sb.length() > 64 * 1024); 11714 } 11715 11716 // Flush immediately if the buffer's grown too large, or this 11717 // is a non-system app. Non-system apps are isolated with a 11718 // different tag & policy and not batched. 11719 // 11720 // Batching is useful during internal testing with 11721 // StrictMode settings turned up high. Without batching, 11722 // thousands of separate files could be created on boot. 11723 if (!isSystemApp || needsFlush) { 11724 new Thread("Error dump: " + dropboxTag) { 11725 @Override 11726 public void run() { 11727 String report; 11728 synchronized (sb) { 11729 report = sb.toString(); 11730 sb.delete(0, sb.length()); 11731 sb.trimToSize(); 11732 } 11733 if (report.length() != 0) { 11734 dbox.addText(dropboxTag, report); 11735 } 11736 } 11737 }.start(); 11738 return; 11739 } 11740 11741 // System app batching: 11742 if (!bufferWasEmpty) { 11743 // An existing dropbox-writing thread is outstanding, so 11744 // we don't need to start it up. The existing thread will 11745 // catch the buffer appends we just did. 11746 return; 11747 } 11748 11749 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11750 // (After this point, we shouldn't access AMS internal data structures.) 11751 new Thread("Error dump: " + dropboxTag) { 11752 @Override 11753 public void run() { 11754 // 5 second sleep to let stacks arrive and be batched together 11755 try { 11756 Thread.sleep(5000); // 5 seconds 11757 } catch (InterruptedException e) {} 11758 11759 String errorReport; 11760 synchronized (mStrictModeBuffer) { 11761 errorReport = mStrictModeBuffer.toString(); 11762 if (errorReport.length() == 0) { 11763 return; 11764 } 11765 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11766 mStrictModeBuffer.trimToSize(); 11767 } 11768 dbox.addText(dropboxTag, errorReport); 11769 } 11770 }.start(); 11771 } 11772 11773 /** 11774 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11775 * @param app object of the crashing app, null for the system server 11776 * @param tag reported by the caller 11777 * @param system whether this wtf is coming from the system 11778 * @param crashInfo describing the context of the error 11779 * @return true if the process should exit immediately (WTF is fatal) 11780 */ 11781 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11782 final ApplicationErrorReport.CrashInfo crashInfo) { 11783 final int callingUid = Binder.getCallingUid(); 11784 final int callingPid = Binder.getCallingPid(); 11785 11786 if (system) { 11787 // If this is coming from the system, we could very well have low-level 11788 // system locks held, so we want to do this all asynchronously. And we 11789 // never want this to become fatal, so there is that too. 11790 mHandler.post(new Runnable() { 11791 @Override public void run() { 11792 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11793 } 11794 }); 11795 return false; 11796 } 11797 11798 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11799 crashInfo); 11800 11801 if (r != null && r.pid != Process.myPid() && 11802 Settings.Global.getInt(mContext.getContentResolver(), 11803 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11804 crashApplication(r, crashInfo); 11805 return true; 11806 } else { 11807 return false; 11808 } 11809 } 11810 11811 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11812 final ApplicationErrorReport.CrashInfo crashInfo) { 11813 final ProcessRecord r = findAppProcess(app, "WTF"); 11814 final String processName = app == null ? "system_server" 11815 : (r == null ? "unknown" : r.processName); 11816 11817 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11818 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11819 11820 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11821 11822 return r; 11823 } 11824 11825 /** 11826 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11827 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11828 */ 11829 private ProcessRecord findAppProcess(IBinder app, String reason) { 11830 if (app == null) { 11831 return null; 11832 } 11833 11834 synchronized (this) { 11835 final int NP = mProcessNames.getMap().size(); 11836 for (int ip=0; ip<NP; ip++) { 11837 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11838 final int NA = apps.size(); 11839 for (int ia=0; ia<NA; ia++) { 11840 ProcessRecord p = apps.valueAt(ia); 11841 if (p.thread != null && p.thread.asBinder() == app) { 11842 return p; 11843 } 11844 } 11845 } 11846 11847 Slog.w(TAG, "Can't find mystery application for " + reason 11848 + " from pid=" + Binder.getCallingPid() 11849 + " uid=" + Binder.getCallingUid() + ": " + app); 11850 return null; 11851 } 11852 } 11853 11854 /** 11855 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11856 * to append various headers to the dropbox log text. 11857 */ 11858 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11859 StringBuilder sb) { 11860 // Watchdog thread ends up invoking this function (with 11861 // a null ProcessRecord) to add the stack file to dropbox. 11862 // Do not acquire a lock on this (am) in such cases, as it 11863 // could cause a potential deadlock, if and when watchdog 11864 // is invoked due to unavailability of lock on am and it 11865 // would prevent watchdog from killing system_server. 11866 if (process == null) { 11867 sb.append("Process: ").append(processName).append("\n"); 11868 return; 11869 } 11870 // Note: ProcessRecord 'process' is guarded by the service 11871 // instance. (notably process.pkgList, which could otherwise change 11872 // concurrently during execution of this method) 11873 synchronized (this) { 11874 sb.append("Process: ").append(processName).append("\n"); 11875 int flags = process.info.flags; 11876 IPackageManager pm = AppGlobals.getPackageManager(); 11877 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11878 for (int ip=0; ip<process.pkgList.size(); ip++) { 11879 String pkg = process.pkgList.keyAt(ip); 11880 sb.append("Package: ").append(pkg); 11881 try { 11882 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11883 if (pi != null) { 11884 sb.append(" v").append(pi.versionCode); 11885 if (pi.versionName != null) { 11886 sb.append(" (").append(pi.versionName).append(")"); 11887 } 11888 } 11889 } catch (RemoteException e) { 11890 Slog.e(TAG, "Error getting package info: " + pkg, e); 11891 } 11892 sb.append("\n"); 11893 } 11894 } 11895 } 11896 11897 private static String processClass(ProcessRecord process) { 11898 if (process == null || process.pid == MY_PID) { 11899 return "system_server"; 11900 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11901 return "system_app"; 11902 } else { 11903 return "data_app"; 11904 } 11905 } 11906 11907 /** 11908 * Write a description of an error (crash, WTF, ANR) to the drop box. 11909 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11910 * @param process which caused the error, null means the system server 11911 * @param activity which triggered the error, null if unknown 11912 * @param parent activity related to the error, null if unknown 11913 * @param subject line related to the error, null if absent 11914 * @param report in long form describing the error, null if absent 11915 * @param logFile to include in the report, null if none 11916 * @param crashInfo giving an application stack trace, null if absent 11917 */ 11918 public void addErrorToDropBox(String eventType, 11919 ProcessRecord process, String processName, ActivityRecord activity, 11920 ActivityRecord parent, String subject, 11921 final String report, final File logFile, 11922 final ApplicationErrorReport.CrashInfo crashInfo) { 11923 // NOTE -- this must never acquire the ActivityManagerService lock, 11924 // otherwise the watchdog may be prevented from resetting the system. 11925 11926 final String dropboxTag = processClass(process) + "_" + eventType; 11927 final DropBoxManager dbox = (DropBoxManager) 11928 mContext.getSystemService(Context.DROPBOX_SERVICE); 11929 11930 // Exit early if the dropbox isn't configured to accept this report type. 11931 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11932 11933 final StringBuilder sb = new StringBuilder(1024); 11934 appendDropBoxProcessHeaders(process, processName, sb); 11935 if (activity != null) { 11936 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11937 } 11938 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11939 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11940 } 11941 if (parent != null && parent != activity) { 11942 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11943 } 11944 if (subject != null) { 11945 sb.append("Subject: ").append(subject).append("\n"); 11946 } 11947 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11948 if (Debug.isDebuggerConnected()) { 11949 sb.append("Debugger: Connected\n"); 11950 } 11951 sb.append("\n"); 11952 11953 // Do the rest in a worker thread to avoid blocking the caller on I/O 11954 // (After this point, we shouldn't access AMS internal data structures.) 11955 Thread worker = new Thread("Error dump: " + dropboxTag) { 11956 @Override 11957 public void run() { 11958 if (report != null) { 11959 sb.append(report); 11960 } 11961 if (logFile != null) { 11962 try { 11963 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11964 "\n\n[[TRUNCATED]]")); 11965 } catch (IOException e) { 11966 Slog.e(TAG, "Error reading " + logFile, e); 11967 } 11968 } 11969 if (crashInfo != null && crashInfo.stackTrace != null) { 11970 sb.append(crashInfo.stackTrace); 11971 } 11972 11973 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11974 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11975 if (lines > 0) { 11976 sb.append("\n"); 11977 11978 // Merge several logcat streams, and take the last N lines 11979 InputStreamReader input = null; 11980 try { 11981 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11982 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11983 "-b", "crash", 11984 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11985 11986 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11987 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11988 input = new InputStreamReader(logcat.getInputStream()); 11989 11990 int num; 11991 char[] buf = new char[8192]; 11992 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11993 } catch (IOException e) { 11994 Slog.e(TAG, "Error running logcat", e); 11995 } finally { 11996 if (input != null) try { input.close(); } catch (IOException e) {} 11997 } 11998 } 11999 12000 dbox.addText(dropboxTag, sb.toString()); 12001 } 12002 }; 12003 12004 if (process == null) { 12005 // If process is null, we are being called from some internal code 12006 // and may be about to die -- run this synchronously. 12007 worker.run(); 12008 } else { 12009 worker.start(); 12010 } 12011 } 12012 12013 /** 12014 * Bring up the "unexpected error" dialog box for a crashing app. 12015 * Deal with edge cases (intercepts from instrumented applications, 12016 * ActivityController, error intent receivers, that sort of thing). 12017 * @param r the application crashing 12018 * @param crashInfo describing the failure 12019 */ 12020 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12021 long timeMillis = System.currentTimeMillis(); 12022 String shortMsg = crashInfo.exceptionClassName; 12023 String longMsg = crashInfo.exceptionMessage; 12024 String stackTrace = crashInfo.stackTrace; 12025 if (shortMsg != null && longMsg != null) { 12026 longMsg = shortMsg + ": " + longMsg; 12027 } else if (shortMsg != null) { 12028 longMsg = shortMsg; 12029 } 12030 12031 AppErrorResult result = new AppErrorResult(); 12032 synchronized (this) { 12033 if (mController != null) { 12034 try { 12035 String name = r != null ? r.processName : null; 12036 int pid = r != null ? r.pid : Binder.getCallingPid(); 12037 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12038 if (!mController.appCrashed(name, pid, 12039 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12040 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12041 && "Native crash".equals(crashInfo.exceptionClassName)) { 12042 Slog.w(TAG, "Skip killing native crashed app " + name 12043 + "(" + pid + ") during testing"); 12044 } else { 12045 Slog.w(TAG, "Force-killing crashed app " + name 12046 + " at watcher's request"); 12047 if (r != null) { 12048 r.kill("crash", true); 12049 } else { 12050 // Huh. 12051 Process.killProcess(pid); 12052 Process.killProcessGroup(uid, pid); 12053 } 12054 } 12055 return; 12056 } 12057 } catch (RemoteException e) { 12058 mController = null; 12059 Watchdog.getInstance().setActivityController(null); 12060 } 12061 } 12062 12063 final long origId = Binder.clearCallingIdentity(); 12064 12065 // If this process is running instrumentation, finish it. 12066 if (r != null && r.instrumentationClass != null) { 12067 Slog.w(TAG, "Error in app " + r.processName 12068 + " running instrumentation " + r.instrumentationClass + ":"); 12069 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12070 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12071 Bundle info = new Bundle(); 12072 info.putString("shortMsg", shortMsg); 12073 info.putString("longMsg", longMsg); 12074 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12075 Binder.restoreCallingIdentity(origId); 12076 return; 12077 } 12078 12079 // Log crash in battery stats. 12080 if (r != null) { 12081 mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 12082 } 12083 12084 // If we can't identify the process or it's already exceeded its crash quota, 12085 // quit right away without showing a crash dialog. 12086 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12087 Binder.restoreCallingIdentity(origId); 12088 return; 12089 } 12090 12091 Message msg = Message.obtain(); 12092 msg.what = SHOW_ERROR_MSG; 12093 HashMap data = new HashMap(); 12094 data.put("result", result); 12095 data.put("app", r); 12096 msg.obj = data; 12097 mHandler.sendMessage(msg); 12098 12099 Binder.restoreCallingIdentity(origId); 12100 } 12101 12102 int res = result.get(); 12103 12104 Intent appErrorIntent = null; 12105 synchronized (this) { 12106 if (r != null && !r.isolated) { 12107 // XXX Can't keep track of crash time for isolated processes, 12108 // since they don't have a persistent identity. 12109 mProcessCrashTimes.put(r.info.processName, r.uid, 12110 SystemClock.uptimeMillis()); 12111 } 12112 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12113 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12114 } 12115 } 12116 12117 if (appErrorIntent != null) { 12118 try { 12119 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12120 } catch (ActivityNotFoundException e) { 12121 Slog.w(TAG, "bug report receiver dissappeared", e); 12122 } 12123 } 12124 } 12125 12126 Intent createAppErrorIntentLocked(ProcessRecord r, 12127 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12128 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12129 if (report == null) { 12130 return null; 12131 } 12132 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12133 result.setComponent(r.errorReportReceiver); 12134 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12135 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12136 return result; 12137 } 12138 12139 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12140 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12141 if (r.errorReportReceiver == null) { 12142 return null; 12143 } 12144 12145 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12146 return null; 12147 } 12148 12149 ApplicationErrorReport report = new ApplicationErrorReport(); 12150 report.packageName = r.info.packageName; 12151 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12152 report.processName = r.processName; 12153 report.time = timeMillis; 12154 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12155 12156 if (r.crashing || r.forceCrashReport) { 12157 report.type = ApplicationErrorReport.TYPE_CRASH; 12158 report.crashInfo = crashInfo; 12159 } else if (r.notResponding) { 12160 report.type = ApplicationErrorReport.TYPE_ANR; 12161 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12162 12163 report.anrInfo.activity = r.notRespondingReport.tag; 12164 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12165 report.anrInfo.info = r.notRespondingReport.longMsg; 12166 } 12167 12168 return report; 12169 } 12170 12171 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12172 enforceNotIsolatedCaller("getProcessesInErrorState"); 12173 // assume our apps are happy - lazy create the list 12174 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12175 12176 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12177 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12178 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12179 12180 synchronized (this) { 12181 12182 // iterate across all processes 12183 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12184 ProcessRecord app = mLruProcesses.get(i); 12185 if (!allUsers && app.userId != userId) { 12186 continue; 12187 } 12188 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12189 // This one's in trouble, so we'll generate a report for it 12190 // crashes are higher priority (in case there's a crash *and* an anr) 12191 ActivityManager.ProcessErrorStateInfo report = null; 12192 if (app.crashing) { 12193 report = app.crashingReport; 12194 } else if (app.notResponding) { 12195 report = app.notRespondingReport; 12196 } 12197 12198 if (report != null) { 12199 if (errList == null) { 12200 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12201 } 12202 errList.add(report); 12203 } else { 12204 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12205 " crashing = " + app.crashing + 12206 " notResponding = " + app.notResponding); 12207 } 12208 } 12209 } 12210 } 12211 12212 return errList; 12213 } 12214 12215 static int procStateToImportance(int procState, int memAdj, 12216 ActivityManager.RunningAppProcessInfo currApp) { 12217 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12218 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12219 currApp.lru = memAdj; 12220 } else { 12221 currApp.lru = 0; 12222 } 12223 return imp; 12224 } 12225 12226 private void fillInProcMemInfo(ProcessRecord app, 12227 ActivityManager.RunningAppProcessInfo outInfo) { 12228 outInfo.pid = app.pid; 12229 outInfo.uid = app.info.uid; 12230 if (mHeavyWeightProcess == app) { 12231 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12232 } 12233 if (app.persistent) { 12234 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12235 } 12236 if (app.activities.size() > 0) { 12237 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12238 } 12239 outInfo.lastTrimLevel = app.trimMemoryLevel; 12240 int adj = app.curAdj; 12241 int procState = app.curProcState; 12242 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12243 outInfo.importanceReasonCode = app.adjTypeCode; 12244 outInfo.processState = app.curProcState; 12245 } 12246 12247 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12248 enforceNotIsolatedCaller("getRunningAppProcesses"); 12249 12250 final int callingUid = Binder.getCallingUid(); 12251 12252 // Lazy instantiation of list 12253 List<ActivityManager.RunningAppProcessInfo> runList = null; 12254 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12255 callingUid) == PackageManager.PERMISSION_GRANTED; 12256 final int userId = UserHandle.getUserId(callingUid); 12257 final boolean allUids = isGetTasksAllowed( 12258 "getRunningAppProcesses", Binder.getCallingPid(), callingUid); 12259 12260 synchronized (this) { 12261 // Iterate across all processes 12262 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 12263 ProcessRecord app = mLruProcesses.get(i); 12264 if ((!allUsers && app.userId != userId) 12265 || (!allUids && app.uid != callingUid)) { 12266 continue; 12267 } 12268 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12269 // Generate process state info for running application 12270 ActivityManager.RunningAppProcessInfo currApp = 12271 new ActivityManager.RunningAppProcessInfo(app.processName, 12272 app.pid, app.getPackageList()); 12273 fillInProcMemInfo(app, currApp); 12274 if (app.adjSource instanceof ProcessRecord) { 12275 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12276 currApp.importanceReasonImportance = 12277 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12278 app.adjSourceProcState); 12279 } else if (app.adjSource instanceof ActivityRecord) { 12280 ActivityRecord r = (ActivityRecord)app.adjSource; 12281 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12282 } 12283 if (app.adjTarget instanceof ComponentName) { 12284 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12285 } 12286 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12287 // + " lru=" + currApp.lru); 12288 if (runList == null) { 12289 runList = new ArrayList<>(); 12290 } 12291 runList.add(currApp); 12292 } 12293 } 12294 } 12295 return runList; 12296 } 12297 12298 public List<ApplicationInfo> getRunningExternalApplications() { 12299 enforceNotIsolatedCaller("getRunningExternalApplications"); 12300 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12301 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12302 if (runningApps != null && runningApps.size() > 0) { 12303 Set<String> extList = new HashSet<String>(); 12304 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12305 if (app.pkgList != null) { 12306 for (String pkg : app.pkgList) { 12307 extList.add(pkg); 12308 } 12309 } 12310 } 12311 IPackageManager pm = AppGlobals.getPackageManager(); 12312 for (String pkg : extList) { 12313 try { 12314 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12315 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12316 retList.add(info); 12317 } 12318 } catch (RemoteException e) { 12319 } 12320 } 12321 } 12322 return retList; 12323 } 12324 12325 @Override 12326 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12327 enforceNotIsolatedCaller("getMyMemoryState"); 12328 synchronized (this) { 12329 ProcessRecord proc; 12330 synchronized (mPidsSelfLocked) { 12331 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12332 } 12333 fillInProcMemInfo(proc, outInfo); 12334 } 12335 } 12336 12337 @Override 12338 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12339 if (checkCallingPermission(android.Manifest.permission.DUMP) 12340 != PackageManager.PERMISSION_GRANTED) { 12341 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12342 + Binder.getCallingPid() 12343 + ", uid=" + Binder.getCallingUid() 12344 + " without permission " 12345 + android.Manifest.permission.DUMP); 12346 return; 12347 } 12348 12349 boolean dumpAll = false; 12350 boolean dumpClient = false; 12351 String dumpPackage = null; 12352 12353 int opti = 0; 12354 while (opti < args.length) { 12355 String opt = args[opti]; 12356 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12357 break; 12358 } 12359 opti++; 12360 if ("-a".equals(opt)) { 12361 dumpAll = true; 12362 } else if ("-c".equals(opt)) { 12363 dumpClient = true; 12364 } else if ("-p".equals(opt)) { 12365 if (opti < args.length) { 12366 dumpPackage = args[opti]; 12367 opti++; 12368 } else { 12369 pw.println("Error: -p option requires package argument"); 12370 return; 12371 } 12372 dumpClient = true; 12373 } else if ("-h".equals(opt)) { 12374 pw.println("Activity manager dump options:"); 12375 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ..."); 12376 pw.println(" cmd may be one of:"); 12377 pw.println(" a[ctivities]: activity stack state"); 12378 pw.println(" r[recents]: recent activities state"); 12379 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12380 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12381 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12382 pw.println(" o[om]: out of memory management"); 12383 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12384 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12385 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12386 pw.println(" as[sociations]: tracked app associations"); 12387 pw.println(" service [COMP_SPEC]: service client-side state"); 12388 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12389 pw.println(" all: dump all activities"); 12390 pw.println(" top: dump the top activity"); 12391 pw.println(" write: write all pending state to storage"); 12392 pw.println(" track-associations: enable association tracking"); 12393 pw.println(" untrack-associations: disable and clear association tracking"); 12394 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12395 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12396 pw.println(" a partial substring in a component name, a"); 12397 pw.println(" hex object identifier."); 12398 pw.println(" -a: include all available server state."); 12399 pw.println(" -c: include client state."); 12400 pw.println(" -p: limit output to given package."); 12401 return; 12402 } else { 12403 pw.println("Unknown argument: " + opt + "; use -h for help"); 12404 } 12405 } 12406 12407 long origId = Binder.clearCallingIdentity(); 12408 boolean more = false; 12409 // Is the caller requesting to dump a particular piece of data? 12410 if (opti < args.length) { 12411 String cmd = args[opti]; 12412 opti++; 12413 if ("activities".equals(cmd) || "a".equals(cmd)) { 12414 synchronized (this) { 12415 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12416 } 12417 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12418 synchronized (this) { 12419 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 12420 } 12421 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12422 String[] newArgs; 12423 String name; 12424 if (opti >= args.length) { 12425 name = null; 12426 newArgs = EMPTY_STRING_ARRAY; 12427 } else { 12428 dumpPackage = args[opti]; 12429 opti++; 12430 newArgs = new String[args.length - opti]; 12431 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12432 args.length - opti); 12433 } 12434 synchronized (this) { 12435 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 12436 } 12437 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12438 String[] newArgs; 12439 String name; 12440 if (opti >= args.length) { 12441 name = null; 12442 newArgs = EMPTY_STRING_ARRAY; 12443 } else { 12444 dumpPackage = args[opti]; 12445 opti++; 12446 newArgs = new String[args.length - opti]; 12447 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12448 args.length - opti); 12449 } 12450 synchronized (this) { 12451 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 12452 } 12453 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12454 String[] newArgs; 12455 String name; 12456 if (opti >= args.length) { 12457 name = null; 12458 newArgs = EMPTY_STRING_ARRAY; 12459 } else { 12460 dumpPackage = args[opti]; 12461 opti++; 12462 newArgs = new String[args.length - opti]; 12463 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12464 args.length - opti); 12465 } 12466 synchronized (this) { 12467 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 12468 } 12469 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12470 synchronized (this) { 12471 dumpOomLocked(fd, pw, args, opti, true); 12472 } 12473 } else if ("provider".equals(cmd)) { 12474 String[] newArgs; 12475 String name; 12476 if (opti >= args.length) { 12477 name = null; 12478 newArgs = EMPTY_STRING_ARRAY; 12479 } else { 12480 name = args[opti]; 12481 opti++; 12482 newArgs = new String[args.length - opti]; 12483 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12484 } 12485 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12486 pw.println("No providers match: " + name); 12487 pw.println("Use -h for help."); 12488 } 12489 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12490 synchronized (this) { 12491 dumpProvidersLocked(fd, pw, args, opti, true, null); 12492 } 12493 } else if ("service".equals(cmd)) { 12494 String[] newArgs; 12495 String name; 12496 if (opti >= args.length) { 12497 name = null; 12498 newArgs = EMPTY_STRING_ARRAY; 12499 } else { 12500 name = args[opti]; 12501 opti++; 12502 newArgs = new String[args.length - opti]; 12503 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12504 args.length - opti); 12505 } 12506 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12507 pw.println("No services match: " + name); 12508 pw.println("Use -h for help."); 12509 } 12510 } else if ("package".equals(cmd)) { 12511 String[] newArgs; 12512 if (opti >= args.length) { 12513 pw.println("package: no package name specified"); 12514 pw.println("Use -h for help."); 12515 } else { 12516 dumpPackage = args[opti]; 12517 opti++; 12518 newArgs = new String[args.length - opti]; 12519 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12520 args.length - opti); 12521 args = newArgs; 12522 opti = 0; 12523 more = true; 12524 } 12525 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 12526 synchronized (this) { 12527 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12528 } 12529 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12530 synchronized (this) { 12531 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 12532 } 12533 } else if ("write".equals(cmd)) { 12534 mTaskPersister.flush(); 12535 pw.println("All tasks persisted."); 12536 return; 12537 } else if ("track-associations".equals(cmd)) { 12538 synchronized (this) { 12539 if (!mTrackingAssociations) { 12540 mTrackingAssociations = true; 12541 pw.println("Association tracking started."); 12542 } else { 12543 pw.println("Association tracking already enabled."); 12544 } 12545 } 12546 return; 12547 } else if ("untrack-associations".equals(cmd)) { 12548 synchronized (this) { 12549 if (mTrackingAssociations) { 12550 mTrackingAssociations = false; 12551 mAssociations.clear(); 12552 pw.println("Association tracking stopped."); 12553 } else { 12554 pw.println("Association tracking not running."); 12555 } 12556 } 12557 return; 12558 } else { 12559 // Dumping a single activity? 12560 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12561 pw.println("Bad activity command, or no activities match: " + cmd); 12562 pw.println("Use -h for help."); 12563 } 12564 } 12565 if (!more) { 12566 Binder.restoreCallingIdentity(origId); 12567 return; 12568 } 12569 } 12570 12571 // No piece of data specified, dump everything. 12572 synchronized (this) { 12573 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12574 pw.println(); 12575 if (dumpAll) { 12576 pw.println("-------------------------------------------------------------------------------"); 12577 } 12578 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12579 pw.println(); 12580 if (dumpAll) { 12581 pw.println("-------------------------------------------------------------------------------"); 12582 } 12583 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12584 pw.println(); 12585 if (dumpAll) { 12586 pw.println("-------------------------------------------------------------------------------"); 12587 } 12588 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12589 pw.println(); 12590 if (dumpAll) { 12591 pw.println("-------------------------------------------------------------------------------"); 12592 } 12593 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12594 pw.println(); 12595 if (dumpAll) { 12596 pw.println("-------------------------------------------------------------------------------"); 12597 } 12598 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12599 if (mAssociations.size() > 0) { 12600 pw.println(); 12601 if (dumpAll) { 12602 pw.println("-------------------------------------------------------------------------------"); 12603 } 12604 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12605 } 12606 pw.println(); 12607 if (dumpAll) { 12608 pw.println("-------------------------------------------------------------------------------"); 12609 } 12610 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12611 } 12612 Binder.restoreCallingIdentity(origId); 12613 } 12614 12615 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12616 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12617 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12618 12619 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12620 dumpPackage); 12621 boolean needSep = printedAnything; 12622 12623 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12624 dumpPackage, needSep, " mFocusedActivity: "); 12625 if (printed) { 12626 printedAnything = true; 12627 needSep = false; 12628 } 12629 12630 if (dumpPackage == null) { 12631 if (needSep) { 12632 pw.println(); 12633 } 12634 needSep = true; 12635 printedAnything = true; 12636 mStackSupervisor.dump(pw, " "); 12637 } 12638 12639 if (!printedAnything) { 12640 pw.println(" (nothing)"); 12641 } 12642 } 12643 12644 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12645 int opti, boolean dumpAll, String dumpPackage) { 12646 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12647 12648 boolean printedAnything = false; 12649 12650 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12651 boolean printedHeader = false; 12652 12653 final int N = mRecentTasks.size(); 12654 for (int i=0; i<N; i++) { 12655 TaskRecord tr = mRecentTasks.get(i); 12656 if (dumpPackage != null) { 12657 if (tr.realActivity == null || 12658 !dumpPackage.equals(tr.realActivity)) { 12659 continue; 12660 } 12661 } 12662 if (!printedHeader) { 12663 pw.println(" Recent tasks:"); 12664 printedHeader = true; 12665 printedAnything = true; 12666 } 12667 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12668 pw.println(tr); 12669 if (dumpAll) { 12670 mRecentTasks.get(i).dump(pw, " "); 12671 } 12672 } 12673 } 12674 12675 if (!printedAnything) { 12676 pw.println(" (nothing)"); 12677 } 12678 } 12679 12680 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12681 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12682 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 12683 12684 int dumpUid = 0; 12685 if (dumpPackage != null) { 12686 IPackageManager pm = AppGlobals.getPackageManager(); 12687 try { 12688 dumpUid = pm.getPackageUid(dumpPackage, 0); 12689 } catch (RemoteException e) { 12690 } 12691 } 12692 12693 boolean printedAnything = false; 12694 12695 final long now = SystemClock.uptimeMillis(); 12696 12697 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 12698 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 12699 = mAssociations.valueAt(i1); 12700 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 12701 SparseArray<ArrayMap<String, Association>> sourceUids 12702 = targetComponents.valueAt(i2); 12703 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 12704 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 12705 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 12706 Association ass = sourceProcesses.valueAt(i4); 12707 if (dumpPackage != null) { 12708 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 12709 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 12710 continue; 12711 } 12712 } 12713 printedAnything = true; 12714 pw.print(" "); 12715 pw.print(ass.mTargetProcess); 12716 pw.print("/"); 12717 UserHandle.formatUid(pw, ass.mTargetUid); 12718 pw.print(" <- "); 12719 pw.print(ass.mSourceProcess); 12720 pw.print("/"); 12721 UserHandle.formatUid(pw, ass.mSourceUid); 12722 pw.println(); 12723 pw.print(" via "); 12724 pw.print(ass.mTargetComponent.flattenToShortString()); 12725 pw.println(); 12726 pw.print(" "); 12727 long dur = ass.mTime; 12728 if (ass.mNesting > 0) { 12729 dur += now - ass.mStartTime; 12730 } 12731 TimeUtils.formatDuration(dur, pw); 12732 pw.print(" ("); 12733 pw.print(ass.mCount); 12734 pw.println(" times)"); 12735 if (ass.mNesting > 0) { 12736 pw.print(" "); 12737 pw.print(" Currently active: "); 12738 TimeUtils.formatDuration(now - ass.mStartTime, pw); 12739 pw.println(); 12740 } 12741 } 12742 } 12743 } 12744 12745 } 12746 12747 if (!printedAnything) { 12748 pw.println(" (nothing)"); 12749 } 12750 } 12751 12752 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12753 int opti, boolean dumpAll, String dumpPackage) { 12754 boolean needSep = false; 12755 boolean printedAnything = false; 12756 int numPers = 0; 12757 12758 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12759 12760 if (dumpAll) { 12761 final int NP = mProcessNames.getMap().size(); 12762 for (int ip=0; ip<NP; ip++) { 12763 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12764 final int NA = procs.size(); 12765 for (int ia=0; ia<NA; ia++) { 12766 ProcessRecord r = procs.valueAt(ia); 12767 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12768 continue; 12769 } 12770 if (!needSep) { 12771 pw.println(" All known processes:"); 12772 needSep = true; 12773 printedAnything = true; 12774 } 12775 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12776 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12777 pw.print(" "); pw.println(r); 12778 r.dump(pw, " "); 12779 if (r.persistent) { 12780 numPers++; 12781 } 12782 } 12783 } 12784 } 12785 12786 if (mIsolatedProcesses.size() > 0) { 12787 boolean printed = false; 12788 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12789 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12790 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12791 continue; 12792 } 12793 if (!printed) { 12794 if (needSep) { 12795 pw.println(); 12796 } 12797 pw.println(" Isolated process list (sorted by uid):"); 12798 printedAnything = true; 12799 printed = true; 12800 needSep = true; 12801 } 12802 pw.println(String.format("%sIsolated #%2d: %s", 12803 " ", i, r.toString())); 12804 } 12805 } 12806 12807 if (mLruProcesses.size() > 0) { 12808 if (needSep) { 12809 pw.println(); 12810 } 12811 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12812 pw.print(" total, non-act at "); 12813 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12814 pw.print(", non-svc at "); 12815 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12816 pw.println("):"); 12817 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12818 needSep = true; 12819 printedAnything = true; 12820 } 12821 12822 if (dumpAll || dumpPackage != null) { 12823 synchronized (mPidsSelfLocked) { 12824 boolean printed = false; 12825 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12826 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12827 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12828 continue; 12829 } 12830 if (!printed) { 12831 if (needSep) pw.println(); 12832 needSep = true; 12833 pw.println(" PID mappings:"); 12834 printed = true; 12835 printedAnything = true; 12836 } 12837 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12838 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12839 } 12840 } 12841 } 12842 12843 if (mForegroundProcesses.size() > 0) { 12844 synchronized (mPidsSelfLocked) { 12845 boolean printed = false; 12846 for (int i=0; i<mForegroundProcesses.size(); i++) { 12847 ProcessRecord r = mPidsSelfLocked.get( 12848 mForegroundProcesses.valueAt(i).pid); 12849 if (dumpPackage != null && (r == null 12850 || !r.pkgList.containsKey(dumpPackage))) { 12851 continue; 12852 } 12853 if (!printed) { 12854 if (needSep) pw.println(); 12855 needSep = true; 12856 pw.println(" Foreground Processes:"); 12857 printed = true; 12858 printedAnything = true; 12859 } 12860 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12861 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12862 } 12863 } 12864 } 12865 12866 if (mPersistentStartingProcesses.size() > 0) { 12867 if (needSep) pw.println(); 12868 needSep = true; 12869 printedAnything = true; 12870 pw.println(" Persisent processes that are starting:"); 12871 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12872 "Starting Norm", "Restarting PERS", dumpPackage); 12873 } 12874 12875 if (mRemovedProcesses.size() > 0) { 12876 if (needSep) pw.println(); 12877 needSep = true; 12878 printedAnything = true; 12879 pw.println(" Processes that are being removed:"); 12880 dumpProcessList(pw, this, mRemovedProcesses, " ", 12881 "Removed Norm", "Removed PERS", dumpPackage); 12882 } 12883 12884 if (mProcessesOnHold.size() > 0) { 12885 if (needSep) pw.println(); 12886 needSep = true; 12887 printedAnything = true; 12888 pw.println(" Processes that are on old until the system is ready:"); 12889 dumpProcessList(pw, this, mProcessesOnHold, " ", 12890 "OnHold Norm", "OnHold PERS", dumpPackage); 12891 } 12892 12893 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12894 12895 if (mProcessCrashTimes.getMap().size() > 0) { 12896 boolean printed = false; 12897 long now = SystemClock.uptimeMillis(); 12898 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12899 final int NP = pmap.size(); 12900 for (int ip=0; ip<NP; ip++) { 12901 String pname = pmap.keyAt(ip); 12902 SparseArray<Long> uids = pmap.valueAt(ip); 12903 final int N = uids.size(); 12904 for (int i=0; i<N; i++) { 12905 int puid = uids.keyAt(i); 12906 ProcessRecord r = mProcessNames.get(pname, puid); 12907 if (dumpPackage != null && (r == null 12908 || !r.pkgList.containsKey(dumpPackage))) { 12909 continue; 12910 } 12911 if (!printed) { 12912 if (needSep) pw.println(); 12913 needSep = true; 12914 pw.println(" Time since processes crashed:"); 12915 printed = true; 12916 printedAnything = true; 12917 } 12918 pw.print(" Process "); pw.print(pname); 12919 pw.print(" uid "); pw.print(puid); 12920 pw.print(": last crashed "); 12921 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12922 pw.println(" ago"); 12923 } 12924 } 12925 } 12926 12927 if (mBadProcesses.getMap().size() > 0) { 12928 boolean printed = false; 12929 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12930 final int NP = pmap.size(); 12931 for (int ip=0; ip<NP; ip++) { 12932 String pname = pmap.keyAt(ip); 12933 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12934 final int N = uids.size(); 12935 for (int i=0; i<N; i++) { 12936 int puid = uids.keyAt(i); 12937 ProcessRecord r = mProcessNames.get(pname, puid); 12938 if (dumpPackage != null && (r == null 12939 || !r.pkgList.containsKey(dumpPackage))) { 12940 continue; 12941 } 12942 if (!printed) { 12943 if (needSep) pw.println(); 12944 needSep = true; 12945 pw.println(" Bad processes:"); 12946 printedAnything = true; 12947 } 12948 BadProcessInfo info = uids.valueAt(i); 12949 pw.print(" Bad process "); pw.print(pname); 12950 pw.print(" uid "); pw.print(puid); 12951 pw.print(": crashed at time "); pw.println(info.time); 12952 if (info.shortMsg != null) { 12953 pw.print(" Short msg: "); pw.println(info.shortMsg); 12954 } 12955 if (info.longMsg != null) { 12956 pw.print(" Long msg: "); pw.println(info.longMsg); 12957 } 12958 if (info.stack != null) { 12959 pw.println(" Stack:"); 12960 int lastPos = 0; 12961 for (int pos=0; pos<info.stack.length(); pos++) { 12962 if (info.stack.charAt(pos) == '\n') { 12963 pw.print(" "); 12964 pw.write(info.stack, lastPos, pos-lastPos); 12965 pw.println(); 12966 lastPos = pos+1; 12967 } 12968 } 12969 if (lastPos < info.stack.length()) { 12970 pw.print(" "); 12971 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12972 pw.println(); 12973 } 12974 } 12975 } 12976 } 12977 } 12978 12979 if (dumpPackage == null) { 12980 pw.println(); 12981 needSep = false; 12982 pw.println(" mStartedUsers:"); 12983 for (int i=0; i<mStartedUsers.size(); i++) { 12984 UserStartedState uss = mStartedUsers.valueAt(i); 12985 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12986 pw.print(": "); uss.dump("", pw); 12987 } 12988 pw.print(" mStartedUserArray: ["); 12989 for (int i=0; i<mStartedUserArray.length; i++) { 12990 if (i > 0) pw.print(", "); 12991 pw.print(mStartedUserArray[i]); 12992 } 12993 pw.println("]"); 12994 pw.print(" mUserLru: ["); 12995 for (int i=0; i<mUserLru.size(); i++) { 12996 if (i > 0) pw.print(", "); 12997 pw.print(mUserLru.get(i)); 12998 } 12999 pw.println("]"); 13000 if (dumpAll) { 13001 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 13002 } 13003 synchronized (mUserProfileGroupIdsSelfLocked) { 13004 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 13005 pw.println(" mUserProfileGroupIds:"); 13006 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 13007 pw.print(" User #"); 13008 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 13009 pw.print(" -> profile #"); 13010 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 13011 } 13012 } 13013 } 13014 } 13015 if (mHomeProcess != null && (dumpPackage == null 13016 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 13017 if (needSep) { 13018 pw.println(); 13019 needSep = false; 13020 } 13021 pw.println(" mHomeProcess: " + mHomeProcess); 13022 } 13023 if (mPreviousProcess != null && (dumpPackage == null 13024 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 13025 if (needSep) { 13026 pw.println(); 13027 needSep = false; 13028 } 13029 pw.println(" mPreviousProcess: " + mPreviousProcess); 13030 } 13031 if (dumpAll) { 13032 StringBuilder sb = new StringBuilder(128); 13033 sb.append(" mPreviousProcessVisibleTime: "); 13034 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 13035 pw.println(sb); 13036 } 13037 if (mHeavyWeightProcess != null && (dumpPackage == null 13038 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 13039 if (needSep) { 13040 pw.println(); 13041 needSep = false; 13042 } 13043 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13044 } 13045 if (dumpPackage == null) { 13046 pw.println(" mConfiguration: " + mConfiguration); 13047 } 13048 if (dumpAll) { 13049 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 13050 if (mCompatModePackages.getPackages().size() > 0) { 13051 boolean printed = false; 13052 for (Map.Entry<String, Integer> entry 13053 : mCompatModePackages.getPackages().entrySet()) { 13054 String pkg = entry.getKey(); 13055 int mode = entry.getValue(); 13056 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 13057 continue; 13058 } 13059 if (!printed) { 13060 pw.println(" mScreenCompatPackages:"); 13061 printed = true; 13062 } 13063 pw.print(" "); pw.print(pkg); pw.print(": "); 13064 pw.print(mode); pw.println(); 13065 } 13066 } 13067 } 13068 if (dumpPackage == null) { 13069 pw.println(" mWakefulness=" 13070 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 13071 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" 13072 + lockScreenShownToString()); 13073 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice 13074 + " mTestPssMode=" + mTestPssMode); 13075 } 13076 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 13077 || mOrigWaitForDebugger) { 13078 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 13079 || dumpPackage.equals(mOrigDebugApp)) { 13080 if (needSep) { 13081 pw.println(); 13082 needSep = false; 13083 } 13084 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 13085 + " mDebugTransient=" + mDebugTransient 13086 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 13087 } 13088 } 13089 if (mOpenGlTraceApp != null) { 13090 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 13091 if (needSep) { 13092 pw.println(); 13093 needSep = false; 13094 } 13095 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 13096 } 13097 } 13098 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 13099 || mProfileFd != null) { 13100 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 13101 if (needSep) { 13102 pw.println(); 13103 needSep = false; 13104 } 13105 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 13106 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 13107 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 13108 + mAutoStopProfiler); 13109 pw.println(" mProfileType=" + mProfileType); 13110 } 13111 } 13112 if (dumpPackage == null) { 13113 if (mAlwaysFinishActivities || mController != null) { 13114 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 13115 + " mController=" + mController); 13116 } 13117 if (dumpAll) { 13118 pw.println(" Total persistent processes: " + numPers); 13119 pw.println(" mProcessesReady=" + mProcessesReady 13120 + " mSystemReady=" + mSystemReady 13121 + " mBooted=" + mBooted 13122 + " mFactoryTest=" + mFactoryTest); 13123 pw.println(" mBooting=" + mBooting 13124 + " mCallFinishBooting=" + mCallFinishBooting 13125 + " mBootAnimationComplete=" + mBootAnimationComplete); 13126 pw.print(" mLastPowerCheckRealtime="); 13127 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13128 pw.println(""); 13129 pw.print(" mLastPowerCheckUptime="); 13130 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13131 pw.println(""); 13132 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13133 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13134 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13135 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13136 + " (" + mLruProcesses.size() + " total)" 13137 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13138 + " mNumServiceProcs=" + mNumServiceProcs 13139 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13140 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13141 + " mLastMemoryLevel" + mLastMemoryLevel 13142 + " mLastNumProcesses" + mLastNumProcesses); 13143 long now = SystemClock.uptimeMillis(); 13144 pw.print(" mLastIdleTime="); 13145 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13146 pw.print(" mLowRamSinceLastIdle="); 13147 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13148 pw.println(); 13149 } 13150 } 13151 13152 if (!printedAnything) { 13153 pw.println(" (nothing)"); 13154 } 13155 } 13156 13157 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13158 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13159 if (mProcessesToGc.size() > 0) { 13160 boolean printed = false; 13161 long now = SystemClock.uptimeMillis(); 13162 for (int i=0; i<mProcessesToGc.size(); i++) { 13163 ProcessRecord proc = mProcessesToGc.get(i); 13164 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13165 continue; 13166 } 13167 if (!printed) { 13168 if (needSep) pw.println(); 13169 needSep = true; 13170 pw.println(" Processes that are waiting to GC:"); 13171 printed = true; 13172 } 13173 pw.print(" Process "); pw.println(proc); 13174 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13175 pw.print(", last gced="); 13176 pw.print(now-proc.lastRequestedGc); 13177 pw.print(" ms ago, last lowMem="); 13178 pw.print(now-proc.lastLowMemory); 13179 pw.println(" ms ago"); 13180 13181 } 13182 } 13183 return needSep; 13184 } 13185 13186 void printOomLevel(PrintWriter pw, String name, int adj) { 13187 pw.print(" "); 13188 if (adj >= 0) { 13189 pw.print(' '); 13190 if (adj < 10) pw.print(' '); 13191 } else { 13192 if (adj > -10) pw.print(' '); 13193 } 13194 pw.print(adj); 13195 pw.print(": "); 13196 pw.print(name); 13197 pw.print(" ("); 13198 pw.print(mProcessList.getMemLevel(adj)/1024); 13199 pw.println(" kB)"); 13200 } 13201 13202 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13203 int opti, boolean dumpAll) { 13204 boolean needSep = false; 13205 13206 if (mLruProcesses.size() > 0) { 13207 if (needSep) pw.println(); 13208 needSep = true; 13209 pw.println(" OOM levels:"); 13210 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13211 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13212 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13213 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13214 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13215 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13216 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13217 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13218 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13219 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13220 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13221 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13222 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13223 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13224 13225 if (needSep) pw.println(); 13226 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13227 pw.print(" total, non-act at "); 13228 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13229 pw.print(", non-svc at "); 13230 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13231 pw.println("):"); 13232 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13233 needSep = true; 13234 } 13235 13236 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13237 13238 pw.println(); 13239 pw.println(" mHomeProcess: " + mHomeProcess); 13240 pw.println(" mPreviousProcess: " + mPreviousProcess); 13241 if (mHeavyWeightProcess != null) { 13242 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13243 } 13244 13245 return true; 13246 } 13247 13248 /** 13249 * There are three ways to call this: 13250 * - no provider specified: dump all the providers 13251 * - a flattened component name that matched an existing provider was specified as the 13252 * first arg: dump that one provider 13253 * - the first arg isn't the flattened component name of an existing provider: 13254 * dump all providers whose component contains the first arg as a substring 13255 */ 13256 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13257 int opti, boolean dumpAll) { 13258 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13259 } 13260 13261 static class ItemMatcher { 13262 ArrayList<ComponentName> components; 13263 ArrayList<String> strings; 13264 ArrayList<Integer> objects; 13265 boolean all; 13266 13267 ItemMatcher() { 13268 all = true; 13269 } 13270 13271 void build(String name) { 13272 ComponentName componentName = ComponentName.unflattenFromString(name); 13273 if (componentName != null) { 13274 if (components == null) { 13275 components = new ArrayList<ComponentName>(); 13276 } 13277 components.add(componentName); 13278 all = false; 13279 } else { 13280 int objectId = 0; 13281 // Not a '/' separated full component name; maybe an object ID? 13282 try { 13283 objectId = Integer.parseInt(name, 16); 13284 if (objects == null) { 13285 objects = new ArrayList<Integer>(); 13286 } 13287 objects.add(objectId); 13288 all = false; 13289 } catch (RuntimeException e) { 13290 // Not an integer; just do string match. 13291 if (strings == null) { 13292 strings = new ArrayList<String>(); 13293 } 13294 strings.add(name); 13295 all = false; 13296 } 13297 } 13298 } 13299 13300 int build(String[] args, int opti) { 13301 for (; opti<args.length; opti++) { 13302 String name = args[opti]; 13303 if ("--".equals(name)) { 13304 return opti+1; 13305 } 13306 build(name); 13307 } 13308 return opti; 13309 } 13310 13311 boolean match(Object object, ComponentName comp) { 13312 if (all) { 13313 return true; 13314 } 13315 if (components != null) { 13316 for (int i=0; i<components.size(); i++) { 13317 if (components.get(i).equals(comp)) { 13318 return true; 13319 } 13320 } 13321 } 13322 if (objects != null) { 13323 for (int i=0; i<objects.size(); i++) { 13324 if (System.identityHashCode(object) == objects.get(i)) { 13325 return true; 13326 } 13327 } 13328 } 13329 if (strings != null) { 13330 String flat = comp.flattenToString(); 13331 for (int i=0; i<strings.size(); i++) { 13332 if (flat.contains(strings.get(i))) { 13333 return true; 13334 } 13335 } 13336 } 13337 return false; 13338 } 13339 } 13340 13341 /** 13342 * There are three things that cmd can be: 13343 * - a flattened component name that matches an existing activity 13344 * - the cmd arg isn't the flattened component name of an existing activity: 13345 * dump all activity whose component contains the cmd as a substring 13346 * - A hex number of the ActivityRecord object instance. 13347 */ 13348 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13349 int opti, boolean dumpAll) { 13350 ArrayList<ActivityRecord> activities; 13351 13352 synchronized (this) { 13353 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13354 } 13355 13356 if (activities.size() <= 0) { 13357 return false; 13358 } 13359 13360 String[] newArgs = new String[args.length - opti]; 13361 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13362 13363 TaskRecord lastTask = null; 13364 boolean needSep = false; 13365 for (int i=activities.size()-1; i>=0; i--) { 13366 ActivityRecord r = activities.get(i); 13367 if (needSep) { 13368 pw.println(); 13369 } 13370 needSep = true; 13371 synchronized (this) { 13372 if (lastTask != r.task) { 13373 lastTask = r.task; 13374 pw.print("TASK "); pw.print(lastTask.affinity); 13375 pw.print(" id="); pw.println(lastTask.taskId); 13376 if (dumpAll) { 13377 lastTask.dump(pw, " "); 13378 } 13379 } 13380 } 13381 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13382 } 13383 return true; 13384 } 13385 13386 /** 13387 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13388 * there is a thread associated with the activity. 13389 */ 13390 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13391 final ActivityRecord r, String[] args, boolean dumpAll) { 13392 String innerPrefix = prefix + " "; 13393 synchronized (this) { 13394 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13395 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13396 pw.print(" pid="); 13397 if (r.app != null) pw.println(r.app.pid); 13398 else pw.println("(not running)"); 13399 if (dumpAll) { 13400 r.dump(pw, innerPrefix); 13401 } 13402 } 13403 if (r.app != null && r.app.thread != null) { 13404 // flush anything that is already in the PrintWriter since the thread is going 13405 // to write to the file descriptor directly 13406 pw.flush(); 13407 try { 13408 TransferPipe tp = new TransferPipe(); 13409 try { 13410 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13411 r.appToken, innerPrefix, args); 13412 tp.go(fd); 13413 } finally { 13414 tp.kill(); 13415 } 13416 } catch (IOException e) { 13417 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13418 } catch (RemoteException e) { 13419 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13420 } 13421 } 13422 } 13423 13424 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13425 int opti, boolean dumpAll, String dumpPackage) { 13426 boolean needSep = false; 13427 boolean onlyHistory = false; 13428 boolean printedAnything = false; 13429 13430 if ("history".equals(dumpPackage)) { 13431 if (opti < args.length && "-s".equals(args[opti])) { 13432 dumpAll = false; 13433 } 13434 onlyHistory = true; 13435 dumpPackage = null; 13436 } 13437 13438 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13439 if (!onlyHistory && dumpAll) { 13440 if (mRegisteredReceivers.size() > 0) { 13441 boolean printed = false; 13442 Iterator it = mRegisteredReceivers.values().iterator(); 13443 while (it.hasNext()) { 13444 ReceiverList r = (ReceiverList)it.next(); 13445 if (dumpPackage != null && (r.app == null || 13446 !dumpPackage.equals(r.app.info.packageName))) { 13447 continue; 13448 } 13449 if (!printed) { 13450 pw.println(" Registered Receivers:"); 13451 needSep = true; 13452 printed = true; 13453 printedAnything = true; 13454 } 13455 pw.print(" * "); pw.println(r); 13456 r.dump(pw, " "); 13457 } 13458 } 13459 13460 if (mReceiverResolver.dump(pw, needSep ? 13461 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13462 " ", dumpPackage, false, false)) { 13463 needSep = true; 13464 printedAnything = true; 13465 } 13466 } 13467 13468 for (BroadcastQueue q : mBroadcastQueues) { 13469 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13470 printedAnything |= needSep; 13471 } 13472 13473 needSep = true; 13474 13475 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13476 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13477 if (needSep) { 13478 pw.println(); 13479 } 13480 needSep = true; 13481 printedAnything = true; 13482 pw.print(" Sticky broadcasts for user "); 13483 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13484 StringBuilder sb = new StringBuilder(128); 13485 for (Map.Entry<String, ArrayList<Intent>> ent 13486 : mStickyBroadcasts.valueAt(user).entrySet()) { 13487 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13488 if (dumpAll) { 13489 pw.println(":"); 13490 ArrayList<Intent> intents = ent.getValue(); 13491 final int N = intents.size(); 13492 for (int i=0; i<N; i++) { 13493 sb.setLength(0); 13494 sb.append(" Intent: "); 13495 intents.get(i).toShortString(sb, false, true, false, false); 13496 pw.println(sb.toString()); 13497 Bundle bundle = intents.get(i).getExtras(); 13498 if (bundle != null) { 13499 pw.print(" "); 13500 pw.println(bundle.toString()); 13501 } 13502 } 13503 } else { 13504 pw.println(""); 13505 } 13506 } 13507 } 13508 } 13509 13510 if (!onlyHistory && dumpAll) { 13511 pw.println(); 13512 for (BroadcastQueue queue : mBroadcastQueues) { 13513 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13514 + queue.mBroadcastsScheduled); 13515 } 13516 pw.println(" mHandler:"); 13517 mHandler.dump(new PrintWriterPrinter(pw), " "); 13518 needSep = true; 13519 printedAnything = true; 13520 } 13521 13522 if (!printedAnything) { 13523 pw.println(" (nothing)"); 13524 } 13525 } 13526 13527 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13528 int opti, boolean dumpAll, String dumpPackage) { 13529 boolean needSep; 13530 boolean printedAnything = false; 13531 13532 ItemMatcher matcher = new ItemMatcher(); 13533 matcher.build(args, opti); 13534 13535 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13536 13537 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13538 printedAnything |= needSep; 13539 13540 if (mLaunchingProviders.size() > 0) { 13541 boolean printed = false; 13542 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13543 ContentProviderRecord r = mLaunchingProviders.get(i); 13544 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13545 continue; 13546 } 13547 if (!printed) { 13548 if (needSep) pw.println(); 13549 needSep = true; 13550 pw.println(" Launching content providers:"); 13551 printed = true; 13552 printedAnything = true; 13553 } 13554 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13555 pw.println(r); 13556 } 13557 } 13558 13559 if (mGrantedUriPermissions.size() > 0) { 13560 boolean printed = false; 13561 int dumpUid = -2; 13562 if (dumpPackage != null) { 13563 try { 13564 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13565 } catch (NameNotFoundException e) { 13566 dumpUid = -1; 13567 } 13568 } 13569 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13570 int uid = mGrantedUriPermissions.keyAt(i); 13571 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13572 continue; 13573 } 13574 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13575 if (!printed) { 13576 if (needSep) pw.println(); 13577 needSep = true; 13578 pw.println(" Granted Uri Permissions:"); 13579 printed = true; 13580 printedAnything = true; 13581 } 13582 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13583 for (UriPermission perm : perms.values()) { 13584 pw.print(" "); pw.println(perm); 13585 if (dumpAll) { 13586 perm.dump(pw, " "); 13587 } 13588 } 13589 } 13590 } 13591 13592 if (!printedAnything) { 13593 pw.println(" (nothing)"); 13594 } 13595 } 13596 13597 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13598 int opti, boolean dumpAll, String dumpPackage) { 13599 boolean printed = false; 13600 13601 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13602 13603 if (mIntentSenderRecords.size() > 0) { 13604 Iterator<WeakReference<PendingIntentRecord>> it 13605 = mIntentSenderRecords.values().iterator(); 13606 while (it.hasNext()) { 13607 WeakReference<PendingIntentRecord> ref = it.next(); 13608 PendingIntentRecord rec = ref != null ? ref.get(): null; 13609 if (dumpPackage != null && (rec == null 13610 || !dumpPackage.equals(rec.key.packageName))) { 13611 continue; 13612 } 13613 printed = true; 13614 if (rec != null) { 13615 pw.print(" * "); pw.println(rec); 13616 if (dumpAll) { 13617 rec.dump(pw, " "); 13618 } 13619 } else { 13620 pw.print(" * "); pw.println(ref); 13621 } 13622 } 13623 } 13624 13625 if (!printed) { 13626 pw.println(" (nothing)"); 13627 } 13628 } 13629 13630 private static final int dumpProcessList(PrintWriter pw, 13631 ActivityManagerService service, List list, 13632 String prefix, String normalLabel, String persistentLabel, 13633 String dumpPackage) { 13634 int numPers = 0; 13635 final int N = list.size()-1; 13636 for (int i=N; i>=0; i--) { 13637 ProcessRecord r = (ProcessRecord)list.get(i); 13638 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13639 continue; 13640 } 13641 pw.println(String.format("%s%s #%2d: %s", 13642 prefix, (r.persistent ? persistentLabel : normalLabel), 13643 i, r.toString())); 13644 if (r.persistent) { 13645 numPers++; 13646 } 13647 } 13648 return numPers; 13649 } 13650 13651 private static final boolean dumpProcessOomList(PrintWriter pw, 13652 ActivityManagerService service, List<ProcessRecord> origList, 13653 String prefix, String normalLabel, String persistentLabel, 13654 boolean inclDetails, String dumpPackage) { 13655 13656 ArrayList<Pair<ProcessRecord, Integer>> list 13657 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13658 for (int i=0; i<origList.size(); i++) { 13659 ProcessRecord r = origList.get(i); 13660 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13661 continue; 13662 } 13663 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13664 } 13665 13666 if (list.size() <= 0) { 13667 return false; 13668 } 13669 13670 Comparator<Pair<ProcessRecord, Integer>> comparator 13671 = new Comparator<Pair<ProcessRecord, Integer>>() { 13672 @Override 13673 public int compare(Pair<ProcessRecord, Integer> object1, 13674 Pair<ProcessRecord, Integer> object2) { 13675 if (object1.first.setAdj != object2.first.setAdj) { 13676 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13677 } 13678 if (object1.second.intValue() != object2.second.intValue()) { 13679 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13680 } 13681 return 0; 13682 } 13683 }; 13684 13685 Collections.sort(list, comparator); 13686 13687 final long curRealtime = SystemClock.elapsedRealtime(); 13688 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13689 final long curUptime = SystemClock.uptimeMillis(); 13690 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13691 13692 for (int i=list.size()-1; i>=0; i--) { 13693 ProcessRecord r = list.get(i).first; 13694 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13695 char schedGroup; 13696 switch (r.setSchedGroup) { 13697 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13698 schedGroup = 'B'; 13699 break; 13700 case Process.THREAD_GROUP_DEFAULT: 13701 schedGroup = 'F'; 13702 break; 13703 default: 13704 schedGroup = '?'; 13705 break; 13706 } 13707 char foreground; 13708 if (r.foregroundActivities) { 13709 foreground = 'A'; 13710 } else if (r.foregroundServices) { 13711 foreground = 'S'; 13712 } else { 13713 foreground = ' '; 13714 } 13715 String procState = ProcessList.makeProcStateString(r.curProcState); 13716 pw.print(prefix); 13717 pw.print(r.persistent ? persistentLabel : normalLabel); 13718 pw.print(" #"); 13719 int num = (origList.size()-1)-list.get(i).second; 13720 if (num < 10) pw.print(' '); 13721 pw.print(num); 13722 pw.print(": "); 13723 pw.print(oomAdj); 13724 pw.print(' '); 13725 pw.print(schedGroup); 13726 pw.print('/'); 13727 pw.print(foreground); 13728 pw.print('/'); 13729 pw.print(procState); 13730 pw.print(" trm:"); 13731 if (r.trimMemoryLevel < 10) pw.print(' '); 13732 pw.print(r.trimMemoryLevel); 13733 pw.print(' '); 13734 pw.print(r.toShortString()); 13735 pw.print(" ("); 13736 pw.print(r.adjType); 13737 pw.println(')'); 13738 if (r.adjSource != null || r.adjTarget != null) { 13739 pw.print(prefix); 13740 pw.print(" "); 13741 if (r.adjTarget instanceof ComponentName) { 13742 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13743 } else if (r.adjTarget != null) { 13744 pw.print(r.adjTarget.toString()); 13745 } else { 13746 pw.print("{null}"); 13747 } 13748 pw.print("<="); 13749 if (r.adjSource instanceof ProcessRecord) { 13750 pw.print("Proc{"); 13751 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13752 pw.println("}"); 13753 } else if (r.adjSource != null) { 13754 pw.println(r.adjSource.toString()); 13755 } else { 13756 pw.println("{null}"); 13757 } 13758 } 13759 if (inclDetails) { 13760 pw.print(prefix); 13761 pw.print(" "); 13762 pw.print("oom: max="); pw.print(r.maxAdj); 13763 pw.print(" curRaw="); pw.print(r.curRawAdj); 13764 pw.print(" setRaw="); pw.print(r.setRawAdj); 13765 pw.print(" cur="); pw.print(r.curAdj); 13766 pw.print(" set="); pw.println(r.setAdj); 13767 pw.print(prefix); 13768 pw.print(" "); 13769 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13770 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13771 pw.print(" lastPss="); pw.print(r.lastPss); 13772 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13773 pw.print(prefix); 13774 pw.print(" "); 13775 pw.print("cached="); pw.print(r.cached); 13776 pw.print(" empty="); pw.print(r.empty); 13777 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13778 13779 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13780 if (r.lastWakeTime != 0) { 13781 long wtime; 13782 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13783 synchronized (stats) { 13784 wtime = stats.getProcessWakeTime(r.info.uid, 13785 r.pid, curRealtime); 13786 } 13787 long timeUsed = wtime - r.lastWakeTime; 13788 pw.print(prefix); 13789 pw.print(" "); 13790 pw.print("keep awake over "); 13791 TimeUtils.formatDuration(realtimeSince, pw); 13792 pw.print(" used "); 13793 TimeUtils.formatDuration(timeUsed, pw); 13794 pw.print(" ("); 13795 pw.print((timeUsed*100)/realtimeSince); 13796 pw.println("%)"); 13797 } 13798 if (r.lastCpuTime != 0) { 13799 long timeUsed = r.curCpuTime - r.lastCpuTime; 13800 pw.print(prefix); 13801 pw.print(" "); 13802 pw.print("run cpu over "); 13803 TimeUtils.formatDuration(uptimeSince, pw); 13804 pw.print(" used "); 13805 TimeUtils.formatDuration(timeUsed, pw); 13806 pw.print(" ("); 13807 pw.print((timeUsed*100)/uptimeSince); 13808 pw.println("%)"); 13809 } 13810 } 13811 } 13812 } 13813 return true; 13814 } 13815 13816 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13817 String[] args) { 13818 ArrayList<ProcessRecord> procs; 13819 synchronized (this) { 13820 if (args != null && args.length > start 13821 && args[start].charAt(0) != '-') { 13822 procs = new ArrayList<ProcessRecord>(); 13823 int pid = -1; 13824 try { 13825 pid = Integer.parseInt(args[start]); 13826 } catch (NumberFormatException e) { 13827 } 13828 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13829 ProcessRecord proc = mLruProcesses.get(i); 13830 if (proc.pid == pid) { 13831 procs.add(proc); 13832 } else if (allPkgs && proc.pkgList != null 13833 && proc.pkgList.containsKey(args[start])) { 13834 procs.add(proc); 13835 } else if (proc.processName.equals(args[start])) { 13836 procs.add(proc); 13837 } 13838 } 13839 if (procs.size() <= 0) { 13840 return null; 13841 } 13842 } else { 13843 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13844 } 13845 } 13846 return procs; 13847 } 13848 13849 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13850 PrintWriter pw, String[] args) { 13851 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13852 if (procs == null) { 13853 pw.println("No process found for: " + args[0]); 13854 return; 13855 } 13856 13857 long uptime = SystemClock.uptimeMillis(); 13858 long realtime = SystemClock.elapsedRealtime(); 13859 pw.println("Applications Graphics Acceleration Info:"); 13860 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13861 13862 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13863 ProcessRecord r = procs.get(i); 13864 if (r.thread != null) { 13865 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13866 pw.flush(); 13867 try { 13868 TransferPipe tp = new TransferPipe(); 13869 try { 13870 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13871 tp.go(fd); 13872 } finally { 13873 tp.kill(); 13874 } 13875 } catch (IOException e) { 13876 pw.println("Failure while dumping the app: " + r); 13877 pw.flush(); 13878 } catch (RemoteException e) { 13879 pw.println("Got a RemoteException while dumping the app " + r); 13880 pw.flush(); 13881 } 13882 } 13883 } 13884 } 13885 13886 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13887 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13888 if (procs == null) { 13889 pw.println("No process found for: " + args[0]); 13890 return; 13891 } 13892 13893 pw.println("Applications Database Info:"); 13894 13895 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13896 ProcessRecord r = procs.get(i); 13897 if (r.thread != null) { 13898 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13899 pw.flush(); 13900 try { 13901 TransferPipe tp = new TransferPipe(); 13902 try { 13903 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13904 tp.go(fd); 13905 } finally { 13906 tp.kill(); 13907 } 13908 } catch (IOException e) { 13909 pw.println("Failure while dumping the app: " + r); 13910 pw.flush(); 13911 } catch (RemoteException e) { 13912 pw.println("Got a RemoteException while dumping the app " + r); 13913 pw.flush(); 13914 } 13915 } 13916 } 13917 } 13918 13919 final static class MemItem { 13920 final boolean isProc; 13921 final String label; 13922 final String shortLabel; 13923 final long pss; 13924 final int id; 13925 final boolean hasActivities; 13926 ArrayList<MemItem> subitems; 13927 13928 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13929 boolean _hasActivities) { 13930 isProc = true; 13931 label = _label; 13932 shortLabel = _shortLabel; 13933 pss = _pss; 13934 id = _id; 13935 hasActivities = _hasActivities; 13936 } 13937 13938 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13939 isProc = false; 13940 label = _label; 13941 shortLabel = _shortLabel; 13942 pss = _pss; 13943 id = _id; 13944 hasActivities = false; 13945 } 13946 } 13947 13948 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13949 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13950 if (sort && !isCompact) { 13951 Collections.sort(items, new Comparator<MemItem>() { 13952 @Override 13953 public int compare(MemItem lhs, MemItem rhs) { 13954 if (lhs.pss < rhs.pss) { 13955 return 1; 13956 } else if (lhs.pss > rhs.pss) { 13957 return -1; 13958 } 13959 return 0; 13960 } 13961 }); 13962 } 13963 13964 for (int i=0; i<items.size(); i++) { 13965 MemItem mi = items.get(i); 13966 if (!isCompact) { 13967 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13968 } else if (mi.isProc) { 13969 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13970 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13971 pw.println(mi.hasActivities ? ",a" : ",e"); 13972 } else { 13973 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13974 pw.println(mi.pss); 13975 } 13976 if (mi.subitems != null) { 13977 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13978 true, isCompact); 13979 } 13980 } 13981 } 13982 13983 // These are in KB. 13984 static final long[] DUMP_MEM_BUCKETS = new long[] { 13985 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13986 120*1024, 160*1024, 200*1024, 13987 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13988 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13989 }; 13990 13991 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13992 boolean stackLike) { 13993 int start = label.lastIndexOf('.'); 13994 if (start >= 0) start++; 13995 else start = 0; 13996 int end = label.length(); 13997 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13998 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13999 long bucket = DUMP_MEM_BUCKETS[i]/1024; 14000 out.append(bucket); 14001 out.append(stackLike ? "MB." : "MB "); 14002 out.append(label, start, end); 14003 return; 14004 } 14005 } 14006 out.append(memKB/1024); 14007 out.append(stackLike ? "MB." : "MB "); 14008 out.append(label, start, end); 14009 } 14010 14011 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 14012 ProcessList.NATIVE_ADJ, 14013 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 14014 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 14015 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 14016 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 14017 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 14018 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 14019 }; 14020 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 14021 "Native", 14022 "System", "Persistent", "Persistent Service", "Foreground", 14023 "Visible", "Perceptible", 14024 "Heavy Weight", "Backup", 14025 "A Services", "Home", 14026 "Previous", "B Services", "Cached" 14027 }; 14028 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 14029 "native", 14030 "sys", "pers", "persvc", "fore", 14031 "vis", "percept", 14032 "heavy", "backup", 14033 "servicea", "home", 14034 "prev", "serviceb", "cached" 14035 }; 14036 14037 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 14038 long realtime, boolean isCheckinRequest, boolean isCompact) { 14039 if (isCheckinRequest || isCompact) { 14040 // short checkin version 14041 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 14042 } else { 14043 pw.println("Applications Memory Usage (kB):"); 14044 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 14045 } 14046 } 14047 14048 private static final int KSM_SHARED = 0; 14049 private static final int KSM_SHARING = 1; 14050 private static final int KSM_UNSHARED = 2; 14051 private static final int KSM_VOLATILE = 3; 14052 14053 private final long[] getKsmInfo() { 14054 long[] longOut = new long[4]; 14055 final int[] SINGLE_LONG_FORMAT = new int[] { 14056 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14057 }; 14058 long[] longTmp = new long[1]; 14059 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14060 SINGLE_LONG_FORMAT, null, longTmp, null); 14061 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14062 longTmp[0] = 0; 14063 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14064 SINGLE_LONG_FORMAT, null, longTmp, null); 14065 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14066 longTmp[0] = 0; 14067 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14068 SINGLE_LONG_FORMAT, null, longTmp, null); 14069 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14070 longTmp[0] = 0; 14071 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14072 SINGLE_LONG_FORMAT, null, longTmp, null); 14073 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 14074 return longOut; 14075 } 14076 14077 final void dumpApplicationMemoryUsage(FileDescriptor fd, 14078 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 14079 boolean dumpDetails = false; 14080 boolean dumpFullDetails = false; 14081 boolean dumpDalvik = false; 14082 boolean oomOnly = false; 14083 boolean isCompact = false; 14084 boolean localOnly = false; 14085 boolean packages = false; 14086 14087 int opti = 0; 14088 while (opti < args.length) { 14089 String opt = args[opti]; 14090 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14091 break; 14092 } 14093 opti++; 14094 if ("-a".equals(opt)) { 14095 dumpDetails = true; 14096 dumpFullDetails = true; 14097 dumpDalvik = true; 14098 } else if ("-d".equals(opt)) { 14099 dumpDalvik = true; 14100 } else if ("-c".equals(opt)) { 14101 isCompact = true; 14102 } else if ("--oom".equals(opt)) { 14103 oomOnly = true; 14104 } else if ("--local".equals(opt)) { 14105 localOnly = true; 14106 } else if ("--package".equals(opt)) { 14107 packages = true; 14108 } else if ("-h".equals(opt)) { 14109 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 14110 pw.println(" -a: include all available information for each process."); 14111 pw.println(" -d: include dalvik details when dumping process details."); 14112 pw.println(" -c: dump in a compact machine-parseable representation."); 14113 pw.println(" --oom: only show processes organized by oom adj."); 14114 pw.println(" --local: only collect details locally, don't call process."); 14115 pw.println(" --package: interpret process arg as package, dumping all"); 14116 pw.println(" processes that have loaded that package."); 14117 pw.println("If [process] is specified it can be the name or "); 14118 pw.println("pid of a specific process to dump."); 14119 return; 14120 } else { 14121 pw.println("Unknown argument: " + opt + "; use -h for help"); 14122 } 14123 } 14124 14125 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 14126 long uptime = SystemClock.uptimeMillis(); 14127 long realtime = SystemClock.elapsedRealtime(); 14128 final long[] tmpLong = new long[1]; 14129 14130 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 14131 if (procs == null) { 14132 // No Java processes. Maybe they want to print a native process. 14133 if (args != null && args.length > opti 14134 && args[opti].charAt(0) != '-') { 14135 ArrayList<ProcessCpuTracker.Stats> nativeProcs 14136 = new ArrayList<ProcessCpuTracker.Stats>(); 14137 updateCpuStatsNow(); 14138 int findPid = -1; 14139 try { 14140 findPid = Integer.parseInt(args[opti]); 14141 } catch (NumberFormatException e) { 14142 } 14143 synchronized (mProcessCpuTracker) { 14144 final int N = mProcessCpuTracker.countStats(); 14145 for (int i=0; i<N; i++) { 14146 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14147 if (st.pid == findPid || (st.baseName != null 14148 && st.baseName.equals(args[opti]))) { 14149 nativeProcs.add(st); 14150 } 14151 } 14152 } 14153 if (nativeProcs.size() > 0) { 14154 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14155 isCompact); 14156 Debug.MemoryInfo mi = null; 14157 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14158 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14159 final int pid = r.pid; 14160 if (!isCheckinRequest && dumpDetails) { 14161 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14162 } 14163 if (mi == null) { 14164 mi = new Debug.MemoryInfo(); 14165 } 14166 if (dumpDetails || (!brief && !oomOnly)) { 14167 Debug.getMemoryInfo(pid, mi); 14168 } else { 14169 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14170 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14171 } 14172 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14173 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14174 if (isCheckinRequest) { 14175 pw.println(); 14176 } 14177 } 14178 return; 14179 } 14180 } 14181 pw.println("No process found for: " + args[opti]); 14182 return; 14183 } 14184 14185 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14186 dumpDetails = true; 14187 } 14188 14189 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14190 14191 String[] innerArgs = new String[args.length-opti]; 14192 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14193 14194 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14195 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14196 long nativePss = 0; 14197 long dalvikPss = 0; 14198 long otherPss = 0; 14199 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14200 14201 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14202 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14203 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14204 14205 long totalPss = 0; 14206 long cachedPss = 0; 14207 14208 Debug.MemoryInfo mi = null; 14209 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14210 final ProcessRecord r = procs.get(i); 14211 final IApplicationThread thread; 14212 final int pid; 14213 final int oomAdj; 14214 final boolean hasActivities; 14215 synchronized (this) { 14216 thread = r.thread; 14217 pid = r.pid; 14218 oomAdj = r.getSetAdjWithServices(); 14219 hasActivities = r.activities.size() > 0; 14220 } 14221 if (thread != null) { 14222 if (!isCheckinRequest && dumpDetails) { 14223 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14224 } 14225 if (mi == null) { 14226 mi = new Debug.MemoryInfo(); 14227 } 14228 if (dumpDetails || (!brief && !oomOnly)) { 14229 Debug.getMemoryInfo(pid, mi); 14230 } else { 14231 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 14232 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14233 } 14234 if (dumpDetails) { 14235 if (localOnly) { 14236 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14237 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14238 if (isCheckinRequest) { 14239 pw.println(); 14240 } 14241 } else { 14242 try { 14243 pw.flush(); 14244 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14245 dumpDalvik, innerArgs); 14246 } catch (RemoteException e) { 14247 if (!isCheckinRequest) { 14248 pw.println("Got RemoteException!"); 14249 pw.flush(); 14250 } 14251 } 14252 } 14253 } 14254 14255 final long myTotalPss = mi.getTotalPss(); 14256 final long myTotalUss = mi.getTotalUss(); 14257 14258 synchronized (this) { 14259 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14260 // Record this for posterity if the process has been stable. 14261 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14262 } 14263 } 14264 14265 if (!isCheckinRequest && mi != null) { 14266 totalPss += myTotalPss; 14267 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14268 (hasActivities ? " / activities)" : ")"), 14269 r.processName, myTotalPss, pid, hasActivities); 14270 procMems.add(pssItem); 14271 procMemsMap.put(pid, pssItem); 14272 14273 nativePss += mi.nativePss; 14274 dalvikPss += mi.dalvikPss; 14275 otherPss += mi.otherPss; 14276 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14277 long mem = mi.getOtherPss(j); 14278 miscPss[j] += mem; 14279 otherPss -= mem; 14280 } 14281 14282 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14283 cachedPss += myTotalPss; 14284 } 14285 14286 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14287 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14288 || oomIndex == (oomPss.length-1)) { 14289 oomPss[oomIndex] += myTotalPss; 14290 if (oomProcs[oomIndex] == null) { 14291 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14292 } 14293 oomProcs[oomIndex].add(pssItem); 14294 break; 14295 } 14296 } 14297 } 14298 } 14299 } 14300 14301 long nativeProcTotalPss = 0; 14302 14303 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14304 // If we are showing aggregations, also look for native processes to 14305 // include so that our aggregations are more accurate. 14306 updateCpuStatsNow(); 14307 mi = null; 14308 synchronized (mProcessCpuTracker) { 14309 final int N = mProcessCpuTracker.countStats(); 14310 for (int i=0; i<N; i++) { 14311 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14312 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14313 if (mi == null) { 14314 mi = new Debug.MemoryInfo(); 14315 } 14316 if (!brief && !oomOnly) { 14317 Debug.getMemoryInfo(st.pid, mi); 14318 } else { 14319 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 14320 mi.nativePrivateDirty = (int)tmpLong[0]; 14321 } 14322 14323 final long myTotalPss = mi.getTotalPss(); 14324 totalPss += myTotalPss; 14325 nativeProcTotalPss += myTotalPss; 14326 14327 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14328 st.name, myTotalPss, st.pid, false); 14329 procMems.add(pssItem); 14330 14331 nativePss += mi.nativePss; 14332 dalvikPss += mi.dalvikPss; 14333 otherPss += mi.otherPss; 14334 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14335 long mem = mi.getOtherPss(j); 14336 miscPss[j] += mem; 14337 otherPss -= mem; 14338 } 14339 oomPss[0] += myTotalPss; 14340 if (oomProcs[0] == null) { 14341 oomProcs[0] = new ArrayList<MemItem>(); 14342 } 14343 oomProcs[0].add(pssItem); 14344 } 14345 } 14346 } 14347 14348 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14349 14350 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14351 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14352 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14353 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14354 String label = Debug.MemoryInfo.getOtherLabel(j); 14355 catMems.add(new MemItem(label, label, miscPss[j], j)); 14356 } 14357 14358 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14359 for (int j=0; j<oomPss.length; j++) { 14360 if (oomPss[j] != 0) { 14361 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14362 : DUMP_MEM_OOM_LABEL[j]; 14363 MemItem item = new MemItem(label, label, oomPss[j], 14364 DUMP_MEM_OOM_ADJ[j]); 14365 item.subitems = oomProcs[j]; 14366 oomMems.add(item); 14367 } 14368 } 14369 14370 if (!brief && !oomOnly && !isCompact) { 14371 pw.println(); 14372 pw.println("Total PSS by process:"); 14373 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14374 pw.println(); 14375 } 14376 if (!isCompact) { 14377 pw.println("Total PSS by OOM adjustment:"); 14378 } 14379 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14380 if (!brief && !oomOnly) { 14381 PrintWriter out = categoryPw != null ? categoryPw : pw; 14382 if (!isCompact) { 14383 out.println(); 14384 out.println("Total PSS by category:"); 14385 } 14386 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14387 } 14388 if (!isCompact) { 14389 pw.println(); 14390 } 14391 MemInfoReader memInfo = new MemInfoReader(); 14392 memInfo.readMemInfo(); 14393 if (nativeProcTotalPss > 0) { 14394 synchronized (this) { 14395 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14396 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14397 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss); 14398 } 14399 } 14400 if (!brief) { 14401 if (!isCompact) { 14402 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14403 pw.print(" kB (status "); 14404 switch (mLastMemoryLevel) { 14405 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14406 pw.println("normal)"); 14407 break; 14408 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14409 pw.println("moderate)"); 14410 break; 14411 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14412 pw.println("low)"); 14413 break; 14414 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14415 pw.println("critical)"); 14416 break; 14417 default: 14418 pw.print(mLastMemoryLevel); 14419 pw.println(")"); 14420 break; 14421 } 14422 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14423 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14424 pw.print(cachedPss); pw.print(" cached pss + "); 14425 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + "); 14426 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14427 } else { 14428 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14429 pw.print(cachedPss + memInfo.getCachedSizeKb() 14430 + memInfo.getFreeSizeKb()); pw.print(","); 14431 pw.println(totalPss - cachedPss); 14432 } 14433 } 14434 if (!isCompact) { 14435 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14436 + memInfo.getKernelUsedSizeKb()); pw.print(" kB ("); 14437 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14438 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n"); 14439 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14440 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14441 - memInfo.getKernelUsedSizeKb()); pw.println(" kB"); 14442 } 14443 if (!brief) { 14444 if (memInfo.getZramTotalSizeKb() != 0) { 14445 if (!isCompact) { 14446 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14447 pw.print(" kB physical used for "); 14448 pw.print(memInfo.getSwapTotalSizeKb() 14449 - memInfo.getSwapFreeSizeKb()); 14450 pw.print(" kB in swap ("); 14451 pw.print(memInfo.getSwapTotalSizeKb()); 14452 pw.println(" kB total swap)"); 14453 } else { 14454 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14455 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14456 pw.println(memInfo.getSwapFreeSizeKb()); 14457 } 14458 } 14459 final long[] ksm = getKsmInfo(); 14460 if (!isCompact) { 14461 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14462 || ksm[KSM_VOLATILE] != 0) { 14463 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]); 14464 pw.print(" kB saved from shared "); 14465 pw.print(ksm[KSM_SHARED]); pw.println(" kB"); 14466 pw.print(" "); pw.print(ksm[KSM_UNSHARED]); 14467 pw.print(" kB unshared; "); 14468 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile"); 14469 } 14470 pw.print(" Tuning: "); 14471 pw.print(ActivityManager.staticGetMemoryClass()); 14472 pw.print(" (large "); 14473 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14474 pw.print("), oom "); 14475 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14476 pw.print(" kB"); 14477 pw.print(", restore limit "); 14478 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14479 pw.print(" kB"); 14480 if (ActivityManager.isLowRamDeviceStatic()) { 14481 pw.print(" (low-ram)"); 14482 } 14483 if (ActivityManager.isHighEndGfx()) { 14484 pw.print(" (high-end-gfx)"); 14485 } 14486 pw.println(); 14487 } else { 14488 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 14489 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 14490 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 14491 pw.print("tuning,"); 14492 pw.print(ActivityManager.staticGetMemoryClass()); 14493 pw.print(','); 14494 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14495 pw.print(','); 14496 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14497 if (ActivityManager.isLowRamDeviceStatic()) { 14498 pw.print(",low-ram"); 14499 } 14500 if (ActivityManager.isHighEndGfx()) { 14501 pw.print(",high-end-gfx"); 14502 } 14503 pw.println(); 14504 } 14505 } 14506 } 14507 } 14508 14509 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 14510 long memtrack, String name) { 14511 sb.append(" "); 14512 sb.append(ProcessList.makeOomAdjString(oomAdj)); 14513 sb.append(' '); 14514 sb.append(ProcessList.makeProcStateString(procState)); 14515 sb.append(' '); 14516 ProcessList.appendRamKb(sb, pss); 14517 sb.append(" kB: "); 14518 sb.append(name); 14519 if (memtrack > 0) { 14520 sb.append(" ("); 14521 sb.append(memtrack); 14522 sb.append(" kB memtrack)"); 14523 } 14524 } 14525 14526 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 14527 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 14528 sb.append(" (pid "); 14529 sb.append(mi.pid); 14530 sb.append(") "); 14531 sb.append(mi.adjType); 14532 sb.append('\n'); 14533 if (mi.adjReason != null) { 14534 sb.append(" "); 14535 sb.append(mi.adjReason); 14536 sb.append('\n'); 14537 } 14538 } 14539 14540 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 14541 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 14542 for (int i=0, N=memInfos.size(); i<N; i++) { 14543 ProcessMemInfo mi = memInfos.get(i); 14544 infoMap.put(mi.pid, mi); 14545 } 14546 updateCpuStatsNow(); 14547 long[] memtrackTmp = new long[1]; 14548 synchronized (mProcessCpuTracker) { 14549 final int N = mProcessCpuTracker.countStats(); 14550 for (int i=0; i<N; i++) { 14551 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14552 if (st.vsize > 0) { 14553 long pss = Debug.getPss(st.pid, null, memtrackTmp); 14554 if (pss > 0) { 14555 if (infoMap.indexOfKey(st.pid) < 0) { 14556 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 14557 ProcessList.NATIVE_ADJ, -1, "native", null); 14558 mi.pss = pss; 14559 mi.memtrack = memtrackTmp[0]; 14560 memInfos.add(mi); 14561 } 14562 } 14563 } 14564 } 14565 } 14566 14567 long totalPss = 0; 14568 long totalMemtrack = 0; 14569 for (int i=0, N=memInfos.size(); i<N; i++) { 14570 ProcessMemInfo mi = memInfos.get(i); 14571 if (mi.pss == 0) { 14572 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 14573 mi.memtrack = memtrackTmp[0]; 14574 } 14575 totalPss += mi.pss; 14576 totalMemtrack += mi.memtrack; 14577 } 14578 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 14579 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 14580 if (lhs.oomAdj != rhs.oomAdj) { 14581 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 14582 } 14583 if (lhs.pss != rhs.pss) { 14584 return lhs.pss < rhs.pss ? 1 : -1; 14585 } 14586 return 0; 14587 } 14588 }); 14589 14590 StringBuilder tag = new StringBuilder(128); 14591 StringBuilder stack = new StringBuilder(128); 14592 tag.append("Low on memory -- "); 14593 appendMemBucket(tag, totalPss, "total", false); 14594 appendMemBucket(stack, totalPss, "total", true); 14595 14596 StringBuilder fullNativeBuilder = new StringBuilder(1024); 14597 StringBuilder shortNativeBuilder = new StringBuilder(1024); 14598 StringBuilder fullJavaBuilder = new StringBuilder(1024); 14599 14600 boolean firstLine = true; 14601 int lastOomAdj = Integer.MIN_VALUE; 14602 long extraNativeRam = 0; 14603 long extraNativeMemtrack = 0; 14604 long cachedPss = 0; 14605 for (int i=0, N=memInfos.size(); i<N; i++) { 14606 ProcessMemInfo mi = memInfos.get(i); 14607 14608 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14609 cachedPss += mi.pss; 14610 } 14611 14612 if (mi.oomAdj != ProcessList.NATIVE_ADJ 14613 && (mi.oomAdj < ProcessList.SERVICE_ADJ 14614 || mi.oomAdj == ProcessList.HOME_APP_ADJ 14615 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 14616 if (lastOomAdj != mi.oomAdj) { 14617 lastOomAdj = mi.oomAdj; 14618 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14619 tag.append(" / "); 14620 } 14621 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 14622 if (firstLine) { 14623 stack.append(":"); 14624 firstLine = false; 14625 } 14626 stack.append("\n\t at "); 14627 } else { 14628 stack.append("$"); 14629 } 14630 } else { 14631 tag.append(" "); 14632 stack.append("$"); 14633 } 14634 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14635 appendMemBucket(tag, mi.pss, mi.name, false); 14636 } 14637 appendMemBucket(stack, mi.pss, mi.name, true); 14638 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 14639 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 14640 stack.append("("); 14641 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 14642 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 14643 stack.append(DUMP_MEM_OOM_LABEL[k]); 14644 stack.append(":"); 14645 stack.append(DUMP_MEM_OOM_ADJ[k]); 14646 } 14647 } 14648 stack.append(")"); 14649 } 14650 } 14651 14652 appendMemInfo(fullNativeBuilder, mi); 14653 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 14654 // The short form only has native processes that are >= 512K. 14655 if (mi.pss >= 512) { 14656 appendMemInfo(shortNativeBuilder, mi); 14657 } else { 14658 extraNativeRam += mi.pss; 14659 extraNativeMemtrack += mi.memtrack; 14660 } 14661 } else { 14662 // Short form has all other details, but if we have collected RAM 14663 // from smaller native processes let's dump a summary of that. 14664 if (extraNativeRam > 0) { 14665 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 14666 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 14667 shortNativeBuilder.append('\n'); 14668 extraNativeRam = 0; 14669 } 14670 appendMemInfo(fullJavaBuilder, mi); 14671 } 14672 } 14673 14674 fullJavaBuilder.append(" "); 14675 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 14676 fullJavaBuilder.append(" kB: TOTAL"); 14677 if (totalMemtrack > 0) { 14678 fullJavaBuilder.append(" ("); 14679 fullJavaBuilder.append(totalMemtrack); 14680 fullJavaBuilder.append(" kB memtrack)"); 14681 } else { 14682 } 14683 fullJavaBuilder.append("\n"); 14684 14685 MemInfoReader memInfo = new MemInfoReader(); 14686 memInfo.readMemInfo(); 14687 final long[] infos = memInfo.getRawInfo(); 14688 14689 StringBuilder memInfoBuilder = new StringBuilder(1024); 14690 Debug.getMemInfo(infos); 14691 memInfoBuilder.append(" MemInfo: "); 14692 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 14693 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 14694 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, "); 14695 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables "); 14696 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n"); 14697 memInfoBuilder.append(" "); 14698 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 14699 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 14700 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, "); 14701 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 14702 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 14703 memInfoBuilder.append(" ZRAM: "); 14704 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 14705 memInfoBuilder.append(" kB RAM, "); 14706 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 14707 memInfoBuilder.append(" kB swap total, "); 14708 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 14709 memInfoBuilder.append(" kB swap free\n"); 14710 } 14711 final long[] ksm = getKsmInfo(); 14712 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 14713 || ksm[KSM_VOLATILE] != 0) { 14714 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]); 14715 memInfoBuilder.append(" kB saved from shared "); 14716 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n"); 14717 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]); 14718 memInfoBuilder.append(" kB unshared; "); 14719 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n"); 14720 } 14721 memInfoBuilder.append(" Free RAM: "); 14722 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb() 14723 + memInfo.getFreeSizeKb()); 14724 memInfoBuilder.append(" kB\n"); 14725 memInfoBuilder.append(" Used RAM: "); 14726 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb()); 14727 memInfoBuilder.append(" kB\n"); 14728 memInfoBuilder.append(" Lost RAM: "); 14729 memInfoBuilder.append(memInfo.getTotalSizeKb() 14730 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14731 - memInfo.getKernelUsedSizeKb()); 14732 memInfoBuilder.append(" kB\n"); 14733 Slog.i(TAG, "Low on memory:"); 14734 Slog.i(TAG, shortNativeBuilder.toString()); 14735 Slog.i(TAG, fullJavaBuilder.toString()); 14736 Slog.i(TAG, memInfoBuilder.toString()); 14737 14738 StringBuilder dropBuilder = new StringBuilder(1024); 14739 /* 14740 StringWriter oomSw = new StringWriter(); 14741 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 14742 StringWriter catSw = new StringWriter(); 14743 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14744 String[] emptyArgs = new String[] { }; 14745 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 14746 oomPw.flush(); 14747 String oomString = oomSw.toString(); 14748 */ 14749 dropBuilder.append("Low on memory:"); 14750 dropBuilder.append(stack); 14751 dropBuilder.append('\n'); 14752 dropBuilder.append(fullNativeBuilder); 14753 dropBuilder.append(fullJavaBuilder); 14754 dropBuilder.append('\n'); 14755 dropBuilder.append(memInfoBuilder); 14756 dropBuilder.append('\n'); 14757 /* 14758 dropBuilder.append(oomString); 14759 dropBuilder.append('\n'); 14760 */ 14761 StringWriter catSw = new StringWriter(); 14762 synchronized (ActivityManagerService.this) { 14763 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 14764 String[] emptyArgs = new String[] { }; 14765 catPw.println(); 14766 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 14767 catPw.println(); 14768 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 14769 false, false, null); 14770 catPw.println(); 14771 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 14772 catPw.flush(); 14773 } 14774 dropBuilder.append(catSw.toString()); 14775 addErrorToDropBox("lowmem", null, "system_server", null, 14776 null, tag.toString(), dropBuilder.toString(), null, null); 14777 //Slog.i(TAG, "Sent to dropbox:"); 14778 //Slog.i(TAG, dropBuilder.toString()); 14779 synchronized (ActivityManagerService.this) { 14780 long now = SystemClock.uptimeMillis(); 14781 if (mLastMemUsageReportTime < now) { 14782 mLastMemUsageReportTime = now; 14783 } 14784 } 14785 } 14786 14787 /** 14788 * Searches array of arguments for the specified string 14789 * @param args array of argument strings 14790 * @param value value to search for 14791 * @return true if the value is contained in the array 14792 */ 14793 private static boolean scanArgs(String[] args, String value) { 14794 if (args != null) { 14795 for (String arg : args) { 14796 if (value.equals(arg)) { 14797 return true; 14798 } 14799 } 14800 } 14801 return false; 14802 } 14803 14804 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14805 ContentProviderRecord cpr, boolean always) { 14806 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14807 14808 if (!inLaunching || always) { 14809 synchronized (cpr) { 14810 cpr.launchingApp = null; 14811 cpr.notifyAll(); 14812 } 14813 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14814 String names[] = cpr.info.authority.split(";"); 14815 for (int j = 0; j < names.length; j++) { 14816 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14817 } 14818 } 14819 14820 for (int i=0; i<cpr.connections.size(); i++) { 14821 ContentProviderConnection conn = cpr.connections.get(i); 14822 if (conn.waiting) { 14823 // If this connection is waiting for the provider, then we don't 14824 // need to mess with its process unless we are always removing 14825 // or for some reason the provider is not currently launching. 14826 if (inLaunching && !always) { 14827 continue; 14828 } 14829 } 14830 ProcessRecord capp = conn.client; 14831 conn.dead = true; 14832 if (conn.stableCount > 0) { 14833 if (!capp.persistent && capp.thread != null 14834 && capp.pid != 0 14835 && capp.pid != MY_PID) { 14836 capp.kill("depends on provider " 14837 + cpr.name.flattenToShortString() 14838 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14839 } 14840 } else if (capp.thread != null && conn.provider.provider != null) { 14841 try { 14842 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14843 } catch (RemoteException e) { 14844 } 14845 // In the protocol here, we don't expect the client to correctly 14846 // clean up this connection, we'll just remove it. 14847 cpr.connections.remove(i); 14848 if (conn.client.conProviders.remove(conn)) { 14849 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 14850 } 14851 } 14852 } 14853 14854 if (inLaunching && always) { 14855 mLaunchingProviders.remove(cpr); 14856 } 14857 return inLaunching; 14858 } 14859 14860 /** 14861 * Main code for cleaning up a process when it has gone away. This is 14862 * called both as a result of the process dying, or directly when stopping 14863 * a process when running in single process mode. 14864 * 14865 * @return Returns true if the given process has been restarted, so the 14866 * app that was passed in must remain on the process lists. 14867 */ 14868 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14869 boolean restarting, boolean allowRestart, int index) { 14870 if (index >= 0) { 14871 removeLruProcessLocked(app); 14872 ProcessList.remove(app.pid); 14873 } 14874 14875 mProcessesToGc.remove(app); 14876 mPendingPssProcesses.remove(app); 14877 14878 // Dismiss any open dialogs. 14879 if (app.crashDialog != null && !app.forceCrashReport) { 14880 app.crashDialog.dismiss(); 14881 app.crashDialog = null; 14882 } 14883 if (app.anrDialog != null) { 14884 app.anrDialog.dismiss(); 14885 app.anrDialog = null; 14886 } 14887 if (app.waitDialog != null) { 14888 app.waitDialog.dismiss(); 14889 app.waitDialog = null; 14890 } 14891 14892 app.crashing = false; 14893 app.notResponding = false; 14894 14895 app.resetPackageList(mProcessStats); 14896 app.unlinkDeathRecipient(); 14897 app.makeInactive(mProcessStats); 14898 app.waitingToKill = null; 14899 app.forcingToForeground = null; 14900 updateProcessForegroundLocked(app, false, false); 14901 app.foregroundActivities = false; 14902 app.hasShownUi = false; 14903 app.treatLikeActivity = false; 14904 app.hasAboveClient = false; 14905 app.hasClientActivities = false; 14906 14907 mServices.killServicesLocked(app, allowRestart); 14908 14909 boolean restart = false; 14910 14911 // Remove published content providers. 14912 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14913 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14914 final boolean always = app.bad || !allowRestart; 14915 if (removeDyingProviderLocked(app, cpr, always) || always) { 14916 // We left the provider in the launching list, need to 14917 // restart it. 14918 restart = true; 14919 } 14920 14921 cpr.provider = null; 14922 cpr.proc = null; 14923 } 14924 app.pubProviders.clear(); 14925 14926 // Take care of any launching providers waiting for this process. 14927 if (checkAppInLaunchingProvidersLocked(app, false)) { 14928 restart = true; 14929 } 14930 14931 // Unregister from connected content providers. 14932 if (!app.conProviders.isEmpty()) { 14933 for (int i=0; i<app.conProviders.size(); i++) { 14934 ContentProviderConnection conn = app.conProviders.get(i); 14935 conn.provider.connections.remove(conn); 14936 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 14937 conn.provider.name); 14938 } 14939 app.conProviders.clear(); 14940 } 14941 14942 // At this point there may be remaining entries in mLaunchingProviders 14943 // where we were the only one waiting, so they are no longer of use. 14944 // Look for these and clean up if found. 14945 // XXX Commented out for now. Trying to figure out a way to reproduce 14946 // the actual situation to identify what is actually going on. 14947 if (false) { 14948 for (int i=0; i<mLaunchingProviders.size(); i++) { 14949 ContentProviderRecord cpr = (ContentProviderRecord) 14950 mLaunchingProviders.get(i); 14951 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14952 synchronized (cpr) { 14953 cpr.launchingApp = null; 14954 cpr.notifyAll(); 14955 } 14956 } 14957 } 14958 } 14959 14960 skipCurrentReceiverLocked(app); 14961 14962 // Unregister any receivers. 14963 for (int i=app.receivers.size()-1; i>=0; i--) { 14964 removeReceiverLocked(app.receivers.valueAt(i)); 14965 } 14966 app.receivers.clear(); 14967 14968 // If the app is undergoing backup, tell the backup manager about it 14969 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14970 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14971 + mBackupTarget.appInfo + " died during backup"); 14972 try { 14973 IBackupManager bm = IBackupManager.Stub.asInterface( 14974 ServiceManager.getService(Context.BACKUP_SERVICE)); 14975 bm.agentDisconnected(app.info.packageName); 14976 } catch (RemoteException e) { 14977 // can't happen; backup manager is local 14978 } 14979 } 14980 14981 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14982 ProcessChangeItem item = mPendingProcessChanges.get(i); 14983 if (item.pid == app.pid) { 14984 mPendingProcessChanges.remove(i); 14985 mAvailProcessChanges.add(item); 14986 } 14987 } 14988 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14989 14990 // If the caller is restarting this app, then leave it in its 14991 // current lists and let the caller take care of it. 14992 if (restarting) { 14993 return false; 14994 } 14995 14996 if (!app.persistent || app.isolated) { 14997 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14998 "Removing non-persistent process during cleanup: " + app); 14999 mProcessNames.remove(app.processName, app.uid); 15000 mIsolatedProcesses.remove(app.uid); 15001 if (mHeavyWeightProcess == app) { 15002 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 15003 mHeavyWeightProcess.userId, 0)); 15004 mHeavyWeightProcess = null; 15005 } 15006 } else if (!app.removed) { 15007 // This app is persistent, so we need to keep its record around. 15008 // If it is not already on the pending app list, add it there 15009 // and start a new process for it. 15010 if (mPersistentStartingProcesses.indexOf(app) < 0) { 15011 mPersistentStartingProcesses.add(app); 15012 restart = true; 15013 } 15014 } 15015 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 15016 "Clean-up removing on hold: " + app); 15017 mProcessesOnHold.remove(app); 15018 15019 if (app == mHomeProcess) { 15020 mHomeProcess = null; 15021 } 15022 if (app == mPreviousProcess) { 15023 mPreviousProcess = null; 15024 } 15025 15026 if (restart && !app.isolated) { 15027 // We have components that still need to be running in the 15028 // process, so re-launch it. 15029 if (index < 0) { 15030 ProcessList.remove(app.pid); 15031 } 15032 mProcessNames.put(app.processName, app.uid, app); 15033 startProcessLocked(app, "restart", app.processName); 15034 return true; 15035 } else if (app.pid > 0 && app.pid != MY_PID) { 15036 // Goodbye! 15037 boolean removed; 15038 synchronized (mPidsSelfLocked) { 15039 mPidsSelfLocked.remove(app.pid); 15040 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 15041 } 15042 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 15043 if (app.isolated) { 15044 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 15045 } 15046 app.setPid(0); 15047 } 15048 return false; 15049 } 15050 15051 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 15052 // Look through the content providers we are waiting to have launched, 15053 // and if any run in this process then either schedule a restart of 15054 // the process or kill the client waiting for it if this process has 15055 // gone bad. 15056 int NL = mLaunchingProviders.size(); 15057 boolean restart = false; 15058 for (int i=0; i<NL; i++) { 15059 ContentProviderRecord cpr = mLaunchingProviders.get(i); 15060 if (cpr.launchingApp == app) { 15061 if (!alwaysBad && !app.bad) { 15062 restart = true; 15063 } else { 15064 removeDyingProviderLocked(app, cpr, true); 15065 // cpr should have been removed from mLaunchingProviders 15066 NL = mLaunchingProviders.size(); 15067 i--; 15068 } 15069 } 15070 } 15071 return restart; 15072 } 15073 15074 // ========================================================= 15075 // SERVICES 15076 // ========================================================= 15077 15078 @Override 15079 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 15080 int flags) { 15081 enforceNotIsolatedCaller("getServices"); 15082 synchronized (this) { 15083 return mServices.getRunningServiceInfoLocked(maxNum, flags); 15084 } 15085 } 15086 15087 @Override 15088 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 15089 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 15090 synchronized (this) { 15091 return mServices.getRunningServiceControlPanelLocked(name); 15092 } 15093 } 15094 15095 @Override 15096 public ComponentName startService(IApplicationThread caller, Intent service, 15097 String resolvedType, int userId) { 15098 enforceNotIsolatedCaller("startService"); 15099 // Refuse possible leaked file descriptors 15100 if (service != null && service.hasFileDescriptors() == true) { 15101 throw new IllegalArgumentException("File descriptors passed in Intent"); 15102 } 15103 15104 if (DEBUG_SERVICE) 15105 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 15106 synchronized(this) { 15107 final int callingPid = Binder.getCallingPid(); 15108 final int callingUid = Binder.getCallingUid(); 15109 final long origId = Binder.clearCallingIdentity(); 15110 ComponentName res = mServices.startServiceLocked(caller, service, 15111 resolvedType, callingPid, callingUid, userId); 15112 Binder.restoreCallingIdentity(origId); 15113 return res; 15114 } 15115 } 15116 15117 ComponentName startServiceInPackage(int uid, 15118 Intent service, String resolvedType, int userId) { 15119 synchronized(this) { 15120 if (DEBUG_SERVICE) 15121 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 15122 final long origId = Binder.clearCallingIdentity(); 15123 ComponentName res = mServices.startServiceLocked(null, service, 15124 resolvedType, -1, uid, userId); 15125 Binder.restoreCallingIdentity(origId); 15126 return res; 15127 } 15128 } 15129 15130 @Override 15131 public int stopService(IApplicationThread caller, Intent service, 15132 String resolvedType, int userId) { 15133 enforceNotIsolatedCaller("stopService"); 15134 // Refuse possible leaked file descriptors 15135 if (service != null && service.hasFileDescriptors() == true) { 15136 throw new IllegalArgumentException("File descriptors passed in Intent"); 15137 } 15138 15139 synchronized(this) { 15140 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 15141 } 15142 } 15143 15144 @Override 15145 public IBinder peekService(Intent service, String resolvedType) { 15146 enforceNotIsolatedCaller("peekService"); 15147 // Refuse possible leaked file descriptors 15148 if (service != null && service.hasFileDescriptors() == true) { 15149 throw new IllegalArgumentException("File descriptors passed in Intent"); 15150 } 15151 synchronized(this) { 15152 return mServices.peekServiceLocked(service, resolvedType); 15153 } 15154 } 15155 15156 @Override 15157 public boolean stopServiceToken(ComponentName className, IBinder token, 15158 int startId) { 15159 synchronized(this) { 15160 return mServices.stopServiceTokenLocked(className, token, startId); 15161 } 15162 } 15163 15164 @Override 15165 public void setServiceForeground(ComponentName className, IBinder token, 15166 int id, Notification notification, boolean removeNotification) { 15167 synchronized(this) { 15168 mServices.setServiceForegroundLocked(className, token, id, notification, 15169 removeNotification); 15170 } 15171 } 15172 15173 @Override 15174 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15175 boolean requireFull, String name, String callerPackage) { 15176 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 15177 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 15178 } 15179 15180 int unsafeConvertIncomingUser(int userId) { 15181 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 15182 ? mCurrentUserId : userId; 15183 } 15184 15185 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 15186 int allowMode, String name, String callerPackage) { 15187 final int callingUserId = UserHandle.getUserId(callingUid); 15188 if (callingUserId == userId) { 15189 return userId; 15190 } 15191 15192 // Note that we may be accessing mCurrentUserId outside of a lock... 15193 // shouldn't be a big deal, if this is being called outside 15194 // of a locked context there is intrinsically a race with 15195 // the value the caller will receive and someone else changing it. 15196 // We assume that USER_CURRENT_OR_SELF will use the current user; later 15197 // we will switch to the calling user if access to the current user fails. 15198 int targetUserId = unsafeConvertIncomingUser(userId); 15199 15200 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 15201 final boolean allow; 15202 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 15203 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 15204 // If the caller has this permission, they always pass go. And collect $200. 15205 allow = true; 15206 } else if (allowMode == ALLOW_FULL_ONLY) { 15207 // We require full access, sucks to be you. 15208 allow = false; 15209 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 15210 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 15211 // If the caller does not have either permission, they are always doomed. 15212 allow = false; 15213 } else if (allowMode == ALLOW_NON_FULL) { 15214 // We are blanket allowing non-full access, you lucky caller! 15215 allow = true; 15216 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 15217 // We may or may not allow this depending on whether the two users are 15218 // in the same profile. 15219 synchronized (mUserProfileGroupIdsSelfLocked) { 15220 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 15221 UserInfo.NO_PROFILE_GROUP_ID); 15222 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 15223 UserInfo.NO_PROFILE_GROUP_ID); 15224 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 15225 && callingProfile == targetProfile; 15226 } 15227 } else { 15228 throw new IllegalArgumentException("Unknown mode: " + allowMode); 15229 } 15230 if (!allow) { 15231 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 15232 // In this case, they would like to just execute as their 15233 // owner user instead of failing. 15234 targetUserId = callingUserId; 15235 } else { 15236 StringBuilder builder = new StringBuilder(128); 15237 builder.append("Permission Denial: "); 15238 builder.append(name); 15239 if (callerPackage != null) { 15240 builder.append(" from "); 15241 builder.append(callerPackage); 15242 } 15243 builder.append(" asks to run as user "); 15244 builder.append(userId); 15245 builder.append(" but is calling from user "); 15246 builder.append(UserHandle.getUserId(callingUid)); 15247 builder.append("; this requires "); 15248 builder.append(INTERACT_ACROSS_USERS_FULL); 15249 if (allowMode != ALLOW_FULL_ONLY) { 15250 builder.append(" or "); 15251 builder.append(INTERACT_ACROSS_USERS); 15252 } 15253 String msg = builder.toString(); 15254 Slog.w(TAG, msg); 15255 throw new SecurityException(msg); 15256 } 15257 } 15258 } 15259 if (!allowAll && targetUserId < 0) { 15260 throw new IllegalArgumentException( 15261 "Call does not support special user #" + targetUserId); 15262 } 15263 // Check shell permission 15264 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 15265 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 15266 targetUserId)) { 15267 throw new SecurityException("Shell does not have permission to access user " 15268 + targetUserId + "\n " + Debug.getCallers(3)); 15269 } 15270 } 15271 return targetUserId; 15272 } 15273 15274 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 15275 String className, int flags) { 15276 boolean result = false; 15277 // For apps that don't have pre-defined UIDs, check for permission 15278 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 15279 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15280 if (ActivityManager.checkUidPermission( 15281 INTERACT_ACROSS_USERS, 15282 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 15283 ComponentName comp = new ComponentName(aInfo.packageName, className); 15284 String msg = "Permission Denial: Component " + comp.flattenToShortString() 15285 + " requests FLAG_SINGLE_USER, but app does not hold " 15286 + INTERACT_ACROSS_USERS; 15287 Slog.w(TAG, msg); 15288 throw new SecurityException(msg); 15289 } 15290 // Permission passed 15291 result = true; 15292 } 15293 } else if ("system".equals(componentProcessName)) { 15294 result = true; 15295 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 15296 // Phone app and persistent apps are allowed to export singleuser providers. 15297 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 15298 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 15299 } 15300 if (DEBUG_MU) { 15301 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 15302 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 15303 } 15304 return result; 15305 } 15306 15307 /** 15308 * Checks to see if the caller is in the same app as the singleton 15309 * component, or the component is in a special app. It allows special apps 15310 * to export singleton components but prevents exporting singleton 15311 * components for regular apps. 15312 */ 15313 boolean isValidSingletonCall(int callingUid, int componentUid) { 15314 int componentAppId = UserHandle.getAppId(componentUid); 15315 return UserHandle.isSameApp(callingUid, componentUid) 15316 || componentAppId == Process.SYSTEM_UID 15317 || componentAppId == Process.PHONE_UID 15318 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 15319 == PackageManager.PERMISSION_GRANTED; 15320 } 15321 15322 public int bindService(IApplicationThread caller, IBinder token, 15323 Intent service, String resolvedType, 15324 IServiceConnection connection, int flags, int userId) { 15325 enforceNotIsolatedCaller("bindService"); 15326 15327 // Refuse possible leaked file descriptors 15328 if (service != null && service.hasFileDescriptors() == true) { 15329 throw new IllegalArgumentException("File descriptors passed in Intent"); 15330 } 15331 15332 synchronized(this) { 15333 return mServices.bindServiceLocked(caller, token, service, resolvedType, 15334 connection, flags, userId); 15335 } 15336 } 15337 15338 public boolean unbindService(IServiceConnection connection) { 15339 synchronized (this) { 15340 return mServices.unbindServiceLocked(connection); 15341 } 15342 } 15343 15344 public void publishService(IBinder token, Intent intent, IBinder service) { 15345 // Refuse possible leaked file descriptors 15346 if (intent != null && intent.hasFileDescriptors() == true) { 15347 throw new IllegalArgumentException("File descriptors passed in Intent"); 15348 } 15349 15350 synchronized(this) { 15351 if (!(token instanceof ServiceRecord)) { 15352 throw new IllegalArgumentException("Invalid service token"); 15353 } 15354 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 15355 } 15356 } 15357 15358 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 15359 // Refuse possible leaked file descriptors 15360 if (intent != null && intent.hasFileDescriptors() == true) { 15361 throw new IllegalArgumentException("File descriptors passed in Intent"); 15362 } 15363 15364 synchronized(this) { 15365 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 15366 } 15367 } 15368 15369 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 15370 synchronized(this) { 15371 if (!(token instanceof ServiceRecord)) { 15372 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 15373 throw new IllegalArgumentException("Invalid service token"); 15374 } 15375 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 15376 } 15377 } 15378 15379 // ========================================================= 15380 // BACKUP AND RESTORE 15381 // ========================================================= 15382 15383 // Cause the target app to be launched if necessary and its backup agent 15384 // instantiated. The backup agent will invoke backupAgentCreated() on the 15385 // activity manager to announce its creation. 15386 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 15387 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 15388 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 15389 15390 synchronized(this) { 15391 // !!! TODO: currently no check here that we're already bound 15392 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 15393 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15394 synchronized (stats) { 15395 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 15396 } 15397 15398 // Backup agent is now in use, its package can't be stopped. 15399 try { 15400 AppGlobals.getPackageManager().setPackageStoppedState( 15401 app.packageName, false, UserHandle.getUserId(app.uid)); 15402 } catch (RemoteException e) { 15403 } catch (IllegalArgumentException e) { 15404 Slog.w(TAG, "Failed trying to unstop package " 15405 + app.packageName + ": " + e); 15406 } 15407 15408 BackupRecord r = new BackupRecord(ss, app, backupMode); 15409 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 15410 ? new ComponentName(app.packageName, app.backupAgentName) 15411 : new ComponentName("android", "FullBackupAgent"); 15412 // startProcessLocked() returns existing proc's record if it's already running 15413 ProcessRecord proc = startProcessLocked(app.processName, app, 15414 false, 0, "backup", hostingName, false, false, false); 15415 if (proc == null) { 15416 Slog.e(TAG, "Unable to start backup agent process " + r); 15417 return false; 15418 } 15419 15420 r.app = proc; 15421 mBackupTarget = r; 15422 mBackupAppName = app.packageName; 15423 15424 // Try not to kill the process during backup 15425 updateOomAdjLocked(proc); 15426 15427 // If the process is already attached, schedule the creation of the backup agent now. 15428 // If it is not yet live, this will be done when it attaches to the framework. 15429 if (proc.thread != null) { 15430 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15431 try { 15432 proc.thread.scheduleCreateBackupAgent(app, 15433 compatibilityInfoForPackageLocked(app), backupMode); 15434 } catch (RemoteException e) { 15435 // Will time out on the backup manager side 15436 } 15437 } else { 15438 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15439 } 15440 // Invariants: at this point, the target app process exists and the application 15441 // is either already running or in the process of coming up. mBackupTarget and 15442 // mBackupAppName describe the app, so that when it binds back to the AM we 15443 // know that it's scheduled for a backup-agent operation. 15444 } 15445 15446 return true; 15447 } 15448 15449 @Override 15450 public void clearPendingBackup() { 15451 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15452 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15453 15454 synchronized (this) { 15455 mBackupTarget = null; 15456 mBackupAppName = null; 15457 } 15458 } 15459 15460 // A backup agent has just come up 15461 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15462 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15463 + " = " + agent); 15464 15465 synchronized(this) { 15466 if (!agentPackageName.equals(mBackupAppName)) { 15467 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15468 return; 15469 } 15470 } 15471 15472 long oldIdent = Binder.clearCallingIdentity(); 15473 try { 15474 IBackupManager bm = IBackupManager.Stub.asInterface( 15475 ServiceManager.getService(Context.BACKUP_SERVICE)); 15476 bm.agentConnected(agentPackageName, agent); 15477 } catch (RemoteException e) { 15478 // can't happen; the backup manager service is local 15479 } catch (Exception e) { 15480 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15481 e.printStackTrace(); 15482 } finally { 15483 Binder.restoreCallingIdentity(oldIdent); 15484 } 15485 } 15486 15487 // done with this agent 15488 public void unbindBackupAgent(ApplicationInfo appInfo) { 15489 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15490 if (appInfo == null) { 15491 Slog.w(TAG, "unbind backup agent for null app"); 15492 return; 15493 } 15494 15495 synchronized(this) { 15496 try { 15497 if (mBackupAppName == null) { 15498 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15499 return; 15500 } 15501 15502 if (!mBackupAppName.equals(appInfo.packageName)) { 15503 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15504 return; 15505 } 15506 15507 // Not backing this app up any more; reset its OOM adjustment 15508 final ProcessRecord proc = mBackupTarget.app; 15509 updateOomAdjLocked(proc); 15510 15511 // If the app crashed during backup, 'thread' will be null here 15512 if (proc.thread != null) { 15513 try { 15514 proc.thread.scheduleDestroyBackupAgent(appInfo, 15515 compatibilityInfoForPackageLocked(appInfo)); 15516 } catch (Exception e) { 15517 Slog.e(TAG, "Exception when unbinding backup agent:"); 15518 e.printStackTrace(); 15519 } 15520 } 15521 } finally { 15522 mBackupTarget = null; 15523 mBackupAppName = null; 15524 } 15525 } 15526 } 15527 // ========================================================= 15528 // BROADCASTS 15529 // ========================================================= 15530 15531 private final List getStickiesLocked(String action, IntentFilter filter, 15532 List cur, int userId) { 15533 final ContentResolver resolver = mContext.getContentResolver(); 15534 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15535 if (stickies == null) { 15536 return cur; 15537 } 15538 final ArrayList<Intent> list = stickies.get(action); 15539 if (list == null) { 15540 return cur; 15541 } 15542 int N = list.size(); 15543 for (int i=0; i<N; i++) { 15544 Intent intent = list.get(i); 15545 if (filter.match(resolver, intent, true, TAG) >= 0) { 15546 if (cur == null) { 15547 cur = new ArrayList<Intent>(); 15548 } 15549 cur.add(intent); 15550 } 15551 } 15552 return cur; 15553 } 15554 15555 boolean isPendingBroadcastProcessLocked(int pid) { 15556 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15557 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15558 } 15559 15560 void skipPendingBroadcastLocked(int pid) { 15561 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15562 for (BroadcastQueue queue : mBroadcastQueues) { 15563 queue.skipPendingBroadcastLocked(pid); 15564 } 15565 } 15566 15567 // The app just attached; send any pending broadcasts that it should receive 15568 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15569 boolean didSomething = false; 15570 for (BroadcastQueue queue : mBroadcastQueues) { 15571 didSomething |= queue.sendPendingBroadcastsLocked(app); 15572 } 15573 return didSomething; 15574 } 15575 15576 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15577 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15578 enforceNotIsolatedCaller("registerReceiver"); 15579 int callingUid; 15580 int callingPid; 15581 synchronized(this) { 15582 ProcessRecord callerApp = null; 15583 if (caller != null) { 15584 callerApp = getRecordForAppLocked(caller); 15585 if (callerApp == null) { 15586 throw new SecurityException( 15587 "Unable to find app for caller " + caller 15588 + " (pid=" + Binder.getCallingPid() 15589 + ") when registering receiver " + receiver); 15590 } 15591 if (callerApp.info.uid != Process.SYSTEM_UID && 15592 !callerApp.pkgList.containsKey(callerPackage) && 15593 !"android".equals(callerPackage)) { 15594 throw new SecurityException("Given caller package " + callerPackage 15595 + " is not running in process " + callerApp); 15596 } 15597 callingUid = callerApp.info.uid; 15598 callingPid = callerApp.pid; 15599 } else { 15600 callerPackage = null; 15601 callingUid = Binder.getCallingUid(); 15602 callingPid = Binder.getCallingPid(); 15603 } 15604 15605 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15606 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15607 15608 List allSticky = null; 15609 15610 // Look for any matching sticky broadcasts... 15611 Iterator actions = filter.actionsIterator(); 15612 if (actions != null) { 15613 while (actions.hasNext()) { 15614 String action = (String)actions.next(); 15615 allSticky = getStickiesLocked(action, filter, allSticky, 15616 UserHandle.USER_ALL); 15617 allSticky = getStickiesLocked(action, filter, allSticky, 15618 UserHandle.getUserId(callingUid)); 15619 } 15620 } else { 15621 allSticky = getStickiesLocked(null, filter, allSticky, 15622 UserHandle.USER_ALL); 15623 allSticky = getStickiesLocked(null, filter, allSticky, 15624 UserHandle.getUserId(callingUid)); 15625 } 15626 15627 // The first sticky in the list is returned directly back to 15628 // the client. 15629 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15630 15631 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15632 + ": " + sticky); 15633 15634 if (receiver == null) { 15635 return sticky; 15636 } 15637 15638 ReceiverList rl 15639 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15640 if (rl == null) { 15641 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15642 userId, receiver); 15643 if (rl.app != null) { 15644 rl.app.receivers.add(rl); 15645 } else { 15646 try { 15647 receiver.asBinder().linkToDeath(rl, 0); 15648 } catch (RemoteException e) { 15649 return sticky; 15650 } 15651 rl.linkedToDeath = true; 15652 } 15653 mRegisteredReceivers.put(receiver.asBinder(), rl); 15654 } else if (rl.uid != callingUid) { 15655 throw new IllegalArgumentException( 15656 "Receiver requested to register for uid " + callingUid 15657 + " was previously registered for uid " + rl.uid); 15658 } else if (rl.pid != callingPid) { 15659 throw new IllegalArgumentException( 15660 "Receiver requested to register for pid " + callingPid 15661 + " was previously registered for pid " + rl.pid); 15662 } else if (rl.userId != userId) { 15663 throw new IllegalArgumentException( 15664 "Receiver requested to register for user " + userId 15665 + " was previously registered for user " + rl.userId); 15666 } 15667 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15668 permission, callingUid, userId); 15669 rl.add(bf); 15670 if (!bf.debugCheck()) { 15671 Slog.w(TAG, "==> For Dynamic broadast"); 15672 } 15673 mReceiverResolver.addFilter(bf); 15674 15675 // Enqueue broadcasts for all existing stickies that match 15676 // this filter. 15677 if (allSticky != null) { 15678 ArrayList receivers = new ArrayList(); 15679 receivers.add(bf); 15680 15681 int N = allSticky.size(); 15682 for (int i=0; i<N; i++) { 15683 Intent intent = (Intent)allSticky.get(i); 15684 BroadcastQueue queue = broadcastQueueForIntent(intent); 15685 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15686 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15687 null, null, false, true, true, -1); 15688 queue.enqueueParallelBroadcastLocked(r); 15689 queue.scheduleBroadcastsLocked(); 15690 } 15691 } 15692 15693 return sticky; 15694 } 15695 } 15696 15697 public void unregisterReceiver(IIntentReceiver receiver) { 15698 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15699 15700 final long origId = Binder.clearCallingIdentity(); 15701 try { 15702 boolean doTrim = false; 15703 15704 synchronized(this) { 15705 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15706 if (rl != null) { 15707 if (rl.curBroadcast != null) { 15708 BroadcastRecord r = rl.curBroadcast; 15709 final boolean doNext = finishReceiverLocked( 15710 receiver.asBinder(), r.resultCode, r.resultData, 15711 r.resultExtras, r.resultAbort); 15712 if (doNext) { 15713 doTrim = true; 15714 r.queue.processNextBroadcast(false); 15715 } 15716 } 15717 15718 if (rl.app != null) { 15719 rl.app.receivers.remove(rl); 15720 } 15721 removeReceiverLocked(rl); 15722 if (rl.linkedToDeath) { 15723 rl.linkedToDeath = false; 15724 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15725 } 15726 } 15727 } 15728 15729 // If we actually concluded any broadcasts, we might now be able 15730 // to trim the recipients' apps from our working set 15731 if (doTrim) { 15732 trimApplications(); 15733 return; 15734 } 15735 15736 } finally { 15737 Binder.restoreCallingIdentity(origId); 15738 } 15739 } 15740 15741 void removeReceiverLocked(ReceiverList rl) { 15742 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15743 int N = rl.size(); 15744 for (int i=0; i<N; i++) { 15745 mReceiverResolver.removeFilter(rl.get(i)); 15746 } 15747 } 15748 15749 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15750 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15751 ProcessRecord r = mLruProcesses.get(i); 15752 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15753 try { 15754 r.thread.dispatchPackageBroadcast(cmd, packages); 15755 } catch (RemoteException ex) { 15756 } 15757 } 15758 } 15759 } 15760 15761 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15762 int callingUid, int[] users) { 15763 List<ResolveInfo> receivers = null; 15764 try { 15765 HashSet<ComponentName> singleUserReceivers = null; 15766 boolean scannedFirstReceivers = false; 15767 for (int user : users) { 15768 // Skip users that have Shell restrictions 15769 if (callingUid == Process.SHELL_UID 15770 && getUserManagerLocked().hasUserRestriction( 15771 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15772 continue; 15773 } 15774 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15775 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15776 if (user != 0 && newReceivers != null) { 15777 // If this is not the primary user, we need to check for 15778 // any receivers that should be filtered out. 15779 for (int i=0; i<newReceivers.size(); i++) { 15780 ResolveInfo ri = newReceivers.get(i); 15781 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15782 newReceivers.remove(i); 15783 i--; 15784 } 15785 } 15786 } 15787 if (newReceivers != null && newReceivers.size() == 0) { 15788 newReceivers = null; 15789 } 15790 if (receivers == null) { 15791 receivers = newReceivers; 15792 } else if (newReceivers != null) { 15793 // We need to concatenate the additional receivers 15794 // found with what we have do far. This would be easy, 15795 // but we also need to de-dup any receivers that are 15796 // singleUser. 15797 if (!scannedFirstReceivers) { 15798 // Collect any single user receivers we had already retrieved. 15799 scannedFirstReceivers = true; 15800 for (int i=0; i<receivers.size(); i++) { 15801 ResolveInfo ri = receivers.get(i); 15802 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15803 ComponentName cn = new ComponentName( 15804 ri.activityInfo.packageName, ri.activityInfo.name); 15805 if (singleUserReceivers == null) { 15806 singleUserReceivers = new HashSet<ComponentName>(); 15807 } 15808 singleUserReceivers.add(cn); 15809 } 15810 } 15811 } 15812 // Add the new results to the existing results, tracking 15813 // and de-dupping single user receivers. 15814 for (int i=0; i<newReceivers.size(); i++) { 15815 ResolveInfo ri = newReceivers.get(i); 15816 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15817 ComponentName cn = new ComponentName( 15818 ri.activityInfo.packageName, ri.activityInfo.name); 15819 if (singleUserReceivers == null) { 15820 singleUserReceivers = new HashSet<ComponentName>(); 15821 } 15822 if (!singleUserReceivers.contains(cn)) { 15823 singleUserReceivers.add(cn); 15824 receivers.add(ri); 15825 } 15826 } else { 15827 receivers.add(ri); 15828 } 15829 } 15830 } 15831 } 15832 } catch (RemoteException ex) { 15833 // pm is in same process, this will never happen. 15834 } 15835 return receivers; 15836 } 15837 15838 private final int broadcastIntentLocked(ProcessRecord callerApp, 15839 String callerPackage, Intent intent, String resolvedType, 15840 IIntentReceiver resultTo, int resultCode, String resultData, 15841 Bundle map, String requiredPermission, int appOp, 15842 boolean ordered, boolean sticky, int callingPid, int callingUid, 15843 int userId) { 15844 intent = new Intent(intent); 15845 15846 // By default broadcasts do not go to stopped apps. 15847 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15848 15849 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15850 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15851 + " ordered=" + ordered + " userid=" + userId); 15852 if ((resultTo != null) && !ordered) { 15853 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15854 } 15855 15856 userId = handleIncomingUser(callingPid, callingUid, userId, 15857 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15858 15859 // Make sure that the user who is receiving this broadcast is running. 15860 // If not, we will just skip it. Make an exception for shutdown broadcasts 15861 // and upgrade steps. 15862 15863 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) { 15864 if ((callingUid != Process.SYSTEM_UID 15865 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 15866 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 15867 Slog.w(TAG, "Skipping broadcast of " + intent 15868 + ": user " + userId + " is stopped"); 15869 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 15870 } 15871 } 15872 15873 /* 15874 * Prevent non-system code (defined here to be non-persistent 15875 * processes) from sending protected broadcasts. 15876 */ 15877 int callingAppId = UserHandle.getAppId(callingUid); 15878 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15879 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15880 || callingAppId == Process.NFC_UID || callingUid == 0) { 15881 // Always okay. 15882 } else if (callerApp == null || !callerApp.persistent) { 15883 try { 15884 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15885 intent.getAction())) { 15886 String msg = "Permission Denial: not allowed to send broadcast " 15887 + intent.getAction() + " from pid=" 15888 + callingPid + ", uid=" + callingUid; 15889 Slog.w(TAG, msg); 15890 throw new SecurityException(msg); 15891 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15892 // Special case for compatibility: we don't want apps to send this, 15893 // but historically it has not been protected and apps may be using it 15894 // to poke their own app widget. So, instead of making it protected, 15895 // just limit it to the caller. 15896 if (callerApp == null) { 15897 String msg = "Permission Denial: not allowed to send broadcast " 15898 + intent.getAction() + " from unknown caller."; 15899 Slog.w(TAG, msg); 15900 throw new SecurityException(msg); 15901 } else if (intent.getComponent() != null) { 15902 // They are good enough to send to an explicit component... verify 15903 // it is being sent to the calling app. 15904 if (!intent.getComponent().getPackageName().equals( 15905 callerApp.info.packageName)) { 15906 String msg = "Permission Denial: not allowed to send broadcast " 15907 + intent.getAction() + " to " 15908 + intent.getComponent().getPackageName() + " from " 15909 + callerApp.info.packageName; 15910 Slog.w(TAG, msg); 15911 throw new SecurityException(msg); 15912 } 15913 } else { 15914 // Limit broadcast to their own package. 15915 intent.setPackage(callerApp.info.packageName); 15916 } 15917 } 15918 } catch (RemoteException e) { 15919 Slog.w(TAG, "Remote exception", e); 15920 return ActivityManager.BROADCAST_SUCCESS; 15921 } 15922 } 15923 15924 final String action = intent.getAction(); 15925 if (action != null) { 15926 switch (action) { 15927 case Intent.ACTION_UID_REMOVED: 15928 case Intent.ACTION_PACKAGE_REMOVED: 15929 case Intent.ACTION_PACKAGE_CHANGED: 15930 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15931 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15932 // Handle special intents: if this broadcast is from the package 15933 // manager about a package being removed, we need to remove all of 15934 // its activities from the history stack. 15935 if (checkComponentPermission( 15936 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15937 callingPid, callingUid, -1, true) 15938 != PackageManager.PERMISSION_GRANTED) { 15939 String msg = "Permission Denial: " + intent.getAction() 15940 + " broadcast from " + callerPackage + " (pid=" + callingPid 15941 + ", uid=" + callingUid + ")" 15942 + " requires " 15943 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15944 Slog.w(TAG, msg); 15945 throw new SecurityException(msg); 15946 } 15947 switch (action) { 15948 case Intent.ACTION_UID_REMOVED: 15949 final Bundle intentExtras = intent.getExtras(); 15950 final int uid = intentExtras != null 15951 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15952 if (uid >= 0) { 15953 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15954 synchronized (bs) { 15955 bs.removeUidStatsLocked(uid); 15956 } 15957 mAppOpsService.uidRemoved(uid); 15958 } 15959 break; 15960 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 15961 // If resources are unavailable just force stop all those packages 15962 // and flush the attribute cache as well. 15963 String list[] = 15964 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15965 if (list != null && list.length > 0) { 15966 for (int i = 0; i < list.length; i++) { 15967 forceStopPackageLocked(list[i], -1, false, true, true, 15968 false, false, userId, "storage unmount"); 15969 } 15970 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15971 sendPackageBroadcastLocked( 15972 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, 15973 userId); 15974 } 15975 break; 15976 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 15977 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15978 break; 15979 case Intent.ACTION_PACKAGE_REMOVED: 15980 case Intent.ACTION_PACKAGE_CHANGED: 15981 Uri data = intent.getData(); 15982 String ssp; 15983 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15984 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 15985 boolean fullUninstall = removed && 15986 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15987 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15988 forceStopPackageLocked(ssp, UserHandle.getAppId( 15989 intent.getIntExtra(Intent.EXTRA_UID, -1)), 15990 false, true, true, false, fullUninstall, userId, 15991 removed ? "pkg removed" : "pkg changed"); 15992 } 15993 if (removed) { 15994 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15995 new String[] {ssp}, userId); 15996 if (fullUninstall) { 15997 mAppOpsService.packageRemoved( 15998 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15999 16000 // Remove all permissions granted from/to this package 16001 removeUriPermissionsForPackageLocked(ssp, userId, true); 16002 16003 removeTasksByPackageNameLocked(ssp, userId); 16004 if (userId == UserHandle.USER_OWNER) { 16005 mTaskPersister.removeFromPackageCache(ssp); 16006 } 16007 } 16008 } else { 16009 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16010 if (userId == UserHandle.USER_OWNER) { 16011 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16012 } 16013 } 16014 } 16015 break; 16016 } 16017 break; 16018 case Intent.ACTION_PACKAGE_ADDED: 16019 // Special case for adding a package: by default turn on compatibility mode. 16020 Uri data = intent.getData(); 16021 String ssp; 16022 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 16023 final boolean replacing = 16024 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 16025 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 16026 16027 if (replacing) { 16028 removeTasksByRemovedPackageComponentsLocked(ssp, userId); 16029 } 16030 if (userId == UserHandle.USER_OWNER) { 16031 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); 16032 } 16033 } 16034 break; 16035 case Intent.ACTION_TIMEZONE_CHANGED: 16036 // If this is the time zone changed action, queue up a message that will reset 16037 // the timezone of all currently running processes. This message will get 16038 // queued up before the broadcast happens. 16039 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 16040 break; 16041 case Intent.ACTION_TIME_CHANGED: 16042 // If the user set the time, let all running processes know. 16043 final int is24Hour = 16044 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 16045 : 0; 16046 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 16047 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16048 synchronized (stats) { 16049 stats.noteCurrentTimeChangedLocked(); 16050 } 16051 break; 16052 case Intent.ACTION_CLEAR_DNS_CACHE: 16053 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 16054 break; 16055 case Proxy.PROXY_CHANGE_ACTION: 16056 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 16057 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 16058 break; 16059 } 16060 } 16061 16062 // Add to the sticky list if requested. 16063 if (sticky) { 16064 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 16065 callingPid, callingUid) 16066 != PackageManager.PERMISSION_GRANTED) { 16067 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 16068 + callingPid + ", uid=" + callingUid 16069 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16070 Slog.w(TAG, msg); 16071 throw new SecurityException(msg); 16072 } 16073 if (requiredPermission != null) { 16074 Slog.w(TAG, "Can't broadcast sticky intent " + intent 16075 + " and enforce permission " + requiredPermission); 16076 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 16077 } 16078 if (intent.getComponent() != null) { 16079 throw new SecurityException( 16080 "Sticky broadcasts can't target a specific component"); 16081 } 16082 // We use userId directly here, since the "all" target is maintained 16083 // as a separate set of sticky broadcasts. 16084 if (userId != UserHandle.USER_ALL) { 16085 // But first, if this is not a broadcast to all users, then 16086 // make sure it doesn't conflict with an existing broadcast to 16087 // all users. 16088 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 16089 UserHandle.USER_ALL); 16090 if (stickies != null) { 16091 ArrayList<Intent> list = stickies.get(intent.getAction()); 16092 if (list != null) { 16093 int N = list.size(); 16094 int i; 16095 for (i=0; i<N; i++) { 16096 if (intent.filterEquals(list.get(i))) { 16097 throw new IllegalArgumentException( 16098 "Sticky broadcast " + intent + " for user " 16099 + userId + " conflicts with existing global broadcast"); 16100 } 16101 } 16102 } 16103 } 16104 } 16105 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16106 if (stickies == null) { 16107 stickies = new ArrayMap<String, ArrayList<Intent>>(); 16108 mStickyBroadcasts.put(userId, stickies); 16109 } 16110 ArrayList<Intent> list = stickies.get(intent.getAction()); 16111 if (list == null) { 16112 list = new ArrayList<Intent>(); 16113 stickies.put(intent.getAction(), list); 16114 } 16115 int N = list.size(); 16116 int i; 16117 for (i=0; i<N; i++) { 16118 if (intent.filterEquals(list.get(i))) { 16119 // This sticky already exists, replace it. 16120 list.set(i, new Intent(intent)); 16121 break; 16122 } 16123 } 16124 if (i >= N) { 16125 list.add(new Intent(intent)); 16126 } 16127 } 16128 16129 int[] users; 16130 if (userId == UserHandle.USER_ALL) { 16131 // Caller wants broadcast to go to all started users. 16132 users = mStartedUserArray; 16133 } else { 16134 // Caller wants broadcast to go to one specific user. 16135 users = new int[] {userId}; 16136 } 16137 16138 // Figure out who all will receive this broadcast. 16139 List receivers = null; 16140 List<BroadcastFilter> registeredReceivers = null; 16141 // Need to resolve the intent to interested receivers... 16142 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 16143 == 0) { 16144 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 16145 } 16146 if (intent.getComponent() == null) { 16147 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 16148 // Query one target user at a time, excluding shell-restricted users 16149 UserManagerService ums = getUserManagerLocked(); 16150 for (int i = 0; i < users.length; i++) { 16151 if (ums.hasUserRestriction( 16152 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 16153 continue; 16154 } 16155 List<BroadcastFilter> registeredReceiversForUser = 16156 mReceiverResolver.queryIntent(intent, 16157 resolvedType, false, users[i]); 16158 if (registeredReceivers == null) { 16159 registeredReceivers = registeredReceiversForUser; 16160 } else if (registeredReceiversForUser != null) { 16161 registeredReceivers.addAll(registeredReceiversForUser); 16162 } 16163 } 16164 } else { 16165 registeredReceivers = mReceiverResolver.queryIntent(intent, 16166 resolvedType, false, userId); 16167 } 16168 } 16169 16170 final boolean replacePending = 16171 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 16172 16173 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 16174 + " replacePending=" + replacePending); 16175 16176 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 16177 if (!ordered && NR > 0) { 16178 // If we are not serializing this broadcast, then send the 16179 // registered receivers separately so they don't wait for the 16180 // components to be launched. 16181 final BroadcastQueue queue = broadcastQueueForIntent(intent); 16182 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16183 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 16184 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 16185 ordered, sticky, false, userId); 16186 if (DEBUG_BROADCAST) Slog.v( 16187 TAG, "Enqueueing parallel broadcast " + r); 16188 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 16189 if (!replaced) { 16190 queue.enqueueParallelBroadcastLocked(r); 16191 queue.scheduleBroadcastsLocked(); 16192 } 16193 registeredReceivers = null; 16194 NR = 0; 16195 } 16196 16197 // Merge into one list. 16198 int ir = 0; 16199 if (receivers != null) { 16200 // A special case for PACKAGE_ADDED: do not allow the package 16201 // being added to see this broadcast. This prevents them from 16202 // using this as a back door to get run as soon as they are 16203 // installed. Maybe in the future we want to have a special install 16204 // broadcast or such for apps, but we'd like to deliberately make 16205 // this decision. 16206 String skipPackages[] = null; 16207 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 16208 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 16209 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 16210 Uri data = intent.getData(); 16211 if (data != null) { 16212 String pkgName = data.getSchemeSpecificPart(); 16213 if (pkgName != null) { 16214 skipPackages = new String[] { pkgName }; 16215 } 16216 } 16217 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 16218 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 16219 } 16220 if (skipPackages != null && (skipPackages.length > 0)) { 16221 for (String skipPackage : skipPackages) { 16222 if (skipPackage != null) { 16223 int NT = receivers.size(); 16224 for (int it=0; it<NT; it++) { 16225 ResolveInfo curt = (ResolveInfo)receivers.get(it); 16226 if (curt.activityInfo.packageName.equals(skipPackage)) { 16227 receivers.remove(it); 16228 it--; 16229 NT--; 16230 } 16231 } 16232 } 16233 } 16234 } 16235 16236 int NT = receivers != null ? receivers.size() : 0; 16237 int it = 0; 16238 ResolveInfo curt = null; 16239 BroadcastFilter curr = null; 16240 while (it < NT && ir < NR) { 16241 if (curt == null) { 16242 curt = (ResolveInfo)receivers.get(it); 16243 } 16244 if (curr == null) { 16245 curr = registeredReceivers.get(ir); 16246 } 16247 if (curr.getPriority() >= curt.priority) { 16248 // Insert this broadcast record into the final list. 16249 receivers.add(it, curr); 16250 ir++; 16251 curr = null; 16252 it++; 16253 NT++; 16254 } else { 16255 // Skip to the next ResolveInfo in the final list. 16256 it++; 16257 curt = null; 16258 } 16259 } 16260 } 16261 while (ir < NR) { 16262 if (receivers == null) { 16263 receivers = new ArrayList(); 16264 } 16265 receivers.add(registeredReceivers.get(ir)); 16266 ir++; 16267 } 16268 16269 if ((receivers != null && receivers.size() > 0) 16270 || resultTo != null) { 16271 BroadcastQueue queue = broadcastQueueForIntent(intent); 16272 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 16273 callerPackage, callingPid, callingUid, resolvedType, 16274 requiredPermission, appOp, receivers, resultTo, resultCode, 16275 resultData, map, ordered, sticky, false, userId); 16276 if (DEBUG_BROADCAST) Slog.v( 16277 TAG, "Enqueueing ordered broadcast " + r 16278 + ": prev had " + queue.mOrderedBroadcasts.size()); 16279 if (DEBUG_BROADCAST) { 16280 int seq = r.intent.getIntExtra("seq", -1); 16281 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 16282 } 16283 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 16284 if (!replaced) { 16285 queue.enqueueOrderedBroadcastLocked(r); 16286 queue.scheduleBroadcastsLocked(); 16287 } 16288 } 16289 16290 return ActivityManager.BROADCAST_SUCCESS; 16291 } 16292 16293 final Intent verifyBroadcastLocked(Intent intent) { 16294 // Refuse possible leaked file descriptors 16295 if (intent != null && intent.hasFileDescriptors() == true) { 16296 throw new IllegalArgumentException("File descriptors passed in Intent"); 16297 } 16298 16299 int flags = intent.getFlags(); 16300 16301 if (!mProcessesReady) { 16302 // if the caller really truly claims to know what they're doing, go 16303 // ahead and allow the broadcast without launching any receivers 16304 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 16305 intent = new Intent(intent); 16306 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16307 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 16308 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 16309 + " before boot completion"); 16310 throw new IllegalStateException("Cannot broadcast before boot completed"); 16311 } 16312 } 16313 16314 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 16315 throw new IllegalArgumentException( 16316 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 16317 } 16318 16319 return intent; 16320 } 16321 16322 public final int broadcastIntent(IApplicationThread caller, 16323 Intent intent, String resolvedType, IIntentReceiver resultTo, 16324 int resultCode, String resultData, Bundle map, 16325 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 16326 enforceNotIsolatedCaller("broadcastIntent"); 16327 synchronized(this) { 16328 intent = verifyBroadcastLocked(intent); 16329 16330 final ProcessRecord callerApp = getRecordForAppLocked(caller); 16331 final int callingPid = Binder.getCallingPid(); 16332 final int callingUid = Binder.getCallingUid(); 16333 final long origId = Binder.clearCallingIdentity(); 16334 int res = broadcastIntentLocked(callerApp, 16335 callerApp != null ? callerApp.info.packageName : null, 16336 intent, resolvedType, resultTo, 16337 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 16338 callingPid, callingUid, userId); 16339 Binder.restoreCallingIdentity(origId); 16340 return res; 16341 } 16342 } 16343 16344 int broadcastIntentInPackage(String packageName, int uid, 16345 Intent intent, String resolvedType, IIntentReceiver resultTo, 16346 int resultCode, String resultData, Bundle map, 16347 String requiredPermission, boolean serialized, boolean sticky, int userId) { 16348 synchronized(this) { 16349 intent = verifyBroadcastLocked(intent); 16350 16351 final long origId = Binder.clearCallingIdentity(); 16352 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 16353 resultTo, resultCode, resultData, map, requiredPermission, 16354 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 16355 Binder.restoreCallingIdentity(origId); 16356 return res; 16357 } 16358 } 16359 16360 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 16361 // Refuse possible leaked file descriptors 16362 if (intent != null && intent.hasFileDescriptors() == true) { 16363 throw new IllegalArgumentException("File descriptors passed in Intent"); 16364 } 16365 16366 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16367 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 16368 16369 synchronized(this) { 16370 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 16371 != PackageManager.PERMISSION_GRANTED) { 16372 String msg = "Permission Denial: unbroadcastIntent() from pid=" 16373 + Binder.getCallingPid() 16374 + ", uid=" + Binder.getCallingUid() 16375 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 16376 Slog.w(TAG, msg); 16377 throw new SecurityException(msg); 16378 } 16379 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 16380 if (stickies != null) { 16381 ArrayList<Intent> list = stickies.get(intent.getAction()); 16382 if (list != null) { 16383 int N = list.size(); 16384 int i; 16385 for (i=0; i<N; i++) { 16386 if (intent.filterEquals(list.get(i))) { 16387 list.remove(i); 16388 break; 16389 } 16390 } 16391 if (list.size() <= 0) { 16392 stickies.remove(intent.getAction()); 16393 } 16394 } 16395 if (stickies.size() <= 0) { 16396 mStickyBroadcasts.remove(userId); 16397 } 16398 } 16399 } 16400 } 16401 16402 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 16403 String resultData, Bundle resultExtras, boolean resultAbort) { 16404 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 16405 if (r == null) { 16406 Slog.w(TAG, "finishReceiver called but not found on queue"); 16407 return false; 16408 } 16409 16410 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 16411 } 16412 16413 void backgroundServicesFinishedLocked(int userId) { 16414 for (BroadcastQueue queue : mBroadcastQueues) { 16415 queue.backgroundServicesFinishedLocked(userId); 16416 } 16417 } 16418 16419 public void finishReceiver(IBinder who, int resultCode, String resultData, 16420 Bundle resultExtras, boolean resultAbort) { 16421 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 16422 16423 // Refuse possible leaked file descriptors 16424 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 16425 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16426 } 16427 16428 final long origId = Binder.clearCallingIdentity(); 16429 try { 16430 boolean doNext = false; 16431 BroadcastRecord r; 16432 16433 synchronized(this) { 16434 r = broadcastRecordForReceiverLocked(who); 16435 if (r != null) { 16436 doNext = r.queue.finishReceiverLocked(r, resultCode, 16437 resultData, resultExtras, resultAbort, true); 16438 } 16439 } 16440 16441 if (doNext) { 16442 r.queue.processNextBroadcast(false); 16443 } 16444 trimApplications(); 16445 } finally { 16446 Binder.restoreCallingIdentity(origId); 16447 } 16448 } 16449 16450 // ========================================================= 16451 // INSTRUMENTATION 16452 // ========================================================= 16453 16454 public boolean startInstrumentation(ComponentName className, 16455 String profileFile, int flags, Bundle arguments, 16456 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16457 int userId, String abiOverride) { 16458 enforceNotIsolatedCaller("startInstrumentation"); 16459 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16460 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16461 // Refuse possible leaked file descriptors 16462 if (arguments != null && arguments.hasFileDescriptors()) { 16463 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16464 } 16465 16466 synchronized(this) { 16467 InstrumentationInfo ii = null; 16468 ApplicationInfo ai = null; 16469 try { 16470 ii = mContext.getPackageManager().getInstrumentationInfo( 16471 className, STOCK_PM_FLAGS); 16472 ai = AppGlobals.getPackageManager().getApplicationInfo( 16473 ii.targetPackage, STOCK_PM_FLAGS, userId); 16474 } catch (PackageManager.NameNotFoundException e) { 16475 } catch (RemoteException e) { 16476 } 16477 if (ii == null) { 16478 reportStartInstrumentationFailure(watcher, className, 16479 "Unable to find instrumentation info for: " + className); 16480 return false; 16481 } 16482 if (ai == null) { 16483 reportStartInstrumentationFailure(watcher, className, 16484 "Unable to find instrumentation target package: " + ii.targetPackage); 16485 return false; 16486 } 16487 16488 int match = mContext.getPackageManager().checkSignatures( 16489 ii.targetPackage, ii.packageName); 16490 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16491 String msg = "Permission Denial: starting instrumentation " 16492 + className + " from pid=" 16493 + Binder.getCallingPid() 16494 + ", uid=" + Binder.getCallingPid() 16495 + " not allowed because package " + ii.packageName 16496 + " does not have a signature matching the target " 16497 + ii.targetPackage; 16498 reportStartInstrumentationFailure(watcher, className, msg); 16499 throw new SecurityException(msg); 16500 } 16501 16502 final long origId = Binder.clearCallingIdentity(); 16503 // Instrumentation can kill and relaunch even persistent processes 16504 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16505 "start instr"); 16506 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16507 app.instrumentationClass = className; 16508 app.instrumentationInfo = ai; 16509 app.instrumentationProfileFile = profileFile; 16510 app.instrumentationArguments = arguments; 16511 app.instrumentationWatcher = watcher; 16512 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16513 app.instrumentationResultClass = className; 16514 Binder.restoreCallingIdentity(origId); 16515 } 16516 16517 return true; 16518 } 16519 16520 /** 16521 * Report errors that occur while attempting to start Instrumentation. Always writes the 16522 * error to the logs, but if somebody is watching, send the report there too. This enables 16523 * the "am" command to report errors with more information. 16524 * 16525 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16526 * @param cn The component name of the instrumentation. 16527 * @param report The error report. 16528 */ 16529 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16530 ComponentName cn, String report) { 16531 Slog.w(TAG, report); 16532 try { 16533 if (watcher != null) { 16534 Bundle results = new Bundle(); 16535 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16536 results.putString("Error", report); 16537 watcher.instrumentationStatus(cn, -1, results); 16538 } 16539 } catch (RemoteException e) { 16540 Slog.w(TAG, e); 16541 } 16542 } 16543 16544 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16545 if (app.instrumentationWatcher != null) { 16546 try { 16547 // NOTE: IInstrumentationWatcher *must* be oneway here 16548 app.instrumentationWatcher.instrumentationFinished( 16549 app.instrumentationClass, 16550 resultCode, 16551 results); 16552 } catch (RemoteException e) { 16553 } 16554 } 16555 if (app.instrumentationUiAutomationConnection != null) { 16556 try { 16557 app.instrumentationUiAutomationConnection.shutdown(); 16558 } catch (RemoteException re) { 16559 /* ignore */ 16560 } 16561 // Only a UiAutomation can set this flag and now that 16562 // it is finished we make sure it is reset to its default. 16563 mUserIsMonkey = false; 16564 } 16565 app.instrumentationWatcher = null; 16566 app.instrumentationUiAutomationConnection = null; 16567 app.instrumentationClass = null; 16568 app.instrumentationInfo = null; 16569 app.instrumentationProfileFile = null; 16570 app.instrumentationArguments = null; 16571 16572 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16573 "finished inst"); 16574 } 16575 16576 public void finishInstrumentation(IApplicationThread target, 16577 int resultCode, Bundle results) { 16578 int userId = UserHandle.getCallingUserId(); 16579 // Refuse possible leaked file descriptors 16580 if (results != null && results.hasFileDescriptors()) { 16581 throw new IllegalArgumentException("File descriptors passed in Intent"); 16582 } 16583 16584 synchronized(this) { 16585 ProcessRecord app = getRecordForAppLocked(target); 16586 if (app == null) { 16587 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16588 return; 16589 } 16590 final long origId = Binder.clearCallingIdentity(); 16591 finishInstrumentationLocked(app, resultCode, results); 16592 Binder.restoreCallingIdentity(origId); 16593 } 16594 } 16595 16596 // ========================================================= 16597 // CONFIGURATION 16598 // ========================================================= 16599 16600 public ConfigurationInfo getDeviceConfigurationInfo() { 16601 ConfigurationInfo config = new ConfigurationInfo(); 16602 synchronized (this) { 16603 config.reqTouchScreen = mConfiguration.touchscreen; 16604 config.reqKeyboardType = mConfiguration.keyboard; 16605 config.reqNavigation = mConfiguration.navigation; 16606 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16607 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16608 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16609 } 16610 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16611 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16612 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16613 } 16614 config.reqGlEsVersion = GL_ES_VERSION; 16615 } 16616 return config; 16617 } 16618 16619 ActivityStack getFocusedStack() { 16620 return mStackSupervisor.getFocusedStack(); 16621 } 16622 16623 public Configuration getConfiguration() { 16624 Configuration ci; 16625 synchronized(this) { 16626 ci = new Configuration(mConfiguration); 16627 ci.userSetLocale = false; 16628 } 16629 return ci; 16630 } 16631 16632 public void updatePersistentConfiguration(Configuration values) { 16633 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16634 "updateConfiguration()"); 16635 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16636 "updateConfiguration()"); 16637 if (values == null) { 16638 throw new NullPointerException("Configuration must not be null"); 16639 } 16640 16641 synchronized(this) { 16642 final long origId = Binder.clearCallingIdentity(); 16643 updateConfigurationLocked(values, null, true, false); 16644 Binder.restoreCallingIdentity(origId); 16645 } 16646 } 16647 16648 public void updateConfiguration(Configuration values) { 16649 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16650 "updateConfiguration()"); 16651 16652 synchronized(this) { 16653 if (values == null && mWindowManager != null) { 16654 // sentinel: fetch the current configuration from the window manager 16655 values = mWindowManager.computeNewConfiguration(); 16656 } 16657 16658 if (mWindowManager != null) { 16659 mProcessList.applyDisplaySize(mWindowManager); 16660 } 16661 16662 final long origId = Binder.clearCallingIdentity(); 16663 if (values != null) { 16664 Settings.System.clearConfiguration(values); 16665 } 16666 updateConfigurationLocked(values, null, false, false); 16667 Binder.restoreCallingIdentity(origId); 16668 } 16669 } 16670 16671 /** 16672 * Do either or both things: (1) change the current configuration, and (2) 16673 * make sure the given activity is running with the (now) current 16674 * configuration. Returns true if the activity has been left running, or 16675 * false if <var>starting</var> is being destroyed to match the new 16676 * configuration. 16677 * @param persistent TODO 16678 */ 16679 boolean updateConfigurationLocked(Configuration values, 16680 ActivityRecord starting, boolean persistent, boolean initLocale) { 16681 int changes = 0; 16682 16683 if (values != null) { 16684 Configuration newConfig = new Configuration(mConfiguration); 16685 changes = newConfig.updateFrom(values); 16686 if (changes != 0) { 16687 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16688 Slog.i(TAG, "Updating configuration to: " + values); 16689 } 16690 16691 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16692 16693 if (values.locale != null && !initLocale) { 16694 saveLocaleLocked(values.locale, 16695 !values.locale.equals(mConfiguration.locale), 16696 values.userSetLocale); 16697 } 16698 16699 mConfigurationSeq++; 16700 if (mConfigurationSeq <= 0) { 16701 mConfigurationSeq = 1; 16702 } 16703 newConfig.seq = mConfigurationSeq; 16704 mConfiguration = newConfig; 16705 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16706 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16707 //mUsageStatsService.noteStartConfig(newConfig); 16708 16709 final Configuration configCopy = new Configuration(mConfiguration); 16710 16711 // TODO: If our config changes, should we auto dismiss any currently 16712 // showing dialogs? 16713 mShowDialogs = shouldShowDialogs(newConfig); 16714 16715 AttributeCache ac = AttributeCache.instance(); 16716 if (ac != null) { 16717 ac.updateConfiguration(configCopy); 16718 } 16719 16720 // Make sure all resources in our process are updated 16721 // right now, so that anyone who is going to retrieve 16722 // resource values after we return will be sure to get 16723 // the new ones. This is especially important during 16724 // boot, where the first config change needs to guarantee 16725 // all resources have that config before following boot 16726 // code is executed. 16727 mSystemThread.applyConfigurationToResources(configCopy); 16728 16729 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16730 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16731 msg.obj = new Configuration(configCopy); 16732 mHandler.sendMessage(msg); 16733 } 16734 16735 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16736 ProcessRecord app = mLruProcesses.get(i); 16737 try { 16738 if (app.thread != null) { 16739 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16740 + app.processName + " new config " + mConfiguration); 16741 app.thread.scheduleConfigurationChanged(configCopy); 16742 } 16743 } catch (Exception e) { 16744 } 16745 } 16746 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16747 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16748 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16749 | Intent.FLAG_RECEIVER_FOREGROUND); 16750 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16751 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16752 Process.SYSTEM_UID, UserHandle.USER_ALL); 16753 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16754 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16755 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16756 broadcastIntentLocked(null, null, intent, 16757 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16758 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16759 } 16760 } 16761 } 16762 16763 boolean kept = true; 16764 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16765 // mainStack is null during startup. 16766 if (mainStack != null) { 16767 if (changes != 0 && starting == null) { 16768 // If the configuration changed, and the caller is not already 16769 // in the process of starting an activity, then find the top 16770 // activity to check if its configuration needs to change. 16771 starting = mainStack.topRunningActivityLocked(null); 16772 } 16773 16774 if (starting != null) { 16775 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16776 // And we need to make sure at this point that all other activities 16777 // are made visible with the correct configuration. 16778 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16779 } 16780 } 16781 16782 if (values != null && mWindowManager != null) { 16783 mWindowManager.setNewConfiguration(mConfiguration); 16784 } 16785 16786 return kept; 16787 } 16788 16789 /** 16790 * Decide based on the configuration whether we should shouw the ANR, 16791 * crash, etc dialogs. The idea is that if there is no affordnace to 16792 * press the on-screen buttons, we shouldn't show the dialog. 16793 * 16794 * A thought: SystemUI might also want to get told about this, the Power 16795 * dialog / global actions also might want different behaviors. 16796 */ 16797 private static final boolean shouldShowDialogs(Configuration config) { 16798 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16799 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16800 } 16801 16802 /** 16803 * Save the locale. You must be inside a synchronized (this) block. 16804 */ 16805 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16806 if(isDiff) { 16807 SystemProperties.set("user.language", l.getLanguage()); 16808 SystemProperties.set("user.region", l.getCountry()); 16809 } 16810 16811 if(isPersist) { 16812 SystemProperties.set("persist.sys.language", l.getLanguage()); 16813 SystemProperties.set("persist.sys.country", l.getCountry()); 16814 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16815 16816 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16817 } 16818 } 16819 16820 @Override 16821 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16822 synchronized (this) { 16823 ActivityRecord srec = ActivityRecord.forToken(token); 16824 if (srec.task != null && srec.task.stack != null) { 16825 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16826 } 16827 } 16828 return false; 16829 } 16830 16831 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16832 Intent resultData) { 16833 16834 synchronized (this) { 16835 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16836 if (stack != null) { 16837 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16838 } 16839 return false; 16840 } 16841 } 16842 16843 public int getLaunchedFromUid(IBinder activityToken) { 16844 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16845 if (srec == null) { 16846 return -1; 16847 } 16848 return srec.launchedFromUid; 16849 } 16850 16851 public String getLaunchedFromPackage(IBinder activityToken) { 16852 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16853 if (srec == null) { 16854 return null; 16855 } 16856 return srec.launchedFromPackage; 16857 } 16858 16859 // ========================================================= 16860 // LIFETIME MANAGEMENT 16861 // ========================================================= 16862 16863 // Returns which broadcast queue the app is the current [or imminent] receiver 16864 // on, or 'null' if the app is not an active broadcast recipient. 16865 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16866 BroadcastRecord r = app.curReceiver; 16867 if (r != null) { 16868 return r.queue; 16869 } 16870 16871 // It's not the current receiver, but it might be starting up to become one 16872 synchronized (this) { 16873 for (BroadcastQueue queue : mBroadcastQueues) { 16874 r = queue.mPendingBroadcast; 16875 if (r != null && r.curApp == app) { 16876 // found it; report which queue it's in 16877 return queue; 16878 } 16879 } 16880 } 16881 16882 return null; 16883 } 16884 16885 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16886 ComponentName targetComponent, String targetProcess) { 16887 if (!mTrackingAssociations) { 16888 return null; 16889 } 16890 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16891 = mAssociations.get(targetUid); 16892 if (components == null) { 16893 components = new ArrayMap<>(); 16894 mAssociations.put(targetUid, components); 16895 } 16896 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16897 if (sourceUids == null) { 16898 sourceUids = new SparseArray<>(); 16899 components.put(targetComponent, sourceUids); 16900 } 16901 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16902 if (sourceProcesses == null) { 16903 sourceProcesses = new ArrayMap<>(); 16904 sourceUids.put(sourceUid, sourceProcesses); 16905 } 16906 Association ass = sourceProcesses.get(sourceProcess); 16907 if (ass == null) { 16908 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 16909 targetProcess); 16910 sourceProcesses.put(sourceProcess, ass); 16911 } 16912 ass.mCount++; 16913 ass.mNesting++; 16914 if (ass.mNesting == 1) { 16915 ass.mStartTime = SystemClock.uptimeMillis(); 16916 } 16917 return ass; 16918 } 16919 16920 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 16921 ComponentName targetComponent) { 16922 if (!mTrackingAssociations) { 16923 return; 16924 } 16925 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 16926 = mAssociations.get(targetUid); 16927 if (components == null) { 16928 return; 16929 } 16930 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 16931 if (sourceUids == null) { 16932 return; 16933 } 16934 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 16935 if (sourceProcesses == null) { 16936 return; 16937 } 16938 Association ass = sourceProcesses.get(sourceProcess); 16939 if (ass == null || ass.mNesting <= 0) { 16940 return; 16941 } 16942 ass.mNesting--; 16943 if (ass.mNesting == 0) { 16944 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime; 16945 } 16946 } 16947 16948 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16949 boolean doingAll, long now) { 16950 if (mAdjSeq == app.adjSeq) { 16951 // This adjustment has already been computed. 16952 return app.curRawAdj; 16953 } 16954 16955 if (app.thread == null) { 16956 app.adjSeq = mAdjSeq; 16957 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16958 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16959 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16960 } 16961 16962 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16963 app.adjSource = null; 16964 app.adjTarget = null; 16965 app.empty = false; 16966 app.cached = false; 16967 16968 final int activitiesSize = app.activities.size(); 16969 16970 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16971 // The max adjustment doesn't allow this app to be anything 16972 // below foreground, so it is not worth doing work for it. 16973 app.adjType = "fixed"; 16974 app.adjSeq = mAdjSeq; 16975 app.curRawAdj = app.maxAdj; 16976 app.foregroundActivities = false; 16977 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16978 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16979 // System processes can do UI, and when they do we want to have 16980 // them trim their memory after the user leaves the UI. To 16981 // facilitate this, here we need to determine whether or not it 16982 // is currently showing UI. 16983 app.systemNoUi = true; 16984 if (app == TOP_APP) { 16985 app.systemNoUi = false; 16986 } else if (activitiesSize > 0) { 16987 for (int j = 0; j < activitiesSize; j++) { 16988 final ActivityRecord r = app.activities.get(j); 16989 if (r.visible) { 16990 app.systemNoUi = false; 16991 } 16992 } 16993 } 16994 if (!app.systemNoUi) { 16995 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16996 } 16997 return (app.curAdj=app.maxAdj); 16998 } 16999 17000 app.systemNoUi = false; 17001 17002 // Determine the importance of the process, starting with most 17003 // important to least, and assign an appropriate OOM adjustment. 17004 int adj; 17005 int schedGroup; 17006 int procState; 17007 boolean foregroundActivities = false; 17008 BroadcastQueue queue; 17009 if (app == TOP_APP) { 17010 // The last app on the list is the foreground app. 17011 adj = ProcessList.FOREGROUND_APP_ADJ; 17012 schedGroup = Process.THREAD_GROUP_DEFAULT; 17013 app.adjType = "top-activity"; 17014 foregroundActivities = true; 17015 procState = ActivityManager.PROCESS_STATE_TOP; 17016 } else if (app.instrumentationClass != null) { 17017 // Don't want to kill running instrumentation. 17018 adj = ProcessList.FOREGROUND_APP_ADJ; 17019 schedGroup = Process.THREAD_GROUP_DEFAULT; 17020 app.adjType = "instrumentation"; 17021 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17022 } else if ((queue = isReceivingBroadcast(app)) != null) { 17023 // An app that is currently receiving a broadcast also 17024 // counts as being in the foreground for OOM killer purposes. 17025 // It's placed in a sched group based on the nature of the 17026 // broadcast as reflected by which queue it's active in. 17027 adj = ProcessList.FOREGROUND_APP_ADJ; 17028 schedGroup = (queue == mFgBroadcastQueue) 17029 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17030 app.adjType = "broadcast"; 17031 procState = ActivityManager.PROCESS_STATE_RECEIVER; 17032 } else if (app.executingServices.size() > 0) { 17033 // An app that is currently executing a service callback also 17034 // counts as being in the foreground. 17035 adj = ProcessList.FOREGROUND_APP_ADJ; 17036 schedGroup = app.execServicesFg ? 17037 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 17038 app.adjType = "exec-service"; 17039 procState = ActivityManager.PROCESS_STATE_SERVICE; 17040 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 17041 } else { 17042 // As far as we know the process is empty. We may change our mind later. 17043 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17044 // At this point we don't actually know the adjustment. Use the cached adj 17045 // value that the caller wants us to. 17046 adj = cachedAdj; 17047 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17048 app.cached = true; 17049 app.empty = true; 17050 app.adjType = "cch-empty"; 17051 } 17052 17053 // Examine all activities if not already foreground. 17054 if (!foregroundActivities && activitiesSize > 0) { 17055 for (int j = 0; j < activitiesSize; j++) { 17056 final ActivityRecord r = app.activities.get(j); 17057 if (r.app != app) { 17058 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 17059 + app + "?!?"); 17060 continue; 17061 } 17062 if (r.visible) { 17063 // App has a visible activity; only upgrade adjustment. 17064 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17065 adj = ProcessList.VISIBLE_APP_ADJ; 17066 app.adjType = "visible"; 17067 } 17068 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17069 procState = ActivityManager.PROCESS_STATE_TOP; 17070 } 17071 schedGroup = Process.THREAD_GROUP_DEFAULT; 17072 app.cached = false; 17073 app.empty = false; 17074 foregroundActivities = true; 17075 break; 17076 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 17077 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17078 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17079 app.adjType = "pausing"; 17080 } 17081 if (procState > ActivityManager.PROCESS_STATE_TOP) { 17082 procState = ActivityManager.PROCESS_STATE_TOP; 17083 } 17084 schedGroup = Process.THREAD_GROUP_DEFAULT; 17085 app.cached = false; 17086 app.empty = false; 17087 foregroundActivities = true; 17088 } else if (r.state == ActivityState.STOPPING) { 17089 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17090 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17091 app.adjType = "stopping"; 17092 } 17093 // For the process state, we will at this point consider the 17094 // process to be cached. It will be cached either as an activity 17095 // or empty depending on whether the activity is finishing. We do 17096 // this so that we can treat the process as cached for purposes of 17097 // memory trimming (determing current memory level, trim command to 17098 // send to process) since there can be an arbitrary number of stopping 17099 // processes and they should soon all go into the cached state. 17100 if (!r.finishing) { 17101 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17102 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17103 } 17104 } 17105 app.cached = false; 17106 app.empty = false; 17107 foregroundActivities = true; 17108 } else { 17109 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17110 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17111 app.adjType = "cch-act"; 17112 } 17113 } 17114 } 17115 } 17116 17117 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17118 if (app.foregroundServices) { 17119 // The user is aware of this app, so make it visible. 17120 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17121 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17122 app.cached = false; 17123 app.adjType = "fg-service"; 17124 schedGroup = Process.THREAD_GROUP_DEFAULT; 17125 } else if (app.forcingToForeground != null) { 17126 // The user is aware of this app, so make it visible. 17127 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17128 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17129 app.cached = false; 17130 app.adjType = "force-fg"; 17131 app.adjSource = app.forcingToForeground; 17132 schedGroup = Process.THREAD_GROUP_DEFAULT; 17133 } 17134 } 17135 17136 if (app == mHeavyWeightProcess) { 17137 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 17138 // We don't want to kill the current heavy-weight process. 17139 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 17140 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17141 app.cached = false; 17142 app.adjType = "heavy"; 17143 } 17144 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17145 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 17146 } 17147 } 17148 17149 if (app == mHomeProcess) { 17150 if (adj > ProcessList.HOME_APP_ADJ) { 17151 // This process is hosting what we currently consider to be the 17152 // home app, so we don't want to let it go into the background. 17153 adj = ProcessList.HOME_APP_ADJ; 17154 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17155 app.cached = false; 17156 app.adjType = "home"; 17157 } 17158 if (procState > ActivityManager.PROCESS_STATE_HOME) { 17159 procState = ActivityManager.PROCESS_STATE_HOME; 17160 } 17161 } 17162 17163 if (app == mPreviousProcess && app.activities.size() > 0) { 17164 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 17165 // This was the previous process that showed UI to the user. 17166 // We want to try to keep it around more aggressively, to give 17167 // a good experience around switching between two apps. 17168 adj = ProcessList.PREVIOUS_APP_ADJ; 17169 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 17170 app.cached = false; 17171 app.adjType = "previous"; 17172 } 17173 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 17174 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 17175 } 17176 } 17177 17178 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 17179 + " reason=" + app.adjType); 17180 17181 // By default, we use the computed adjustment. It may be changed if 17182 // there are applications dependent on our services or providers, but 17183 // this gives us a baseline and makes sure we don't get into an 17184 // infinite recursion. 17185 app.adjSeq = mAdjSeq; 17186 app.curRawAdj = adj; 17187 app.hasStartedServices = false; 17188 17189 if (mBackupTarget != null && app == mBackupTarget.app) { 17190 // If possible we want to avoid killing apps while they're being backed up 17191 if (adj > ProcessList.BACKUP_APP_ADJ) { 17192 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 17193 adj = ProcessList.BACKUP_APP_ADJ; 17194 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17195 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17196 } 17197 app.adjType = "backup"; 17198 app.cached = false; 17199 } 17200 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 17201 procState = ActivityManager.PROCESS_STATE_BACKUP; 17202 } 17203 } 17204 17205 boolean mayBeTop = false; 17206 17207 for (int is = app.services.size()-1; 17208 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17209 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17210 || procState > ActivityManager.PROCESS_STATE_TOP); 17211 is--) { 17212 ServiceRecord s = app.services.valueAt(is); 17213 if (s.startRequested) { 17214 app.hasStartedServices = true; 17215 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 17216 procState = ActivityManager.PROCESS_STATE_SERVICE; 17217 } 17218 if (app.hasShownUi && app != mHomeProcess) { 17219 // If this process has shown some UI, let it immediately 17220 // go to the LRU list because it may be pretty heavy with 17221 // UI stuff. We'll tag it with a label just to help 17222 // debug and understand what is going on. 17223 if (adj > ProcessList.SERVICE_ADJ) { 17224 app.adjType = "cch-started-ui-services"; 17225 } 17226 } else { 17227 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17228 // This service has seen some activity within 17229 // recent memory, so we will keep its process ahead 17230 // of the background processes. 17231 if (adj > ProcessList.SERVICE_ADJ) { 17232 adj = ProcessList.SERVICE_ADJ; 17233 app.adjType = "started-services"; 17234 app.cached = false; 17235 } 17236 } 17237 // If we have let the service slide into the background 17238 // state, still have some text describing what it is doing 17239 // even though the service no longer has an impact. 17240 if (adj > ProcessList.SERVICE_ADJ) { 17241 app.adjType = "cch-started-services"; 17242 } 17243 } 17244 } 17245 for (int conni = s.connections.size()-1; 17246 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17247 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17248 || procState > ActivityManager.PROCESS_STATE_TOP); 17249 conni--) { 17250 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 17251 for (int i = 0; 17252 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 17253 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17254 || procState > ActivityManager.PROCESS_STATE_TOP); 17255 i++) { 17256 // XXX should compute this based on the max of 17257 // all connected clients. 17258 ConnectionRecord cr = clist.get(i); 17259 if (cr.binding.client == app) { 17260 // Binding to ourself is not interesting. 17261 continue; 17262 } 17263 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 17264 ProcessRecord client = cr.binding.client; 17265 int clientAdj = computeOomAdjLocked(client, cachedAdj, 17266 TOP_APP, doingAll, now); 17267 int clientProcState = client.curProcState; 17268 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17269 // If the other app is cached for any reason, for purposes here 17270 // we are going to consider it empty. The specific cached state 17271 // doesn't propagate except under certain conditions. 17272 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17273 } 17274 String adjType = null; 17275 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 17276 // Not doing bind OOM management, so treat 17277 // this guy more like a started service. 17278 if (app.hasShownUi && app != mHomeProcess) { 17279 // If this process has shown some UI, let it immediately 17280 // go to the LRU list because it may be pretty heavy with 17281 // UI stuff. We'll tag it with a label just to help 17282 // debug and understand what is going on. 17283 if (adj > clientAdj) { 17284 adjType = "cch-bound-ui-services"; 17285 } 17286 app.cached = false; 17287 clientAdj = adj; 17288 clientProcState = procState; 17289 } else { 17290 if (now >= (s.lastActivity 17291 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 17292 // This service has not seen activity within 17293 // recent memory, so allow it to drop to the 17294 // LRU list if there is no other reason to keep 17295 // it around. We'll also tag it with a label just 17296 // to help debug and undertand what is going on. 17297 if (adj > clientAdj) { 17298 adjType = "cch-bound-services"; 17299 } 17300 clientAdj = adj; 17301 } 17302 } 17303 } 17304 if (adj > clientAdj) { 17305 // If this process has recently shown UI, and 17306 // the process that is binding to it is less 17307 // important than being visible, then we don't 17308 // care about the binding as much as we care 17309 // about letting this process get into the LRU 17310 // list to be killed and restarted if needed for 17311 // memory. 17312 if (app.hasShownUi && app != mHomeProcess 17313 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17314 adjType = "cch-bound-ui-services"; 17315 } else { 17316 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 17317 |Context.BIND_IMPORTANT)) != 0) { 17318 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 17319 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 17320 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 17321 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 17322 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17323 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 17324 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 17325 adj = clientAdj; 17326 } else { 17327 if (adj > ProcessList.VISIBLE_APP_ADJ) { 17328 adj = ProcessList.VISIBLE_APP_ADJ; 17329 } 17330 } 17331 if (!client.cached) { 17332 app.cached = false; 17333 } 17334 adjType = "service"; 17335 } 17336 } 17337 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17338 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17339 schedGroup = Process.THREAD_GROUP_DEFAULT; 17340 } 17341 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17342 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17343 // Special handling of clients who are in the top state. 17344 // We *may* want to consider this process to be in the 17345 // top state as well, but only if there is not another 17346 // reason for it to be running. Being on the top is a 17347 // special state, meaning you are specifically running 17348 // for the current top app. If the process is already 17349 // running in the background for some other reason, it 17350 // is more important to continue considering it to be 17351 // in the background state. 17352 mayBeTop = true; 17353 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17354 } else { 17355 // Special handling for above-top states (persistent 17356 // processes). These should not bring the current process 17357 // into the top state, since they are not on top. Instead 17358 // give them the best state after that. 17359 clientProcState = 17360 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17361 } 17362 } 17363 } else { 17364 if (clientProcState < 17365 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 17366 clientProcState = 17367 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 17368 } 17369 } 17370 if (procState > clientProcState) { 17371 procState = clientProcState; 17372 } 17373 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17374 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 17375 app.pendingUiClean = true; 17376 } 17377 if (adjType != null) { 17378 app.adjType = adjType; 17379 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17380 .REASON_SERVICE_IN_USE; 17381 app.adjSource = cr.binding.client; 17382 app.adjSourceProcState = clientProcState; 17383 app.adjTarget = s.name; 17384 } 17385 } 17386 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 17387 app.treatLikeActivity = true; 17388 } 17389 final ActivityRecord a = cr.activity; 17390 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 17391 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 17392 (a.visible || a.state == ActivityState.RESUMED 17393 || a.state == ActivityState.PAUSING)) { 17394 adj = ProcessList.FOREGROUND_APP_ADJ; 17395 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 17396 schedGroup = Process.THREAD_GROUP_DEFAULT; 17397 } 17398 app.cached = false; 17399 app.adjType = "service"; 17400 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17401 .REASON_SERVICE_IN_USE; 17402 app.adjSource = a; 17403 app.adjSourceProcState = procState; 17404 app.adjTarget = s.name; 17405 } 17406 } 17407 } 17408 } 17409 } 17410 17411 for (int provi = app.pubProviders.size()-1; 17412 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17413 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17414 || procState > ActivityManager.PROCESS_STATE_TOP); 17415 provi--) { 17416 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 17417 for (int i = cpr.connections.size()-1; 17418 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 17419 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 17420 || procState > ActivityManager.PROCESS_STATE_TOP); 17421 i--) { 17422 ContentProviderConnection conn = cpr.connections.get(i); 17423 ProcessRecord client = conn.client; 17424 if (client == app) { 17425 // Being our own client is not interesting. 17426 continue; 17427 } 17428 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 17429 int clientProcState = client.curProcState; 17430 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 17431 // If the other app is cached for any reason, for purposes here 17432 // we are going to consider it empty. 17433 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17434 } 17435 if (adj > clientAdj) { 17436 if (app.hasShownUi && app != mHomeProcess 17437 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 17438 app.adjType = "cch-ui-provider"; 17439 } else { 17440 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 17441 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 17442 app.adjType = "provider"; 17443 } 17444 app.cached &= client.cached; 17445 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 17446 .REASON_PROVIDER_IN_USE; 17447 app.adjSource = client; 17448 app.adjSourceProcState = clientProcState; 17449 app.adjTarget = cpr.name; 17450 } 17451 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 17452 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 17453 // Special handling of clients who are in the top state. 17454 // We *may* want to consider this process to be in the 17455 // top state as well, but only if there is not another 17456 // reason for it to be running. Being on the top is a 17457 // special state, meaning you are specifically running 17458 // for the current top app. If the process is already 17459 // running in the background for some other reason, it 17460 // is more important to continue considering it to be 17461 // in the background state. 17462 mayBeTop = true; 17463 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 17464 } else { 17465 // Special handling for above-top states (persistent 17466 // processes). These should not bring the current process 17467 // into the top state, since they are not on top. Instead 17468 // give them the best state after that. 17469 clientProcState = 17470 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17471 } 17472 } 17473 if (procState > clientProcState) { 17474 procState = clientProcState; 17475 } 17476 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 17477 schedGroup = Process.THREAD_GROUP_DEFAULT; 17478 } 17479 } 17480 // If the provider has external (non-framework) process 17481 // dependencies, ensure that its adjustment is at least 17482 // FOREGROUND_APP_ADJ. 17483 if (cpr.hasExternalProcessHandles()) { 17484 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 17485 adj = ProcessList.FOREGROUND_APP_ADJ; 17486 schedGroup = Process.THREAD_GROUP_DEFAULT; 17487 app.cached = false; 17488 app.adjType = "provider"; 17489 app.adjTarget = cpr.name; 17490 } 17491 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 17492 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17493 } 17494 } 17495 } 17496 17497 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17498 // A client of one of our services or providers is in the top state. We 17499 // *may* want to be in the top state, but not if we are already running in 17500 // the background for some other reason. For the decision here, we are going 17501 // to pick out a few specific states that we want to remain in when a client 17502 // is top (states that tend to be longer-term) and otherwise allow it to go 17503 // to the top state. 17504 switch (procState) { 17505 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17506 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17507 case ActivityManager.PROCESS_STATE_SERVICE: 17508 // These all are longer-term states, so pull them up to the top 17509 // of the background states, but not all the way to the top state. 17510 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17511 break; 17512 default: 17513 // Otherwise, top is a better choice, so take it. 17514 procState = ActivityManager.PROCESS_STATE_TOP; 17515 break; 17516 } 17517 } 17518 17519 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17520 if (app.hasClientActivities) { 17521 // This is a cached process, but with client activities. Mark it so. 17522 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17523 app.adjType = "cch-client-act"; 17524 } else if (app.treatLikeActivity) { 17525 // This is a cached process, but somebody wants us to treat it like it has 17526 // an activity, okay! 17527 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17528 app.adjType = "cch-as-act"; 17529 } 17530 } 17531 17532 if (adj == ProcessList.SERVICE_ADJ) { 17533 if (doingAll) { 17534 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17535 mNewNumServiceProcs++; 17536 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17537 if (!app.serviceb) { 17538 // This service isn't far enough down on the LRU list to 17539 // normally be a B service, but if we are low on RAM and it 17540 // is large we want to force it down since we would prefer to 17541 // keep launcher over it. 17542 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17543 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17544 app.serviceHighRam = true; 17545 app.serviceb = true; 17546 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17547 } else { 17548 mNewNumAServiceProcs++; 17549 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17550 } 17551 } else { 17552 app.serviceHighRam = false; 17553 } 17554 } 17555 if (app.serviceb) { 17556 adj = ProcessList.SERVICE_B_ADJ; 17557 } 17558 } 17559 17560 app.curRawAdj = adj; 17561 17562 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17563 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17564 if (adj > app.maxAdj) { 17565 adj = app.maxAdj; 17566 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17567 schedGroup = Process.THREAD_GROUP_DEFAULT; 17568 } 17569 } 17570 17571 // Do final modification to adj. Everything we do between here and applying 17572 // the final setAdj must be done in this function, because we will also use 17573 // it when computing the final cached adj later. Note that we don't need to 17574 // worry about this for max adj above, since max adj will always be used to 17575 // keep it out of the cached vaues. 17576 app.curAdj = app.modifyRawOomAdj(adj); 17577 app.curSchedGroup = schedGroup; 17578 app.curProcState = procState; 17579 app.foregroundActivities = foregroundActivities; 17580 17581 return app.curRawAdj; 17582 } 17583 17584 /** 17585 * Record new PSS sample for a process. 17586 */ 17587 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) { 17588 proc.lastPssTime = now; 17589 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 17590 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 17591 + ": " + pss + " lastPss=" + proc.lastPss 17592 + " state=" + ProcessList.makeProcStateString(procState)); 17593 if (proc.initialIdlePss == 0) { 17594 proc.initialIdlePss = pss; 17595 } 17596 proc.lastPss = pss; 17597 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 17598 proc.lastCachedPss = pss; 17599 } 17600 } 17601 17602 /** 17603 * Schedule PSS collection of a process. 17604 */ 17605 void requestPssLocked(ProcessRecord proc, int procState) { 17606 if (mPendingPssProcesses.contains(proc)) { 17607 return; 17608 } 17609 if (mPendingPssProcesses.size() == 0) { 17610 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17611 } 17612 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17613 proc.pssProcState = procState; 17614 mPendingPssProcesses.add(proc); 17615 } 17616 17617 /** 17618 * Schedule PSS collection of all processes. 17619 */ 17620 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17621 if (!always) { 17622 if (now < (mLastFullPssTime + 17623 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17624 return; 17625 } 17626 } 17627 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17628 mLastFullPssTime = now; 17629 mFullPssPending = true; 17630 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17631 mPendingPssProcesses.clear(); 17632 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17633 ProcessRecord app = mLruProcesses.get(i); 17634 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17635 app.pssProcState = app.setProcState; 17636 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17637 mTestPssMode, isSleeping(), now); 17638 mPendingPssProcesses.add(app); 17639 } 17640 } 17641 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17642 } 17643 17644 public void setTestPssMode(boolean enabled) { 17645 synchronized (this) { 17646 mTestPssMode = enabled; 17647 if (enabled) { 17648 // Whenever we enable the mode, we want to take a snapshot all of current 17649 // process mem use. 17650 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 17651 } 17652 } 17653 } 17654 17655 /** 17656 * Ask a given process to GC right now. 17657 */ 17658 final void performAppGcLocked(ProcessRecord app) { 17659 try { 17660 app.lastRequestedGc = SystemClock.uptimeMillis(); 17661 if (app.thread != null) { 17662 if (app.reportLowMemory) { 17663 app.reportLowMemory = false; 17664 app.thread.scheduleLowMemory(); 17665 } else { 17666 app.thread.processInBackground(); 17667 } 17668 } 17669 } catch (Exception e) { 17670 // whatever. 17671 } 17672 } 17673 17674 /** 17675 * Returns true if things are idle enough to perform GCs. 17676 */ 17677 private final boolean canGcNowLocked() { 17678 boolean processingBroadcasts = false; 17679 for (BroadcastQueue q : mBroadcastQueues) { 17680 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17681 processingBroadcasts = true; 17682 } 17683 } 17684 return !processingBroadcasts 17685 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17686 } 17687 17688 /** 17689 * Perform GCs on all processes that are waiting for it, but only 17690 * if things are idle. 17691 */ 17692 final void performAppGcsLocked() { 17693 final int N = mProcessesToGc.size(); 17694 if (N <= 0) { 17695 return; 17696 } 17697 if (canGcNowLocked()) { 17698 while (mProcessesToGc.size() > 0) { 17699 ProcessRecord proc = mProcessesToGc.remove(0); 17700 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17701 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17702 <= SystemClock.uptimeMillis()) { 17703 // To avoid spamming the system, we will GC processes one 17704 // at a time, waiting a few seconds between each. 17705 performAppGcLocked(proc); 17706 scheduleAppGcsLocked(); 17707 return; 17708 } else { 17709 // It hasn't been long enough since we last GCed this 17710 // process... put it in the list to wait for its time. 17711 addProcessToGcListLocked(proc); 17712 break; 17713 } 17714 } 17715 } 17716 17717 scheduleAppGcsLocked(); 17718 } 17719 } 17720 17721 /** 17722 * If all looks good, perform GCs on all processes waiting for them. 17723 */ 17724 final void performAppGcsIfAppropriateLocked() { 17725 if (canGcNowLocked()) { 17726 performAppGcsLocked(); 17727 return; 17728 } 17729 // Still not idle, wait some more. 17730 scheduleAppGcsLocked(); 17731 } 17732 17733 /** 17734 * Schedule the execution of all pending app GCs. 17735 */ 17736 final void scheduleAppGcsLocked() { 17737 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17738 17739 if (mProcessesToGc.size() > 0) { 17740 // Schedule a GC for the time to the next process. 17741 ProcessRecord proc = mProcessesToGc.get(0); 17742 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17743 17744 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17745 long now = SystemClock.uptimeMillis(); 17746 if (when < (now+GC_TIMEOUT)) { 17747 when = now + GC_TIMEOUT; 17748 } 17749 mHandler.sendMessageAtTime(msg, when); 17750 } 17751 } 17752 17753 /** 17754 * Add a process to the array of processes waiting to be GCed. Keeps the 17755 * list in sorted order by the last GC time. The process can't already be 17756 * on the list. 17757 */ 17758 final void addProcessToGcListLocked(ProcessRecord proc) { 17759 boolean added = false; 17760 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17761 if (mProcessesToGc.get(i).lastRequestedGc < 17762 proc.lastRequestedGc) { 17763 added = true; 17764 mProcessesToGc.add(i+1, proc); 17765 break; 17766 } 17767 } 17768 if (!added) { 17769 mProcessesToGc.add(0, proc); 17770 } 17771 } 17772 17773 /** 17774 * Set up to ask a process to GC itself. This will either do it 17775 * immediately, or put it on the list of processes to gc the next 17776 * time things are idle. 17777 */ 17778 final void scheduleAppGcLocked(ProcessRecord app) { 17779 long now = SystemClock.uptimeMillis(); 17780 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17781 return; 17782 } 17783 if (!mProcessesToGc.contains(app)) { 17784 addProcessToGcListLocked(app); 17785 scheduleAppGcsLocked(); 17786 } 17787 } 17788 17789 final void checkExcessivePowerUsageLocked(boolean doKills) { 17790 updateCpuStatsNow(); 17791 17792 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17793 boolean doWakeKills = doKills; 17794 boolean doCpuKills = doKills; 17795 if (mLastPowerCheckRealtime == 0) { 17796 doWakeKills = false; 17797 } 17798 if (mLastPowerCheckUptime == 0) { 17799 doCpuKills = false; 17800 } 17801 if (stats.isScreenOn()) { 17802 doWakeKills = false; 17803 } 17804 final long curRealtime = SystemClock.elapsedRealtime(); 17805 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17806 final long curUptime = SystemClock.uptimeMillis(); 17807 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17808 mLastPowerCheckRealtime = curRealtime; 17809 mLastPowerCheckUptime = curUptime; 17810 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17811 doWakeKills = false; 17812 } 17813 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17814 doCpuKills = false; 17815 } 17816 int i = mLruProcesses.size(); 17817 while (i > 0) { 17818 i--; 17819 ProcessRecord app = mLruProcesses.get(i); 17820 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17821 long wtime; 17822 synchronized (stats) { 17823 wtime = stats.getProcessWakeTime(app.info.uid, 17824 app.pid, curRealtime); 17825 } 17826 long wtimeUsed = wtime - app.lastWakeTime; 17827 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17828 if (DEBUG_POWER) { 17829 StringBuilder sb = new StringBuilder(128); 17830 sb.append("Wake for "); 17831 app.toShortString(sb); 17832 sb.append(": over "); 17833 TimeUtils.formatDuration(realtimeSince, sb); 17834 sb.append(" used "); 17835 TimeUtils.formatDuration(wtimeUsed, sb); 17836 sb.append(" ("); 17837 sb.append((wtimeUsed*100)/realtimeSince); 17838 sb.append("%)"); 17839 Slog.i(TAG, sb.toString()); 17840 sb.setLength(0); 17841 sb.append("CPU for "); 17842 app.toShortString(sb); 17843 sb.append(": over "); 17844 TimeUtils.formatDuration(uptimeSince, sb); 17845 sb.append(" used "); 17846 TimeUtils.formatDuration(cputimeUsed, sb); 17847 sb.append(" ("); 17848 sb.append((cputimeUsed*100)/uptimeSince); 17849 sb.append("%)"); 17850 Slog.i(TAG, sb.toString()); 17851 } 17852 // If a process has held a wake lock for more 17853 // than 50% of the time during this period, 17854 // that sounds bad. Kill! 17855 if (doWakeKills && realtimeSince > 0 17856 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17857 synchronized (stats) { 17858 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17859 realtimeSince, wtimeUsed); 17860 } 17861 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17862 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17863 } else if (doCpuKills && uptimeSince > 0 17864 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17865 synchronized (stats) { 17866 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17867 uptimeSince, cputimeUsed); 17868 } 17869 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17870 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17871 } else { 17872 app.lastWakeTime = wtime; 17873 app.lastCpuTime = app.curCpuTime; 17874 } 17875 } 17876 } 17877 } 17878 17879 private final boolean applyOomAdjLocked(ProcessRecord app, 17880 ProcessRecord TOP_APP, boolean doingAll, long now) { 17881 boolean success = true; 17882 17883 if (app.curRawAdj != app.setRawAdj) { 17884 app.setRawAdj = app.curRawAdj; 17885 } 17886 17887 int changes = 0; 17888 17889 if (app.curAdj != app.setAdj) { 17890 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17891 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17892 TAG, "Set " + app.pid + " " + app.processName + 17893 " adj " + app.curAdj + ": " + app.adjType); 17894 app.setAdj = app.curAdj; 17895 } 17896 17897 if (app.setSchedGroup != app.curSchedGroup) { 17898 app.setSchedGroup = app.curSchedGroup; 17899 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17900 "Setting process group of " + app.processName 17901 + " to " + app.curSchedGroup); 17902 if (app.waitingToKill != null && 17903 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17904 app.kill(app.waitingToKill, true); 17905 success = false; 17906 } else { 17907 if (true) { 17908 long oldId = Binder.clearCallingIdentity(); 17909 try { 17910 Process.setProcessGroup(app.pid, app.curSchedGroup); 17911 } catch (Exception e) { 17912 Slog.w(TAG, "Failed setting process group of " + app.pid 17913 + " to " + app.curSchedGroup); 17914 e.printStackTrace(); 17915 } finally { 17916 Binder.restoreCallingIdentity(oldId); 17917 } 17918 } else { 17919 if (app.thread != null) { 17920 try { 17921 app.thread.setSchedulingGroup(app.curSchedGroup); 17922 } catch (RemoteException e) { 17923 } 17924 } 17925 } 17926 Process.setSwappiness(app.pid, 17927 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17928 } 17929 } 17930 if (app.repForegroundActivities != app.foregroundActivities) { 17931 app.repForegroundActivities = app.foregroundActivities; 17932 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17933 } 17934 if (app.repProcState != app.curProcState) { 17935 app.repProcState = app.curProcState; 17936 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17937 if (app.thread != null) { 17938 try { 17939 if (false) { 17940 //RuntimeException h = new RuntimeException("here"); 17941 Slog.i(TAG, "Sending new process state " + app.repProcState 17942 + " to " + app /*, h*/); 17943 } 17944 app.thread.setProcessState(app.repProcState); 17945 } catch (RemoteException e) { 17946 } 17947 } 17948 } 17949 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17950 app.setProcState)) { 17951 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 17952 // Experimental code to more aggressively collect pss while 17953 // running test... the problem is that this tends to collect 17954 // the data right when a process is transitioning between process 17955 // states, which well tend to give noisy data. 17956 long start = SystemClock.uptimeMillis(); 17957 long pss = Debug.getPss(app.pid, mTmpLong, null); 17958 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now); 17959 mPendingPssProcesses.remove(app); 17960 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 17961 + " to " + app.curProcState + ": " 17962 + (SystemClock.uptimeMillis()-start) + "ms"); 17963 } 17964 app.lastStateTime = now; 17965 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17966 mTestPssMode, isSleeping(), now); 17967 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17968 + ProcessList.makeProcStateString(app.setProcState) + " to " 17969 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17970 + (app.nextPssTime-now) + ": " + app); 17971 } else { 17972 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17973 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 17974 mTestPssMode)))) { 17975 requestPssLocked(app, app.setProcState); 17976 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17977 mTestPssMode, isSleeping(), now); 17978 } else if (false && DEBUG_PSS) { 17979 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17980 } 17981 } 17982 if (app.setProcState != app.curProcState) { 17983 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17984 "Proc state change of " + app.processName 17985 + " to " + app.curProcState); 17986 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17987 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17988 if (setImportant && !curImportant) { 17989 // This app is no longer something we consider important enough to allow to 17990 // use arbitrary amounts of battery power. Note 17991 // its current wake lock time to later know to kill it if 17992 // it is not behaving well. 17993 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17994 synchronized (stats) { 17995 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17996 app.pid, SystemClock.elapsedRealtime()); 17997 } 17998 app.lastCpuTime = app.curCpuTime; 17999 18000 } 18001 app.setProcState = app.curProcState; 18002 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 18003 app.notCachedSinceIdle = false; 18004 } 18005 if (!doingAll) { 18006 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 18007 } else { 18008 app.procStateChanged = true; 18009 } 18010 } 18011 18012 if (changes != 0) { 18013 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 18014 int i = mPendingProcessChanges.size()-1; 18015 ProcessChangeItem item = null; 18016 while (i >= 0) { 18017 item = mPendingProcessChanges.get(i); 18018 if (item.pid == app.pid) { 18019 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 18020 break; 18021 } 18022 i--; 18023 } 18024 if (i < 0) { 18025 // No existing item in pending changes; need a new one. 18026 final int NA = mAvailProcessChanges.size(); 18027 if (NA > 0) { 18028 item = mAvailProcessChanges.remove(NA-1); 18029 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 18030 } else { 18031 item = new ProcessChangeItem(); 18032 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 18033 } 18034 item.changes = 0; 18035 item.pid = app.pid; 18036 item.uid = app.info.uid; 18037 if (mPendingProcessChanges.size() == 0) { 18038 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 18039 "*** Enqueueing dispatch processes changed!"); 18040 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 18041 } 18042 mPendingProcessChanges.add(item); 18043 } 18044 item.changes |= changes; 18045 item.processState = app.repProcState; 18046 item.foregroundActivities = app.repForegroundActivities; 18047 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 18048 + Integer.toHexString(System.identityHashCode(item)) 18049 + " " + app.toShortString() + ": changes=" + item.changes 18050 + " procState=" + item.processState 18051 + " foreground=" + item.foregroundActivities 18052 + " type=" + app.adjType + " source=" + app.adjSource 18053 + " target=" + app.adjTarget); 18054 } 18055 18056 return success; 18057 } 18058 18059 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 18060 if (proc.thread != null) { 18061 if (proc.baseProcessTracker != null) { 18062 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 18063 } 18064 if (proc.repProcState >= 0) { 18065 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 18066 proc.repProcState); 18067 } 18068 } 18069 } 18070 18071 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 18072 ProcessRecord TOP_APP, boolean doingAll, long now) { 18073 if (app.thread == null) { 18074 return false; 18075 } 18076 18077 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 18078 18079 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 18080 } 18081 18082 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 18083 boolean oomAdj) { 18084 if (isForeground != proc.foregroundServices) { 18085 proc.foregroundServices = isForeground; 18086 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 18087 proc.info.uid); 18088 if (isForeground) { 18089 if (curProcs == null) { 18090 curProcs = new ArrayList<ProcessRecord>(); 18091 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 18092 } 18093 if (!curProcs.contains(proc)) { 18094 curProcs.add(proc); 18095 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 18096 proc.info.packageName, proc.info.uid); 18097 } 18098 } else { 18099 if (curProcs != null) { 18100 if (curProcs.remove(proc)) { 18101 mBatteryStatsService.noteEvent( 18102 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 18103 proc.info.packageName, proc.info.uid); 18104 if (curProcs.size() <= 0) { 18105 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 18106 } 18107 } 18108 } 18109 } 18110 if (oomAdj) { 18111 updateOomAdjLocked(); 18112 } 18113 } 18114 } 18115 18116 private final ActivityRecord resumedAppLocked() { 18117 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 18118 String pkg; 18119 int uid; 18120 if (act != null) { 18121 pkg = act.packageName; 18122 uid = act.info.applicationInfo.uid; 18123 } else { 18124 pkg = null; 18125 uid = -1; 18126 } 18127 // Has the UID or resumed package name changed? 18128 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 18129 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 18130 if (mCurResumedPackage != null) { 18131 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 18132 mCurResumedPackage, mCurResumedUid); 18133 } 18134 mCurResumedPackage = pkg; 18135 mCurResumedUid = uid; 18136 if (mCurResumedPackage != null) { 18137 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 18138 mCurResumedPackage, mCurResumedUid); 18139 } 18140 } 18141 return act; 18142 } 18143 18144 final boolean updateOomAdjLocked(ProcessRecord app) { 18145 final ActivityRecord TOP_ACT = resumedAppLocked(); 18146 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18147 final boolean wasCached = app.cached; 18148 18149 mAdjSeq++; 18150 18151 // This is the desired cached adjusment we want to tell it to use. 18152 // If our app is currently cached, we know it, and that is it. Otherwise, 18153 // we don't know it yet, and it needs to now be cached we will then 18154 // need to do a complete oom adj. 18155 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 18156 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 18157 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 18158 SystemClock.uptimeMillis()); 18159 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 18160 // Changed to/from cached state, so apps after it in the LRU 18161 // list may also be changed. 18162 updateOomAdjLocked(); 18163 } 18164 return success; 18165 } 18166 18167 final void updateOomAdjLocked() { 18168 final ActivityRecord TOP_ACT = resumedAppLocked(); 18169 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 18170 final long now = SystemClock.uptimeMillis(); 18171 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 18172 final int N = mLruProcesses.size(); 18173 18174 if (false) { 18175 RuntimeException e = new RuntimeException(); 18176 e.fillInStackTrace(); 18177 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 18178 } 18179 18180 mAdjSeq++; 18181 mNewNumServiceProcs = 0; 18182 mNewNumAServiceProcs = 0; 18183 18184 final int emptyProcessLimit; 18185 final int cachedProcessLimit; 18186 if (mProcessLimit <= 0) { 18187 emptyProcessLimit = cachedProcessLimit = 0; 18188 } else if (mProcessLimit == 1) { 18189 emptyProcessLimit = 1; 18190 cachedProcessLimit = 0; 18191 } else { 18192 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 18193 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 18194 } 18195 18196 // Let's determine how many processes we have running vs. 18197 // how many slots we have for background processes; we may want 18198 // to put multiple processes in a slot of there are enough of 18199 // them. 18200 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 18201 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 18202 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 18203 if (numEmptyProcs > cachedProcessLimit) { 18204 // If there are more empty processes than our limit on cached 18205 // processes, then use the cached process limit for the factor. 18206 // This ensures that the really old empty processes get pushed 18207 // down to the bottom, so if we are running low on memory we will 18208 // have a better chance at keeping around more cached processes 18209 // instead of a gazillion empty processes. 18210 numEmptyProcs = cachedProcessLimit; 18211 } 18212 int emptyFactor = numEmptyProcs/numSlots; 18213 if (emptyFactor < 1) emptyFactor = 1; 18214 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 18215 if (cachedFactor < 1) cachedFactor = 1; 18216 int stepCached = 0; 18217 int stepEmpty = 0; 18218 int numCached = 0; 18219 int numEmpty = 0; 18220 int numTrimming = 0; 18221 18222 mNumNonCachedProcs = 0; 18223 mNumCachedHiddenProcs = 0; 18224 18225 // First update the OOM adjustment for each of the 18226 // application processes based on their current state. 18227 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 18228 int nextCachedAdj = curCachedAdj+1; 18229 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 18230 int nextEmptyAdj = curEmptyAdj+2; 18231 for (int i=N-1; i>=0; i--) { 18232 ProcessRecord app = mLruProcesses.get(i); 18233 if (!app.killedByAm && app.thread != null) { 18234 app.procStateChanged = false; 18235 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 18236 18237 // If we haven't yet assigned the final cached adj 18238 // to the process, do that now. 18239 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 18240 switch (app.curProcState) { 18241 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18242 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18243 // This process is a cached process holding activities... 18244 // assign it the next cached value for that type, and then 18245 // step that cached level. 18246 app.curRawAdj = curCachedAdj; 18247 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 18248 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 18249 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 18250 + ")"); 18251 if (curCachedAdj != nextCachedAdj) { 18252 stepCached++; 18253 if (stepCached >= cachedFactor) { 18254 stepCached = 0; 18255 curCachedAdj = nextCachedAdj; 18256 nextCachedAdj += 2; 18257 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18258 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 18259 } 18260 } 18261 } 18262 break; 18263 default: 18264 // For everything else, assign next empty cached process 18265 // level and bump that up. Note that this means that 18266 // long-running services that have dropped down to the 18267 // cached level will be treated as empty (since their process 18268 // state is still as a service), which is what we want. 18269 app.curRawAdj = curEmptyAdj; 18270 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 18271 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 18272 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 18273 + ")"); 18274 if (curEmptyAdj != nextEmptyAdj) { 18275 stepEmpty++; 18276 if (stepEmpty >= emptyFactor) { 18277 stepEmpty = 0; 18278 curEmptyAdj = nextEmptyAdj; 18279 nextEmptyAdj += 2; 18280 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 18281 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 18282 } 18283 } 18284 } 18285 break; 18286 } 18287 } 18288 18289 applyOomAdjLocked(app, TOP_APP, true, now); 18290 18291 // Count the number of process types. 18292 switch (app.curProcState) { 18293 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 18294 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 18295 mNumCachedHiddenProcs++; 18296 numCached++; 18297 if (numCached > cachedProcessLimit) { 18298 app.kill("cached #" + numCached, true); 18299 } 18300 break; 18301 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 18302 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 18303 && app.lastActivityTime < oldTime) { 18304 app.kill("empty for " 18305 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 18306 / 1000) + "s", true); 18307 } else { 18308 numEmpty++; 18309 if (numEmpty > emptyProcessLimit) { 18310 app.kill("empty #" + numEmpty, true); 18311 } 18312 } 18313 break; 18314 default: 18315 mNumNonCachedProcs++; 18316 break; 18317 } 18318 18319 if (app.isolated && app.services.size() <= 0) { 18320 // If this is an isolated process, and there are no 18321 // services running in it, then the process is no longer 18322 // needed. We agressively kill these because we can by 18323 // definition not re-use the same process again, and it is 18324 // good to avoid having whatever code was running in them 18325 // left sitting around after no longer needed. 18326 app.kill("isolated not needed", true); 18327 } 18328 18329 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18330 && !app.killedByAm) { 18331 numTrimming++; 18332 } 18333 } 18334 } 18335 18336 mNumServiceProcs = mNewNumServiceProcs; 18337 18338 // Now determine the memory trimming level of background processes. 18339 // Unfortunately we need to start at the back of the list to do this 18340 // properly. We only do this if the number of background apps we 18341 // are managing to keep around is less than half the maximum we desire; 18342 // if we are keeping a good number around, we'll let them use whatever 18343 // memory they want. 18344 final int numCachedAndEmpty = numCached + numEmpty; 18345 int memFactor; 18346 if (numCached <= ProcessList.TRIM_CACHED_APPS 18347 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 18348 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 18349 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 18350 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 18351 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 18352 } else { 18353 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 18354 } 18355 } else { 18356 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 18357 } 18358 // We always allow the memory level to go up (better). We only allow it to go 18359 // down if we are in a state where that is allowed, *and* the total number of processes 18360 // has gone down since last time. 18361 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 18362 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 18363 + " last=" + mLastNumProcesses); 18364 if (memFactor > mLastMemoryLevel) { 18365 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 18366 memFactor = mLastMemoryLevel; 18367 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 18368 } 18369 } 18370 mLastMemoryLevel = memFactor; 18371 mLastNumProcesses = mLruProcesses.size(); 18372 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 18373 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 18374 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 18375 if (mLowRamStartTime == 0) { 18376 mLowRamStartTime = now; 18377 } 18378 int step = 0; 18379 int fgTrimLevel; 18380 switch (memFactor) { 18381 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 18382 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 18383 break; 18384 case ProcessStats.ADJ_MEM_FACTOR_LOW: 18385 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 18386 break; 18387 default: 18388 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 18389 break; 18390 } 18391 int factor = numTrimming/3; 18392 int minFactor = 2; 18393 if (mHomeProcess != null) minFactor++; 18394 if (mPreviousProcess != null) minFactor++; 18395 if (factor < minFactor) factor = minFactor; 18396 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 18397 for (int i=N-1; i>=0; i--) { 18398 ProcessRecord app = mLruProcesses.get(i); 18399 if (allChanged || app.procStateChanged) { 18400 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18401 app.procStateChanged = false; 18402 } 18403 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 18404 && !app.killedByAm) { 18405 if (app.trimMemoryLevel < curLevel && app.thread != null) { 18406 try { 18407 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18408 "Trimming memory of " + app.processName 18409 + " to " + curLevel); 18410 app.thread.scheduleTrimMemory(curLevel); 18411 } catch (RemoteException e) { 18412 } 18413 if (false) { 18414 // For now we won't do this; our memory trimming seems 18415 // to be good enough at this point that destroying 18416 // activities causes more harm than good. 18417 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 18418 && app != mHomeProcess && app != mPreviousProcess) { 18419 // Need to do this on its own message because the stack may not 18420 // be in a consistent state at this point. 18421 // For these apps we will also finish their activities 18422 // to help them free memory. 18423 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 18424 } 18425 } 18426 } 18427 app.trimMemoryLevel = curLevel; 18428 step++; 18429 if (step >= factor) { 18430 step = 0; 18431 switch (curLevel) { 18432 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 18433 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 18434 break; 18435 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 18436 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18437 break; 18438 } 18439 } 18440 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 18441 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 18442 && app.thread != null) { 18443 try { 18444 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18445 "Trimming memory of heavy-weight " + app.processName 18446 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18447 app.thread.scheduleTrimMemory( 18448 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 18449 } catch (RemoteException e) { 18450 } 18451 } 18452 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 18453 } else { 18454 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18455 || app.systemNoUi) && app.pendingUiClean) { 18456 // If this application is now in the background and it 18457 // had done UI, then give it the special trim level to 18458 // have it free UI resources. 18459 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 18460 if (app.trimMemoryLevel < level && app.thread != null) { 18461 try { 18462 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18463 "Trimming memory of bg-ui " + app.processName 18464 + " to " + level); 18465 app.thread.scheduleTrimMemory(level); 18466 } catch (RemoteException e) { 18467 } 18468 } 18469 app.pendingUiClean = false; 18470 } 18471 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 18472 try { 18473 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18474 "Trimming memory of fg " + app.processName 18475 + " to " + fgTrimLevel); 18476 app.thread.scheduleTrimMemory(fgTrimLevel); 18477 } catch (RemoteException e) { 18478 } 18479 } 18480 app.trimMemoryLevel = fgTrimLevel; 18481 } 18482 } 18483 } else { 18484 if (mLowRamStartTime != 0) { 18485 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 18486 mLowRamStartTime = 0; 18487 } 18488 for (int i=N-1; i>=0; i--) { 18489 ProcessRecord app = mLruProcesses.get(i); 18490 if (allChanged || app.procStateChanged) { 18491 setProcessTrackerStateLocked(app, trackerMemFactor, now); 18492 app.procStateChanged = false; 18493 } 18494 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 18495 || app.systemNoUi) && app.pendingUiClean) { 18496 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 18497 && app.thread != null) { 18498 try { 18499 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 18500 "Trimming memory of ui hidden " + app.processName 18501 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18502 app.thread.scheduleTrimMemory( 18503 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 18504 } catch (RemoteException e) { 18505 } 18506 } 18507 app.pendingUiClean = false; 18508 } 18509 app.trimMemoryLevel = 0; 18510 } 18511 } 18512 18513 if (mAlwaysFinishActivities) { 18514 // Need to do this on its own message because the stack may not 18515 // be in a consistent state at this point. 18516 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 18517 } 18518 18519 if (allChanged) { 18520 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 18521 } 18522 18523 if (mProcessStats.shouldWriteNowLocked(now)) { 18524 mHandler.post(new Runnable() { 18525 @Override public void run() { 18526 synchronized (ActivityManagerService.this) { 18527 mProcessStats.writeStateAsyncLocked(); 18528 } 18529 } 18530 }); 18531 } 18532 18533 if (DEBUG_OOM_ADJ) { 18534 if (false) { 18535 RuntimeException here = new RuntimeException("here"); 18536 here.fillInStackTrace(); 18537 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 18538 } else { 18539 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 18540 } 18541 } 18542 } 18543 18544 final void trimApplications() { 18545 synchronized (this) { 18546 int i; 18547 18548 // First remove any unused application processes whose package 18549 // has been removed. 18550 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18551 final ProcessRecord app = mRemovedProcesses.get(i); 18552 if (app.activities.size() == 0 18553 && app.curReceiver == null && app.services.size() == 0) { 18554 Slog.i( 18555 TAG, "Exiting empty application process " 18556 + app.processName + " (" 18557 + (app.thread != null ? app.thread.asBinder() : null) 18558 + ")\n"); 18559 if (app.pid > 0 && app.pid != MY_PID) { 18560 app.kill("empty", false); 18561 } else { 18562 try { 18563 app.thread.scheduleExit(); 18564 } catch (Exception e) { 18565 // Ignore exceptions. 18566 } 18567 } 18568 cleanUpApplicationRecordLocked(app, false, true, -1); 18569 mRemovedProcesses.remove(i); 18570 18571 if (app.persistent) { 18572 addAppLocked(app.info, false, null /* ABI override */); 18573 } 18574 } 18575 } 18576 18577 // Now update the oom adj for all processes. 18578 updateOomAdjLocked(); 18579 } 18580 } 18581 18582 /** This method sends the specified signal to each of the persistent apps */ 18583 public void signalPersistentProcesses(int sig) throws RemoteException { 18584 if (sig != Process.SIGNAL_USR1) { 18585 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18586 } 18587 18588 synchronized (this) { 18589 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18590 != PackageManager.PERMISSION_GRANTED) { 18591 throw new SecurityException("Requires permission " 18592 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18593 } 18594 18595 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18596 ProcessRecord r = mLruProcesses.get(i); 18597 if (r.thread != null && r.persistent) { 18598 Process.sendSignal(r.pid, sig); 18599 } 18600 } 18601 } 18602 } 18603 18604 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18605 if (proc == null || proc == mProfileProc) { 18606 proc = mProfileProc; 18607 profileType = mProfileType; 18608 clearProfilerLocked(); 18609 } 18610 if (proc == null) { 18611 return; 18612 } 18613 try { 18614 proc.thread.profilerControl(false, null, profileType); 18615 } catch (RemoteException e) { 18616 throw new IllegalStateException("Process disappeared"); 18617 } 18618 } 18619 18620 private void clearProfilerLocked() { 18621 if (mProfileFd != null) { 18622 try { 18623 mProfileFd.close(); 18624 } catch (IOException e) { 18625 } 18626 } 18627 mProfileApp = null; 18628 mProfileProc = null; 18629 mProfileFile = null; 18630 mProfileType = 0; 18631 mAutoStopProfiler = false; 18632 mSamplingInterval = 0; 18633 } 18634 18635 public boolean profileControl(String process, int userId, boolean start, 18636 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18637 18638 try { 18639 synchronized (this) { 18640 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18641 // its own permission. 18642 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18643 != PackageManager.PERMISSION_GRANTED) { 18644 throw new SecurityException("Requires permission " 18645 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18646 } 18647 18648 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18649 throw new IllegalArgumentException("null profile info or fd"); 18650 } 18651 18652 ProcessRecord proc = null; 18653 if (process != null) { 18654 proc = findProcessLocked(process, userId, "profileControl"); 18655 } 18656 18657 if (start && (proc == null || proc.thread == null)) { 18658 throw new IllegalArgumentException("Unknown process: " + process); 18659 } 18660 18661 if (start) { 18662 stopProfilerLocked(null, 0); 18663 setProfileApp(proc.info, proc.processName, profilerInfo); 18664 mProfileProc = proc; 18665 mProfileType = profileType; 18666 ParcelFileDescriptor fd = profilerInfo.profileFd; 18667 try { 18668 fd = fd.dup(); 18669 } catch (IOException e) { 18670 fd = null; 18671 } 18672 profilerInfo.profileFd = fd; 18673 proc.thread.profilerControl(start, profilerInfo, profileType); 18674 fd = null; 18675 mProfileFd = null; 18676 } else { 18677 stopProfilerLocked(proc, profileType); 18678 if (profilerInfo != null && profilerInfo.profileFd != null) { 18679 try { 18680 profilerInfo.profileFd.close(); 18681 } catch (IOException e) { 18682 } 18683 } 18684 } 18685 18686 return true; 18687 } 18688 } catch (RemoteException e) { 18689 throw new IllegalStateException("Process disappeared"); 18690 } finally { 18691 if (profilerInfo != null && profilerInfo.profileFd != null) { 18692 try { 18693 profilerInfo.profileFd.close(); 18694 } catch (IOException e) { 18695 } 18696 } 18697 } 18698 } 18699 18700 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18701 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18702 userId, true, ALLOW_FULL_ONLY, callName, null); 18703 ProcessRecord proc = null; 18704 try { 18705 int pid = Integer.parseInt(process); 18706 synchronized (mPidsSelfLocked) { 18707 proc = mPidsSelfLocked.get(pid); 18708 } 18709 } catch (NumberFormatException e) { 18710 } 18711 18712 if (proc == null) { 18713 ArrayMap<String, SparseArray<ProcessRecord>> all 18714 = mProcessNames.getMap(); 18715 SparseArray<ProcessRecord> procs = all.get(process); 18716 if (procs != null && procs.size() > 0) { 18717 proc = procs.valueAt(0); 18718 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18719 for (int i=1; i<procs.size(); i++) { 18720 ProcessRecord thisProc = procs.valueAt(i); 18721 if (thisProc.userId == userId) { 18722 proc = thisProc; 18723 break; 18724 } 18725 } 18726 } 18727 } 18728 } 18729 18730 return proc; 18731 } 18732 18733 public boolean dumpHeap(String process, int userId, boolean managed, 18734 String path, ParcelFileDescriptor fd) throws RemoteException { 18735 18736 try { 18737 synchronized (this) { 18738 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18739 // its own permission (same as profileControl). 18740 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18741 != PackageManager.PERMISSION_GRANTED) { 18742 throw new SecurityException("Requires permission " 18743 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18744 } 18745 18746 if (fd == null) { 18747 throw new IllegalArgumentException("null fd"); 18748 } 18749 18750 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18751 if (proc == null || proc.thread == null) { 18752 throw new IllegalArgumentException("Unknown process: " + process); 18753 } 18754 18755 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18756 if (!isDebuggable) { 18757 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18758 throw new SecurityException("Process not debuggable: " + proc); 18759 } 18760 } 18761 18762 proc.thread.dumpHeap(managed, path, fd); 18763 fd = null; 18764 return true; 18765 } 18766 } catch (RemoteException e) { 18767 throw new IllegalStateException("Process disappeared"); 18768 } finally { 18769 if (fd != null) { 18770 try { 18771 fd.close(); 18772 } catch (IOException e) { 18773 } 18774 } 18775 } 18776 } 18777 18778 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18779 public void monitor() { 18780 synchronized (this) { } 18781 } 18782 18783 void onCoreSettingsChange(Bundle settings) { 18784 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18785 ProcessRecord processRecord = mLruProcesses.get(i); 18786 try { 18787 if (processRecord.thread != null) { 18788 processRecord.thread.setCoreSettings(settings); 18789 } 18790 } catch (RemoteException re) { 18791 /* ignore */ 18792 } 18793 } 18794 } 18795 18796 // Multi-user methods 18797 18798 /** 18799 * Start user, if its not already running, but don't bring it to foreground. 18800 */ 18801 @Override 18802 public boolean startUserInBackground(final int userId) { 18803 return startUser(userId, /* foreground */ false); 18804 } 18805 18806 /** 18807 * Start user, if its not already running, and bring it to foreground. 18808 */ 18809 boolean startUserInForeground(final int userId, Dialog dlg) { 18810 boolean result = startUser(userId, /* foreground */ true); 18811 dlg.dismiss(); 18812 return result; 18813 } 18814 18815 /** 18816 * Refreshes the list of users related to the current user when either a 18817 * user switch happens or when a new related user is started in the 18818 * background. 18819 */ 18820 private void updateCurrentProfileIdsLocked() { 18821 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18822 mCurrentUserId, false /* enabledOnly */); 18823 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18824 for (int i = 0; i < currentProfileIds.length; i++) { 18825 currentProfileIds[i] = profiles.get(i).id; 18826 } 18827 mCurrentProfileIds = currentProfileIds; 18828 18829 synchronized (mUserProfileGroupIdsSelfLocked) { 18830 mUserProfileGroupIdsSelfLocked.clear(); 18831 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18832 for (int i = 0; i < users.size(); i++) { 18833 UserInfo user = users.get(i); 18834 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18835 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18836 } 18837 } 18838 } 18839 } 18840 18841 private Set getProfileIdsLocked(int userId) { 18842 Set userIds = new HashSet<Integer>(); 18843 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18844 userId, false /* enabledOnly */); 18845 for (UserInfo user : profiles) { 18846 userIds.add(Integer.valueOf(user.id)); 18847 } 18848 return userIds; 18849 } 18850 18851 @Override 18852 public boolean switchUser(final int userId) { 18853 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18854 String userName; 18855 synchronized (this) { 18856 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18857 if (userInfo == null) { 18858 Slog.w(TAG, "No user info for user #" + userId); 18859 return false; 18860 } 18861 if (userInfo.isManagedProfile()) { 18862 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18863 return false; 18864 } 18865 userName = userInfo.name; 18866 mTargetUserId = userId; 18867 } 18868 mHandler.removeMessages(START_USER_SWITCH_MSG); 18869 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18870 return true; 18871 } 18872 18873 private void showUserSwitchDialog(int userId, String userName) { 18874 // The dialog will show and then initiate the user switch by calling startUserInForeground 18875 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18876 true /* above system */); 18877 d.show(); 18878 } 18879 18880 private boolean startUser(final int userId, final boolean foreground) { 18881 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18882 != PackageManager.PERMISSION_GRANTED) { 18883 String msg = "Permission Denial: switchUser() from pid=" 18884 + Binder.getCallingPid() 18885 + ", uid=" + Binder.getCallingUid() 18886 + " requires " + INTERACT_ACROSS_USERS_FULL; 18887 Slog.w(TAG, msg); 18888 throw new SecurityException(msg); 18889 } 18890 18891 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18892 18893 final long ident = Binder.clearCallingIdentity(); 18894 try { 18895 synchronized (this) { 18896 final int oldUserId = mCurrentUserId; 18897 if (oldUserId == userId) { 18898 return true; 18899 } 18900 18901 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser"); 18902 18903 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18904 if (userInfo == null) { 18905 Slog.w(TAG, "No user info for user #" + userId); 18906 return false; 18907 } 18908 if (foreground && userInfo.isManagedProfile()) { 18909 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18910 return false; 18911 } 18912 18913 if (foreground) { 18914 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18915 R.anim.screen_user_enter); 18916 } 18917 18918 boolean needStart = false; 18919 18920 // If the user we are switching to is not currently started, then 18921 // we need to start it now. 18922 if (mStartedUsers.get(userId) == null) { 18923 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18924 updateStartedUserArrayLocked(); 18925 needStart = true; 18926 } 18927 18928 final Integer userIdInt = Integer.valueOf(userId); 18929 mUserLru.remove(userIdInt); 18930 mUserLru.add(userIdInt); 18931 18932 if (foreground) { 18933 mCurrentUserId = userId; 18934 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18935 updateCurrentProfileIdsLocked(); 18936 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18937 // Once the internal notion of the active user has switched, we lock the device 18938 // with the option to show the user switcher on the keyguard. 18939 mWindowManager.lockNow(null); 18940 } else { 18941 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18942 updateCurrentProfileIdsLocked(); 18943 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18944 mUserLru.remove(currentUserIdInt); 18945 mUserLru.add(currentUserIdInt); 18946 } 18947 18948 final UserStartedState uss = mStartedUsers.get(userId); 18949 18950 // Make sure user is in the started state. If it is currently 18951 // stopping, we need to knock that off. 18952 if (uss.mState == UserStartedState.STATE_STOPPING) { 18953 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18954 // so we can just fairly silently bring the user back from 18955 // the almost-dead. 18956 uss.mState = UserStartedState.STATE_RUNNING; 18957 updateStartedUserArrayLocked(); 18958 needStart = true; 18959 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18960 // This means ACTION_SHUTDOWN has been sent, so we will 18961 // need to treat this as a new boot of the user. 18962 uss.mState = UserStartedState.STATE_BOOTING; 18963 updateStartedUserArrayLocked(); 18964 needStart = true; 18965 } 18966 18967 if (uss.mState == UserStartedState.STATE_BOOTING) { 18968 // Booting up a new user, need to tell system services about it. 18969 // Note that this is on the same handler as scheduling of broadcasts, 18970 // which is important because it needs to go first. 18971 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18972 } 18973 18974 if (foreground) { 18975 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18976 oldUserId)); 18977 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18978 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18979 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18980 oldUserId, userId, uss)); 18981 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18982 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18983 } 18984 18985 if (needStart) { 18986 // Send USER_STARTED broadcast 18987 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18988 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18989 | Intent.FLAG_RECEIVER_FOREGROUND); 18990 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18991 broadcastIntentLocked(null, null, intent, 18992 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18993 false, false, MY_PID, Process.SYSTEM_UID, userId); 18994 } 18995 18996 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18997 if (userId != UserHandle.USER_OWNER) { 18998 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18999 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 19000 broadcastIntentLocked(null, null, intent, null, 19001 new IIntentReceiver.Stub() { 19002 public void performReceive(Intent intent, int resultCode, 19003 String data, Bundle extras, boolean ordered, 19004 boolean sticky, int sendingUser) { 19005 onUserInitialized(uss, foreground, oldUserId, userId); 19006 } 19007 }, 0, null, null, null, AppOpsManager.OP_NONE, 19008 true, false, MY_PID, Process.SYSTEM_UID, 19009 userId); 19010 uss.initializing = true; 19011 } else { 19012 getUserManagerLocked().makeInitialized(userInfo.id); 19013 } 19014 } 19015 19016 if (foreground) { 19017 if (!uss.initializing) { 19018 moveUserToForeground(uss, oldUserId, userId); 19019 } 19020 } else { 19021 mStackSupervisor.startBackgroundUserLocked(userId, uss); 19022 } 19023 19024 if (needStart) { 19025 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 19026 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19027 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19028 broadcastIntentLocked(null, null, intent, 19029 null, new IIntentReceiver.Stub() { 19030 @Override 19031 public void performReceive(Intent intent, int resultCode, String data, 19032 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 19033 throws RemoteException { 19034 } 19035 }, 0, null, null, 19036 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19037 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19038 } 19039 } 19040 } finally { 19041 Binder.restoreCallingIdentity(ident); 19042 } 19043 19044 return true; 19045 } 19046 19047 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 19048 long ident = Binder.clearCallingIdentity(); 19049 try { 19050 Intent intent; 19051 if (oldUserId >= 0) { 19052 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 19053 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 19054 int count = profiles.size(); 19055 for (int i = 0; i < count; i++) { 19056 int profileUserId = profiles.get(i).id; 19057 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 19058 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19059 | Intent.FLAG_RECEIVER_FOREGROUND); 19060 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19061 broadcastIntentLocked(null, null, intent, 19062 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19063 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19064 } 19065 } 19066 if (newUserId >= 0) { 19067 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 19068 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 19069 int count = profiles.size(); 19070 for (int i = 0; i < count; i++) { 19071 int profileUserId = profiles.get(i).id; 19072 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 19073 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19074 | Intent.FLAG_RECEIVER_FOREGROUND); 19075 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 19076 broadcastIntentLocked(null, null, intent, 19077 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 19078 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 19079 } 19080 intent = new Intent(Intent.ACTION_USER_SWITCHED); 19081 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 19082 | Intent.FLAG_RECEIVER_FOREGROUND); 19083 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 19084 broadcastIntentLocked(null, null, intent, 19085 null, null, 0, null, null, 19086 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 19087 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19088 } 19089 } finally { 19090 Binder.restoreCallingIdentity(ident); 19091 } 19092 } 19093 19094 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 19095 final int newUserId) { 19096 final int N = mUserSwitchObservers.beginBroadcast(); 19097 if (N > 0) { 19098 final IRemoteCallback callback = new IRemoteCallback.Stub() { 19099 int mCount = 0; 19100 @Override 19101 public void sendResult(Bundle data) throws RemoteException { 19102 synchronized (ActivityManagerService.this) { 19103 if (mCurUserSwitchCallback == this) { 19104 mCount++; 19105 if (mCount == N) { 19106 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19107 } 19108 } 19109 } 19110 } 19111 }; 19112 synchronized (this) { 19113 uss.switching = true; 19114 mCurUserSwitchCallback = callback; 19115 } 19116 for (int i=0; i<N; i++) { 19117 try { 19118 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 19119 newUserId, callback); 19120 } catch (RemoteException e) { 19121 } 19122 } 19123 } else { 19124 synchronized (this) { 19125 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19126 } 19127 } 19128 mUserSwitchObservers.finishBroadcast(); 19129 } 19130 19131 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19132 synchronized (this) { 19133 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 19134 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 19135 } 19136 } 19137 19138 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 19139 mCurUserSwitchCallback = null; 19140 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 19141 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 19142 oldUserId, newUserId, uss)); 19143 } 19144 19145 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 19146 synchronized (this) { 19147 if (foreground) { 19148 moveUserToForeground(uss, oldUserId, newUserId); 19149 } 19150 } 19151 19152 completeSwitchAndInitalize(uss, newUserId, true, false); 19153 } 19154 19155 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 19156 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 19157 if (homeInFront) { 19158 startHomeActivityLocked(newUserId, "moveUserToFroreground"); 19159 } else { 19160 mStackSupervisor.resumeTopActivitiesLocked(); 19161 } 19162 EventLogTags.writeAmSwitchUser(newUserId); 19163 getUserManagerLocked().userForeground(newUserId); 19164 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 19165 } 19166 19167 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 19168 completeSwitchAndInitalize(uss, newUserId, false, true); 19169 } 19170 19171 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 19172 boolean clearInitializing, boolean clearSwitching) { 19173 boolean unfrozen = false; 19174 synchronized (this) { 19175 if (clearInitializing) { 19176 uss.initializing = false; 19177 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 19178 } 19179 if (clearSwitching) { 19180 uss.switching = false; 19181 } 19182 if (!uss.switching && !uss.initializing) { 19183 mWindowManager.stopFreezingScreen(); 19184 unfrozen = true; 19185 } 19186 } 19187 if (unfrozen) { 19188 final int N = mUserSwitchObservers.beginBroadcast(); 19189 for (int i=0; i<N; i++) { 19190 try { 19191 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 19192 } catch (RemoteException e) { 19193 } 19194 } 19195 mUserSwitchObservers.finishBroadcast(); 19196 } 19197 stopGuestUserIfBackground(); 19198 } 19199 19200 /** 19201 * Stops the guest user if it has gone to the background. 19202 */ 19203 private void stopGuestUserIfBackground() { 19204 synchronized (this) { 19205 final int num = mUserLru.size(); 19206 for (int i = 0; i < num; i++) { 19207 Integer oldUserId = mUserLru.get(i); 19208 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19209 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId 19210 || oldUss.mState == UserStartedState.STATE_STOPPING 19211 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19212 continue; 19213 } 19214 UserInfo userInfo = mUserManager.getUserInfo(oldUserId); 19215 if (userInfo.isGuest()) { 19216 // This is a user to be stopped. 19217 stopUserLocked(oldUserId, null); 19218 break; 19219 } 19220 } 19221 } 19222 } 19223 19224 void scheduleStartProfilesLocked() { 19225 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 19226 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 19227 DateUtils.SECOND_IN_MILLIS); 19228 } 19229 } 19230 19231 void startProfilesLocked() { 19232 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 19233 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 19234 mCurrentUserId, false /* enabledOnly */); 19235 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 19236 for (UserInfo user : profiles) { 19237 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 19238 && user.id != mCurrentUserId) { 19239 toStart.add(user); 19240 } 19241 } 19242 final int n = toStart.size(); 19243 int i = 0; 19244 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 19245 startUserInBackground(toStart.get(i).id); 19246 } 19247 if (i < n) { 19248 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 19249 } 19250 } 19251 19252 void finishUserBoot(UserStartedState uss) { 19253 synchronized (this) { 19254 if (uss.mState == UserStartedState.STATE_BOOTING 19255 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 19256 uss.mState = UserStartedState.STATE_RUNNING; 19257 final int userId = uss.mHandle.getIdentifier(); 19258 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 19259 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19260 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 19261 broadcastIntentLocked(null, null, intent, 19262 null, null, 0, null, null, 19263 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 19264 true, false, MY_PID, Process.SYSTEM_UID, userId); 19265 } 19266 } 19267 } 19268 19269 void finishUserSwitch(UserStartedState uss) { 19270 synchronized (this) { 19271 finishUserBoot(uss); 19272 19273 startProfilesLocked(); 19274 19275 int num = mUserLru.size(); 19276 int i = 0; 19277 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 19278 Integer oldUserId = mUserLru.get(i); 19279 UserStartedState oldUss = mStartedUsers.get(oldUserId); 19280 if (oldUss == null) { 19281 // Shouldn't happen, but be sane if it does. 19282 mUserLru.remove(i); 19283 num--; 19284 continue; 19285 } 19286 if (oldUss.mState == UserStartedState.STATE_STOPPING 19287 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 19288 // This user is already stopping, doesn't count. 19289 num--; 19290 i++; 19291 continue; 19292 } 19293 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 19294 // Owner and current can't be stopped, but count as running. 19295 i++; 19296 continue; 19297 } 19298 // This is a user to be stopped. 19299 stopUserLocked(oldUserId, null); 19300 num--; 19301 i++; 19302 } 19303 } 19304 } 19305 19306 @Override 19307 public int stopUser(final int userId, final IStopUserCallback callback) { 19308 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19309 != PackageManager.PERMISSION_GRANTED) { 19310 String msg = "Permission Denial: switchUser() from pid=" 19311 + Binder.getCallingPid() 19312 + ", uid=" + Binder.getCallingUid() 19313 + " requires " + INTERACT_ACROSS_USERS_FULL; 19314 Slog.w(TAG, msg); 19315 throw new SecurityException(msg); 19316 } 19317 if (userId <= 0) { 19318 throw new IllegalArgumentException("Can't stop primary user " + userId); 19319 } 19320 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 19321 synchronized (this) { 19322 return stopUserLocked(userId, callback); 19323 } 19324 } 19325 19326 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 19327 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 19328 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 19329 return ActivityManager.USER_OP_IS_CURRENT; 19330 } 19331 19332 final UserStartedState uss = mStartedUsers.get(userId); 19333 if (uss == null) { 19334 // User is not started, nothing to do... but we do need to 19335 // callback if requested. 19336 if (callback != null) { 19337 mHandler.post(new Runnable() { 19338 @Override 19339 public void run() { 19340 try { 19341 callback.userStopped(userId); 19342 } catch (RemoteException e) { 19343 } 19344 } 19345 }); 19346 } 19347 return ActivityManager.USER_OP_SUCCESS; 19348 } 19349 19350 if (callback != null) { 19351 uss.mStopCallbacks.add(callback); 19352 } 19353 19354 if (uss.mState != UserStartedState.STATE_STOPPING 19355 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19356 uss.mState = UserStartedState.STATE_STOPPING; 19357 updateStartedUserArrayLocked(); 19358 19359 long ident = Binder.clearCallingIdentity(); 19360 try { 19361 // We are going to broadcast ACTION_USER_STOPPING and then 19362 // once that is done send a final ACTION_SHUTDOWN and then 19363 // stop the user. 19364 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 19365 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19366 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 19367 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 19368 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 19369 // This is the result receiver for the final shutdown broadcast. 19370 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 19371 @Override 19372 public void performReceive(Intent intent, int resultCode, String data, 19373 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19374 finishUserStop(uss); 19375 } 19376 }; 19377 // This is the result receiver for the initial stopping broadcast. 19378 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 19379 @Override 19380 public void performReceive(Intent intent, int resultCode, String data, 19381 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 19382 // On to the next. 19383 synchronized (ActivityManagerService.this) { 19384 if (uss.mState != UserStartedState.STATE_STOPPING) { 19385 // Whoops, we are being started back up. Abort, abort! 19386 return; 19387 } 19388 uss.mState = UserStartedState.STATE_SHUTDOWN; 19389 } 19390 mBatteryStatsService.noteEvent( 19391 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 19392 Integer.toString(userId), userId); 19393 mSystemServiceManager.stopUser(userId); 19394 broadcastIntentLocked(null, null, shutdownIntent, 19395 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 19396 true, false, MY_PID, Process.SYSTEM_UID, userId); 19397 } 19398 }; 19399 // Kick things off. 19400 broadcastIntentLocked(null, null, stoppingIntent, 19401 null, stoppingReceiver, 0, null, null, 19402 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 19403 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 19404 } finally { 19405 Binder.restoreCallingIdentity(ident); 19406 } 19407 } 19408 19409 return ActivityManager.USER_OP_SUCCESS; 19410 } 19411 19412 void finishUserStop(UserStartedState uss) { 19413 final int userId = uss.mHandle.getIdentifier(); 19414 boolean stopped; 19415 ArrayList<IStopUserCallback> callbacks; 19416 synchronized (this) { 19417 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 19418 if (mStartedUsers.get(userId) != uss) { 19419 stopped = false; 19420 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 19421 stopped = false; 19422 } else { 19423 stopped = true; 19424 // User can no longer run. 19425 mStartedUsers.remove(userId); 19426 mUserLru.remove(Integer.valueOf(userId)); 19427 updateStartedUserArrayLocked(); 19428 19429 // Clean up all state and processes associated with the user. 19430 // Kill all the processes for the user. 19431 forceStopUserLocked(userId, "finish user"); 19432 } 19433 19434 // Explicitly remove the old information in mRecentTasks. 19435 removeRecentTasksForUserLocked(userId); 19436 } 19437 19438 for (int i=0; i<callbacks.size(); i++) { 19439 try { 19440 if (stopped) callbacks.get(i).userStopped(userId); 19441 else callbacks.get(i).userStopAborted(userId); 19442 } catch (RemoteException e) { 19443 } 19444 } 19445 19446 if (stopped) { 19447 mSystemServiceManager.cleanupUser(userId); 19448 synchronized (this) { 19449 mStackSupervisor.removeUserLocked(userId); 19450 } 19451 } 19452 } 19453 19454 @Override 19455 public UserInfo getCurrentUser() { 19456 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 19457 != PackageManager.PERMISSION_GRANTED) && ( 19458 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19459 != PackageManager.PERMISSION_GRANTED)) { 19460 String msg = "Permission Denial: getCurrentUser() from pid=" 19461 + Binder.getCallingPid() 19462 + ", uid=" + Binder.getCallingUid() 19463 + " requires " + INTERACT_ACROSS_USERS; 19464 Slog.w(TAG, msg); 19465 throw new SecurityException(msg); 19466 } 19467 synchronized (this) { 19468 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19469 return getUserManagerLocked().getUserInfo(userId); 19470 } 19471 } 19472 19473 int getCurrentUserIdLocked() { 19474 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 19475 } 19476 19477 @Override 19478 public boolean isUserRunning(int userId, boolean orStopped) { 19479 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19480 != PackageManager.PERMISSION_GRANTED) { 19481 String msg = "Permission Denial: isUserRunning() from pid=" 19482 + Binder.getCallingPid() 19483 + ", uid=" + Binder.getCallingUid() 19484 + " requires " + INTERACT_ACROSS_USERS; 19485 Slog.w(TAG, msg); 19486 throw new SecurityException(msg); 19487 } 19488 synchronized (this) { 19489 return isUserRunningLocked(userId, orStopped); 19490 } 19491 } 19492 19493 boolean isUserRunningLocked(int userId, boolean orStopped) { 19494 UserStartedState state = mStartedUsers.get(userId); 19495 if (state == null) { 19496 return false; 19497 } 19498 if (orStopped) { 19499 return true; 19500 } 19501 return state.mState != UserStartedState.STATE_STOPPING 19502 && state.mState != UserStartedState.STATE_SHUTDOWN; 19503 } 19504 19505 @Override 19506 public int[] getRunningUserIds() { 19507 if (checkCallingPermission(INTERACT_ACROSS_USERS) 19508 != PackageManager.PERMISSION_GRANTED) { 19509 String msg = "Permission Denial: isUserRunning() from pid=" 19510 + Binder.getCallingPid() 19511 + ", uid=" + Binder.getCallingUid() 19512 + " requires " + INTERACT_ACROSS_USERS; 19513 Slog.w(TAG, msg); 19514 throw new SecurityException(msg); 19515 } 19516 synchronized (this) { 19517 return mStartedUserArray; 19518 } 19519 } 19520 19521 private void updateStartedUserArrayLocked() { 19522 int num = 0; 19523 for (int i=0; i<mStartedUsers.size(); i++) { 19524 UserStartedState uss = mStartedUsers.valueAt(i); 19525 // This list does not include stopping users. 19526 if (uss.mState != UserStartedState.STATE_STOPPING 19527 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19528 num++; 19529 } 19530 } 19531 mStartedUserArray = new int[num]; 19532 num = 0; 19533 for (int i=0; i<mStartedUsers.size(); i++) { 19534 UserStartedState uss = mStartedUsers.valueAt(i); 19535 if (uss.mState != UserStartedState.STATE_STOPPING 19536 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 19537 mStartedUserArray[num] = mStartedUsers.keyAt(i); 19538 num++; 19539 } 19540 } 19541 } 19542 19543 @Override 19544 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 19545 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 19546 != PackageManager.PERMISSION_GRANTED) { 19547 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 19548 + Binder.getCallingPid() 19549 + ", uid=" + Binder.getCallingUid() 19550 + " requires " + INTERACT_ACROSS_USERS_FULL; 19551 Slog.w(TAG, msg); 19552 throw new SecurityException(msg); 19553 } 19554 19555 mUserSwitchObservers.register(observer); 19556 } 19557 19558 @Override 19559 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 19560 mUserSwitchObservers.unregister(observer); 19561 } 19562 19563 private boolean userExists(int userId) { 19564 if (userId == 0) { 19565 return true; 19566 } 19567 UserManagerService ums = getUserManagerLocked(); 19568 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19569 } 19570 19571 int[] getUsersLocked() { 19572 UserManagerService ums = getUserManagerLocked(); 19573 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19574 } 19575 19576 UserManagerService getUserManagerLocked() { 19577 if (mUserManager == null) { 19578 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19579 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19580 } 19581 return mUserManager; 19582 } 19583 19584 private int applyUserId(int uid, int userId) { 19585 return UserHandle.getUid(userId, uid); 19586 } 19587 19588 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19589 if (info == null) return null; 19590 ApplicationInfo newInfo = new ApplicationInfo(info); 19591 newInfo.uid = applyUserId(info.uid, userId); 19592 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19593 + info.packageName; 19594 return newInfo; 19595 } 19596 19597 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19598 if (aInfo == null 19599 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19600 return aInfo; 19601 } 19602 19603 ActivityInfo info = new ActivityInfo(aInfo); 19604 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19605 return info; 19606 } 19607 19608 private final class LocalService extends ActivityManagerInternal { 19609 @Override 19610 public void onWakefulnessChanged(int wakefulness) { 19611 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 19612 } 19613 19614 @Override 19615 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19616 String processName, String abiOverride, int uid, Runnable crashHandler) { 19617 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19618 processName, abiOverride, uid, crashHandler); 19619 } 19620 } 19621 19622 /** 19623 * An implementation of IAppTask, that allows an app to manage its own tasks via 19624 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19625 * only the process that calls getAppTasks() can call the AppTask methods. 19626 */ 19627 class AppTaskImpl extends IAppTask.Stub { 19628 private int mTaskId; 19629 private int mCallingUid; 19630 19631 public AppTaskImpl(int taskId, int callingUid) { 19632 mTaskId = taskId; 19633 mCallingUid = callingUid; 19634 } 19635 19636 private void checkCaller() { 19637 if (mCallingUid != Binder.getCallingUid()) { 19638 throw new SecurityException("Caller " + mCallingUid 19639 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19640 } 19641 } 19642 19643 @Override 19644 public void finishAndRemoveTask() { 19645 checkCaller(); 19646 19647 synchronized (ActivityManagerService.this) { 19648 long origId = Binder.clearCallingIdentity(); 19649 try { 19650 if (!removeTaskByIdLocked(mTaskId, false)) { 19651 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19652 } 19653 } finally { 19654 Binder.restoreCallingIdentity(origId); 19655 } 19656 } 19657 } 19658 19659 @Override 19660 public ActivityManager.RecentTaskInfo getTaskInfo() { 19661 checkCaller(); 19662 19663 synchronized (ActivityManagerService.this) { 19664 long origId = Binder.clearCallingIdentity(); 19665 try { 19666 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19667 if (tr == null) { 19668 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19669 } 19670 return createRecentTaskInfoFromTaskRecord(tr); 19671 } finally { 19672 Binder.restoreCallingIdentity(origId); 19673 } 19674 } 19675 } 19676 19677 @Override 19678 public void moveToFront() { 19679 checkCaller(); 19680 // Will bring task to front if it already has a root activity. 19681 startActivityFromRecentsInner(mTaskId, null); 19682 } 19683 19684 @Override 19685 public int startActivity(IBinder whoThread, String callingPackage, 19686 Intent intent, String resolvedType, Bundle options) { 19687 checkCaller(); 19688 19689 int callingUser = UserHandle.getCallingUserId(); 19690 TaskRecord tr; 19691 IApplicationThread appThread; 19692 synchronized (ActivityManagerService.this) { 19693 tr = recentTaskForIdLocked(mTaskId); 19694 if (tr == null) { 19695 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19696 } 19697 appThread = ApplicationThreadNative.asInterface(whoThread); 19698 if (appThread == null) { 19699 throw new IllegalArgumentException("Bad app thread " + appThread); 19700 } 19701 } 19702 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19703 resolvedType, null, null, null, null, 0, 0, null, null, 19704 null, options, callingUser, null, tr); 19705 } 19706 19707 @Override 19708 public void setExcludeFromRecents(boolean exclude) { 19709 checkCaller(); 19710 19711 synchronized (ActivityManagerService.this) { 19712 long origId = Binder.clearCallingIdentity(); 19713 try { 19714 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19715 if (tr == null) { 19716 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19717 } 19718 Intent intent = tr.getBaseIntent(); 19719 if (exclude) { 19720 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19721 } else { 19722 intent.setFlags(intent.getFlags() 19723 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19724 } 19725 } finally { 19726 Binder.restoreCallingIdentity(origId); 19727 } 19728 } 19729 } 19730 } 19731 } 19732