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 34 import android.Manifest; 35 import android.app.AppOpsManager; 36 import android.app.ApplicationThreadNative; 37 import android.app.IActivityContainer; 38 import android.app.IActivityContainerCallback; 39 import android.app.IAppTask; 40 import android.app.ProfilerInfo; 41 import android.app.admin.DevicePolicyManager; 42 import android.app.usage.UsageEvents; 43 import android.app.usage.UsageStatsManagerInternal; 44 import android.appwidget.AppWidgetManager; 45 import android.content.res.Resources; 46 import android.graphics.Bitmap; 47 import android.graphics.Point; 48 import android.graphics.Rect; 49 import android.os.BatteryStats; 50 import android.os.PersistableBundle; 51 import android.os.storage.IMountService; 52 import android.os.storage.StorageManager; 53 import android.service.voice.IVoiceInteractionSession; 54 import android.util.ArrayMap; 55 import android.util.ArraySet; 56 import android.util.SparseIntArray; 57 58 import com.android.internal.R; 59 import com.android.internal.annotations.GuardedBy; 60 import com.android.internal.app.IAppOpsService; 61 import com.android.internal.app.IVoiceInteractor; 62 import com.android.internal.app.ProcessMap; 63 import com.android.internal.app.ProcessStats; 64 import com.android.internal.content.PackageMonitor; 65 import com.android.internal.os.BackgroundThread; 66 import com.android.internal.os.BatteryStatsImpl; 67 import com.android.internal.os.ProcessCpuTracker; 68 import com.android.internal.os.TransferPipe; 69 import com.android.internal.os.Zygote; 70 import com.android.internal.util.FastPrintWriter; 71 import com.android.internal.util.FastXmlSerializer; 72 import com.android.internal.util.MemInfoReader; 73 import com.android.internal.util.Preconditions; 74 import com.android.server.AppOpsService; 75 import com.android.server.AttributeCache; 76 import com.android.server.IntentResolver; 77 import com.android.server.LocalServices; 78 import com.android.server.ServiceThread; 79 import com.android.server.SystemService; 80 import com.android.server.SystemServiceManager; 81 import com.android.server.Watchdog; 82 import com.android.server.am.ActivityStack.ActivityState; 83 import com.android.server.firewall.IntentFirewall; 84 import com.android.server.pm.UserManagerService; 85 import com.android.server.wm.AppTransition; 86 import com.android.server.wm.WindowManagerService; 87 import com.google.android.collect.Lists; 88 import com.google.android.collect.Maps; 89 90 import libcore.io.IoUtils; 91 92 import org.xmlpull.v1.XmlPullParser; 93 import org.xmlpull.v1.XmlPullParserException; 94 import org.xmlpull.v1.XmlSerializer; 95 96 import android.app.Activity; 97 import android.app.ActivityManager; 98 import android.app.ActivityManager.RunningTaskInfo; 99 import android.app.ActivityManager.StackInfo; 100 import android.app.ActivityManagerInternal; 101 import android.app.ActivityManagerNative; 102 import android.app.ActivityOptions; 103 import android.app.ActivityThread; 104 import android.app.AlertDialog; 105 import android.app.AppGlobals; 106 import android.app.ApplicationErrorReport; 107 import android.app.Dialog; 108 import android.app.IActivityController; 109 import android.app.IApplicationThread; 110 import android.app.IInstrumentationWatcher; 111 import android.app.INotificationManager; 112 import android.app.IProcessObserver; 113 import android.app.IServiceConnection; 114 import android.app.IStopUserCallback; 115 import android.app.IUiAutomationConnection; 116 import android.app.IUserSwitchObserver; 117 import android.app.Instrumentation; 118 import android.app.Notification; 119 import android.app.NotificationManager; 120 import android.app.PendingIntent; 121 import android.app.backup.IBackupManager; 122 import android.content.ActivityNotFoundException; 123 import android.content.BroadcastReceiver; 124 import android.content.ClipData; 125 import android.content.ComponentCallbacks2; 126 import android.content.ComponentName; 127 import android.content.ContentProvider; 128 import android.content.ContentResolver; 129 import android.content.Context; 130 import android.content.DialogInterface; 131 import android.content.IContentProvider; 132 import android.content.IIntentReceiver; 133 import android.content.IIntentSender; 134 import android.content.Intent; 135 import android.content.IntentFilter; 136 import android.content.IntentSender; 137 import android.content.pm.ActivityInfo; 138 import android.content.pm.ApplicationInfo; 139 import android.content.pm.ConfigurationInfo; 140 import android.content.pm.IPackageDataObserver; 141 import android.content.pm.IPackageManager; 142 import android.content.pm.InstrumentationInfo; 143 import android.content.pm.PackageInfo; 144 import android.content.pm.PackageManager; 145 import android.content.pm.ParceledListSlice; 146 import android.content.pm.UserInfo; 147 import android.content.pm.PackageManager.NameNotFoundException; 148 import android.content.pm.PathPermission; 149 import android.content.pm.ProviderInfo; 150 import android.content.pm.ResolveInfo; 151 import android.content.pm.ServiceInfo; 152 import android.content.res.CompatibilityInfo; 153 import android.content.res.Configuration; 154 import android.net.Proxy; 155 import android.net.ProxyInfo; 156 import android.net.Uri; 157 import android.os.Binder; 158 import android.os.Build; 159 import android.os.Bundle; 160 import android.os.Debug; 161 import android.os.DropBoxManager; 162 import android.os.Environment; 163 import android.os.FactoryTest; 164 import android.os.FileObserver; 165 import android.os.FileUtils; 166 import android.os.Handler; 167 import android.os.IBinder; 168 import android.os.IPermissionController; 169 import android.os.IRemoteCallback; 170 import android.os.IUserManager; 171 import android.os.Looper; 172 import android.os.Message; 173 import android.os.Parcel; 174 import android.os.ParcelFileDescriptor; 175 import android.os.Process; 176 import android.os.RemoteCallbackList; 177 import android.os.RemoteException; 178 import android.os.SELinux; 179 import android.os.ServiceManager; 180 import android.os.StrictMode; 181 import android.os.SystemClock; 182 import android.os.SystemProperties; 183 import android.os.UpdateLock; 184 import android.os.UserHandle; 185 import android.os.UserManager; 186 import android.provider.Settings; 187 import android.text.format.DateUtils; 188 import android.text.format.Time; 189 import android.util.AtomicFile; 190 import android.util.EventLog; 191 import android.util.Log; 192 import android.util.Pair; 193 import android.util.PrintWriterPrinter; 194 import android.util.Slog; 195 import android.util.SparseArray; 196 import android.util.TimeUtils; 197 import android.util.Xml; 198 import android.view.Gravity; 199 import android.view.LayoutInflater; 200 import android.view.View; 201 import android.view.WindowManager; 202 import dalvik.system.VMRuntime; 203 204 import java.io.BufferedInputStream; 205 import java.io.BufferedOutputStream; 206 import java.io.DataInputStream; 207 import java.io.DataOutputStream; 208 import java.io.File; 209 import java.io.FileDescriptor; 210 import java.io.FileInputStream; 211 import java.io.FileNotFoundException; 212 import java.io.FileOutputStream; 213 import java.io.IOException; 214 import java.io.InputStreamReader; 215 import java.io.PrintWriter; 216 import java.io.StringWriter; 217 import java.lang.ref.WeakReference; 218 import java.util.ArrayList; 219 import java.util.Arrays; 220 import java.util.Collections; 221 import java.util.Comparator; 222 import java.util.HashMap; 223 import java.util.HashSet; 224 import java.util.Iterator; 225 import java.util.List; 226 import java.util.Locale; 227 import java.util.Map; 228 import java.util.Set; 229 import java.util.concurrent.atomic.AtomicBoolean; 230 import java.util.concurrent.atomic.AtomicLong; 231 232 public final class ActivityManagerService extends ActivityManagerNative 233 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 234 235 private static final String USER_DATA_DIR = "/data/user/"; 236 // File that stores last updated system version and called preboot receivers 237 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 238 239 static final String TAG = "ActivityManager"; 240 static final String TAG_MU = "ActivityManagerServiceMU"; 241 static final boolean DEBUG = false; 242 static final boolean localLOGV = DEBUG; 243 static final boolean DEBUG_BACKUP = localLOGV || false; 244 static final boolean DEBUG_BROADCAST = localLOGV || false; 245 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 246 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 247 static final boolean DEBUG_CLEANUP = localLOGV || false; 248 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 249 static final boolean DEBUG_FOCUS = false; 250 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 251 static final boolean DEBUG_MU = localLOGV || false; 252 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 253 static final boolean DEBUG_LRU = localLOGV || false; 254 static final boolean DEBUG_PAUSE = localLOGV || false; 255 static final boolean DEBUG_POWER = localLOGV || false; 256 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 257 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 258 static final boolean DEBUG_PROCESSES = localLOGV || false; 259 static final boolean DEBUG_PROVIDER = localLOGV || false; 260 static final boolean DEBUG_RESULTS = localLOGV || false; 261 static final boolean DEBUG_SERVICE = localLOGV || false; 262 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 263 static final boolean DEBUG_STACK = localLOGV || false; 264 static final boolean DEBUG_SWITCH = localLOGV || false; 265 static final boolean DEBUG_TASKS = localLOGV || false; 266 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 267 static final boolean DEBUG_TRANSITION = localLOGV || false; 268 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 269 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 270 static final boolean DEBUG_VISBILITY = localLOGV || false; 271 static final boolean DEBUG_PSS = localLOGV || false; 272 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 273 static final boolean DEBUG_RECENTS = localLOGV || false; 274 static final boolean VALIDATE_TOKENS = false; 275 static final boolean SHOW_ACTIVITY_START_TIME = true; 276 277 // Control over CPU and battery monitoring. 278 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 279 static final boolean MONITOR_CPU_USAGE = true; 280 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 281 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 282 static final boolean MONITOR_THREAD_CPU_USAGE = false; 283 284 // The flags that are set for all calls we make to the package manager. 285 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 286 287 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 288 289 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 290 291 // Maximum number recent bitmaps to keep in memory. 292 static final int MAX_RECENT_BITMAPS = 5; 293 294 // Amount of time after a call to stopAppSwitches() during which we will 295 // prevent further untrusted switches from happening. 296 static final long APP_SWITCH_DELAY_TIME = 5*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real. 300 static final int PROC_START_TIMEOUT = 10*1000; 301 302 // How long we wait for a launched process to attach to the activity manager 303 // before we decide it's never going to come up for real, when the process was 304 // started with a wrapper for instrumentation (such as Valgrind) because it 305 // could take much longer than usual. 306 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 307 308 // How long to wait after going idle before forcing apps to GC. 309 static final int GC_TIMEOUT = 5*1000; 310 311 // The minimum amount of time between successive GC requests for a process. 312 static final int GC_MIN_INTERVAL = 60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process. 315 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 316 317 // The minimum amount of time between successive PSS requests for a process 318 // when the request is due to the memory state being lowered. 319 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 320 321 // The rate at which we check for apps using excessive power -- 15 mins. 322 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on wake locks to start killing things. 326 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // The minimum sample duration we will allow before deciding we have 329 // enough data on CPU usage to start killing things. 330 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 331 332 // How long we allow a receiver to run before giving up on it. 333 static final int BROADCAST_FG_TIMEOUT = 10*1000; 334 static final int BROADCAST_BG_TIMEOUT = 60*1000; 335 336 // How long we wait until we timeout on key dispatching. 337 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 338 339 // How long we wait until we timeout on key dispatching during instrumentation. 340 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 341 342 // Amount of time we wait for observers to handle a user switch before 343 // giving up on them and unfreezing the screen. 344 static final int USER_SWITCH_TIMEOUT = 2*1000; 345 346 // Maximum number of users we allow to be running at a time. 347 static final int MAX_RUNNING_USERS = 3; 348 349 // How long to wait in getAssistContextExtras for the activity and foreground services 350 // to respond with the result. 351 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 352 353 // Maximum number of persisted Uri grants a package is allowed 354 static final int MAX_PERSISTED_URI_GRANTS = 128; 355 356 static final int MY_PID = Process.myPid(); 357 358 static final String[] EMPTY_STRING_ARRAY = new String[0]; 359 360 // How many bytes to write into the dropbox log before truncating 361 static final int DROPBOX_MAX_SIZE = 256 * 1024; 362 363 // Access modes for handleIncomingUser. 364 static final int ALLOW_NON_FULL = 0; 365 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 366 static final int ALLOW_FULL_ONLY = 2; 367 368 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 369 370 /** All system services */ 371 SystemServiceManager mSystemServiceManager; 372 373 /** Run all ActivityStacks through this */ 374 ActivityStackSupervisor mStackSupervisor; 375 376 public IntentFirewall mIntentFirewall; 377 378 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 379 // default actuion automatically. Important for devices without direct input 380 // devices. 381 private boolean mShowDialogs = true; 382 383 BroadcastQueue mFgBroadcastQueue; 384 BroadcastQueue mBgBroadcastQueue; 385 // Convenient for easy iteration over the queues. Foreground is first 386 // so that dispatch of foreground broadcasts gets precedence. 387 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 388 389 BroadcastQueue broadcastQueueForIntent(Intent intent) { 390 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 391 if (DEBUG_BACKGROUND_BROADCAST) { 392 Slog.i(TAG, "Broadcast intent " + intent + " on " 393 + (isFg ? "foreground" : "background") 394 + " queue"); 395 } 396 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 397 } 398 399 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 400 for (BroadcastQueue queue : mBroadcastQueues) { 401 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 402 if (r != null) { 403 return r; 404 } 405 } 406 return null; 407 } 408 409 /** 410 * Activity we have told the window manager to have key focus. 411 */ 412 ActivityRecord mFocusedActivity = null; 413 414 /** 415 * List of intents that were used to start the most recent tasks. 416 */ 417 ArrayList<TaskRecord> mRecentTasks; 418 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 419 420 /** 421 * For addAppTask: cached of the last activity component that was added. 422 */ 423 ComponentName mLastAddedTaskComponent; 424 425 /** 426 * For addAppTask: cached of the last activity uid that was added. 427 */ 428 int mLastAddedTaskUid; 429 430 /** 431 * For addAppTask: cached of the last ActivityInfo that was added. 432 */ 433 ActivityInfo mLastAddedTaskActivity; 434 435 public class PendingAssistExtras extends Binder implements Runnable { 436 public final ActivityRecord activity; 437 public final Bundle extras; 438 public final Intent intent; 439 public final String hint; 440 public final int userHandle; 441 public boolean haveResult = false; 442 public Bundle result = null; 443 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 444 String _hint, int _userHandle) { 445 activity = _activity; 446 extras = _extras; 447 intent = _intent; 448 hint = _hint; 449 userHandle = _userHandle; 450 } 451 @Override 452 public void run() { 453 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 454 synchronized (this) { 455 haveResult = true; 456 notifyAll(); 457 } 458 } 459 } 460 461 final ArrayList<PendingAssistExtras> mPendingAssistExtras 462 = new ArrayList<PendingAssistExtras>(); 463 464 /** 465 * Process management. 466 */ 467 final ProcessList mProcessList = new ProcessList(); 468 469 /** 470 * All of the applications we currently have running organized by name. 471 * The keys are strings of the application package name (as 472 * returned by the package manager), and the keys are ApplicationRecord 473 * objects. 474 */ 475 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 476 477 /** 478 * Tracking long-term execution of processes to look for abuse and other 479 * bad app behavior. 480 */ 481 final ProcessStatsService mProcessStats; 482 483 /** 484 * The currently running isolated processes. 485 */ 486 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 487 488 /** 489 * Counter for assigning isolated process uids, to avoid frequently reusing the 490 * same ones. 491 */ 492 int mNextIsolatedProcessUid = 0; 493 494 /** 495 * The currently running heavy-weight process, if any. 496 */ 497 ProcessRecord mHeavyWeightProcess = null; 498 499 /** 500 * The last time that various processes have crashed. 501 */ 502 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 503 504 /** 505 * Information about a process that is currently marked as bad. 506 */ 507 static final class BadProcessInfo { 508 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 509 this.time = time; 510 this.shortMsg = shortMsg; 511 this.longMsg = longMsg; 512 this.stack = stack; 513 } 514 515 final long time; 516 final String shortMsg; 517 final String longMsg; 518 final String stack; 519 } 520 521 /** 522 * Set of applications that we consider to be bad, and will reject 523 * incoming broadcasts from (which the user has no control over). 524 * Processes are added to this set when they have crashed twice within 525 * a minimum amount of time; they are removed from it when they are 526 * later restarted (hopefully due to some user action). The value is the 527 * time it was added to the list. 528 */ 529 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 530 531 /** 532 * All of the processes we currently have running organized by pid. 533 * The keys are the pid running the application. 534 * 535 * <p>NOTE: This object is protected by its own lock, NOT the global 536 * activity manager lock! 537 */ 538 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 539 540 /** 541 * All of the processes that have been forced to be foreground. The key 542 * is the pid of the caller who requested it (we hold a death 543 * link on it). 544 */ 545 abstract class ForegroundToken implements IBinder.DeathRecipient { 546 int pid; 547 IBinder token; 548 } 549 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 550 551 /** 552 * List of records for processes that someone had tried to start before the 553 * system was ready. We don't start them at that point, but ensure they 554 * are started by the time booting is complete. 555 */ 556 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of persistent applications that are in the process 560 * of being started. 561 */ 562 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Processes that are being forcibly torn down. 566 */ 567 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 568 569 /** 570 * List of running applications, sorted by recent usage. 571 * The first entry in the list is the least recently used. 572 */ 573 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 574 575 /** 576 * Where in mLruProcesses that the processes hosting activities start. 577 */ 578 int mLruProcessActivityStart = 0; 579 580 /** 581 * Where in mLruProcesses that the processes hosting services start. 582 * This is after (lower index) than mLruProcessesActivityStart. 583 */ 584 int mLruProcessServiceStart = 0; 585 586 /** 587 * List of processes that should gc as soon as things are idle. 588 */ 589 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 590 591 /** 592 * Processes we want to collect PSS data from. 593 */ 594 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 595 596 /** 597 * Last time we requested PSS data of all processes. 598 */ 599 long mLastFullPssTime = SystemClock.uptimeMillis(); 600 601 /** 602 * If set, the next time we collect PSS data we should do a full collection 603 * with data from native processes and the kernel. 604 */ 605 boolean mFullPssPending = false; 606 607 /** 608 * This is the process holding what we currently consider to be 609 * the "home" activity. 610 */ 611 ProcessRecord mHomeProcess; 612 613 /** 614 * This is the process holding the activity the user last visited that 615 * is in a different process from the one they are currently in. 616 */ 617 ProcessRecord mPreviousProcess; 618 619 /** 620 * The time at which the previous process was last visible. 621 */ 622 long mPreviousProcessVisibleTime; 623 624 /** 625 * Which uses have been started, so are allowed to run code. 626 */ 627 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 628 629 /** 630 * LRU list of history of current users. Most recently current is at the end. 631 */ 632 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 633 634 /** 635 * Constant array of the users that are currently started. 636 */ 637 int[] mStartedUserArray = new int[] { 0 }; 638 639 /** 640 * Registered observers of the user switching mechanics. 641 */ 642 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 643 = new RemoteCallbackList<IUserSwitchObserver>(); 644 645 /** 646 * Currently active user switch. 647 */ 648 Object mCurUserSwitchCallback; 649 650 /** 651 * Packages that the user has asked to have run in screen size 652 * compatibility mode instead of filling the screen. 653 */ 654 final CompatModePackages mCompatModePackages; 655 656 /** 657 * Set of IntentSenderRecord objects that are currently active. 658 */ 659 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 660 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 661 662 /** 663 * Fingerprints (hashCode()) of stack traces that we've 664 * already logged DropBox entries for. Guarded by itself. If 665 * something (rogue user app) forces this over 666 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 667 */ 668 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 669 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 670 671 /** 672 * Strict Mode background batched logging state. 673 * 674 * The string buffer is guarded by itself, and its lock is also 675 * used to determine if another batched write is already 676 * in-flight. 677 */ 678 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 679 680 /** 681 * Keeps track of all IIntentReceivers that have been registered for 682 * broadcasts. Hash keys are the receiver IBinder, hash value is 683 * a ReceiverList. 684 */ 685 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 686 new HashMap<IBinder, ReceiverList>(); 687 688 /** 689 * Resolver for broadcast intents to registered receivers. 690 * Holds BroadcastFilter (subclass of IntentFilter). 691 */ 692 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 693 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 694 @Override 695 protected boolean allowFilterResult( 696 BroadcastFilter filter, List<BroadcastFilter> dest) { 697 IBinder target = filter.receiverList.receiver.asBinder(); 698 for (int i=dest.size()-1; i>=0; i--) { 699 if (dest.get(i).receiverList.receiver.asBinder() == target) { 700 return false; 701 } 702 } 703 return true; 704 } 705 706 @Override 707 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 708 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 709 || userId == filter.owningUserId) { 710 return super.newResult(filter, match, userId); 711 } 712 return null; 713 } 714 715 @Override 716 protected BroadcastFilter[] newArray(int size) { 717 return new BroadcastFilter[size]; 718 } 719 720 @Override 721 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 722 return packageName.equals(filter.packageName); 723 } 724 }; 725 726 /** 727 * State of all active sticky broadcasts per user. Keys are the action of the 728 * sticky Intent, values are an ArrayList of all broadcasted intents with 729 * that action (which should usually be one). The SparseArray is keyed 730 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 731 * for stickies that are sent to all users. 732 */ 733 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 734 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 735 736 final ActiveServices mServices; 737 738 /** 739 * Backup/restore process management 740 */ 741 String mBackupAppName = null; 742 BackupRecord mBackupTarget = null; 743 744 final ProviderMap mProviderMap; 745 746 /** 747 * List of content providers who have clients waiting for them. The 748 * application is currently being launched and the provider will be 749 * removed from this list once it is published. 750 */ 751 final ArrayList<ContentProviderRecord> mLaunchingProviders 752 = new ArrayList<ContentProviderRecord>(); 753 754 /** 755 * File storing persisted {@link #mGrantedUriPermissions}. 756 */ 757 private final AtomicFile mGrantFile; 758 759 /** XML constants used in {@link #mGrantFile} */ 760 private static final String TAG_URI_GRANTS = "uri-grants"; 761 private static final String TAG_URI_GRANT = "uri-grant"; 762 private static final String ATTR_USER_HANDLE = "userHandle"; 763 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 764 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 765 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 766 private static final String ATTR_TARGET_PKG = "targetPkg"; 767 private static final String ATTR_URI = "uri"; 768 private static final String ATTR_MODE_FLAGS = "modeFlags"; 769 private static final String ATTR_CREATED_TIME = "createdTime"; 770 private static final String ATTR_PREFIX = "prefix"; 771 772 /** 773 * Global set of specific {@link Uri} permissions that have been granted. 774 * This optimized lookup structure maps from {@link UriPermission#targetUid} 775 * to {@link UriPermission#uri} to {@link UriPermission}. 776 */ 777 @GuardedBy("this") 778 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 779 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 780 781 public static class GrantUri { 782 public final int sourceUserId; 783 public final Uri uri; 784 public boolean prefix; 785 786 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 787 this.sourceUserId = sourceUserId; 788 this.uri = uri; 789 this.prefix = prefix; 790 } 791 792 @Override 793 public int hashCode() { 794 return toString().hashCode(); 795 } 796 797 @Override 798 public boolean equals(Object o) { 799 if (o instanceof GrantUri) { 800 GrantUri other = (GrantUri) o; 801 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 802 && prefix == other.prefix; 803 } 804 return false; 805 } 806 807 @Override 808 public String toString() { 809 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 810 if (prefix) result += " [prefix]"; 811 return result; 812 } 813 814 public String toSafeString() { 815 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 816 if (prefix) result += " [prefix]"; 817 return result; 818 } 819 820 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 821 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 822 ContentProvider.getUriWithoutUserId(uri), false); 823 } 824 } 825 826 CoreSettingsObserver mCoreSettingsObserver; 827 828 /** 829 * Thread-local storage used to carry caller permissions over through 830 * indirect content-provider access. 831 */ 832 private class Identity { 833 public int pid; 834 public int uid; 835 836 Identity(int _pid, int _uid) { 837 pid = _pid; 838 uid = _uid; 839 } 840 } 841 842 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 843 844 /** 845 * All information we have collected about the runtime performance of 846 * any user id that can impact battery performance. 847 */ 848 final BatteryStatsService mBatteryStatsService; 849 850 /** 851 * Information about component usage 852 */ 853 UsageStatsManagerInternal mUsageStatsService; 854 855 /** 856 * Information about and control over application operations 857 */ 858 final AppOpsService mAppOpsService; 859 860 /** 861 * Save recent tasks information across reboots. 862 */ 863 final TaskPersister mTaskPersister; 864 865 /** 866 * Current configuration information. HistoryRecord objects are given 867 * a reference to this object to indicate which configuration they are 868 * currently running in, so this object must be kept immutable. 869 */ 870 Configuration mConfiguration = new Configuration(); 871 872 /** 873 * Current sequencing integer of the configuration, for skipping old 874 * configurations. 875 */ 876 int mConfigurationSeq = 0; 877 878 /** 879 * Hardware-reported OpenGLES version. 880 */ 881 final int GL_ES_VERSION; 882 883 /** 884 * List of initialization arguments to pass to all processes when binding applications to them. 885 * For example, references to the commonly used services. 886 */ 887 HashMap<String, IBinder> mAppBindArgs; 888 889 /** 890 * Temporary to avoid allocations. Protected by main lock. 891 */ 892 final StringBuilder mStringBuilder = new StringBuilder(256); 893 894 /** 895 * Used to control how we initialize the service. 896 */ 897 ComponentName mTopComponent; 898 String mTopAction = Intent.ACTION_MAIN; 899 String mTopData; 900 boolean mProcessesReady = false; 901 boolean mSystemReady = false; 902 boolean mBooting = false; 903 boolean mCallFinishBooting = false; 904 boolean mBootAnimationComplete = false; 905 boolean mWaitingUpdate = false; 906 boolean mDidUpdate = false; 907 boolean mOnBattery = false; 908 boolean mLaunchWarningShown = false; 909 910 Context mContext; 911 912 int mFactoryTest; 913 914 boolean mCheckedForSetup; 915 916 /** 917 * The time at which we will allow normal application switches again, 918 * after a call to {@link #stopAppSwitches()}. 919 */ 920 long mAppSwitchesAllowedTime; 921 922 /** 923 * This is set to true after the first switch after mAppSwitchesAllowedTime 924 * is set; any switches after that will clear the time. 925 */ 926 boolean mDidAppSwitch; 927 928 /** 929 * Last time (in realtime) at which we checked for power usage. 930 */ 931 long mLastPowerCheckRealtime; 932 933 /** 934 * Last time (in uptime) at which we checked for power usage. 935 */ 936 long mLastPowerCheckUptime; 937 938 /** 939 * Set while we are wanting to sleep, to prevent any 940 * activities from being started/resumed. 941 */ 942 private boolean mSleeping = false; 943 944 /** 945 * Set while we are running a voice interaction. This overrides 946 * sleeping while it is active. 947 */ 948 private boolean mRunningVoice = false; 949 950 /** 951 * State of external calls telling us if the device is asleep. 952 */ 953 private boolean mWentToSleep = false; 954 955 /** 956 * State of external call telling us if the lock screen is shown. 957 */ 958 private boolean mLockScreenShown = false; 959 960 /** 961 * Set if we are shutting down the system, similar to sleeping. 962 */ 963 boolean mShuttingDown = false; 964 965 /** 966 * Current sequence id for oom_adj computation traversal. 967 */ 968 int mAdjSeq = 0; 969 970 /** 971 * Current sequence id for process LRU updating. 972 */ 973 int mLruSeq = 0; 974 975 /** 976 * Keep track of the non-cached/empty process we last found, to help 977 * determine how to distribute cached/empty processes next time. 978 */ 979 int mNumNonCachedProcs = 0; 980 981 /** 982 * Keep track of the number of cached hidden procs, to balance oom adj 983 * distribution between those and empty procs. 984 */ 985 int mNumCachedHiddenProcs = 0; 986 987 /** 988 * Keep track of the number of service processes we last found, to 989 * determine on the next iteration which should be B services. 990 */ 991 int mNumServiceProcs = 0; 992 int mNewNumAServiceProcs = 0; 993 int mNewNumServiceProcs = 0; 994 995 /** 996 * Allow the current computed overall memory level of the system to go down? 997 * This is set to false when we are killing processes for reasons other than 998 * memory management, so that the now smaller process list will not be taken as 999 * an indication that memory is tighter. 1000 */ 1001 boolean mAllowLowerMemLevel = false; 1002 1003 /** 1004 * The last computed memory level, for holding when we are in a state that 1005 * processes are going away for other reasons. 1006 */ 1007 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1008 1009 /** 1010 * The last total number of process we have, to determine if changes actually look 1011 * like a shrinking number of process due to lower RAM. 1012 */ 1013 int mLastNumProcesses; 1014 1015 /** 1016 * The uptime of the last time we performed idle maintenance. 1017 */ 1018 long mLastIdleTime = SystemClock.uptimeMillis(); 1019 1020 /** 1021 * Total time spent with RAM that has been added in the past since the last idle time. 1022 */ 1023 long mLowRamTimeSinceLastIdle = 0; 1024 1025 /** 1026 * If RAM is currently low, when that horrible situation started. 1027 */ 1028 long mLowRamStartTime = 0; 1029 1030 /** 1031 * For reporting to battery stats the current top application. 1032 */ 1033 private String mCurResumedPackage = null; 1034 private int mCurResumedUid = -1; 1035 1036 /** 1037 * For reporting to battery stats the apps currently running foreground 1038 * service. The ProcessMap is package/uid tuples; each of these contain 1039 * an array of the currently foreground processes. 1040 */ 1041 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1042 = new ProcessMap<ArrayList<ProcessRecord>>(); 1043 1044 /** 1045 * This is set if we had to do a delayed dexopt of an app before launching 1046 * it, to increase the ANR timeouts in that case. 1047 */ 1048 boolean mDidDexOpt; 1049 1050 /** 1051 * Set if the systemServer made a call to enterSafeMode. 1052 */ 1053 boolean mSafeMode; 1054 1055 String mDebugApp = null; 1056 boolean mWaitForDebugger = false; 1057 boolean mDebugTransient = false; 1058 String mOrigDebugApp = null; 1059 boolean mOrigWaitForDebugger = false; 1060 boolean mAlwaysFinishActivities = false; 1061 IActivityController mController = null; 1062 String mProfileApp = null; 1063 ProcessRecord mProfileProc = null; 1064 String mProfileFile; 1065 ParcelFileDescriptor mProfileFd; 1066 int mSamplingInterval = 0; 1067 boolean mAutoStopProfiler = false; 1068 int mProfileType = 0; 1069 String mOpenGlTraceApp = null; 1070 1071 static class ProcessChangeItem { 1072 static final int CHANGE_ACTIVITIES = 1<<0; 1073 static final int CHANGE_PROCESS_STATE = 1<<1; 1074 int changes; 1075 int uid; 1076 int pid; 1077 int processState; 1078 boolean foregroundActivities; 1079 } 1080 1081 final RemoteCallbackList<IProcessObserver> mProcessObservers 1082 = new RemoteCallbackList<IProcessObserver>(); 1083 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1084 1085 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1086 = new ArrayList<ProcessChangeItem>(); 1087 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1088 = new ArrayList<ProcessChangeItem>(); 1089 1090 /** 1091 * Runtime CPU use collection thread. This object's lock is used to 1092 * perform synchronization with the thread (notifying it to run). 1093 */ 1094 final Thread mProcessCpuThread; 1095 1096 /** 1097 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1098 * Must acquire this object's lock when accessing it. 1099 * NOTE: this lock will be held while doing long operations (trawling 1100 * through all processes in /proc), so it should never be acquired by 1101 * any critical paths such as when holding the main activity manager lock. 1102 */ 1103 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1104 MONITOR_THREAD_CPU_USAGE); 1105 final AtomicLong mLastCpuTime = new AtomicLong(0); 1106 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1107 1108 long mLastWriteTime = 0; 1109 1110 /** 1111 * Used to retain an update lock when the foreground activity is in 1112 * immersive mode. 1113 */ 1114 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1115 1116 /** 1117 * Set to true after the system has finished booting. 1118 */ 1119 boolean mBooted = false; 1120 1121 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1122 int mProcessLimitOverride = -1; 1123 1124 WindowManagerService mWindowManager; 1125 1126 final ActivityThread mSystemThread; 1127 1128 // Holds the current foreground user's id 1129 int mCurrentUserId = 0; 1130 // Holds the target user's id during a user switch 1131 int mTargetUserId = UserHandle.USER_NULL; 1132 // If there are multiple profiles for the current user, their ids are here 1133 // Currently only the primary user can have managed profiles 1134 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1135 1136 /** 1137 * Mapping from each known user ID to the profile group ID it is associated with. 1138 */ 1139 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1140 1141 private UserManagerService mUserManager; 1142 1143 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1144 final ProcessRecord mApp; 1145 final int mPid; 1146 final IApplicationThread mAppThread; 1147 1148 AppDeathRecipient(ProcessRecord app, int pid, 1149 IApplicationThread thread) { 1150 if (localLOGV) Slog.v( 1151 TAG, "New death recipient " + this 1152 + " for thread " + thread.asBinder()); 1153 mApp = app; 1154 mPid = pid; 1155 mAppThread = thread; 1156 } 1157 1158 @Override 1159 public void binderDied() { 1160 if (localLOGV) Slog.v( 1161 TAG, "Death received in " + this 1162 + " for thread " + mAppThread.asBinder()); 1163 synchronized(ActivityManagerService.this) { 1164 appDiedLocked(mApp, mPid, mAppThread); 1165 } 1166 } 1167 } 1168 1169 static final int SHOW_ERROR_MSG = 1; 1170 static final int SHOW_NOT_RESPONDING_MSG = 2; 1171 static final int SHOW_FACTORY_ERROR_MSG = 3; 1172 static final int UPDATE_CONFIGURATION_MSG = 4; 1173 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1174 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1175 static final int SERVICE_TIMEOUT_MSG = 12; 1176 static final int UPDATE_TIME_ZONE = 13; 1177 static final int SHOW_UID_ERROR_MSG = 14; 1178 static final int IM_FEELING_LUCKY_MSG = 15; 1179 static final int PROC_START_TIMEOUT_MSG = 20; 1180 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1181 static final int KILL_APPLICATION_MSG = 22; 1182 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1183 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1184 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1185 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1186 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1187 static final int CLEAR_DNS_CACHE_MSG = 28; 1188 static final int UPDATE_HTTP_PROXY_MSG = 29; 1189 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1190 static final int DISPATCH_PROCESSES_CHANGED = 31; 1191 static final int DISPATCH_PROCESS_DIED = 32; 1192 static final int REPORT_MEM_USAGE_MSG = 33; 1193 static final int REPORT_USER_SWITCH_MSG = 34; 1194 static final int CONTINUE_USER_SWITCH_MSG = 35; 1195 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1196 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1197 static final int PERSIST_URI_GRANTS_MSG = 38; 1198 static final int REQUEST_ALL_PSS_MSG = 39; 1199 static final int START_PROFILES_MSG = 40; 1200 static final int UPDATE_TIME = 41; 1201 static final int SYSTEM_USER_START_MSG = 42; 1202 static final int SYSTEM_USER_CURRENT_MSG = 43; 1203 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1204 static final int FINISH_BOOTING_MSG = 45; 1205 static final int START_USER_SWITCH_MSG = 46; 1206 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1207 1208 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1209 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1210 static final int FIRST_COMPAT_MODE_MSG = 300; 1211 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1212 1213 AlertDialog mUidAlert; 1214 CompatModeDialog mCompatModeDialog; 1215 long mLastMemUsageReportTime = 0; 1216 1217 private LockToAppRequestDialog mLockToAppRequest; 1218 1219 /** 1220 * Flag whether the current user is a "monkey", i.e. whether 1221 * the UI is driven by a UI automation tool. 1222 */ 1223 private boolean mUserIsMonkey; 1224 1225 /** Flag whether the device has a Recents UI */ 1226 boolean mHasRecents; 1227 1228 /** The dimensions of the thumbnails in the Recents UI. */ 1229 int mThumbnailWidth; 1230 int mThumbnailHeight; 1231 1232 final ServiceThread mHandlerThread; 1233 final MainHandler mHandler; 1234 1235 final class MainHandler extends Handler { 1236 public MainHandler(Looper looper) { 1237 super(looper, null, true); 1238 } 1239 1240 @Override 1241 public void handleMessage(Message msg) { 1242 switch (msg.what) { 1243 case SHOW_ERROR_MSG: { 1244 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1245 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1246 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1247 synchronized (ActivityManagerService.this) { 1248 ProcessRecord proc = (ProcessRecord)data.get("app"); 1249 AppErrorResult res = (AppErrorResult) data.get("result"); 1250 if (proc != null && proc.crashDialog != null) { 1251 Slog.e(TAG, "App already has crash dialog: " + proc); 1252 if (res != null) { 1253 res.set(0); 1254 } 1255 return; 1256 } 1257 boolean isBackground = (UserHandle.getAppId(proc.uid) 1258 >= Process.FIRST_APPLICATION_UID 1259 && proc.pid != MY_PID); 1260 for (int userId : mCurrentProfileIds) { 1261 isBackground &= (proc.userId != userId); 1262 } 1263 if (isBackground && !showBackground) { 1264 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1265 if (res != null) { 1266 res.set(0); 1267 } 1268 return; 1269 } 1270 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1271 Dialog d = new AppErrorDialog(mContext, 1272 ActivityManagerService.this, res, proc); 1273 d.show(); 1274 proc.crashDialog = d; 1275 } else { 1276 // The device is asleep, so just pretend that the user 1277 // saw a crash dialog and hit "force quit". 1278 if (res != null) { 1279 res.set(0); 1280 } 1281 } 1282 } 1283 1284 ensureBootCompleted(); 1285 } break; 1286 case SHOW_NOT_RESPONDING_MSG: { 1287 synchronized (ActivityManagerService.this) { 1288 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1289 ProcessRecord proc = (ProcessRecord)data.get("app"); 1290 if (proc != null && proc.anrDialog != null) { 1291 Slog.e(TAG, "App already has anr dialog: " + proc); 1292 return; 1293 } 1294 1295 Intent intent = new Intent("android.intent.action.ANR"); 1296 if (!mProcessesReady) { 1297 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1298 | Intent.FLAG_RECEIVER_FOREGROUND); 1299 } 1300 broadcastIntentLocked(null, null, intent, 1301 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1302 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1303 1304 if (mShowDialogs) { 1305 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1306 mContext, proc, (ActivityRecord)data.get("activity"), 1307 msg.arg1 != 0); 1308 d.show(); 1309 proc.anrDialog = d; 1310 } else { 1311 // Just kill the app if there is no dialog to be shown. 1312 killAppAtUsersRequest(proc, null); 1313 } 1314 } 1315 1316 ensureBootCompleted(); 1317 } break; 1318 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1319 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1320 synchronized (ActivityManagerService.this) { 1321 ProcessRecord proc = (ProcessRecord) data.get("app"); 1322 if (proc == null) { 1323 Slog.e(TAG, "App not found when showing strict mode dialog."); 1324 break; 1325 } 1326 if (proc.crashDialog != null) { 1327 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1328 return; 1329 } 1330 AppErrorResult res = (AppErrorResult) data.get("result"); 1331 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1332 Dialog d = new StrictModeViolationDialog(mContext, 1333 ActivityManagerService.this, res, proc); 1334 d.show(); 1335 proc.crashDialog = d; 1336 } else { 1337 // The device is asleep, so just pretend that the user 1338 // saw a crash dialog and hit "force quit". 1339 res.set(0); 1340 } 1341 } 1342 ensureBootCompleted(); 1343 } break; 1344 case SHOW_FACTORY_ERROR_MSG: { 1345 Dialog d = new FactoryErrorDialog( 1346 mContext, msg.getData().getCharSequence("msg")); 1347 d.show(); 1348 ensureBootCompleted(); 1349 } break; 1350 case UPDATE_CONFIGURATION_MSG: { 1351 final ContentResolver resolver = mContext.getContentResolver(); 1352 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1353 } break; 1354 case GC_BACKGROUND_PROCESSES_MSG: { 1355 synchronized (ActivityManagerService.this) { 1356 performAppGcsIfAppropriateLocked(); 1357 } 1358 } break; 1359 case WAIT_FOR_DEBUGGER_MSG: { 1360 synchronized (ActivityManagerService.this) { 1361 ProcessRecord app = (ProcessRecord)msg.obj; 1362 if (msg.arg1 != 0) { 1363 if (!app.waitedForDebugger) { 1364 Dialog d = new AppWaitingForDebuggerDialog( 1365 ActivityManagerService.this, 1366 mContext, app); 1367 app.waitDialog = d; 1368 app.waitedForDebugger = true; 1369 d.show(); 1370 } 1371 } else { 1372 if (app.waitDialog != null) { 1373 app.waitDialog.dismiss(); 1374 app.waitDialog = null; 1375 } 1376 } 1377 } 1378 } break; 1379 case SERVICE_TIMEOUT_MSG: { 1380 if (mDidDexOpt) { 1381 mDidDexOpt = false; 1382 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1383 nmsg.obj = msg.obj; 1384 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1385 return; 1386 } 1387 mServices.serviceTimeout((ProcessRecord)msg.obj); 1388 } break; 1389 case UPDATE_TIME_ZONE: { 1390 synchronized (ActivityManagerService.this) { 1391 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1392 ProcessRecord r = mLruProcesses.get(i); 1393 if (r.thread != null) { 1394 try { 1395 r.thread.updateTimeZone(); 1396 } catch (RemoteException ex) { 1397 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1398 } 1399 } 1400 } 1401 } 1402 } break; 1403 case CLEAR_DNS_CACHE_MSG: { 1404 synchronized (ActivityManagerService.this) { 1405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1406 ProcessRecord r = mLruProcesses.get(i); 1407 if (r.thread != null) { 1408 try { 1409 r.thread.clearDnsCache(); 1410 } catch (RemoteException ex) { 1411 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1412 } 1413 } 1414 } 1415 } 1416 } break; 1417 case UPDATE_HTTP_PROXY_MSG: { 1418 ProxyInfo proxy = (ProxyInfo)msg.obj; 1419 String host = ""; 1420 String port = ""; 1421 String exclList = ""; 1422 Uri pacFileUrl = Uri.EMPTY; 1423 if (proxy != null) { 1424 host = proxy.getHost(); 1425 port = Integer.toString(proxy.getPort()); 1426 exclList = proxy.getExclusionListAsString(); 1427 pacFileUrl = proxy.getPacFileUrl(); 1428 } 1429 synchronized (ActivityManagerService.this) { 1430 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1431 ProcessRecord r = mLruProcesses.get(i); 1432 if (r.thread != null) { 1433 try { 1434 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1435 } catch (RemoteException ex) { 1436 Slog.w(TAG, "Failed to update http proxy for: " + 1437 r.info.processName); 1438 } 1439 } 1440 } 1441 } 1442 } break; 1443 case SHOW_UID_ERROR_MSG: { 1444 String title = "System UIDs Inconsistent"; 1445 String text = "UIDs on the system are inconsistent, you need to wipe your" 1446 + " data partition or your device will be unstable."; 1447 Log.e(TAG, title + ": " + text); 1448 if (mShowDialogs) { 1449 // XXX This is a temporary dialog, no need to localize. 1450 AlertDialog d = new BaseErrorDialog(mContext); 1451 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1452 d.setCancelable(false); 1453 d.setTitle(title); 1454 d.setMessage(text); 1455 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1456 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1457 mUidAlert = d; 1458 d.show(); 1459 } 1460 } break; 1461 case IM_FEELING_LUCKY_MSG: { 1462 if (mUidAlert != null) { 1463 mUidAlert.dismiss(); 1464 mUidAlert = null; 1465 } 1466 } break; 1467 case PROC_START_TIMEOUT_MSG: { 1468 if (mDidDexOpt) { 1469 mDidDexOpt = false; 1470 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1471 nmsg.obj = msg.obj; 1472 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1473 return; 1474 } 1475 ProcessRecord app = (ProcessRecord)msg.obj; 1476 synchronized (ActivityManagerService.this) { 1477 processStartTimedOutLocked(app); 1478 } 1479 } break; 1480 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1481 synchronized (ActivityManagerService.this) { 1482 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1483 } 1484 } break; 1485 case KILL_APPLICATION_MSG: { 1486 synchronized (ActivityManagerService.this) { 1487 int appid = msg.arg1; 1488 boolean restart = (msg.arg2 == 1); 1489 Bundle bundle = (Bundle)msg.obj; 1490 String pkg = bundle.getString("pkg"); 1491 String reason = bundle.getString("reason"); 1492 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1493 false, UserHandle.USER_ALL, reason); 1494 } 1495 } break; 1496 case FINALIZE_PENDING_INTENT_MSG: { 1497 ((PendingIntentRecord)msg.obj).completeFinalize(); 1498 } break; 1499 case POST_HEAVY_NOTIFICATION_MSG: { 1500 INotificationManager inm = NotificationManager.getService(); 1501 if (inm == null) { 1502 return; 1503 } 1504 1505 ActivityRecord root = (ActivityRecord)msg.obj; 1506 ProcessRecord process = root.app; 1507 if (process == null) { 1508 return; 1509 } 1510 1511 try { 1512 Context context = mContext.createPackageContext(process.info.packageName, 0); 1513 String text = mContext.getString(R.string.heavy_weight_notification, 1514 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1515 Notification notification = new Notification(); 1516 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1517 notification.when = 0; 1518 notification.flags = Notification.FLAG_ONGOING_EVENT; 1519 notification.tickerText = text; 1520 notification.defaults = 0; // please be quiet 1521 notification.sound = null; 1522 notification.vibrate = null; 1523 notification.color = mContext.getResources().getColor( 1524 com.android.internal.R.color.system_notification_accent_color); 1525 notification.setLatestEventInfo(context, text, 1526 mContext.getText(R.string.heavy_weight_notification_detail), 1527 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1528 PendingIntent.FLAG_CANCEL_CURRENT, null, 1529 new UserHandle(root.userId))); 1530 1531 try { 1532 int[] outId = new int[1]; 1533 inm.enqueueNotificationWithTag("android", "android", null, 1534 R.string.heavy_weight_notification, 1535 notification, outId, root.userId); 1536 } catch (RuntimeException e) { 1537 Slog.w(ActivityManagerService.TAG, 1538 "Error showing notification for heavy-weight app", e); 1539 } catch (RemoteException e) { 1540 } 1541 } catch (NameNotFoundException e) { 1542 Slog.w(TAG, "Unable to create context for heavy notification", e); 1543 } 1544 } break; 1545 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1546 INotificationManager inm = NotificationManager.getService(); 1547 if (inm == null) { 1548 return; 1549 } 1550 try { 1551 inm.cancelNotificationWithTag("android", null, 1552 R.string.heavy_weight_notification, msg.arg1); 1553 } catch (RuntimeException e) { 1554 Slog.w(ActivityManagerService.TAG, 1555 "Error canceling notification for service", e); 1556 } catch (RemoteException e) { 1557 } 1558 } break; 1559 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1560 synchronized (ActivityManagerService.this) { 1561 checkExcessivePowerUsageLocked(true); 1562 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1563 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1564 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1565 } 1566 } break; 1567 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1568 synchronized (ActivityManagerService.this) { 1569 ActivityRecord ar = (ActivityRecord)msg.obj; 1570 if (mCompatModeDialog != null) { 1571 if (mCompatModeDialog.mAppInfo.packageName.equals( 1572 ar.info.applicationInfo.packageName)) { 1573 return; 1574 } 1575 mCompatModeDialog.dismiss(); 1576 mCompatModeDialog = null; 1577 } 1578 if (ar != null && false) { 1579 if (mCompatModePackages.getPackageAskCompatModeLocked( 1580 ar.packageName)) { 1581 int mode = mCompatModePackages.computeCompatModeLocked( 1582 ar.info.applicationInfo); 1583 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1584 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1585 mCompatModeDialog = new CompatModeDialog( 1586 ActivityManagerService.this, mContext, 1587 ar.info.applicationInfo); 1588 mCompatModeDialog.show(); 1589 } 1590 } 1591 } 1592 } 1593 break; 1594 } 1595 case DISPATCH_PROCESSES_CHANGED: { 1596 dispatchProcessesChanged(); 1597 break; 1598 } 1599 case DISPATCH_PROCESS_DIED: { 1600 final int pid = msg.arg1; 1601 final int uid = msg.arg2; 1602 dispatchProcessDied(pid, uid); 1603 break; 1604 } 1605 case REPORT_MEM_USAGE_MSG: { 1606 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1607 Thread thread = new Thread() { 1608 @Override public void run() { 1609 final SparseArray<ProcessMemInfo> infoMap 1610 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1611 for (int i=0, N=memInfos.size(); i<N; i++) { 1612 ProcessMemInfo mi = memInfos.get(i); 1613 infoMap.put(mi.pid, mi); 1614 } 1615 updateCpuStatsNow(); 1616 synchronized (mProcessCpuTracker) { 1617 final int N = mProcessCpuTracker.countStats(); 1618 for (int i=0; i<N; i++) { 1619 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1620 if (st.vsize > 0) { 1621 long pss = Debug.getPss(st.pid, null); 1622 if (pss > 0) { 1623 if (infoMap.indexOfKey(st.pid) < 0) { 1624 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1625 ProcessList.NATIVE_ADJ, -1, "native", null); 1626 mi.pss = pss; 1627 memInfos.add(mi); 1628 } 1629 } 1630 } 1631 } 1632 } 1633 1634 long totalPss = 0; 1635 for (int i=0, N=memInfos.size(); i<N; i++) { 1636 ProcessMemInfo mi = memInfos.get(i); 1637 if (mi.pss == 0) { 1638 mi.pss = Debug.getPss(mi.pid, null); 1639 } 1640 totalPss += mi.pss; 1641 } 1642 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1643 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1644 if (lhs.oomAdj != rhs.oomAdj) { 1645 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1646 } 1647 if (lhs.pss != rhs.pss) { 1648 return lhs.pss < rhs.pss ? 1 : -1; 1649 } 1650 return 0; 1651 } 1652 }); 1653 1654 StringBuilder tag = new StringBuilder(128); 1655 StringBuilder stack = new StringBuilder(128); 1656 tag.append("Low on memory -- "); 1657 appendMemBucket(tag, totalPss, "total", false); 1658 appendMemBucket(stack, totalPss, "total", true); 1659 1660 StringBuilder logBuilder = new StringBuilder(1024); 1661 logBuilder.append("Low on memory:\n"); 1662 1663 boolean firstLine = true; 1664 int lastOomAdj = Integer.MIN_VALUE; 1665 for (int i=0, N=memInfos.size(); i<N; i++) { 1666 ProcessMemInfo mi = memInfos.get(i); 1667 1668 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1669 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1670 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1671 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1672 if (lastOomAdj != mi.oomAdj) { 1673 lastOomAdj = mi.oomAdj; 1674 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1675 tag.append(" / "); 1676 } 1677 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1678 if (firstLine) { 1679 stack.append(":"); 1680 firstLine = false; 1681 } 1682 stack.append("\n\t at "); 1683 } else { 1684 stack.append("$"); 1685 } 1686 } else { 1687 tag.append(" "); 1688 stack.append("$"); 1689 } 1690 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1691 appendMemBucket(tag, mi.pss, mi.name, false); 1692 } 1693 appendMemBucket(stack, mi.pss, mi.name, true); 1694 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1695 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1696 stack.append("("); 1697 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1698 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1699 stack.append(DUMP_MEM_OOM_LABEL[k]); 1700 stack.append(":"); 1701 stack.append(DUMP_MEM_OOM_ADJ[k]); 1702 } 1703 } 1704 stack.append(")"); 1705 } 1706 } 1707 1708 logBuilder.append(" "); 1709 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1710 logBuilder.append(' '); 1711 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1712 logBuilder.append(' '); 1713 ProcessList.appendRamKb(logBuilder, mi.pss); 1714 logBuilder.append(" kB: "); 1715 logBuilder.append(mi.name); 1716 logBuilder.append(" ("); 1717 logBuilder.append(mi.pid); 1718 logBuilder.append(") "); 1719 logBuilder.append(mi.adjType); 1720 logBuilder.append('\n'); 1721 if (mi.adjReason != null) { 1722 logBuilder.append(" "); 1723 logBuilder.append(mi.adjReason); 1724 logBuilder.append('\n'); 1725 } 1726 } 1727 1728 logBuilder.append(" "); 1729 ProcessList.appendRamKb(logBuilder, totalPss); 1730 logBuilder.append(" kB: TOTAL\n"); 1731 1732 long[] infos = new long[Debug.MEMINFO_COUNT]; 1733 Debug.getMemInfo(infos); 1734 logBuilder.append(" MemInfo: "); 1735 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1736 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1737 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1738 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1739 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1740 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1741 logBuilder.append(" ZRAM: "); 1742 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1743 logBuilder.append(" kB RAM, "); 1744 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1745 logBuilder.append(" kB swap total, "); 1746 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1747 logBuilder.append(" kB swap free\n"); 1748 } 1749 Slog.i(TAG, logBuilder.toString()); 1750 1751 StringBuilder dropBuilder = new StringBuilder(1024); 1752 /* 1753 StringWriter oomSw = new StringWriter(); 1754 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1755 StringWriter catSw = new StringWriter(); 1756 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1757 String[] emptyArgs = new String[] { }; 1758 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1759 oomPw.flush(); 1760 String oomString = oomSw.toString(); 1761 */ 1762 dropBuilder.append(stack); 1763 dropBuilder.append('\n'); 1764 dropBuilder.append('\n'); 1765 dropBuilder.append(logBuilder); 1766 dropBuilder.append('\n'); 1767 /* 1768 dropBuilder.append(oomString); 1769 dropBuilder.append('\n'); 1770 */ 1771 StringWriter catSw = new StringWriter(); 1772 synchronized (ActivityManagerService.this) { 1773 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1774 String[] emptyArgs = new String[] { }; 1775 catPw.println(); 1776 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1777 catPw.println(); 1778 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1779 false, false, null); 1780 catPw.println(); 1781 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1782 catPw.flush(); 1783 } 1784 dropBuilder.append(catSw.toString()); 1785 addErrorToDropBox("lowmem", null, "system_server", null, 1786 null, tag.toString(), dropBuilder.toString(), null, null); 1787 //Slog.i(TAG, "Sent to dropbox:"); 1788 //Slog.i(TAG, dropBuilder.toString()); 1789 synchronized (ActivityManagerService.this) { 1790 long now = SystemClock.uptimeMillis(); 1791 if (mLastMemUsageReportTime < now) { 1792 mLastMemUsageReportTime = now; 1793 } 1794 } 1795 } 1796 }; 1797 thread.start(); 1798 break; 1799 } 1800 case START_USER_SWITCH_MSG: { 1801 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1802 break; 1803 } 1804 case REPORT_USER_SWITCH_MSG: { 1805 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1806 break; 1807 } 1808 case CONTINUE_USER_SWITCH_MSG: { 1809 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1810 break; 1811 } 1812 case USER_SWITCH_TIMEOUT_MSG: { 1813 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1814 break; 1815 } 1816 case IMMERSIVE_MODE_LOCK_MSG: { 1817 final boolean nextState = (msg.arg1 != 0); 1818 if (mUpdateLock.isHeld() != nextState) { 1819 if (DEBUG_IMMERSIVE) { 1820 final ActivityRecord r = (ActivityRecord) msg.obj; 1821 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1822 } 1823 if (nextState) { 1824 mUpdateLock.acquire(); 1825 } else { 1826 mUpdateLock.release(); 1827 } 1828 } 1829 break; 1830 } 1831 case PERSIST_URI_GRANTS_MSG: { 1832 writeGrantedUriPermissions(); 1833 break; 1834 } 1835 case REQUEST_ALL_PSS_MSG: { 1836 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1837 break; 1838 } 1839 case START_PROFILES_MSG: { 1840 synchronized (ActivityManagerService.this) { 1841 startProfilesLocked(); 1842 } 1843 break; 1844 } 1845 case UPDATE_TIME: { 1846 synchronized (ActivityManagerService.this) { 1847 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1848 ProcessRecord r = mLruProcesses.get(i); 1849 if (r.thread != null) { 1850 try { 1851 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1852 } catch (RemoteException ex) { 1853 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1854 } 1855 } 1856 } 1857 } 1858 break; 1859 } 1860 case SYSTEM_USER_START_MSG: { 1861 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1862 Integer.toString(msg.arg1), msg.arg1); 1863 mSystemServiceManager.startUser(msg.arg1); 1864 break; 1865 } 1866 case SYSTEM_USER_CURRENT_MSG: { 1867 mBatteryStatsService.noteEvent( 1868 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1869 Integer.toString(msg.arg2), msg.arg2); 1870 mBatteryStatsService.noteEvent( 1871 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1872 Integer.toString(msg.arg1), msg.arg1); 1873 mSystemServiceManager.switchUser(msg.arg1); 1874 mLockToAppRequest.clearPrompt(); 1875 break; 1876 } 1877 case ENTER_ANIMATION_COMPLETE_MSG: { 1878 synchronized (ActivityManagerService.this) { 1879 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1880 if (r != null && r.app != null && r.app.thread != null) { 1881 try { 1882 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1883 } catch (RemoteException e) { 1884 } 1885 } 1886 } 1887 break; 1888 } 1889 case FINISH_BOOTING_MSG: { 1890 if (msg.arg1 != 0) { 1891 finishBooting(); 1892 } 1893 if (msg.arg2 != 0) { 1894 enableScreenAfterBoot(); 1895 } 1896 break; 1897 } 1898 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 1899 try { 1900 Locale l = (Locale) msg.obj; 1901 IBinder service = ServiceManager.getService("mount"); 1902 IMountService mountService = IMountService.Stub.asInterface(service); 1903 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 1904 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 1905 } catch (RemoteException e) { 1906 Log.e(TAG, "Error storing locale for decryption UI", e); 1907 } 1908 break; 1909 } 1910 } 1911 } 1912 }; 1913 1914 static final int COLLECT_PSS_BG_MSG = 1; 1915 1916 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1917 @Override 1918 public void handleMessage(Message msg) { 1919 switch (msg.what) { 1920 case COLLECT_PSS_BG_MSG: { 1921 long start = SystemClock.uptimeMillis(); 1922 MemInfoReader memInfo = null; 1923 synchronized (ActivityManagerService.this) { 1924 if (mFullPssPending) { 1925 mFullPssPending = false; 1926 memInfo = new MemInfoReader(); 1927 } 1928 } 1929 if (memInfo != null) { 1930 updateCpuStatsNow(); 1931 long nativeTotalPss = 0; 1932 synchronized (mProcessCpuTracker) { 1933 final int N = mProcessCpuTracker.countStats(); 1934 for (int j=0; j<N; j++) { 1935 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1936 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1937 // This is definitely an application process; skip it. 1938 continue; 1939 } 1940 synchronized (mPidsSelfLocked) { 1941 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1942 // This is one of our own processes; skip it. 1943 continue; 1944 } 1945 } 1946 nativeTotalPss += Debug.getPss(st.pid, null); 1947 } 1948 } 1949 memInfo.readMemInfo(); 1950 synchronized (ActivityManagerService.this) { 1951 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1952 + (SystemClock.uptimeMillis()-start) + "ms"); 1953 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1954 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1955 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1956 +memInfo.getSlabSizeKb(), 1957 nativeTotalPss); 1958 } 1959 } 1960 1961 int i=0, num=0; 1962 long[] tmp = new long[1]; 1963 do { 1964 ProcessRecord proc; 1965 int procState; 1966 int pid; 1967 synchronized (ActivityManagerService.this) { 1968 if (i >= mPendingPssProcesses.size()) { 1969 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1970 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1971 mPendingPssProcesses.clear(); 1972 return; 1973 } 1974 proc = mPendingPssProcesses.get(i); 1975 procState = proc.pssProcState; 1976 if (proc.thread != null && procState == proc.setProcState) { 1977 pid = proc.pid; 1978 } else { 1979 proc = null; 1980 pid = 0; 1981 } 1982 i++; 1983 } 1984 if (proc != null) { 1985 long pss = Debug.getPss(pid, tmp); 1986 synchronized (ActivityManagerService.this) { 1987 if (proc.thread != null && proc.setProcState == procState 1988 && proc.pid == pid) { 1989 num++; 1990 proc.lastPssTime = SystemClock.uptimeMillis(); 1991 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1992 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1993 + ": " + pss + " lastPss=" + proc.lastPss 1994 + " state=" + ProcessList.makeProcStateString(procState)); 1995 if (proc.initialIdlePss == 0) { 1996 proc.initialIdlePss = pss; 1997 } 1998 proc.lastPss = pss; 1999 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 2000 proc.lastCachedPss = pss; 2001 } 2002 } 2003 } 2004 } 2005 } while (true); 2006 } 2007 } 2008 } 2009 }; 2010 2011 /** 2012 * Monitor for package changes and update our internal state. 2013 */ 2014 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 2015 @Override 2016 public void onPackageRemoved(String packageName, int uid) { 2017 // Remove all tasks with activities in the specified package from the list of recent tasks 2018 final int eventUserId = getChangingUserId(); 2019 synchronized (ActivityManagerService.this) { 2020 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2021 TaskRecord tr = mRecentTasks.get(i); 2022 if (tr.userId != eventUserId) continue; 2023 2024 ComponentName cn = tr.intent.getComponent(); 2025 if (cn != null && cn.getPackageName().equals(packageName)) { 2026 // If the package name matches, remove the task and kill the process 2027 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 2028 } 2029 } 2030 } 2031 } 2032 2033 @Override 2034 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2035 onPackageModified(packageName); 2036 return true; 2037 } 2038 2039 @Override 2040 public void onPackageModified(String packageName) { 2041 final int eventUserId = getChangingUserId(); 2042 final IPackageManager pm = AppGlobals.getPackageManager(); 2043 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2044 new ArrayList<Pair<Intent, Integer>>(); 2045 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); 2046 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2047 // Copy the list of recent tasks so that we don't hold onto the lock on 2048 // ActivityManagerService for long periods while checking if components exist. 2049 synchronized (ActivityManagerService.this) { 2050 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2051 TaskRecord tr = mRecentTasks.get(i); 2052 if (tr.userId != eventUserId) continue; 2053 2054 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2055 } 2056 } 2057 // Check the recent tasks and filter out all tasks with components that no longer exist. 2058 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2059 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2060 ComponentName cn = p.first.getComponent(); 2061 if (cn != null && cn.getPackageName().equals(packageName)) { 2062 if (componentsKnownToExist.contains(cn)) { 2063 // If we know that the component still exists in the package, then skip 2064 continue; 2065 } 2066 try { 2067 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId); 2068 if (info != null) { 2069 componentsKnownToExist.add(cn); 2070 } else { 2071 tasksToRemove.add(p.second); 2072 } 2073 } catch (RemoteException e) { 2074 Log.e(TAG, "Failed to query activity info for component: " + cn, e); 2075 } 2076 } 2077 } 2078 // Prune all the tasks with removed components from the list of recent tasks 2079 synchronized (ActivityManagerService.this) { 2080 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2081 // Remove the task but don't kill the process (since other components in that 2082 // package may still be running and in the background) 2083 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2084 } 2085 } 2086 } 2087 2088 @Override 2089 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2090 // Force stop the specified packages 2091 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 2092 if (packages != null) { 2093 for (String pkg : packages) { 2094 synchronized (ActivityManagerService.this) { 2095 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 2096 userId, "finished booting")) { 2097 return true; 2098 } 2099 } 2100 } 2101 } 2102 return false; 2103 } 2104 }; 2105 2106 public void setSystemProcess() { 2107 try { 2108 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2109 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2110 ServiceManager.addService("meminfo", new MemBinder(this)); 2111 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2112 ServiceManager.addService("dbinfo", new DbBinder(this)); 2113 if (MONITOR_CPU_USAGE) { 2114 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2115 } 2116 ServiceManager.addService("permission", new PermissionController(this)); 2117 2118 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2119 "android", STOCK_PM_FLAGS); 2120 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2121 2122 synchronized (this) { 2123 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2124 app.persistent = true; 2125 app.pid = MY_PID; 2126 app.maxAdj = ProcessList.SYSTEM_ADJ; 2127 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2128 mProcessNames.put(app.processName, app.uid, app); 2129 synchronized (mPidsSelfLocked) { 2130 mPidsSelfLocked.put(app.pid, app); 2131 } 2132 updateLruProcessLocked(app, false, null); 2133 updateOomAdjLocked(); 2134 } 2135 } catch (PackageManager.NameNotFoundException e) { 2136 throw new RuntimeException( 2137 "Unable to find android system package", e); 2138 } 2139 } 2140 2141 public void setWindowManager(WindowManagerService wm) { 2142 mWindowManager = wm; 2143 mStackSupervisor.setWindowManager(wm); 2144 } 2145 2146 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2147 mUsageStatsService = usageStatsManager; 2148 } 2149 2150 public void startObservingNativeCrashes() { 2151 final NativeCrashListener ncl = new NativeCrashListener(this); 2152 ncl.start(); 2153 } 2154 2155 public IAppOpsService getAppOpsService() { 2156 return mAppOpsService; 2157 } 2158 2159 static class MemBinder extends Binder { 2160 ActivityManagerService mActivityManagerService; 2161 MemBinder(ActivityManagerService activityManagerService) { 2162 mActivityManagerService = activityManagerService; 2163 } 2164 2165 @Override 2166 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2167 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2168 != PackageManager.PERMISSION_GRANTED) { 2169 pw.println("Permission Denial: can't dump meminfo from from pid=" 2170 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2171 + " without permission " + android.Manifest.permission.DUMP); 2172 return; 2173 } 2174 2175 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2176 } 2177 } 2178 2179 static class GraphicsBinder extends Binder { 2180 ActivityManagerService mActivityManagerService; 2181 GraphicsBinder(ActivityManagerService activityManagerService) { 2182 mActivityManagerService = activityManagerService; 2183 } 2184 2185 @Override 2186 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2187 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2188 != PackageManager.PERMISSION_GRANTED) { 2189 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2190 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2191 + " without permission " + android.Manifest.permission.DUMP); 2192 return; 2193 } 2194 2195 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2196 } 2197 } 2198 2199 static class DbBinder extends Binder { 2200 ActivityManagerService mActivityManagerService; 2201 DbBinder(ActivityManagerService activityManagerService) { 2202 mActivityManagerService = activityManagerService; 2203 } 2204 2205 @Override 2206 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2207 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2208 != PackageManager.PERMISSION_GRANTED) { 2209 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2210 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2211 + " without permission " + android.Manifest.permission.DUMP); 2212 return; 2213 } 2214 2215 mActivityManagerService.dumpDbInfo(fd, pw, args); 2216 } 2217 } 2218 2219 static class CpuBinder extends Binder { 2220 ActivityManagerService mActivityManagerService; 2221 CpuBinder(ActivityManagerService activityManagerService) { 2222 mActivityManagerService = activityManagerService; 2223 } 2224 2225 @Override 2226 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2227 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2228 != PackageManager.PERMISSION_GRANTED) { 2229 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2230 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2231 + " without permission " + android.Manifest.permission.DUMP); 2232 return; 2233 } 2234 2235 synchronized (mActivityManagerService.mProcessCpuTracker) { 2236 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2237 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2238 SystemClock.uptimeMillis())); 2239 } 2240 } 2241 } 2242 2243 public static final class Lifecycle extends SystemService { 2244 private final ActivityManagerService mService; 2245 2246 public Lifecycle(Context context) { 2247 super(context); 2248 mService = new ActivityManagerService(context); 2249 } 2250 2251 @Override 2252 public void onStart() { 2253 mService.start(); 2254 } 2255 2256 public ActivityManagerService getService() { 2257 return mService; 2258 } 2259 } 2260 2261 // Note: This method is invoked on the main thread but may need to attach various 2262 // handlers to other threads. So take care to be explicit about the looper. 2263 public ActivityManagerService(Context systemContext) { 2264 mContext = systemContext; 2265 mFactoryTest = FactoryTest.getMode(); 2266 mSystemThread = ActivityThread.currentActivityThread(); 2267 2268 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2269 2270 mHandlerThread = new ServiceThread(TAG, 2271 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2272 mHandlerThread.start(); 2273 mHandler = new MainHandler(mHandlerThread.getLooper()); 2274 2275 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2276 "foreground", BROADCAST_FG_TIMEOUT, false); 2277 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2278 "background", BROADCAST_BG_TIMEOUT, true); 2279 mBroadcastQueues[0] = mFgBroadcastQueue; 2280 mBroadcastQueues[1] = mBgBroadcastQueue; 2281 2282 mServices = new ActiveServices(this); 2283 mProviderMap = new ProviderMap(this); 2284 2285 // TODO: Move creation of battery stats service outside of activity manager service. 2286 File dataDir = Environment.getDataDirectory(); 2287 File systemDir = new File(dataDir, "system"); 2288 systemDir.mkdirs(); 2289 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2290 mBatteryStatsService.getActiveStatistics().readLocked(); 2291 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2292 mOnBattery = DEBUG_POWER ? true 2293 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2294 mBatteryStatsService.getActiveStatistics().setCallback(this); 2295 2296 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2297 2298 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2299 2300 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2301 2302 // User 0 is the first and only user that runs at boot. 2303 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2304 mUserLru.add(Integer.valueOf(0)); 2305 updateStartedUserArrayLocked(); 2306 2307 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2308 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2309 2310 mConfiguration.setToDefaults(); 2311 mConfiguration.setLocale(Locale.getDefault()); 2312 2313 mConfigurationSeq = mConfiguration.seq = 1; 2314 mProcessCpuTracker.init(); 2315 2316 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2317 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2318 mStackSupervisor = new ActivityStackSupervisor(this); 2319 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2320 2321 mProcessCpuThread = new Thread("CpuTracker") { 2322 @Override 2323 public void run() { 2324 while (true) { 2325 try { 2326 try { 2327 synchronized(this) { 2328 final long now = SystemClock.uptimeMillis(); 2329 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2330 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2331 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2332 // + ", write delay=" + nextWriteDelay); 2333 if (nextWriteDelay < nextCpuDelay) { 2334 nextCpuDelay = nextWriteDelay; 2335 } 2336 if (nextCpuDelay > 0) { 2337 mProcessCpuMutexFree.set(true); 2338 this.wait(nextCpuDelay); 2339 } 2340 } 2341 } catch (InterruptedException e) { 2342 } 2343 updateCpuStatsNow(); 2344 } catch (Exception e) { 2345 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2346 } 2347 } 2348 } 2349 }; 2350 2351 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2352 2353 Watchdog.getInstance().addMonitor(this); 2354 Watchdog.getInstance().addThread(mHandler); 2355 } 2356 2357 public void setSystemServiceManager(SystemServiceManager mgr) { 2358 mSystemServiceManager = mgr; 2359 } 2360 2361 private void start() { 2362 Process.removeAllProcessGroups(); 2363 mProcessCpuThread.start(); 2364 2365 mBatteryStatsService.publish(mContext); 2366 mAppOpsService.publish(mContext); 2367 Slog.d("AppOps", "AppOpsService published"); 2368 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2369 } 2370 2371 public void initPowerManagement() { 2372 mStackSupervisor.initPowerManagement(); 2373 mBatteryStatsService.initPowerManagement(); 2374 } 2375 2376 @Override 2377 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2378 throws RemoteException { 2379 if (code == SYSPROPS_TRANSACTION) { 2380 // We need to tell all apps about the system property change. 2381 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2382 synchronized(this) { 2383 final int NP = mProcessNames.getMap().size(); 2384 for (int ip=0; ip<NP; ip++) { 2385 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2386 final int NA = apps.size(); 2387 for (int ia=0; ia<NA; ia++) { 2388 ProcessRecord app = apps.valueAt(ia); 2389 if (app.thread != null) { 2390 procs.add(app.thread.asBinder()); 2391 } 2392 } 2393 } 2394 } 2395 2396 int N = procs.size(); 2397 for (int i=0; i<N; i++) { 2398 Parcel data2 = Parcel.obtain(); 2399 try { 2400 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2401 } catch (RemoteException e) { 2402 } 2403 data2.recycle(); 2404 } 2405 } 2406 try { 2407 return super.onTransact(code, data, reply, flags); 2408 } catch (RuntimeException e) { 2409 // The activity manager only throws security exceptions, so let's 2410 // log all others. 2411 if (!(e instanceof SecurityException)) { 2412 Slog.wtf(TAG, "Activity Manager Crash", e); 2413 } 2414 throw e; 2415 } 2416 } 2417 2418 void updateCpuStats() { 2419 final long now = SystemClock.uptimeMillis(); 2420 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2421 return; 2422 } 2423 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2424 synchronized (mProcessCpuThread) { 2425 mProcessCpuThread.notify(); 2426 } 2427 } 2428 } 2429 2430 void updateCpuStatsNow() { 2431 synchronized (mProcessCpuTracker) { 2432 mProcessCpuMutexFree.set(false); 2433 final long now = SystemClock.uptimeMillis(); 2434 boolean haveNewCpuStats = false; 2435 2436 if (MONITOR_CPU_USAGE && 2437 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2438 mLastCpuTime.set(now); 2439 haveNewCpuStats = true; 2440 mProcessCpuTracker.update(); 2441 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2442 //Slog.i(TAG, "Total CPU usage: " 2443 // + mProcessCpu.getTotalCpuPercent() + "%"); 2444 2445 // Slog the cpu usage if the property is set. 2446 if ("true".equals(SystemProperties.get("events.cpu"))) { 2447 int user = mProcessCpuTracker.getLastUserTime(); 2448 int system = mProcessCpuTracker.getLastSystemTime(); 2449 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2450 int irq = mProcessCpuTracker.getLastIrqTime(); 2451 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2452 int idle = mProcessCpuTracker.getLastIdleTime(); 2453 2454 int total = user + system + iowait + irq + softIrq + idle; 2455 if (total == 0) total = 1; 2456 2457 EventLog.writeEvent(EventLogTags.CPU, 2458 ((user+system+iowait+irq+softIrq) * 100) / total, 2459 (user * 100) / total, 2460 (system * 100) / total, 2461 (iowait * 100) / total, 2462 (irq * 100) / total, 2463 (softIrq * 100) / total); 2464 } 2465 } 2466 2467 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2468 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2469 synchronized(bstats) { 2470 synchronized(mPidsSelfLocked) { 2471 if (haveNewCpuStats) { 2472 if (mOnBattery) { 2473 int perc = bstats.startAddingCpuLocked(); 2474 int totalUTime = 0; 2475 int totalSTime = 0; 2476 final int N = mProcessCpuTracker.countStats(); 2477 for (int i=0; i<N; i++) { 2478 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2479 if (!st.working) { 2480 continue; 2481 } 2482 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2483 int otherUTime = (st.rel_utime*perc)/100; 2484 int otherSTime = (st.rel_stime*perc)/100; 2485 totalUTime += otherUTime; 2486 totalSTime += otherSTime; 2487 if (pr != null) { 2488 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2489 if (ps == null || !ps.isActive()) { 2490 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2491 pr.info.uid, pr.processName); 2492 } 2493 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2494 st.rel_stime-otherSTime); 2495 ps.addSpeedStepTimes(cpuSpeedTimes); 2496 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2497 } else { 2498 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2499 if (ps == null || !ps.isActive()) { 2500 st.batteryStats = ps = bstats.getProcessStatsLocked( 2501 bstats.mapUid(st.uid), st.name); 2502 } 2503 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2504 st.rel_stime-otherSTime); 2505 ps.addSpeedStepTimes(cpuSpeedTimes); 2506 } 2507 } 2508 bstats.finishAddingCpuLocked(perc, totalUTime, 2509 totalSTime, cpuSpeedTimes); 2510 } 2511 } 2512 } 2513 2514 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2515 mLastWriteTime = now; 2516 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2517 } 2518 } 2519 } 2520 } 2521 2522 @Override 2523 public void batteryNeedsCpuUpdate() { 2524 updateCpuStatsNow(); 2525 } 2526 2527 @Override 2528 public void batteryPowerChanged(boolean onBattery) { 2529 // When plugging in, update the CPU stats first before changing 2530 // the plug state. 2531 updateCpuStatsNow(); 2532 synchronized (this) { 2533 synchronized(mPidsSelfLocked) { 2534 mOnBattery = DEBUG_POWER ? true : onBattery; 2535 } 2536 } 2537 } 2538 2539 /** 2540 * Initialize the application bind args. These are passed to each 2541 * process when the bindApplication() IPC is sent to the process. They're 2542 * lazily setup to make sure the services are running when they're asked for. 2543 */ 2544 private HashMap<String, IBinder> getCommonServicesLocked() { 2545 if (mAppBindArgs == null) { 2546 mAppBindArgs = new HashMap<String, IBinder>(); 2547 2548 // Setup the application init args 2549 mAppBindArgs.put("package", ServiceManager.getService("package")); 2550 mAppBindArgs.put("window", ServiceManager.getService("window")); 2551 mAppBindArgs.put(Context.ALARM_SERVICE, 2552 ServiceManager.getService(Context.ALARM_SERVICE)); 2553 } 2554 return mAppBindArgs; 2555 } 2556 2557 final void setFocusedActivityLocked(ActivityRecord r) { 2558 if (mFocusedActivity != r) { 2559 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2560 mFocusedActivity = r; 2561 if (r.task != null && r.task.voiceInteractor != null) { 2562 startRunningVoiceLocked(); 2563 } else { 2564 finishRunningVoiceLocked(); 2565 } 2566 mStackSupervisor.setFocusedStack(r); 2567 if (r != null) { 2568 mWindowManager.setFocusedApp(r.appToken, true); 2569 } 2570 applyUpdateLockStateLocked(r); 2571 } 2572 } 2573 2574 final void clearFocusedActivity(ActivityRecord r) { 2575 if (mFocusedActivity == r) { 2576 mFocusedActivity = null; 2577 } 2578 } 2579 2580 @Override 2581 public void setFocusedStack(int stackId) { 2582 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2583 synchronized (ActivityManagerService.this) { 2584 ActivityStack stack = mStackSupervisor.getStack(stackId); 2585 if (stack != null) { 2586 ActivityRecord r = stack.topRunningActivityLocked(null); 2587 if (r != null) { 2588 setFocusedActivityLocked(r); 2589 } 2590 } 2591 } 2592 } 2593 2594 @Override 2595 public void notifyActivityDrawn(IBinder token) { 2596 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2597 synchronized (this) { 2598 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2599 if (r != null) { 2600 r.task.stack.notifyActivityDrawnLocked(r); 2601 } 2602 } 2603 } 2604 2605 final void applyUpdateLockStateLocked(ActivityRecord r) { 2606 // Modifications to the UpdateLock state are done on our handler, outside 2607 // the activity manager's locks. The new state is determined based on the 2608 // state *now* of the relevant activity record. The object is passed to 2609 // the handler solely for logging detail, not to be consulted/modified. 2610 final boolean nextState = r != null && r.immersive; 2611 mHandler.sendMessage( 2612 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2613 } 2614 2615 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2616 Message msg = Message.obtain(); 2617 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2618 msg.obj = r.task.askedCompatMode ? null : r; 2619 mHandler.sendMessage(msg); 2620 } 2621 2622 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2623 String what, Object obj, ProcessRecord srcApp) { 2624 app.lastActivityTime = now; 2625 2626 if (app.activities.size() > 0) { 2627 // Don't want to touch dependent processes that are hosting activities. 2628 return index; 2629 } 2630 2631 int lrui = mLruProcesses.lastIndexOf(app); 2632 if (lrui < 0) { 2633 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2634 + what + " " + obj + " from " + srcApp); 2635 return index; 2636 } 2637 2638 if (lrui >= index) { 2639 // Don't want to cause this to move dependent processes *back* in the 2640 // list as if they were less frequently used. 2641 return index; 2642 } 2643 2644 if (lrui >= mLruProcessActivityStart) { 2645 // Don't want to touch dependent processes that are hosting activities. 2646 return index; 2647 } 2648 2649 mLruProcesses.remove(lrui); 2650 if (index > 0) { 2651 index--; 2652 } 2653 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2654 + " in LRU list: " + app); 2655 mLruProcesses.add(index, app); 2656 return index; 2657 } 2658 2659 final void removeLruProcessLocked(ProcessRecord app) { 2660 int lrui = mLruProcesses.lastIndexOf(app); 2661 if (lrui >= 0) { 2662 if (!app.killed) { 2663 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2664 Process.killProcessQuiet(app.pid); 2665 Process.killProcessGroup(app.info.uid, app.pid); 2666 } 2667 if (lrui <= mLruProcessActivityStart) { 2668 mLruProcessActivityStart--; 2669 } 2670 if (lrui <= mLruProcessServiceStart) { 2671 mLruProcessServiceStart--; 2672 } 2673 mLruProcesses.remove(lrui); 2674 } 2675 } 2676 2677 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2678 ProcessRecord client) { 2679 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2680 || app.treatLikeActivity; 2681 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2682 if (!activityChange && hasActivity) { 2683 // The process has activities, so we are only allowing activity-based adjustments 2684 // to move it. It should be kept in the front of the list with other 2685 // processes that have activities, and we don't want those to change their 2686 // order except due to activity operations. 2687 return; 2688 } 2689 2690 mLruSeq++; 2691 final long now = SystemClock.uptimeMillis(); 2692 app.lastActivityTime = now; 2693 2694 // First a quick reject: if the app is already at the position we will 2695 // put it, then there is nothing to do. 2696 if (hasActivity) { 2697 final int N = mLruProcesses.size(); 2698 if (N > 0 && mLruProcesses.get(N-1) == app) { 2699 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2700 return; 2701 } 2702 } else { 2703 if (mLruProcessServiceStart > 0 2704 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2705 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2706 return; 2707 } 2708 } 2709 2710 int lrui = mLruProcesses.lastIndexOf(app); 2711 2712 if (app.persistent && lrui >= 0) { 2713 // We don't care about the position of persistent processes, as long as 2714 // they are in the list. 2715 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2716 return; 2717 } 2718 2719 /* In progress: compute new position first, so we can avoid doing work 2720 if the process is not actually going to move. Not yet working. 2721 int addIndex; 2722 int nextIndex; 2723 boolean inActivity = false, inService = false; 2724 if (hasActivity) { 2725 // Process has activities, put it at the very tipsy-top. 2726 addIndex = mLruProcesses.size(); 2727 nextIndex = mLruProcessServiceStart; 2728 inActivity = true; 2729 } else if (hasService) { 2730 // Process has services, put it at the top of the service list. 2731 addIndex = mLruProcessActivityStart; 2732 nextIndex = mLruProcessServiceStart; 2733 inActivity = true; 2734 inService = true; 2735 } else { 2736 // Process not otherwise of interest, it goes to the top of the non-service area. 2737 addIndex = mLruProcessServiceStart; 2738 if (client != null) { 2739 int clientIndex = mLruProcesses.lastIndexOf(client); 2740 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2741 + app); 2742 if (clientIndex >= 0 && addIndex > clientIndex) { 2743 addIndex = clientIndex; 2744 } 2745 } 2746 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2747 } 2748 2749 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2750 + mLruProcessActivityStart + "): " + app); 2751 */ 2752 2753 if (lrui >= 0) { 2754 if (lrui < mLruProcessActivityStart) { 2755 mLruProcessActivityStart--; 2756 } 2757 if (lrui < mLruProcessServiceStart) { 2758 mLruProcessServiceStart--; 2759 } 2760 /* 2761 if (addIndex > lrui) { 2762 addIndex--; 2763 } 2764 if (nextIndex > lrui) { 2765 nextIndex--; 2766 } 2767 */ 2768 mLruProcesses.remove(lrui); 2769 } 2770 2771 /* 2772 mLruProcesses.add(addIndex, app); 2773 if (inActivity) { 2774 mLruProcessActivityStart++; 2775 } 2776 if (inService) { 2777 mLruProcessActivityStart++; 2778 } 2779 */ 2780 2781 int nextIndex; 2782 if (hasActivity) { 2783 final int N = mLruProcesses.size(); 2784 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2785 // Process doesn't have activities, but has clients with 2786 // activities... move it up, but one below the top (the top 2787 // should always have a real activity). 2788 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2789 mLruProcesses.add(N-1, app); 2790 // To keep it from spamming the LRU list (by making a bunch of clients), 2791 // we will push down any other entries owned by the app. 2792 final int uid = app.info.uid; 2793 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2794 ProcessRecord subProc = mLruProcesses.get(i); 2795 if (subProc.info.uid == uid) { 2796 // We want to push this one down the list. If the process after 2797 // it is for the same uid, however, don't do so, because we don't 2798 // want them internally to be re-ordered. 2799 if (mLruProcesses.get(i-1).info.uid != uid) { 2800 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2801 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2802 ProcessRecord tmp = mLruProcesses.get(i); 2803 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2804 mLruProcesses.set(i-1, tmp); 2805 i--; 2806 } 2807 } else { 2808 // A gap, we can stop here. 2809 break; 2810 } 2811 } 2812 } else { 2813 // Process has activities, put it at the very tipsy-top. 2814 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2815 mLruProcesses.add(app); 2816 } 2817 nextIndex = mLruProcessServiceStart; 2818 } else if (hasService) { 2819 // Process has services, put it at the top of the service list. 2820 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2821 mLruProcesses.add(mLruProcessActivityStart, app); 2822 nextIndex = mLruProcessServiceStart; 2823 mLruProcessActivityStart++; 2824 } else { 2825 // Process not otherwise of interest, it goes to the top of the non-service area. 2826 int index = mLruProcessServiceStart; 2827 if (client != null) { 2828 // If there is a client, don't allow the process to be moved up higher 2829 // in the list than that client. 2830 int clientIndex = mLruProcesses.lastIndexOf(client); 2831 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2832 + " when updating " + app); 2833 if (clientIndex <= lrui) { 2834 // Don't allow the client index restriction to push it down farther in the 2835 // list than it already is. 2836 clientIndex = lrui; 2837 } 2838 if (clientIndex >= 0 && index > clientIndex) { 2839 index = clientIndex; 2840 } 2841 } 2842 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2843 mLruProcesses.add(index, app); 2844 nextIndex = index-1; 2845 mLruProcessActivityStart++; 2846 mLruProcessServiceStart++; 2847 } 2848 2849 // If the app is currently using a content provider or service, 2850 // bump those processes as well. 2851 for (int j=app.connections.size()-1; j>=0; j--) { 2852 ConnectionRecord cr = app.connections.valueAt(j); 2853 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2854 && cr.binding.service.app != null 2855 && cr.binding.service.app.lruSeq != mLruSeq 2856 && !cr.binding.service.app.persistent) { 2857 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2858 "service connection", cr, app); 2859 } 2860 } 2861 for (int j=app.conProviders.size()-1; j>=0; j--) { 2862 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2863 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2864 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2865 "provider reference", cpr, app); 2866 } 2867 } 2868 } 2869 2870 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2871 if (uid == Process.SYSTEM_UID) { 2872 // The system gets to run in any process. If there are multiple 2873 // processes with the same uid, just pick the first (this 2874 // should never happen). 2875 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2876 if (procs == null) return null; 2877 final int N = procs.size(); 2878 for (int i = 0; i < N; i++) { 2879 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2880 } 2881 } 2882 ProcessRecord proc = mProcessNames.get(processName, uid); 2883 if (false && proc != null && !keepIfLarge 2884 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2885 && proc.lastCachedPss >= 4000) { 2886 // Turn this condition on to cause killing to happen regularly, for testing. 2887 if (proc.baseProcessTracker != null) { 2888 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2889 } 2890 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2891 } else if (proc != null && !keepIfLarge 2892 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2893 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2894 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2895 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2896 if (proc.baseProcessTracker != null) { 2897 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2898 } 2899 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2900 } 2901 } 2902 return proc; 2903 } 2904 2905 void ensurePackageDexOpt(String packageName) { 2906 IPackageManager pm = AppGlobals.getPackageManager(); 2907 try { 2908 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2909 mDidDexOpt = true; 2910 } 2911 } catch (RemoteException e) { 2912 } 2913 } 2914 2915 boolean isNextTransitionForward() { 2916 int transit = mWindowManager.getPendingAppTransition(); 2917 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2918 || transit == AppTransition.TRANSIT_TASK_OPEN 2919 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2920 } 2921 2922 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2923 String processName, String abiOverride, int uid, Runnable crashHandler) { 2924 synchronized(this) { 2925 ApplicationInfo info = new ApplicationInfo(); 2926 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2927 // For isolated processes, the former contains the parent's uid and the latter the 2928 // actual uid of the isolated process. 2929 // In the special case introduced by this method (which is, starting an isolated 2930 // process directly from the SystemServer without an actual parent app process) the 2931 // closest thing to a parent's uid is SYSTEM_UID. 2932 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2933 // the |isolated| logic in the ProcessRecord constructor. 2934 info.uid = Process.SYSTEM_UID; 2935 info.processName = processName; 2936 info.className = entryPoint; 2937 info.packageName = "android"; 2938 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2939 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2940 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2941 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2942 crashHandler); 2943 return proc != null ? proc.pid : 0; 2944 } 2945 } 2946 2947 final ProcessRecord startProcessLocked(String processName, 2948 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2949 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2950 boolean isolated, boolean keepIfLarge) { 2951 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2952 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2953 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2954 null /* crashHandler */); 2955 } 2956 2957 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2958 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2959 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2960 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2961 long startTime = SystemClock.elapsedRealtime(); 2962 ProcessRecord app; 2963 if (!isolated) { 2964 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2965 checkTime(startTime, "startProcess: after getProcessRecord"); 2966 } else { 2967 // If this is an isolated process, it can't re-use an existing process. 2968 app = null; 2969 } 2970 // We don't have to do anything more if: 2971 // (1) There is an existing application record; and 2972 // (2) The caller doesn't think it is dead, OR there is no thread 2973 // object attached to it so we know it couldn't have crashed; and 2974 // (3) There is a pid assigned to it, so it is either starting or 2975 // already running. 2976 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2977 + " app=" + app + " knownToBeDead=" + knownToBeDead 2978 + " thread=" + (app != null ? app.thread : null) 2979 + " pid=" + (app != null ? app.pid : -1)); 2980 if (app != null && app.pid > 0) { 2981 if (!knownToBeDead || app.thread == null) { 2982 // We already have the app running, or are waiting for it to 2983 // come up (we have a pid but not yet its thread), so keep it. 2984 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2985 // If this is a new package in the process, add the package to the list 2986 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2987 checkTime(startTime, "startProcess: done, added package to proc"); 2988 return app; 2989 } 2990 2991 // An application record is attached to a previous process, 2992 // clean it up now. 2993 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2994 checkTime(startTime, "startProcess: bad proc running, killing"); 2995 Process.killProcessGroup(app.info.uid, app.pid); 2996 handleAppDiedLocked(app, true, true); 2997 checkTime(startTime, "startProcess: done killing old proc"); 2998 } 2999 3000 String hostingNameStr = hostingName != null 3001 ? hostingName.flattenToShortString() : null; 3002 3003 if (!isolated) { 3004 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 3005 // If we are in the background, then check to see if this process 3006 // is bad. If so, we will just silently fail. 3007 if (mBadProcesses.get(info.processName, info.uid) != null) { 3008 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3009 + "/" + info.processName); 3010 return null; 3011 } 3012 } else { 3013 // When the user is explicitly starting a process, then clear its 3014 // crash count so that we won't make it bad until they see at 3015 // least one crash dialog again, and make the process good again 3016 // if it had been bad. 3017 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3018 + "/" + info.processName); 3019 mProcessCrashTimes.remove(info.processName, info.uid); 3020 if (mBadProcesses.get(info.processName, info.uid) != null) { 3021 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3022 UserHandle.getUserId(info.uid), info.uid, 3023 info.processName); 3024 mBadProcesses.remove(info.processName, info.uid); 3025 if (app != null) { 3026 app.bad = false; 3027 } 3028 } 3029 } 3030 } 3031 3032 if (app == null) { 3033 checkTime(startTime, "startProcess: creating new process record"); 3034 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3035 app.crashHandler = crashHandler; 3036 if (app == null) { 3037 Slog.w(TAG, "Failed making new process record for " 3038 + processName + "/" + info.uid + " isolated=" + isolated); 3039 return null; 3040 } 3041 mProcessNames.put(processName, app.uid, app); 3042 if (isolated) { 3043 mIsolatedProcesses.put(app.uid, app); 3044 } 3045 checkTime(startTime, "startProcess: done creating new process record"); 3046 } else { 3047 // If this is a new package in the process, add the package to the list 3048 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3049 checkTime(startTime, "startProcess: added package to existing proc"); 3050 } 3051 3052 // If the system is not ready yet, then hold off on starting this 3053 // process until it is. 3054 if (!mProcessesReady 3055 && !isAllowedWhileBooting(info) 3056 && !allowWhileBooting) { 3057 if (!mProcessesOnHold.contains(app)) { 3058 mProcessesOnHold.add(app); 3059 } 3060 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3061 checkTime(startTime, "startProcess: returning with proc on hold"); 3062 return app; 3063 } 3064 3065 checkTime(startTime, "startProcess: stepping in to startProcess"); 3066 startProcessLocked( 3067 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3068 checkTime(startTime, "startProcess: done starting proc!"); 3069 return (app.pid != 0) ? app : null; 3070 } 3071 3072 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3073 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3074 } 3075 3076 private final void startProcessLocked(ProcessRecord app, 3077 String hostingType, String hostingNameStr) { 3078 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3079 null /* entryPoint */, null /* entryPointArgs */); 3080 } 3081 3082 private final void startProcessLocked(ProcessRecord app, String hostingType, 3083 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3084 long startTime = SystemClock.elapsedRealtime(); 3085 if (app.pid > 0 && app.pid != MY_PID) { 3086 checkTime(startTime, "startProcess: removing from pids map"); 3087 synchronized (mPidsSelfLocked) { 3088 mPidsSelfLocked.remove(app.pid); 3089 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3090 } 3091 checkTime(startTime, "startProcess: done removing from pids map"); 3092 app.setPid(0); 3093 } 3094 3095 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3096 "startProcessLocked removing on hold: " + app); 3097 mProcessesOnHold.remove(app); 3098 3099 checkTime(startTime, "startProcess: starting to update cpu stats"); 3100 updateCpuStats(); 3101 checkTime(startTime, "startProcess: done updating cpu stats"); 3102 3103 try { 3104 int uid = app.uid; 3105 3106 int[] gids = null; 3107 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3108 if (!app.isolated) { 3109 int[] permGids = null; 3110 try { 3111 checkTime(startTime, "startProcess: getting gids from package manager"); 3112 final PackageManager pm = mContext.getPackageManager(); 3113 permGids = pm.getPackageGids(app.info.packageName); 3114 3115 if (Environment.isExternalStorageEmulated()) { 3116 checkTime(startTime, "startProcess: checking external storage perm"); 3117 if (pm.checkPermission( 3118 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3119 app.info.packageName) == PERMISSION_GRANTED) { 3120 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3121 } else { 3122 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3123 } 3124 } 3125 } catch (PackageManager.NameNotFoundException e) { 3126 Slog.w(TAG, "Unable to retrieve gids", e); 3127 } 3128 3129 /* 3130 * Add shared application and profile GIDs so applications can share some 3131 * resources like shared libraries and access user-wide resources 3132 */ 3133 if (permGids == null) { 3134 gids = new int[2]; 3135 } else { 3136 gids = new int[permGids.length + 2]; 3137 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3138 } 3139 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3140 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3141 } 3142 checkTime(startTime, "startProcess: building args"); 3143 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3144 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3145 && mTopComponent != null 3146 && app.processName.equals(mTopComponent.getPackageName())) { 3147 uid = 0; 3148 } 3149 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3150 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3151 uid = 0; 3152 } 3153 } 3154 int debugFlags = 0; 3155 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3156 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3157 // Also turn on CheckJNI for debuggable apps. It's quite 3158 // awkward to turn on otherwise. 3159 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3160 } 3161 // Run the app in safe mode if its manifest requests so or the 3162 // system is booted in safe mode. 3163 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3164 mSafeMode == true) { 3165 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3166 } 3167 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3168 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3169 } 3170 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3171 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3172 } 3173 if ("1".equals(SystemProperties.get("debug.assert"))) { 3174 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3175 } 3176 3177 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3178 if (requiredAbi == null) { 3179 requiredAbi = Build.SUPPORTED_ABIS[0]; 3180 } 3181 3182 String instructionSet = null; 3183 if (app.info.primaryCpuAbi != null) { 3184 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3185 } 3186 3187 // Start the process. It will either succeed and return a result containing 3188 // the PID of the new process, or else throw a RuntimeException. 3189 boolean isActivityProcess = (entryPoint == null); 3190 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3191 checkTime(startTime, "startProcess: asking zygote to start proc"); 3192 Process.ProcessStartResult startResult = Process.start(entryPoint, 3193 app.processName, uid, uid, gids, debugFlags, mountExternal, 3194 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3195 app.info.dataDir, entryPointArgs); 3196 checkTime(startTime, "startProcess: returned from zygote!"); 3197 3198 if (app.isolated) { 3199 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3200 } 3201 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3202 checkTime(startTime, "startProcess: done updating battery stats"); 3203 3204 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3205 UserHandle.getUserId(uid), startResult.pid, uid, 3206 app.processName, hostingType, 3207 hostingNameStr != null ? hostingNameStr : ""); 3208 3209 if (app.persistent) { 3210 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3211 } 3212 3213 checkTime(startTime, "startProcess: building log message"); 3214 StringBuilder buf = mStringBuilder; 3215 buf.setLength(0); 3216 buf.append("Start proc "); 3217 buf.append(app.processName); 3218 if (!isActivityProcess) { 3219 buf.append(" ["); 3220 buf.append(entryPoint); 3221 buf.append("]"); 3222 } 3223 buf.append(" for "); 3224 buf.append(hostingType); 3225 if (hostingNameStr != null) { 3226 buf.append(" "); 3227 buf.append(hostingNameStr); 3228 } 3229 buf.append(": pid="); 3230 buf.append(startResult.pid); 3231 buf.append(" uid="); 3232 buf.append(uid); 3233 buf.append(" gids={"); 3234 if (gids != null) { 3235 for (int gi=0; gi<gids.length; gi++) { 3236 if (gi != 0) buf.append(", "); 3237 buf.append(gids[gi]); 3238 3239 } 3240 } 3241 buf.append("}"); 3242 if (requiredAbi != null) { 3243 buf.append(" abi="); 3244 buf.append(requiredAbi); 3245 } 3246 Slog.i(TAG, buf.toString()); 3247 app.setPid(startResult.pid); 3248 app.usingWrapper = startResult.usingWrapper; 3249 app.removed = false; 3250 app.killed = false; 3251 app.killedByAm = false; 3252 checkTime(startTime, "startProcess: starting to update pids map"); 3253 synchronized (mPidsSelfLocked) { 3254 this.mPidsSelfLocked.put(startResult.pid, app); 3255 if (isActivityProcess) { 3256 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3257 msg.obj = app; 3258 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3259 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3260 } 3261 } 3262 checkTime(startTime, "startProcess: done updating pids map"); 3263 } catch (RuntimeException e) { 3264 // XXX do better error recovery. 3265 app.setPid(0); 3266 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3267 if (app.isolated) { 3268 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3269 } 3270 Slog.e(TAG, "Failure starting process " + app.processName, e); 3271 } 3272 } 3273 3274 void updateUsageStats(ActivityRecord component, boolean resumed) { 3275 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3276 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3277 if (resumed) { 3278 if (mUsageStatsService != null) { 3279 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3280 UsageEvents.Event.MOVE_TO_FOREGROUND); 3281 } 3282 synchronized (stats) { 3283 stats.noteActivityResumedLocked(component.app.uid); 3284 } 3285 } else { 3286 if (mUsageStatsService != null) { 3287 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3288 UsageEvents.Event.MOVE_TO_BACKGROUND); 3289 } 3290 synchronized (stats) { 3291 stats.noteActivityPausedLocked(component.app.uid); 3292 } 3293 } 3294 } 3295 3296 Intent getHomeIntent() { 3297 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3298 intent.setComponent(mTopComponent); 3299 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3300 intent.addCategory(Intent.CATEGORY_HOME); 3301 } 3302 return intent; 3303 } 3304 3305 boolean startHomeActivityLocked(int userId) { 3306 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3307 && mTopAction == null) { 3308 // We are running in factory test mode, but unable to find 3309 // the factory test app, so just sit around displaying the 3310 // error message and don't try to start anything. 3311 return false; 3312 } 3313 Intent intent = getHomeIntent(); 3314 ActivityInfo aInfo = 3315 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3316 if (aInfo != null) { 3317 intent.setComponent(new ComponentName( 3318 aInfo.applicationInfo.packageName, aInfo.name)); 3319 // Don't do this if the home app is currently being 3320 // instrumented. 3321 aInfo = new ActivityInfo(aInfo); 3322 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3323 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3324 aInfo.applicationInfo.uid, true); 3325 if (app == null || app.instrumentationClass == null) { 3326 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3327 mStackSupervisor.startHomeActivity(intent, aInfo); 3328 } 3329 } 3330 3331 return true; 3332 } 3333 3334 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3335 ActivityInfo ai = null; 3336 ComponentName comp = intent.getComponent(); 3337 try { 3338 if (comp != null) { 3339 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3340 } else { 3341 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3342 intent, 3343 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3344 flags, userId); 3345 3346 if (info != null) { 3347 ai = info.activityInfo; 3348 } 3349 } 3350 } catch (RemoteException e) { 3351 // ignore 3352 } 3353 3354 return ai; 3355 } 3356 3357 /** 3358 * Starts the "new version setup screen" if appropriate. 3359 */ 3360 void startSetupActivityLocked() { 3361 // Only do this once per boot. 3362 if (mCheckedForSetup) { 3363 return; 3364 } 3365 3366 // We will show this screen if the current one is a different 3367 // version than the last one shown, and we are not running in 3368 // low-level factory test mode. 3369 final ContentResolver resolver = mContext.getContentResolver(); 3370 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3371 Settings.Global.getInt(resolver, 3372 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3373 mCheckedForSetup = true; 3374 3375 // See if we should be showing the platform update setup UI. 3376 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3377 List<ResolveInfo> ris = mContext.getPackageManager() 3378 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3379 3380 // We don't allow third party apps to replace this. 3381 ResolveInfo ri = null; 3382 for (int i=0; ris != null && i<ris.size(); i++) { 3383 if ((ris.get(i).activityInfo.applicationInfo.flags 3384 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3385 ri = ris.get(i); 3386 break; 3387 } 3388 } 3389 3390 if (ri != null) { 3391 String vers = ri.activityInfo.metaData != null 3392 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3393 : null; 3394 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3395 vers = ri.activityInfo.applicationInfo.metaData.getString( 3396 Intent.METADATA_SETUP_VERSION); 3397 } 3398 String lastVers = Settings.Secure.getString( 3399 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3400 if (vers != null && !vers.equals(lastVers)) { 3401 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3402 intent.setComponent(new ComponentName( 3403 ri.activityInfo.packageName, ri.activityInfo.name)); 3404 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3405 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3406 null); 3407 } 3408 } 3409 } 3410 } 3411 3412 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3413 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3414 } 3415 3416 void enforceNotIsolatedCaller(String caller) { 3417 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3418 throw new SecurityException("Isolated process not allowed to call " + caller); 3419 } 3420 } 3421 3422 void enforceShellRestriction(String restriction, int userHandle) { 3423 if (Binder.getCallingUid() == Process.SHELL_UID) { 3424 if (userHandle < 0 3425 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3426 throw new SecurityException("Shell does not have permission to access user " 3427 + userHandle); 3428 } 3429 } 3430 } 3431 3432 @Override 3433 public int getFrontActivityScreenCompatMode() { 3434 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3435 synchronized (this) { 3436 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3437 } 3438 } 3439 3440 @Override 3441 public void setFrontActivityScreenCompatMode(int mode) { 3442 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3443 "setFrontActivityScreenCompatMode"); 3444 synchronized (this) { 3445 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3446 } 3447 } 3448 3449 @Override 3450 public int getPackageScreenCompatMode(String packageName) { 3451 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3452 synchronized (this) { 3453 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3454 } 3455 } 3456 3457 @Override 3458 public void setPackageScreenCompatMode(String packageName, int mode) { 3459 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3460 "setPackageScreenCompatMode"); 3461 synchronized (this) { 3462 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3463 } 3464 } 3465 3466 @Override 3467 public boolean getPackageAskScreenCompat(String packageName) { 3468 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3469 synchronized (this) { 3470 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3471 } 3472 } 3473 3474 @Override 3475 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3476 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3477 "setPackageAskScreenCompat"); 3478 synchronized (this) { 3479 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3480 } 3481 } 3482 3483 private void dispatchProcessesChanged() { 3484 int N; 3485 synchronized (this) { 3486 N = mPendingProcessChanges.size(); 3487 if (mActiveProcessChanges.length < N) { 3488 mActiveProcessChanges = new ProcessChangeItem[N]; 3489 } 3490 mPendingProcessChanges.toArray(mActiveProcessChanges); 3491 mAvailProcessChanges.addAll(mPendingProcessChanges); 3492 mPendingProcessChanges.clear(); 3493 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3494 } 3495 3496 int i = mProcessObservers.beginBroadcast(); 3497 while (i > 0) { 3498 i--; 3499 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3500 if (observer != null) { 3501 try { 3502 for (int j=0; j<N; j++) { 3503 ProcessChangeItem item = mActiveProcessChanges[j]; 3504 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3505 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3506 + item.pid + " uid=" + item.uid + ": " 3507 + item.foregroundActivities); 3508 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3509 item.foregroundActivities); 3510 } 3511 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3512 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3513 + item.pid + " uid=" + item.uid + ": " + item.processState); 3514 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3515 } 3516 } 3517 } catch (RemoteException e) { 3518 } 3519 } 3520 } 3521 mProcessObservers.finishBroadcast(); 3522 } 3523 3524 private void dispatchProcessDied(int pid, int uid) { 3525 int i = mProcessObservers.beginBroadcast(); 3526 while (i > 0) { 3527 i--; 3528 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3529 if (observer != null) { 3530 try { 3531 observer.onProcessDied(pid, uid); 3532 } catch (RemoteException e) { 3533 } 3534 } 3535 } 3536 mProcessObservers.finishBroadcast(); 3537 } 3538 3539 @Override 3540 public final int startActivity(IApplicationThread caller, String callingPackage, 3541 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3542 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3543 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3544 resultWho, requestCode, startFlags, profilerInfo, options, 3545 UserHandle.getCallingUserId()); 3546 } 3547 3548 @Override 3549 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3550 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3551 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3552 enforceNotIsolatedCaller("startActivity"); 3553 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3554 false, ALLOW_FULL_ONLY, "startActivity", null); 3555 // TODO: Switch to user app stacks here. 3556 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3557 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3558 profilerInfo, null, null, options, userId, null, null); 3559 } 3560 3561 @Override 3562 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3563 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3564 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3565 3566 // This is very dangerous -- it allows you to perform a start activity (including 3567 // permission grants) as any app that may launch one of your own activities. So 3568 // we will only allow this to be done from activities that are part of the core framework, 3569 // and then only when they are running as the system. 3570 final ActivityRecord sourceRecord; 3571 final int targetUid; 3572 final String targetPackage; 3573 synchronized (this) { 3574 if (resultTo == null) { 3575 throw new SecurityException("Must be called from an activity"); 3576 } 3577 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3578 if (sourceRecord == null) { 3579 throw new SecurityException("Called with bad activity token: " + resultTo); 3580 } 3581 if (!sourceRecord.info.packageName.equals("android")) { 3582 throw new SecurityException( 3583 "Must be called from an activity that is declared in the android package"); 3584 } 3585 if (sourceRecord.app == null) { 3586 throw new SecurityException("Called without a process attached to activity"); 3587 } 3588 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3589 // This is still okay, as long as this activity is running under the 3590 // uid of the original calling activity. 3591 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3592 throw new SecurityException( 3593 "Calling activity in uid " + sourceRecord.app.uid 3594 + " must be system uid or original calling uid " 3595 + sourceRecord.launchedFromUid); 3596 } 3597 } 3598 targetUid = sourceRecord.launchedFromUid; 3599 targetPackage = sourceRecord.launchedFromPackage; 3600 } 3601 3602 if (userId == UserHandle.USER_NULL) { 3603 userId = UserHandle.getUserId(sourceRecord.app.uid); 3604 } 3605 3606 // TODO: Switch to user app stacks here. 3607 try { 3608 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3609 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3610 null, null, options, userId, null, null); 3611 return ret; 3612 } catch (SecurityException e) { 3613 // XXX need to figure out how to propagate to original app. 3614 // A SecurityException here is generally actually a fault of the original 3615 // calling activity (such as a fairly granting permissions), so propagate it 3616 // back to them. 3617 /* 3618 StringBuilder msg = new StringBuilder(); 3619 msg.append("While launching"); 3620 msg.append(intent.toString()); 3621 msg.append(": "); 3622 msg.append(e.getMessage()); 3623 */ 3624 throw e; 3625 } 3626 } 3627 3628 @Override 3629 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3630 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3631 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3632 enforceNotIsolatedCaller("startActivityAndWait"); 3633 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3634 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3635 WaitResult res = new WaitResult(); 3636 // TODO: Switch to user app stacks here. 3637 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3638 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3639 options, userId, null, null); 3640 return res; 3641 } 3642 3643 @Override 3644 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3645 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3646 int startFlags, Configuration config, Bundle options, int userId) { 3647 enforceNotIsolatedCaller("startActivityWithConfig"); 3648 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3649 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3650 // TODO: Switch to user app stacks here. 3651 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3652 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3653 null, null, config, options, userId, null, null); 3654 return ret; 3655 } 3656 3657 @Override 3658 public int startActivityIntentSender(IApplicationThread caller, 3659 IntentSender intent, Intent fillInIntent, String resolvedType, 3660 IBinder resultTo, String resultWho, int requestCode, 3661 int flagsMask, int flagsValues, Bundle options) { 3662 enforceNotIsolatedCaller("startActivityIntentSender"); 3663 // Refuse possible leaked file descriptors 3664 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3665 throw new IllegalArgumentException("File descriptors passed in Intent"); 3666 } 3667 3668 IIntentSender sender = intent.getTarget(); 3669 if (!(sender instanceof PendingIntentRecord)) { 3670 throw new IllegalArgumentException("Bad PendingIntent object"); 3671 } 3672 3673 PendingIntentRecord pir = (PendingIntentRecord)sender; 3674 3675 synchronized (this) { 3676 // If this is coming from the currently resumed activity, it is 3677 // effectively saying that app switches are allowed at this point. 3678 final ActivityStack stack = getFocusedStack(); 3679 if (stack.mResumedActivity != null && 3680 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3681 mAppSwitchesAllowedTime = 0; 3682 } 3683 } 3684 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3685 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3686 return ret; 3687 } 3688 3689 @Override 3690 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3691 Intent intent, String resolvedType, IVoiceInteractionSession session, 3692 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3693 Bundle options, int userId) { 3694 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3695 != PackageManager.PERMISSION_GRANTED) { 3696 String msg = "Permission Denial: startVoiceActivity() from pid=" 3697 + Binder.getCallingPid() 3698 + ", uid=" + Binder.getCallingUid() 3699 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3700 Slog.w(TAG, msg); 3701 throw new SecurityException(msg); 3702 } 3703 if (session == null || interactor == null) { 3704 throw new NullPointerException("null session or interactor"); 3705 } 3706 userId = handleIncomingUser(callingPid, callingUid, userId, 3707 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3708 // TODO: Switch to user app stacks here. 3709 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3710 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3711 null, options, userId, null, null); 3712 } 3713 3714 @Override 3715 public boolean startNextMatchingActivity(IBinder callingActivity, 3716 Intent intent, Bundle options) { 3717 // Refuse possible leaked file descriptors 3718 if (intent != null && intent.hasFileDescriptors() == true) { 3719 throw new IllegalArgumentException("File descriptors passed in Intent"); 3720 } 3721 3722 synchronized (this) { 3723 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3724 if (r == null) { 3725 ActivityOptions.abort(options); 3726 return false; 3727 } 3728 if (r.app == null || r.app.thread == null) { 3729 // The caller is not running... d'oh! 3730 ActivityOptions.abort(options); 3731 return false; 3732 } 3733 intent = new Intent(intent); 3734 // The caller is not allowed to change the data. 3735 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3736 // And we are resetting to find the next component... 3737 intent.setComponent(null); 3738 3739 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3740 3741 ActivityInfo aInfo = null; 3742 try { 3743 List<ResolveInfo> resolves = 3744 AppGlobals.getPackageManager().queryIntentActivities( 3745 intent, r.resolvedType, 3746 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3747 UserHandle.getCallingUserId()); 3748 3749 // Look for the original activity in the list... 3750 final int N = resolves != null ? resolves.size() : 0; 3751 for (int i=0; i<N; i++) { 3752 ResolveInfo rInfo = resolves.get(i); 3753 if (rInfo.activityInfo.packageName.equals(r.packageName) 3754 && rInfo.activityInfo.name.equals(r.info.name)) { 3755 // We found the current one... the next matching is 3756 // after it. 3757 i++; 3758 if (i<N) { 3759 aInfo = resolves.get(i).activityInfo; 3760 } 3761 if (debug) { 3762 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3763 + "/" + r.info.name); 3764 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3765 + "/" + aInfo.name); 3766 } 3767 break; 3768 } 3769 } 3770 } catch (RemoteException e) { 3771 } 3772 3773 if (aInfo == null) { 3774 // Nobody who is next! 3775 ActivityOptions.abort(options); 3776 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3777 return false; 3778 } 3779 3780 intent.setComponent(new ComponentName( 3781 aInfo.applicationInfo.packageName, aInfo.name)); 3782 intent.setFlags(intent.getFlags()&~( 3783 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3784 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3785 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3786 Intent.FLAG_ACTIVITY_NEW_TASK)); 3787 3788 // Okay now we need to start the new activity, replacing the 3789 // currently running activity. This is a little tricky because 3790 // we want to start the new one as if the current one is finished, 3791 // but not finish the current one first so that there is no flicker. 3792 // And thus... 3793 final boolean wasFinishing = r.finishing; 3794 r.finishing = true; 3795 3796 // Propagate reply information over to the new activity. 3797 final ActivityRecord resultTo = r.resultTo; 3798 final String resultWho = r.resultWho; 3799 final int requestCode = r.requestCode; 3800 r.resultTo = null; 3801 if (resultTo != null) { 3802 resultTo.removeResultsLocked(r, resultWho, requestCode); 3803 } 3804 3805 final long origId = Binder.clearCallingIdentity(); 3806 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3807 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3808 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3809 -1, r.launchedFromUid, 0, options, false, null, null, null); 3810 Binder.restoreCallingIdentity(origId); 3811 3812 r.finishing = wasFinishing; 3813 if (res != ActivityManager.START_SUCCESS) { 3814 return false; 3815 } 3816 return true; 3817 } 3818 } 3819 3820 @Override 3821 public final int startActivityFromRecents(int taskId, Bundle options) { 3822 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3823 String msg = "Permission Denial: startActivityFromRecents called without " + 3824 START_TASKS_FROM_RECENTS; 3825 Slog.w(TAG, msg); 3826 throw new SecurityException(msg); 3827 } 3828 return startActivityFromRecentsInner(taskId, options); 3829 } 3830 3831 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3832 final TaskRecord task; 3833 final int callingUid; 3834 final String callingPackage; 3835 final Intent intent; 3836 final int userId; 3837 synchronized (this) { 3838 task = recentTaskForIdLocked(taskId); 3839 if (task == null) { 3840 throw new IllegalArgumentException("Task " + taskId + " not found."); 3841 } 3842 callingUid = task.mCallingUid; 3843 callingPackage = task.mCallingPackage; 3844 intent = task.intent; 3845 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3846 userId = task.userId; 3847 } 3848 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3849 options, userId, null, task); 3850 } 3851 3852 final int startActivityInPackage(int uid, String callingPackage, 3853 Intent intent, String resolvedType, IBinder resultTo, 3854 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3855 IActivityContainer container, TaskRecord inTask) { 3856 3857 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3858 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3859 3860 // TODO: Switch to user app stacks here. 3861 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3862 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3863 null, null, null, options, userId, container, inTask); 3864 return ret; 3865 } 3866 3867 @Override 3868 public final int startActivities(IApplicationThread caller, String callingPackage, 3869 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3870 int userId) { 3871 enforceNotIsolatedCaller("startActivities"); 3872 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3873 false, ALLOW_FULL_ONLY, "startActivity", null); 3874 // TODO: Switch to user app stacks here. 3875 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3876 resolvedTypes, resultTo, options, userId); 3877 return ret; 3878 } 3879 3880 final int startActivitiesInPackage(int uid, String callingPackage, 3881 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3882 Bundle options, int userId) { 3883 3884 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3885 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3886 // TODO: Switch to user app stacks here. 3887 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3888 resultTo, options, userId); 3889 return ret; 3890 } 3891 3892 //explicitly remove thd old information in mRecentTasks when removing existing user. 3893 private void removeRecentTasksForUserLocked(int userId) { 3894 if(userId <= 0) { 3895 Slog.i(TAG, "Can't remove recent task on user " + userId); 3896 return; 3897 } 3898 3899 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3900 TaskRecord tr = mRecentTasks.get(i); 3901 if (tr.userId == userId) { 3902 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3903 + " when finishing user" + userId); 3904 mRecentTasks.remove(i); 3905 tr.removedFromRecents(mTaskPersister); 3906 } 3907 } 3908 3909 // Remove tasks from persistent storage. 3910 mTaskPersister.wakeup(null, true); 3911 } 3912 3913 // Sort by taskId 3914 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3915 @Override 3916 public int compare(TaskRecord lhs, TaskRecord rhs) { 3917 return rhs.taskId - lhs.taskId; 3918 } 3919 }; 3920 3921 // Extract the affiliates of the chain containing mRecentTasks[start]. 3922 private int processNextAffiliateChain(int start) { 3923 final TaskRecord startTask = mRecentTasks.get(start); 3924 final int affiliateId = startTask.mAffiliatedTaskId; 3925 3926 // Quick identification of isolated tasks. I.e. those not launched behind. 3927 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3928 startTask.mNextAffiliate == null) { 3929 // There is still a slim chance that there are other tasks that point to this task 3930 // and that the chain is so messed up that this task no longer points to them but 3931 // the gain of this optimization outweighs the risk. 3932 startTask.inRecents = true; 3933 return start + 1; 3934 } 3935 3936 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3937 mTmpRecents.clear(); 3938 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3939 final TaskRecord task = mRecentTasks.get(i); 3940 if (task.mAffiliatedTaskId == affiliateId) { 3941 mRecentTasks.remove(i); 3942 mTmpRecents.add(task); 3943 } 3944 } 3945 3946 // Sort them all by taskId. That is the order they were create in and that order will 3947 // always be correct. 3948 Collections.sort(mTmpRecents, mTaskRecordComparator); 3949 3950 // Go through and fix up the linked list. 3951 // The first one is the end of the chain and has no next. 3952 final TaskRecord first = mTmpRecents.get(0); 3953 first.inRecents = true; 3954 if (first.mNextAffiliate != null) { 3955 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3956 first.setNextAffiliate(null); 3957 mTaskPersister.wakeup(first, false); 3958 } 3959 // Everything in the middle is doubly linked from next to prev. 3960 final int tmpSize = mTmpRecents.size(); 3961 for (int i = 0; i < tmpSize - 1; ++i) { 3962 final TaskRecord next = mTmpRecents.get(i); 3963 final TaskRecord prev = mTmpRecents.get(i + 1); 3964 if (next.mPrevAffiliate != prev) { 3965 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3966 " setting prev=" + prev); 3967 next.setPrevAffiliate(prev); 3968 mTaskPersister.wakeup(next, false); 3969 } 3970 if (prev.mNextAffiliate != next) { 3971 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3972 " setting next=" + next); 3973 prev.setNextAffiliate(next); 3974 mTaskPersister.wakeup(prev, false); 3975 } 3976 prev.inRecents = true; 3977 } 3978 // The last one is the beginning of the list and has no prev. 3979 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3980 if (last.mPrevAffiliate != null) { 3981 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3982 last.setPrevAffiliate(null); 3983 mTaskPersister.wakeup(last, false); 3984 } 3985 3986 // Insert the group back into mRecentTasks at start. 3987 mRecentTasks.addAll(start, mTmpRecents); 3988 3989 // Let the caller know where we left off. 3990 return start + tmpSize; 3991 } 3992 3993 /** 3994 * Update the recent tasks lists: make sure tasks should still be here (their 3995 * applications / activities still exist), update their availability, fixup ordering 3996 * of affiliations. 3997 */ 3998 void cleanupRecentTasksLocked(int userId) { 3999 if (mRecentTasks == null) { 4000 // Happens when called from the packagemanager broadcast before boot. 4001 return; 4002 } 4003 4004 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 4005 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 4006 final IPackageManager pm = AppGlobals.getPackageManager(); 4007 final ActivityInfo dummyAct = new ActivityInfo(); 4008 final ApplicationInfo dummyApp = new ApplicationInfo(); 4009 4010 int N = mRecentTasks.size(); 4011 4012 int[] users = userId == UserHandle.USER_ALL 4013 ? getUsersLocked() : new int[] { userId }; 4014 for (int user : users) { 4015 for (int i = 0; i < N; i++) { 4016 TaskRecord task = mRecentTasks.get(i); 4017 if (task.userId != user) { 4018 // Only look at tasks for the user ID of interest. 4019 continue; 4020 } 4021 if (task.autoRemoveRecents && task.getTopActivity() == null) { 4022 // This situation is broken, and we should just get rid of it now. 4023 mRecentTasks.remove(i); 4024 task.removedFromRecents(mTaskPersister); 4025 i--; 4026 N--; 4027 Slog.w(TAG, "Removing auto-remove without activity: " + task); 4028 continue; 4029 } 4030 // Check whether this activity is currently available. 4031 if (task.realActivity != null) { 4032 ActivityInfo ai = availActCache.get(task.realActivity); 4033 if (ai == null) { 4034 try { 4035 ai = pm.getActivityInfo(task.realActivity, 4036 PackageManager.GET_UNINSTALLED_PACKAGES 4037 | PackageManager.GET_DISABLED_COMPONENTS, user); 4038 } catch (RemoteException e) { 4039 // Will never happen. 4040 continue; 4041 } 4042 if (ai == null) { 4043 ai = dummyAct; 4044 } 4045 availActCache.put(task.realActivity, ai); 4046 } 4047 if (ai == dummyAct) { 4048 // This could be either because the activity no longer exists, or the 4049 // app is temporarily gone. For the former we want to remove the recents 4050 // entry; for the latter we want to mark it as unavailable. 4051 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4052 if (app == null) { 4053 try { 4054 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4055 PackageManager.GET_UNINSTALLED_PACKAGES 4056 | PackageManager.GET_DISABLED_COMPONENTS, user); 4057 } catch (RemoteException e) { 4058 // Will never happen. 4059 continue; 4060 } 4061 if (app == null) { 4062 app = dummyApp; 4063 } 4064 availAppCache.put(task.realActivity.getPackageName(), app); 4065 } 4066 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4067 // Doesn't exist any more! Good-bye. 4068 mRecentTasks.remove(i); 4069 task.removedFromRecents(mTaskPersister); 4070 i--; 4071 N--; 4072 Slog.w(TAG, "Removing no longer valid recent: " + task); 4073 continue; 4074 } else { 4075 // Otherwise just not available for now. 4076 if (task.isAvailable) { 4077 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4078 + task); 4079 } 4080 task.isAvailable = false; 4081 } 4082 } else { 4083 if (!ai.enabled || !ai.applicationInfo.enabled 4084 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4085 if (task.isAvailable) { 4086 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4087 + task + " (enabled=" + ai.enabled + "/" 4088 + ai.applicationInfo.enabled + " flags=" 4089 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4090 } 4091 task.isAvailable = false; 4092 } else { 4093 if (!task.isAvailable) { 4094 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4095 + task); 4096 } 4097 task.isAvailable = true; 4098 } 4099 } 4100 } 4101 } 4102 } 4103 4104 // Verify the affiliate chain for each task. 4105 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4106 } 4107 4108 mTmpRecents.clear(); 4109 // mRecentTasks is now in sorted, affiliated order. 4110 } 4111 4112 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4113 int N = mRecentTasks.size(); 4114 TaskRecord top = task; 4115 int topIndex = taskIndex; 4116 while (top.mNextAffiliate != null && topIndex > 0) { 4117 top = top.mNextAffiliate; 4118 topIndex--; 4119 } 4120 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4121 + topIndex + " from intial " + taskIndex); 4122 // Find the end of the chain, doing a sanity check along the way. 4123 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4124 int endIndex = topIndex; 4125 TaskRecord prev = top; 4126 while (endIndex < N) { 4127 TaskRecord cur = mRecentTasks.get(endIndex); 4128 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4129 + endIndex + " " + cur); 4130 if (cur == top) { 4131 // Verify start of the chain. 4132 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4133 Slog.wtf(TAG, "Bad chain @" + endIndex 4134 + ": first task has next affiliate: " + prev); 4135 sane = false; 4136 break; 4137 } 4138 } else { 4139 // Verify middle of the chain's next points back to the one before. 4140 if (cur.mNextAffiliate != prev 4141 || cur.mNextAffiliateTaskId != prev.taskId) { 4142 Slog.wtf(TAG, "Bad chain @" + endIndex 4143 + ": middle task " + cur + " @" + endIndex 4144 + " has bad next affiliate " 4145 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4146 + ", expected " + prev); 4147 sane = false; 4148 break; 4149 } 4150 } 4151 if (cur.mPrevAffiliateTaskId == -1) { 4152 // Chain ends here. 4153 if (cur.mPrevAffiliate != null) { 4154 Slog.wtf(TAG, "Bad chain @" + endIndex 4155 + ": last task " + cur + " has previous affiliate " 4156 + cur.mPrevAffiliate); 4157 sane = false; 4158 } 4159 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4160 break; 4161 } else { 4162 // Verify middle of the chain's prev points to a valid item. 4163 if (cur.mPrevAffiliate == null) { 4164 Slog.wtf(TAG, "Bad chain @" + endIndex 4165 + ": task " + cur + " has previous affiliate " 4166 + cur.mPrevAffiliate + " but should be id " 4167 + cur.mPrevAffiliate); 4168 sane = false; 4169 break; 4170 } 4171 } 4172 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4173 Slog.wtf(TAG, "Bad chain @" + endIndex 4174 + ": task " + cur + " has affiliated id " 4175 + cur.mAffiliatedTaskId + " but should be " 4176 + task.mAffiliatedTaskId); 4177 sane = false; 4178 break; 4179 } 4180 prev = cur; 4181 endIndex++; 4182 if (endIndex >= N) { 4183 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4184 + ": last task " + prev); 4185 sane = false; 4186 break; 4187 } 4188 } 4189 if (sane) { 4190 if (endIndex < taskIndex) { 4191 Slog.wtf(TAG, "Bad chain @" + endIndex 4192 + ": did not extend to task " + task + " @" + taskIndex); 4193 sane = false; 4194 } 4195 } 4196 if (sane) { 4197 // All looks good, we can just move all of the affiliated tasks 4198 // to the top. 4199 for (int i=topIndex; i<=endIndex; i++) { 4200 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4201 + " from " + i + " to " + (i-topIndex)); 4202 TaskRecord cur = mRecentTasks.remove(i); 4203 mRecentTasks.add(i-topIndex, cur); 4204 } 4205 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4206 + " to " + endIndex); 4207 return true; 4208 } 4209 4210 // Whoops, couldn't do it. 4211 return false; 4212 } 4213 4214 final void addRecentTaskLocked(TaskRecord task) { 4215 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4216 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4217 4218 int N = mRecentTasks.size(); 4219 // Quick case: check if the top-most recent task is the same. 4220 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4221 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4222 return; 4223 } 4224 // Another quick case: check if this is part of a set of affiliated 4225 // tasks that are at the top. 4226 if (isAffiliated && N > 0 && task.inRecents 4227 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4228 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4229 + " at top when adding " + task); 4230 return; 4231 } 4232 // Another quick case: never add voice sessions. 4233 if (task.voiceSession != null) { 4234 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4235 return; 4236 } 4237 4238 boolean needAffiliationFix = false; 4239 4240 // Slightly less quick case: the task is already in recents, so all we need 4241 // to do is move it. 4242 if (task.inRecents) { 4243 int taskIndex = mRecentTasks.indexOf(task); 4244 if (taskIndex >= 0) { 4245 if (!isAffiliated) { 4246 // Simple case: this is not an affiliated task, so we just move it to the front. 4247 mRecentTasks.remove(taskIndex); 4248 mRecentTasks.add(0, task); 4249 notifyTaskPersisterLocked(task, false); 4250 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4251 + " from " + taskIndex); 4252 return; 4253 } else { 4254 // More complicated: need to keep all affiliated tasks together. 4255 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4256 // All went well. 4257 return; 4258 } 4259 4260 // Uh oh... something bad in the affiliation chain, try to rebuild 4261 // everything and then go through our general path of adding a new task. 4262 needAffiliationFix = true; 4263 } 4264 } else { 4265 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4266 needAffiliationFix = true; 4267 } 4268 } 4269 4270 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4271 trimRecentsForTask(task, true); 4272 4273 N = mRecentTasks.size(); 4274 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4275 final TaskRecord tr = mRecentTasks.remove(N - 1); 4276 tr.removedFromRecents(mTaskPersister); 4277 N--; 4278 } 4279 task.inRecents = true; 4280 if (!isAffiliated || needAffiliationFix) { 4281 // If this is a simple non-affiliated task, or we had some failure trying to 4282 // handle it as part of an affilated task, then just place it at the top. 4283 mRecentTasks.add(0, task); 4284 } else if (isAffiliated) { 4285 // If this is a new affiliated task, then move all of the affiliated tasks 4286 // to the front and insert this new one. 4287 TaskRecord other = task.mNextAffiliate; 4288 if (other == null) { 4289 other = task.mPrevAffiliate; 4290 } 4291 if (other != null) { 4292 int otherIndex = mRecentTasks.indexOf(other); 4293 if (otherIndex >= 0) { 4294 // Insert new task at appropriate location. 4295 int taskIndex; 4296 if (other == task.mNextAffiliate) { 4297 // We found the index of our next affiliation, which is who is 4298 // before us in the list, so add after that point. 4299 taskIndex = otherIndex+1; 4300 } else { 4301 // We found the index of our previous affiliation, which is who is 4302 // after us in the list, so add at their position. 4303 taskIndex = otherIndex; 4304 } 4305 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4306 + taskIndex + ": " + task); 4307 mRecentTasks.add(taskIndex, task); 4308 4309 // Now move everything to the front. 4310 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4311 // All went well. 4312 return; 4313 } 4314 4315 // Uh oh... something bad in the affiliation chain, try to rebuild 4316 // everything and then go through our general path of adding a new task. 4317 needAffiliationFix = true; 4318 } else { 4319 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4320 + other); 4321 needAffiliationFix = true; 4322 } 4323 } else { 4324 if (DEBUG_RECENTS) Slog.d(TAG, 4325 "addRecent: adding affiliated task without next/prev:" + task); 4326 needAffiliationFix = true; 4327 } 4328 } 4329 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4330 4331 if (needAffiliationFix) { 4332 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4333 cleanupRecentTasksLocked(task.userId); 4334 } 4335 } 4336 4337 /** 4338 * If needed, remove oldest existing entries in recents that are for the same kind 4339 * of task as the given one. 4340 */ 4341 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4342 int N = mRecentTasks.size(); 4343 final Intent intent = task.intent; 4344 final boolean document = intent != null && intent.isDocument(); 4345 4346 int maxRecents = task.maxRecents - 1; 4347 for (int i=0; i<N; i++) { 4348 final TaskRecord tr = mRecentTasks.get(i); 4349 if (task != tr) { 4350 if (task.userId != tr.userId) { 4351 continue; 4352 } 4353 if (i > MAX_RECENT_BITMAPS) { 4354 tr.freeLastThumbnail(); 4355 } 4356 final Intent trIntent = tr.intent; 4357 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4358 (intent == null || !intent.filterEquals(trIntent))) { 4359 continue; 4360 } 4361 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4362 if (document && trIsDocument) { 4363 // These are the same document activity (not necessarily the same doc). 4364 if (maxRecents > 0) { 4365 --maxRecents; 4366 continue; 4367 } 4368 // Hit the maximum number of documents for this task. Fall through 4369 // and remove this document from recents. 4370 } else if (document || trIsDocument) { 4371 // Only one of these is a document. Not the droid we're looking for. 4372 continue; 4373 } 4374 } 4375 4376 if (!doTrim) { 4377 // If the caller is not actually asking for a trim, just tell them we reached 4378 // a point where the trim would happen. 4379 return i; 4380 } 4381 4382 // Either task and tr are the same or, their affinities match or their intents match 4383 // and neither of them is a document, or they are documents using the same activity 4384 // and their maxRecents has been reached. 4385 tr.disposeThumbnail(); 4386 mRecentTasks.remove(i); 4387 if (task != tr) { 4388 tr.removedFromRecents(mTaskPersister); 4389 } 4390 i--; 4391 N--; 4392 if (task.intent == null) { 4393 // If the new recent task we are adding is not fully 4394 // specified, then replace it with the existing recent task. 4395 task = tr; 4396 } 4397 notifyTaskPersisterLocked(tr, false); 4398 } 4399 4400 return -1; 4401 } 4402 4403 @Override 4404 public void reportActivityFullyDrawn(IBinder token) { 4405 synchronized (this) { 4406 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4407 if (r == null) { 4408 return; 4409 } 4410 r.reportFullyDrawnLocked(); 4411 } 4412 } 4413 4414 @Override 4415 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4416 synchronized (this) { 4417 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4418 if (r == null) { 4419 return; 4420 } 4421 final long origId = Binder.clearCallingIdentity(); 4422 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4423 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4424 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4425 if (config != null) { 4426 r.frozenBeforeDestroy = true; 4427 if (!updateConfigurationLocked(config, r, false, false)) { 4428 mStackSupervisor.resumeTopActivitiesLocked(); 4429 } 4430 } 4431 Binder.restoreCallingIdentity(origId); 4432 } 4433 } 4434 4435 @Override 4436 public int getRequestedOrientation(IBinder token) { 4437 synchronized (this) { 4438 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4439 if (r == null) { 4440 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4441 } 4442 return mWindowManager.getAppOrientation(r.appToken); 4443 } 4444 } 4445 4446 /** 4447 * This is the internal entry point for handling Activity.finish(). 4448 * 4449 * @param token The Binder token referencing the Activity we want to finish. 4450 * @param resultCode Result code, if any, from this Activity. 4451 * @param resultData Result data (Intent), if any, from this Activity. 4452 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4453 * the root Activity in the task. 4454 * 4455 * @return Returns true if the activity successfully finished, or false if it is still running. 4456 */ 4457 @Override 4458 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4459 boolean finishTask) { 4460 // Refuse possible leaked file descriptors 4461 if (resultData != null && resultData.hasFileDescriptors() == true) { 4462 throw new IllegalArgumentException("File descriptors passed in Intent"); 4463 } 4464 4465 synchronized(this) { 4466 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4467 if (r == null) { 4468 return true; 4469 } 4470 // Keep track of the root activity of the task before we finish it 4471 TaskRecord tr = r.task; 4472 ActivityRecord rootR = tr.getRootActivity(); 4473 // Do not allow task to finish in Lock Task mode. 4474 if (tr == mStackSupervisor.mLockTaskModeTask) { 4475 if (rootR == r) { 4476 mStackSupervisor.showLockTaskToast(); 4477 return false; 4478 } 4479 } 4480 if (mController != null) { 4481 // Find the first activity that is not finishing. 4482 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4483 if (next != null) { 4484 // ask watcher if this is allowed 4485 boolean resumeOK = true; 4486 try { 4487 resumeOK = mController.activityResuming(next.packageName); 4488 } catch (RemoteException e) { 4489 mController = null; 4490 Watchdog.getInstance().setActivityController(null); 4491 } 4492 4493 if (!resumeOK) { 4494 return false; 4495 } 4496 } 4497 } 4498 final long origId = Binder.clearCallingIdentity(); 4499 try { 4500 boolean res; 4501 if (finishTask && r == rootR) { 4502 // If requested, remove the task that is associated to this activity only if it 4503 // was the root activity in the task. The result code and data is ignored because 4504 // we don't support returning them across task boundaries. 4505 res = removeTaskByIdLocked(tr.taskId, 0); 4506 } else { 4507 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4508 resultData, "app-request", true); 4509 } 4510 return res; 4511 } finally { 4512 Binder.restoreCallingIdentity(origId); 4513 } 4514 } 4515 } 4516 4517 @Override 4518 public final void finishHeavyWeightApp() { 4519 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4520 != PackageManager.PERMISSION_GRANTED) { 4521 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4522 + Binder.getCallingPid() 4523 + ", uid=" + Binder.getCallingUid() 4524 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4525 Slog.w(TAG, msg); 4526 throw new SecurityException(msg); 4527 } 4528 4529 synchronized(this) { 4530 if (mHeavyWeightProcess == null) { 4531 return; 4532 } 4533 4534 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4535 mHeavyWeightProcess.activities); 4536 for (int i=0; i<activities.size(); i++) { 4537 ActivityRecord r = activities.get(i); 4538 if (!r.finishing) { 4539 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4540 null, "finish-heavy", true); 4541 } 4542 } 4543 4544 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4545 mHeavyWeightProcess.userId, 0)); 4546 mHeavyWeightProcess = null; 4547 } 4548 } 4549 4550 @Override 4551 public void crashApplication(int uid, int initialPid, String packageName, 4552 String message) { 4553 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4554 != PackageManager.PERMISSION_GRANTED) { 4555 String msg = "Permission Denial: crashApplication() from pid=" 4556 + Binder.getCallingPid() 4557 + ", uid=" + Binder.getCallingUid() 4558 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4559 Slog.w(TAG, msg); 4560 throw new SecurityException(msg); 4561 } 4562 4563 synchronized(this) { 4564 ProcessRecord proc = null; 4565 4566 // Figure out which process to kill. We don't trust that initialPid 4567 // still has any relation to current pids, so must scan through the 4568 // list. 4569 synchronized (mPidsSelfLocked) { 4570 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4571 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4572 if (p.uid != uid) { 4573 continue; 4574 } 4575 if (p.pid == initialPid) { 4576 proc = p; 4577 break; 4578 } 4579 if (p.pkgList.containsKey(packageName)) { 4580 proc = p; 4581 } 4582 } 4583 } 4584 4585 if (proc == null) { 4586 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4587 + " initialPid=" + initialPid 4588 + " packageName=" + packageName); 4589 return; 4590 } 4591 4592 if (proc.thread != null) { 4593 if (proc.pid == Process.myPid()) { 4594 Log.w(TAG, "crashApplication: trying to crash self!"); 4595 return; 4596 } 4597 long ident = Binder.clearCallingIdentity(); 4598 try { 4599 proc.thread.scheduleCrash(message); 4600 } catch (RemoteException e) { 4601 } 4602 Binder.restoreCallingIdentity(ident); 4603 } 4604 } 4605 } 4606 4607 @Override 4608 public final void finishSubActivity(IBinder token, String resultWho, 4609 int requestCode) { 4610 synchronized(this) { 4611 final long origId = Binder.clearCallingIdentity(); 4612 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4613 if (r != null) { 4614 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4615 } 4616 Binder.restoreCallingIdentity(origId); 4617 } 4618 } 4619 4620 @Override 4621 public boolean finishActivityAffinity(IBinder token) { 4622 synchronized(this) { 4623 final long origId = Binder.clearCallingIdentity(); 4624 try { 4625 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4626 4627 ActivityRecord rootR = r.task.getRootActivity(); 4628 // Do not allow task to finish in Lock Task mode. 4629 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4630 if (rootR == r) { 4631 mStackSupervisor.showLockTaskToast(); 4632 return false; 4633 } 4634 } 4635 boolean res = false; 4636 if (r != null) { 4637 res = r.task.stack.finishActivityAffinityLocked(r); 4638 } 4639 return res; 4640 } finally { 4641 Binder.restoreCallingIdentity(origId); 4642 } 4643 } 4644 } 4645 4646 @Override 4647 public void finishVoiceTask(IVoiceInteractionSession session) { 4648 synchronized(this) { 4649 final long origId = Binder.clearCallingIdentity(); 4650 try { 4651 mStackSupervisor.finishVoiceTask(session); 4652 } finally { 4653 Binder.restoreCallingIdentity(origId); 4654 } 4655 } 4656 4657 } 4658 4659 @Override 4660 public boolean releaseActivityInstance(IBinder token) { 4661 synchronized(this) { 4662 final long origId = Binder.clearCallingIdentity(); 4663 try { 4664 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4665 if (r.task == null || r.task.stack == null) { 4666 return false; 4667 } 4668 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4669 } finally { 4670 Binder.restoreCallingIdentity(origId); 4671 } 4672 } 4673 } 4674 4675 @Override 4676 public void releaseSomeActivities(IApplicationThread appInt) { 4677 synchronized(this) { 4678 final long origId = Binder.clearCallingIdentity(); 4679 try { 4680 ProcessRecord app = getRecordForAppLocked(appInt); 4681 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4682 } finally { 4683 Binder.restoreCallingIdentity(origId); 4684 } 4685 } 4686 } 4687 4688 @Override 4689 public boolean willActivityBeVisible(IBinder token) { 4690 synchronized(this) { 4691 ActivityStack stack = ActivityRecord.getStackLocked(token); 4692 if (stack != null) { 4693 return stack.willActivityBeVisibleLocked(token); 4694 } 4695 return false; 4696 } 4697 } 4698 4699 @Override 4700 public void overridePendingTransition(IBinder token, String packageName, 4701 int enterAnim, int exitAnim) { 4702 synchronized(this) { 4703 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4704 if (self == null) { 4705 return; 4706 } 4707 4708 final long origId = Binder.clearCallingIdentity(); 4709 4710 if (self.state == ActivityState.RESUMED 4711 || self.state == ActivityState.PAUSING) { 4712 mWindowManager.overridePendingAppTransition(packageName, 4713 enterAnim, exitAnim, null); 4714 } 4715 4716 Binder.restoreCallingIdentity(origId); 4717 } 4718 } 4719 4720 /** 4721 * Main function for removing an existing process from the activity manager 4722 * as a result of that process going away. Clears out all connections 4723 * to the process. 4724 */ 4725 private final void handleAppDiedLocked(ProcessRecord app, 4726 boolean restarting, boolean allowRestart) { 4727 int pid = app.pid; 4728 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4729 if (!kept && !restarting) { 4730 removeLruProcessLocked(app); 4731 if (pid > 0) { 4732 ProcessList.remove(pid); 4733 } 4734 } 4735 4736 if (mProfileProc == app) { 4737 clearProfilerLocked(); 4738 } 4739 4740 // Remove this application's activities from active lists. 4741 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4742 4743 app.activities.clear(); 4744 4745 if (app.instrumentationClass != null) { 4746 Slog.w(TAG, "Crash of app " + app.processName 4747 + " running instrumentation " + app.instrumentationClass); 4748 Bundle info = new Bundle(); 4749 info.putString("shortMsg", "Process crashed."); 4750 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4751 } 4752 4753 if (!restarting) { 4754 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4755 // If there was nothing to resume, and we are not already 4756 // restarting this process, but there is a visible activity that 4757 // is hosted by the process... then make sure all visible 4758 // activities are running, taking care of restarting this 4759 // process. 4760 if (hasVisibleActivities) { 4761 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4762 } 4763 } 4764 } 4765 } 4766 4767 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4768 IBinder threadBinder = thread.asBinder(); 4769 // Find the application record. 4770 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4771 ProcessRecord rec = mLruProcesses.get(i); 4772 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4773 return i; 4774 } 4775 } 4776 return -1; 4777 } 4778 4779 final ProcessRecord getRecordForAppLocked( 4780 IApplicationThread thread) { 4781 if (thread == null) { 4782 return null; 4783 } 4784 4785 int appIndex = getLRURecordIndexForAppLocked(thread); 4786 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4787 } 4788 4789 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4790 // If there are no longer any background processes running, 4791 // and the app that died was not running instrumentation, 4792 // then tell everyone we are now low on memory. 4793 boolean haveBg = false; 4794 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4795 ProcessRecord rec = mLruProcesses.get(i); 4796 if (rec.thread != null 4797 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4798 haveBg = true; 4799 break; 4800 } 4801 } 4802 4803 if (!haveBg) { 4804 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4805 if (doReport) { 4806 long now = SystemClock.uptimeMillis(); 4807 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4808 doReport = false; 4809 } else { 4810 mLastMemUsageReportTime = now; 4811 } 4812 } 4813 final ArrayList<ProcessMemInfo> memInfos 4814 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4815 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4816 long now = SystemClock.uptimeMillis(); 4817 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4818 ProcessRecord rec = mLruProcesses.get(i); 4819 if (rec == dyingProc || rec.thread == null) { 4820 continue; 4821 } 4822 if (doReport) { 4823 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4824 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4825 } 4826 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4827 // The low memory report is overriding any current 4828 // state for a GC request. Make sure to do 4829 // heavy/important/visible/foreground processes first. 4830 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4831 rec.lastRequestedGc = 0; 4832 } else { 4833 rec.lastRequestedGc = rec.lastLowMemory; 4834 } 4835 rec.reportLowMemory = true; 4836 rec.lastLowMemory = now; 4837 mProcessesToGc.remove(rec); 4838 addProcessToGcListLocked(rec); 4839 } 4840 } 4841 if (doReport) { 4842 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4843 mHandler.sendMessage(msg); 4844 } 4845 scheduleAppGcsLocked(); 4846 } 4847 } 4848 4849 final void appDiedLocked(ProcessRecord app) { 4850 appDiedLocked(app, app.pid, app.thread); 4851 } 4852 4853 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4854 // First check if this ProcessRecord is actually active for the pid. 4855 synchronized (mPidsSelfLocked) { 4856 ProcessRecord curProc = mPidsSelfLocked.get(pid); 4857 if (curProc != app) { 4858 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 4859 return; 4860 } 4861 } 4862 4863 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4864 synchronized (stats) { 4865 stats.noteProcessDiedLocked(app.info.uid, pid); 4866 } 4867 4868 Process.killProcessQuiet(pid); 4869 Process.killProcessGroup(app.info.uid, pid); 4870 app.killed = true; 4871 4872 // Clean up already done if the process has been re-started. 4873 if (app.pid == pid && app.thread != null && 4874 app.thread.asBinder() == thread.asBinder()) { 4875 boolean doLowMem = app.instrumentationClass == null; 4876 boolean doOomAdj = doLowMem; 4877 if (!app.killedByAm) { 4878 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4879 + ") has died"); 4880 mAllowLowerMemLevel = true; 4881 } else { 4882 // Note that we always want to do oom adj to update our state with the 4883 // new number of procs. 4884 mAllowLowerMemLevel = false; 4885 doLowMem = false; 4886 } 4887 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4888 if (DEBUG_CLEANUP) Slog.v( 4889 TAG, "Dying app: " + app + ", pid: " + pid 4890 + ", thread: " + thread.asBinder()); 4891 handleAppDiedLocked(app, false, true); 4892 4893 if (doOomAdj) { 4894 updateOomAdjLocked(); 4895 } 4896 if (doLowMem) { 4897 doLowMemReportIfNeededLocked(app); 4898 } 4899 } else if (app.pid != pid) { 4900 // A new process has already been started. 4901 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4902 + ") has died and restarted (pid " + app.pid + ")."); 4903 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4904 } else if (DEBUG_PROCESSES) { 4905 Slog.d(TAG, "Received spurious death notification for thread " 4906 + thread.asBinder()); 4907 } 4908 } 4909 4910 /** 4911 * If a stack trace dump file is configured, dump process stack traces. 4912 * @param clearTraces causes the dump file to be erased prior to the new 4913 * traces being written, if true; when false, the new traces will be 4914 * appended to any existing file content. 4915 * @param firstPids of dalvik VM processes to dump stack traces for first 4916 * @param lastPids of dalvik VM processes to dump stack traces for last 4917 * @param nativeProcs optional list of native process names to dump stack crawls 4918 * @return file containing stack traces, or null if no dump file is configured 4919 */ 4920 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4921 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4922 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4923 if (tracesPath == null || tracesPath.length() == 0) { 4924 return null; 4925 } 4926 4927 File tracesFile = new File(tracesPath); 4928 try { 4929 File tracesDir = tracesFile.getParentFile(); 4930 if (!tracesDir.exists()) { 4931 tracesDir.mkdirs(); 4932 if (!SELinux.restorecon(tracesDir)) { 4933 return null; 4934 } 4935 } 4936 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4937 4938 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4939 tracesFile.createNewFile(); 4940 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4941 } catch (IOException e) { 4942 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4943 return null; 4944 } 4945 4946 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4947 return tracesFile; 4948 } 4949 4950 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4951 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4952 // Use a FileObserver to detect when traces finish writing. 4953 // The order of traces is considered important to maintain for legibility. 4954 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4955 @Override 4956 public synchronized void onEvent(int event, String path) { notify(); } 4957 }; 4958 4959 try { 4960 observer.startWatching(); 4961 4962 // First collect all of the stacks of the most important pids. 4963 if (firstPids != null) { 4964 try { 4965 int num = firstPids.size(); 4966 for (int i = 0; i < num; i++) { 4967 synchronized (observer) { 4968 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4969 observer.wait(200); // Wait for write-close, give up after 200msec 4970 } 4971 } 4972 } catch (InterruptedException e) { 4973 Slog.wtf(TAG, e); 4974 } 4975 } 4976 4977 // Next collect the stacks of the native pids 4978 if (nativeProcs != null) { 4979 int[] pids = Process.getPidsForCommands(nativeProcs); 4980 if (pids != null) { 4981 for (int pid : pids) { 4982 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4983 } 4984 } 4985 } 4986 4987 // Lastly, measure CPU usage. 4988 if (processCpuTracker != null) { 4989 processCpuTracker.init(); 4990 System.gc(); 4991 processCpuTracker.update(); 4992 try { 4993 synchronized (processCpuTracker) { 4994 processCpuTracker.wait(500); // measure over 1/2 second. 4995 } 4996 } catch (InterruptedException e) { 4997 } 4998 processCpuTracker.update(); 4999 5000 // We'll take the stack crawls of just the top apps using CPU. 5001 final int N = processCpuTracker.countWorkingStats(); 5002 int numProcs = 0; 5003 for (int i=0; i<N && numProcs<5; i++) { 5004 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5005 if (lastPids.indexOfKey(stats.pid) >= 0) { 5006 numProcs++; 5007 try { 5008 synchronized (observer) { 5009 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 5010 observer.wait(200); // Wait for write-close, give up after 200msec 5011 } 5012 } catch (InterruptedException e) { 5013 Slog.wtf(TAG, e); 5014 } 5015 5016 } 5017 } 5018 } 5019 } finally { 5020 observer.stopWatching(); 5021 } 5022 } 5023 5024 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5025 if (true || IS_USER_BUILD) { 5026 return; 5027 } 5028 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5029 if (tracesPath == null || tracesPath.length() == 0) { 5030 return; 5031 } 5032 5033 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5034 StrictMode.allowThreadDiskWrites(); 5035 try { 5036 final File tracesFile = new File(tracesPath); 5037 final File tracesDir = tracesFile.getParentFile(); 5038 final File tracesTmp = new File(tracesDir, "__tmp__"); 5039 try { 5040 if (!tracesDir.exists()) { 5041 tracesDir.mkdirs(); 5042 if (!SELinux.restorecon(tracesDir.getPath())) { 5043 return; 5044 } 5045 } 5046 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 5047 5048 if (tracesFile.exists()) { 5049 tracesTmp.delete(); 5050 tracesFile.renameTo(tracesTmp); 5051 } 5052 StringBuilder sb = new StringBuilder(); 5053 Time tobj = new Time(); 5054 tobj.set(System.currentTimeMillis()); 5055 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5056 sb.append(": "); 5057 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5058 sb.append(" since "); 5059 sb.append(msg); 5060 FileOutputStream fos = new FileOutputStream(tracesFile); 5061 fos.write(sb.toString().getBytes()); 5062 if (app == null) { 5063 fos.write("\n*** No application process!".getBytes()); 5064 } 5065 fos.close(); 5066 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5067 } catch (IOException e) { 5068 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5069 return; 5070 } 5071 5072 if (app != null) { 5073 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5074 firstPids.add(app.pid); 5075 dumpStackTraces(tracesPath, firstPids, null, null, null); 5076 } 5077 5078 File lastTracesFile = null; 5079 File curTracesFile = null; 5080 for (int i=9; i>=0; i--) { 5081 String name = String.format(Locale.US, "slow%02d.txt", i); 5082 curTracesFile = new File(tracesDir, name); 5083 if (curTracesFile.exists()) { 5084 if (lastTracesFile != null) { 5085 curTracesFile.renameTo(lastTracesFile); 5086 } else { 5087 curTracesFile.delete(); 5088 } 5089 } 5090 lastTracesFile = curTracesFile; 5091 } 5092 tracesFile.renameTo(curTracesFile); 5093 if (tracesTmp.exists()) { 5094 tracesTmp.renameTo(tracesFile); 5095 } 5096 } finally { 5097 StrictMode.setThreadPolicy(oldPolicy); 5098 } 5099 } 5100 5101 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5102 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5103 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5104 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5105 5106 if (mController != null) { 5107 try { 5108 // 0 == continue, -1 = kill process immediately 5109 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5110 if (res < 0 && app.pid != MY_PID) { 5111 app.kill("anr", true); 5112 } 5113 } catch (RemoteException e) { 5114 mController = null; 5115 Watchdog.getInstance().setActivityController(null); 5116 } 5117 } 5118 5119 long anrTime = SystemClock.uptimeMillis(); 5120 if (MONITOR_CPU_USAGE) { 5121 updateCpuStatsNow(); 5122 } 5123 5124 synchronized (this) { 5125 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5126 if (mShuttingDown) { 5127 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5128 return; 5129 } else if (app.notResponding) { 5130 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5131 return; 5132 } else if (app.crashing) { 5133 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5134 return; 5135 } 5136 5137 // In case we come through here for the same app before completing 5138 // this one, mark as anring now so we will bail out. 5139 app.notResponding = true; 5140 5141 // Log the ANR to the event log. 5142 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5143 app.processName, app.info.flags, annotation); 5144 5145 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5146 firstPids.add(app.pid); 5147 5148 int parentPid = app.pid; 5149 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5150 if (parentPid != app.pid) firstPids.add(parentPid); 5151 5152 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5153 5154 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5155 ProcessRecord r = mLruProcesses.get(i); 5156 if (r != null && r.thread != null) { 5157 int pid = r.pid; 5158 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5159 if (r.persistent) { 5160 firstPids.add(pid); 5161 } else { 5162 lastPids.put(pid, Boolean.TRUE); 5163 } 5164 } 5165 } 5166 } 5167 } 5168 5169 // Log the ANR to the main log. 5170 StringBuilder info = new StringBuilder(); 5171 info.setLength(0); 5172 info.append("ANR in ").append(app.processName); 5173 if (activity != null && activity.shortComponentName != null) { 5174 info.append(" (").append(activity.shortComponentName).append(")"); 5175 } 5176 info.append("\n"); 5177 info.append("PID: ").append(app.pid).append("\n"); 5178 if (annotation != null) { 5179 info.append("Reason: ").append(annotation).append("\n"); 5180 } 5181 if (parent != null && parent != activity) { 5182 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5183 } 5184 5185 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5186 5187 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5188 NATIVE_STACKS_OF_INTEREST); 5189 5190 String cpuInfo = null; 5191 if (MONITOR_CPU_USAGE) { 5192 updateCpuStatsNow(); 5193 synchronized (mProcessCpuTracker) { 5194 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5195 } 5196 info.append(processCpuTracker.printCurrentLoad()); 5197 info.append(cpuInfo); 5198 } 5199 5200 info.append(processCpuTracker.printCurrentState(anrTime)); 5201 5202 Slog.e(TAG, info.toString()); 5203 if (tracesFile == null) { 5204 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5205 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5206 } 5207 5208 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5209 cpuInfo, tracesFile, null); 5210 5211 if (mController != null) { 5212 try { 5213 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5214 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5215 if (res != 0) { 5216 if (res < 0 && app.pid != MY_PID) { 5217 app.kill("anr", true); 5218 } else { 5219 synchronized (this) { 5220 mServices.scheduleServiceTimeoutLocked(app); 5221 } 5222 } 5223 return; 5224 } 5225 } catch (RemoteException e) { 5226 mController = null; 5227 Watchdog.getInstance().setActivityController(null); 5228 } 5229 } 5230 5231 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5232 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5233 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5234 5235 synchronized (this) { 5236 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5237 app.kill("bg anr", true); 5238 return; 5239 } 5240 5241 // Set the app's notResponding state, and look up the errorReportReceiver 5242 makeAppNotRespondingLocked(app, 5243 activity != null ? activity.shortComponentName : null, 5244 annotation != null ? "ANR " + annotation : "ANR", 5245 info.toString()); 5246 5247 // Bring up the infamous App Not Responding dialog 5248 Message msg = Message.obtain(); 5249 HashMap<String, Object> map = new HashMap<String, Object>(); 5250 msg.what = SHOW_NOT_RESPONDING_MSG; 5251 msg.obj = map; 5252 msg.arg1 = aboveSystem ? 1 : 0; 5253 map.put("app", app); 5254 if (activity != null) { 5255 map.put("activity", activity); 5256 } 5257 5258 mHandler.sendMessage(msg); 5259 } 5260 } 5261 5262 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5263 if (!mLaunchWarningShown) { 5264 mLaunchWarningShown = true; 5265 mHandler.post(new Runnable() { 5266 @Override 5267 public void run() { 5268 synchronized (ActivityManagerService.this) { 5269 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5270 d.show(); 5271 mHandler.postDelayed(new Runnable() { 5272 @Override 5273 public void run() { 5274 synchronized (ActivityManagerService.this) { 5275 d.dismiss(); 5276 mLaunchWarningShown = false; 5277 } 5278 } 5279 }, 4000); 5280 } 5281 } 5282 }); 5283 } 5284 } 5285 5286 @Override 5287 public boolean clearApplicationUserData(final String packageName, 5288 final IPackageDataObserver observer, int userId) { 5289 enforceNotIsolatedCaller("clearApplicationUserData"); 5290 int uid = Binder.getCallingUid(); 5291 int pid = Binder.getCallingPid(); 5292 userId = handleIncomingUser(pid, uid, 5293 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5294 long callingId = Binder.clearCallingIdentity(); 5295 try { 5296 IPackageManager pm = AppGlobals.getPackageManager(); 5297 int pkgUid = -1; 5298 synchronized(this) { 5299 try { 5300 pkgUid = pm.getPackageUid(packageName, userId); 5301 } catch (RemoteException e) { 5302 } 5303 if (pkgUid == -1) { 5304 Slog.w(TAG, "Invalid packageName: " + packageName); 5305 if (observer != null) { 5306 try { 5307 observer.onRemoveCompleted(packageName, false); 5308 } catch (RemoteException e) { 5309 Slog.i(TAG, "Observer no longer exists."); 5310 } 5311 } 5312 return false; 5313 } 5314 if (uid == pkgUid || checkComponentPermission( 5315 android.Manifest.permission.CLEAR_APP_USER_DATA, 5316 pid, uid, -1, true) 5317 == PackageManager.PERMISSION_GRANTED) { 5318 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5319 } else { 5320 throw new SecurityException("PID " + pid + " does not have permission " 5321 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5322 + " of package " + packageName); 5323 } 5324 5325 // Remove all tasks match the cleared application package and user 5326 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5327 final TaskRecord tr = mRecentTasks.get(i); 5328 final String taskPackageName = 5329 tr.getBaseIntent().getComponent().getPackageName(); 5330 if (tr.userId != userId) continue; 5331 if (!taskPackageName.equals(packageName)) continue; 5332 removeTaskByIdLocked(tr.taskId, 0); 5333 } 5334 } 5335 5336 try { 5337 // Clear application user data 5338 pm.clearApplicationUserData(packageName, observer, userId); 5339 5340 synchronized(this) { 5341 // Remove all permissions granted from/to this package 5342 removeUriPermissionsForPackageLocked(packageName, userId, true); 5343 } 5344 5345 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5346 Uri.fromParts("package", packageName, null)); 5347 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5348 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5349 null, null, 0, null, null, null, false, false, userId); 5350 } catch (RemoteException e) { 5351 } 5352 } finally { 5353 Binder.restoreCallingIdentity(callingId); 5354 } 5355 return true; 5356 } 5357 5358 @Override 5359 public void killBackgroundProcesses(final String packageName, int userId) { 5360 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5361 != PackageManager.PERMISSION_GRANTED && 5362 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5363 != PackageManager.PERMISSION_GRANTED) { 5364 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5365 + Binder.getCallingPid() 5366 + ", uid=" + Binder.getCallingUid() 5367 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5368 Slog.w(TAG, msg); 5369 throw new SecurityException(msg); 5370 } 5371 5372 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5373 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5374 long callingId = Binder.clearCallingIdentity(); 5375 try { 5376 IPackageManager pm = AppGlobals.getPackageManager(); 5377 synchronized(this) { 5378 int appId = -1; 5379 try { 5380 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5381 } catch (RemoteException e) { 5382 } 5383 if (appId == -1) { 5384 Slog.w(TAG, "Invalid packageName: " + packageName); 5385 return; 5386 } 5387 killPackageProcessesLocked(packageName, appId, userId, 5388 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5389 } 5390 } finally { 5391 Binder.restoreCallingIdentity(callingId); 5392 } 5393 } 5394 5395 @Override 5396 public void killAllBackgroundProcesses() { 5397 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5398 != PackageManager.PERMISSION_GRANTED) { 5399 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5400 + Binder.getCallingPid() 5401 + ", uid=" + Binder.getCallingUid() 5402 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5403 Slog.w(TAG, msg); 5404 throw new SecurityException(msg); 5405 } 5406 5407 long callingId = Binder.clearCallingIdentity(); 5408 try { 5409 synchronized(this) { 5410 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5411 final int NP = mProcessNames.getMap().size(); 5412 for (int ip=0; ip<NP; ip++) { 5413 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5414 final int NA = apps.size(); 5415 for (int ia=0; ia<NA; ia++) { 5416 ProcessRecord app = apps.valueAt(ia); 5417 if (app.persistent) { 5418 // we don't kill persistent processes 5419 continue; 5420 } 5421 if (app.removed) { 5422 procs.add(app); 5423 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5424 app.removed = true; 5425 procs.add(app); 5426 } 5427 } 5428 } 5429 5430 int N = procs.size(); 5431 for (int i=0; i<N; i++) { 5432 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5433 } 5434 mAllowLowerMemLevel = true; 5435 updateOomAdjLocked(); 5436 doLowMemReportIfNeededLocked(null); 5437 } 5438 } finally { 5439 Binder.restoreCallingIdentity(callingId); 5440 } 5441 } 5442 5443 @Override 5444 public void forceStopPackage(final String packageName, int userId) { 5445 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5446 != PackageManager.PERMISSION_GRANTED) { 5447 String msg = "Permission Denial: forceStopPackage() from pid=" 5448 + Binder.getCallingPid() 5449 + ", uid=" + Binder.getCallingUid() 5450 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5451 Slog.w(TAG, msg); 5452 throw new SecurityException(msg); 5453 } 5454 final int callingPid = Binder.getCallingPid(); 5455 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5456 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5457 long callingId = Binder.clearCallingIdentity(); 5458 try { 5459 IPackageManager pm = AppGlobals.getPackageManager(); 5460 synchronized(this) { 5461 int[] users = userId == UserHandle.USER_ALL 5462 ? getUsersLocked() : new int[] { userId }; 5463 for (int user : users) { 5464 int pkgUid = -1; 5465 try { 5466 pkgUid = pm.getPackageUid(packageName, user); 5467 } catch (RemoteException e) { 5468 } 5469 if (pkgUid == -1) { 5470 Slog.w(TAG, "Invalid packageName: " + packageName); 5471 continue; 5472 } 5473 try { 5474 pm.setPackageStoppedState(packageName, true, user); 5475 } catch (RemoteException e) { 5476 } catch (IllegalArgumentException e) { 5477 Slog.w(TAG, "Failed trying to unstop package " 5478 + packageName + ": " + e); 5479 } 5480 if (isUserRunningLocked(user, false)) { 5481 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5482 } 5483 } 5484 } 5485 } finally { 5486 Binder.restoreCallingIdentity(callingId); 5487 } 5488 } 5489 5490 @Override 5491 public void addPackageDependency(String packageName) { 5492 synchronized (this) { 5493 int callingPid = Binder.getCallingPid(); 5494 if (callingPid == Process.myPid()) { 5495 // Yeah, um, no. 5496 Slog.w(TAG, "Can't addPackageDependency on system process"); 5497 return; 5498 } 5499 ProcessRecord proc; 5500 synchronized (mPidsSelfLocked) { 5501 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5502 } 5503 if (proc != null) { 5504 if (proc.pkgDeps == null) { 5505 proc.pkgDeps = new ArraySet<String>(1); 5506 } 5507 proc.pkgDeps.add(packageName); 5508 } 5509 } 5510 } 5511 5512 /* 5513 * The pkg name and app id have to be specified. 5514 */ 5515 @Override 5516 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5517 if (pkg == null) { 5518 return; 5519 } 5520 // Make sure the uid is valid. 5521 if (appid < 0) { 5522 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5523 return; 5524 } 5525 int callerUid = Binder.getCallingUid(); 5526 // Only the system server can kill an application 5527 if (callerUid == Process.SYSTEM_UID) { 5528 // Post an aysnc message to kill the application 5529 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5530 msg.arg1 = appid; 5531 msg.arg2 = 0; 5532 Bundle bundle = new Bundle(); 5533 bundle.putString("pkg", pkg); 5534 bundle.putString("reason", reason); 5535 msg.obj = bundle; 5536 mHandler.sendMessage(msg); 5537 } else { 5538 throw new SecurityException(callerUid + " cannot kill pkg: " + 5539 pkg); 5540 } 5541 } 5542 5543 @Override 5544 public void closeSystemDialogs(String reason) { 5545 enforceNotIsolatedCaller("closeSystemDialogs"); 5546 5547 final int pid = Binder.getCallingPid(); 5548 final int uid = Binder.getCallingUid(); 5549 final long origId = Binder.clearCallingIdentity(); 5550 try { 5551 synchronized (this) { 5552 // Only allow this from foreground processes, so that background 5553 // applications can't abuse it to prevent system UI from being shown. 5554 if (uid >= Process.FIRST_APPLICATION_UID) { 5555 ProcessRecord proc; 5556 synchronized (mPidsSelfLocked) { 5557 proc = mPidsSelfLocked.get(pid); 5558 } 5559 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5560 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5561 + " from background process " + proc); 5562 return; 5563 } 5564 } 5565 closeSystemDialogsLocked(reason); 5566 } 5567 } finally { 5568 Binder.restoreCallingIdentity(origId); 5569 } 5570 } 5571 5572 void closeSystemDialogsLocked(String reason) { 5573 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5574 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5575 | Intent.FLAG_RECEIVER_FOREGROUND); 5576 if (reason != null) { 5577 intent.putExtra("reason", reason); 5578 } 5579 mWindowManager.closeSystemDialogs(reason); 5580 5581 mStackSupervisor.closeSystemDialogsLocked(); 5582 5583 broadcastIntentLocked(null, null, intent, null, 5584 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5585 Process.SYSTEM_UID, UserHandle.USER_ALL); 5586 } 5587 5588 @Override 5589 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5590 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5591 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5592 for (int i=pids.length-1; i>=0; i--) { 5593 ProcessRecord proc; 5594 int oomAdj; 5595 synchronized (this) { 5596 synchronized (mPidsSelfLocked) { 5597 proc = mPidsSelfLocked.get(pids[i]); 5598 oomAdj = proc != null ? proc.setAdj : 0; 5599 } 5600 } 5601 infos[i] = new Debug.MemoryInfo(); 5602 Debug.getMemoryInfo(pids[i], infos[i]); 5603 if (proc != null) { 5604 synchronized (this) { 5605 if (proc.thread != null && proc.setAdj == oomAdj) { 5606 // Record this for posterity if the process has been stable. 5607 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5608 infos[i].getTotalUss(), false, proc.pkgList); 5609 } 5610 } 5611 } 5612 } 5613 return infos; 5614 } 5615 5616 @Override 5617 public long[] getProcessPss(int[] pids) { 5618 enforceNotIsolatedCaller("getProcessPss"); 5619 long[] pss = new long[pids.length]; 5620 for (int i=pids.length-1; i>=0; i--) { 5621 ProcessRecord proc; 5622 int oomAdj; 5623 synchronized (this) { 5624 synchronized (mPidsSelfLocked) { 5625 proc = mPidsSelfLocked.get(pids[i]); 5626 oomAdj = proc != null ? proc.setAdj : 0; 5627 } 5628 } 5629 long[] tmpUss = new long[1]; 5630 pss[i] = Debug.getPss(pids[i], tmpUss); 5631 if (proc != null) { 5632 synchronized (this) { 5633 if (proc.thread != null && proc.setAdj == oomAdj) { 5634 // Record this for posterity if the process has been stable. 5635 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5636 } 5637 } 5638 } 5639 } 5640 return pss; 5641 } 5642 5643 @Override 5644 public void killApplicationProcess(String processName, int uid) { 5645 if (processName == null) { 5646 return; 5647 } 5648 5649 int callerUid = Binder.getCallingUid(); 5650 // Only the system server can kill an application 5651 if (callerUid == Process.SYSTEM_UID) { 5652 synchronized (this) { 5653 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5654 if (app != null && app.thread != null) { 5655 try { 5656 app.thread.scheduleSuicide(); 5657 } catch (RemoteException e) { 5658 // If the other end already died, then our work here is done. 5659 } 5660 } else { 5661 Slog.w(TAG, "Process/uid not found attempting kill of " 5662 + processName + " / " + uid); 5663 } 5664 } 5665 } else { 5666 throw new SecurityException(callerUid + " cannot kill app process: " + 5667 processName); 5668 } 5669 } 5670 5671 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5672 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5673 false, true, false, false, UserHandle.getUserId(uid), reason); 5674 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5675 Uri.fromParts("package", packageName, null)); 5676 if (!mProcessesReady) { 5677 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5678 | Intent.FLAG_RECEIVER_FOREGROUND); 5679 } 5680 intent.putExtra(Intent.EXTRA_UID, uid); 5681 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5682 broadcastIntentLocked(null, null, intent, 5683 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5684 false, false, 5685 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5686 } 5687 5688 private void forceStopUserLocked(int userId, String reason) { 5689 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5690 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5691 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5692 | Intent.FLAG_RECEIVER_FOREGROUND); 5693 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5694 broadcastIntentLocked(null, null, intent, 5695 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5696 false, false, 5697 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5698 } 5699 5700 private final boolean killPackageProcessesLocked(String packageName, int appId, 5701 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5702 boolean doit, boolean evenPersistent, String reason) { 5703 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5704 5705 // Remove all processes this package may have touched: all with the 5706 // same UID (except for the system or root user), and all whose name 5707 // matches the package name. 5708 final int NP = mProcessNames.getMap().size(); 5709 for (int ip=0; ip<NP; ip++) { 5710 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5711 final int NA = apps.size(); 5712 for (int ia=0; ia<NA; ia++) { 5713 ProcessRecord app = apps.valueAt(ia); 5714 if (app.persistent && !evenPersistent) { 5715 // we don't kill persistent processes 5716 continue; 5717 } 5718 if (app.removed) { 5719 if (doit) { 5720 procs.add(app); 5721 } 5722 continue; 5723 } 5724 5725 // Skip process if it doesn't meet our oom adj requirement. 5726 if (app.setAdj < minOomAdj) { 5727 continue; 5728 } 5729 5730 // If no package is specified, we call all processes under the 5731 // give user id. 5732 if (packageName == null) { 5733 if (app.userId != userId) { 5734 continue; 5735 } 5736 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5737 continue; 5738 } 5739 // Package has been specified, we want to hit all processes 5740 // that match it. We need to qualify this by the processes 5741 // that are running under the specified app and user ID. 5742 } else { 5743 final boolean isDep = app.pkgDeps != null 5744 && app.pkgDeps.contains(packageName); 5745 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5746 continue; 5747 } 5748 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5749 continue; 5750 } 5751 if (!app.pkgList.containsKey(packageName) && !isDep) { 5752 continue; 5753 } 5754 } 5755 5756 // Process has passed all conditions, kill it! 5757 if (!doit) { 5758 return true; 5759 } 5760 app.removed = true; 5761 procs.add(app); 5762 } 5763 } 5764 5765 int N = procs.size(); 5766 for (int i=0; i<N; i++) { 5767 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5768 } 5769 updateOomAdjLocked(); 5770 return N > 0; 5771 } 5772 5773 private final boolean forceStopPackageLocked(String name, int appId, 5774 boolean callerWillRestart, boolean purgeCache, boolean doit, 5775 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5776 int i; 5777 int N; 5778 5779 if (userId == UserHandle.USER_ALL && name == null) { 5780 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5781 } 5782 5783 if (appId < 0 && name != null) { 5784 try { 5785 appId = UserHandle.getAppId( 5786 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5787 } catch (RemoteException e) { 5788 } 5789 } 5790 5791 if (doit) { 5792 if (name != null) { 5793 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5794 + " user=" + userId + ": " + reason); 5795 } else { 5796 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5797 } 5798 5799 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5800 for (int ip=pmap.size()-1; ip>=0; ip--) { 5801 SparseArray<Long> ba = pmap.valueAt(ip); 5802 for (i=ba.size()-1; i>=0; i--) { 5803 boolean remove = false; 5804 final int entUid = ba.keyAt(i); 5805 if (name != null) { 5806 if (userId == UserHandle.USER_ALL) { 5807 if (UserHandle.getAppId(entUid) == appId) { 5808 remove = true; 5809 } 5810 } else { 5811 if (entUid == UserHandle.getUid(userId, appId)) { 5812 remove = true; 5813 } 5814 } 5815 } else if (UserHandle.getUserId(entUid) == userId) { 5816 remove = true; 5817 } 5818 if (remove) { 5819 ba.removeAt(i); 5820 } 5821 } 5822 if (ba.size() == 0) { 5823 pmap.removeAt(ip); 5824 } 5825 } 5826 } 5827 5828 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5829 -100, callerWillRestart, true, doit, evenPersistent, 5830 name == null ? ("stop user " + userId) : ("stop " + name)); 5831 5832 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5833 if (!doit) { 5834 return true; 5835 } 5836 didSomething = true; 5837 } 5838 5839 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5840 if (!doit) { 5841 return true; 5842 } 5843 didSomething = true; 5844 } 5845 5846 if (name == null) { 5847 // Remove all sticky broadcasts from this user. 5848 mStickyBroadcasts.remove(userId); 5849 } 5850 5851 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5852 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5853 userId, providers)) { 5854 if (!doit) { 5855 return true; 5856 } 5857 didSomething = true; 5858 } 5859 N = providers.size(); 5860 for (i=0; i<N; i++) { 5861 removeDyingProviderLocked(null, providers.get(i), true); 5862 } 5863 5864 // Remove transient permissions granted from/to this package/user 5865 removeUriPermissionsForPackageLocked(name, userId, false); 5866 5867 if (name == null || uninstalling) { 5868 // Remove pending intents. For now we only do this when force 5869 // stopping users, because we have some problems when doing this 5870 // for packages -- app widgets are not currently cleaned up for 5871 // such packages, so they can be left with bad pending intents. 5872 if (mIntentSenderRecords.size() > 0) { 5873 Iterator<WeakReference<PendingIntentRecord>> it 5874 = mIntentSenderRecords.values().iterator(); 5875 while (it.hasNext()) { 5876 WeakReference<PendingIntentRecord> wpir = it.next(); 5877 if (wpir == null) { 5878 it.remove(); 5879 continue; 5880 } 5881 PendingIntentRecord pir = wpir.get(); 5882 if (pir == null) { 5883 it.remove(); 5884 continue; 5885 } 5886 if (name == null) { 5887 // Stopping user, remove all objects for the user. 5888 if (pir.key.userId != userId) { 5889 // Not the same user, skip it. 5890 continue; 5891 } 5892 } else { 5893 if (UserHandle.getAppId(pir.uid) != appId) { 5894 // Different app id, skip it. 5895 continue; 5896 } 5897 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5898 // Different user, skip it. 5899 continue; 5900 } 5901 if (!pir.key.packageName.equals(name)) { 5902 // Different package, skip it. 5903 continue; 5904 } 5905 } 5906 if (!doit) { 5907 return true; 5908 } 5909 didSomething = true; 5910 it.remove(); 5911 pir.canceled = true; 5912 if (pir.key.activity != null) { 5913 pir.key.activity.pendingResults.remove(pir.ref); 5914 } 5915 } 5916 } 5917 } 5918 5919 if (doit) { 5920 if (purgeCache && name != null) { 5921 AttributeCache ac = AttributeCache.instance(); 5922 if (ac != null) { 5923 ac.removePackage(name); 5924 } 5925 } 5926 if (mBooted) { 5927 mStackSupervisor.resumeTopActivitiesLocked(); 5928 mStackSupervisor.scheduleIdleLocked(); 5929 } 5930 } 5931 5932 return didSomething; 5933 } 5934 5935 private final boolean removeProcessLocked(ProcessRecord app, 5936 boolean callerWillRestart, boolean allowRestart, String reason) { 5937 final String name = app.processName; 5938 final int uid = app.uid; 5939 if (DEBUG_PROCESSES) Slog.d( 5940 TAG, "Force removing proc " + app.toShortString() + " (" + name 5941 + "/" + uid + ")"); 5942 5943 mProcessNames.remove(name, uid); 5944 mIsolatedProcesses.remove(app.uid); 5945 if (mHeavyWeightProcess == app) { 5946 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5947 mHeavyWeightProcess.userId, 0)); 5948 mHeavyWeightProcess = null; 5949 } 5950 boolean needRestart = false; 5951 if (app.pid > 0 && app.pid != MY_PID) { 5952 int pid = app.pid; 5953 synchronized (mPidsSelfLocked) { 5954 mPidsSelfLocked.remove(pid); 5955 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5956 } 5957 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5958 if (app.isolated) { 5959 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5960 } 5961 app.kill(reason, true); 5962 handleAppDiedLocked(app, true, allowRestart); 5963 removeLruProcessLocked(app); 5964 5965 if (app.persistent && !app.isolated) { 5966 if (!callerWillRestart) { 5967 addAppLocked(app.info, false, null /* ABI override */); 5968 } else { 5969 needRestart = true; 5970 } 5971 } 5972 } else { 5973 mRemovedProcesses.add(app); 5974 } 5975 5976 return needRestart; 5977 } 5978 5979 private final void processStartTimedOutLocked(ProcessRecord app) { 5980 final int pid = app.pid; 5981 boolean gone = false; 5982 synchronized (mPidsSelfLocked) { 5983 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5984 if (knownApp != null && knownApp.thread == null) { 5985 mPidsSelfLocked.remove(pid); 5986 gone = true; 5987 } 5988 } 5989 5990 if (gone) { 5991 Slog.w(TAG, "Process " + app + " failed to attach"); 5992 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5993 pid, app.uid, app.processName); 5994 mProcessNames.remove(app.processName, app.uid); 5995 mIsolatedProcesses.remove(app.uid); 5996 if (mHeavyWeightProcess == app) { 5997 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5998 mHeavyWeightProcess.userId, 0)); 5999 mHeavyWeightProcess = null; 6000 } 6001 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6002 if (app.isolated) { 6003 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6004 } 6005 // Take care of any launching providers waiting for this process. 6006 checkAppInLaunchingProvidersLocked(app, true); 6007 // Take care of any services that are waiting for the process. 6008 mServices.processStartTimedOutLocked(app); 6009 app.kill("start timeout", true); 6010 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6011 Slog.w(TAG, "Unattached app died before backup, skipping"); 6012 try { 6013 IBackupManager bm = IBackupManager.Stub.asInterface( 6014 ServiceManager.getService(Context.BACKUP_SERVICE)); 6015 bm.agentDisconnected(app.info.packageName); 6016 } catch (RemoteException e) { 6017 // Can't happen; the backup manager is local 6018 } 6019 } 6020 if (isPendingBroadcastProcessLocked(pid)) { 6021 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6022 skipPendingBroadcastLocked(pid); 6023 } 6024 } else { 6025 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6026 } 6027 } 6028 6029 private final boolean attachApplicationLocked(IApplicationThread thread, 6030 int pid) { 6031 6032 // Find the application record that is being attached... either via 6033 // the pid if we are running in multiple processes, or just pull the 6034 // next app record if we are emulating process with anonymous threads. 6035 ProcessRecord app; 6036 if (pid != MY_PID && pid >= 0) { 6037 synchronized (mPidsSelfLocked) { 6038 app = mPidsSelfLocked.get(pid); 6039 } 6040 } else { 6041 app = null; 6042 } 6043 6044 if (app == null) { 6045 Slog.w(TAG, "No pending application record for pid " + pid 6046 + " (IApplicationThread " + thread + "); dropping process"); 6047 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6048 if (pid > 0 && pid != MY_PID) { 6049 Process.killProcessQuiet(pid); 6050 //TODO: Process.killProcessGroup(app.info.uid, pid); 6051 } else { 6052 try { 6053 thread.scheduleExit(); 6054 } catch (Exception e) { 6055 // Ignore exceptions. 6056 } 6057 } 6058 return false; 6059 } 6060 6061 // If this application record is still attached to a previous 6062 // process, clean it up now. 6063 if (app.thread != null) { 6064 handleAppDiedLocked(app, true, true); 6065 } 6066 6067 // Tell the process all about itself. 6068 6069 if (localLOGV) Slog.v( 6070 TAG, "Binding process pid " + pid + " to record " + app); 6071 6072 final String processName = app.processName; 6073 try { 6074 AppDeathRecipient adr = new AppDeathRecipient( 6075 app, pid, thread); 6076 thread.asBinder().linkToDeath(adr, 0); 6077 app.deathRecipient = adr; 6078 } catch (RemoteException e) { 6079 app.resetPackageList(mProcessStats); 6080 startProcessLocked(app, "link fail", processName); 6081 return false; 6082 } 6083 6084 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6085 6086 app.makeActive(thread, mProcessStats); 6087 app.curAdj = app.setAdj = -100; 6088 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6089 app.forcingToForeground = null; 6090 updateProcessForegroundLocked(app, false, false); 6091 app.hasShownUi = false; 6092 app.debugging = false; 6093 app.cached = false; 6094 6095 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6096 6097 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6098 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6099 6100 if (!normalMode) { 6101 Slog.i(TAG, "Launching preboot mode app: " + app); 6102 } 6103 6104 if (localLOGV) Slog.v( 6105 TAG, "New app record " + app 6106 + " thread=" + thread.asBinder() + " pid=" + pid); 6107 try { 6108 int testMode = IApplicationThread.DEBUG_OFF; 6109 if (mDebugApp != null && mDebugApp.equals(processName)) { 6110 testMode = mWaitForDebugger 6111 ? IApplicationThread.DEBUG_WAIT 6112 : IApplicationThread.DEBUG_ON; 6113 app.debugging = true; 6114 if (mDebugTransient) { 6115 mDebugApp = mOrigDebugApp; 6116 mWaitForDebugger = mOrigWaitForDebugger; 6117 } 6118 } 6119 String profileFile = app.instrumentationProfileFile; 6120 ParcelFileDescriptor profileFd = null; 6121 int samplingInterval = 0; 6122 boolean profileAutoStop = false; 6123 if (mProfileApp != null && mProfileApp.equals(processName)) { 6124 mProfileProc = app; 6125 profileFile = mProfileFile; 6126 profileFd = mProfileFd; 6127 samplingInterval = mSamplingInterval; 6128 profileAutoStop = mAutoStopProfiler; 6129 } 6130 boolean enableOpenGlTrace = false; 6131 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6132 enableOpenGlTrace = true; 6133 mOpenGlTraceApp = null; 6134 } 6135 6136 // If the app is being launched for restore or full backup, set it up specially 6137 boolean isRestrictedBackupMode = false; 6138 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6139 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6140 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6141 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6142 } 6143 6144 ensurePackageDexOpt(app.instrumentationInfo != null 6145 ? app.instrumentationInfo.packageName 6146 : app.info.packageName); 6147 if (app.instrumentationClass != null) { 6148 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6149 } 6150 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6151 + processName + " with config " + mConfiguration); 6152 ApplicationInfo appInfo = app.instrumentationInfo != null 6153 ? app.instrumentationInfo : app.info; 6154 app.compat = compatibilityInfoForPackageLocked(appInfo); 6155 if (profileFd != null) { 6156 profileFd = profileFd.dup(); 6157 } 6158 ProfilerInfo profilerInfo = profileFile == null ? null 6159 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6160 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6161 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6162 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6163 isRestrictedBackupMode || !normalMode, app.persistent, 6164 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6165 mCoreSettingsObserver.getCoreSettingsLocked()); 6166 updateLruProcessLocked(app, false, null); 6167 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6168 } catch (Exception e) { 6169 // todo: Yikes! What should we do? For now we will try to 6170 // start another process, but that could easily get us in 6171 // an infinite loop of restarting processes... 6172 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6173 6174 app.resetPackageList(mProcessStats); 6175 app.unlinkDeathRecipient(); 6176 startProcessLocked(app, "bind fail", processName); 6177 return false; 6178 } 6179 6180 // Remove this record from the list of starting applications. 6181 mPersistentStartingProcesses.remove(app); 6182 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6183 "Attach application locked removing on hold: " + app); 6184 mProcessesOnHold.remove(app); 6185 6186 boolean badApp = false; 6187 boolean didSomething = false; 6188 6189 // See if the top visible activity is waiting to run in this process... 6190 if (normalMode) { 6191 try { 6192 if (mStackSupervisor.attachApplicationLocked(app)) { 6193 didSomething = true; 6194 } 6195 } catch (Exception e) { 6196 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6197 badApp = true; 6198 } 6199 } 6200 6201 // Find any services that should be running in this process... 6202 if (!badApp) { 6203 try { 6204 didSomething |= mServices.attachApplicationLocked(app, processName); 6205 } catch (Exception e) { 6206 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6207 badApp = true; 6208 } 6209 } 6210 6211 // Check if a next-broadcast receiver is in this process... 6212 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6213 try { 6214 didSomething |= sendPendingBroadcastsLocked(app); 6215 } catch (Exception e) { 6216 // If the app died trying to launch the receiver we declare it 'bad' 6217 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6218 badApp = true; 6219 } 6220 } 6221 6222 // Check whether the next backup agent is in this process... 6223 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6224 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6225 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6226 try { 6227 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6228 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6229 mBackupTarget.backupMode); 6230 } catch (Exception e) { 6231 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6232 badApp = true; 6233 } 6234 } 6235 6236 if (badApp) { 6237 app.kill("error during init", true); 6238 handleAppDiedLocked(app, false, true); 6239 return false; 6240 } 6241 6242 if (!didSomething) { 6243 updateOomAdjLocked(); 6244 } 6245 6246 return true; 6247 } 6248 6249 @Override 6250 public final void attachApplication(IApplicationThread thread) { 6251 synchronized (this) { 6252 int callingPid = Binder.getCallingPid(); 6253 final long origId = Binder.clearCallingIdentity(); 6254 attachApplicationLocked(thread, callingPid); 6255 Binder.restoreCallingIdentity(origId); 6256 } 6257 } 6258 6259 @Override 6260 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6261 final long origId = Binder.clearCallingIdentity(); 6262 synchronized (this) { 6263 ActivityStack stack = ActivityRecord.getStackLocked(token); 6264 if (stack != null) { 6265 ActivityRecord r = 6266 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6267 if (stopProfiling) { 6268 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6269 try { 6270 mProfileFd.close(); 6271 } catch (IOException e) { 6272 } 6273 clearProfilerLocked(); 6274 } 6275 } 6276 } 6277 } 6278 Binder.restoreCallingIdentity(origId); 6279 } 6280 6281 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6282 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6283 finishBooting? 1 : 0, enableScreen ? 1 : 0)); 6284 } 6285 6286 void enableScreenAfterBoot() { 6287 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6288 SystemClock.uptimeMillis()); 6289 mWindowManager.enableScreenAfterBoot(); 6290 6291 synchronized (this) { 6292 updateEventDispatchingLocked(); 6293 } 6294 } 6295 6296 @Override 6297 public void showBootMessage(final CharSequence msg, final boolean always) { 6298 enforceNotIsolatedCaller("showBootMessage"); 6299 mWindowManager.showBootMessage(msg, always); 6300 } 6301 6302 @Override 6303 public void keyguardWaitingForActivityDrawn() { 6304 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6305 final long token = Binder.clearCallingIdentity(); 6306 try { 6307 synchronized (this) { 6308 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6309 mWindowManager.keyguardWaitingForActivityDrawn(); 6310 if (mLockScreenShown) { 6311 mLockScreenShown = false; 6312 comeOutOfSleepIfNeededLocked(); 6313 } 6314 } 6315 } finally { 6316 Binder.restoreCallingIdentity(token); 6317 } 6318 } 6319 6320 final void finishBooting() { 6321 synchronized (this) { 6322 if (!mBootAnimationComplete) { 6323 mCallFinishBooting = true; 6324 return; 6325 } 6326 mCallFinishBooting = false; 6327 } 6328 6329 // Register receivers to handle package update events 6330 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false); 6331 6332 // Let system services know. 6333 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6334 6335 synchronized (this) { 6336 // Ensure that any processes we had put on hold are now started 6337 // up. 6338 final int NP = mProcessesOnHold.size(); 6339 if (NP > 0) { 6340 ArrayList<ProcessRecord> procs = 6341 new ArrayList<ProcessRecord>(mProcessesOnHold); 6342 for (int ip=0; ip<NP; ip++) { 6343 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6344 + procs.get(ip)); 6345 startProcessLocked(procs.get(ip), "on-hold", null); 6346 } 6347 } 6348 6349 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6350 // Start looking for apps that are abusing wake locks. 6351 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6352 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6353 // Tell anyone interested that we are done booting! 6354 SystemProperties.set("sys.boot_completed", "1"); 6355 6356 // And trigger dev.bootcomplete if we are not showing encryption progress 6357 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6358 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6359 SystemProperties.set("dev.bootcomplete", "1"); 6360 } 6361 for (int i=0; i<mStartedUsers.size(); i++) { 6362 UserStartedState uss = mStartedUsers.valueAt(i); 6363 if (uss.mState == UserStartedState.STATE_BOOTING) { 6364 uss.mState = UserStartedState.STATE_RUNNING; 6365 final int userId = mStartedUsers.keyAt(i); 6366 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6367 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6368 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6369 broadcastIntentLocked(null, null, intent, null, 6370 new IIntentReceiver.Stub() { 6371 @Override 6372 public void performReceive(Intent intent, int resultCode, 6373 String data, Bundle extras, boolean ordered, 6374 boolean sticky, int sendingUser) { 6375 synchronized (ActivityManagerService.this) { 6376 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6377 true, false); 6378 } 6379 } 6380 }, 6381 0, null, null, 6382 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6383 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6384 userId); 6385 } 6386 } 6387 scheduleStartProfilesLocked(); 6388 } 6389 } 6390 } 6391 6392 @Override 6393 public void bootAnimationComplete() { 6394 final boolean callFinishBooting; 6395 synchronized (this) { 6396 callFinishBooting = mCallFinishBooting; 6397 mBootAnimationComplete = true; 6398 } 6399 if (callFinishBooting) { 6400 finishBooting(); 6401 } 6402 } 6403 6404 final void ensureBootCompleted() { 6405 boolean booting; 6406 boolean enableScreen; 6407 synchronized (this) { 6408 booting = mBooting; 6409 mBooting = false; 6410 enableScreen = !mBooted; 6411 mBooted = true; 6412 } 6413 6414 if (booting) { 6415 finishBooting(); 6416 } 6417 6418 if (enableScreen) { 6419 enableScreenAfterBoot(); 6420 } 6421 } 6422 6423 @Override 6424 public final void activityResumed(IBinder token) { 6425 final long origId = Binder.clearCallingIdentity(); 6426 synchronized(this) { 6427 ActivityStack stack = ActivityRecord.getStackLocked(token); 6428 if (stack != null) { 6429 ActivityRecord.activityResumedLocked(token); 6430 } 6431 } 6432 Binder.restoreCallingIdentity(origId); 6433 } 6434 6435 @Override 6436 public final void activityPaused(IBinder token) { 6437 final long origId = Binder.clearCallingIdentity(); 6438 synchronized(this) { 6439 ActivityStack stack = ActivityRecord.getStackLocked(token); 6440 if (stack != null) { 6441 stack.activityPausedLocked(token, false); 6442 } 6443 } 6444 Binder.restoreCallingIdentity(origId); 6445 } 6446 6447 @Override 6448 public final void activityStopped(IBinder token, Bundle icicle, 6449 PersistableBundle persistentState, CharSequence description) { 6450 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6451 6452 // Refuse possible leaked file descriptors 6453 if (icicle != null && icicle.hasFileDescriptors()) { 6454 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6455 } 6456 6457 final long origId = Binder.clearCallingIdentity(); 6458 6459 synchronized (this) { 6460 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6461 if (r != null) { 6462 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6463 } 6464 } 6465 6466 trimApplications(); 6467 6468 Binder.restoreCallingIdentity(origId); 6469 } 6470 6471 @Override 6472 public final void activityDestroyed(IBinder token) { 6473 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6474 synchronized (this) { 6475 ActivityStack stack = ActivityRecord.getStackLocked(token); 6476 if (stack != null) { 6477 stack.activityDestroyedLocked(token); 6478 } 6479 } 6480 } 6481 6482 @Override 6483 public final void backgroundResourcesReleased(IBinder token) { 6484 final long origId = Binder.clearCallingIdentity(); 6485 try { 6486 synchronized (this) { 6487 ActivityStack stack = ActivityRecord.getStackLocked(token); 6488 if (stack != null) { 6489 stack.backgroundResourcesReleased(token); 6490 } 6491 } 6492 } finally { 6493 Binder.restoreCallingIdentity(origId); 6494 } 6495 } 6496 6497 @Override 6498 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6499 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6500 } 6501 6502 @Override 6503 public final void notifyEnterAnimationComplete(IBinder token) { 6504 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6505 } 6506 6507 @Override 6508 public String getCallingPackage(IBinder token) { 6509 synchronized (this) { 6510 ActivityRecord r = getCallingRecordLocked(token); 6511 return r != null ? r.info.packageName : null; 6512 } 6513 } 6514 6515 @Override 6516 public ComponentName getCallingActivity(IBinder token) { 6517 synchronized (this) { 6518 ActivityRecord r = getCallingRecordLocked(token); 6519 return r != null ? r.intent.getComponent() : null; 6520 } 6521 } 6522 6523 private ActivityRecord getCallingRecordLocked(IBinder token) { 6524 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6525 if (r == null) { 6526 return null; 6527 } 6528 return r.resultTo; 6529 } 6530 6531 @Override 6532 public ComponentName getActivityClassForToken(IBinder token) { 6533 synchronized(this) { 6534 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6535 if (r == null) { 6536 return null; 6537 } 6538 return r.intent.getComponent(); 6539 } 6540 } 6541 6542 @Override 6543 public String getPackageForToken(IBinder token) { 6544 synchronized(this) { 6545 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6546 if (r == null) { 6547 return null; 6548 } 6549 return r.packageName; 6550 } 6551 } 6552 6553 @Override 6554 public IIntentSender getIntentSender(int type, 6555 String packageName, IBinder token, String resultWho, 6556 int requestCode, Intent[] intents, String[] resolvedTypes, 6557 int flags, Bundle options, int userId) { 6558 enforceNotIsolatedCaller("getIntentSender"); 6559 // Refuse possible leaked file descriptors 6560 if (intents != null) { 6561 if (intents.length < 1) { 6562 throw new IllegalArgumentException("Intents array length must be >= 1"); 6563 } 6564 for (int i=0; i<intents.length; i++) { 6565 Intent intent = intents[i]; 6566 if (intent != null) { 6567 if (intent.hasFileDescriptors()) { 6568 throw new IllegalArgumentException("File descriptors passed in Intent"); 6569 } 6570 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6571 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6572 throw new IllegalArgumentException( 6573 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6574 } 6575 intents[i] = new Intent(intent); 6576 } 6577 } 6578 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6579 throw new IllegalArgumentException( 6580 "Intent array length does not match resolvedTypes length"); 6581 } 6582 } 6583 if (options != null) { 6584 if (options.hasFileDescriptors()) { 6585 throw new IllegalArgumentException("File descriptors passed in options"); 6586 } 6587 } 6588 6589 synchronized(this) { 6590 int callingUid = Binder.getCallingUid(); 6591 int origUserId = userId; 6592 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6593 type == ActivityManager.INTENT_SENDER_BROADCAST, 6594 ALLOW_NON_FULL, "getIntentSender", null); 6595 if (origUserId == UserHandle.USER_CURRENT) { 6596 // We don't want to evaluate this until the pending intent is 6597 // actually executed. However, we do want to always do the 6598 // security checking for it above. 6599 userId = UserHandle.USER_CURRENT; 6600 } 6601 try { 6602 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6603 int uid = AppGlobals.getPackageManager() 6604 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6605 if (!UserHandle.isSameApp(callingUid, uid)) { 6606 String msg = "Permission Denial: getIntentSender() from pid=" 6607 + Binder.getCallingPid() 6608 + ", uid=" + Binder.getCallingUid() 6609 + ", (need uid=" + uid + ")" 6610 + " is not allowed to send as package " + packageName; 6611 Slog.w(TAG, msg); 6612 throw new SecurityException(msg); 6613 } 6614 } 6615 6616 return getIntentSenderLocked(type, packageName, callingUid, userId, 6617 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6618 6619 } catch (RemoteException e) { 6620 throw new SecurityException(e); 6621 } 6622 } 6623 } 6624 6625 IIntentSender getIntentSenderLocked(int type, String packageName, 6626 int callingUid, int userId, IBinder token, String resultWho, 6627 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6628 Bundle options) { 6629 if (DEBUG_MU) 6630 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6631 ActivityRecord activity = null; 6632 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6633 activity = ActivityRecord.isInStackLocked(token); 6634 if (activity == null) { 6635 return null; 6636 } 6637 if (activity.finishing) { 6638 return null; 6639 } 6640 } 6641 6642 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6643 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6644 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6645 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6646 |PendingIntent.FLAG_UPDATE_CURRENT); 6647 6648 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6649 type, packageName, activity, resultWho, 6650 requestCode, intents, resolvedTypes, flags, options, userId); 6651 WeakReference<PendingIntentRecord> ref; 6652 ref = mIntentSenderRecords.get(key); 6653 PendingIntentRecord rec = ref != null ? ref.get() : null; 6654 if (rec != null) { 6655 if (!cancelCurrent) { 6656 if (updateCurrent) { 6657 if (rec.key.requestIntent != null) { 6658 rec.key.requestIntent.replaceExtras(intents != null ? 6659 intents[intents.length - 1] : null); 6660 } 6661 if (intents != null) { 6662 intents[intents.length-1] = rec.key.requestIntent; 6663 rec.key.allIntents = intents; 6664 rec.key.allResolvedTypes = resolvedTypes; 6665 } else { 6666 rec.key.allIntents = null; 6667 rec.key.allResolvedTypes = null; 6668 } 6669 } 6670 return rec; 6671 } 6672 rec.canceled = true; 6673 mIntentSenderRecords.remove(key); 6674 } 6675 if (noCreate) { 6676 return rec; 6677 } 6678 rec = new PendingIntentRecord(this, key, callingUid); 6679 mIntentSenderRecords.put(key, rec.ref); 6680 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6681 if (activity.pendingResults == null) { 6682 activity.pendingResults 6683 = new HashSet<WeakReference<PendingIntentRecord>>(); 6684 } 6685 activity.pendingResults.add(rec.ref); 6686 } 6687 return rec; 6688 } 6689 6690 @Override 6691 public void cancelIntentSender(IIntentSender sender) { 6692 if (!(sender instanceof PendingIntentRecord)) { 6693 return; 6694 } 6695 synchronized(this) { 6696 PendingIntentRecord rec = (PendingIntentRecord)sender; 6697 try { 6698 int uid = AppGlobals.getPackageManager() 6699 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6700 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6701 String msg = "Permission Denial: cancelIntentSender() from pid=" 6702 + Binder.getCallingPid() 6703 + ", uid=" + Binder.getCallingUid() 6704 + " is not allowed to cancel packges " 6705 + rec.key.packageName; 6706 Slog.w(TAG, msg); 6707 throw new SecurityException(msg); 6708 } 6709 } catch (RemoteException e) { 6710 throw new SecurityException(e); 6711 } 6712 cancelIntentSenderLocked(rec, true); 6713 } 6714 } 6715 6716 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6717 rec.canceled = true; 6718 mIntentSenderRecords.remove(rec.key); 6719 if (cleanActivity && rec.key.activity != null) { 6720 rec.key.activity.pendingResults.remove(rec.ref); 6721 } 6722 } 6723 6724 @Override 6725 public String getPackageForIntentSender(IIntentSender pendingResult) { 6726 if (!(pendingResult instanceof PendingIntentRecord)) { 6727 return null; 6728 } 6729 try { 6730 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6731 return res.key.packageName; 6732 } catch (ClassCastException e) { 6733 } 6734 return null; 6735 } 6736 6737 @Override 6738 public int getUidForIntentSender(IIntentSender sender) { 6739 if (sender instanceof PendingIntentRecord) { 6740 try { 6741 PendingIntentRecord res = (PendingIntentRecord)sender; 6742 return res.uid; 6743 } catch (ClassCastException e) { 6744 } 6745 } 6746 return -1; 6747 } 6748 6749 @Override 6750 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6751 if (!(pendingResult instanceof PendingIntentRecord)) { 6752 return false; 6753 } 6754 try { 6755 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6756 if (res.key.allIntents == null) { 6757 return false; 6758 } 6759 for (int i=0; i<res.key.allIntents.length; i++) { 6760 Intent intent = res.key.allIntents[i]; 6761 if (intent.getPackage() != null && intent.getComponent() != null) { 6762 return false; 6763 } 6764 } 6765 return true; 6766 } catch (ClassCastException e) { 6767 } 6768 return false; 6769 } 6770 6771 @Override 6772 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6773 if (!(pendingResult instanceof PendingIntentRecord)) { 6774 return false; 6775 } 6776 try { 6777 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6778 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6779 return true; 6780 } 6781 return false; 6782 } catch (ClassCastException e) { 6783 } 6784 return false; 6785 } 6786 6787 @Override 6788 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6789 if (!(pendingResult instanceof PendingIntentRecord)) { 6790 return null; 6791 } 6792 try { 6793 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6794 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6795 } catch (ClassCastException e) { 6796 } 6797 return null; 6798 } 6799 6800 @Override 6801 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6802 if (!(pendingResult instanceof PendingIntentRecord)) { 6803 return null; 6804 } 6805 try { 6806 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6807 Intent intent = res.key.requestIntent; 6808 if (intent != null) { 6809 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6810 || res.lastTagPrefix.equals(prefix))) { 6811 return res.lastTag; 6812 } 6813 res.lastTagPrefix = prefix; 6814 StringBuilder sb = new StringBuilder(128); 6815 if (prefix != null) { 6816 sb.append(prefix); 6817 } 6818 if (intent.getAction() != null) { 6819 sb.append(intent.getAction()); 6820 } else if (intent.getComponent() != null) { 6821 intent.getComponent().appendShortString(sb); 6822 } else { 6823 sb.append("?"); 6824 } 6825 return res.lastTag = sb.toString(); 6826 } 6827 } catch (ClassCastException e) { 6828 } 6829 return null; 6830 } 6831 6832 @Override 6833 public void setProcessLimit(int max) { 6834 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6835 "setProcessLimit()"); 6836 synchronized (this) { 6837 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6838 mProcessLimitOverride = max; 6839 } 6840 trimApplications(); 6841 } 6842 6843 @Override 6844 public int getProcessLimit() { 6845 synchronized (this) { 6846 return mProcessLimitOverride; 6847 } 6848 } 6849 6850 void foregroundTokenDied(ForegroundToken token) { 6851 synchronized (ActivityManagerService.this) { 6852 synchronized (mPidsSelfLocked) { 6853 ForegroundToken cur 6854 = mForegroundProcesses.get(token.pid); 6855 if (cur != token) { 6856 return; 6857 } 6858 mForegroundProcesses.remove(token.pid); 6859 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6860 if (pr == null) { 6861 return; 6862 } 6863 pr.forcingToForeground = null; 6864 updateProcessForegroundLocked(pr, false, false); 6865 } 6866 updateOomAdjLocked(); 6867 } 6868 } 6869 6870 @Override 6871 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6872 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6873 "setProcessForeground()"); 6874 synchronized(this) { 6875 boolean changed = false; 6876 6877 synchronized (mPidsSelfLocked) { 6878 ProcessRecord pr = mPidsSelfLocked.get(pid); 6879 if (pr == null && isForeground) { 6880 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6881 return; 6882 } 6883 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6884 if (oldToken != null) { 6885 oldToken.token.unlinkToDeath(oldToken, 0); 6886 mForegroundProcesses.remove(pid); 6887 if (pr != null) { 6888 pr.forcingToForeground = null; 6889 } 6890 changed = true; 6891 } 6892 if (isForeground && token != null) { 6893 ForegroundToken newToken = new ForegroundToken() { 6894 @Override 6895 public void binderDied() { 6896 foregroundTokenDied(this); 6897 } 6898 }; 6899 newToken.pid = pid; 6900 newToken.token = token; 6901 try { 6902 token.linkToDeath(newToken, 0); 6903 mForegroundProcesses.put(pid, newToken); 6904 pr.forcingToForeground = token; 6905 changed = true; 6906 } catch (RemoteException e) { 6907 // If the process died while doing this, we will later 6908 // do the cleanup with the process death link. 6909 } 6910 } 6911 } 6912 6913 if (changed) { 6914 updateOomAdjLocked(); 6915 } 6916 } 6917 } 6918 6919 // ========================================================= 6920 // PERMISSIONS 6921 // ========================================================= 6922 6923 static class PermissionController extends IPermissionController.Stub { 6924 ActivityManagerService mActivityManagerService; 6925 PermissionController(ActivityManagerService activityManagerService) { 6926 mActivityManagerService = activityManagerService; 6927 } 6928 6929 @Override 6930 public boolean checkPermission(String permission, int pid, int uid) { 6931 return mActivityManagerService.checkPermission(permission, pid, 6932 uid) == PackageManager.PERMISSION_GRANTED; 6933 } 6934 } 6935 6936 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6937 @Override 6938 public int checkComponentPermission(String permission, int pid, int uid, 6939 int owningUid, boolean exported) { 6940 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6941 owningUid, exported); 6942 } 6943 6944 @Override 6945 public Object getAMSLock() { 6946 return ActivityManagerService.this; 6947 } 6948 } 6949 6950 /** 6951 * This can be called with or without the global lock held. 6952 */ 6953 int checkComponentPermission(String permission, int pid, int uid, 6954 int owningUid, boolean exported) { 6955 // We might be performing an operation on behalf of an indirect binder 6956 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6957 // client identity accordingly before proceeding. 6958 Identity tlsIdentity = sCallerIdentity.get(); 6959 if (tlsIdentity != null) { 6960 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6961 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6962 uid = tlsIdentity.uid; 6963 pid = tlsIdentity.pid; 6964 } 6965 6966 if (pid == MY_PID) { 6967 return PackageManager.PERMISSION_GRANTED; 6968 } 6969 6970 return ActivityManager.checkComponentPermission(permission, uid, 6971 owningUid, exported); 6972 } 6973 6974 /** 6975 * As the only public entry point for permissions checking, this method 6976 * can enforce the semantic that requesting a check on a null global 6977 * permission is automatically denied. (Internally a null permission 6978 * string is used when calling {@link #checkComponentPermission} in cases 6979 * when only uid-based security is needed.) 6980 * 6981 * This can be called with or without the global lock held. 6982 */ 6983 @Override 6984 public int checkPermission(String permission, int pid, int uid) { 6985 if (permission == null) { 6986 return PackageManager.PERMISSION_DENIED; 6987 } 6988 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6989 } 6990 6991 /** 6992 * Binder IPC calls go through the public entry point. 6993 * This can be called with or without the global lock held. 6994 */ 6995 int checkCallingPermission(String permission) { 6996 return checkPermission(permission, 6997 Binder.getCallingPid(), 6998 UserHandle.getAppId(Binder.getCallingUid())); 6999 } 7000 7001 /** 7002 * This can be called with or without the global lock held. 7003 */ 7004 void enforceCallingPermission(String permission, String func) { 7005 if (checkCallingPermission(permission) 7006 == PackageManager.PERMISSION_GRANTED) { 7007 return; 7008 } 7009 7010 String msg = "Permission Denial: " + func + " from pid=" 7011 + Binder.getCallingPid() 7012 + ", uid=" + Binder.getCallingUid() 7013 + " requires " + permission; 7014 Slog.w(TAG, msg); 7015 throw new SecurityException(msg); 7016 } 7017 7018 /** 7019 * Determine if UID is holding permissions required to access {@link Uri} in 7020 * the given {@link ProviderInfo}. Final permission checking is always done 7021 * in {@link ContentProvider}. 7022 */ 7023 private final boolean checkHoldingPermissionsLocked( 7024 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 7025 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7026 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 7027 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 7028 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 7029 != PERMISSION_GRANTED) { 7030 return false; 7031 } 7032 } 7033 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 7034 } 7035 7036 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 7037 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 7038 if (pi.applicationInfo.uid == uid) { 7039 return true; 7040 } else if (!pi.exported) { 7041 return false; 7042 } 7043 7044 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 7045 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 7046 try { 7047 // check if target holds top-level <provider> permissions 7048 if (!readMet && pi.readPermission != null && considerUidPermissions 7049 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 7050 readMet = true; 7051 } 7052 if (!writeMet && pi.writePermission != null && considerUidPermissions 7053 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 7054 writeMet = true; 7055 } 7056 7057 // track if unprotected read/write is allowed; any denied 7058 // <path-permission> below removes this ability 7059 boolean allowDefaultRead = pi.readPermission == null; 7060 boolean allowDefaultWrite = pi.writePermission == null; 7061 7062 // check if target holds any <path-permission> that match uri 7063 final PathPermission[] pps = pi.pathPermissions; 7064 if (pps != null) { 7065 final String path = grantUri.uri.getPath(); 7066 int i = pps.length; 7067 while (i > 0 && (!readMet || !writeMet)) { 7068 i--; 7069 PathPermission pp = pps[i]; 7070 if (pp.match(path)) { 7071 if (!readMet) { 7072 final String pprperm = pp.getReadPermission(); 7073 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7074 + pprperm + " for " + pp.getPath() 7075 + ": match=" + pp.match(path) 7076 + " check=" + pm.checkUidPermission(pprperm, uid)); 7077 if (pprperm != null) { 7078 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7079 == PERMISSION_GRANTED) { 7080 readMet = true; 7081 } else { 7082 allowDefaultRead = false; 7083 } 7084 } 7085 } 7086 if (!writeMet) { 7087 final String ppwperm = pp.getWritePermission(); 7088 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7089 + ppwperm + " for " + pp.getPath() 7090 + ": match=" + pp.match(path) 7091 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7092 if (ppwperm != null) { 7093 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7094 == PERMISSION_GRANTED) { 7095 writeMet = true; 7096 } else { 7097 allowDefaultWrite = false; 7098 } 7099 } 7100 } 7101 } 7102 } 7103 } 7104 7105 // grant unprotected <provider> read/write, if not blocked by 7106 // <path-permission> above 7107 if (allowDefaultRead) readMet = true; 7108 if (allowDefaultWrite) writeMet = true; 7109 7110 } catch (RemoteException e) { 7111 return false; 7112 } 7113 7114 return readMet && writeMet; 7115 } 7116 7117 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7118 ProviderInfo pi = null; 7119 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7120 if (cpr != null) { 7121 pi = cpr.info; 7122 } else { 7123 try { 7124 pi = AppGlobals.getPackageManager().resolveContentProvider( 7125 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7126 } catch (RemoteException ex) { 7127 } 7128 } 7129 return pi; 7130 } 7131 7132 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7133 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7134 if (targetUris != null) { 7135 return targetUris.get(grantUri); 7136 } 7137 return null; 7138 } 7139 7140 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7141 String targetPkg, int targetUid, GrantUri grantUri) { 7142 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7143 if (targetUris == null) { 7144 targetUris = Maps.newArrayMap(); 7145 mGrantedUriPermissions.put(targetUid, targetUris); 7146 } 7147 7148 UriPermission perm = targetUris.get(grantUri); 7149 if (perm == null) { 7150 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7151 targetUris.put(grantUri, perm); 7152 } 7153 7154 return perm; 7155 } 7156 7157 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7158 final int modeFlags) { 7159 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7160 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7161 : UriPermission.STRENGTH_OWNED; 7162 7163 // Root gets to do everything. 7164 if (uid == 0) { 7165 return true; 7166 } 7167 7168 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7169 if (perms == null) return false; 7170 7171 // First look for exact match 7172 final UriPermission exactPerm = perms.get(grantUri); 7173 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7174 return true; 7175 } 7176 7177 // No exact match, look for prefixes 7178 final int N = perms.size(); 7179 for (int i = 0; i < N; i++) { 7180 final UriPermission perm = perms.valueAt(i); 7181 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7182 && perm.getStrength(modeFlags) >= minStrength) { 7183 return true; 7184 } 7185 } 7186 7187 return false; 7188 } 7189 7190 /** 7191 * @param uri This uri must NOT contain an embedded userId. 7192 * @param userId The userId in which the uri is to be resolved. 7193 */ 7194 @Override 7195 public int checkUriPermission(Uri uri, int pid, int uid, 7196 final int modeFlags, int userId) { 7197 enforceNotIsolatedCaller("checkUriPermission"); 7198 7199 // Another redirected-binder-call permissions check as in 7200 // {@link checkComponentPermission}. 7201 Identity tlsIdentity = sCallerIdentity.get(); 7202 if (tlsIdentity != null) { 7203 uid = tlsIdentity.uid; 7204 pid = tlsIdentity.pid; 7205 } 7206 7207 // Our own process gets to do everything. 7208 if (pid == MY_PID) { 7209 return PackageManager.PERMISSION_GRANTED; 7210 } 7211 synchronized (this) { 7212 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7213 ? PackageManager.PERMISSION_GRANTED 7214 : PackageManager.PERMISSION_DENIED; 7215 } 7216 } 7217 7218 /** 7219 * Check if the targetPkg can be granted permission to access uri by 7220 * the callingUid using the given modeFlags. Throws a security exception 7221 * if callingUid is not allowed to do this. Returns the uid of the target 7222 * if the URI permission grant should be performed; returns -1 if it is not 7223 * needed (for example targetPkg already has permission to access the URI). 7224 * If you already know the uid of the target, you can supply it in 7225 * lastTargetUid else set that to -1. 7226 */ 7227 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7228 final int modeFlags, int lastTargetUid) { 7229 if (!Intent.isAccessUriMode(modeFlags)) { 7230 return -1; 7231 } 7232 7233 if (targetPkg != null) { 7234 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7235 "Checking grant " + targetPkg + " permission to " + grantUri); 7236 } 7237 7238 final IPackageManager pm = AppGlobals.getPackageManager(); 7239 7240 // If this is not a content: uri, we can't do anything with it. 7241 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7242 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7243 "Can't grant URI permission for non-content URI: " + grantUri); 7244 return -1; 7245 } 7246 7247 final String authority = grantUri.uri.getAuthority(); 7248 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7249 if (pi == null) { 7250 Slog.w(TAG, "No content provider found for permission check: " + 7251 grantUri.uri.toSafeString()); 7252 return -1; 7253 } 7254 7255 int targetUid = lastTargetUid; 7256 if (targetUid < 0 && targetPkg != null) { 7257 try { 7258 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7259 if (targetUid < 0) { 7260 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7261 "Can't grant URI permission no uid for: " + targetPkg); 7262 return -1; 7263 } 7264 } catch (RemoteException ex) { 7265 return -1; 7266 } 7267 } 7268 7269 if (targetUid >= 0) { 7270 // First... does the target actually need this permission? 7271 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7272 // No need to grant the target this permission. 7273 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7274 "Target " + targetPkg + " already has full permission to " + grantUri); 7275 return -1; 7276 } 7277 } else { 7278 // First... there is no target package, so can anyone access it? 7279 boolean allowed = pi.exported; 7280 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7281 if (pi.readPermission != null) { 7282 allowed = false; 7283 } 7284 } 7285 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7286 if (pi.writePermission != null) { 7287 allowed = false; 7288 } 7289 } 7290 if (allowed) { 7291 return -1; 7292 } 7293 } 7294 7295 /* There is a special cross user grant if: 7296 * - The target is on another user. 7297 * - Apps on the current user can access the uri without any uid permissions. 7298 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7299 * grant uri permissions. 7300 */ 7301 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7302 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7303 modeFlags, false /*without considering the uid permissions*/); 7304 7305 // Second... is the provider allowing granting of URI permissions? 7306 if (!specialCrossUserGrant) { 7307 if (!pi.grantUriPermissions) { 7308 throw new SecurityException("Provider " + pi.packageName 7309 + "/" + pi.name 7310 + " does not allow granting of Uri permissions (uri " 7311 + grantUri + ")"); 7312 } 7313 if (pi.uriPermissionPatterns != null) { 7314 final int N = pi.uriPermissionPatterns.length; 7315 boolean allowed = false; 7316 for (int i=0; i<N; i++) { 7317 if (pi.uriPermissionPatterns[i] != null 7318 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7319 allowed = true; 7320 break; 7321 } 7322 } 7323 if (!allowed) { 7324 throw new SecurityException("Provider " + pi.packageName 7325 + "/" + pi.name 7326 + " does not allow granting of permission to path of Uri " 7327 + grantUri); 7328 } 7329 } 7330 } 7331 7332 // Third... does the caller itself have permission to access 7333 // this uri? 7334 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7335 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7336 // Require they hold a strong enough Uri permission 7337 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7338 throw new SecurityException("Uid " + callingUid 7339 + " does not have permission to uri " + grantUri); 7340 } 7341 } 7342 } 7343 return targetUid; 7344 } 7345 7346 /** 7347 * @param uri This uri must NOT contain an embedded userId. 7348 * @param userId The userId in which the uri is to be resolved. 7349 */ 7350 @Override 7351 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7352 final int modeFlags, int userId) { 7353 enforceNotIsolatedCaller("checkGrantUriPermission"); 7354 synchronized(this) { 7355 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7356 new GrantUri(userId, uri, false), modeFlags, -1); 7357 } 7358 } 7359 7360 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7361 final int modeFlags, UriPermissionOwner owner) { 7362 if (!Intent.isAccessUriMode(modeFlags)) { 7363 return; 7364 } 7365 7366 // So here we are: the caller has the assumed permission 7367 // to the uri, and the target doesn't. Let's now give this to 7368 // the target. 7369 7370 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7371 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7372 7373 final String authority = grantUri.uri.getAuthority(); 7374 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7375 if (pi == null) { 7376 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7377 return; 7378 } 7379 7380 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7381 grantUri.prefix = true; 7382 } 7383 final UriPermission perm = findOrCreateUriPermissionLocked( 7384 pi.packageName, targetPkg, targetUid, grantUri); 7385 perm.grantModes(modeFlags, owner); 7386 } 7387 7388 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7389 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7390 if (targetPkg == null) { 7391 throw new NullPointerException("targetPkg"); 7392 } 7393 int targetUid; 7394 final IPackageManager pm = AppGlobals.getPackageManager(); 7395 try { 7396 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7397 } catch (RemoteException ex) { 7398 return; 7399 } 7400 7401 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7402 targetUid); 7403 if (targetUid < 0) { 7404 return; 7405 } 7406 7407 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7408 owner); 7409 } 7410 7411 static class NeededUriGrants extends ArrayList<GrantUri> { 7412 final String targetPkg; 7413 final int targetUid; 7414 final int flags; 7415 7416 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7417 this.targetPkg = targetPkg; 7418 this.targetUid = targetUid; 7419 this.flags = flags; 7420 } 7421 } 7422 7423 /** 7424 * Like checkGrantUriPermissionLocked, but takes an Intent. 7425 */ 7426 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7427 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7428 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7429 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7430 + " clip=" + (intent != null ? intent.getClipData() : null) 7431 + " from " + intent + "; flags=0x" 7432 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7433 7434 if (targetPkg == null) { 7435 throw new NullPointerException("targetPkg"); 7436 } 7437 7438 if (intent == null) { 7439 return null; 7440 } 7441 Uri data = intent.getData(); 7442 ClipData clip = intent.getClipData(); 7443 if (data == null && clip == null) { 7444 return null; 7445 } 7446 // Default userId for uris in the intent (if they don't specify it themselves) 7447 int contentUserHint = intent.getContentUserHint(); 7448 if (contentUserHint == UserHandle.USER_CURRENT) { 7449 contentUserHint = UserHandle.getUserId(callingUid); 7450 } 7451 final IPackageManager pm = AppGlobals.getPackageManager(); 7452 int targetUid; 7453 if (needed != null) { 7454 targetUid = needed.targetUid; 7455 } else { 7456 try { 7457 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7458 } catch (RemoteException ex) { 7459 return null; 7460 } 7461 if (targetUid < 0) { 7462 if (DEBUG_URI_PERMISSION) { 7463 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7464 + " on user " + targetUserId); 7465 } 7466 return null; 7467 } 7468 } 7469 if (data != null) { 7470 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7471 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7472 targetUid); 7473 if (targetUid > 0) { 7474 if (needed == null) { 7475 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7476 } 7477 needed.add(grantUri); 7478 } 7479 } 7480 if (clip != null) { 7481 for (int i=0; i<clip.getItemCount(); i++) { 7482 Uri uri = clip.getItemAt(i).getUri(); 7483 if (uri != null) { 7484 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7485 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7486 targetUid); 7487 if (targetUid > 0) { 7488 if (needed == null) { 7489 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7490 } 7491 needed.add(grantUri); 7492 } 7493 } else { 7494 Intent clipIntent = clip.getItemAt(i).getIntent(); 7495 if (clipIntent != null) { 7496 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7497 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7498 if (newNeeded != null) { 7499 needed = newNeeded; 7500 } 7501 } 7502 } 7503 } 7504 } 7505 7506 return needed; 7507 } 7508 7509 /** 7510 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7511 */ 7512 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7513 UriPermissionOwner owner) { 7514 if (needed != null) { 7515 for (int i=0; i<needed.size(); i++) { 7516 GrantUri grantUri = needed.get(i); 7517 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7518 grantUri, needed.flags, owner); 7519 } 7520 } 7521 } 7522 7523 void grantUriPermissionFromIntentLocked(int callingUid, 7524 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7525 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7526 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7527 if (needed == null) { 7528 return; 7529 } 7530 7531 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7532 } 7533 7534 /** 7535 * @param uri This uri must NOT contain an embedded userId. 7536 * @param userId The userId in which the uri is to be resolved. 7537 */ 7538 @Override 7539 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7540 final int modeFlags, int userId) { 7541 enforceNotIsolatedCaller("grantUriPermission"); 7542 GrantUri grantUri = new GrantUri(userId, uri, false); 7543 synchronized(this) { 7544 final ProcessRecord r = getRecordForAppLocked(caller); 7545 if (r == null) { 7546 throw new SecurityException("Unable to find app for caller " 7547 + caller 7548 + " when granting permission to uri " + grantUri); 7549 } 7550 if (targetPkg == null) { 7551 throw new IllegalArgumentException("null target"); 7552 } 7553 if (grantUri == null) { 7554 throw new IllegalArgumentException("null uri"); 7555 } 7556 7557 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7558 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7559 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7560 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7561 7562 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7563 UserHandle.getUserId(r.uid)); 7564 } 7565 } 7566 7567 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7568 if (perm.modeFlags == 0) { 7569 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7570 perm.targetUid); 7571 if (perms != null) { 7572 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7573 "Removing " + perm.targetUid + " permission to " + perm.uri); 7574 7575 perms.remove(perm.uri); 7576 if (perms.isEmpty()) { 7577 mGrantedUriPermissions.remove(perm.targetUid); 7578 } 7579 } 7580 } 7581 } 7582 7583 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7584 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7585 7586 final IPackageManager pm = AppGlobals.getPackageManager(); 7587 final String authority = grantUri.uri.getAuthority(); 7588 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7589 if (pi == null) { 7590 Slog.w(TAG, "No content provider found for permission revoke: " 7591 + grantUri.toSafeString()); 7592 return; 7593 } 7594 7595 // Does the caller have this permission on the URI? 7596 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7597 // If they don't have direct access to the URI, then revoke any 7598 // ownerless URI permissions that have been granted to them. 7599 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7600 if (perms != null) { 7601 boolean persistChanged = false; 7602 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7603 final UriPermission perm = it.next(); 7604 if (perm.uri.sourceUserId == grantUri.sourceUserId 7605 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7606 if (DEBUG_URI_PERMISSION) 7607 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7608 " permission to " + perm.uri); 7609 persistChanged |= perm.revokeModes( 7610 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7611 if (perm.modeFlags == 0) { 7612 it.remove(); 7613 } 7614 } 7615 } 7616 if (perms.isEmpty()) { 7617 mGrantedUriPermissions.remove(callingUid); 7618 } 7619 if (persistChanged) { 7620 schedulePersistUriGrants(); 7621 } 7622 } 7623 return; 7624 } 7625 7626 boolean persistChanged = false; 7627 7628 // Go through all of the permissions and remove any that match. 7629 int N = mGrantedUriPermissions.size(); 7630 for (int i = 0; i < N; i++) { 7631 final int targetUid = mGrantedUriPermissions.keyAt(i); 7632 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7633 7634 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7635 final UriPermission perm = it.next(); 7636 if (perm.uri.sourceUserId == grantUri.sourceUserId 7637 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7638 if (DEBUG_URI_PERMISSION) 7639 Slog.v(TAG, 7640 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7641 persistChanged |= perm.revokeModes( 7642 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7643 if (perm.modeFlags == 0) { 7644 it.remove(); 7645 } 7646 } 7647 } 7648 7649 if (perms.isEmpty()) { 7650 mGrantedUriPermissions.remove(targetUid); 7651 N--; 7652 i--; 7653 } 7654 } 7655 7656 if (persistChanged) { 7657 schedulePersistUriGrants(); 7658 } 7659 } 7660 7661 /** 7662 * @param uri This uri must NOT contain an embedded userId. 7663 * @param userId The userId in which the uri is to be resolved. 7664 */ 7665 @Override 7666 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7667 int userId) { 7668 enforceNotIsolatedCaller("revokeUriPermission"); 7669 synchronized(this) { 7670 final ProcessRecord r = getRecordForAppLocked(caller); 7671 if (r == null) { 7672 throw new SecurityException("Unable to find app for caller " 7673 + caller 7674 + " when revoking permission to uri " + uri); 7675 } 7676 if (uri == null) { 7677 Slog.w(TAG, "revokeUriPermission: null uri"); 7678 return; 7679 } 7680 7681 if (!Intent.isAccessUriMode(modeFlags)) { 7682 return; 7683 } 7684 7685 final IPackageManager pm = AppGlobals.getPackageManager(); 7686 final String authority = uri.getAuthority(); 7687 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7688 if (pi == null) { 7689 Slog.w(TAG, "No content provider found for permission revoke: " 7690 + uri.toSafeString()); 7691 return; 7692 } 7693 7694 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7695 } 7696 } 7697 7698 /** 7699 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7700 * given package. 7701 * 7702 * @param packageName Package name to match, or {@code null} to apply to all 7703 * packages. 7704 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7705 * to all users. 7706 * @param persistable If persistable grants should be removed. 7707 */ 7708 private void removeUriPermissionsForPackageLocked( 7709 String packageName, int userHandle, boolean persistable) { 7710 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7711 throw new IllegalArgumentException("Must narrow by either package or user"); 7712 } 7713 7714 boolean persistChanged = false; 7715 7716 int N = mGrantedUriPermissions.size(); 7717 for (int i = 0; i < N; i++) { 7718 final int targetUid = mGrantedUriPermissions.keyAt(i); 7719 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7720 7721 // Only inspect grants matching user 7722 if (userHandle == UserHandle.USER_ALL 7723 || userHandle == UserHandle.getUserId(targetUid)) { 7724 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7725 final UriPermission perm = it.next(); 7726 7727 // Only inspect grants matching package 7728 if (packageName == null || perm.sourcePkg.equals(packageName) 7729 || perm.targetPkg.equals(packageName)) { 7730 persistChanged |= perm.revokeModes(persistable 7731 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7732 7733 // Only remove when no modes remain; any persisted grants 7734 // will keep this alive. 7735 if (perm.modeFlags == 0) { 7736 it.remove(); 7737 } 7738 } 7739 } 7740 7741 if (perms.isEmpty()) { 7742 mGrantedUriPermissions.remove(targetUid); 7743 N--; 7744 i--; 7745 } 7746 } 7747 } 7748 7749 if (persistChanged) { 7750 schedulePersistUriGrants(); 7751 } 7752 } 7753 7754 @Override 7755 public IBinder newUriPermissionOwner(String name) { 7756 enforceNotIsolatedCaller("newUriPermissionOwner"); 7757 synchronized(this) { 7758 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7759 return owner.getExternalTokenLocked(); 7760 } 7761 } 7762 7763 /** 7764 * @param uri This uri must NOT contain an embedded userId. 7765 * @param sourceUserId The userId in which the uri is to be resolved. 7766 * @param targetUserId The userId of the app that receives the grant. 7767 */ 7768 @Override 7769 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7770 final int modeFlags, int sourceUserId, int targetUserId) { 7771 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7772 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7773 synchronized(this) { 7774 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7775 if (owner == null) { 7776 throw new IllegalArgumentException("Unknown owner: " + token); 7777 } 7778 if (fromUid != Binder.getCallingUid()) { 7779 if (Binder.getCallingUid() != Process.myUid()) { 7780 // Only system code can grant URI permissions on behalf 7781 // of other users. 7782 throw new SecurityException("nice try"); 7783 } 7784 } 7785 if (targetPkg == null) { 7786 throw new IllegalArgumentException("null target"); 7787 } 7788 if (uri == null) { 7789 throw new IllegalArgumentException("null uri"); 7790 } 7791 7792 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7793 modeFlags, owner, targetUserId); 7794 } 7795 } 7796 7797 /** 7798 * @param uri This uri must NOT contain an embedded userId. 7799 * @param userId The userId in which the uri is to be resolved. 7800 */ 7801 @Override 7802 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7803 synchronized(this) { 7804 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7805 if (owner == null) { 7806 throw new IllegalArgumentException("Unknown owner: " + token); 7807 } 7808 7809 if (uri == null) { 7810 owner.removeUriPermissionsLocked(mode); 7811 } else { 7812 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7813 } 7814 } 7815 } 7816 7817 private void schedulePersistUriGrants() { 7818 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7819 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7820 10 * DateUtils.SECOND_IN_MILLIS); 7821 } 7822 } 7823 7824 private void writeGrantedUriPermissions() { 7825 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7826 7827 // Snapshot permissions so we can persist without lock 7828 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7829 synchronized (this) { 7830 final int size = mGrantedUriPermissions.size(); 7831 for (int i = 0; i < size; i++) { 7832 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7833 for (UriPermission perm : perms.values()) { 7834 if (perm.persistedModeFlags != 0) { 7835 persist.add(perm.snapshot()); 7836 } 7837 } 7838 } 7839 } 7840 7841 FileOutputStream fos = null; 7842 try { 7843 fos = mGrantFile.startWrite(); 7844 7845 XmlSerializer out = new FastXmlSerializer(); 7846 out.setOutput(fos, "utf-8"); 7847 out.startDocument(null, true); 7848 out.startTag(null, TAG_URI_GRANTS); 7849 for (UriPermission.Snapshot perm : persist) { 7850 out.startTag(null, TAG_URI_GRANT); 7851 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7852 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7853 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7854 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7855 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7856 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7857 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7858 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7859 out.endTag(null, TAG_URI_GRANT); 7860 } 7861 out.endTag(null, TAG_URI_GRANTS); 7862 out.endDocument(); 7863 7864 mGrantFile.finishWrite(fos); 7865 } catch (IOException e) { 7866 if (fos != null) { 7867 mGrantFile.failWrite(fos); 7868 } 7869 } 7870 } 7871 7872 private void readGrantedUriPermissionsLocked() { 7873 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7874 7875 final long now = System.currentTimeMillis(); 7876 7877 FileInputStream fis = null; 7878 try { 7879 fis = mGrantFile.openRead(); 7880 final XmlPullParser in = Xml.newPullParser(); 7881 in.setInput(fis, null); 7882 7883 int type; 7884 while ((type = in.next()) != END_DOCUMENT) { 7885 final String tag = in.getName(); 7886 if (type == START_TAG) { 7887 if (TAG_URI_GRANT.equals(tag)) { 7888 final int sourceUserId; 7889 final int targetUserId; 7890 final int userHandle = readIntAttribute(in, 7891 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7892 if (userHandle != UserHandle.USER_NULL) { 7893 // For backwards compatibility. 7894 sourceUserId = userHandle; 7895 targetUserId = userHandle; 7896 } else { 7897 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7898 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7899 } 7900 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7901 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7902 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7903 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7904 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7905 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7906 7907 // Sanity check that provider still belongs to source package 7908 final ProviderInfo pi = getProviderInfoLocked( 7909 uri.getAuthority(), sourceUserId); 7910 if (pi != null && sourcePkg.equals(pi.packageName)) { 7911 int targetUid = -1; 7912 try { 7913 targetUid = AppGlobals.getPackageManager() 7914 .getPackageUid(targetPkg, targetUserId); 7915 } catch (RemoteException e) { 7916 } 7917 if (targetUid != -1) { 7918 final UriPermission perm = findOrCreateUriPermissionLocked( 7919 sourcePkg, targetPkg, targetUid, 7920 new GrantUri(sourceUserId, uri, prefix)); 7921 perm.initPersistedModes(modeFlags, createdTime); 7922 } 7923 } else { 7924 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7925 + " but instead found " + pi); 7926 } 7927 } 7928 } 7929 } 7930 } catch (FileNotFoundException e) { 7931 // Missing grants is okay 7932 } catch (IOException e) { 7933 Slog.wtf(TAG, "Failed reading Uri grants", e); 7934 } catch (XmlPullParserException e) { 7935 Slog.wtf(TAG, "Failed reading Uri grants", e); 7936 } finally { 7937 IoUtils.closeQuietly(fis); 7938 } 7939 } 7940 7941 /** 7942 * @param uri This uri must NOT contain an embedded userId. 7943 * @param userId The userId in which the uri is to be resolved. 7944 */ 7945 @Override 7946 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7947 enforceNotIsolatedCaller("takePersistableUriPermission"); 7948 7949 Preconditions.checkFlagsArgument(modeFlags, 7950 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7951 7952 synchronized (this) { 7953 final int callingUid = Binder.getCallingUid(); 7954 boolean persistChanged = false; 7955 GrantUri grantUri = new GrantUri(userId, uri, false); 7956 7957 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7958 new GrantUri(userId, uri, false)); 7959 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7960 new GrantUri(userId, uri, true)); 7961 7962 final boolean exactValid = (exactPerm != null) 7963 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7964 final boolean prefixValid = (prefixPerm != null) 7965 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7966 7967 if (!(exactValid || prefixValid)) { 7968 throw new SecurityException("No persistable permission grants found for UID " 7969 + callingUid + " and Uri " + grantUri.toSafeString()); 7970 } 7971 7972 if (exactValid) { 7973 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7974 } 7975 if (prefixValid) { 7976 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7977 } 7978 7979 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7980 7981 if (persistChanged) { 7982 schedulePersistUriGrants(); 7983 } 7984 } 7985 } 7986 7987 /** 7988 * @param uri This uri must NOT contain an embedded userId. 7989 * @param userId The userId in which the uri is to be resolved. 7990 */ 7991 @Override 7992 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7993 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7994 7995 Preconditions.checkFlagsArgument(modeFlags, 7996 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7997 7998 synchronized (this) { 7999 final int callingUid = Binder.getCallingUid(); 8000 boolean persistChanged = false; 8001 8002 UriPermission exactPerm = findUriPermissionLocked(callingUid, 8003 new GrantUri(userId, uri, false)); 8004 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 8005 new GrantUri(userId, uri, true)); 8006 if (exactPerm == null && prefixPerm == null) { 8007 throw new SecurityException("No permission grants found for UID " + callingUid 8008 + " and Uri " + uri.toSafeString()); 8009 } 8010 8011 if (exactPerm != null) { 8012 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 8013 removeUriPermissionIfNeededLocked(exactPerm); 8014 } 8015 if (prefixPerm != null) { 8016 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 8017 removeUriPermissionIfNeededLocked(prefixPerm); 8018 } 8019 8020 if (persistChanged) { 8021 schedulePersistUriGrants(); 8022 } 8023 } 8024 } 8025 8026 /** 8027 * Prune any older {@link UriPermission} for the given UID until outstanding 8028 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 8029 * 8030 * @return if any mutations occured that require persisting. 8031 */ 8032 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 8033 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8034 if (perms == null) return false; 8035 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 8036 8037 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 8038 for (UriPermission perm : perms.values()) { 8039 if (perm.persistedModeFlags != 0) { 8040 persisted.add(perm); 8041 } 8042 } 8043 8044 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 8045 if (trimCount <= 0) return false; 8046 8047 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 8048 for (int i = 0; i < trimCount; i++) { 8049 final UriPermission perm = persisted.get(i); 8050 8051 if (DEBUG_URI_PERMISSION) { 8052 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 8053 } 8054 8055 perm.releasePersistableModes(~0); 8056 removeUriPermissionIfNeededLocked(perm); 8057 } 8058 8059 return true; 8060 } 8061 8062 @Override 8063 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8064 String packageName, boolean incoming) { 8065 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8066 Preconditions.checkNotNull(packageName, "packageName"); 8067 8068 final int callingUid = Binder.getCallingUid(); 8069 final IPackageManager pm = AppGlobals.getPackageManager(); 8070 try { 8071 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8072 if (packageUid != callingUid) { 8073 throw new SecurityException( 8074 "Package " + packageName + " does not belong to calling UID " + callingUid); 8075 } 8076 } catch (RemoteException e) { 8077 throw new SecurityException("Failed to verify package name ownership"); 8078 } 8079 8080 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8081 synchronized (this) { 8082 if (incoming) { 8083 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8084 callingUid); 8085 if (perms == null) { 8086 Slog.w(TAG, "No permission grants found for " + packageName); 8087 } else { 8088 for (UriPermission perm : perms.values()) { 8089 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8090 result.add(perm.buildPersistedPublicApiObject()); 8091 } 8092 } 8093 } 8094 } else { 8095 final int size = mGrantedUriPermissions.size(); 8096 for (int i = 0; i < size; i++) { 8097 final ArrayMap<GrantUri, UriPermission> perms = 8098 mGrantedUriPermissions.valueAt(i); 8099 for (UriPermission perm : perms.values()) { 8100 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8101 result.add(perm.buildPersistedPublicApiObject()); 8102 } 8103 } 8104 } 8105 } 8106 } 8107 return new ParceledListSlice<android.content.UriPermission>(result); 8108 } 8109 8110 @Override 8111 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8112 synchronized (this) { 8113 ProcessRecord app = 8114 who != null ? getRecordForAppLocked(who) : null; 8115 if (app == null) return; 8116 8117 Message msg = Message.obtain(); 8118 msg.what = WAIT_FOR_DEBUGGER_MSG; 8119 msg.obj = app; 8120 msg.arg1 = waiting ? 1 : 0; 8121 mHandler.sendMessage(msg); 8122 } 8123 } 8124 8125 @Override 8126 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8127 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8128 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8129 outInfo.availMem = Process.getFreeMemory(); 8130 outInfo.totalMem = Process.getTotalMemory(); 8131 outInfo.threshold = homeAppMem; 8132 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8133 outInfo.hiddenAppThreshold = cachedAppMem; 8134 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8135 ProcessList.SERVICE_ADJ); 8136 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8137 ProcessList.VISIBLE_APP_ADJ); 8138 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8139 ProcessList.FOREGROUND_APP_ADJ); 8140 } 8141 8142 // ========================================================= 8143 // TASK MANAGEMENT 8144 // ========================================================= 8145 8146 @Override 8147 public List<IAppTask> getAppTasks(String callingPackage) { 8148 int callingUid = Binder.getCallingUid(); 8149 long ident = Binder.clearCallingIdentity(); 8150 8151 synchronized(this) { 8152 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8153 try { 8154 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8155 8156 final int N = mRecentTasks.size(); 8157 for (int i = 0; i < N; i++) { 8158 TaskRecord tr = mRecentTasks.get(i); 8159 // Skip tasks that do not match the caller. We don't need to verify 8160 // callingPackage, because we are also limiting to callingUid and know 8161 // that will limit to the correct security sandbox. 8162 if (tr.effectiveUid != callingUid) { 8163 continue; 8164 } 8165 Intent intent = tr.getBaseIntent(); 8166 if (intent == null || 8167 !callingPackage.equals(intent.getComponent().getPackageName())) { 8168 continue; 8169 } 8170 ActivityManager.RecentTaskInfo taskInfo = 8171 createRecentTaskInfoFromTaskRecord(tr); 8172 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8173 list.add(taskImpl); 8174 } 8175 } finally { 8176 Binder.restoreCallingIdentity(ident); 8177 } 8178 return list; 8179 } 8180 } 8181 8182 @Override 8183 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8184 final int callingUid = Binder.getCallingUid(); 8185 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8186 8187 synchronized(this) { 8188 if (localLOGV) Slog.v( 8189 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8190 8191 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 8192 callingUid); 8193 8194 // TODO: Improve with MRU list from all ActivityStacks. 8195 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8196 } 8197 8198 return list; 8199 } 8200 8201 TaskRecord getMostRecentTask() { 8202 return mRecentTasks.get(0); 8203 } 8204 8205 /** 8206 * Creates a new RecentTaskInfo from a TaskRecord. 8207 */ 8208 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8209 // Update the task description to reflect any changes in the task stack 8210 tr.updateTaskDescription(); 8211 8212 // Compose the recent task info 8213 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8214 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8215 rti.persistentId = tr.taskId; 8216 rti.baseIntent = new Intent(tr.getBaseIntent()); 8217 rti.origActivity = tr.origActivity; 8218 rti.description = tr.lastDescription; 8219 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8220 rti.userId = tr.userId; 8221 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8222 rti.firstActiveTime = tr.firstActiveTime; 8223 rti.lastActiveTime = tr.lastActiveTime; 8224 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8225 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8226 return rti; 8227 } 8228 8229 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 8230 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 8231 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 8232 if (!allowed) { 8233 if (checkPermission(android.Manifest.permission.GET_TASKS, 8234 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 8235 // Temporary compatibility: some existing apps on the system image may 8236 // still be requesting the old permission and not switched to the new 8237 // one; if so, we'll still allow them full access. This means we need 8238 // to see if they are holding the old permission and are a system app. 8239 try { 8240 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 8241 allowed = true; 8242 Slog.w(TAG, caller + ": caller " + callingUid 8243 + " is using old GET_TASKS but privileged; allowing"); 8244 } 8245 } catch (RemoteException e) { 8246 } 8247 } 8248 } 8249 if (!allowed) { 8250 Slog.w(TAG, caller + ": caller " + callingUid 8251 + " does not hold GET_TASKS; limiting output"); 8252 } 8253 return allowed; 8254 } 8255 8256 @Override 8257 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8258 final int callingUid = Binder.getCallingUid(); 8259 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8260 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8261 8262 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8263 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8264 synchronized (this) { 8265 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 8266 callingUid); 8267 final boolean detailed = checkCallingPermission( 8268 android.Manifest.permission.GET_DETAILED_TASKS) 8269 == PackageManager.PERMISSION_GRANTED; 8270 8271 final int N = mRecentTasks.size(); 8272 ArrayList<ActivityManager.RecentTaskInfo> res 8273 = new ArrayList<ActivityManager.RecentTaskInfo>( 8274 maxNum < N ? maxNum : N); 8275 8276 final Set<Integer> includedUsers; 8277 if (includeProfiles) { 8278 includedUsers = getProfileIdsLocked(userId); 8279 } else { 8280 includedUsers = new HashSet<Integer>(); 8281 } 8282 includedUsers.add(Integer.valueOf(userId)); 8283 8284 for (int i=0; i<N && maxNum > 0; i++) { 8285 TaskRecord tr = mRecentTasks.get(i); 8286 // Only add calling user or related users recent tasks 8287 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8288 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8289 continue; 8290 } 8291 8292 // Return the entry if desired by the caller. We always return 8293 // the first entry, because callers always expect this to be the 8294 // foreground app. We may filter others if the caller has 8295 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8296 // we should exclude the entry. 8297 8298 if (i == 0 8299 || withExcluded 8300 || (tr.intent == null) 8301 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8302 == 0)) { 8303 if (!allowed) { 8304 // If the caller doesn't have the GET_TASKS permission, then only 8305 // allow them to see a small subset of tasks -- their own and home. 8306 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8307 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8308 continue; 8309 } 8310 } 8311 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8312 if (tr.stack != null && tr.stack.isHomeStack()) { 8313 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8314 continue; 8315 } 8316 } 8317 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8318 // Don't include auto remove tasks that are finished or finishing. 8319 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8320 + tr); 8321 continue; 8322 } 8323 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8324 && !tr.isAvailable) { 8325 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8326 continue; 8327 } 8328 8329 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8330 if (!detailed) { 8331 rti.baseIntent.replaceExtras((Bundle)null); 8332 } 8333 8334 res.add(rti); 8335 maxNum--; 8336 } 8337 } 8338 return res; 8339 } 8340 } 8341 8342 private TaskRecord recentTaskForIdLocked(int id) { 8343 final int N = mRecentTasks.size(); 8344 for (int i=0; i<N; i++) { 8345 TaskRecord tr = mRecentTasks.get(i); 8346 if (tr.taskId == id) { 8347 return tr; 8348 } 8349 } 8350 return null; 8351 } 8352 8353 @Override 8354 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8355 synchronized (this) { 8356 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8357 "getTaskThumbnail()"); 8358 TaskRecord tr = recentTaskForIdLocked(id); 8359 if (tr != null) { 8360 return tr.getTaskThumbnailLocked(); 8361 } 8362 } 8363 return null; 8364 } 8365 8366 @Override 8367 public int addAppTask(IBinder activityToken, Intent intent, 8368 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8369 final int callingUid = Binder.getCallingUid(); 8370 final long callingIdent = Binder.clearCallingIdentity(); 8371 8372 try { 8373 synchronized (this) { 8374 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8375 if (r == null) { 8376 throw new IllegalArgumentException("Activity does not exist; token=" 8377 + activityToken); 8378 } 8379 ComponentName comp = intent.getComponent(); 8380 if (comp == null) { 8381 throw new IllegalArgumentException("Intent " + intent 8382 + " must specify explicit component"); 8383 } 8384 if (thumbnail.getWidth() != mThumbnailWidth 8385 || thumbnail.getHeight() != mThumbnailHeight) { 8386 throw new IllegalArgumentException("Bad thumbnail size: got " 8387 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8388 + mThumbnailWidth + "x" + mThumbnailHeight); 8389 } 8390 if (intent.getSelector() != null) { 8391 intent.setSelector(null); 8392 } 8393 if (intent.getSourceBounds() != null) { 8394 intent.setSourceBounds(null); 8395 } 8396 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8397 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8398 // The caller has added this as an auto-remove task... that makes no 8399 // sense, so turn off auto-remove. 8400 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8401 } 8402 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8403 // Must be a new task. 8404 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8405 } 8406 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8407 mLastAddedTaskActivity = null; 8408 } 8409 ActivityInfo ainfo = mLastAddedTaskActivity; 8410 if (ainfo == null) { 8411 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8412 comp, 0, UserHandle.getUserId(callingUid)); 8413 if (ainfo.applicationInfo.uid != callingUid) { 8414 throw new SecurityException( 8415 "Can't add task for another application: target uid=" 8416 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8417 } 8418 } 8419 8420 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8421 intent, description); 8422 8423 int trimIdx = trimRecentsForTask(task, false); 8424 if (trimIdx >= 0) { 8425 // If this would have caused a trim, then we'll abort because that 8426 // means it would be added at the end of the list but then just removed. 8427 return -1; 8428 } 8429 8430 final int N = mRecentTasks.size(); 8431 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8432 final TaskRecord tr = mRecentTasks.remove(N - 1); 8433 tr.removedFromRecents(mTaskPersister); 8434 } 8435 8436 task.inRecents = true; 8437 mRecentTasks.add(task); 8438 r.task.stack.addTask(task, false, false); 8439 8440 task.setLastThumbnail(thumbnail); 8441 task.freeLastThumbnail(); 8442 8443 return task.taskId; 8444 } 8445 } finally { 8446 Binder.restoreCallingIdentity(callingIdent); 8447 } 8448 } 8449 8450 @Override 8451 public Point getAppTaskThumbnailSize() { 8452 synchronized (this) { 8453 return new Point(mThumbnailWidth, mThumbnailHeight); 8454 } 8455 } 8456 8457 @Override 8458 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8459 synchronized (this) { 8460 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8461 if (r != null) { 8462 r.setTaskDescription(td); 8463 r.task.updateTaskDescription(); 8464 } 8465 } 8466 } 8467 8468 @Override 8469 public Bitmap getTaskDescriptionIcon(String filename) { 8470 if (!FileUtils.isValidExtFilename(filename) 8471 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8472 throw new IllegalArgumentException("Bad filename: " + filename); 8473 } 8474 return mTaskPersister.getTaskDescriptionIcon(filename); 8475 } 8476 8477 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8478 mRecentTasks.remove(tr); 8479 tr.removedFromRecents(mTaskPersister); 8480 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8481 Intent baseIntent = new Intent( 8482 tr.intent != null ? tr.intent : tr.affinityIntent); 8483 ComponentName component = baseIntent.getComponent(); 8484 if (component == null) { 8485 Slog.w(TAG, "Now component for base intent of task: " + tr); 8486 return; 8487 } 8488 8489 // Find any running services associated with this app. 8490 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8491 8492 if (killProcesses) { 8493 // Find any running processes associated with this app. 8494 final String pkg = component.getPackageName(); 8495 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8496 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8497 for (int i=0; i<pmap.size(); i++) { 8498 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8499 for (int j=0; j<uids.size(); j++) { 8500 ProcessRecord proc = uids.valueAt(j); 8501 if (proc.userId != tr.userId) { 8502 continue; 8503 } 8504 if (!proc.pkgList.containsKey(pkg)) { 8505 continue; 8506 } 8507 procs.add(proc); 8508 } 8509 } 8510 8511 // Kill the running processes. 8512 for (int i=0; i<procs.size(); i++) { 8513 ProcessRecord pr = procs.get(i); 8514 if (pr == mHomeProcess) { 8515 // Don't kill the home process along with tasks from the same package. 8516 continue; 8517 } 8518 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8519 pr.kill("remove task", true); 8520 } else { 8521 pr.waitingToKill = "remove task"; 8522 } 8523 } 8524 } 8525 } 8526 8527 /** 8528 * Removes the task with the specified task id. 8529 * 8530 * @param taskId Identifier of the task to be removed. 8531 * @param flags Additional operational flags. May be 0 or 8532 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8533 * @return Returns true if the given task was found and removed. 8534 */ 8535 private boolean removeTaskByIdLocked(int taskId, int flags) { 8536 TaskRecord tr = recentTaskForIdLocked(taskId); 8537 if (tr != null) { 8538 tr.removeTaskActivitiesLocked(); 8539 cleanUpRemovedTaskLocked(tr, flags); 8540 if (tr.isPersistable) { 8541 notifyTaskPersisterLocked(null, true); 8542 } 8543 return true; 8544 } 8545 return false; 8546 } 8547 8548 @Override 8549 public boolean removeTask(int taskId, int flags) { 8550 synchronized (this) { 8551 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8552 "removeTask()"); 8553 long ident = Binder.clearCallingIdentity(); 8554 try { 8555 return removeTaskByIdLocked(taskId, flags); 8556 } finally { 8557 Binder.restoreCallingIdentity(ident); 8558 } 8559 } 8560 } 8561 8562 /** 8563 * TODO: Add mController hook 8564 */ 8565 @Override 8566 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8567 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8568 "moveTaskToFront()"); 8569 8570 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8571 synchronized(this) { 8572 moveTaskToFrontLocked(taskId, flags, options); 8573 } 8574 } 8575 8576 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8577 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8578 Binder.getCallingUid(), -1, -1, "Task to front")) { 8579 ActivityOptions.abort(options); 8580 return; 8581 } 8582 final long origId = Binder.clearCallingIdentity(); 8583 try { 8584 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8585 if (task == null) { 8586 return; 8587 } 8588 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8589 mStackSupervisor.showLockTaskToast(); 8590 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8591 return; 8592 } 8593 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8594 if (prev != null && prev.isRecentsActivity()) { 8595 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8596 } 8597 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8598 } finally { 8599 Binder.restoreCallingIdentity(origId); 8600 } 8601 ActivityOptions.abort(options); 8602 } 8603 8604 @Override 8605 public void moveTaskToBack(int taskId) { 8606 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8607 "moveTaskToBack()"); 8608 8609 synchronized(this) { 8610 TaskRecord tr = recentTaskForIdLocked(taskId); 8611 if (tr != null) { 8612 if (tr == mStackSupervisor.mLockTaskModeTask) { 8613 mStackSupervisor.showLockTaskToast(); 8614 return; 8615 } 8616 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8617 ActivityStack stack = tr.stack; 8618 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8619 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8620 Binder.getCallingUid(), -1, -1, "Task to back")) { 8621 return; 8622 } 8623 } 8624 final long origId = Binder.clearCallingIdentity(); 8625 try { 8626 stack.moveTaskToBackLocked(taskId, null); 8627 } finally { 8628 Binder.restoreCallingIdentity(origId); 8629 } 8630 } 8631 } 8632 } 8633 8634 /** 8635 * Moves an activity, and all of the other activities within the same task, to the bottom 8636 * of the history stack. The activity's order within the task is unchanged. 8637 * 8638 * @param token A reference to the activity we wish to move 8639 * @param nonRoot If false then this only works if the activity is the root 8640 * of a task; if true it will work for any activity in a task. 8641 * @return Returns true if the move completed, false if not. 8642 */ 8643 @Override 8644 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8645 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8646 synchronized(this) { 8647 final long origId = Binder.clearCallingIdentity(); 8648 try { 8649 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8650 if (taskId >= 0) { 8651 if ((mStackSupervisor.mLockTaskModeTask != null) 8652 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8653 mStackSupervisor.showLockTaskToast(); 8654 return false; 8655 } 8656 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8657 } 8658 } finally { 8659 Binder.restoreCallingIdentity(origId); 8660 } 8661 } 8662 return false; 8663 } 8664 8665 @Override 8666 public void moveTaskBackwards(int task) { 8667 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8668 "moveTaskBackwards()"); 8669 8670 synchronized(this) { 8671 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8672 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8673 return; 8674 } 8675 final long origId = Binder.clearCallingIdentity(); 8676 moveTaskBackwardsLocked(task); 8677 Binder.restoreCallingIdentity(origId); 8678 } 8679 } 8680 8681 private final void moveTaskBackwardsLocked(int task) { 8682 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8683 } 8684 8685 @Override 8686 public IBinder getHomeActivityToken() throws RemoteException { 8687 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8688 "getHomeActivityToken()"); 8689 synchronized (this) { 8690 return mStackSupervisor.getHomeActivityToken(); 8691 } 8692 } 8693 8694 @Override 8695 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8696 IActivityContainerCallback callback) throws RemoteException { 8697 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8698 "createActivityContainer()"); 8699 synchronized (this) { 8700 if (parentActivityToken == null) { 8701 throw new IllegalArgumentException("parent token must not be null"); 8702 } 8703 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8704 if (r == null) { 8705 return null; 8706 } 8707 if (callback == null) { 8708 throw new IllegalArgumentException("callback must not be null"); 8709 } 8710 return mStackSupervisor.createActivityContainer(r, callback); 8711 } 8712 } 8713 8714 @Override 8715 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8717 "deleteActivityContainer()"); 8718 synchronized (this) { 8719 mStackSupervisor.deleteActivityContainer(container); 8720 } 8721 } 8722 8723 @Override 8724 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8725 throws RemoteException { 8726 synchronized (this) { 8727 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8728 if (stack != null) { 8729 return stack.mActivityContainer; 8730 } 8731 return null; 8732 } 8733 } 8734 8735 @Override 8736 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8737 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8738 "moveTaskToStack()"); 8739 if (stackId == HOME_STACK_ID) { 8740 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8741 new RuntimeException("here").fillInStackTrace()); 8742 } 8743 synchronized (this) { 8744 long ident = Binder.clearCallingIdentity(); 8745 try { 8746 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8747 + stackId + " toTop=" + toTop); 8748 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8749 } finally { 8750 Binder.restoreCallingIdentity(ident); 8751 } 8752 } 8753 } 8754 8755 @Override 8756 public void resizeStack(int stackBoxId, Rect bounds) { 8757 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8758 "resizeStackBox()"); 8759 long ident = Binder.clearCallingIdentity(); 8760 try { 8761 mWindowManager.resizeStack(stackBoxId, bounds); 8762 } finally { 8763 Binder.restoreCallingIdentity(ident); 8764 } 8765 } 8766 8767 @Override 8768 public List<StackInfo> getAllStackInfos() { 8769 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8770 "getAllStackInfos()"); 8771 long ident = Binder.clearCallingIdentity(); 8772 try { 8773 synchronized (this) { 8774 return mStackSupervisor.getAllStackInfosLocked(); 8775 } 8776 } finally { 8777 Binder.restoreCallingIdentity(ident); 8778 } 8779 } 8780 8781 @Override 8782 public StackInfo getStackInfo(int stackId) { 8783 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8784 "getStackInfo()"); 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 synchronized (this) { 8788 return mStackSupervisor.getStackInfoLocked(stackId); 8789 } 8790 } finally { 8791 Binder.restoreCallingIdentity(ident); 8792 } 8793 } 8794 8795 @Override 8796 public boolean isInHomeStack(int taskId) { 8797 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8798 "getStackInfo()"); 8799 long ident = Binder.clearCallingIdentity(); 8800 try { 8801 synchronized (this) { 8802 TaskRecord tr = recentTaskForIdLocked(taskId); 8803 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8804 } 8805 } finally { 8806 Binder.restoreCallingIdentity(ident); 8807 } 8808 } 8809 8810 @Override 8811 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8812 synchronized(this) { 8813 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8814 } 8815 } 8816 8817 private boolean isLockTaskAuthorized(String pkg) { 8818 final DevicePolicyManager dpm = (DevicePolicyManager) 8819 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8820 try { 8821 int uid = mContext.getPackageManager().getPackageUid(pkg, 8822 Binder.getCallingUserHandle().getIdentifier()); 8823 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8824 } catch (NameNotFoundException e) { 8825 return false; 8826 } 8827 } 8828 8829 void startLockTaskMode(TaskRecord task) { 8830 final String pkg; 8831 synchronized (this) { 8832 pkg = task.intent.getComponent().getPackageName(); 8833 } 8834 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8835 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8836 final TaskRecord taskRecord = task; 8837 mHandler.post(new Runnable() { 8838 @Override 8839 public void run() { 8840 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8841 } 8842 }); 8843 return; 8844 } 8845 long ident = Binder.clearCallingIdentity(); 8846 try { 8847 synchronized (this) { 8848 // Since we lost lock on task, make sure it is still there. 8849 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8850 if (task != null) { 8851 if (!isSystemInitiated 8852 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8853 throw new IllegalArgumentException("Invalid task, not in foreground"); 8854 } 8855 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8856 } 8857 } 8858 } finally { 8859 Binder.restoreCallingIdentity(ident); 8860 } 8861 } 8862 8863 @Override 8864 public void startLockTaskMode(int taskId) { 8865 final TaskRecord task; 8866 long ident = Binder.clearCallingIdentity(); 8867 try { 8868 synchronized (this) { 8869 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8870 } 8871 } finally { 8872 Binder.restoreCallingIdentity(ident); 8873 } 8874 if (task != null) { 8875 startLockTaskMode(task); 8876 } 8877 } 8878 8879 @Override 8880 public void startLockTaskMode(IBinder token) { 8881 final TaskRecord task; 8882 long ident = Binder.clearCallingIdentity(); 8883 try { 8884 synchronized (this) { 8885 final ActivityRecord r = ActivityRecord.forToken(token); 8886 if (r == null) { 8887 return; 8888 } 8889 task = r.task; 8890 } 8891 } finally { 8892 Binder.restoreCallingIdentity(ident); 8893 } 8894 if (task != null) { 8895 startLockTaskMode(task); 8896 } 8897 } 8898 8899 @Override 8900 public void startLockTaskModeOnCurrent() throws RemoteException { 8901 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8902 "startLockTaskModeOnCurrent"); 8903 ActivityRecord r = null; 8904 synchronized (this) { 8905 r = mStackSupervisor.topRunningActivityLocked(); 8906 } 8907 startLockTaskMode(r.task); 8908 } 8909 8910 @Override 8911 public void stopLockTaskMode() { 8912 // Verify that the user matches the package of the intent for the TaskRecord 8913 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8914 // and stopLockTaskMode. 8915 final int callingUid = Binder.getCallingUid(); 8916 if (callingUid != Process.SYSTEM_UID) { 8917 try { 8918 String pkg = 8919 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8920 int uid = mContext.getPackageManager().getPackageUid(pkg, 8921 Binder.getCallingUserHandle().getIdentifier()); 8922 if (uid != callingUid) { 8923 throw new SecurityException("Invalid uid, expected " + uid); 8924 } 8925 } catch (NameNotFoundException e) { 8926 Log.d(TAG, "stopLockTaskMode " + e); 8927 return; 8928 } 8929 } 8930 long ident = Binder.clearCallingIdentity(); 8931 try { 8932 Log.d(TAG, "stopLockTaskMode"); 8933 // Stop lock task 8934 synchronized (this) { 8935 mStackSupervisor.setLockTaskModeLocked(null, false); 8936 } 8937 } finally { 8938 Binder.restoreCallingIdentity(ident); 8939 } 8940 } 8941 8942 @Override 8943 public void stopLockTaskModeOnCurrent() throws RemoteException { 8944 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8945 "stopLockTaskModeOnCurrent"); 8946 long ident = Binder.clearCallingIdentity(); 8947 try { 8948 stopLockTaskMode(); 8949 } finally { 8950 Binder.restoreCallingIdentity(ident); 8951 } 8952 } 8953 8954 @Override 8955 public boolean isInLockTaskMode() { 8956 synchronized (this) { 8957 return mStackSupervisor.isInLockTaskMode(); 8958 } 8959 } 8960 8961 // ========================================================= 8962 // CONTENT PROVIDERS 8963 // ========================================================= 8964 8965 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8966 List<ProviderInfo> providers = null; 8967 try { 8968 providers = AppGlobals.getPackageManager(). 8969 queryContentProviders(app.processName, app.uid, 8970 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8971 } catch (RemoteException ex) { 8972 } 8973 if (DEBUG_MU) 8974 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8975 int userId = app.userId; 8976 if (providers != null) { 8977 int N = providers.size(); 8978 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8979 for (int i=0; i<N; i++) { 8980 ProviderInfo cpi = 8981 (ProviderInfo)providers.get(i); 8982 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8983 cpi.name, cpi.flags); 8984 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8985 // This is a singleton provider, but a user besides the 8986 // default user is asking to initialize a process it runs 8987 // in... well, no, it doesn't actually run in this process, 8988 // it runs in the process of the default user. Get rid of it. 8989 providers.remove(i); 8990 N--; 8991 i--; 8992 continue; 8993 } 8994 8995 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8996 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8997 if (cpr == null) { 8998 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8999 mProviderMap.putProviderByClass(comp, cpr); 9000 } 9001 if (DEBUG_MU) 9002 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 9003 app.pubProviders.put(cpi.name, cpr); 9004 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 9005 // Don't add this if it is a platform component that is marked 9006 // to run in multiple processes, because this is actually 9007 // part of the framework so doesn't make sense to track as a 9008 // separate apk in the process. 9009 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 9010 mProcessStats); 9011 } 9012 ensurePackageDexOpt(cpi.applicationInfo.packageName); 9013 } 9014 } 9015 return providers; 9016 } 9017 9018 /** 9019 * Check if {@link ProcessRecord} has a possible chance at accessing the 9020 * given {@link ProviderInfo}. Final permission checking is always done 9021 * in {@link ContentProvider}. 9022 */ 9023 private final String checkContentProviderPermissionLocked( 9024 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 9025 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 9026 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 9027 boolean checkedGrants = false; 9028 if (checkUser) { 9029 // Looking for cross-user grants before enforcing the typical cross-users permissions 9030 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 9031 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 9032 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 9033 return null; 9034 } 9035 checkedGrants = true; 9036 } 9037 userId = handleIncomingUser(callingPid, callingUid, userId, 9038 false, ALLOW_NON_FULL, 9039 "checkContentProviderPermissionLocked " + cpi.authority, null); 9040 if (userId != tmpTargetUserId) { 9041 // When we actually went to determine the final targer user ID, this ended 9042 // up different than our initial check for the authority. This is because 9043 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 9044 // SELF. So we need to re-check the grants again. 9045 checkedGrants = false; 9046 } 9047 } 9048 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 9049 cpi.applicationInfo.uid, cpi.exported) 9050 == PackageManager.PERMISSION_GRANTED) { 9051 return null; 9052 } 9053 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 9054 cpi.applicationInfo.uid, cpi.exported) 9055 == PackageManager.PERMISSION_GRANTED) { 9056 return null; 9057 } 9058 9059 PathPermission[] pps = cpi.pathPermissions; 9060 if (pps != null) { 9061 int i = pps.length; 9062 while (i > 0) { 9063 i--; 9064 PathPermission pp = pps[i]; 9065 String pprperm = pp.getReadPermission(); 9066 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 9067 cpi.applicationInfo.uid, cpi.exported) 9068 == PackageManager.PERMISSION_GRANTED) { 9069 return null; 9070 } 9071 String ppwperm = pp.getWritePermission(); 9072 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 9073 cpi.applicationInfo.uid, cpi.exported) 9074 == PackageManager.PERMISSION_GRANTED) { 9075 return null; 9076 } 9077 } 9078 } 9079 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 9080 return null; 9081 } 9082 9083 String msg; 9084 if (!cpi.exported) { 9085 msg = "Permission Denial: opening provider " + cpi.name 9086 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9087 + ", uid=" + callingUid + ") that is not exported from uid " 9088 + cpi.applicationInfo.uid; 9089 } else { 9090 msg = "Permission Denial: opening provider " + cpi.name 9091 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9092 + ", uid=" + callingUid + ") requires " 9093 + cpi.readPermission + " or " + cpi.writePermission; 9094 } 9095 Slog.w(TAG, msg); 9096 return msg; 9097 } 9098 9099 /** 9100 * Returns if the ContentProvider has granted a uri to callingUid 9101 */ 9102 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9103 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9104 if (perms != null) { 9105 for (int i=perms.size()-1; i>=0; i--) { 9106 GrantUri grantUri = perms.keyAt(i); 9107 if (grantUri.sourceUserId == userId || !checkUser) { 9108 if (matchesProvider(grantUri.uri, cpi)) { 9109 return true; 9110 } 9111 } 9112 } 9113 } 9114 return false; 9115 } 9116 9117 /** 9118 * Returns true if the uri authority is one of the authorities specified in the provider. 9119 */ 9120 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9121 String uriAuth = uri.getAuthority(); 9122 String cpiAuth = cpi.authority; 9123 if (cpiAuth.indexOf(';') == -1) { 9124 return cpiAuth.equals(uriAuth); 9125 } 9126 String[] cpiAuths = cpiAuth.split(";"); 9127 int length = cpiAuths.length; 9128 for (int i = 0; i < length; i++) { 9129 if (cpiAuths[i].equals(uriAuth)) return true; 9130 } 9131 return false; 9132 } 9133 9134 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9135 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9136 if (r != null) { 9137 for (int i=0; i<r.conProviders.size(); i++) { 9138 ContentProviderConnection conn = r.conProviders.get(i); 9139 if (conn.provider == cpr) { 9140 if (DEBUG_PROVIDER) Slog.v(TAG, 9141 "Adding provider requested by " 9142 + r.processName + " from process " 9143 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9144 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9145 if (stable) { 9146 conn.stableCount++; 9147 conn.numStableIncs++; 9148 } else { 9149 conn.unstableCount++; 9150 conn.numUnstableIncs++; 9151 } 9152 return conn; 9153 } 9154 } 9155 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9156 if (stable) { 9157 conn.stableCount = 1; 9158 conn.numStableIncs = 1; 9159 } else { 9160 conn.unstableCount = 1; 9161 conn.numUnstableIncs = 1; 9162 } 9163 cpr.connections.add(conn); 9164 r.conProviders.add(conn); 9165 return conn; 9166 } 9167 cpr.addExternalProcessHandleLocked(externalProcessToken); 9168 return null; 9169 } 9170 9171 boolean decProviderCountLocked(ContentProviderConnection conn, 9172 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9173 if (conn != null) { 9174 cpr = conn.provider; 9175 if (DEBUG_PROVIDER) Slog.v(TAG, 9176 "Removing provider requested by " 9177 + conn.client.processName + " from process " 9178 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9179 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9180 if (stable) { 9181 conn.stableCount--; 9182 } else { 9183 conn.unstableCount--; 9184 } 9185 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9186 cpr.connections.remove(conn); 9187 conn.client.conProviders.remove(conn); 9188 return true; 9189 } 9190 return false; 9191 } 9192 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9193 return false; 9194 } 9195 9196 private void checkTime(long startTime, String where) { 9197 long now = SystemClock.elapsedRealtime(); 9198 if ((now-startTime) > 1000) { 9199 // If we are taking more than a second, log about it. 9200 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9201 } 9202 } 9203 9204 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9205 String name, IBinder token, boolean stable, int userId) { 9206 ContentProviderRecord cpr; 9207 ContentProviderConnection conn = null; 9208 ProviderInfo cpi = null; 9209 9210 synchronized(this) { 9211 long startTime = SystemClock.elapsedRealtime(); 9212 9213 ProcessRecord r = null; 9214 if (caller != null) { 9215 r = getRecordForAppLocked(caller); 9216 if (r == null) { 9217 throw new SecurityException( 9218 "Unable to find app for caller " + caller 9219 + " (pid=" + Binder.getCallingPid() 9220 + ") when getting content provider " + name); 9221 } 9222 } 9223 9224 boolean checkCrossUser = true; 9225 9226 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9227 9228 // First check if this content provider has been published... 9229 cpr = mProviderMap.getProviderByName(name, userId); 9230 // If that didn't work, check if it exists for user 0 and then 9231 // verify that it's a singleton provider before using it. 9232 if (cpr == null && userId != UserHandle.USER_OWNER) { 9233 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9234 if (cpr != null) { 9235 cpi = cpr.info; 9236 if (isSingleton(cpi.processName, cpi.applicationInfo, 9237 cpi.name, cpi.flags) 9238 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9239 userId = UserHandle.USER_OWNER; 9240 checkCrossUser = false; 9241 } else { 9242 cpr = null; 9243 cpi = null; 9244 } 9245 } 9246 } 9247 9248 boolean providerRunning = cpr != null; 9249 if (providerRunning) { 9250 cpi = cpr.info; 9251 String msg; 9252 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9253 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9254 != null) { 9255 throw new SecurityException(msg); 9256 } 9257 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9258 9259 if (r != null && cpr.canRunHere(r)) { 9260 // This provider has been published or is in the process 9261 // of being published... but it is also allowed to run 9262 // in the caller's process, so don't make a connection 9263 // and just let the caller instantiate its own instance. 9264 ContentProviderHolder holder = cpr.newHolder(null); 9265 // don't give caller the provider object, it needs 9266 // to make its own. 9267 holder.provider = null; 9268 return holder; 9269 } 9270 9271 final long origId = Binder.clearCallingIdentity(); 9272 9273 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9274 9275 // In this case the provider instance already exists, so we can 9276 // return it right away. 9277 conn = incProviderCountLocked(r, cpr, token, stable); 9278 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9279 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9280 // If this is a perceptible app accessing the provider, 9281 // make sure to count it as being accessed and thus 9282 // back up on the LRU list. This is good because 9283 // content providers are often expensive to start. 9284 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9285 updateLruProcessLocked(cpr.proc, false, null); 9286 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9287 } 9288 } 9289 9290 if (cpr.proc != null) { 9291 if (false) { 9292 if (cpr.name.flattenToShortString().equals( 9293 "com.android.providers.calendar/.CalendarProvider2")) { 9294 Slog.v(TAG, "****************** KILLING " 9295 + cpr.name.flattenToShortString()); 9296 Process.killProcess(cpr.proc.pid); 9297 } 9298 } 9299 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9300 boolean success = updateOomAdjLocked(cpr.proc); 9301 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9302 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9303 // NOTE: there is still a race here where a signal could be 9304 // pending on the process even though we managed to update its 9305 // adj level. Not sure what to do about this, but at least 9306 // the race is now smaller. 9307 if (!success) { 9308 // Uh oh... it looks like the provider's process 9309 // has been killed on us. We need to wait for a new 9310 // process to be started, and make sure its death 9311 // doesn't kill our process. 9312 Slog.i(TAG, 9313 "Existing provider " + cpr.name.flattenToShortString() 9314 + " is crashing; detaching " + r); 9315 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9316 checkTime(startTime, "getContentProviderImpl: before appDied"); 9317 appDiedLocked(cpr.proc); 9318 checkTime(startTime, "getContentProviderImpl: after appDied"); 9319 if (!lastRef) { 9320 // This wasn't the last ref our process had on 9321 // the provider... we have now been killed, bail. 9322 return null; 9323 } 9324 providerRunning = false; 9325 conn = null; 9326 } 9327 } 9328 9329 Binder.restoreCallingIdentity(origId); 9330 } 9331 9332 boolean singleton; 9333 if (!providerRunning) { 9334 try { 9335 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9336 cpi = AppGlobals.getPackageManager(). 9337 resolveContentProvider(name, 9338 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9339 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9340 } catch (RemoteException ex) { 9341 } 9342 if (cpi == null) { 9343 return null; 9344 } 9345 // If the provider is a singleton AND 9346 // (it's a call within the same user || the provider is a 9347 // privileged app) 9348 // Then allow connecting to the singleton provider 9349 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9350 cpi.name, cpi.flags) 9351 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9352 if (singleton) { 9353 userId = UserHandle.USER_OWNER; 9354 } 9355 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9356 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9357 9358 String msg; 9359 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9360 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9361 != null) { 9362 throw new SecurityException(msg); 9363 } 9364 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9365 9366 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9367 && !cpi.processName.equals("system")) { 9368 // If this content provider does not run in the system 9369 // process, and the system is not yet ready to run other 9370 // processes, then fail fast instead of hanging. 9371 throw new IllegalArgumentException( 9372 "Attempt to launch content provider before system ready"); 9373 } 9374 9375 // Make sure that the user who owns this provider is started. If not, 9376 // we don't want to allow it to run. 9377 if (mStartedUsers.get(userId) == null) { 9378 Slog.w(TAG, "Unable to launch app " 9379 + cpi.applicationInfo.packageName + "/" 9380 + cpi.applicationInfo.uid + " for provider " 9381 + name + ": user " + userId + " is stopped"); 9382 return null; 9383 } 9384 9385 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9386 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9387 cpr = mProviderMap.getProviderByClass(comp, userId); 9388 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9389 final boolean firstClass = cpr == null; 9390 if (firstClass) { 9391 final long ident = Binder.clearCallingIdentity(); 9392 try { 9393 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9394 ApplicationInfo ai = 9395 AppGlobals.getPackageManager(). 9396 getApplicationInfo( 9397 cpi.applicationInfo.packageName, 9398 STOCK_PM_FLAGS, userId); 9399 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9400 if (ai == null) { 9401 Slog.w(TAG, "No package info for content provider " 9402 + cpi.name); 9403 return null; 9404 } 9405 ai = getAppInfoForUser(ai, userId); 9406 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9407 } catch (RemoteException ex) { 9408 // pm is in same process, this will never happen. 9409 } finally { 9410 Binder.restoreCallingIdentity(ident); 9411 } 9412 } 9413 9414 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9415 9416 if (r != null && cpr.canRunHere(r)) { 9417 // If this is a multiprocess provider, then just return its 9418 // info and allow the caller to instantiate it. Only do 9419 // this if the provider is the same user as the caller's 9420 // process, or can run as root (so can be in any process). 9421 return cpr.newHolder(null); 9422 } 9423 9424 if (DEBUG_PROVIDER) { 9425 RuntimeException e = new RuntimeException("here"); 9426 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9427 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9428 } 9429 9430 // This is single process, and our app is now connecting to it. 9431 // See if we are already in the process of launching this 9432 // provider. 9433 final int N = mLaunchingProviders.size(); 9434 int i; 9435 for (i=0; i<N; i++) { 9436 if (mLaunchingProviders.get(i) == cpr) { 9437 break; 9438 } 9439 } 9440 9441 // If the provider is not already being launched, then get it 9442 // started. 9443 if (i >= N) { 9444 final long origId = Binder.clearCallingIdentity(); 9445 9446 try { 9447 // Content provider is now in use, its package can't be stopped. 9448 try { 9449 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9450 AppGlobals.getPackageManager().setPackageStoppedState( 9451 cpr.appInfo.packageName, false, userId); 9452 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9453 } catch (RemoteException e) { 9454 } catch (IllegalArgumentException e) { 9455 Slog.w(TAG, "Failed trying to unstop package " 9456 + cpr.appInfo.packageName + ": " + e); 9457 } 9458 9459 // Use existing process if already started 9460 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9461 ProcessRecord proc = getProcessRecordLocked( 9462 cpi.processName, cpr.appInfo.uid, false); 9463 if (proc != null && proc.thread != null) { 9464 if (DEBUG_PROVIDER) { 9465 Slog.d(TAG, "Installing in existing process " + proc); 9466 } 9467 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9468 proc.pubProviders.put(cpi.name, cpr); 9469 try { 9470 proc.thread.scheduleInstallProvider(cpi); 9471 } catch (RemoteException e) { 9472 } 9473 } else { 9474 checkTime(startTime, "getContentProviderImpl: before start process"); 9475 proc = startProcessLocked(cpi.processName, 9476 cpr.appInfo, false, 0, "content provider", 9477 new ComponentName(cpi.applicationInfo.packageName, 9478 cpi.name), false, false, false); 9479 checkTime(startTime, "getContentProviderImpl: after start process"); 9480 if (proc == null) { 9481 Slog.w(TAG, "Unable to launch app " 9482 + cpi.applicationInfo.packageName + "/" 9483 + cpi.applicationInfo.uid + " for provider " 9484 + name + ": process is bad"); 9485 return null; 9486 } 9487 } 9488 cpr.launchingApp = proc; 9489 mLaunchingProviders.add(cpr); 9490 } finally { 9491 Binder.restoreCallingIdentity(origId); 9492 } 9493 } 9494 9495 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9496 9497 // Make sure the provider is published (the same provider class 9498 // may be published under multiple names). 9499 if (firstClass) { 9500 mProviderMap.putProviderByClass(comp, cpr); 9501 } 9502 9503 mProviderMap.putProviderByName(name, cpr); 9504 conn = incProviderCountLocked(r, cpr, token, stable); 9505 if (conn != null) { 9506 conn.waiting = true; 9507 } 9508 } 9509 checkTime(startTime, "getContentProviderImpl: done!"); 9510 } 9511 9512 // Wait for the provider to be published... 9513 synchronized (cpr) { 9514 while (cpr.provider == null) { 9515 if (cpr.launchingApp == null) { 9516 Slog.w(TAG, "Unable to launch app " 9517 + cpi.applicationInfo.packageName + "/" 9518 + cpi.applicationInfo.uid + " for provider " 9519 + name + ": launching app became null"); 9520 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9521 UserHandle.getUserId(cpi.applicationInfo.uid), 9522 cpi.applicationInfo.packageName, 9523 cpi.applicationInfo.uid, name); 9524 return null; 9525 } 9526 try { 9527 if (DEBUG_MU) { 9528 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9529 + cpr.launchingApp); 9530 } 9531 if (conn != null) { 9532 conn.waiting = true; 9533 } 9534 cpr.wait(); 9535 } catch (InterruptedException ex) { 9536 } finally { 9537 if (conn != null) { 9538 conn.waiting = false; 9539 } 9540 } 9541 } 9542 } 9543 return cpr != null ? cpr.newHolder(conn) : null; 9544 } 9545 9546 @Override 9547 public final ContentProviderHolder getContentProvider( 9548 IApplicationThread caller, String name, int userId, boolean stable) { 9549 enforceNotIsolatedCaller("getContentProvider"); 9550 if (caller == null) { 9551 String msg = "null IApplicationThread when getting content provider " 9552 + name; 9553 Slog.w(TAG, msg); 9554 throw new SecurityException(msg); 9555 } 9556 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9557 // with cross-user grant. 9558 return getContentProviderImpl(caller, name, null, stable, userId); 9559 } 9560 9561 public ContentProviderHolder getContentProviderExternal( 9562 String name, int userId, IBinder token) { 9563 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9564 "Do not have permission in call getContentProviderExternal()"); 9565 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9566 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9567 return getContentProviderExternalUnchecked(name, token, userId); 9568 } 9569 9570 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9571 IBinder token, int userId) { 9572 return getContentProviderImpl(null, name, token, true, userId); 9573 } 9574 9575 /** 9576 * Drop a content provider from a ProcessRecord's bookkeeping 9577 */ 9578 public void removeContentProvider(IBinder connection, boolean stable) { 9579 enforceNotIsolatedCaller("removeContentProvider"); 9580 long ident = Binder.clearCallingIdentity(); 9581 try { 9582 synchronized (this) { 9583 ContentProviderConnection conn; 9584 try { 9585 conn = (ContentProviderConnection)connection; 9586 } catch (ClassCastException e) { 9587 String msg ="removeContentProvider: " + connection 9588 + " not a ContentProviderConnection"; 9589 Slog.w(TAG, msg); 9590 throw new IllegalArgumentException(msg); 9591 } 9592 if (conn == null) { 9593 throw new NullPointerException("connection is null"); 9594 } 9595 if (decProviderCountLocked(conn, null, null, stable)) { 9596 updateOomAdjLocked(); 9597 } 9598 } 9599 } finally { 9600 Binder.restoreCallingIdentity(ident); 9601 } 9602 } 9603 9604 public void removeContentProviderExternal(String name, IBinder token) { 9605 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9606 "Do not have permission in call removeContentProviderExternal()"); 9607 int userId = UserHandle.getCallingUserId(); 9608 long ident = Binder.clearCallingIdentity(); 9609 try { 9610 removeContentProviderExternalUnchecked(name, token, userId); 9611 } finally { 9612 Binder.restoreCallingIdentity(ident); 9613 } 9614 } 9615 9616 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9617 synchronized (this) { 9618 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9619 if(cpr == null) { 9620 //remove from mProvidersByClass 9621 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9622 return; 9623 } 9624 9625 //update content provider record entry info 9626 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9627 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9628 if (localCpr.hasExternalProcessHandles()) { 9629 if (localCpr.removeExternalProcessHandleLocked(token)) { 9630 updateOomAdjLocked(); 9631 } else { 9632 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9633 + " with no external reference for token: " 9634 + token + "."); 9635 } 9636 } else { 9637 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9638 + " with no external references."); 9639 } 9640 } 9641 } 9642 9643 public final void publishContentProviders(IApplicationThread caller, 9644 List<ContentProviderHolder> providers) { 9645 if (providers == null) { 9646 return; 9647 } 9648 9649 enforceNotIsolatedCaller("publishContentProviders"); 9650 synchronized (this) { 9651 final ProcessRecord r = getRecordForAppLocked(caller); 9652 if (DEBUG_MU) 9653 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9654 if (r == null) { 9655 throw new SecurityException( 9656 "Unable to find app for caller " + caller 9657 + " (pid=" + Binder.getCallingPid() 9658 + ") when publishing content providers"); 9659 } 9660 9661 final long origId = Binder.clearCallingIdentity(); 9662 9663 final int N = providers.size(); 9664 for (int i=0; i<N; i++) { 9665 ContentProviderHolder src = providers.get(i); 9666 if (src == null || src.info == null || src.provider == null) { 9667 continue; 9668 } 9669 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9670 if (DEBUG_MU) 9671 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9672 if (dst != null) { 9673 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9674 mProviderMap.putProviderByClass(comp, dst); 9675 String names[] = dst.info.authority.split(";"); 9676 for (int j = 0; j < names.length; j++) { 9677 mProviderMap.putProviderByName(names[j], dst); 9678 } 9679 9680 int NL = mLaunchingProviders.size(); 9681 int j; 9682 for (j=0; j<NL; j++) { 9683 if (mLaunchingProviders.get(j) == dst) { 9684 mLaunchingProviders.remove(j); 9685 j--; 9686 NL--; 9687 } 9688 } 9689 synchronized (dst) { 9690 dst.provider = src.provider; 9691 dst.proc = r; 9692 dst.notifyAll(); 9693 } 9694 updateOomAdjLocked(r); 9695 } 9696 } 9697 9698 Binder.restoreCallingIdentity(origId); 9699 } 9700 } 9701 9702 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9703 ContentProviderConnection conn; 9704 try { 9705 conn = (ContentProviderConnection)connection; 9706 } catch (ClassCastException e) { 9707 String msg ="refContentProvider: " + connection 9708 + " not a ContentProviderConnection"; 9709 Slog.w(TAG, msg); 9710 throw new IllegalArgumentException(msg); 9711 } 9712 if (conn == null) { 9713 throw new NullPointerException("connection is null"); 9714 } 9715 9716 synchronized (this) { 9717 if (stable > 0) { 9718 conn.numStableIncs += stable; 9719 } 9720 stable = conn.stableCount + stable; 9721 if (stable < 0) { 9722 throw new IllegalStateException("stableCount < 0: " + stable); 9723 } 9724 9725 if (unstable > 0) { 9726 conn.numUnstableIncs += unstable; 9727 } 9728 unstable = conn.unstableCount + unstable; 9729 if (unstable < 0) { 9730 throw new IllegalStateException("unstableCount < 0: " + unstable); 9731 } 9732 9733 if ((stable+unstable) <= 0) { 9734 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9735 + stable + " unstable=" + unstable); 9736 } 9737 conn.stableCount = stable; 9738 conn.unstableCount = unstable; 9739 return !conn.dead; 9740 } 9741 } 9742 9743 public void unstableProviderDied(IBinder connection) { 9744 ContentProviderConnection conn; 9745 try { 9746 conn = (ContentProviderConnection)connection; 9747 } catch (ClassCastException e) { 9748 String msg ="refContentProvider: " + connection 9749 + " not a ContentProviderConnection"; 9750 Slog.w(TAG, msg); 9751 throw new IllegalArgumentException(msg); 9752 } 9753 if (conn == null) { 9754 throw new NullPointerException("connection is null"); 9755 } 9756 9757 // Safely retrieve the content provider associated with the connection. 9758 IContentProvider provider; 9759 synchronized (this) { 9760 provider = conn.provider.provider; 9761 } 9762 9763 if (provider == null) { 9764 // Um, yeah, we're way ahead of you. 9765 return; 9766 } 9767 9768 // Make sure the caller is being honest with us. 9769 if (provider.asBinder().pingBinder()) { 9770 // Er, no, still looks good to us. 9771 synchronized (this) { 9772 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9773 + " says " + conn + " died, but we don't agree"); 9774 return; 9775 } 9776 } 9777 9778 // Well look at that! It's dead! 9779 synchronized (this) { 9780 if (conn.provider.provider != provider) { 9781 // But something changed... good enough. 9782 return; 9783 } 9784 9785 ProcessRecord proc = conn.provider.proc; 9786 if (proc == null || proc.thread == null) { 9787 // Seems like the process is already cleaned up. 9788 return; 9789 } 9790 9791 // As far as we're concerned, this is just like receiving a 9792 // death notification... just a bit prematurely. 9793 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9794 + ") early provider death"); 9795 final long ident = Binder.clearCallingIdentity(); 9796 try { 9797 appDiedLocked(proc); 9798 } finally { 9799 Binder.restoreCallingIdentity(ident); 9800 } 9801 } 9802 } 9803 9804 @Override 9805 public void appNotRespondingViaProvider(IBinder connection) { 9806 enforceCallingPermission( 9807 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9808 9809 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9810 if (conn == null) { 9811 Slog.w(TAG, "ContentProviderConnection is null"); 9812 return; 9813 } 9814 9815 final ProcessRecord host = conn.provider.proc; 9816 if (host == null) { 9817 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9818 return; 9819 } 9820 9821 final long token = Binder.clearCallingIdentity(); 9822 try { 9823 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9824 } finally { 9825 Binder.restoreCallingIdentity(token); 9826 } 9827 } 9828 9829 public final void installSystemProviders() { 9830 List<ProviderInfo> providers; 9831 synchronized (this) { 9832 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9833 providers = generateApplicationProvidersLocked(app); 9834 if (providers != null) { 9835 for (int i=providers.size()-1; i>=0; i--) { 9836 ProviderInfo pi = (ProviderInfo)providers.get(i); 9837 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9838 Slog.w(TAG, "Not installing system proc provider " + pi.name 9839 + ": not system .apk"); 9840 providers.remove(i); 9841 } 9842 } 9843 } 9844 } 9845 if (providers != null) { 9846 mSystemThread.installSystemProviders(providers); 9847 } 9848 9849 mCoreSettingsObserver = new CoreSettingsObserver(this); 9850 9851 //mUsageStatsService.monitorPackages(); 9852 } 9853 9854 /** 9855 * Allows apps to retrieve the MIME type of a URI. 9856 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9857 * users, then it does not need permission to access the ContentProvider. 9858 * Either, it needs cross-user uri grants. 9859 * 9860 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9861 * 9862 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9863 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9864 */ 9865 public String getProviderMimeType(Uri uri, int userId) { 9866 enforceNotIsolatedCaller("getProviderMimeType"); 9867 final String name = uri.getAuthority(); 9868 int callingUid = Binder.getCallingUid(); 9869 int callingPid = Binder.getCallingPid(); 9870 long ident = 0; 9871 boolean clearedIdentity = false; 9872 userId = unsafeConvertIncomingUser(userId); 9873 if (canClearIdentity(callingPid, callingUid, userId)) { 9874 clearedIdentity = true; 9875 ident = Binder.clearCallingIdentity(); 9876 } 9877 ContentProviderHolder holder = null; 9878 try { 9879 holder = getContentProviderExternalUnchecked(name, null, userId); 9880 if (holder != null) { 9881 return holder.provider.getType(uri); 9882 } 9883 } catch (RemoteException e) { 9884 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9885 return null; 9886 } finally { 9887 // We need to clear the identity to call removeContentProviderExternalUnchecked 9888 if (!clearedIdentity) { 9889 ident = Binder.clearCallingIdentity(); 9890 } 9891 try { 9892 if (holder != null) { 9893 removeContentProviderExternalUnchecked(name, null, userId); 9894 } 9895 } finally { 9896 Binder.restoreCallingIdentity(ident); 9897 } 9898 } 9899 9900 return null; 9901 } 9902 9903 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9904 if (UserHandle.getUserId(callingUid) == userId) { 9905 return true; 9906 } 9907 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9908 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9909 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9910 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9911 return true; 9912 } 9913 return false; 9914 } 9915 9916 // ========================================================= 9917 // GLOBAL MANAGEMENT 9918 // ========================================================= 9919 9920 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9921 boolean isolated, int isolatedUid) { 9922 String proc = customProcess != null ? customProcess : info.processName; 9923 BatteryStatsImpl.Uid.Proc ps = null; 9924 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9925 int uid = info.uid; 9926 if (isolated) { 9927 if (isolatedUid == 0) { 9928 int userId = UserHandle.getUserId(uid); 9929 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9930 while (true) { 9931 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9932 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9933 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9934 } 9935 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9936 mNextIsolatedProcessUid++; 9937 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9938 // No process for this uid, use it. 9939 break; 9940 } 9941 stepsLeft--; 9942 if (stepsLeft <= 0) { 9943 return null; 9944 } 9945 } 9946 } else { 9947 // Special case for startIsolatedProcess (internal only), where 9948 // the uid of the isolated process is specified by the caller. 9949 uid = isolatedUid; 9950 } 9951 } 9952 return new ProcessRecord(stats, info, proc, uid); 9953 } 9954 9955 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9956 String abiOverride) { 9957 ProcessRecord app; 9958 if (!isolated) { 9959 app = getProcessRecordLocked(info.processName, info.uid, true); 9960 } else { 9961 app = null; 9962 } 9963 9964 if (app == null) { 9965 app = newProcessRecordLocked(info, null, isolated, 0); 9966 mProcessNames.put(info.processName, app.uid, app); 9967 if (isolated) { 9968 mIsolatedProcesses.put(app.uid, app); 9969 } 9970 updateLruProcessLocked(app, false, null); 9971 updateOomAdjLocked(); 9972 } 9973 9974 // This package really, really can not be stopped. 9975 try { 9976 AppGlobals.getPackageManager().setPackageStoppedState( 9977 info.packageName, false, UserHandle.getUserId(app.uid)); 9978 } catch (RemoteException e) { 9979 } catch (IllegalArgumentException e) { 9980 Slog.w(TAG, "Failed trying to unstop package " 9981 + info.packageName + ": " + e); 9982 } 9983 9984 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9985 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9986 app.persistent = true; 9987 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9988 } 9989 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9990 mPersistentStartingProcesses.add(app); 9991 startProcessLocked(app, "added application", app.processName, abiOverride, 9992 null /* entryPoint */, null /* entryPointArgs */); 9993 } 9994 9995 return app; 9996 } 9997 9998 public void unhandledBack() { 9999 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 10000 "unhandledBack()"); 10001 10002 synchronized(this) { 10003 final long origId = Binder.clearCallingIdentity(); 10004 try { 10005 getFocusedStack().unhandledBackLocked(); 10006 } finally { 10007 Binder.restoreCallingIdentity(origId); 10008 } 10009 } 10010 } 10011 10012 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 10013 enforceNotIsolatedCaller("openContentUri"); 10014 final int userId = UserHandle.getCallingUserId(); 10015 String name = uri.getAuthority(); 10016 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 10017 ParcelFileDescriptor pfd = null; 10018 if (cph != null) { 10019 // We record the binder invoker's uid in thread-local storage before 10020 // going to the content provider to open the file. Later, in the code 10021 // that handles all permissions checks, we look for this uid and use 10022 // that rather than the Activity Manager's own uid. The effect is that 10023 // we do the check against the caller's permissions even though it looks 10024 // to the content provider like the Activity Manager itself is making 10025 // the request. 10026 sCallerIdentity.set(new Identity( 10027 Binder.getCallingPid(), Binder.getCallingUid())); 10028 try { 10029 pfd = cph.provider.openFile(null, uri, "r", null); 10030 } catch (FileNotFoundException e) { 10031 // do nothing; pfd will be returned null 10032 } finally { 10033 // Ensure that whatever happens, we clean up the identity state 10034 sCallerIdentity.remove(); 10035 } 10036 10037 // We've got the fd now, so we're done with the provider. 10038 removeContentProviderExternalUnchecked(name, null, userId); 10039 } else { 10040 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 10041 } 10042 return pfd; 10043 } 10044 10045 // Actually is sleeping or shutting down or whatever else in the future 10046 // is an inactive state. 10047 public boolean isSleepingOrShuttingDown() { 10048 return isSleeping() || mShuttingDown; 10049 } 10050 10051 public boolean isSleeping() { 10052 return mSleeping; 10053 } 10054 10055 void goingToSleep() { 10056 synchronized(this) { 10057 mWentToSleep = true; 10058 goToSleepIfNeededLocked(); 10059 } 10060 } 10061 10062 void finishRunningVoiceLocked() { 10063 if (mRunningVoice) { 10064 mRunningVoice = false; 10065 goToSleepIfNeededLocked(); 10066 } 10067 } 10068 10069 void goToSleepIfNeededLocked() { 10070 if (mWentToSleep && !mRunningVoice) { 10071 if (!mSleeping) { 10072 mSleeping = true; 10073 mStackSupervisor.goingToSleepLocked(); 10074 10075 // Initialize the wake times of all processes. 10076 checkExcessivePowerUsageLocked(false); 10077 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10078 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 10079 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 10080 } 10081 } 10082 } 10083 10084 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 10085 if (task != null && task.stack != null && task.stack.isHomeStack()) { 10086 // Never persist the home stack. 10087 return; 10088 } 10089 mTaskPersister.wakeup(task, flush); 10090 } 10091 10092 @Override 10093 public boolean shutdown(int timeout) { 10094 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10095 != PackageManager.PERMISSION_GRANTED) { 10096 throw new SecurityException("Requires permission " 10097 + android.Manifest.permission.SHUTDOWN); 10098 } 10099 10100 boolean timedout = false; 10101 10102 synchronized(this) { 10103 mShuttingDown = true; 10104 updateEventDispatchingLocked(); 10105 timedout = mStackSupervisor.shutdownLocked(timeout); 10106 } 10107 10108 mAppOpsService.shutdown(); 10109 if (mUsageStatsService != null) { 10110 mUsageStatsService.prepareShutdown(); 10111 } 10112 mBatteryStatsService.shutdown(); 10113 synchronized (this) { 10114 mProcessStats.shutdownLocked(); 10115 } 10116 notifyTaskPersisterLocked(null, true); 10117 10118 return timedout; 10119 } 10120 10121 public final void activitySlept(IBinder token) { 10122 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10123 10124 final long origId = Binder.clearCallingIdentity(); 10125 10126 synchronized (this) { 10127 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10128 if (r != null) { 10129 mStackSupervisor.activitySleptLocked(r); 10130 } 10131 } 10132 10133 Binder.restoreCallingIdentity(origId); 10134 } 10135 10136 void logLockScreen(String msg) { 10137 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10138 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10139 mWentToSleep + " mSleeping=" + mSleeping); 10140 } 10141 10142 private void comeOutOfSleepIfNeededLocked() { 10143 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10144 if (mSleeping) { 10145 mSleeping = false; 10146 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10147 } 10148 } 10149 } 10150 10151 void wakingUp() { 10152 synchronized(this) { 10153 mWentToSleep = false; 10154 comeOutOfSleepIfNeededLocked(); 10155 } 10156 } 10157 10158 void startRunningVoiceLocked() { 10159 if (!mRunningVoice) { 10160 mRunningVoice = true; 10161 comeOutOfSleepIfNeededLocked(); 10162 } 10163 } 10164 10165 private void updateEventDispatchingLocked() { 10166 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10167 } 10168 10169 public void setLockScreenShown(boolean shown) { 10170 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10171 != PackageManager.PERMISSION_GRANTED) { 10172 throw new SecurityException("Requires permission " 10173 + android.Manifest.permission.DEVICE_POWER); 10174 } 10175 10176 synchronized(this) { 10177 long ident = Binder.clearCallingIdentity(); 10178 try { 10179 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10180 mLockScreenShown = shown; 10181 comeOutOfSleepIfNeededLocked(); 10182 } finally { 10183 Binder.restoreCallingIdentity(ident); 10184 } 10185 } 10186 } 10187 10188 @Override 10189 public void stopAppSwitches() { 10190 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10191 != PackageManager.PERMISSION_GRANTED) { 10192 throw new SecurityException("Requires permission " 10193 + android.Manifest.permission.STOP_APP_SWITCHES); 10194 } 10195 10196 synchronized(this) { 10197 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10198 + APP_SWITCH_DELAY_TIME; 10199 mDidAppSwitch = false; 10200 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10201 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10202 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10203 } 10204 } 10205 10206 public void resumeAppSwitches() { 10207 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10208 != PackageManager.PERMISSION_GRANTED) { 10209 throw new SecurityException("Requires permission " 10210 + android.Manifest.permission.STOP_APP_SWITCHES); 10211 } 10212 10213 synchronized(this) { 10214 // Note that we don't execute any pending app switches... we will 10215 // let those wait until either the timeout, or the next start 10216 // activity request. 10217 mAppSwitchesAllowedTime = 0; 10218 } 10219 } 10220 10221 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10222 int callingPid, int callingUid, String name) { 10223 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10224 return true; 10225 } 10226 10227 int perm = checkComponentPermission( 10228 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10229 sourceUid, -1, true); 10230 if (perm == PackageManager.PERMISSION_GRANTED) { 10231 return true; 10232 } 10233 10234 // If the actual IPC caller is different from the logical source, then 10235 // also see if they are allowed to control app switches. 10236 if (callingUid != -1 && callingUid != sourceUid) { 10237 perm = checkComponentPermission( 10238 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10239 callingUid, -1, true); 10240 if (perm == PackageManager.PERMISSION_GRANTED) { 10241 return true; 10242 } 10243 } 10244 10245 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10246 return false; 10247 } 10248 10249 public void setDebugApp(String packageName, boolean waitForDebugger, 10250 boolean persistent) { 10251 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10252 "setDebugApp()"); 10253 10254 long ident = Binder.clearCallingIdentity(); 10255 try { 10256 // Note that this is not really thread safe if there are multiple 10257 // callers into it at the same time, but that's not a situation we 10258 // care about. 10259 if (persistent) { 10260 final ContentResolver resolver = mContext.getContentResolver(); 10261 Settings.Global.putString( 10262 resolver, Settings.Global.DEBUG_APP, 10263 packageName); 10264 Settings.Global.putInt( 10265 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10266 waitForDebugger ? 1 : 0); 10267 } 10268 10269 synchronized (this) { 10270 if (!persistent) { 10271 mOrigDebugApp = mDebugApp; 10272 mOrigWaitForDebugger = mWaitForDebugger; 10273 } 10274 mDebugApp = packageName; 10275 mWaitForDebugger = waitForDebugger; 10276 mDebugTransient = !persistent; 10277 if (packageName != null) { 10278 forceStopPackageLocked(packageName, -1, false, false, true, true, 10279 false, UserHandle.USER_ALL, "set debug app"); 10280 } 10281 } 10282 } finally { 10283 Binder.restoreCallingIdentity(ident); 10284 } 10285 } 10286 10287 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10288 synchronized (this) { 10289 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10290 if (!isDebuggable) { 10291 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10292 throw new SecurityException("Process not debuggable: " + app.packageName); 10293 } 10294 } 10295 10296 mOpenGlTraceApp = processName; 10297 } 10298 } 10299 10300 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10301 synchronized (this) { 10302 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10303 if (!isDebuggable) { 10304 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10305 throw new SecurityException("Process not debuggable: " + app.packageName); 10306 } 10307 } 10308 mProfileApp = processName; 10309 mProfileFile = profilerInfo.profileFile; 10310 if (mProfileFd != null) { 10311 try { 10312 mProfileFd.close(); 10313 } catch (IOException e) { 10314 } 10315 mProfileFd = null; 10316 } 10317 mProfileFd = profilerInfo.profileFd; 10318 mSamplingInterval = profilerInfo.samplingInterval; 10319 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10320 mProfileType = 0; 10321 } 10322 } 10323 10324 @Override 10325 public void setAlwaysFinish(boolean enabled) { 10326 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10327 "setAlwaysFinish()"); 10328 10329 Settings.Global.putInt( 10330 mContext.getContentResolver(), 10331 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10332 10333 synchronized (this) { 10334 mAlwaysFinishActivities = enabled; 10335 } 10336 } 10337 10338 @Override 10339 public void setActivityController(IActivityController controller) { 10340 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10341 "setActivityController()"); 10342 synchronized (this) { 10343 mController = controller; 10344 Watchdog.getInstance().setActivityController(controller); 10345 } 10346 } 10347 10348 @Override 10349 public void setUserIsMonkey(boolean userIsMonkey) { 10350 synchronized (this) { 10351 synchronized (mPidsSelfLocked) { 10352 final int callingPid = Binder.getCallingPid(); 10353 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10354 if (precessRecord == null) { 10355 throw new SecurityException("Unknown process: " + callingPid); 10356 } 10357 if (precessRecord.instrumentationUiAutomationConnection == null) { 10358 throw new SecurityException("Only an instrumentation process " 10359 + "with a UiAutomation can call setUserIsMonkey"); 10360 } 10361 } 10362 mUserIsMonkey = userIsMonkey; 10363 } 10364 } 10365 10366 @Override 10367 public boolean isUserAMonkey() { 10368 synchronized (this) { 10369 // If there is a controller also implies the user is a monkey. 10370 return (mUserIsMonkey || mController != null); 10371 } 10372 } 10373 10374 public void requestBugReport() { 10375 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10376 SystemProperties.set("ctl.start", "bugreport"); 10377 } 10378 10379 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10380 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10381 } 10382 10383 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10384 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10385 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10386 } 10387 return KEY_DISPATCHING_TIMEOUT; 10388 } 10389 10390 @Override 10391 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10392 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10393 != PackageManager.PERMISSION_GRANTED) { 10394 throw new SecurityException("Requires permission " 10395 + android.Manifest.permission.FILTER_EVENTS); 10396 } 10397 ProcessRecord proc; 10398 long timeout; 10399 synchronized (this) { 10400 synchronized (mPidsSelfLocked) { 10401 proc = mPidsSelfLocked.get(pid); 10402 } 10403 timeout = getInputDispatchingTimeoutLocked(proc); 10404 } 10405 10406 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10407 return -1; 10408 } 10409 10410 return timeout; 10411 } 10412 10413 /** 10414 * Handle input dispatching timeouts. 10415 * Returns whether input dispatching should be aborted or not. 10416 */ 10417 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10418 final ActivityRecord activity, final ActivityRecord parent, 10419 final boolean aboveSystem, String reason) { 10420 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10421 != PackageManager.PERMISSION_GRANTED) { 10422 throw new SecurityException("Requires permission " 10423 + android.Manifest.permission.FILTER_EVENTS); 10424 } 10425 10426 final String annotation; 10427 if (reason == null) { 10428 annotation = "Input dispatching timed out"; 10429 } else { 10430 annotation = "Input dispatching timed out (" + reason + ")"; 10431 } 10432 10433 if (proc != null) { 10434 synchronized (this) { 10435 if (proc.debugging) { 10436 return false; 10437 } 10438 10439 if (mDidDexOpt) { 10440 // Give more time since we were dexopting. 10441 mDidDexOpt = false; 10442 return false; 10443 } 10444 10445 if (proc.instrumentationClass != null) { 10446 Bundle info = new Bundle(); 10447 info.putString("shortMsg", "keyDispatchingTimedOut"); 10448 info.putString("longMsg", annotation); 10449 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10450 return true; 10451 } 10452 } 10453 mHandler.post(new Runnable() { 10454 @Override 10455 public void run() { 10456 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10457 } 10458 }); 10459 } 10460 10461 return true; 10462 } 10463 10464 public Bundle getAssistContextExtras(int requestType) { 10465 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, 10466 UserHandle.getCallingUserId()); 10467 if (pae == null) { 10468 return null; 10469 } 10470 synchronized (pae) { 10471 while (!pae.haveResult) { 10472 try { 10473 pae.wait(); 10474 } catch (InterruptedException e) { 10475 } 10476 } 10477 if (pae.result != null) { 10478 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10479 } 10480 } 10481 synchronized (this) { 10482 mPendingAssistExtras.remove(pae); 10483 mHandler.removeCallbacks(pae); 10484 } 10485 return pae.extras; 10486 } 10487 10488 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 10489 int userHandle) { 10490 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10491 "getAssistContextExtras()"); 10492 PendingAssistExtras pae; 10493 Bundle extras = new Bundle(); 10494 synchronized (this) { 10495 ActivityRecord activity = getFocusedStack().mResumedActivity; 10496 if (activity == null) { 10497 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10498 return null; 10499 } 10500 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10501 if (activity.app == null || activity.app.thread == null) { 10502 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10503 return null; 10504 } 10505 if (activity.app.pid == Binder.getCallingPid()) { 10506 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10507 return null; 10508 } 10509 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle); 10510 try { 10511 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10512 requestType); 10513 mPendingAssistExtras.add(pae); 10514 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10515 } catch (RemoteException e) { 10516 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10517 return null; 10518 } 10519 return pae; 10520 } 10521 } 10522 10523 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10524 PendingAssistExtras pae = (PendingAssistExtras)token; 10525 synchronized (pae) { 10526 pae.result = extras; 10527 pae.haveResult = true; 10528 pae.notifyAll(); 10529 if (pae.intent == null) { 10530 // Caller is just waiting for the result. 10531 return; 10532 } 10533 } 10534 10535 // We are now ready to launch the assist activity. 10536 synchronized (this) { 10537 boolean exists = mPendingAssistExtras.remove(pae); 10538 mHandler.removeCallbacks(pae); 10539 if (!exists) { 10540 // Timed out. 10541 return; 10542 } 10543 } 10544 pae.intent.replaceExtras(extras); 10545 if (pae.hint != null) { 10546 pae.intent.putExtra(pae.hint, true); 10547 } 10548 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 10549 | Intent.FLAG_ACTIVITY_SINGLE_TOP 10550 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 10551 closeSystemDialogs("assist"); 10552 try { 10553 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 10554 } catch (ActivityNotFoundException e) { 10555 Slog.w(TAG, "No activity to handle assist action.", e); 10556 } 10557 } 10558 10559 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) { 10560 return enqueueAssistContext(requestType, intent, hint, userHandle) != null; 10561 } 10562 10563 public void registerProcessObserver(IProcessObserver observer) { 10564 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10565 "registerProcessObserver()"); 10566 synchronized (this) { 10567 mProcessObservers.register(observer); 10568 } 10569 } 10570 10571 @Override 10572 public void unregisterProcessObserver(IProcessObserver observer) { 10573 synchronized (this) { 10574 mProcessObservers.unregister(observer); 10575 } 10576 } 10577 10578 @Override 10579 public boolean convertFromTranslucent(IBinder token) { 10580 final long origId = Binder.clearCallingIdentity(); 10581 try { 10582 synchronized (this) { 10583 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10584 if (r == null) { 10585 return false; 10586 } 10587 final boolean translucentChanged = r.changeWindowTranslucency(true); 10588 if (translucentChanged) { 10589 r.task.stack.releaseBackgroundResources(); 10590 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10591 } 10592 mWindowManager.setAppFullscreen(token, true); 10593 return translucentChanged; 10594 } 10595 } finally { 10596 Binder.restoreCallingIdentity(origId); 10597 } 10598 } 10599 10600 @Override 10601 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10602 final long origId = Binder.clearCallingIdentity(); 10603 try { 10604 synchronized (this) { 10605 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10606 if (r == null) { 10607 return false; 10608 } 10609 int index = r.task.mActivities.lastIndexOf(r); 10610 if (index > 0) { 10611 ActivityRecord under = r.task.mActivities.get(index - 1); 10612 under.returningOptions = options; 10613 } 10614 final boolean translucentChanged = r.changeWindowTranslucency(false); 10615 if (translucentChanged) { 10616 r.task.stack.convertToTranslucent(r); 10617 } 10618 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10619 mWindowManager.setAppFullscreen(token, false); 10620 return translucentChanged; 10621 } 10622 } finally { 10623 Binder.restoreCallingIdentity(origId); 10624 } 10625 } 10626 10627 @Override 10628 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10629 final long origId = Binder.clearCallingIdentity(); 10630 try { 10631 synchronized (this) { 10632 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10633 if (r != null) { 10634 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10635 } 10636 } 10637 return false; 10638 } finally { 10639 Binder.restoreCallingIdentity(origId); 10640 } 10641 } 10642 10643 @Override 10644 public boolean isBackgroundVisibleBehind(IBinder token) { 10645 final long origId = Binder.clearCallingIdentity(); 10646 try { 10647 synchronized (this) { 10648 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10649 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10650 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10651 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10652 return visible; 10653 } 10654 } finally { 10655 Binder.restoreCallingIdentity(origId); 10656 } 10657 } 10658 10659 @Override 10660 public ActivityOptions getActivityOptions(IBinder token) { 10661 final long origId = Binder.clearCallingIdentity(); 10662 try { 10663 synchronized (this) { 10664 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10665 if (r != null) { 10666 final ActivityOptions activityOptions = r.pendingOptions; 10667 r.pendingOptions = null; 10668 return activityOptions; 10669 } 10670 return null; 10671 } 10672 } finally { 10673 Binder.restoreCallingIdentity(origId); 10674 } 10675 } 10676 10677 @Override 10678 public void setImmersive(IBinder token, boolean immersive) { 10679 synchronized(this) { 10680 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10681 if (r == null) { 10682 throw new IllegalArgumentException(); 10683 } 10684 r.immersive = immersive; 10685 10686 // update associated state if we're frontmost 10687 if (r == mFocusedActivity) { 10688 if (DEBUG_IMMERSIVE) { 10689 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10690 } 10691 applyUpdateLockStateLocked(r); 10692 } 10693 } 10694 } 10695 10696 @Override 10697 public boolean isImmersive(IBinder token) { 10698 synchronized (this) { 10699 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10700 if (r == null) { 10701 throw new IllegalArgumentException(); 10702 } 10703 return r.immersive; 10704 } 10705 } 10706 10707 public boolean isTopActivityImmersive() { 10708 enforceNotIsolatedCaller("startActivity"); 10709 synchronized (this) { 10710 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10711 return (r != null) ? r.immersive : false; 10712 } 10713 } 10714 10715 @Override 10716 public boolean isTopOfTask(IBinder token) { 10717 synchronized (this) { 10718 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10719 if (r == null) { 10720 throw new IllegalArgumentException(); 10721 } 10722 return r.task.getTopActivity() == r; 10723 } 10724 } 10725 10726 public final void enterSafeMode() { 10727 synchronized(this) { 10728 // It only makes sense to do this before the system is ready 10729 // and started launching other packages. 10730 if (!mSystemReady) { 10731 try { 10732 AppGlobals.getPackageManager().enterSafeMode(); 10733 } catch (RemoteException e) { 10734 } 10735 } 10736 10737 mSafeMode = true; 10738 } 10739 } 10740 10741 public final void showSafeModeOverlay() { 10742 View v = LayoutInflater.from(mContext).inflate( 10743 com.android.internal.R.layout.safe_mode, null); 10744 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10745 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10746 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10747 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10748 lp.gravity = Gravity.BOTTOM | Gravity.START; 10749 lp.format = v.getBackground().getOpacity(); 10750 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10751 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10752 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10753 ((WindowManager)mContext.getSystemService( 10754 Context.WINDOW_SERVICE)).addView(v, lp); 10755 } 10756 10757 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10758 if (!(sender instanceof PendingIntentRecord)) { 10759 return; 10760 } 10761 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10762 synchronized (stats) { 10763 if (mBatteryStatsService.isOnBattery()) { 10764 mBatteryStatsService.enforceCallingPermission(); 10765 PendingIntentRecord rec = (PendingIntentRecord)sender; 10766 int MY_UID = Binder.getCallingUid(); 10767 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10768 BatteryStatsImpl.Uid.Pkg pkg = 10769 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10770 sourcePkg != null ? sourcePkg : rec.key.packageName); 10771 pkg.incWakeupsLocked(); 10772 } 10773 } 10774 } 10775 10776 public boolean killPids(int[] pids, String pReason, boolean secure) { 10777 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10778 throw new SecurityException("killPids only available to the system"); 10779 } 10780 String reason = (pReason == null) ? "Unknown" : pReason; 10781 // XXX Note: don't acquire main activity lock here, because the window 10782 // manager calls in with its locks held. 10783 10784 boolean killed = false; 10785 synchronized (mPidsSelfLocked) { 10786 int[] types = new int[pids.length]; 10787 int worstType = 0; 10788 for (int i=0; i<pids.length; i++) { 10789 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10790 if (proc != null) { 10791 int type = proc.setAdj; 10792 types[i] = type; 10793 if (type > worstType) { 10794 worstType = type; 10795 } 10796 } 10797 } 10798 10799 // If the worst oom_adj is somewhere in the cached proc LRU range, 10800 // then constrain it so we will kill all cached procs. 10801 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10802 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10803 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10804 } 10805 10806 // If this is not a secure call, don't let it kill processes that 10807 // are important. 10808 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10809 worstType = ProcessList.SERVICE_ADJ; 10810 } 10811 10812 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10813 for (int i=0; i<pids.length; i++) { 10814 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10815 if (proc == null) { 10816 continue; 10817 } 10818 int adj = proc.setAdj; 10819 if (adj >= worstType && !proc.killedByAm) { 10820 proc.kill(reason, true); 10821 killed = true; 10822 } 10823 } 10824 } 10825 return killed; 10826 } 10827 10828 @Override 10829 public void killUid(int uid, String reason) { 10830 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10831 throw new SecurityException("killUid only available to the system"); 10832 } 10833 synchronized (this) { 10834 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10835 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10836 reason != null ? reason : "kill uid"); 10837 } 10838 } 10839 10840 @Override 10841 public boolean killProcessesBelowForeground(String reason) { 10842 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10843 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10844 } 10845 10846 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10847 } 10848 10849 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10850 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10851 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10852 } 10853 10854 boolean killed = false; 10855 synchronized (mPidsSelfLocked) { 10856 final int size = mPidsSelfLocked.size(); 10857 for (int i = 0; i < size; i++) { 10858 final int pid = mPidsSelfLocked.keyAt(i); 10859 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10860 if (proc == null) continue; 10861 10862 final int adj = proc.setAdj; 10863 if (adj > belowAdj && !proc.killedByAm) { 10864 proc.kill(reason, true); 10865 killed = true; 10866 } 10867 } 10868 } 10869 return killed; 10870 } 10871 10872 @Override 10873 public void hang(final IBinder who, boolean allowRestart) { 10874 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10875 != PackageManager.PERMISSION_GRANTED) { 10876 throw new SecurityException("Requires permission " 10877 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10878 } 10879 10880 final IBinder.DeathRecipient death = new DeathRecipient() { 10881 @Override 10882 public void binderDied() { 10883 synchronized (this) { 10884 notifyAll(); 10885 } 10886 } 10887 }; 10888 10889 try { 10890 who.linkToDeath(death, 0); 10891 } catch (RemoteException e) { 10892 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10893 return; 10894 } 10895 10896 synchronized (this) { 10897 Watchdog.getInstance().setAllowRestart(allowRestart); 10898 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10899 synchronized (death) { 10900 while (who.isBinderAlive()) { 10901 try { 10902 death.wait(); 10903 } catch (InterruptedException e) { 10904 } 10905 } 10906 } 10907 Watchdog.getInstance().setAllowRestart(true); 10908 } 10909 } 10910 10911 @Override 10912 public void restart() { 10913 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10914 != PackageManager.PERMISSION_GRANTED) { 10915 throw new SecurityException("Requires permission " 10916 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10917 } 10918 10919 Log.i(TAG, "Sending shutdown broadcast..."); 10920 10921 BroadcastReceiver br = new BroadcastReceiver() { 10922 @Override public void onReceive(Context context, Intent intent) { 10923 // Now the broadcast is done, finish up the low-level shutdown. 10924 Log.i(TAG, "Shutting down activity manager..."); 10925 shutdown(10000); 10926 Log.i(TAG, "Shutdown complete, restarting!"); 10927 Process.killProcess(Process.myPid()); 10928 System.exit(10); 10929 } 10930 }; 10931 10932 // First send the high-level shut down broadcast. 10933 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10934 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10935 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10936 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10937 mContext.sendOrderedBroadcastAsUser(intent, 10938 UserHandle.ALL, null, br, mHandler, 0, null, null); 10939 */ 10940 br.onReceive(mContext, intent); 10941 } 10942 10943 private long getLowRamTimeSinceIdle(long now) { 10944 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10945 } 10946 10947 @Override 10948 public void performIdleMaintenance() { 10949 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10950 != PackageManager.PERMISSION_GRANTED) { 10951 throw new SecurityException("Requires permission " 10952 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10953 } 10954 10955 synchronized (this) { 10956 final long now = SystemClock.uptimeMillis(); 10957 final long timeSinceLastIdle = now - mLastIdleTime; 10958 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10959 mLastIdleTime = now; 10960 mLowRamTimeSinceLastIdle = 0; 10961 if (mLowRamStartTime != 0) { 10962 mLowRamStartTime = now; 10963 } 10964 10965 StringBuilder sb = new StringBuilder(128); 10966 sb.append("Idle maintenance over "); 10967 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10968 sb.append(" low RAM for "); 10969 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10970 Slog.i(TAG, sb.toString()); 10971 10972 // If at least 1/3 of our time since the last idle period has been spent 10973 // with RAM low, then we want to kill processes. 10974 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10975 10976 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10977 ProcessRecord proc = mLruProcesses.get(i); 10978 if (proc.notCachedSinceIdle) { 10979 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10980 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10981 if (doKilling && proc.initialIdlePss != 0 10982 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10983 proc.kill("idle maint (pss " + proc.lastPss 10984 + " from " + proc.initialIdlePss + ")", true); 10985 } 10986 } 10987 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10988 proc.notCachedSinceIdle = true; 10989 proc.initialIdlePss = 0; 10990 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10991 isSleeping(), now); 10992 } 10993 } 10994 10995 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10996 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10997 } 10998 } 10999 11000 private void retrieveSettings() { 11001 final ContentResolver resolver = mContext.getContentResolver(); 11002 String debugApp = Settings.Global.getString( 11003 resolver, Settings.Global.DEBUG_APP); 11004 boolean waitForDebugger = Settings.Global.getInt( 11005 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 11006 boolean alwaysFinishActivities = Settings.Global.getInt( 11007 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 11008 boolean forceRtl = Settings.Global.getInt( 11009 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 11010 // Transfer any global setting for forcing RTL layout, into a System Property 11011 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 11012 11013 Configuration configuration = new Configuration(); 11014 Settings.System.getConfiguration(resolver, configuration); 11015 if (forceRtl) { 11016 // This will take care of setting the correct layout direction flags 11017 configuration.setLayoutDirection(configuration.locale); 11018 } 11019 11020 synchronized (this) { 11021 mDebugApp = mOrigDebugApp = debugApp; 11022 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 11023 mAlwaysFinishActivities = alwaysFinishActivities; 11024 // This happens before any activities are started, so we can 11025 // change mConfiguration in-place. 11026 updateConfigurationLocked(configuration, null, false, true); 11027 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 11028 } 11029 } 11030 11031 /** Loads resources after the current configuration has been set. */ 11032 private void loadResourcesOnSystemReady() { 11033 final Resources res = mContext.getResources(); 11034 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 11035 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 11036 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 11037 } 11038 11039 public boolean testIsSystemReady() { 11040 // no need to synchronize(this) just to read & return the value 11041 return mSystemReady; 11042 } 11043 11044 private static File getCalledPreBootReceiversFile() { 11045 File dataDir = Environment.getDataDirectory(); 11046 File systemDir = new File(dataDir, "system"); 11047 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 11048 return fname; 11049 } 11050 11051 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 11052 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 11053 File file = getCalledPreBootReceiversFile(); 11054 FileInputStream fis = null; 11055 try { 11056 fis = new FileInputStream(file); 11057 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 11058 int fvers = dis.readInt(); 11059 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 11060 String vers = dis.readUTF(); 11061 String codename = dis.readUTF(); 11062 String build = dis.readUTF(); 11063 if (android.os.Build.VERSION.RELEASE.equals(vers) 11064 && android.os.Build.VERSION.CODENAME.equals(codename) 11065 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 11066 int num = dis.readInt(); 11067 while (num > 0) { 11068 num--; 11069 String pkg = dis.readUTF(); 11070 String cls = dis.readUTF(); 11071 lastDoneReceivers.add(new ComponentName(pkg, cls)); 11072 } 11073 } 11074 } 11075 } catch (FileNotFoundException e) { 11076 } catch (IOException e) { 11077 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 11078 } finally { 11079 if (fis != null) { 11080 try { 11081 fis.close(); 11082 } catch (IOException e) { 11083 } 11084 } 11085 } 11086 return lastDoneReceivers; 11087 } 11088 11089 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 11090 File file = getCalledPreBootReceiversFile(); 11091 FileOutputStream fos = null; 11092 DataOutputStream dos = null; 11093 try { 11094 fos = new FileOutputStream(file); 11095 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 11096 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 11097 dos.writeUTF(android.os.Build.VERSION.RELEASE); 11098 dos.writeUTF(android.os.Build.VERSION.CODENAME); 11099 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 11100 dos.writeInt(list.size()); 11101 for (int i=0; i<list.size(); i++) { 11102 dos.writeUTF(list.get(i).getPackageName()); 11103 dos.writeUTF(list.get(i).getClassName()); 11104 } 11105 } catch (IOException e) { 11106 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 11107 file.delete(); 11108 } finally { 11109 FileUtils.sync(fos); 11110 if (dos != null) { 11111 try { 11112 dos.close(); 11113 } catch (IOException e) { 11114 // TODO Auto-generated catch block 11115 e.printStackTrace(); 11116 } 11117 } 11118 } 11119 } 11120 11121 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 11122 ArrayList<ComponentName> doneReceivers, int userId) { 11123 boolean waitingUpdate = false; 11124 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 11125 List<ResolveInfo> ris = null; 11126 try { 11127 ris = AppGlobals.getPackageManager().queryIntentReceivers( 11128 intent, null, 0, userId); 11129 } catch (RemoteException e) { 11130 } 11131 if (ris != null) { 11132 for (int i=ris.size()-1; i>=0; i--) { 11133 if ((ris.get(i).activityInfo.applicationInfo.flags 11134 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11135 ris.remove(i); 11136 } 11137 } 11138 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11139 11140 // For User 0, load the version number. When delivering to a new user, deliver 11141 // to all receivers. 11142 if (userId == UserHandle.USER_OWNER) { 11143 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11144 for (int i=0; i<ris.size(); i++) { 11145 ActivityInfo ai = ris.get(i).activityInfo; 11146 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11147 if (lastDoneReceivers.contains(comp)) { 11148 // We already did the pre boot receiver for this app with the current 11149 // platform version, so don't do it again... 11150 ris.remove(i); 11151 i--; 11152 // ...however, do keep it as one that has been done, so we don't 11153 // forget about it when rewriting the file of last done receivers. 11154 doneReceivers.add(comp); 11155 } 11156 } 11157 } 11158 11159 // If primary user, send broadcast to all available users, else just to userId 11160 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11161 : new int[] { userId }; 11162 for (int i = 0; i < ris.size(); i++) { 11163 ActivityInfo ai = ris.get(i).activityInfo; 11164 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11165 doneReceivers.add(comp); 11166 intent.setComponent(comp); 11167 for (int j=0; j<users.length; j++) { 11168 IIntentReceiver finisher = null; 11169 // On last receiver and user, set up a completion callback 11170 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11171 finisher = new IIntentReceiver.Stub() { 11172 public void performReceive(Intent intent, int resultCode, 11173 String data, Bundle extras, boolean ordered, 11174 boolean sticky, int sendingUser) { 11175 // The raw IIntentReceiver interface is called 11176 // with the AM lock held, so redispatch to 11177 // execute our code without the lock. 11178 mHandler.post(onFinishCallback); 11179 } 11180 }; 11181 } 11182 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11183 + " for user " + users[j]); 11184 broadcastIntentLocked(null, null, intent, null, finisher, 11185 0, null, null, null, AppOpsManager.OP_NONE, 11186 true, false, MY_PID, Process.SYSTEM_UID, 11187 users[j]); 11188 if (finisher != null) { 11189 waitingUpdate = true; 11190 } 11191 } 11192 } 11193 } 11194 11195 return waitingUpdate; 11196 } 11197 11198 public void systemReady(final Runnable goingCallback) { 11199 synchronized(this) { 11200 if (mSystemReady) { 11201 // If we're done calling all the receivers, run the next "boot phase" passed in 11202 // by the SystemServer 11203 if (goingCallback != null) { 11204 goingCallback.run(); 11205 } 11206 return; 11207 } 11208 11209 // Make sure we have the current profile info, since it is needed for 11210 // security checks. 11211 updateCurrentProfileIdsLocked(); 11212 11213 if (mRecentTasks == null) { 11214 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11215 if (!mRecentTasks.isEmpty()) { 11216 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11217 } 11218 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11219 mTaskPersister.startPersisting(); 11220 } 11221 11222 // Check to see if there are any update receivers to run. 11223 if (!mDidUpdate) { 11224 if (mWaitingUpdate) { 11225 return; 11226 } 11227 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11228 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11229 public void run() { 11230 synchronized (ActivityManagerService.this) { 11231 mDidUpdate = true; 11232 } 11233 writeLastDonePreBootReceivers(doneReceivers); 11234 showBootMessage(mContext.getText( 11235 R.string.android_upgrading_complete), 11236 false); 11237 systemReady(goingCallback); 11238 } 11239 }, doneReceivers, UserHandle.USER_OWNER); 11240 11241 if (mWaitingUpdate) { 11242 return; 11243 } 11244 mDidUpdate = true; 11245 } 11246 11247 mAppOpsService.systemReady(); 11248 mSystemReady = true; 11249 } 11250 11251 ArrayList<ProcessRecord> procsToKill = null; 11252 synchronized(mPidsSelfLocked) { 11253 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11254 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11255 if (!isAllowedWhileBooting(proc.info)){ 11256 if (procsToKill == null) { 11257 procsToKill = new ArrayList<ProcessRecord>(); 11258 } 11259 procsToKill.add(proc); 11260 } 11261 } 11262 } 11263 11264 synchronized(this) { 11265 if (procsToKill != null) { 11266 for (int i=procsToKill.size()-1; i>=0; i--) { 11267 ProcessRecord proc = procsToKill.get(i); 11268 Slog.i(TAG, "Removing system update proc: " + proc); 11269 removeProcessLocked(proc, true, false, "system update done"); 11270 } 11271 } 11272 11273 // Now that we have cleaned up any update processes, we 11274 // are ready to start launching real processes and know that 11275 // we won't trample on them any more. 11276 mProcessesReady = true; 11277 } 11278 11279 Slog.i(TAG, "System now ready"); 11280 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11281 SystemClock.uptimeMillis()); 11282 11283 synchronized(this) { 11284 // Make sure we have no pre-ready processes sitting around. 11285 11286 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11287 ResolveInfo ri = mContext.getPackageManager() 11288 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11289 STOCK_PM_FLAGS); 11290 CharSequence errorMsg = null; 11291 if (ri != null) { 11292 ActivityInfo ai = ri.activityInfo; 11293 ApplicationInfo app = ai.applicationInfo; 11294 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11295 mTopAction = Intent.ACTION_FACTORY_TEST; 11296 mTopData = null; 11297 mTopComponent = new ComponentName(app.packageName, 11298 ai.name); 11299 } else { 11300 errorMsg = mContext.getResources().getText( 11301 com.android.internal.R.string.factorytest_not_system); 11302 } 11303 } else { 11304 errorMsg = mContext.getResources().getText( 11305 com.android.internal.R.string.factorytest_no_action); 11306 } 11307 if (errorMsg != null) { 11308 mTopAction = null; 11309 mTopData = null; 11310 mTopComponent = null; 11311 Message msg = Message.obtain(); 11312 msg.what = SHOW_FACTORY_ERROR_MSG; 11313 msg.getData().putCharSequence("msg", errorMsg); 11314 mHandler.sendMessage(msg); 11315 } 11316 } 11317 } 11318 11319 retrieveSettings(); 11320 loadResourcesOnSystemReady(); 11321 11322 synchronized (this) { 11323 readGrantedUriPermissionsLocked(); 11324 } 11325 11326 if (goingCallback != null) goingCallback.run(); 11327 11328 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11329 Integer.toString(mCurrentUserId), mCurrentUserId); 11330 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11331 Integer.toString(mCurrentUserId), mCurrentUserId); 11332 mSystemServiceManager.startUser(mCurrentUserId); 11333 11334 synchronized (this) { 11335 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11336 try { 11337 List apps = AppGlobals.getPackageManager(). 11338 getPersistentApplications(STOCK_PM_FLAGS); 11339 if (apps != null) { 11340 int N = apps.size(); 11341 int i; 11342 for (i=0; i<N; i++) { 11343 ApplicationInfo info 11344 = (ApplicationInfo)apps.get(i); 11345 if (info != null && 11346 !info.packageName.equals("android")) { 11347 addAppLocked(info, false, null /* ABI override */); 11348 } 11349 } 11350 } 11351 } catch (RemoteException ex) { 11352 // pm is in same process, this will never happen. 11353 } 11354 } 11355 11356 // Start up initial activity. 11357 mBooting = true; 11358 startHomeActivityLocked(mCurrentUserId); 11359 11360 try { 11361 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11362 Message msg = Message.obtain(); 11363 msg.what = SHOW_UID_ERROR_MSG; 11364 mHandler.sendMessage(msg); 11365 } 11366 } catch (RemoteException e) { 11367 } 11368 11369 long ident = Binder.clearCallingIdentity(); 11370 try { 11371 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11372 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11373 | Intent.FLAG_RECEIVER_FOREGROUND); 11374 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11375 broadcastIntentLocked(null, null, intent, 11376 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11377 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11378 intent = new Intent(Intent.ACTION_USER_STARTING); 11379 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11380 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11381 broadcastIntentLocked(null, null, intent, 11382 null, new IIntentReceiver.Stub() { 11383 @Override 11384 public void performReceive(Intent intent, int resultCode, String data, 11385 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11386 throws RemoteException { 11387 } 11388 }, 0, null, null, 11389 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11390 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11391 } catch (Throwable t) { 11392 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11393 } finally { 11394 Binder.restoreCallingIdentity(ident); 11395 } 11396 mStackSupervisor.resumeTopActivitiesLocked(); 11397 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11398 } 11399 } 11400 11401 private boolean makeAppCrashingLocked(ProcessRecord app, 11402 String shortMsg, String longMsg, String stackTrace) { 11403 app.crashing = true; 11404 app.crashingReport = generateProcessError(app, 11405 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11406 startAppProblemLocked(app); 11407 app.stopFreezingAllLocked(); 11408 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11409 } 11410 11411 private void makeAppNotRespondingLocked(ProcessRecord app, 11412 String activity, String shortMsg, String longMsg) { 11413 app.notResponding = true; 11414 app.notRespondingReport = generateProcessError(app, 11415 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11416 activity, shortMsg, longMsg, null); 11417 startAppProblemLocked(app); 11418 app.stopFreezingAllLocked(); 11419 } 11420 11421 /** 11422 * Generate a process error record, suitable for attachment to a ProcessRecord. 11423 * 11424 * @param app The ProcessRecord in which the error occurred. 11425 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11426 * ActivityManager.AppErrorStateInfo 11427 * @param activity The activity associated with the crash, if known. 11428 * @param shortMsg Short message describing the crash. 11429 * @param longMsg Long message describing the crash. 11430 * @param stackTrace Full crash stack trace, may be null. 11431 * 11432 * @return Returns a fully-formed AppErrorStateInfo record. 11433 */ 11434 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11435 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11436 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11437 11438 report.condition = condition; 11439 report.processName = app.processName; 11440 report.pid = app.pid; 11441 report.uid = app.info.uid; 11442 report.tag = activity; 11443 report.shortMsg = shortMsg; 11444 report.longMsg = longMsg; 11445 report.stackTrace = stackTrace; 11446 11447 return report; 11448 } 11449 11450 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11451 synchronized (this) { 11452 app.crashing = false; 11453 app.crashingReport = null; 11454 app.notResponding = false; 11455 app.notRespondingReport = null; 11456 if (app.anrDialog == fromDialog) { 11457 app.anrDialog = null; 11458 } 11459 if (app.waitDialog == fromDialog) { 11460 app.waitDialog = null; 11461 } 11462 if (app.pid > 0 && app.pid != MY_PID) { 11463 handleAppCrashLocked(app, null, null, null); 11464 app.kill("user request after error", true); 11465 } 11466 } 11467 } 11468 11469 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11470 String stackTrace) { 11471 long now = SystemClock.uptimeMillis(); 11472 11473 Long crashTime; 11474 if (!app.isolated) { 11475 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11476 } else { 11477 crashTime = null; 11478 } 11479 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11480 // This process loses! 11481 Slog.w(TAG, "Process " + app.info.processName 11482 + " has crashed too many times: killing!"); 11483 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11484 app.userId, app.info.processName, app.uid); 11485 mStackSupervisor.handleAppCrashLocked(app); 11486 if (!app.persistent) { 11487 // We don't want to start this process again until the user 11488 // explicitly does so... but for persistent process, we really 11489 // need to keep it running. If a persistent process is actually 11490 // repeatedly crashing, then badness for everyone. 11491 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11492 app.info.processName); 11493 if (!app.isolated) { 11494 // XXX We don't have a way to mark isolated processes 11495 // as bad, since they don't have a peristent identity. 11496 mBadProcesses.put(app.info.processName, app.uid, 11497 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11498 mProcessCrashTimes.remove(app.info.processName, app.uid); 11499 } 11500 app.bad = true; 11501 app.removed = true; 11502 // Don't let services in this process be restarted and potentially 11503 // annoy the user repeatedly. Unless it is persistent, since those 11504 // processes run critical code. 11505 removeProcessLocked(app, false, false, "crash"); 11506 mStackSupervisor.resumeTopActivitiesLocked(); 11507 return false; 11508 } 11509 mStackSupervisor.resumeTopActivitiesLocked(); 11510 } else { 11511 mStackSupervisor.finishTopRunningActivityLocked(app); 11512 } 11513 11514 // Bump up the crash count of any services currently running in the proc. 11515 for (int i=app.services.size()-1; i>=0; i--) { 11516 // Any services running in the application need to be placed 11517 // back in the pending list. 11518 ServiceRecord sr = app.services.valueAt(i); 11519 sr.crashCount++; 11520 } 11521 11522 // If the crashing process is what we consider to be the "home process" and it has been 11523 // replaced by a third-party app, clear the package preferred activities from packages 11524 // with a home activity running in the process to prevent a repeatedly crashing app 11525 // from blocking the user to manually clear the list. 11526 final ArrayList<ActivityRecord> activities = app.activities; 11527 if (app == mHomeProcess && activities.size() > 0 11528 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11529 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11530 final ActivityRecord r = activities.get(activityNdx); 11531 if (r.isHomeActivity()) { 11532 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11533 try { 11534 ActivityThread.getPackageManager() 11535 .clearPackagePreferredActivities(r.packageName); 11536 } catch (RemoteException c) { 11537 // pm is in same process, this will never happen. 11538 } 11539 } 11540 } 11541 } 11542 11543 if (!app.isolated) { 11544 // XXX Can't keep track of crash times for isolated processes, 11545 // because they don't have a perisistent identity. 11546 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11547 } 11548 11549 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11550 return true; 11551 } 11552 11553 void startAppProblemLocked(ProcessRecord app) { 11554 // If this app is not running under the current user, then we 11555 // can't give it a report button because that would require 11556 // launching the report UI under a different user. 11557 app.errorReportReceiver = null; 11558 11559 for (int userId : mCurrentProfileIds) { 11560 if (app.userId == userId) { 11561 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11562 mContext, app.info.packageName, app.info.flags); 11563 } 11564 } 11565 skipCurrentReceiverLocked(app); 11566 } 11567 11568 void skipCurrentReceiverLocked(ProcessRecord app) { 11569 for (BroadcastQueue queue : mBroadcastQueues) { 11570 queue.skipCurrentReceiverLocked(app); 11571 } 11572 } 11573 11574 /** 11575 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11576 * The application process will exit immediately after this call returns. 11577 * @param app object of the crashing app, null for the system server 11578 * @param crashInfo describing the exception 11579 */ 11580 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11581 ProcessRecord r = findAppProcess(app, "Crash"); 11582 final String processName = app == null ? "system_server" 11583 : (r == null ? "unknown" : r.processName); 11584 11585 handleApplicationCrashInner("crash", r, processName, crashInfo); 11586 } 11587 11588 /* Native crash reporting uses this inner version because it needs to be somewhat 11589 * decoupled from the AM-managed cleanup lifecycle 11590 */ 11591 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11592 ApplicationErrorReport.CrashInfo crashInfo) { 11593 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11594 UserHandle.getUserId(Binder.getCallingUid()), processName, 11595 r == null ? -1 : r.info.flags, 11596 crashInfo.exceptionClassName, 11597 crashInfo.exceptionMessage, 11598 crashInfo.throwFileName, 11599 crashInfo.throwLineNumber); 11600 11601 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11602 11603 crashApplication(r, crashInfo); 11604 } 11605 11606 public void handleApplicationStrictModeViolation( 11607 IBinder app, 11608 int violationMask, 11609 StrictMode.ViolationInfo info) { 11610 ProcessRecord r = findAppProcess(app, "StrictMode"); 11611 if (r == null) { 11612 return; 11613 } 11614 11615 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11616 Integer stackFingerprint = info.hashCode(); 11617 boolean logIt = true; 11618 synchronized (mAlreadyLoggedViolatedStacks) { 11619 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11620 logIt = false; 11621 // TODO: sub-sample into EventLog for these, with 11622 // the info.durationMillis? Then we'd get 11623 // the relative pain numbers, without logging all 11624 // the stack traces repeatedly. We'd want to do 11625 // likewise in the client code, which also does 11626 // dup suppression, before the Binder call. 11627 } else { 11628 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11629 mAlreadyLoggedViolatedStacks.clear(); 11630 } 11631 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11632 } 11633 } 11634 if (logIt) { 11635 logStrictModeViolationToDropBox(r, info); 11636 } 11637 } 11638 11639 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11640 AppErrorResult result = new AppErrorResult(); 11641 synchronized (this) { 11642 final long origId = Binder.clearCallingIdentity(); 11643 11644 Message msg = Message.obtain(); 11645 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11646 HashMap<String, Object> data = new HashMap<String, Object>(); 11647 data.put("result", result); 11648 data.put("app", r); 11649 data.put("violationMask", violationMask); 11650 data.put("info", info); 11651 msg.obj = data; 11652 mHandler.sendMessage(msg); 11653 11654 Binder.restoreCallingIdentity(origId); 11655 } 11656 int res = result.get(); 11657 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11658 } 11659 } 11660 11661 // Depending on the policy in effect, there could be a bunch of 11662 // these in quick succession so we try to batch these together to 11663 // minimize disk writes, number of dropbox entries, and maximize 11664 // compression, by having more fewer, larger records. 11665 private void logStrictModeViolationToDropBox( 11666 ProcessRecord process, 11667 StrictMode.ViolationInfo info) { 11668 if (info == null) { 11669 return; 11670 } 11671 final boolean isSystemApp = process == null || 11672 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11673 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11674 final String processName = process == null ? "unknown" : process.processName; 11675 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11676 final DropBoxManager dbox = (DropBoxManager) 11677 mContext.getSystemService(Context.DROPBOX_SERVICE); 11678 11679 // Exit early if the dropbox isn't configured to accept this report type. 11680 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11681 11682 boolean bufferWasEmpty; 11683 boolean needsFlush; 11684 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11685 synchronized (sb) { 11686 bufferWasEmpty = sb.length() == 0; 11687 appendDropBoxProcessHeaders(process, processName, sb); 11688 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11689 sb.append("System-App: ").append(isSystemApp).append("\n"); 11690 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11691 if (info.violationNumThisLoop != 0) { 11692 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11693 } 11694 if (info.numAnimationsRunning != 0) { 11695 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11696 } 11697 if (info.broadcastIntentAction != null) { 11698 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11699 } 11700 if (info.durationMillis != -1) { 11701 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11702 } 11703 if (info.numInstances != -1) { 11704 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11705 } 11706 if (info.tags != null) { 11707 for (String tag : info.tags) { 11708 sb.append("Span-Tag: ").append(tag).append("\n"); 11709 } 11710 } 11711 sb.append("\n"); 11712 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11713 sb.append(info.crashInfo.stackTrace); 11714 } 11715 sb.append("\n"); 11716 11717 // Only buffer up to ~64k. Various logging bits truncate 11718 // things at 128k. 11719 needsFlush = (sb.length() > 64 * 1024); 11720 } 11721 11722 // Flush immediately if the buffer's grown too large, or this 11723 // is a non-system app. Non-system apps are isolated with a 11724 // different tag & policy and not batched. 11725 // 11726 // Batching is useful during internal testing with 11727 // StrictMode settings turned up high. Without batching, 11728 // thousands of separate files could be created on boot. 11729 if (!isSystemApp || needsFlush) { 11730 new Thread("Error dump: " + dropboxTag) { 11731 @Override 11732 public void run() { 11733 String report; 11734 synchronized (sb) { 11735 report = sb.toString(); 11736 sb.delete(0, sb.length()); 11737 sb.trimToSize(); 11738 } 11739 if (report.length() != 0) { 11740 dbox.addText(dropboxTag, report); 11741 } 11742 } 11743 }.start(); 11744 return; 11745 } 11746 11747 // System app batching: 11748 if (!bufferWasEmpty) { 11749 // An existing dropbox-writing thread is outstanding, so 11750 // we don't need to start it up. The existing thread will 11751 // catch the buffer appends we just did. 11752 return; 11753 } 11754 11755 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11756 // (After this point, we shouldn't access AMS internal data structures.) 11757 new Thread("Error dump: " + dropboxTag) { 11758 @Override 11759 public void run() { 11760 // 5 second sleep to let stacks arrive and be batched together 11761 try { 11762 Thread.sleep(5000); // 5 seconds 11763 } catch (InterruptedException e) {} 11764 11765 String errorReport; 11766 synchronized (mStrictModeBuffer) { 11767 errorReport = mStrictModeBuffer.toString(); 11768 if (errorReport.length() == 0) { 11769 return; 11770 } 11771 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11772 mStrictModeBuffer.trimToSize(); 11773 } 11774 dbox.addText(dropboxTag, errorReport); 11775 } 11776 }.start(); 11777 } 11778 11779 /** 11780 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11781 * @param app object of the crashing app, null for the system server 11782 * @param tag reported by the caller 11783 * @param system whether this wtf is coming from the system 11784 * @param crashInfo describing the context of the error 11785 * @return true if the process should exit immediately (WTF is fatal) 11786 */ 11787 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 11788 final ApplicationErrorReport.CrashInfo crashInfo) { 11789 final int callingUid = Binder.getCallingUid(); 11790 final int callingPid = Binder.getCallingPid(); 11791 11792 if (system) { 11793 // If this is coming from the system, we could very well have low-level 11794 // system locks held, so we want to do this all asynchronously. And we 11795 // never want this to become fatal, so there is that too. 11796 mHandler.post(new Runnable() { 11797 @Override public void run() { 11798 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 11799 } 11800 }); 11801 return false; 11802 } 11803 11804 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 11805 crashInfo); 11806 11807 if (r != null && r.pid != Process.myPid() && 11808 Settings.Global.getInt(mContext.getContentResolver(), 11809 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11810 crashApplication(r, crashInfo); 11811 return true; 11812 } else { 11813 return false; 11814 } 11815 } 11816 11817 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 11818 final ApplicationErrorReport.CrashInfo crashInfo) { 11819 final ProcessRecord r = findAppProcess(app, "WTF"); 11820 final String processName = app == null ? "system_server" 11821 : (r == null ? "unknown" : r.processName); 11822 11823 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 11824 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 11825 11826 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11827 11828 return r; 11829 } 11830 11831 /** 11832 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11833 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11834 */ 11835 private ProcessRecord findAppProcess(IBinder app, String reason) { 11836 if (app == null) { 11837 return null; 11838 } 11839 11840 synchronized (this) { 11841 final int NP = mProcessNames.getMap().size(); 11842 for (int ip=0; ip<NP; ip++) { 11843 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11844 final int NA = apps.size(); 11845 for (int ia=0; ia<NA; ia++) { 11846 ProcessRecord p = apps.valueAt(ia); 11847 if (p.thread != null && p.thread.asBinder() == app) { 11848 return p; 11849 } 11850 } 11851 } 11852 11853 Slog.w(TAG, "Can't find mystery application for " + reason 11854 + " from pid=" + Binder.getCallingPid() 11855 + " uid=" + Binder.getCallingUid() + ": " + app); 11856 return null; 11857 } 11858 } 11859 11860 /** 11861 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11862 * to append various headers to the dropbox log text. 11863 */ 11864 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11865 StringBuilder sb) { 11866 // Watchdog thread ends up invoking this function (with 11867 // a null ProcessRecord) to add the stack file to dropbox. 11868 // Do not acquire a lock on this (am) in such cases, as it 11869 // could cause a potential deadlock, if and when watchdog 11870 // is invoked due to unavailability of lock on am and it 11871 // would prevent watchdog from killing system_server. 11872 if (process == null) { 11873 sb.append("Process: ").append(processName).append("\n"); 11874 return; 11875 } 11876 // Note: ProcessRecord 'process' is guarded by the service 11877 // instance. (notably process.pkgList, which could otherwise change 11878 // concurrently during execution of this method) 11879 synchronized (this) { 11880 sb.append("Process: ").append(processName).append("\n"); 11881 int flags = process.info.flags; 11882 IPackageManager pm = AppGlobals.getPackageManager(); 11883 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11884 for (int ip=0; ip<process.pkgList.size(); ip++) { 11885 String pkg = process.pkgList.keyAt(ip); 11886 sb.append("Package: ").append(pkg); 11887 try { 11888 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11889 if (pi != null) { 11890 sb.append(" v").append(pi.versionCode); 11891 if (pi.versionName != null) { 11892 sb.append(" (").append(pi.versionName).append(")"); 11893 } 11894 } 11895 } catch (RemoteException e) { 11896 Slog.e(TAG, "Error getting package info: " + pkg, e); 11897 } 11898 sb.append("\n"); 11899 } 11900 } 11901 } 11902 11903 private static String processClass(ProcessRecord process) { 11904 if (process == null || process.pid == MY_PID) { 11905 return "system_server"; 11906 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11907 return "system_app"; 11908 } else { 11909 return "data_app"; 11910 } 11911 } 11912 11913 /** 11914 * Write a description of an error (crash, WTF, ANR) to the drop box. 11915 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11916 * @param process which caused the error, null means the system server 11917 * @param activity which triggered the error, null if unknown 11918 * @param parent activity related to the error, null if unknown 11919 * @param subject line related to the error, null if absent 11920 * @param report in long form describing the error, null if absent 11921 * @param logFile to include in the report, null if none 11922 * @param crashInfo giving an application stack trace, null if absent 11923 */ 11924 public void addErrorToDropBox(String eventType, 11925 ProcessRecord process, String processName, ActivityRecord activity, 11926 ActivityRecord parent, String subject, 11927 final String report, final File logFile, 11928 final ApplicationErrorReport.CrashInfo crashInfo) { 11929 // NOTE -- this must never acquire the ActivityManagerService lock, 11930 // otherwise the watchdog may be prevented from resetting the system. 11931 11932 final String dropboxTag = processClass(process) + "_" + eventType; 11933 final DropBoxManager dbox = (DropBoxManager) 11934 mContext.getSystemService(Context.DROPBOX_SERVICE); 11935 11936 // Exit early if the dropbox isn't configured to accept this report type. 11937 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11938 11939 final StringBuilder sb = new StringBuilder(1024); 11940 appendDropBoxProcessHeaders(process, processName, sb); 11941 if (activity != null) { 11942 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11943 } 11944 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11945 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11946 } 11947 if (parent != null && parent != activity) { 11948 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11949 } 11950 if (subject != null) { 11951 sb.append("Subject: ").append(subject).append("\n"); 11952 } 11953 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11954 if (Debug.isDebuggerConnected()) { 11955 sb.append("Debugger: Connected\n"); 11956 } 11957 sb.append("\n"); 11958 11959 // Do the rest in a worker thread to avoid blocking the caller on I/O 11960 // (After this point, we shouldn't access AMS internal data structures.) 11961 Thread worker = new Thread("Error dump: " + dropboxTag) { 11962 @Override 11963 public void run() { 11964 if (report != null) { 11965 sb.append(report); 11966 } 11967 if (logFile != null) { 11968 try { 11969 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11970 "\n\n[[TRUNCATED]]")); 11971 } catch (IOException e) { 11972 Slog.e(TAG, "Error reading " + logFile, e); 11973 } 11974 } 11975 if (crashInfo != null && crashInfo.stackTrace != null) { 11976 sb.append(crashInfo.stackTrace); 11977 } 11978 11979 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11980 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11981 if (lines > 0) { 11982 sb.append("\n"); 11983 11984 // Merge several logcat streams, and take the last N lines 11985 InputStreamReader input = null; 11986 try { 11987 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11988 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11989 "-b", "crash", 11990 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11991 11992 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11993 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11994 input = new InputStreamReader(logcat.getInputStream()); 11995 11996 int num; 11997 char[] buf = new char[8192]; 11998 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11999 } catch (IOException e) { 12000 Slog.e(TAG, "Error running logcat", e); 12001 } finally { 12002 if (input != null) try { input.close(); } catch (IOException e) {} 12003 } 12004 } 12005 12006 dbox.addText(dropboxTag, sb.toString()); 12007 } 12008 }; 12009 12010 if (process == null) { 12011 // If process is null, we are being called from some internal code 12012 // and may be about to die -- run this synchronously. 12013 worker.run(); 12014 } else { 12015 worker.start(); 12016 } 12017 } 12018 12019 /** 12020 * Bring up the "unexpected error" dialog box for a crashing app. 12021 * Deal with edge cases (intercepts from instrumented applications, 12022 * ActivityController, error intent receivers, that sort of thing). 12023 * @param r the application crashing 12024 * @param crashInfo describing the failure 12025 */ 12026 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 12027 long timeMillis = System.currentTimeMillis(); 12028 String shortMsg = crashInfo.exceptionClassName; 12029 String longMsg = crashInfo.exceptionMessage; 12030 String stackTrace = crashInfo.stackTrace; 12031 if (shortMsg != null && longMsg != null) { 12032 longMsg = shortMsg + ": " + longMsg; 12033 } else if (shortMsg != null) { 12034 longMsg = shortMsg; 12035 } 12036 12037 AppErrorResult result = new AppErrorResult(); 12038 synchronized (this) { 12039 if (mController != null) { 12040 try { 12041 String name = r != null ? r.processName : null; 12042 int pid = r != null ? r.pid : Binder.getCallingPid(); 12043 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 12044 if (!mController.appCrashed(name, pid, 12045 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 12046 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 12047 && "Native crash".equals(crashInfo.exceptionClassName)) { 12048 Slog.w(TAG, "Skip killing native crashed app " + name 12049 + "(" + pid + ") during testing"); 12050 } else { 12051 Slog.w(TAG, "Force-killing crashed app " + name 12052 + " at watcher's request"); 12053 if (r != null) { 12054 r.kill("crash", true); 12055 } else { 12056 // Huh. 12057 Process.killProcess(pid); 12058 Process.killProcessGroup(uid, pid); 12059 } 12060 } 12061 return; 12062 } 12063 } catch (RemoteException e) { 12064 mController = null; 12065 Watchdog.getInstance().setActivityController(null); 12066 } 12067 } 12068 12069 final long origId = Binder.clearCallingIdentity(); 12070 12071 // If this process is running instrumentation, finish it. 12072 if (r != null && r.instrumentationClass != null) { 12073 Slog.w(TAG, "Error in app " + r.processName 12074 + " running instrumentation " + r.instrumentationClass + ":"); 12075 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 12076 if (longMsg != null) Slog.w(TAG, " " + longMsg); 12077 Bundle info = new Bundle(); 12078 info.putString("shortMsg", shortMsg); 12079 info.putString("longMsg", longMsg); 12080 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 12081 Binder.restoreCallingIdentity(origId); 12082 return; 12083 } 12084 12085 // If we can't identify the process or it's already exceeded its crash quota, 12086 // quit right away without showing a crash dialog. 12087 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 12088 Binder.restoreCallingIdentity(origId); 12089 return; 12090 } 12091 12092 Message msg = Message.obtain(); 12093 msg.what = SHOW_ERROR_MSG; 12094 HashMap data = new HashMap(); 12095 data.put("result", result); 12096 data.put("app", r); 12097 msg.obj = data; 12098 mHandler.sendMessage(msg); 12099 12100 Binder.restoreCallingIdentity(origId); 12101 } 12102 12103 int res = result.get(); 12104 12105 Intent appErrorIntent = null; 12106 synchronized (this) { 12107 if (r != null && !r.isolated) { 12108 // XXX Can't keep track of crash time for isolated processes, 12109 // since they don't have a persistent identity. 12110 mProcessCrashTimes.put(r.info.processName, r.uid, 12111 SystemClock.uptimeMillis()); 12112 } 12113 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 12114 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 12115 } 12116 } 12117 12118 if (appErrorIntent != null) { 12119 try { 12120 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 12121 } catch (ActivityNotFoundException e) { 12122 Slog.w(TAG, "bug report receiver dissappeared", e); 12123 } 12124 } 12125 } 12126 12127 Intent createAppErrorIntentLocked(ProcessRecord r, 12128 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12129 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 12130 if (report == null) { 12131 return null; 12132 } 12133 Intent result = new Intent(Intent.ACTION_APP_ERROR); 12134 result.setComponent(r.errorReportReceiver); 12135 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 12136 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12137 return result; 12138 } 12139 12140 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12141 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12142 if (r.errorReportReceiver == null) { 12143 return null; 12144 } 12145 12146 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12147 return null; 12148 } 12149 12150 ApplicationErrorReport report = new ApplicationErrorReport(); 12151 report.packageName = r.info.packageName; 12152 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12153 report.processName = r.processName; 12154 report.time = timeMillis; 12155 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12156 12157 if (r.crashing || r.forceCrashReport) { 12158 report.type = ApplicationErrorReport.TYPE_CRASH; 12159 report.crashInfo = crashInfo; 12160 } else if (r.notResponding) { 12161 report.type = ApplicationErrorReport.TYPE_ANR; 12162 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12163 12164 report.anrInfo.activity = r.notRespondingReport.tag; 12165 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12166 report.anrInfo.info = r.notRespondingReport.longMsg; 12167 } 12168 12169 return report; 12170 } 12171 12172 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12173 enforceNotIsolatedCaller("getProcessesInErrorState"); 12174 // assume our apps are happy - lazy create the list 12175 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12176 12177 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12178 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12179 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12180 12181 synchronized (this) { 12182 12183 // iterate across all processes 12184 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12185 ProcessRecord app = mLruProcesses.get(i); 12186 if (!allUsers && app.userId != userId) { 12187 continue; 12188 } 12189 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12190 // This one's in trouble, so we'll generate a report for it 12191 // crashes are higher priority (in case there's a crash *and* an anr) 12192 ActivityManager.ProcessErrorStateInfo report = null; 12193 if (app.crashing) { 12194 report = app.crashingReport; 12195 } else if (app.notResponding) { 12196 report = app.notRespondingReport; 12197 } 12198 12199 if (report != null) { 12200 if (errList == null) { 12201 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12202 } 12203 errList.add(report); 12204 } else { 12205 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12206 " crashing = " + app.crashing + 12207 " notResponding = " + app.notResponding); 12208 } 12209 } 12210 } 12211 } 12212 12213 return errList; 12214 } 12215 12216 static int procStateToImportance(int procState, int memAdj, 12217 ActivityManager.RunningAppProcessInfo currApp) { 12218 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12219 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12220 currApp.lru = memAdj; 12221 } else { 12222 currApp.lru = 0; 12223 } 12224 return imp; 12225 } 12226 12227 private void fillInProcMemInfo(ProcessRecord app, 12228 ActivityManager.RunningAppProcessInfo outInfo) { 12229 outInfo.pid = app.pid; 12230 outInfo.uid = app.info.uid; 12231 if (mHeavyWeightProcess == app) { 12232 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12233 } 12234 if (app.persistent) { 12235 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12236 } 12237 if (app.activities.size() > 0) { 12238 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12239 } 12240 outInfo.lastTrimLevel = app.trimMemoryLevel; 12241 int adj = app.curAdj; 12242 int procState = app.curProcState; 12243 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12244 outInfo.importanceReasonCode = app.adjTypeCode; 12245 outInfo.processState = app.curProcState; 12246 } 12247 12248 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12249 enforceNotIsolatedCaller("getRunningAppProcesses"); 12250 // Lazy instantiation of list 12251 List<ActivityManager.RunningAppProcessInfo> runList = null; 12252 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12253 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12254 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12255 synchronized (this) { 12256 // Iterate across all processes 12257 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12258 ProcessRecord app = mLruProcesses.get(i); 12259 if (!allUsers && app.userId != userId) { 12260 continue; 12261 } 12262 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12263 // Generate process state info for running application 12264 ActivityManager.RunningAppProcessInfo currApp = 12265 new ActivityManager.RunningAppProcessInfo(app.processName, 12266 app.pid, app.getPackageList()); 12267 fillInProcMemInfo(app, currApp); 12268 if (app.adjSource instanceof ProcessRecord) { 12269 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12270 currApp.importanceReasonImportance = 12271 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12272 app.adjSourceProcState); 12273 } else if (app.adjSource instanceof ActivityRecord) { 12274 ActivityRecord r = (ActivityRecord)app.adjSource; 12275 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12276 } 12277 if (app.adjTarget instanceof ComponentName) { 12278 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12279 } 12280 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12281 // + " lru=" + currApp.lru); 12282 if (runList == null) { 12283 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12284 } 12285 runList.add(currApp); 12286 } 12287 } 12288 } 12289 return runList; 12290 } 12291 12292 public List<ApplicationInfo> getRunningExternalApplications() { 12293 enforceNotIsolatedCaller("getRunningExternalApplications"); 12294 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12295 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12296 if (runningApps != null && runningApps.size() > 0) { 12297 Set<String> extList = new HashSet<String>(); 12298 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12299 if (app.pkgList != null) { 12300 for (String pkg : app.pkgList) { 12301 extList.add(pkg); 12302 } 12303 } 12304 } 12305 IPackageManager pm = AppGlobals.getPackageManager(); 12306 for (String pkg : extList) { 12307 try { 12308 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12309 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12310 retList.add(info); 12311 } 12312 } catch (RemoteException e) { 12313 } 12314 } 12315 } 12316 return retList; 12317 } 12318 12319 @Override 12320 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12321 enforceNotIsolatedCaller("getMyMemoryState"); 12322 synchronized (this) { 12323 ProcessRecord proc; 12324 synchronized (mPidsSelfLocked) { 12325 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12326 } 12327 fillInProcMemInfo(proc, outInfo); 12328 } 12329 } 12330 12331 @Override 12332 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12333 if (checkCallingPermission(android.Manifest.permission.DUMP) 12334 != PackageManager.PERMISSION_GRANTED) { 12335 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12336 + Binder.getCallingPid() 12337 + ", uid=" + Binder.getCallingUid() 12338 + " without permission " 12339 + android.Manifest.permission.DUMP); 12340 return; 12341 } 12342 12343 boolean dumpAll = false; 12344 boolean dumpClient = false; 12345 String dumpPackage = null; 12346 12347 int opti = 0; 12348 while (opti < args.length) { 12349 String opt = args[opti]; 12350 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12351 break; 12352 } 12353 opti++; 12354 if ("-a".equals(opt)) { 12355 dumpAll = true; 12356 } else if ("-c".equals(opt)) { 12357 dumpClient = true; 12358 } else if ("-h".equals(opt)) { 12359 pw.println("Activity manager dump options:"); 12360 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12361 pw.println(" cmd may be one of:"); 12362 pw.println(" a[ctivities]: activity stack state"); 12363 pw.println(" r[recents]: recent activities state"); 12364 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12365 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12366 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12367 pw.println(" o[om]: out of memory management"); 12368 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12369 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12370 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12371 pw.println(" service [COMP_SPEC]: service client-side state"); 12372 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12373 pw.println(" all: dump all activities"); 12374 pw.println(" top: dump the top activity"); 12375 pw.println(" write: write all pending state to storage"); 12376 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12377 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12378 pw.println(" a partial substring in a component name, a"); 12379 pw.println(" hex object identifier."); 12380 pw.println(" -a: include all available server state."); 12381 pw.println(" -c: include client state."); 12382 return; 12383 } else { 12384 pw.println("Unknown argument: " + opt + "; use -h for help"); 12385 } 12386 } 12387 12388 long origId = Binder.clearCallingIdentity(); 12389 boolean more = false; 12390 // Is the caller requesting to dump a particular piece of data? 12391 if (opti < args.length) { 12392 String cmd = args[opti]; 12393 opti++; 12394 if ("activities".equals(cmd) || "a".equals(cmd)) { 12395 synchronized (this) { 12396 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12397 } 12398 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12399 synchronized (this) { 12400 dumpRecentsLocked(fd, pw, args, opti, true, null); 12401 } 12402 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12403 String[] newArgs; 12404 String name; 12405 if (opti >= args.length) { 12406 name = null; 12407 newArgs = EMPTY_STRING_ARRAY; 12408 } else { 12409 name = args[opti]; 12410 opti++; 12411 newArgs = new String[args.length - opti]; 12412 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12413 args.length - opti); 12414 } 12415 synchronized (this) { 12416 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12417 } 12418 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12419 String[] newArgs; 12420 String name; 12421 if (opti >= args.length) { 12422 name = null; 12423 newArgs = EMPTY_STRING_ARRAY; 12424 } else { 12425 name = args[opti]; 12426 opti++; 12427 newArgs = new String[args.length - opti]; 12428 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12429 args.length - opti); 12430 } 12431 synchronized (this) { 12432 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12433 } 12434 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12435 String[] newArgs; 12436 String name; 12437 if (opti >= args.length) { 12438 name = null; 12439 newArgs = EMPTY_STRING_ARRAY; 12440 } else { 12441 name = args[opti]; 12442 opti++; 12443 newArgs = new String[args.length - opti]; 12444 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12445 args.length - opti); 12446 } 12447 synchronized (this) { 12448 dumpProcessesLocked(fd, pw, args, opti, true, name); 12449 } 12450 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12451 synchronized (this) { 12452 dumpOomLocked(fd, pw, args, opti, true); 12453 } 12454 } else if ("provider".equals(cmd)) { 12455 String[] newArgs; 12456 String name; 12457 if (opti >= args.length) { 12458 name = null; 12459 newArgs = EMPTY_STRING_ARRAY; 12460 } else { 12461 name = args[opti]; 12462 opti++; 12463 newArgs = new String[args.length - opti]; 12464 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12465 } 12466 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12467 pw.println("No providers match: " + name); 12468 pw.println("Use -h for help."); 12469 } 12470 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12471 synchronized (this) { 12472 dumpProvidersLocked(fd, pw, args, opti, true, null); 12473 } 12474 } else if ("service".equals(cmd)) { 12475 String[] newArgs; 12476 String name; 12477 if (opti >= args.length) { 12478 name = null; 12479 newArgs = EMPTY_STRING_ARRAY; 12480 } else { 12481 name = args[opti]; 12482 opti++; 12483 newArgs = new String[args.length - opti]; 12484 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12485 args.length - opti); 12486 } 12487 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12488 pw.println("No services match: " + name); 12489 pw.println("Use -h for help."); 12490 } 12491 } else if ("package".equals(cmd)) { 12492 String[] newArgs; 12493 if (opti >= args.length) { 12494 pw.println("package: no package name specified"); 12495 pw.println("Use -h for help."); 12496 } else { 12497 dumpPackage = args[opti]; 12498 opti++; 12499 newArgs = new String[args.length - opti]; 12500 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12501 args.length - opti); 12502 args = newArgs; 12503 opti = 0; 12504 more = true; 12505 } 12506 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12507 synchronized (this) { 12508 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12509 } 12510 } else if ("write".equals(cmd)) { 12511 mTaskPersister.flush(); 12512 pw.println("All tasks persisted."); 12513 return; 12514 } else { 12515 // Dumping a single activity? 12516 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12517 pw.println("Bad activity command, or no activities match: " + cmd); 12518 pw.println("Use -h for help."); 12519 } 12520 } 12521 if (!more) { 12522 Binder.restoreCallingIdentity(origId); 12523 return; 12524 } 12525 } 12526 12527 // No piece of data specified, dump everything. 12528 synchronized (this) { 12529 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12530 pw.println(); 12531 if (dumpAll) { 12532 pw.println("-------------------------------------------------------------------------------"); 12533 } 12534 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12535 pw.println(); 12536 if (dumpAll) { 12537 pw.println("-------------------------------------------------------------------------------"); 12538 } 12539 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12540 pw.println(); 12541 if (dumpAll) { 12542 pw.println("-------------------------------------------------------------------------------"); 12543 } 12544 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12545 pw.println(); 12546 if (dumpAll) { 12547 pw.println("-------------------------------------------------------------------------------"); 12548 } 12549 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12550 pw.println(); 12551 if (dumpAll) { 12552 pw.println("-------------------------------------------------------------------------------"); 12553 } 12554 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12555 pw.println(); 12556 if (dumpAll) { 12557 pw.println("-------------------------------------------------------------------------------"); 12558 } 12559 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12560 } 12561 Binder.restoreCallingIdentity(origId); 12562 } 12563 12564 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12565 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12566 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12567 12568 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12569 dumpPackage); 12570 boolean needSep = printedAnything; 12571 12572 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12573 dumpPackage, needSep, " mFocusedActivity: "); 12574 if (printed) { 12575 printedAnything = true; 12576 needSep = false; 12577 } 12578 12579 if (dumpPackage == null) { 12580 if (needSep) { 12581 pw.println(); 12582 } 12583 needSep = true; 12584 printedAnything = true; 12585 mStackSupervisor.dump(pw, " "); 12586 } 12587 12588 if (!printedAnything) { 12589 pw.println(" (nothing)"); 12590 } 12591 } 12592 12593 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12594 int opti, boolean dumpAll, String dumpPackage) { 12595 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 12596 12597 boolean printedAnything = false; 12598 12599 if (mRecentTasks != null && mRecentTasks.size() > 0) { 12600 boolean printedHeader = false; 12601 12602 final int N = mRecentTasks.size(); 12603 for (int i=0; i<N; i++) { 12604 TaskRecord tr = mRecentTasks.get(i); 12605 if (dumpPackage != null) { 12606 if (tr.realActivity == null || 12607 !dumpPackage.equals(tr.realActivity)) { 12608 continue; 12609 } 12610 } 12611 if (!printedHeader) { 12612 pw.println(" Recent tasks:"); 12613 printedHeader = true; 12614 printedAnything = true; 12615 } 12616 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12617 pw.println(tr); 12618 if (dumpAll) { 12619 mRecentTasks.get(i).dump(pw, " "); 12620 } 12621 } 12622 } 12623 12624 if (!printedAnything) { 12625 pw.println(" (nothing)"); 12626 } 12627 } 12628 12629 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12630 int opti, boolean dumpAll, String dumpPackage) { 12631 boolean needSep = false; 12632 boolean printedAnything = false; 12633 int numPers = 0; 12634 12635 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12636 12637 if (dumpAll) { 12638 final int NP = mProcessNames.getMap().size(); 12639 for (int ip=0; ip<NP; ip++) { 12640 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12641 final int NA = procs.size(); 12642 for (int ia=0; ia<NA; ia++) { 12643 ProcessRecord r = procs.valueAt(ia); 12644 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12645 continue; 12646 } 12647 if (!needSep) { 12648 pw.println(" All known processes:"); 12649 needSep = true; 12650 printedAnything = true; 12651 } 12652 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12653 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12654 pw.print(" "); pw.println(r); 12655 r.dump(pw, " "); 12656 if (r.persistent) { 12657 numPers++; 12658 } 12659 } 12660 } 12661 } 12662 12663 if (mIsolatedProcesses.size() > 0) { 12664 boolean printed = false; 12665 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12666 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12667 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12668 continue; 12669 } 12670 if (!printed) { 12671 if (needSep) { 12672 pw.println(); 12673 } 12674 pw.println(" Isolated process list (sorted by uid):"); 12675 printedAnything = true; 12676 printed = true; 12677 needSep = true; 12678 } 12679 pw.println(String.format("%sIsolated #%2d: %s", 12680 " ", i, r.toString())); 12681 } 12682 } 12683 12684 if (mLruProcesses.size() > 0) { 12685 if (needSep) { 12686 pw.println(); 12687 } 12688 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12689 pw.print(" total, non-act at "); 12690 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12691 pw.print(", non-svc at "); 12692 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12693 pw.println("):"); 12694 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12695 needSep = true; 12696 printedAnything = true; 12697 } 12698 12699 if (dumpAll || dumpPackage != null) { 12700 synchronized (mPidsSelfLocked) { 12701 boolean printed = false; 12702 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12703 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12704 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12705 continue; 12706 } 12707 if (!printed) { 12708 if (needSep) pw.println(); 12709 needSep = true; 12710 pw.println(" PID mappings:"); 12711 printed = true; 12712 printedAnything = true; 12713 } 12714 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12715 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12716 } 12717 } 12718 } 12719 12720 if (mForegroundProcesses.size() > 0) { 12721 synchronized (mPidsSelfLocked) { 12722 boolean printed = false; 12723 for (int i=0; i<mForegroundProcesses.size(); i++) { 12724 ProcessRecord r = mPidsSelfLocked.get( 12725 mForegroundProcesses.valueAt(i).pid); 12726 if (dumpPackage != null && (r == null 12727 || !r.pkgList.containsKey(dumpPackage))) { 12728 continue; 12729 } 12730 if (!printed) { 12731 if (needSep) pw.println(); 12732 needSep = true; 12733 pw.println(" Foreground Processes:"); 12734 printed = true; 12735 printedAnything = true; 12736 } 12737 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12738 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12739 } 12740 } 12741 } 12742 12743 if (mPersistentStartingProcesses.size() > 0) { 12744 if (needSep) pw.println(); 12745 needSep = true; 12746 printedAnything = true; 12747 pw.println(" Persisent processes that are starting:"); 12748 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12749 "Starting Norm", "Restarting PERS", dumpPackage); 12750 } 12751 12752 if (mRemovedProcesses.size() > 0) { 12753 if (needSep) pw.println(); 12754 needSep = true; 12755 printedAnything = true; 12756 pw.println(" Processes that are being removed:"); 12757 dumpProcessList(pw, this, mRemovedProcesses, " ", 12758 "Removed Norm", "Removed PERS", dumpPackage); 12759 } 12760 12761 if (mProcessesOnHold.size() > 0) { 12762 if (needSep) pw.println(); 12763 needSep = true; 12764 printedAnything = true; 12765 pw.println(" Processes that are on old until the system is ready:"); 12766 dumpProcessList(pw, this, mProcessesOnHold, " ", 12767 "OnHold Norm", "OnHold PERS", dumpPackage); 12768 } 12769 12770 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12771 12772 if (mProcessCrashTimes.getMap().size() > 0) { 12773 boolean printed = false; 12774 long now = SystemClock.uptimeMillis(); 12775 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12776 final int NP = pmap.size(); 12777 for (int ip=0; ip<NP; ip++) { 12778 String pname = pmap.keyAt(ip); 12779 SparseArray<Long> uids = pmap.valueAt(ip); 12780 final int N = uids.size(); 12781 for (int i=0; i<N; i++) { 12782 int puid = uids.keyAt(i); 12783 ProcessRecord r = mProcessNames.get(pname, puid); 12784 if (dumpPackage != null && (r == null 12785 || !r.pkgList.containsKey(dumpPackage))) { 12786 continue; 12787 } 12788 if (!printed) { 12789 if (needSep) pw.println(); 12790 needSep = true; 12791 pw.println(" Time since processes crashed:"); 12792 printed = true; 12793 printedAnything = true; 12794 } 12795 pw.print(" Process "); pw.print(pname); 12796 pw.print(" uid "); pw.print(puid); 12797 pw.print(": last crashed "); 12798 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12799 pw.println(" ago"); 12800 } 12801 } 12802 } 12803 12804 if (mBadProcesses.getMap().size() > 0) { 12805 boolean printed = false; 12806 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12807 final int NP = pmap.size(); 12808 for (int ip=0; ip<NP; ip++) { 12809 String pname = pmap.keyAt(ip); 12810 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12811 final int N = uids.size(); 12812 for (int i=0; i<N; i++) { 12813 int puid = uids.keyAt(i); 12814 ProcessRecord r = mProcessNames.get(pname, puid); 12815 if (dumpPackage != null && (r == null 12816 || !r.pkgList.containsKey(dumpPackage))) { 12817 continue; 12818 } 12819 if (!printed) { 12820 if (needSep) pw.println(); 12821 needSep = true; 12822 pw.println(" Bad processes:"); 12823 printedAnything = true; 12824 } 12825 BadProcessInfo info = uids.valueAt(i); 12826 pw.print(" Bad process "); pw.print(pname); 12827 pw.print(" uid "); pw.print(puid); 12828 pw.print(": crashed at time "); pw.println(info.time); 12829 if (info.shortMsg != null) { 12830 pw.print(" Short msg: "); pw.println(info.shortMsg); 12831 } 12832 if (info.longMsg != null) { 12833 pw.print(" Long msg: "); pw.println(info.longMsg); 12834 } 12835 if (info.stack != null) { 12836 pw.println(" Stack:"); 12837 int lastPos = 0; 12838 for (int pos=0; pos<info.stack.length(); pos++) { 12839 if (info.stack.charAt(pos) == '\n') { 12840 pw.print(" "); 12841 pw.write(info.stack, lastPos, pos-lastPos); 12842 pw.println(); 12843 lastPos = pos+1; 12844 } 12845 } 12846 if (lastPos < info.stack.length()) { 12847 pw.print(" "); 12848 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12849 pw.println(); 12850 } 12851 } 12852 } 12853 } 12854 } 12855 12856 if (dumpPackage == null) { 12857 pw.println(); 12858 needSep = false; 12859 pw.println(" mStartedUsers:"); 12860 for (int i=0; i<mStartedUsers.size(); i++) { 12861 UserStartedState uss = mStartedUsers.valueAt(i); 12862 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12863 pw.print(": "); uss.dump("", pw); 12864 } 12865 pw.print(" mStartedUserArray: ["); 12866 for (int i=0; i<mStartedUserArray.length; i++) { 12867 if (i > 0) pw.print(", "); 12868 pw.print(mStartedUserArray[i]); 12869 } 12870 pw.println("]"); 12871 pw.print(" mUserLru: ["); 12872 for (int i=0; i<mUserLru.size(); i++) { 12873 if (i > 0) pw.print(", "); 12874 pw.print(mUserLru.get(i)); 12875 } 12876 pw.println("]"); 12877 if (dumpAll) { 12878 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12879 } 12880 synchronized (mUserProfileGroupIdsSelfLocked) { 12881 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12882 pw.println(" mUserProfileGroupIds:"); 12883 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12884 pw.print(" User #"); 12885 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12886 pw.print(" -> profile #"); 12887 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12888 } 12889 } 12890 } 12891 } 12892 if (mHomeProcess != null && (dumpPackage == null 12893 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12894 if (needSep) { 12895 pw.println(); 12896 needSep = false; 12897 } 12898 pw.println(" mHomeProcess: " + mHomeProcess); 12899 } 12900 if (mPreviousProcess != null && (dumpPackage == null 12901 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12902 if (needSep) { 12903 pw.println(); 12904 needSep = false; 12905 } 12906 pw.println(" mPreviousProcess: " + mPreviousProcess); 12907 } 12908 if (dumpAll) { 12909 StringBuilder sb = new StringBuilder(128); 12910 sb.append(" mPreviousProcessVisibleTime: "); 12911 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12912 pw.println(sb); 12913 } 12914 if (mHeavyWeightProcess != null && (dumpPackage == null 12915 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12916 if (needSep) { 12917 pw.println(); 12918 needSep = false; 12919 } 12920 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12921 } 12922 if (dumpPackage == null) { 12923 pw.println(" mConfiguration: " + mConfiguration); 12924 } 12925 if (dumpAll) { 12926 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12927 if (mCompatModePackages.getPackages().size() > 0) { 12928 boolean printed = false; 12929 for (Map.Entry<String, Integer> entry 12930 : mCompatModePackages.getPackages().entrySet()) { 12931 String pkg = entry.getKey(); 12932 int mode = entry.getValue(); 12933 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12934 continue; 12935 } 12936 if (!printed) { 12937 pw.println(" mScreenCompatPackages:"); 12938 printed = true; 12939 } 12940 pw.print(" "); pw.print(pkg); pw.print(": "); 12941 pw.print(mode); pw.println(); 12942 } 12943 } 12944 } 12945 if (dumpPackage == null) { 12946 if (mSleeping || mWentToSleep || mLockScreenShown) { 12947 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12948 + " mLockScreenShown " + mLockScreenShown); 12949 } 12950 if (mShuttingDown || mRunningVoice) { 12951 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12952 } 12953 } 12954 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12955 || mOrigWaitForDebugger) { 12956 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12957 || dumpPackage.equals(mOrigDebugApp)) { 12958 if (needSep) { 12959 pw.println(); 12960 needSep = false; 12961 } 12962 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12963 + " mDebugTransient=" + mDebugTransient 12964 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12965 } 12966 } 12967 if (mOpenGlTraceApp != null) { 12968 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12969 if (needSep) { 12970 pw.println(); 12971 needSep = false; 12972 } 12973 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12974 } 12975 } 12976 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12977 || mProfileFd != null) { 12978 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12979 if (needSep) { 12980 pw.println(); 12981 needSep = false; 12982 } 12983 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12984 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12985 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12986 + mAutoStopProfiler); 12987 pw.println(" mProfileType=" + mProfileType); 12988 } 12989 } 12990 if (dumpPackage == null) { 12991 if (mAlwaysFinishActivities || mController != null) { 12992 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12993 + " mController=" + mController); 12994 } 12995 if (dumpAll) { 12996 pw.println(" Total persistent processes: " + numPers); 12997 pw.println(" mProcessesReady=" + mProcessesReady 12998 + " mSystemReady=" + mSystemReady 12999 + " mBooted=" + mBooted 13000 + " mFactoryTest=" + mFactoryTest); 13001 pw.println(" mBooting=" + mBooting 13002 + " mCallFinishBooting=" + mCallFinishBooting 13003 + " mBootAnimationComplete=" + mBootAnimationComplete); 13004 pw.print(" mLastPowerCheckRealtime="); 13005 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 13006 pw.println(""); 13007 pw.print(" mLastPowerCheckUptime="); 13008 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 13009 pw.println(""); 13010 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 13011 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 13012 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 13013 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 13014 + " (" + mLruProcesses.size() + " total)" 13015 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 13016 + " mNumServiceProcs=" + mNumServiceProcs 13017 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 13018 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 13019 + " mLastMemoryLevel" + mLastMemoryLevel 13020 + " mLastNumProcesses" + mLastNumProcesses); 13021 long now = SystemClock.uptimeMillis(); 13022 pw.print(" mLastIdleTime="); 13023 TimeUtils.formatDuration(now, mLastIdleTime, pw); 13024 pw.print(" mLowRamSinceLastIdle="); 13025 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 13026 pw.println(); 13027 } 13028 } 13029 13030 if (!printedAnything) { 13031 pw.println(" (nothing)"); 13032 } 13033 } 13034 13035 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 13036 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 13037 if (mProcessesToGc.size() > 0) { 13038 boolean printed = false; 13039 long now = SystemClock.uptimeMillis(); 13040 for (int i=0; i<mProcessesToGc.size(); i++) { 13041 ProcessRecord proc = mProcessesToGc.get(i); 13042 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 13043 continue; 13044 } 13045 if (!printed) { 13046 if (needSep) pw.println(); 13047 needSep = true; 13048 pw.println(" Processes that are waiting to GC:"); 13049 printed = true; 13050 } 13051 pw.print(" Process "); pw.println(proc); 13052 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 13053 pw.print(", last gced="); 13054 pw.print(now-proc.lastRequestedGc); 13055 pw.print(" ms ago, last lowMem="); 13056 pw.print(now-proc.lastLowMemory); 13057 pw.println(" ms ago"); 13058 13059 } 13060 } 13061 return needSep; 13062 } 13063 13064 void printOomLevel(PrintWriter pw, String name, int adj) { 13065 pw.print(" "); 13066 if (adj >= 0) { 13067 pw.print(' '); 13068 if (adj < 10) pw.print(' '); 13069 } else { 13070 if (adj > -10) pw.print(' '); 13071 } 13072 pw.print(adj); 13073 pw.print(": "); 13074 pw.print(name); 13075 pw.print(" ("); 13076 pw.print(mProcessList.getMemLevel(adj)/1024); 13077 pw.println(" kB)"); 13078 } 13079 13080 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13081 int opti, boolean dumpAll) { 13082 boolean needSep = false; 13083 13084 if (mLruProcesses.size() > 0) { 13085 if (needSep) pw.println(); 13086 needSep = true; 13087 pw.println(" OOM levels:"); 13088 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 13089 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 13090 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 13091 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 13092 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 13093 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 13094 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 13095 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 13096 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 13097 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 13098 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 13099 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 13100 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 13101 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 13102 13103 if (needSep) pw.println(); 13104 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 13105 pw.print(" total, non-act at "); 13106 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 13107 pw.print(", non-svc at "); 13108 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 13109 pw.println("):"); 13110 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 13111 needSep = true; 13112 } 13113 13114 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 13115 13116 pw.println(); 13117 pw.println(" mHomeProcess: " + mHomeProcess); 13118 pw.println(" mPreviousProcess: " + mPreviousProcess); 13119 if (mHeavyWeightProcess != null) { 13120 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 13121 } 13122 13123 return true; 13124 } 13125 13126 /** 13127 * There are three ways to call this: 13128 * - no provider specified: dump all the providers 13129 * - a flattened component name that matched an existing provider was specified as the 13130 * first arg: dump that one provider 13131 * - the first arg isn't the flattened component name of an existing provider: 13132 * dump all providers whose component contains the first arg as a substring 13133 */ 13134 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13135 int opti, boolean dumpAll) { 13136 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 13137 } 13138 13139 static class ItemMatcher { 13140 ArrayList<ComponentName> components; 13141 ArrayList<String> strings; 13142 ArrayList<Integer> objects; 13143 boolean all; 13144 13145 ItemMatcher() { 13146 all = true; 13147 } 13148 13149 void build(String name) { 13150 ComponentName componentName = ComponentName.unflattenFromString(name); 13151 if (componentName != null) { 13152 if (components == null) { 13153 components = new ArrayList<ComponentName>(); 13154 } 13155 components.add(componentName); 13156 all = false; 13157 } else { 13158 int objectId = 0; 13159 // Not a '/' separated full component name; maybe an object ID? 13160 try { 13161 objectId = Integer.parseInt(name, 16); 13162 if (objects == null) { 13163 objects = new ArrayList<Integer>(); 13164 } 13165 objects.add(objectId); 13166 all = false; 13167 } catch (RuntimeException e) { 13168 // Not an integer; just do string match. 13169 if (strings == null) { 13170 strings = new ArrayList<String>(); 13171 } 13172 strings.add(name); 13173 all = false; 13174 } 13175 } 13176 } 13177 13178 int build(String[] args, int opti) { 13179 for (; opti<args.length; opti++) { 13180 String name = args[opti]; 13181 if ("--".equals(name)) { 13182 return opti+1; 13183 } 13184 build(name); 13185 } 13186 return opti; 13187 } 13188 13189 boolean match(Object object, ComponentName comp) { 13190 if (all) { 13191 return true; 13192 } 13193 if (components != null) { 13194 for (int i=0; i<components.size(); i++) { 13195 if (components.get(i).equals(comp)) { 13196 return true; 13197 } 13198 } 13199 } 13200 if (objects != null) { 13201 for (int i=0; i<objects.size(); i++) { 13202 if (System.identityHashCode(object) == objects.get(i)) { 13203 return true; 13204 } 13205 } 13206 } 13207 if (strings != null) { 13208 String flat = comp.flattenToString(); 13209 for (int i=0; i<strings.size(); i++) { 13210 if (flat.contains(strings.get(i))) { 13211 return true; 13212 } 13213 } 13214 } 13215 return false; 13216 } 13217 } 13218 13219 /** 13220 * There are three things that cmd can be: 13221 * - a flattened component name that matches an existing activity 13222 * - the cmd arg isn't the flattened component name of an existing activity: 13223 * dump all activity whose component contains the cmd as a substring 13224 * - A hex number of the ActivityRecord object instance. 13225 */ 13226 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13227 int opti, boolean dumpAll) { 13228 ArrayList<ActivityRecord> activities; 13229 13230 synchronized (this) { 13231 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13232 } 13233 13234 if (activities.size() <= 0) { 13235 return false; 13236 } 13237 13238 String[] newArgs = new String[args.length - opti]; 13239 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13240 13241 TaskRecord lastTask = null; 13242 boolean needSep = false; 13243 for (int i=activities.size()-1; i>=0; i--) { 13244 ActivityRecord r = activities.get(i); 13245 if (needSep) { 13246 pw.println(); 13247 } 13248 needSep = true; 13249 synchronized (this) { 13250 if (lastTask != r.task) { 13251 lastTask = r.task; 13252 pw.print("TASK "); pw.print(lastTask.affinity); 13253 pw.print(" id="); pw.println(lastTask.taskId); 13254 if (dumpAll) { 13255 lastTask.dump(pw, " "); 13256 } 13257 } 13258 } 13259 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13260 } 13261 return true; 13262 } 13263 13264 /** 13265 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13266 * there is a thread associated with the activity. 13267 */ 13268 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13269 final ActivityRecord r, String[] args, boolean dumpAll) { 13270 String innerPrefix = prefix + " "; 13271 synchronized (this) { 13272 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13273 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13274 pw.print(" pid="); 13275 if (r.app != null) pw.println(r.app.pid); 13276 else pw.println("(not running)"); 13277 if (dumpAll) { 13278 r.dump(pw, innerPrefix); 13279 } 13280 } 13281 if (r.app != null && r.app.thread != null) { 13282 // flush anything that is already in the PrintWriter since the thread is going 13283 // to write to the file descriptor directly 13284 pw.flush(); 13285 try { 13286 TransferPipe tp = new TransferPipe(); 13287 try { 13288 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13289 r.appToken, innerPrefix, args); 13290 tp.go(fd); 13291 } finally { 13292 tp.kill(); 13293 } 13294 } catch (IOException e) { 13295 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13296 } catch (RemoteException e) { 13297 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13298 } 13299 } 13300 } 13301 13302 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13303 int opti, boolean dumpAll, String dumpPackage) { 13304 boolean needSep = false; 13305 boolean onlyHistory = false; 13306 boolean printedAnything = false; 13307 13308 if ("history".equals(dumpPackage)) { 13309 if (opti < args.length && "-s".equals(args[opti])) { 13310 dumpAll = false; 13311 } 13312 onlyHistory = true; 13313 dumpPackage = null; 13314 } 13315 13316 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13317 if (!onlyHistory && dumpAll) { 13318 if (mRegisteredReceivers.size() > 0) { 13319 boolean printed = false; 13320 Iterator it = mRegisteredReceivers.values().iterator(); 13321 while (it.hasNext()) { 13322 ReceiverList r = (ReceiverList)it.next(); 13323 if (dumpPackage != null && (r.app == null || 13324 !dumpPackage.equals(r.app.info.packageName))) { 13325 continue; 13326 } 13327 if (!printed) { 13328 pw.println(" Registered Receivers:"); 13329 needSep = true; 13330 printed = true; 13331 printedAnything = true; 13332 } 13333 pw.print(" * "); pw.println(r); 13334 r.dump(pw, " "); 13335 } 13336 } 13337 13338 if (mReceiverResolver.dump(pw, needSep ? 13339 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13340 " ", dumpPackage, false)) { 13341 needSep = true; 13342 printedAnything = true; 13343 } 13344 } 13345 13346 for (BroadcastQueue q : mBroadcastQueues) { 13347 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13348 printedAnything |= needSep; 13349 } 13350 13351 needSep = true; 13352 13353 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13354 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13355 if (needSep) { 13356 pw.println(); 13357 } 13358 needSep = true; 13359 printedAnything = true; 13360 pw.print(" Sticky broadcasts for user "); 13361 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13362 StringBuilder sb = new StringBuilder(128); 13363 for (Map.Entry<String, ArrayList<Intent>> ent 13364 : mStickyBroadcasts.valueAt(user).entrySet()) { 13365 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13366 if (dumpAll) { 13367 pw.println(":"); 13368 ArrayList<Intent> intents = ent.getValue(); 13369 final int N = intents.size(); 13370 for (int i=0; i<N; i++) { 13371 sb.setLength(0); 13372 sb.append(" Intent: "); 13373 intents.get(i).toShortString(sb, false, true, false, false); 13374 pw.println(sb.toString()); 13375 Bundle bundle = intents.get(i).getExtras(); 13376 if (bundle != null) { 13377 pw.print(" "); 13378 pw.println(bundle.toString()); 13379 } 13380 } 13381 } else { 13382 pw.println(""); 13383 } 13384 } 13385 } 13386 } 13387 13388 if (!onlyHistory && dumpAll) { 13389 pw.println(); 13390 for (BroadcastQueue queue : mBroadcastQueues) { 13391 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13392 + queue.mBroadcastsScheduled); 13393 } 13394 pw.println(" mHandler:"); 13395 mHandler.dump(new PrintWriterPrinter(pw), " "); 13396 needSep = true; 13397 printedAnything = true; 13398 } 13399 13400 if (!printedAnything) { 13401 pw.println(" (nothing)"); 13402 } 13403 } 13404 13405 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13406 int opti, boolean dumpAll, String dumpPackage) { 13407 boolean needSep; 13408 boolean printedAnything = false; 13409 13410 ItemMatcher matcher = new ItemMatcher(); 13411 matcher.build(args, opti); 13412 13413 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13414 13415 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13416 printedAnything |= needSep; 13417 13418 if (mLaunchingProviders.size() > 0) { 13419 boolean printed = false; 13420 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13421 ContentProviderRecord r = mLaunchingProviders.get(i); 13422 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13423 continue; 13424 } 13425 if (!printed) { 13426 if (needSep) pw.println(); 13427 needSep = true; 13428 pw.println(" Launching content providers:"); 13429 printed = true; 13430 printedAnything = true; 13431 } 13432 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13433 pw.println(r); 13434 } 13435 } 13436 13437 if (mGrantedUriPermissions.size() > 0) { 13438 boolean printed = false; 13439 int dumpUid = -2; 13440 if (dumpPackage != null) { 13441 try { 13442 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13443 } catch (NameNotFoundException e) { 13444 dumpUid = -1; 13445 } 13446 } 13447 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13448 int uid = mGrantedUriPermissions.keyAt(i); 13449 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13450 continue; 13451 } 13452 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13453 if (!printed) { 13454 if (needSep) pw.println(); 13455 needSep = true; 13456 pw.println(" Granted Uri Permissions:"); 13457 printed = true; 13458 printedAnything = true; 13459 } 13460 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13461 for (UriPermission perm : perms.values()) { 13462 pw.print(" "); pw.println(perm); 13463 if (dumpAll) { 13464 perm.dump(pw, " "); 13465 } 13466 } 13467 } 13468 } 13469 13470 if (!printedAnything) { 13471 pw.println(" (nothing)"); 13472 } 13473 } 13474 13475 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13476 int opti, boolean dumpAll, String dumpPackage) { 13477 boolean printed = false; 13478 13479 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13480 13481 if (mIntentSenderRecords.size() > 0) { 13482 Iterator<WeakReference<PendingIntentRecord>> it 13483 = mIntentSenderRecords.values().iterator(); 13484 while (it.hasNext()) { 13485 WeakReference<PendingIntentRecord> ref = it.next(); 13486 PendingIntentRecord rec = ref != null ? ref.get(): null; 13487 if (dumpPackage != null && (rec == null 13488 || !dumpPackage.equals(rec.key.packageName))) { 13489 continue; 13490 } 13491 printed = true; 13492 if (rec != null) { 13493 pw.print(" * "); pw.println(rec); 13494 if (dumpAll) { 13495 rec.dump(pw, " "); 13496 } 13497 } else { 13498 pw.print(" * "); pw.println(ref); 13499 } 13500 } 13501 } 13502 13503 if (!printed) { 13504 pw.println(" (nothing)"); 13505 } 13506 } 13507 13508 private static final int dumpProcessList(PrintWriter pw, 13509 ActivityManagerService service, List list, 13510 String prefix, String normalLabel, String persistentLabel, 13511 String dumpPackage) { 13512 int numPers = 0; 13513 final int N = list.size()-1; 13514 for (int i=N; i>=0; i--) { 13515 ProcessRecord r = (ProcessRecord)list.get(i); 13516 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13517 continue; 13518 } 13519 pw.println(String.format("%s%s #%2d: %s", 13520 prefix, (r.persistent ? persistentLabel : normalLabel), 13521 i, r.toString())); 13522 if (r.persistent) { 13523 numPers++; 13524 } 13525 } 13526 return numPers; 13527 } 13528 13529 private static final boolean dumpProcessOomList(PrintWriter pw, 13530 ActivityManagerService service, List<ProcessRecord> origList, 13531 String prefix, String normalLabel, String persistentLabel, 13532 boolean inclDetails, String dumpPackage) { 13533 13534 ArrayList<Pair<ProcessRecord, Integer>> list 13535 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13536 for (int i=0; i<origList.size(); i++) { 13537 ProcessRecord r = origList.get(i); 13538 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13539 continue; 13540 } 13541 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13542 } 13543 13544 if (list.size() <= 0) { 13545 return false; 13546 } 13547 13548 Comparator<Pair<ProcessRecord, Integer>> comparator 13549 = new Comparator<Pair<ProcessRecord, Integer>>() { 13550 @Override 13551 public int compare(Pair<ProcessRecord, Integer> object1, 13552 Pair<ProcessRecord, Integer> object2) { 13553 if (object1.first.setAdj != object2.first.setAdj) { 13554 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13555 } 13556 if (object1.second.intValue() != object2.second.intValue()) { 13557 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13558 } 13559 return 0; 13560 } 13561 }; 13562 13563 Collections.sort(list, comparator); 13564 13565 final long curRealtime = SystemClock.elapsedRealtime(); 13566 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13567 final long curUptime = SystemClock.uptimeMillis(); 13568 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13569 13570 for (int i=list.size()-1; i>=0; i--) { 13571 ProcessRecord r = list.get(i).first; 13572 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13573 char schedGroup; 13574 switch (r.setSchedGroup) { 13575 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13576 schedGroup = 'B'; 13577 break; 13578 case Process.THREAD_GROUP_DEFAULT: 13579 schedGroup = 'F'; 13580 break; 13581 default: 13582 schedGroup = '?'; 13583 break; 13584 } 13585 char foreground; 13586 if (r.foregroundActivities) { 13587 foreground = 'A'; 13588 } else if (r.foregroundServices) { 13589 foreground = 'S'; 13590 } else { 13591 foreground = ' '; 13592 } 13593 String procState = ProcessList.makeProcStateString(r.curProcState); 13594 pw.print(prefix); 13595 pw.print(r.persistent ? persistentLabel : normalLabel); 13596 pw.print(" #"); 13597 int num = (origList.size()-1)-list.get(i).second; 13598 if (num < 10) pw.print(' '); 13599 pw.print(num); 13600 pw.print(": "); 13601 pw.print(oomAdj); 13602 pw.print(' '); 13603 pw.print(schedGroup); 13604 pw.print('/'); 13605 pw.print(foreground); 13606 pw.print('/'); 13607 pw.print(procState); 13608 pw.print(" trm:"); 13609 if (r.trimMemoryLevel < 10) pw.print(' '); 13610 pw.print(r.trimMemoryLevel); 13611 pw.print(' '); 13612 pw.print(r.toShortString()); 13613 pw.print(" ("); 13614 pw.print(r.adjType); 13615 pw.println(')'); 13616 if (r.adjSource != null || r.adjTarget != null) { 13617 pw.print(prefix); 13618 pw.print(" "); 13619 if (r.adjTarget instanceof ComponentName) { 13620 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13621 } else if (r.adjTarget != null) { 13622 pw.print(r.adjTarget.toString()); 13623 } else { 13624 pw.print("{null}"); 13625 } 13626 pw.print("<="); 13627 if (r.adjSource instanceof ProcessRecord) { 13628 pw.print("Proc{"); 13629 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13630 pw.println("}"); 13631 } else if (r.adjSource != null) { 13632 pw.println(r.adjSource.toString()); 13633 } else { 13634 pw.println("{null}"); 13635 } 13636 } 13637 if (inclDetails) { 13638 pw.print(prefix); 13639 pw.print(" "); 13640 pw.print("oom: max="); pw.print(r.maxAdj); 13641 pw.print(" curRaw="); pw.print(r.curRawAdj); 13642 pw.print(" setRaw="); pw.print(r.setRawAdj); 13643 pw.print(" cur="); pw.print(r.curAdj); 13644 pw.print(" set="); pw.println(r.setAdj); 13645 pw.print(prefix); 13646 pw.print(" "); 13647 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13648 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13649 pw.print(" lastPss="); pw.print(r.lastPss); 13650 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13651 pw.print(prefix); 13652 pw.print(" "); 13653 pw.print("cached="); pw.print(r.cached); 13654 pw.print(" empty="); pw.print(r.empty); 13655 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13656 13657 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13658 if (r.lastWakeTime != 0) { 13659 long wtime; 13660 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13661 synchronized (stats) { 13662 wtime = stats.getProcessWakeTime(r.info.uid, 13663 r.pid, curRealtime); 13664 } 13665 long timeUsed = wtime - r.lastWakeTime; 13666 pw.print(prefix); 13667 pw.print(" "); 13668 pw.print("keep awake over "); 13669 TimeUtils.formatDuration(realtimeSince, pw); 13670 pw.print(" used "); 13671 TimeUtils.formatDuration(timeUsed, pw); 13672 pw.print(" ("); 13673 pw.print((timeUsed*100)/realtimeSince); 13674 pw.println("%)"); 13675 } 13676 if (r.lastCpuTime != 0) { 13677 long timeUsed = r.curCpuTime - r.lastCpuTime; 13678 pw.print(prefix); 13679 pw.print(" "); 13680 pw.print("run cpu over "); 13681 TimeUtils.formatDuration(uptimeSince, pw); 13682 pw.print(" used "); 13683 TimeUtils.formatDuration(timeUsed, pw); 13684 pw.print(" ("); 13685 pw.print((timeUsed*100)/uptimeSince); 13686 pw.println("%)"); 13687 } 13688 } 13689 } 13690 } 13691 return true; 13692 } 13693 13694 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 13695 String[] args) { 13696 ArrayList<ProcessRecord> procs; 13697 synchronized (this) { 13698 if (args != null && args.length > start 13699 && args[start].charAt(0) != '-') { 13700 procs = new ArrayList<ProcessRecord>(); 13701 int pid = -1; 13702 try { 13703 pid = Integer.parseInt(args[start]); 13704 } catch (NumberFormatException e) { 13705 } 13706 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13707 ProcessRecord proc = mLruProcesses.get(i); 13708 if (proc.pid == pid) { 13709 procs.add(proc); 13710 } else if (allPkgs && proc.pkgList != null 13711 && proc.pkgList.containsKey(args[start])) { 13712 procs.add(proc); 13713 } else if (proc.processName.equals(args[start])) { 13714 procs.add(proc); 13715 } 13716 } 13717 if (procs.size() <= 0) { 13718 return null; 13719 } 13720 } else { 13721 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13722 } 13723 } 13724 return procs; 13725 } 13726 13727 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13728 PrintWriter pw, String[] args) { 13729 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13730 if (procs == null) { 13731 pw.println("No process found for: " + args[0]); 13732 return; 13733 } 13734 13735 long uptime = SystemClock.uptimeMillis(); 13736 long realtime = SystemClock.elapsedRealtime(); 13737 pw.println("Applications Graphics Acceleration Info:"); 13738 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13739 13740 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13741 ProcessRecord r = procs.get(i); 13742 if (r.thread != null) { 13743 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13744 pw.flush(); 13745 try { 13746 TransferPipe tp = new TransferPipe(); 13747 try { 13748 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13749 tp.go(fd); 13750 } finally { 13751 tp.kill(); 13752 } 13753 } catch (IOException e) { 13754 pw.println("Failure while dumping the app: " + r); 13755 pw.flush(); 13756 } catch (RemoteException e) { 13757 pw.println("Got a RemoteException while dumping the app " + r); 13758 pw.flush(); 13759 } 13760 } 13761 } 13762 } 13763 13764 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13765 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 13766 if (procs == null) { 13767 pw.println("No process found for: " + args[0]); 13768 return; 13769 } 13770 13771 pw.println("Applications Database Info:"); 13772 13773 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13774 ProcessRecord r = procs.get(i); 13775 if (r.thread != null) { 13776 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13777 pw.flush(); 13778 try { 13779 TransferPipe tp = new TransferPipe(); 13780 try { 13781 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13782 tp.go(fd); 13783 } finally { 13784 tp.kill(); 13785 } 13786 } catch (IOException e) { 13787 pw.println("Failure while dumping the app: " + r); 13788 pw.flush(); 13789 } catch (RemoteException e) { 13790 pw.println("Got a RemoteException while dumping the app " + r); 13791 pw.flush(); 13792 } 13793 } 13794 } 13795 } 13796 13797 final static class MemItem { 13798 final boolean isProc; 13799 final String label; 13800 final String shortLabel; 13801 final long pss; 13802 final int id; 13803 final boolean hasActivities; 13804 ArrayList<MemItem> subitems; 13805 13806 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13807 boolean _hasActivities) { 13808 isProc = true; 13809 label = _label; 13810 shortLabel = _shortLabel; 13811 pss = _pss; 13812 id = _id; 13813 hasActivities = _hasActivities; 13814 } 13815 13816 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13817 isProc = false; 13818 label = _label; 13819 shortLabel = _shortLabel; 13820 pss = _pss; 13821 id = _id; 13822 hasActivities = false; 13823 } 13824 } 13825 13826 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13827 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13828 if (sort && !isCompact) { 13829 Collections.sort(items, new Comparator<MemItem>() { 13830 @Override 13831 public int compare(MemItem lhs, MemItem rhs) { 13832 if (lhs.pss < rhs.pss) { 13833 return 1; 13834 } else if (lhs.pss > rhs.pss) { 13835 return -1; 13836 } 13837 return 0; 13838 } 13839 }); 13840 } 13841 13842 for (int i=0; i<items.size(); i++) { 13843 MemItem mi = items.get(i); 13844 if (!isCompact) { 13845 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13846 } else if (mi.isProc) { 13847 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13848 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13849 pw.println(mi.hasActivities ? ",a" : ",e"); 13850 } else { 13851 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13852 pw.println(mi.pss); 13853 } 13854 if (mi.subitems != null) { 13855 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13856 true, isCompact); 13857 } 13858 } 13859 } 13860 13861 // These are in KB. 13862 static final long[] DUMP_MEM_BUCKETS = new long[] { 13863 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13864 120*1024, 160*1024, 200*1024, 13865 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13866 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13867 }; 13868 13869 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13870 boolean stackLike) { 13871 int start = label.lastIndexOf('.'); 13872 if (start >= 0) start++; 13873 else start = 0; 13874 int end = label.length(); 13875 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13876 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13877 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13878 out.append(bucket); 13879 out.append(stackLike ? "MB." : "MB "); 13880 out.append(label, start, end); 13881 return; 13882 } 13883 } 13884 out.append(memKB/1024); 13885 out.append(stackLike ? "MB." : "MB "); 13886 out.append(label, start, end); 13887 } 13888 13889 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13890 ProcessList.NATIVE_ADJ, 13891 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 13892 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13893 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13894 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13895 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13896 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13897 }; 13898 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13899 "Native", 13900 "System", "Persistent", "Persistent Service", "Foreground", 13901 "Visible", "Perceptible", 13902 "Heavy Weight", "Backup", 13903 "A Services", "Home", 13904 "Previous", "B Services", "Cached" 13905 }; 13906 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13907 "native", 13908 "sys", "pers", "persvc", "fore", 13909 "vis", "percept", 13910 "heavy", "backup", 13911 "servicea", "home", 13912 "prev", "serviceb", "cached" 13913 }; 13914 13915 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13916 long realtime, boolean isCheckinRequest, boolean isCompact) { 13917 if (isCheckinRequest || isCompact) { 13918 // short checkin version 13919 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13920 } else { 13921 pw.println("Applications Memory Usage (kB):"); 13922 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13923 } 13924 } 13925 13926 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13927 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13928 boolean dumpDetails = false; 13929 boolean dumpFullDetails = false; 13930 boolean dumpDalvik = false; 13931 boolean oomOnly = false; 13932 boolean isCompact = false; 13933 boolean localOnly = false; 13934 boolean packages = false; 13935 13936 int opti = 0; 13937 while (opti < args.length) { 13938 String opt = args[opti]; 13939 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13940 break; 13941 } 13942 opti++; 13943 if ("-a".equals(opt)) { 13944 dumpDetails = true; 13945 dumpFullDetails = true; 13946 dumpDalvik = true; 13947 } else if ("-d".equals(opt)) { 13948 dumpDalvik = true; 13949 } else if ("-c".equals(opt)) { 13950 isCompact = true; 13951 } else if ("--oom".equals(opt)) { 13952 oomOnly = true; 13953 } else if ("--local".equals(opt)) { 13954 localOnly = true; 13955 } else if ("--package".equals(opt)) { 13956 packages = true; 13957 } else if ("-h".equals(opt)) { 13958 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13959 pw.println(" -a: include all available information for each process."); 13960 pw.println(" -d: include dalvik details when dumping process details."); 13961 pw.println(" -c: dump in a compact machine-parseable representation."); 13962 pw.println(" --oom: only show processes organized by oom adj."); 13963 pw.println(" --local: only collect details locally, don't call process."); 13964 pw.println(" --package: interpret process arg as package, dumping all"); 13965 pw.println(" processes that have loaded that package."); 13966 pw.println("If [process] is specified it can be the name or "); 13967 pw.println("pid of a specific process to dump."); 13968 return; 13969 } else { 13970 pw.println("Unknown argument: " + opt + "; use -h for help"); 13971 } 13972 } 13973 13974 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13975 long uptime = SystemClock.uptimeMillis(); 13976 long realtime = SystemClock.elapsedRealtime(); 13977 final long[] tmpLong = new long[1]; 13978 13979 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 13980 if (procs == null) { 13981 // No Java processes. Maybe they want to print a native process. 13982 if (args != null && args.length > opti 13983 && args[opti].charAt(0) != '-') { 13984 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13985 = new ArrayList<ProcessCpuTracker.Stats>(); 13986 updateCpuStatsNow(); 13987 int findPid = -1; 13988 try { 13989 findPid = Integer.parseInt(args[opti]); 13990 } catch (NumberFormatException e) { 13991 } 13992 synchronized (mProcessCpuTracker) { 13993 final int N = mProcessCpuTracker.countStats(); 13994 for (int i=0; i<N; i++) { 13995 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13996 if (st.pid == findPid || (st.baseName != null 13997 && st.baseName.equals(args[opti]))) { 13998 nativeProcs.add(st); 13999 } 14000 } 14001 } 14002 if (nativeProcs.size() > 0) { 14003 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 14004 isCompact); 14005 Debug.MemoryInfo mi = null; 14006 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 14007 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 14008 final int pid = r.pid; 14009 if (!isCheckinRequest && dumpDetails) { 14010 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 14011 } 14012 if (mi == null) { 14013 mi = new Debug.MemoryInfo(); 14014 } 14015 if (dumpDetails || (!brief && !oomOnly)) { 14016 Debug.getMemoryInfo(pid, mi); 14017 } else { 14018 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14019 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14020 } 14021 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14022 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 14023 if (isCheckinRequest) { 14024 pw.println(); 14025 } 14026 } 14027 return; 14028 } 14029 } 14030 pw.println("No process found for: " + args[opti]); 14031 return; 14032 } 14033 14034 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 14035 dumpDetails = true; 14036 } 14037 14038 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 14039 14040 String[] innerArgs = new String[args.length-opti]; 14041 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 14042 14043 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 14044 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 14045 long nativePss=0, dalvikPss=0, otherPss=0; 14046 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 14047 14048 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 14049 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 14050 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 14051 14052 long totalPss = 0; 14053 long cachedPss = 0; 14054 14055 Debug.MemoryInfo mi = null; 14056 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 14057 final ProcessRecord r = procs.get(i); 14058 final IApplicationThread thread; 14059 final int pid; 14060 final int oomAdj; 14061 final boolean hasActivities; 14062 synchronized (this) { 14063 thread = r.thread; 14064 pid = r.pid; 14065 oomAdj = r.getSetAdjWithServices(); 14066 hasActivities = r.activities.size() > 0; 14067 } 14068 if (thread != null) { 14069 if (!isCheckinRequest && dumpDetails) { 14070 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 14071 } 14072 if (mi == null) { 14073 mi = new Debug.MemoryInfo(); 14074 } 14075 if (dumpDetails || (!brief && !oomOnly)) { 14076 Debug.getMemoryInfo(pid, mi); 14077 } else { 14078 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 14079 mi.dalvikPrivateDirty = (int)tmpLong[0]; 14080 } 14081 if (dumpDetails) { 14082 if (localOnly) { 14083 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 14084 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 14085 if (isCheckinRequest) { 14086 pw.println(); 14087 } 14088 } else { 14089 try { 14090 pw.flush(); 14091 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 14092 dumpDalvik, innerArgs); 14093 } catch (RemoteException e) { 14094 if (!isCheckinRequest) { 14095 pw.println("Got RemoteException!"); 14096 pw.flush(); 14097 } 14098 } 14099 } 14100 } 14101 14102 final long myTotalPss = mi.getTotalPss(); 14103 final long myTotalUss = mi.getTotalUss(); 14104 14105 synchronized (this) { 14106 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 14107 // Record this for posterity if the process has been stable. 14108 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 14109 } 14110 } 14111 14112 if (!isCheckinRequest && mi != null) { 14113 totalPss += myTotalPss; 14114 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 14115 (hasActivities ? " / activities)" : ")"), 14116 r.processName, myTotalPss, pid, hasActivities); 14117 procMems.add(pssItem); 14118 procMemsMap.put(pid, pssItem); 14119 14120 nativePss += mi.nativePss; 14121 dalvikPss += mi.dalvikPss; 14122 otherPss += mi.otherPss; 14123 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14124 long mem = mi.getOtherPss(j); 14125 miscPss[j] += mem; 14126 otherPss -= mem; 14127 } 14128 14129 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 14130 cachedPss += myTotalPss; 14131 } 14132 14133 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 14134 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 14135 || oomIndex == (oomPss.length-1)) { 14136 oomPss[oomIndex] += myTotalPss; 14137 if (oomProcs[oomIndex] == null) { 14138 oomProcs[oomIndex] = new ArrayList<MemItem>(); 14139 } 14140 oomProcs[oomIndex].add(pssItem); 14141 break; 14142 } 14143 } 14144 } 14145 } 14146 } 14147 14148 long nativeProcTotalPss = 0; 14149 14150 if (!isCheckinRequest && procs.size() > 1 && !packages) { 14151 // If we are showing aggregations, also look for native processes to 14152 // include so that our aggregations are more accurate. 14153 updateCpuStatsNow(); 14154 synchronized (mProcessCpuTracker) { 14155 final int N = mProcessCpuTracker.countStats(); 14156 for (int i=0; i<N; i++) { 14157 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14158 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14159 if (mi == null) { 14160 mi = new Debug.MemoryInfo(); 14161 } 14162 if (!brief && !oomOnly) { 14163 Debug.getMemoryInfo(st.pid, mi); 14164 } else { 14165 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14166 mi.nativePrivateDirty = (int)tmpLong[0]; 14167 } 14168 14169 final long myTotalPss = mi.getTotalPss(); 14170 totalPss += myTotalPss; 14171 nativeProcTotalPss += myTotalPss; 14172 14173 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14174 st.name, myTotalPss, st.pid, false); 14175 procMems.add(pssItem); 14176 14177 nativePss += mi.nativePss; 14178 dalvikPss += mi.dalvikPss; 14179 otherPss += mi.otherPss; 14180 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14181 long mem = mi.getOtherPss(j); 14182 miscPss[j] += mem; 14183 otherPss -= mem; 14184 } 14185 oomPss[0] += myTotalPss; 14186 if (oomProcs[0] == null) { 14187 oomProcs[0] = new ArrayList<MemItem>(); 14188 } 14189 oomProcs[0].add(pssItem); 14190 } 14191 } 14192 } 14193 14194 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14195 14196 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14197 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14198 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14199 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14200 String label = Debug.MemoryInfo.getOtherLabel(j); 14201 catMems.add(new MemItem(label, label, miscPss[j], j)); 14202 } 14203 14204 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14205 for (int j=0; j<oomPss.length; j++) { 14206 if (oomPss[j] != 0) { 14207 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14208 : DUMP_MEM_OOM_LABEL[j]; 14209 MemItem item = new MemItem(label, label, oomPss[j], 14210 DUMP_MEM_OOM_ADJ[j]); 14211 item.subitems = oomProcs[j]; 14212 oomMems.add(item); 14213 } 14214 } 14215 14216 if (!brief && !oomOnly && !isCompact) { 14217 pw.println(); 14218 pw.println("Total PSS by process:"); 14219 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14220 pw.println(); 14221 } 14222 if (!isCompact) { 14223 pw.println("Total PSS by OOM adjustment:"); 14224 } 14225 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14226 if (!brief && !oomOnly) { 14227 PrintWriter out = categoryPw != null ? categoryPw : pw; 14228 if (!isCompact) { 14229 out.println(); 14230 out.println("Total PSS by category:"); 14231 } 14232 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14233 } 14234 if (!isCompact) { 14235 pw.println(); 14236 } 14237 MemInfoReader memInfo = new MemInfoReader(); 14238 memInfo.readMemInfo(); 14239 if (nativeProcTotalPss > 0) { 14240 synchronized (this) { 14241 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14242 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14243 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14244 nativeProcTotalPss); 14245 } 14246 } 14247 if (!brief) { 14248 if (!isCompact) { 14249 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14250 pw.print(" kB (status "); 14251 switch (mLastMemoryLevel) { 14252 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14253 pw.println("normal)"); 14254 break; 14255 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14256 pw.println("moderate)"); 14257 break; 14258 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14259 pw.println("low)"); 14260 break; 14261 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14262 pw.println("critical)"); 14263 break; 14264 default: 14265 pw.print(mLastMemoryLevel); 14266 pw.println(")"); 14267 break; 14268 } 14269 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14270 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14271 pw.print(cachedPss); pw.print(" cached pss + "); 14272 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14273 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14274 } else { 14275 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14276 pw.print(cachedPss + memInfo.getCachedSizeKb() 14277 + memInfo.getFreeSizeKb()); pw.print(","); 14278 pw.println(totalPss - cachedPss); 14279 } 14280 } 14281 if (!isCompact) { 14282 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14283 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14284 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14285 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14286 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14287 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14288 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14289 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14290 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14291 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14292 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14293 } 14294 if (!brief) { 14295 if (memInfo.getZramTotalSizeKb() != 0) { 14296 if (!isCompact) { 14297 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14298 pw.print(" kB physical used for "); 14299 pw.print(memInfo.getSwapTotalSizeKb() 14300 - memInfo.getSwapFreeSizeKb()); 14301 pw.print(" kB in swap ("); 14302 pw.print(memInfo.getSwapTotalSizeKb()); 14303 pw.println(" kB total swap)"); 14304 } else { 14305 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14306 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14307 pw.println(memInfo.getSwapFreeSizeKb()); 14308 } 14309 } 14310 final int[] SINGLE_LONG_FORMAT = new int[] { 14311 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14312 }; 14313 long[] longOut = new long[1]; 14314 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14315 SINGLE_LONG_FORMAT, null, longOut, null); 14316 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14317 longOut[0] = 0; 14318 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14319 SINGLE_LONG_FORMAT, null, longOut, null); 14320 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14321 longOut[0] = 0; 14322 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14323 SINGLE_LONG_FORMAT, null, longOut, null); 14324 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14325 longOut[0] = 0; 14326 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14327 SINGLE_LONG_FORMAT, null, longOut, null); 14328 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14329 if (!isCompact) { 14330 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14331 pw.print(" KSM: "); pw.print(sharing); 14332 pw.print(" kB saved from shared "); 14333 pw.print(shared); pw.println(" kB"); 14334 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14335 pw.print(voltile); pw.println(" kB volatile"); 14336 } 14337 pw.print(" Tuning: "); 14338 pw.print(ActivityManager.staticGetMemoryClass()); 14339 pw.print(" (large "); 14340 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14341 pw.print("), oom "); 14342 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14343 pw.print(" kB"); 14344 pw.print(", restore limit "); 14345 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14346 pw.print(" kB"); 14347 if (ActivityManager.isLowRamDeviceStatic()) { 14348 pw.print(" (low-ram)"); 14349 } 14350 if (ActivityManager.isHighEndGfx()) { 14351 pw.print(" (high-end-gfx)"); 14352 } 14353 pw.println(); 14354 } else { 14355 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14356 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14357 pw.println(voltile); 14358 pw.print("tuning,"); 14359 pw.print(ActivityManager.staticGetMemoryClass()); 14360 pw.print(','); 14361 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14362 pw.print(','); 14363 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14364 if (ActivityManager.isLowRamDeviceStatic()) { 14365 pw.print(",low-ram"); 14366 } 14367 if (ActivityManager.isHighEndGfx()) { 14368 pw.print(",high-end-gfx"); 14369 } 14370 pw.println(); 14371 } 14372 } 14373 } 14374 } 14375 14376 /** 14377 * Searches array of arguments for the specified string 14378 * @param args array of argument strings 14379 * @param value value to search for 14380 * @return true if the value is contained in the array 14381 */ 14382 private static boolean scanArgs(String[] args, String value) { 14383 if (args != null) { 14384 for (String arg : args) { 14385 if (value.equals(arg)) { 14386 return true; 14387 } 14388 } 14389 } 14390 return false; 14391 } 14392 14393 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14394 ContentProviderRecord cpr, boolean always) { 14395 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14396 14397 if (!inLaunching || always) { 14398 synchronized (cpr) { 14399 cpr.launchingApp = null; 14400 cpr.notifyAll(); 14401 } 14402 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14403 String names[] = cpr.info.authority.split(";"); 14404 for (int j = 0; j < names.length; j++) { 14405 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14406 } 14407 } 14408 14409 for (int i=0; i<cpr.connections.size(); i++) { 14410 ContentProviderConnection conn = cpr.connections.get(i); 14411 if (conn.waiting) { 14412 // If this connection is waiting for the provider, then we don't 14413 // need to mess with its process unless we are always removing 14414 // or for some reason the provider is not currently launching. 14415 if (inLaunching && !always) { 14416 continue; 14417 } 14418 } 14419 ProcessRecord capp = conn.client; 14420 conn.dead = true; 14421 if (conn.stableCount > 0) { 14422 if (!capp.persistent && capp.thread != null 14423 && capp.pid != 0 14424 && capp.pid != MY_PID) { 14425 capp.kill("depends on provider " 14426 + cpr.name.flattenToShortString() 14427 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14428 } 14429 } else if (capp.thread != null && conn.provider.provider != null) { 14430 try { 14431 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14432 } catch (RemoteException e) { 14433 } 14434 // In the protocol here, we don't expect the client to correctly 14435 // clean up this connection, we'll just remove it. 14436 cpr.connections.remove(i); 14437 conn.client.conProviders.remove(conn); 14438 } 14439 } 14440 14441 if (inLaunching && always) { 14442 mLaunchingProviders.remove(cpr); 14443 } 14444 return inLaunching; 14445 } 14446 14447 /** 14448 * Main code for cleaning up a process when it has gone away. This is 14449 * called both as a result of the process dying, or directly when stopping 14450 * a process when running in single process mode. 14451 * 14452 * @return Returns true if the given process has been restarted, so the 14453 * app that was passed in must remain on the process lists. 14454 */ 14455 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 14456 boolean restarting, boolean allowRestart, int index) { 14457 if (index >= 0) { 14458 removeLruProcessLocked(app); 14459 ProcessList.remove(app.pid); 14460 } 14461 14462 mProcessesToGc.remove(app); 14463 mPendingPssProcesses.remove(app); 14464 14465 // Dismiss any open dialogs. 14466 if (app.crashDialog != null && !app.forceCrashReport) { 14467 app.crashDialog.dismiss(); 14468 app.crashDialog = null; 14469 } 14470 if (app.anrDialog != null) { 14471 app.anrDialog.dismiss(); 14472 app.anrDialog = null; 14473 } 14474 if (app.waitDialog != null) { 14475 app.waitDialog.dismiss(); 14476 app.waitDialog = null; 14477 } 14478 14479 app.crashing = false; 14480 app.notResponding = false; 14481 14482 app.resetPackageList(mProcessStats); 14483 app.unlinkDeathRecipient(); 14484 app.makeInactive(mProcessStats); 14485 app.waitingToKill = null; 14486 app.forcingToForeground = null; 14487 updateProcessForegroundLocked(app, false, false); 14488 app.foregroundActivities = false; 14489 app.hasShownUi = false; 14490 app.treatLikeActivity = false; 14491 app.hasAboveClient = false; 14492 app.hasClientActivities = false; 14493 14494 mServices.killServicesLocked(app, allowRestart); 14495 14496 boolean restart = false; 14497 14498 // Remove published content providers. 14499 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14500 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14501 final boolean always = app.bad || !allowRestart; 14502 if (removeDyingProviderLocked(app, cpr, always) || always) { 14503 // We left the provider in the launching list, need to 14504 // restart it. 14505 restart = true; 14506 } 14507 14508 cpr.provider = null; 14509 cpr.proc = null; 14510 } 14511 app.pubProviders.clear(); 14512 14513 // Take care of any launching providers waiting for this process. 14514 if (checkAppInLaunchingProvidersLocked(app, false)) { 14515 restart = true; 14516 } 14517 14518 // Unregister from connected content providers. 14519 if (!app.conProviders.isEmpty()) { 14520 for (int i=0; i<app.conProviders.size(); i++) { 14521 ContentProviderConnection conn = app.conProviders.get(i); 14522 conn.provider.connections.remove(conn); 14523 } 14524 app.conProviders.clear(); 14525 } 14526 14527 // At this point there may be remaining entries in mLaunchingProviders 14528 // where we were the only one waiting, so they are no longer of use. 14529 // Look for these and clean up if found. 14530 // XXX Commented out for now. Trying to figure out a way to reproduce 14531 // the actual situation to identify what is actually going on. 14532 if (false) { 14533 for (int i=0; i<mLaunchingProviders.size(); i++) { 14534 ContentProviderRecord cpr = (ContentProviderRecord) 14535 mLaunchingProviders.get(i); 14536 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14537 synchronized (cpr) { 14538 cpr.launchingApp = null; 14539 cpr.notifyAll(); 14540 } 14541 } 14542 } 14543 } 14544 14545 skipCurrentReceiverLocked(app); 14546 14547 // Unregister any receivers. 14548 for (int i=app.receivers.size()-1; i>=0; i--) { 14549 removeReceiverLocked(app.receivers.valueAt(i)); 14550 } 14551 app.receivers.clear(); 14552 14553 // If the app is undergoing backup, tell the backup manager about it 14554 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14555 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14556 + mBackupTarget.appInfo + " died during backup"); 14557 try { 14558 IBackupManager bm = IBackupManager.Stub.asInterface( 14559 ServiceManager.getService(Context.BACKUP_SERVICE)); 14560 bm.agentDisconnected(app.info.packageName); 14561 } catch (RemoteException e) { 14562 // can't happen; backup manager is local 14563 } 14564 } 14565 14566 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14567 ProcessChangeItem item = mPendingProcessChanges.get(i); 14568 if (item.pid == app.pid) { 14569 mPendingProcessChanges.remove(i); 14570 mAvailProcessChanges.add(item); 14571 } 14572 } 14573 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14574 14575 // If the caller is restarting this app, then leave it in its 14576 // current lists and let the caller take care of it. 14577 if (restarting) { 14578 return false; 14579 } 14580 14581 if (!app.persistent || app.isolated) { 14582 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14583 "Removing non-persistent process during cleanup: " + app); 14584 mProcessNames.remove(app.processName, app.uid); 14585 mIsolatedProcesses.remove(app.uid); 14586 if (mHeavyWeightProcess == app) { 14587 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14588 mHeavyWeightProcess.userId, 0)); 14589 mHeavyWeightProcess = null; 14590 } 14591 } else if (!app.removed) { 14592 // This app is persistent, so we need to keep its record around. 14593 // If it is not already on the pending app list, add it there 14594 // and start a new process for it. 14595 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14596 mPersistentStartingProcesses.add(app); 14597 restart = true; 14598 } 14599 } 14600 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14601 "Clean-up removing on hold: " + app); 14602 mProcessesOnHold.remove(app); 14603 14604 if (app == mHomeProcess) { 14605 mHomeProcess = null; 14606 } 14607 if (app == mPreviousProcess) { 14608 mPreviousProcess = null; 14609 } 14610 14611 if (restart && !app.isolated) { 14612 // We have components that still need to be running in the 14613 // process, so re-launch it. 14614 if (index < 0) { 14615 ProcessList.remove(app.pid); 14616 } 14617 mProcessNames.put(app.processName, app.uid, app); 14618 startProcessLocked(app, "restart", app.processName); 14619 return true; 14620 } else if (app.pid > 0 && app.pid != MY_PID) { 14621 // Goodbye! 14622 boolean removed; 14623 synchronized (mPidsSelfLocked) { 14624 mPidsSelfLocked.remove(app.pid); 14625 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14626 } 14627 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14628 if (app.isolated) { 14629 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14630 } 14631 app.setPid(0); 14632 } 14633 return false; 14634 } 14635 14636 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14637 // Look through the content providers we are waiting to have launched, 14638 // and if any run in this process then either schedule a restart of 14639 // the process or kill the client waiting for it if this process has 14640 // gone bad. 14641 int NL = mLaunchingProviders.size(); 14642 boolean restart = false; 14643 for (int i=0; i<NL; i++) { 14644 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14645 if (cpr.launchingApp == app) { 14646 if (!alwaysBad && !app.bad) { 14647 restart = true; 14648 } else { 14649 removeDyingProviderLocked(app, cpr, true); 14650 // cpr should have been removed from mLaunchingProviders 14651 NL = mLaunchingProviders.size(); 14652 i--; 14653 } 14654 } 14655 } 14656 return restart; 14657 } 14658 14659 // ========================================================= 14660 // SERVICES 14661 // ========================================================= 14662 14663 @Override 14664 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14665 int flags) { 14666 enforceNotIsolatedCaller("getServices"); 14667 synchronized (this) { 14668 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14669 } 14670 } 14671 14672 @Override 14673 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14674 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14675 synchronized (this) { 14676 return mServices.getRunningServiceControlPanelLocked(name); 14677 } 14678 } 14679 14680 @Override 14681 public ComponentName startService(IApplicationThread caller, Intent service, 14682 String resolvedType, int userId) { 14683 enforceNotIsolatedCaller("startService"); 14684 // Refuse possible leaked file descriptors 14685 if (service != null && service.hasFileDescriptors() == true) { 14686 throw new IllegalArgumentException("File descriptors passed in Intent"); 14687 } 14688 14689 if (DEBUG_SERVICE) 14690 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14691 synchronized(this) { 14692 final int callingPid = Binder.getCallingPid(); 14693 final int callingUid = Binder.getCallingUid(); 14694 final long origId = Binder.clearCallingIdentity(); 14695 ComponentName res = mServices.startServiceLocked(caller, service, 14696 resolvedType, callingPid, callingUid, userId); 14697 Binder.restoreCallingIdentity(origId); 14698 return res; 14699 } 14700 } 14701 14702 ComponentName startServiceInPackage(int uid, 14703 Intent service, String resolvedType, int userId) { 14704 synchronized(this) { 14705 if (DEBUG_SERVICE) 14706 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14707 final long origId = Binder.clearCallingIdentity(); 14708 ComponentName res = mServices.startServiceLocked(null, service, 14709 resolvedType, -1, uid, userId); 14710 Binder.restoreCallingIdentity(origId); 14711 return res; 14712 } 14713 } 14714 14715 @Override 14716 public int stopService(IApplicationThread caller, Intent service, 14717 String resolvedType, int userId) { 14718 enforceNotIsolatedCaller("stopService"); 14719 // Refuse possible leaked file descriptors 14720 if (service != null && service.hasFileDescriptors() == true) { 14721 throw new IllegalArgumentException("File descriptors passed in Intent"); 14722 } 14723 14724 synchronized(this) { 14725 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14726 } 14727 } 14728 14729 @Override 14730 public IBinder peekService(Intent service, String resolvedType) { 14731 enforceNotIsolatedCaller("peekService"); 14732 // Refuse possible leaked file descriptors 14733 if (service != null && service.hasFileDescriptors() == true) { 14734 throw new IllegalArgumentException("File descriptors passed in Intent"); 14735 } 14736 synchronized(this) { 14737 return mServices.peekServiceLocked(service, resolvedType); 14738 } 14739 } 14740 14741 @Override 14742 public boolean stopServiceToken(ComponentName className, IBinder token, 14743 int startId) { 14744 synchronized(this) { 14745 return mServices.stopServiceTokenLocked(className, token, startId); 14746 } 14747 } 14748 14749 @Override 14750 public void setServiceForeground(ComponentName className, IBinder token, 14751 int id, Notification notification, boolean removeNotification) { 14752 synchronized(this) { 14753 mServices.setServiceForegroundLocked(className, token, id, notification, 14754 removeNotification); 14755 } 14756 } 14757 14758 @Override 14759 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14760 boolean requireFull, String name, String callerPackage) { 14761 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14762 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14763 } 14764 14765 int unsafeConvertIncomingUser(int userId) { 14766 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14767 ? mCurrentUserId : userId; 14768 } 14769 14770 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14771 int allowMode, String name, String callerPackage) { 14772 final int callingUserId = UserHandle.getUserId(callingUid); 14773 if (callingUserId == userId) { 14774 return userId; 14775 } 14776 14777 // Note that we may be accessing mCurrentUserId outside of a lock... 14778 // shouldn't be a big deal, if this is being called outside 14779 // of a locked context there is intrinsically a race with 14780 // the value the caller will receive and someone else changing it. 14781 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14782 // we will switch to the calling user if access to the current user fails. 14783 int targetUserId = unsafeConvertIncomingUser(userId); 14784 14785 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14786 final boolean allow; 14787 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14788 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14789 // If the caller has this permission, they always pass go. And collect $200. 14790 allow = true; 14791 } else if (allowMode == ALLOW_FULL_ONLY) { 14792 // We require full access, sucks to be you. 14793 allow = false; 14794 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14795 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14796 // If the caller does not have either permission, they are always doomed. 14797 allow = false; 14798 } else if (allowMode == ALLOW_NON_FULL) { 14799 // We are blanket allowing non-full access, you lucky caller! 14800 allow = true; 14801 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14802 // We may or may not allow this depending on whether the two users are 14803 // in the same profile. 14804 synchronized (mUserProfileGroupIdsSelfLocked) { 14805 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14806 UserInfo.NO_PROFILE_GROUP_ID); 14807 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14808 UserInfo.NO_PROFILE_GROUP_ID); 14809 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14810 && callingProfile == targetProfile; 14811 } 14812 } else { 14813 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14814 } 14815 if (!allow) { 14816 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14817 // In this case, they would like to just execute as their 14818 // owner user instead of failing. 14819 targetUserId = callingUserId; 14820 } else { 14821 StringBuilder builder = new StringBuilder(128); 14822 builder.append("Permission Denial: "); 14823 builder.append(name); 14824 if (callerPackage != null) { 14825 builder.append(" from "); 14826 builder.append(callerPackage); 14827 } 14828 builder.append(" asks to run as user "); 14829 builder.append(userId); 14830 builder.append(" but is calling from user "); 14831 builder.append(UserHandle.getUserId(callingUid)); 14832 builder.append("; this requires "); 14833 builder.append(INTERACT_ACROSS_USERS_FULL); 14834 if (allowMode != ALLOW_FULL_ONLY) { 14835 builder.append(" or "); 14836 builder.append(INTERACT_ACROSS_USERS); 14837 } 14838 String msg = builder.toString(); 14839 Slog.w(TAG, msg); 14840 throw new SecurityException(msg); 14841 } 14842 } 14843 } 14844 if (!allowAll && targetUserId < 0) { 14845 throw new IllegalArgumentException( 14846 "Call does not support special user #" + targetUserId); 14847 } 14848 // Check shell permission 14849 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14850 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14851 targetUserId)) { 14852 throw new SecurityException("Shell does not have permission to access user " 14853 + targetUserId + "\n " + Debug.getCallers(3)); 14854 } 14855 } 14856 return targetUserId; 14857 } 14858 14859 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14860 String className, int flags) { 14861 boolean result = false; 14862 // For apps that don't have pre-defined UIDs, check for permission 14863 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14864 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14865 if (ActivityManager.checkUidPermission( 14866 INTERACT_ACROSS_USERS, 14867 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14868 ComponentName comp = new ComponentName(aInfo.packageName, className); 14869 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14870 + " requests FLAG_SINGLE_USER, but app does not hold " 14871 + INTERACT_ACROSS_USERS; 14872 Slog.w(TAG, msg); 14873 throw new SecurityException(msg); 14874 } 14875 // Permission passed 14876 result = true; 14877 } 14878 } else if ("system".equals(componentProcessName)) { 14879 result = true; 14880 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14881 // Phone app and persistent apps are allowed to export singleuser providers. 14882 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14883 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14884 } 14885 if (DEBUG_MU) { 14886 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14887 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14888 } 14889 return result; 14890 } 14891 14892 /** 14893 * Checks to see if the caller is in the same app as the singleton 14894 * component, or the component is in a special app. It allows special apps 14895 * to export singleton components but prevents exporting singleton 14896 * components for regular apps. 14897 */ 14898 boolean isValidSingletonCall(int callingUid, int componentUid) { 14899 int componentAppId = UserHandle.getAppId(componentUid); 14900 return UserHandle.isSameApp(callingUid, componentUid) 14901 || componentAppId == Process.SYSTEM_UID 14902 || componentAppId == Process.PHONE_UID 14903 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14904 == PackageManager.PERMISSION_GRANTED; 14905 } 14906 14907 public int bindService(IApplicationThread caller, IBinder token, 14908 Intent service, String resolvedType, 14909 IServiceConnection connection, int flags, int userId) { 14910 enforceNotIsolatedCaller("bindService"); 14911 14912 // Refuse possible leaked file descriptors 14913 if (service != null && service.hasFileDescriptors() == true) { 14914 throw new IllegalArgumentException("File descriptors passed in Intent"); 14915 } 14916 14917 synchronized(this) { 14918 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14919 connection, flags, userId); 14920 } 14921 } 14922 14923 public boolean unbindService(IServiceConnection connection) { 14924 synchronized (this) { 14925 return mServices.unbindServiceLocked(connection); 14926 } 14927 } 14928 14929 public void publishService(IBinder token, Intent intent, IBinder service) { 14930 // Refuse possible leaked file descriptors 14931 if (intent != null && intent.hasFileDescriptors() == true) { 14932 throw new IllegalArgumentException("File descriptors passed in Intent"); 14933 } 14934 14935 synchronized(this) { 14936 if (!(token instanceof ServiceRecord)) { 14937 throw new IllegalArgumentException("Invalid service token"); 14938 } 14939 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14940 } 14941 } 14942 14943 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14944 // Refuse possible leaked file descriptors 14945 if (intent != null && intent.hasFileDescriptors() == true) { 14946 throw new IllegalArgumentException("File descriptors passed in Intent"); 14947 } 14948 14949 synchronized(this) { 14950 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14951 } 14952 } 14953 14954 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14955 synchronized(this) { 14956 if (!(token instanceof ServiceRecord)) { 14957 throw new IllegalArgumentException("Invalid service token"); 14958 } 14959 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14960 } 14961 } 14962 14963 // ========================================================= 14964 // BACKUP AND RESTORE 14965 // ========================================================= 14966 14967 // Cause the target app to be launched if necessary and its backup agent 14968 // instantiated. The backup agent will invoke backupAgentCreated() on the 14969 // activity manager to announce its creation. 14970 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14971 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14972 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14973 14974 synchronized(this) { 14975 // !!! TODO: currently no check here that we're already bound 14976 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14977 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14978 synchronized (stats) { 14979 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14980 } 14981 14982 // Backup agent is now in use, its package can't be stopped. 14983 try { 14984 AppGlobals.getPackageManager().setPackageStoppedState( 14985 app.packageName, false, UserHandle.getUserId(app.uid)); 14986 } catch (RemoteException e) { 14987 } catch (IllegalArgumentException e) { 14988 Slog.w(TAG, "Failed trying to unstop package " 14989 + app.packageName + ": " + e); 14990 } 14991 14992 BackupRecord r = new BackupRecord(ss, app, backupMode); 14993 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14994 ? new ComponentName(app.packageName, app.backupAgentName) 14995 : new ComponentName("android", "FullBackupAgent"); 14996 // startProcessLocked() returns existing proc's record if it's already running 14997 ProcessRecord proc = startProcessLocked(app.processName, app, 14998 false, 0, "backup", hostingName, false, false, false); 14999 if (proc == null) { 15000 Slog.e(TAG, "Unable to start backup agent process " + r); 15001 return false; 15002 } 15003 15004 r.app = proc; 15005 mBackupTarget = r; 15006 mBackupAppName = app.packageName; 15007 15008 // Try not to kill the process during backup 15009 updateOomAdjLocked(proc); 15010 15011 // If the process is already attached, schedule the creation of the backup agent now. 15012 // If it is not yet live, this will be done when it attaches to the framework. 15013 if (proc.thread != null) { 15014 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 15015 try { 15016 proc.thread.scheduleCreateBackupAgent(app, 15017 compatibilityInfoForPackageLocked(app), backupMode); 15018 } catch (RemoteException e) { 15019 // Will time out on the backup manager side 15020 } 15021 } else { 15022 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 15023 } 15024 // Invariants: at this point, the target app process exists and the application 15025 // is either already running or in the process of coming up. mBackupTarget and 15026 // mBackupAppName describe the app, so that when it binds back to the AM we 15027 // know that it's scheduled for a backup-agent operation. 15028 } 15029 15030 return true; 15031 } 15032 15033 @Override 15034 public void clearPendingBackup() { 15035 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 15036 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 15037 15038 synchronized (this) { 15039 mBackupTarget = null; 15040 mBackupAppName = null; 15041 } 15042 } 15043 15044 // A backup agent has just come up 15045 public void backupAgentCreated(String agentPackageName, IBinder agent) { 15046 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 15047 + " = " + agent); 15048 15049 synchronized(this) { 15050 if (!agentPackageName.equals(mBackupAppName)) { 15051 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 15052 return; 15053 } 15054 } 15055 15056 long oldIdent = Binder.clearCallingIdentity(); 15057 try { 15058 IBackupManager bm = IBackupManager.Stub.asInterface( 15059 ServiceManager.getService(Context.BACKUP_SERVICE)); 15060 bm.agentConnected(agentPackageName, agent); 15061 } catch (RemoteException e) { 15062 // can't happen; the backup manager service is local 15063 } catch (Exception e) { 15064 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 15065 e.printStackTrace(); 15066 } finally { 15067 Binder.restoreCallingIdentity(oldIdent); 15068 } 15069 } 15070 15071 // done with this agent 15072 public void unbindBackupAgent(ApplicationInfo appInfo) { 15073 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 15074 if (appInfo == null) { 15075 Slog.w(TAG, "unbind backup agent for null app"); 15076 return; 15077 } 15078 15079 synchronized(this) { 15080 try { 15081 if (mBackupAppName == null) { 15082 Slog.w(TAG, "Unbinding backup agent with no active backup"); 15083 return; 15084 } 15085 15086 if (!mBackupAppName.equals(appInfo.packageName)) { 15087 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 15088 return; 15089 } 15090 15091 // Not backing this app up any more; reset its OOM adjustment 15092 final ProcessRecord proc = mBackupTarget.app; 15093 updateOomAdjLocked(proc); 15094 15095 // If the app crashed during backup, 'thread' will be null here 15096 if (proc.thread != null) { 15097 try { 15098 proc.thread.scheduleDestroyBackupAgent(appInfo, 15099 compatibilityInfoForPackageLocked(appInfo)); 15100 } catch (Exception e) { 15101 Slog.e(TAG, "Exception when unbinding backup agent:"); 15102 e.printStackTrace(); 15103 } 15104 } 15105 } finally { 15106 mBackupTarget = null; 15107 mBackupAppName = null; 15108 } 15109 } 15110 } 15111 // ========================================================= 15112 // BROADCASTS 15113 // ========================================================= 15114 15115 private final List getStickiesLocked(String action, IntentFilter filter, 15116 List cur, int userId) { 15117 final ContentResolver resolver = mContext.getContentResolver(); 15118 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15119 if (stickies == null) { 15120 return cur; 15121 } 15122 final ArrayList<Intent> list = stickies.get(action); 15123 if (list == null) { 15124 return cur; 15125 } 15126 int N = list.size(); 15127 for (int i=0; i<N; i++) { 15128 Intent intent = list.get(i); 15129 if (filter.match(resolver, intent, true, TAG) >= 0) { 15130 if (cur == null) { 15131 cur = new ArrayList<Intent>(); 15132 } 15133 cur.add(intent); 15134 } 15135 } 15136 return cur; 15137 } 15138 15139 boolean isPendingBroadcastProcessLocked(int pid) { 15140 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 15141 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 15142 } 15143 15144 void skipPendingBroadcastLocked(int pid) { 15145 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 15146 for (BroadcastQueue queue : mBroadcastQueues) { 15147 queue.skipPendingBroadcastLocked(pid); 15148 } 15149 } 15150 15151 // The app just attached; send any pending broadcasts that it should receive 15152 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 15153 boolean didSomething = false; 15154 for (BroadcastQueue queue : mBroadcastQueues) { 15155 didSomething |= queue.sendPendingBroadcastsLocked(app); 15156 } 15157 return didSomething; 15158 } 15159 15160 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15161 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15162 enforceNotIsolatedCaller("registerReceiver"); 15163 int callingUid; 15164 int callingPid; 15165 synchronized(this) { 15166 ProcessRecord callerApp = null; 15167 if (caller != null) { 15168 callerApp = getRecordForAppLocked(caller); 15169 if (callerApp == null) { 15170 throw new SecurityException( 15171 "Unable to find app for caller " + caller 15172 + " (pid=" + Binder.getCallingPid() 15173 + ") when registering receiver " + receiver); 15174 } 15175 if (callerApp.info.uid != Process.SYSTEM_UID && 15176 !callerApp.pkgList.containsKey(callerPackage) && 15177 !"android".equals(callerPackage)) { 15178 throw new SecurityException("Given caller package " + callerPackage 15179 + " is not running in process " + callerApp); 15180 } 15181 callingUid = callerApp.info.uid; 15182 callingPid = callerApp.pid; 15183 } else { 15184 callerPackage = null; 15185 callingUid = Binder.getCallingUid(); 15186 callingPid = Binder.getCallingPid(); 15187 } 15188 15189 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15190 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15191 15192 List allSticky = null; 15193 15194 // Look for any matching sticky broadcasts... 15195 Iterator actions = filter.actionsIterator(); 15196 if (actions != null) { 15197 while (actions.hasNext()) { 15198 String action = (String)actions.next(); 15199 allSticky = getStickiesLocked(action, filter, allSticky, 15200 UserHandle.USER_ALL); 15201 allSticky = getStickiesLocked(action, filter, allSticky, 15202 UserHandle.getUserId(callingUid)); 15203 } 15204 } else { 15205 allSticky = getStickiesLocked(null, filter, allSticky, 15206 UserHandle.USER_ALL); 15207 allSticky = getStickiesLocked(null, filter, allSticky, 15208 UserHandle.getUserId(callingUid)); 15209 } 15210 15211 // The first sticky in the list is returned directly back to 15212 // the client. 15213 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15214 15215 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15216 + ": " + sticky); 15217 15218 if (receiver == null) { 15219 return sticky; 15220 } 15221 15222 ReceiverList rl 15223 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15224 if (rl == null) { 15225 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15226 userId, receiver); 15227 if (rl.app != null) { 15228 rl.app.receivers.add(rl); 15229 } else { 15230 try { 15231 receiver.asBinder().linkToDeath(rl, 0); 15232 } catch (RemoteException e) { 15233 return sticky; 15234 } 15235 rl.linkedToDeath = true; 15236 } 15237 mRegisteredReceivers.put(receiver.asBinder(), rl); 15238 } else if (rl.uid != callingUid) { 15239 throw new IllegalArgumentException( 15240 "Receiver requested to register for uid " + callingUid 15241 + " was previously registered for uid " + rl.uid); 15242 } else if (rl.pid != callingPid) { 15243 throw new IllegalArgumentException( 15244 "Receiver requested to register for pid " + callingPid 15245 + " was previously registered for pid " + rl.pid); 15246 } else if (rl.userId != userId) { 15247 throw new IllegalArgumentException( 15248 "Receiver requested to register for user " + userId 15249 + " was previously registered for user " + rl.userId); 15250 } 15251 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15252 permission, callingUid, userId); 15253 rl.add(bf); 15254 if (!bf.debugCheck()) { 15255 Slog.w(TAG, "==> For Dynamic broadast"); 15256 } 15257 mReceiverResolver.addFilter(bf); 15258 15259 // Enqueue broadcasts for all existing stickies that match 15260 // this filter. 15261 if (allSticky != null) { 15262 ArrayList receivers = new ArrayList(); 15263 receivers.add(bf); 15264 15265 int N = allSticky.size(); 15266 for (int i=0; i<N; i++) { 15267 Intent intent = (Intent)allSticky.get(i); 15268 BroadcastQueue queue = broadcastQueueForIntent(intent); 15269 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15270 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15271 null, null, false, true, true, -1); 15272 queue.enqueueParallelBroadcastLocked(r); 15273 queue.scheduleBroadcastsLocked(); 15274 } 15275 } 15276 15277 return sticky; 15278 } 15279 } 15280 15281 public void unregisterReceiver(IIntentReceiver receiver) { 15282 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15283 15284 final long origId = Binder.clearCallingIdentity(); 15285 try { 15286 boolean doTrim = false; 15287 15288 synchronized(this) { 15289 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15290 if (rl != null) { 15291 if (rl.curBroadcast != null) { 15292 BroadcastRecord r = rl.curBroadcast; 15293 final boolean doNext = finishReceiverLocked( 15294 receiver.asBinder(), r.resultCode, r.resultData, 15295 r.resultExtras, r.resultAbort); 15296 if (doNext) { 15297 doTrim = true; 15298 r.queue.processNextBroadcast(false); 15299 } 15300 } 15301 15302 if (rl.app != null) { 15303 rl.app.receivers.remove(rl); 15304 } 15305 removeReceiverLocked(rl); 15306 if (rl.linkedToDeath) { 15307 rl.linkedToDeath = false; 15308 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15309 } 15310 } 15311 } 15312 15313 // If we actually concluded any broadcasts, we might now be able 15314 // to trim the recipients' apps from our working set 15315 if (doTrim) { 15316 trimApplications(); 15317 return; 15318 } 15319 15320 } finally { 15321 Binder.restoreCallingIdentity(origId); 15322 } 15323 } 15324 15325 void removeReceiverLocked(ReceiverList rl) { 15326 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15327 int N = rl.size(); 15328 for (int i=0; i<N; i++) { 15329 mReceiverResolver.removeFilter(rl.get(i)); 15330 } 15331 } 15332 15333 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15334 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15335 ProcessRecord r = mLruProcesses.get(i); 15336 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15337 try { 15338 r.thread.dispatchPackageBroadcast(cmd, packages); 15339 } catch (RemoteException ex) { 15340 } 15341 } 15342 } 15343 } 15344 15345 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15346 int callingUid, int[] users) { 15347 List<ResolveInfo> receivers = null; 15348 try { 15349 HashSet<ComponentName> singleUserReceivers = null; 15350 boolean scannedFirstReceivers = false; 15351 for (int user : users) { 15352 // Skip users that have Shell restrictions 15353 if (callingUid == Process.SHELL_UID 15354 && getUserManagerLocked().hasUserRestriction( 15355 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15356 continue; 15357 } 15358 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15359 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15360 if (user != 0 && newReceivers != null) { 15361 // If this is not the primary user, we need to check for 15362 // any receivers that should be filtered out. 15363 for (int i=0; i<newReceivers.size(); i++) { 15364 ResolveInfo ri = newReceivers.get(i); 15365 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15366 newReceivers.remove(i); 15367 i--; 15368 } 15369 } 15370 } 15371 if (newReceivers != null && newReceivers.size() == 0) { 15372 newReceivers = null; 15373 } 15374 if (receivers == null) { 15375 receivers = newReceivers; 15376 } else if (newReceivers != null) { 15377 // We need to concatenate the additional receivers 15378 // found with what we have do far. This would be easy, 15379 // but we also need to de-dup any receivers that are 15380 // singleUser. 15381 if (!scannedFirstReceivers) { 15382 // Collect any single user receivers we had already retrieved. 15383 scannedFirstReceivers = true; 15384 for (int i=0; i<receivers.size(); i++) { 15385 ResolveInfo ri = receivers.get(i); 15386 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15387 ComponentName cn = new ComponentName( 15388 ri.activityInfo.packageName, ri.activityInfo.name); 15389 if (singleUserReceivers == null) { 15390 singleUserReceivers = new HashSet<ComponentName>(); 15391 } 15392 singleUserReceivers.add(cn); 15393 } 15394 } 15395 } 15396 // Add the new results to the existing results, tracking 15397 // and de-dupping single user receivers. 15398 for (int i=0; i<newReceivers.size(); i++) { 15399 ResolveInfo ri = newReceivers.get(i); 15400 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15401 ComponentName cn = new ComponentName( 15402 ri.activityInfo.packageName, ri.activityInfo.name); 15403 if (singleUserReceivers == null) { 15404 singleUserReceivers = new HashSet<ComponentName>(); 15405 } 15406 if (!singleUserReceivers.contains(cn)) { 15407 singleUserReceivers.add(cn); 15408 receivers.add(ri); 15409 } 15410 } else { 15411 receivers.add(ri); 15412 } 15413 } 15414 } 15415 } 15416 } catch (RemoteException ex) { 15417 // pm is in same process, this will never happen. 15418 } 15419 return receivers; 15420 } 15421 15422 private final int broadcastIntentLocked(ProcessRecord callerApp, 15423 String callerPackage, Intent intent, String resolvedType, 15424 IIntentReceiver resultTo, int resultCode, String resultData, 15425 Bundle map, String requiredPermission, int appOp, 15426 boolean ordered, boolean sticky, int callingPid, int callingUid, 15427 int userId) { 15428 intent = new Intent(intent); 15429 15430 // By default broadcasts do not go to stopped apps. 15431 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15432 15433 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15434 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15435 + " ordered=" + ordered + " userid=" + userId); 15436 if ((resultTo != null) && !ordered) { 15437 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15438 } 15439 15440 userId = handleIncomingUser(callingPid, callingUid, userId, 15441 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15442 15443 // Make sure that the user who is receiving this broadcast is started. 15444 // If not, we will just skip it. 15445 15446 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15447 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15448 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15449 Slog.w(TAG, "Skipping broadcast of " + intent 15450 + ": user " + userId + " is stopped"); 15451 return ActivityManager.BROADCAST_SUCCESS; 15452 } 15453 } 15454 15455 /* 15456 * Prevent non-system code (defined here to be non-persistent 15457 * processes) from sending protected broadcasts. 15458 */ 15459 int callingAppId = UserHandle.getAppId(callingUid); 15460 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15461 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15462 || callingAppId == Process.NFC_UID || callingUid == 0) { 15463 // Always okay. 15464 } else if (callerApp == null || !callerApp.persistent) { 15465 try { 15466 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15467 intent.getAction())) { 15468 String msg = "Permission Denial: not allowed to send broadcast " 15469 + intent.getAction() + " from pid=" 15470 + callingPid + ", uid=" + callingUid; 15471 Slog.w(TAG, msg); 15472 throw new SecurityException(msg); 15473 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15474 // Special case for compatibility: we don't want apps to send this, 15475 // but historically it has not been protected and apps may be using it 15476 // to poke their own app widget. So, instead of making it protected, 15477 // just limit it to the caller. 15478 if (callerApp == null) { 15479 String msg = "Permission Denial: not allowed to send broadcast " 15480 + intent.getAction() + " from unknown caller."; 15481 Slog.w(TAG, msg); 15482 throw new SecurityException(msg); 15483 } else if (intent.getComponent() != null) { 15484 // They are good enough to send to an explicit component... verify 15485 // it is being sent to the calling app. 15486 if (!intent.getComponent().getPackageName().equals( 15487 callerApp.info.packageName)) { 15488 String msg = "Permission Denial: not allowed to send broadcast " 15489 + intent.getAction() + " to " 15490 + intent.getComponent().getPackageName() + " from " 15491 + callerApp.info.packageName; 15492 Slog.w(TAG, msg); 15493 throw new SecurityException(msg); 15494 } 15495 } else { 15496 // Limit broadcast to their own package. 15497 intent.setPackage(callerApp.info.packageName); 15498 } 15499 } 15500 } catch (RemoteException e) { 15501 Slog.w(TAG, "Remote exception", e); 15502 return ActivityManager.BROADCAST_SUCCESS; 15503 } 15504 } 15505 15506 // Handle special intents: if this broadcast is from the package 15507 // manager about a package being removed, we need to remove all of 15508 // its activities from the history stack. 15509 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15510 intent.getAction()); 15511 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15512 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15513 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15514 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15515 || uidRemoved) { 15516 if (checkComponentPermission( 15517 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15518 callingPid, callingUid, -1, true) 15519 == PackageManager.PERMISSION_GRANTED) { 15520 if (uidRemoved) { 15521 final Bundle intentExtras = intent.getExtras(); 15522 final int uid = intentExtras != null 15523 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15524 if (uid >= 0) { 15525 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15526 synchronized (bs) { 15527 bs.removeUidStatsLocked(uid); 15528 } 15529 mAppOpsService.uidRemoved(uid); 15530 } 15531 } else { 15532 // If resources are unavailable just force stop all 15533 // those packages and flush the attribute cache as well. 15534 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15535 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15536 if (list != null && (list.length > 0)) { 15537 for (String pkg : list) { 15538 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15539 "storage unmount"); 15540 } 15541 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15542 sendPackageBroadcastLocked( 15543 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15544 } 15545 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15546 intent.getAction())) { 15547 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15548 } else { 15549 Uri data = intent.getData(); 15550 String ssp; 15551 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15552 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15553 intent.getAction()); 15554 boolean fullUninstall = removed && 15555 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15556 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15557 forceStopPackageLocked(ssp, UserHandle.getAppId( 15558 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15559 false, fullUninstall, userId, 15560 removed ? "pkg removed" : "pkg changed"); 15561 } 15562 if (removed) { 15563 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15564 new String[] {ssp}, userId); 15565 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15566 mAppOpsService.packageRemoved( 15567 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15568 15569 // Remove all permissions granted from/to this package 15570 removeUriPermissionsForPackageLocked(ssp, userId, true); 15571 } 15572 } 15573 } 15574 } 15575 } 15576 } else { 15577 String msg = "Permission Denial: " + intent.getAction() 15578 + " broadcast from " + callerPackage + " (pid=" + callingPid 15579 + ", uid=" + callingUid + ")" 15580 + " requires " 15581 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15582 Slog.w(TAG, msg); 15583 throw new SecurityException(msg); 15584 } 15585 15586 // Special case for adding a package: by default turn on compatibility 15587 // mode. 15588 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15589 Uri data = intent.getData(); 15590 String ssp; 15591 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15592 mCompatModePackages.handlePackageAddedLocked(ssp, 15593 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15594 } 15595 } 15596 15597 /* 15598 * If this is the time zone changed action, queue up a message that will reset the timezone 15599 * of all currently running processes. This message will get queued up before the broadcast 15600 * happens. 15601 */ 15602 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15603 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15604 } 15605 15606 /* 15607 * If the user set the time, let all running processes know. 15608 */ 15609 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15610 final int is24Hour = intent.getBooleanExtra( 15611 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15612 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15613 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15614 synchronized (stats) { 15615 stats.noteCurrentTimeChangedLocked(); 15616 } 15617 } 15618 15619 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15620 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15621 } 15622 15623 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15624 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15625 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15626 } 15627 15628 // Add to the sticky list if requested. 15629 if (sticky) { 15630 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15631 callingPid, callingUid) 15632 != PackageManager.PERMISSION_GRANTED) { 15633 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15634 + callingPid + ", uid=" + callingUid 15635 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15636 Slog.w(TAG, msg); 15637 throw new SecurityException(msg); 15638 } 15639 if (requiredPermission != null) { 15640 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15641 + " and enforce permission " + requiredPermission); 15642 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15643 } 15644 if (intent.getComponent() != null) { 15645 throw new SecurityException( 15646 "Sticky broadcasts can't target a specific component"); 15647 } 15648 // We use userId directly here, since the "all" target is maintained 15649 // as a separate set of sticky broadcasts. 15650 if (userId != UserHandle.USER_ALL) { 15651 // But first, if this is not a broadcast to all users, then 15652 // make sure it doesn't conflict with an existing broadcast to 15653 // all users. 15654 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15655 UserHandle.USER_ALL); 15656 if (stickies != null) { 15657 ArrayList<Intent> list = stickies.get(intent.getAction()); 15658 if (list != null) { 15659 int N = list.size(); 15660 int i; 15661 for (i=0; i<N; i++) { 15662 if (intent.filterEquals(list.get(i))) { 15663 throw new IllegalArgumentException( 15664 "Sticky broadcast " + intent + " for user " 15665 + userId + " conflicts with existing global broadcast"); 15666 } 15667 } 15668 } 15669 } 15670 } 15671 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15672 if (stickies == null) { 15673 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15674 mStickyBroadcasts.put(userId, stickies); 15675 } 15676 ArrayList<Intent> list = stickies.get(intent.getAction()); 15677 if (list == null) { 15678 list = new ArrayList<Intent>(); 15679 stickies.put(intent.getAction(), list); 15680 } 15681 int N = list.size(); 15682 int i; 15683 for (i=0; i<N; i++) { 15684 if (intent.filterEquals(list.get(i))) { 15685 // This sticky already exists, replace it. 15686 list.set(i, new Intent(intent)); 15687 break; 15688 } 15689 } 15690 if (i >= N) { 15691 list.add(new Intent(intent)); 15692 } 15693 } 15694 15695 int[] users; 15696 if (userId == UserHandle.USER_ALL) { 15697 // Caller wants broadcast to go to all started users. 15698 users = mStartedUserArray; 15699 } else { 15700 // Caller wants broadcast to go to one specific user. 15701 users = new int[] {userId}; 15702 } 15703 15704 // Figure out who all will receive this broadcast. 15705 List receivers = null; 15706 List<BroadcastFilter> registeredReceivers = null; 15707 // Need to resolve the intent to interested receivers... 15708 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15709 == 0) { 15710 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15711 } 15712 if (intent.getComponent() == null) { 15713 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15714 // Query one target user at a time, excluding shell-restricted users 15715 UserManagerService ums = getUserManagerLocked(); 15716 for (int i = 0; i < users.length; i++) { 15717 if (ums.hasUserRestriction( 15718 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15719 continue; 15720 } 15721 List<BroadcastFilter> registeredReceiversForUser = 15722 mReceiverResolver.queryIntent(intent, 15723 resolvedType, false, users[i]); 15724 if (registeredReceivers == null) { 15725 registeredReceivers = registeredReceiversForUser; 15726 } else if (registeredReceiversForUser != null) { 15727 registeredReceivers.addAll(registeredReceiversForUser); 15728 } 15729 } 15730 } else { 15731 registeredReceivers = mReceiverResolver.queryIntent(intent, 15732 resolvedType, false, userId); 15733 } 15734 } 15735 15736 final boolean replacePending = 15737 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15738 15739 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15740 + " replacePending=" + replacePending); 15741 15742 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15743 if (!ordered && NR > 0) { 15744 // If we are not serializing this broadcast, then send the 15745 // registered receivers separately so they don't wait for the 15746 // components to be launched. 15747 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15748 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15749 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15750 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15751 ordered, sticky, false, userId); 15752 if (DEBUG_BROADCAST) Slog.v( 15753 TAG, "Enqueueing parallel broadcast " + r); 15754 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15755 if (!replaced) { 15756 queue.enqueueParallelBroadcastLocked(r); 15757 queue.scheduleBroadcastsLocked(); 15758 } 15759 registeredReceivers = null; 15760 NR = 0; 15761 } 15762 15763 // Merge into one list. 15764 int ir = 0; 15765 if (receivers != null) { 15766 // A special case for PACKAGE_ADDED: do not allow the package 15767 // being added to see this broadcast. This prevents them from 15768 // using this as a back door to get run as soon as they are 15769 // installed. Maybe in the future we want to have a special install 15770 // broadcast or such for apps, but we'd like to deliberately make 15771 // this decision. 15772 String skipPackages[] = null; 15773 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15774 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15775 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15776 Uri data = intent.getData(); 15777 if (data != null) { 15778 String pkgName = data.getSchemeSpecificPart(); 15779 if (pkgName != null) { 15780 skipPackages = new String[] { pkgName }; 15781 } 15782 } 15783 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15784 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15785 } 15786 if (skipPackages != null && (skipPackages.length > 0)) { 15787 for (String skipPackage : skipPackages) { 15788 if (skipPackage != null) { 15789 int NT = receivers.size(); 15790 for (int it=0; it<NT; it++) { 15791 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15792 if (curt.activityInfo.packageName.equals(skipPackage)) { 15793 receivers.remove(it); 15794 it--; 15795 NT--; 15796 } 15797 } 15798 } 15799 } 15800 } 15801 15802 int NT = receivers != null ? receivers.size() : 0; 15803 int it = 0; 15804 ResolveInfo curt = null; 15805 BroadcastFilter curr = null; 15806 while (it < NT && ir < NR) { 15807 if (curt == null) { 15808 curt = (ResolveInfo)receivers.get(it); 15809 } 15810 if (curr == null) { 15811 curr = registeredReceivers.get(ir); 15812 } 15813 if (curr.getPriority() >= curt.priority) { 15814 // Insert this broadcast record into the final list. 15815 receivers.add(it, curr); 15816 ir++; 15817 curr = null; 15818 it++; 15819 NT++; 15820 } else { 15821 // Skip to the next ResolveInfo in the final list. 15822 it++; 15823 curt = null; 15824 } 15825 } 15826 } 15827 while (ir < NR) { 15828 if (receivers == null) { 15829 receivers = new ArrayList(); 15830 } 15831 receivers.add(registeredReceivers.get(ir)); 15832 ir++; 15833 } 15834 15835 if ((receivers != null && receivers.size() > 0) 15836 || resultTo != null) { 15837 BroadcastQueue queue = broadcastQueueForIntent(intent); 15838 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15839 callerPackage, callingPid, callingUid, resolvedType, 15840 requiredPermission, appOp, receivers, resultTo, resultCode, 15841 resultData, map, ordered, sticky, false, userId); 15842 if (DEBUG_BROADCAST) Slog.v( 15843 TAG, "Enqueueing ordered broadcast " + r 15844 + ": prev had " + queue.mOrderedBroadcasts.size()); 15845 if (DEBUG_BROADCAST) { 15846 int seq = r.intent.getIntExtra("seq", -1); 15847 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15848 } 15849 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15850 if (!replaced) { 15851 queue.enqueueOrderedBroadcastLocked(r); 15852 queue.scheduleBroadcastsLocked(); 15853 } 15854 } 15855 15856 return ActivityManager.BROADCAST_SUCCESS; 15857 } 15858 15859 final Intent verifyBroadcastLocked(Intent intent) { 15860 // Refuse possible leaked file descriptors 15861 if (intent != null && intent.hasFileDescriptors() == true) { 15862 throw new IllegalArgumentException("File descriptors passed in Intent"); 15863 } 15864 15865 int flags = intent.getFlags(); 15866 15867 if (!mProcessesReady) { 15868 // if the caller really truly claims to know what they're doing, go 15869 // ahead and allow the broadcast without launching any receivers 15870 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15871 intent = new Intent(intent); 15872 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15873 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15874 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15875 + " before boot completion"); 15876 throw new IllegalStateException("Cannot broadcast before boot completed"); 15877 } 15878 } 15879 15880 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15881 throw new IllegalArgumentException( 15882 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15883 } 15884 15885 return intent; 15886 } 15887 15888 public final int broadcastIntent(IApplicationThread caller, 15889 Intent intent, String resolvedType, IIntentReceiver resultTo, 15890 int resultCode, String resultData, Bundle map, 15891 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15892 enforceNotIsolatedCaller("broadcastIntent"); 15893 synchronized(this) { 15894 intent = verifyBroadcastLocked(intent); 15895 15896 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15897 final int callingPid = Binder.getCallingPid(); 15898 final int callingUid = Binder.getCallingUid(); 15899 final long origId = Binder.clearCallingIdentity(); 15900 int res = broadcastIntentLocked(callerApp, 15901 callerApp != null ? callerApp.info.packageName : null, 15902 intent, resolvedType, resultTo, 15903 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15904 callingPid, callingUid, userId); 15905 Binder.restoreCallingIdentity(origId); 15906 return res; 15907 } 15908 } 15909 15910 int broadcastIntentInPackage(String packageName, int uid, 15911 Intent intent, String resolvedType, IIntentReceiver resultTo, 15912 int resultCode, String resultData, Bundle map, 15913 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15914 synchronized(this) { 15915 intent = verifyBroadcastLocked(intent); 15916 15917 final long origId = Binder.clearCallingIdentity(); 15918 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15919 resultTo, resultCode, resultData, map, requiredPermission, 15920 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15921 Binder.restoreCallingIdentity(origId); 15922 return res; 15923 } 15924 } 15925 15926 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15927 // Refuse possible leaked file descriptors 15928 if (intent != null && intent.hasFileDescriptors() == true) { 15929 throw new IllegalArgumentException("File descriptors passed in Intent"); 15930 } 15931 15932 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15933 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15934 15935 synchronized(this) { 15936 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15937 != PackageManager.PERMISSION_GRANTED) { 15938 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15939 + Binder.getCallingPid() 15940 + ", uid=" + Binder.getCallingUid() 15941 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15942 Slog.w(TAG, msg); 15943 throw new SecurityException(msg); 15944 } 15945 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15946 if (stickies != null) { 15947 ArrayList<Intent> list = stickies.get(intent.getAction()); 15948 if (list != null) { 15949 int N = list.size(); 15950 int i; 15951 for (i=0; i<N; i++) { 15952 if (intent.filterEquals(list.get(i))) { 15953 list.remove(i); 15954 break; 15955 } 15956 } 15957 if (list.size() <= 0) { 15958 stickies.remove(intent.getAction()); 15959 } 15960 } 15961 if (stickies.size() <= 0) { 15962 mStickyBroadcasts.remove(userId); 15963 } 15964 } 15965 } 15966 } 15967 15968 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15969 String resultData, Bundle resultExtras, boolean resultAbort) { 15970 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15971 if (r == null) { 15972 Slog.w(TAG, "finishReceiver called but not found on queue"); 15973 return false; 15974 } 15975 15976 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15977 } 15978 15979 void backgroundServicesFinishedLocked(int userId) { 15980 for (BroadcastQueue queue : mBroadcastQueues) { 15981 queue.backgroundServicesFinishedLocked(userId); 15982 } 15983 } 15984 15985 public void finishReceiver(IBinder who, int resultCode, String resultData, 15986 Bundle resultExtras, boolean resultAbort) { 15987 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15988 15989 // Refuse possible leaked file descriptors 15990 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15991 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15992 } 15993 15994 final long origId = Binder.clearCallingIdentity(); 15995 try { 15996 boolean doNext = false; 15997 BroadcastRecord r; 15998 15999 synchronized(this) { 16000 r = broadcastRecordForReceiverLocked(who); 16001 if (r != null) { 16002 doNext = r.queue.finishReceiverLocked(r, resultCode, 16003 resultData, resultExtras, resultAbort, true); 16004 } 16005 } 16006 16007 if (doNext) { 16008 r.queue.processNextBroadcast(false); 16009 } 16010 trimApplications(); 16011 } finally { 16012 Binder.restoreCallingIdentity(origId); 16013 } 16014 } 16015 16016 // ========================================================= 16017 // INSTRUMENTATION 16018 // ========================================================= 16019 16020 public boolean startInstrumentation(ComponentName className, 16021 String profileFile, int flags, Bundle arguments, 16022 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 16023 int userId, String abiOverride) { 16024 enforceNotIsolatedCaller("startInstrumentation"); 16025 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16026 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 16027 // Refuse possible leaked file descriptors 16028 if (arguments != null && arguments.hasFileDescriptors()) { 16029 throw new IllegalArgumentException("File descriptors passed in Bundle"); 16030 } 16031 16032 synchronized(this) { 16033 InstrumentationInfo ii = null; 16034 ApplicationInfo ai = null; 16035 try { 16036 ii = mContext.getPackageManager().getInstrumentationInfo( 16037 className, STOCK_PM_FLAGS); 16038 ai = AppGlobals.getPackageManager().getApplicationInfo( 16039 ii.targetPackage, STOCK_PM_FLAGS, userId); 16040 } catch (PackageManager.NameNotFoundException e) { 16041 } catch (RemoteException e) { 16042 } 16043 if (ii == null) { 16044 reportStartInstrumentationFailure(watcher, className, 16045 "Unable to find instrumentation info for: " + className); 16046 return false; 16047 } 16048 if (ai == null) { 16049 reportStartInstrumentationFailure(watcher, className, 16050 "Unable to find instrumentation target package: " + ii.targetPackage); 16051 return false; 16052 } 16053 16054 int match = mContext.getPackageManager().checkSignatures( 16055 ii.targetPackage, ii.packageName); 16056 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 16057 String msg = "Permission Denial: starting instrumentation " 16058 + className + " from pid=" 16059 + Binder.getCallingPid() 16060 + ", uid=" + Binder.getCallingPid() 16061 + " not allowed because package " + ii.packageName 16062 + " does not have a signature matching the target " 16063 + ii.targetPackage; 16064 reportStartInstrumentationFailure(watcher, className, msg); 16065 throw new SecurityException(msg); 16066 } 16067 16068 final long origId = Binder.clearCallingIdentity(); 16069 // Instrumentation can kill and relaunch even persistent processes 16070 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 16071 "start instr"); 16072 ProcessRecord app = addAppLocked(ai, false, abiOverride); 16073 app.instrumentationClass = className; 16074 app.instrumentationInfo = ai; 16075 app.instrumentationProfileFile = profileFile; 16076 app.instrumentationArguments = arguments; 16077 app.instrumentationWatcher = watcher; 16078 app.instrumentationUiAutomationConnection = uiAutomationConnection; 16079 app.instrumentationResultClass = className; 16080 Binder.restoreCallingIdentity(origId); 16081 } 16082 16083 return true; 16084 } 16085 16086 /** 16087 * Report errors that occur while attempting to start Instrumentation. Always writes the 16088 * error to the logs, but if somebody is watching, send the report there too. This enables 16089 * the "am" command to report errors with more information. 16090 * 16091 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 16092 * @param cn The component name of the instrumentation. 16093 * @param report The error report. 16094 */ 16095 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 16096 ComponentName cn, String report) { 16097 Slog.w(TAG, report); 16098 try { 16099 if (watcher != null) { 16100 Bundle results = new Bundle(); 16101 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 16102 results.putString("Error", report); 16103 watcher.instrumentationStatus(cn, -1, results); 16104 } 16105 } catch (RemoteException e) { 16106 Slog.w(TAG, e); 16107 } 16108 } 16109 16110 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 16111 if (app.instrumentationWatcher != null) { 16112 try { 16113 // NOTE: IInstrumentationWatcher *must* be oneway here 16114 app.instrumentationWatcher.instrumentationFinished( 16115 app.instrumentationClass, 16116 resultCode, 16117 results); 16118 } catch (RemoteException e) { 16119 } 16120 } 16121 if (app.instrumentationUiAutomationConnection != null) { 16122 try { 16123 app.instrumentationUiAutomationConnection.shutdown(); 16124 } catch (RemoteException re) { 16125 /* ignore */ 16126 } 16127 // Only a UiAutomation can set this flag and now that 16128 // it is finished we make sure it is reset to its default. 16129 mUserIsMonkey = false; 16130 } 16131 app.instrumentationWatcher = null; 16132 app.instrumentationUiAutomationConnection = null; 16133 app.instrumentationClass = null; 16134 app.instrumentationInfo = null; 16135 app.instrumentationProfileFile = null; 16136 app.instrumentationArguments = null; 16137 16138 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 16139 "finished inst"); 16140 } 16141 16142 public void finishInstrumentation(IApplicationThread target, 16143 int resultCode, Bundle results) { 16144 int userId = UserHandle.getCallingUserId(); 16145 // Refuse possible leaked file descriptors 16146 if (results != null && results.hasFileDescriptors()) { 16147 throw new IllegalArgumentException("File descriptors passed in Intent"); 16148 } 16149 16150 synchronized(this) { 16151 ProcessRecord app = getRecordForAppLocked(target); 16152 if (app == null) { 16153 Slog.w(TAG, "finishInstrumentation: no app for " + target); 16154 return; 16155 } 16156 final long origId = Binder.clearCallingIdentity(); 16157 finishInstrumentationLocked(app, resultCode, results); 16158 Binder.restoreCallingIdentity(origId); 16159 } 16160 } 16161 16162 // ========================================================= 16163 // CONFIGURATION 16164 // ========================================================= 16165 16166 public ConfigurationInfo getDeviceConfigurationInfo() { 16167 ConfigurationInfo config = new ConfigurationInfo(); 16168 synchronized (this) { 16169 config.reqTouchScreen = mConfiguration.touchscreen; 16170 config.reqKeyboardType = mConfiguration.keyboard; 16171 config.reqNavigation = mConfiguration.navigation; 16172 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16173 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16174 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16175 } 16176 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16177 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16178 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16179 } 16180 config.reqGlEsVersion = GL_ES_VERSION; 16181 } 16182 return config; 16183 } 16184 16185 ActivityStack getFocusedStack() { 16186 return mStackSupervisor.getFocusedStack(); 16187 } 16188 16189 public Configuration getConfiguration() { 16190 Configuration ci; 16191 synchronized(this) { 16192 ci = new Configuration(mConfiguration); 16193 } 16194 return ci; 16195 } 16196 16197 public void updatePersistentConfiguration(Configuration values) { 16198 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16199 "updateConfiguration()"); 16200 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16201 "updateConfiguration()"); 16202 if (values == null) { 16203 throw new NullPointerException("Configuration must not be null"); 16204 } 16205 16206 synchronized(this) { 16207 final long origId = Binder.clearCallingIdentity(); 16208 updateConfigurationLocked(values, null, true, false); 16209 Binder.restoreCallingIdentity(origId); 16210 } 16211 } 16212 16213 public void updateConfiguration(Configuration values) { 16214 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16215 "updateConfiguration()"); 16216 16217 synchronized(this) { 16218 if (values == null && mWindowManager != null) { 16219 // sentinel: fetch the current configuration from the window manager 16220 values = mWindowManager.computeNewConfiguration(); 16221 } 16222 16223 if (mWindowManager != null) { 16224 mProcessList.applyDisplaySize(mWindowManager); 16225 } 16226 16227 final long origId = Binder.clearCallingIdentity(); 16228 if (values != null) { 16229 Settings.System.clearConfiguration(values); 16230 } 16231 updateConfigurationLocked(values, null, false, false); 16232 Binder.restoreCallingIdentity(origId); 16233 } 16234 } 16235 16236 /** 16237 * Do either or both things: (1) change the current configuration, and (2) 16238 * make sure the given activity is running with the (now) current 16239 * configuration. Returns true if the activity has been left running, or 16240 * false if <var>starting</var> is being destroyed to match the new 16241 * configuration. 16242 * @param persistent TODO 16243 */ 16244 boolean updateConfigurationLocked(Configuration values, 16245 ActivityRecord starting, boolean persistent, boolean initLocale) { 16246 int changes = 0; 16247 16248 if (values != null) { 16249 Configuration newConfig = new Configuration(mConfiguration); 16250 changes = newConfig.updateFrom(values); 16251 if (changes != 0) { 16252 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16253 Slog.i(TAG, "Updating configuration to: " + values); 16254 } 16255 16256 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16257 16258 if (values.locale != null && !initLocale) { 16259 saveLocaleLocked(values.locale, 16260 !values.locale.equals(mConfiguration.locale), 16261 values.userSetLocale); 16262 } 16263 16264 mConfigurationSeq++; 16265 if (mConfigurationSeq <= 0) { 16266 mConfigurationSeq = 1; 16267 } 16268 newConfig.seq = mConfigurationSeq; 16269 mConfiguration = newConfig; 16270 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16271 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16272 //mUsageStatsService.noteStartConfig(newConfig); 16273 16274 final Configuration configCopy = new Configuration(mConfiguration); 16275 16276 // TODO: If our config changes, should we auto dismiss any currently 16277 // showing dialogs? 16278 mShowDialogs = shouldShowDialogs(newConfig); 16279 16280 AttributeCache ac = AttributeCache.instance(); 16281 if (ac != null) { 16282 ac.updateConfiguration(configCopy); 16283 } 16284 16285 // Make sure all resources in our process are updated 16286 // right now, so that anyone who is going to retrieve 16287 // resource values after we return will be sure to get 16288 // the new ones. This is especially important during 16289 // boot, where the first config change needs to guarantee 16290 // all resources have that config before following boot 16291 // code is executed. 16292 mSystemThread.applyConfigurationToResources(configCopy); 16293 16294 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16295 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16296 msg.obj = new Configuration(configCopy); 16297 mHandler.sendMessage(msg); 16298 } 16299 16300 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16301 ProcessRecord app = mLruProcesses.get(i); 16302 try { 16303 if (app.thread != null) { 16304 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16305 + app.processName + " new config " + mConfiguration); 16306 app.thread.scheduleConfigurationChanged(configCopy); 16307 } 16308 } catch (Exception e) { 16309 } 16310 } 16311 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16312 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16313 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16314 | Intent.FLAG_RECEIVER_FOREGROUND); 16315 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16316 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16317 Process.SYSTEM_UID, UserHandle.USER_ALL); 16318 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16319 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16320 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16321 broadcastIntentLocked(null, null, intent, 16322 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16323 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16324 } 16325 } 16326 } 16327 16328 boolean kept = true; 16329 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16330 // mainStack is null during startup. 16331 if (mainStack != null) { 16332 if (changes != 0 && starting == null) { 16333 // If the configuration changed, and the caller is not already 16334 // in the process of starting an activity, then find the top 16335 // activity to check if its configuration needs to change. 16336 starting = mainStack.topRunningActivityLocked(null); 16337 } 16338 16339 if (starting != null) { 16340 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16341 // And we need to make sure at this point that all other activities 16342 // are made visible with the correct configuration. 16343 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16344 } 16345 } 16346 16347 if (values != null && mWindowManager != null) { 16348 mWindowManager.setNewConfiguration(mConfiguration); 16349 } 16350 16351 return kept; 16352 } 16353 16354 /** 16355 * Decide based on the configuration whether we should shouw the ANR, 16356 * crash, etc dialogs. The idea is that if there is no affordnace to 16357 * press the on-screen buttons, we shouldn't show the dialog. 16358 * 16359 * A thought: SystemUI might also want to get told about this, the Power 16360 * dialog / global actions also might want different behaviors. 16361 */ 16362 private static final boolean shouldShowDialogs(Configuration config) { 16363 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16364 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16365 } 16366 16367 /** 16368 * Save the locale. You must be inside a synchronized (this) block. 16369 */ 16370 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16371 if(isDiff) { 16372 SystemProperties.set("user.language", l.getLanguage()); 16373 SystemProperties.set("user.region", l.getCountry()); 16374 } 16375 16376 if(isPersist) { 16377 SystemProperties.set("persist.sys.language", l.getLanguage()); 16378 SystemProperties.set("persist.sys.country", l.getCountry()); 16379 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16380 16381 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l)); 16382 } 16383 } 16384 16385 @Override 16386 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16387 synchronized (this) { 16388 ActivityRecord srec = ActivityRecord.forToken(token); 16389 if (srec.task != null && srec.task.stack != null) { 16390 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16391 } 16392 } 16393 return false; 16394 } 16395 16396 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16397 Intent resultData) { 16398 16399 synchronized (this) { 16400 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16401 if (stack != null) { 16402 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16403 } 16404 return false; 16405 } 16406 } 16407 16408 public int getLaunchedFromUid(IBinder activityToken) { 16409 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16410 if (srec == null) { 16411 return -1; 16412 } 16413 return srec.launchedFromUid; 16414 } 16415 16416 public String getLaunchedFromPackage(IBinder activityToken) { 16417 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16418 if (srec == null) { 16419 return null; 16420 } 16421 return srec.launchedFromPackage; 16422 } 16423 16424 // ========================================================= 16425 // LIFETIME MANAGEMENT 16426 // ========================================================= 16427 16428 // Returns which broadcast queue the app is the current [or imminent] receiver 16429 // on, or 'null' if the app is not an active broadcast recipient. 16430 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16431 BroadcastRecord r = app.curReceiver; 16432 if (r != null) { 16433 return r.queue; 16434 } 16435 16436 // It's not the current receiver, but it might be starting up to become one 16437 synchronized (this) { 16438 for (BroadcastQueue queue : mBroadcastQueues) { 16439 r = queue.mPendingBroadcast; 16440 if (r != null && r.curApp == app) { 16441 // found it; report which queue it's in 16442 return queue; 16443 } 16444 } 16445 } 16446 16447 return null; 16448 } 16449 16450 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16451 boolean doingAll, long now) { 16452 if (mAdjSeq == app.adjSeq) { 16453 // This adjustment has already been computed. 16454 return app.curRawAdj; 16455 } 16456 16457 if (app.thread == null) { 16458 app.adjSeq = mAdjSeq; 16459 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16460 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16461 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16462 } 16463 16464 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16465 app.adjSource = null; 16466 app.adjTarget = null; 16467 app.empty = false; 16468 app.cached = false; 16469 16470 final int activitiesSize = app.activities.size(); 16471 16472 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16473 // The max adjustment doesn't allow this app to be anything 16474 // below foreground, so it is not worth doing work for it. 16475 app.adjType = "fixed"; 16476 app.adjSeq = mAdjSeq; 16477 app.curRawAdj = app.maxAdj; 16478 app.foregroundActivities = false; 16479 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16480 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16481 // System processes can do UI, and when they do we want to have 16482 // them trim their memory after the user leaves the UI. To 16483 // facilitate this, here we need to determine whether or not it 16484 // is currently showing UI. 16485 app.systemNoUi = true; 16486 if (app == TOP_APP) { 16487 app.systemNoUi = false; 16488 } else if (activitiesSize > 0) { 16489 for (int j = 0; j < activitiesSize; j++) { 16490 final ActivityRecord r = app.activities.get(j); 16491 if (r.visible) { 16492 app.systemNoUi = false; 16493 } 16494 } 16495 } 16496 if (!app.systemNoUi) { 16497 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16498 } 16499 return (app.curAdj=app.maxAdj); 16500 } 16501 16502 app.systemNoUi = false; 16503 16504 // Determine the importance of the process, starting with most 16505 // important to least, and assign an appropriate OOM adjustment. 16506 int adj; 16507 int schedGroup; 16508 int procState; 16509 boolean foregroundActivities = false; 16510 BroadcastQueue queue; 16511 if (app == TOP_APP) { 16512 // The last app on the list is the foreground app. 16513 adj = ProcessList.FOREGROUND_APP_ADJ; 16514 schedGroup = Process.THREAD_GROUP_DEFAULT; 16515 app.adjType = "top-activity"; 16516 foregroundActivities = true; 16517 procState = ActivityManager.PROCESS_STATE_TOP; 16518 } else if (app.instrumentationClass != null) { 16519 // Don't want to kill running instrumentation. 16520 adj = ProcessList.FOREGROUND_APP_ADJ; 16521 schedGroup = Process.THREAD_GROUP_DEFAULT; 16522 app.adjType = "instrumentation"; 16523 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16524 } else if ((queue = isReceivingBroadcast(app)) != null) { 16525 // An app that is currently receiving a broadcast also 16526 // counts as being in the foreground for OOM killer purposes. 16527 // It's placed in a sched group based on the nature of the 16528 // broadcast as reflected by which queue it's active in. 16529 adj = ProcessList.FOREGROUND_APP_ADJ; 16530 schedGroup = (queue == mFgBroadcastQueue) 16531 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16532 app.adjType = "broadcast"; 16533 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16534 } else if (app.executingServices.size() > 0) { 16535 // An app that is currently executing a service callback also 16536 // counts as being in the foreground. 16537 adj = ProcessList.FOREGROUND_APP_ADJ; 16538 schedGroup = app.execServicesFg ? 16539 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16540 app.adjType = "exec-service"; 16541 procState = ActivityManager.PROCESS_STATE_SERVICE; 16542 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16543 } else { 16544 // As far as we know the process is empty. We may change our mind later. 16545 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16546 // At this point we don't actually know the adjustment. Use the cached adj 16547 // value that the caller wants us to. 16548 adj = cachedAdj; 16549 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16550 app.cached = true; 16551 app.empty = true; 16552 app.adjType = "cch-empty"; 16553 } 16554 16555 // Examine all activities if not already foreground. 16556 if (!foregroundActivities && activitiesSize > 0) { 16557 for (int j = 0; j < activitiesSize; j++) { 16558 final ActivityRecord r = app.activities.get(j); 16559 if (r.app != app) { 16560 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16561 + app + "?!?"); 16562 continue; 16563 } 16564 if (r.visible) { 16565 // App has a visible activity; only upgrade adjustment. 16566 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16567 adj = ProcessList.VISIBLE_APP_ADJ; 16568 app.adjType = "visible"; 16569 } 16570 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16571 procState = ActivityManager.PROCESS_STATE_TOP; 16572 } 16573 schedGroup = Process.THREAD_GROUP_DEFAULT; 16574 app.cached = false; 16575 app.empty = false; 16576 foregroundActivities = true; 16577 break; 16578 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16579 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16580 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16581 app.adjType = "pausing"; 16582 } 16583 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16584 procState = ActivityManager.PROCESS_STATE_TOP; 16585 } 16586 schedGroup = Process.THREAD_GROUP_DEFAULT; 16587 app.cached = false; 16588 app.empty = false; 16589 foregroundActivities = true; 16590 } else if (r.state == ActivityState.STOPPING) { 16591 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16592 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16593 app.adjType = "stopping"; 16594 } 16595 // For the process state, we will at this point consider the 16596 // process to be cached. It will be cached either as an activity 16597 // or empty depending on whether the activity is finishing. We do 16598 // this so that we can treat the process as cached for purposes of 16599 // memory trimming (determing current memory level, trim command to 16600 // send to process) since there can be an arbitrary number of stopping 16601 // processes and they should soon all go into the cached state. 16602 if (!r.finishing) { 16603 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16604 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16605 } 16606 } 16607 app.cached = false; 16608 app.empty = false; 16609 foregroundActivities = true; 16610 } else { 16611 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16612 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16613 app.adjType = "cch-act"; 16614 } 16615 } 16616 } 16617 } 16618 16619 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16620 if (app.foregroundServices) { 16621 // The user is aware of this app, so make it visible. 16622 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16623 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16624 app.cached = false; 16625 app.adjType = "fg-service"; 16626 schedGroup = Process.THREAD_GROUP_DEFAULT; 16627 } else if (app.forcingToForeground != null) { 16628 // The user is aware of this app, so make it visible. 16629 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16630 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16631 app.cached = false; 16632 app.adjType = "force-fg"; 16633 app.adjSource = app.forcingToForeground; 16634 schedGroup = Process.THREAD_GROUP_DEFAULT; 16635 } 16636 } 16637 16638 if (app == mHeavyWeightProcess) { 16639 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16640 // We don't want to kill the current heavy-weight process. 16641 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16642 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16643 app.cached = false; 16644 app.adjType = "heavy"; 16645 } 16646 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16647 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16648 } 16649 } 16650 16651 if (app == mHomeProcess) { 16652 if (adj > ProcessList.HOME_APP_ADJ) { 16653 // This process is hosting what we currently consider to be the 16654 // home app, so we don't want to let it go into the background. 16655 adj = ProcessList.HOME_APP_ADJ; 16656 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16657 app.cached = false; 16658 app.adjType = "home"; 16659 } 16660 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16661 procState = ActivityManager.PROCESS_STATE_HOME; 16662 } 16663 } 16664 16665 if (app == mPreviousProcess && app.activities.size() > 0) { 16666 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16667 // This was the previous process that showed UI to the user. 16668 // We want to try to keep it around more aggressively, to give 16669 // a good experience around switching between two apps. 16670 adj = ProcessList.PREVIOUS_APP_ADJ; 16671 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16672 app.cached = false; 16673 app.adjType = "previous"; 16674 } 16675 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16676 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16677 } 16678 } 16679 16680 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16681 + " reason=" + app.adjType); 16682 16683 // By default, we use the computed adjustment. It may be changed if 16684 // there are applications dependent on our services or providers, but 16685 // this gives us a baseline and makes sure we don't get into an 16686 // infinite recursion. 16687 app.adjSeq = mAdjSeq; 16688 app.curRawAdj = adj; 16689 app.hasStartedServices = false; 16690 16691 if (mBackupTarget != null && app == mBackupTarget.app) { 16692 // If possible we want to avoid killing apps while they're being backed up 16693 if (adj > ProcessList.BACKUP_APP_ADJ) { 16694 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16695 adj = ProcessList.BACKUP_APP_ADJ; 16696 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16697 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16698 } 16699 app.adjType = "backup"; 16700 app.cached = false; 16701 } 16702 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16703 procState = ActivityManager.PROCESS_STATE_BACKUP; 16704 } 16705 } 16706 16707 boolean mayBeTop = false; 16708 16709 for (int is = app.services.size()-1; 16710 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16711 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16712 || procState > ActivityManager.PROCESS_STATE_TOP); 16713 is--) { 16714 ServiceRecord s = app.services.valueAt(is); 16715 if (s.startRequested) { 16716 app.hasStartedServices = true; 16717 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16718 procState = ActivityManager.PROCESS_STATE_SERVICE; 16719 } 16720 if (app.hasShownUi && app != mHomeProcess) { 16721 // If this process has shown some UI, let it immediately 16722 // go to the LRU list because it may be pretty heavy with 16723 // UI stuff. We'll tag it with a label just to help 16724 // debug and understand what is going on. 16725 if (adj > ProcessList.SERVICE_ADJ) { 16726 app.adjType = "cch-started-ui-services"; 16727 } 16728 } else { 16729 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16730 // This service has seen some activity within 16731 // recent memory, so we will keep its process ahead 16732 // of the background processes. 16733 if (adj > ProcessList.SERVICE_ADJ) { 16734 adj = ProcessList.SERVICE_ADJ; 16735 app.adjType = "started-services"; 16736 app.cached = false; 16737 } 16738 } 16739 // If we have let the service slide into the background 16740 // state, still have some text describing what it is doing 16741 // even though the service no longer has an impact. 16742 if (adj > ProcessList.SERVICE_ADJ) { 16743 app.adjType = "cch-started-services"; 16744 } 16745 } 16746 } 16747 for (int conni = s.connections.size()-1; 16748 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16749 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16750 || procState > ActivityManager.PROCESS_STATE_TOP); 16751 conni--) { 16752 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16753 for (int i = 0; 16754 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16755 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16756 || procState > ActivityManager.PROCESS_STATE_TOP); 16757 i++) { 16758 // XXX should compute this based on the max of 16759 // all connected clients. 16760 ConnectionRecord cr = clist.get(i); 16761 if (cr.binding.client == app) { 16762 // Binding to ourself is not interesting. 16763 continue; 16764 } 16765 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16766 ProcessRecord client = cr.binding.client; 16767 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16768 TOP_APP, doingAll, now); 16769 int clientProcState = client.curProcState; 16770 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16771 // If the other app is cached for any reason, for purposes here 16772 // we are going to consider it empty. The specific cached state 16773 // doesn't propagate except under certain conditions. 16774 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16775 } 16776 String adjType = null; 16777 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16778 // Not doing bind OOM management, so treat 16779 // this guy more like a started service. 16780 if (app.hasShownUi && app != mHomeProcess) { 16781 // If this process has shown some UI, let it immediately 16782 // go to the LRU list because it may be pretty heavy with 16783 // UI stuff. We'll tag it with a label just to help 16784 // debug and understand what is going on. 16785 if (adj > clientAdj) { 16786 adjType = "cch-bound-ui-services"; 16787 } 16788 app.cached = false; 16789 clientAdj = adj; 16790 clientProcState = procState; 16791 } else { 16792 if (now >= (s.lastActivity 16793 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16794 // This service has not seen activity within 16795 // recent memory, so allow it to drop to the 16796 // LRU list if there is no other reason to keep 16797 // it around. We'll also tag it with a label just 16798 // to help debug and undertand what is going on. 16799 if (adj > clientAdj) { 16800 adjType = "cch-bound-services"; 16801 } 16802 clientAdj = adj; 16803 } 16804 } 16805 } 16806 if (adj > clientAdj) { 16807 // If this process has recently shown UI, and 16808 // the process that is binding to it is less 16809 // important than being visible, then we don't 16810 // care about the binding as much as we care 16811 // about letting this process get into the LRU 16812 // list to be killed and restarted if needed for 16813 // memory. 16814 if (app.hasShownUi && app != mHomeProcess 16815 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16816 adjType = "cch-bound-ui-services"; 16817 } else { 16818 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16819 |Context.BIND_IMPORTANT)) != 0) { 16820 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 16821 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 16822 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16823 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16824 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16825 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16826 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16827 adj = clientAdj; 16828 } else { 16829 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16830 adj = ProcessList.VISIBLE_APP_ADJ; 16831 } 16832 } 16833 if (!client.cached) { 16834 app.cached = false; 16835 } 16836 adjType = "service"; 16837 } 16838 } 16839 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16840 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16841 schedGroup = Process.THREAD_GROUP_DEFAULT; 16842 } 16843 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16844 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16845 // Special handling of clients who are in the top state. 16846 // We *may* want to consider this process to be in the 16847 // top state as well, but only if there is not another 16848 // reason for it to be running. Being on the top is a 16849 // special state, meaning you are specifically running 16850 // for the current top app. If the process is already 16851 // running in the background for some other reason, it 16852 // is more important to continue considering it to be 16853 // in the background state. 16854 mayBeTop = true; 16855 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16856 } else { 16857 // Special handling for above-top states (persistent 16858 // processes). These should not bring the current process 16859 // into the top state, since they are not on top. Instead 16860 // give them the best state after that. 16861 clientProcState = 16862 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16863 } 16864 } 16865 } else { 16866 if (clientProcState < 16867 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16868 clientProcState = 16869 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16870 } 16871 } 16872 if (procState > clientProcState) { 16873 procState = clientProcState; 16874 } 16875 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16876 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16877 app.pendingUiClean = true; 16878 } 16879 if (adjType != null) { 16880 app.adjType = adjType; 16881 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16882 .REASON_SERVICE_IN_USE; 16883 app.adjSource = cr.binding.client; 16884 app.adjSourceProcState = clientProcState; 16885 app.adjTarget = s.name; 16886 } 16887 } 16888 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16889 app.treatLikeActivity = true; 16890 } 16891 final ActivityRecord a = cr.activity; 16892 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16893 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16894 (a.visible || a.state == ActivityState.RESUMED 16895 || a.state == ActivityState.PAUSING)) { 16896 adj = ProcessList.FOREGROUND_APP_ADJ; 16897 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16898 schedGroup = Process.THREAD_GROUP_DEFAULT; 16899 } 16900 app.cached = false; 16901 app.adjType = "service"; 16902 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16903 .REASON_SERVICE_IN_USE; 16904 app.adjSource = a; 16905 app.adjSourceProcState = procState; 16906 app.adjTarget = s.name; 16907 } 16908 } 16909 } 16910 } 16911 } 16912 16913 for (int provi = app.pubProviders.size()-1; 16914 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16915 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16916 || procState > ActivityManager.PROCESS_STATE_TOP); 16917 provi--) { 16918 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16919 for (int i = cpr.connections.size()-1; 16920 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16921 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16922 || procState > ActivityManager.PROCESS_STATE_TOP); 16923 i--) { 16924 ContentProviderConnection conn = cpr.connections.get(i); 16925 ProcessRecord client = conn.client; 16926 if (client == app) { 16927 // Being our own client is not interesting. 16928 continue; 16929 } 16930 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16931 int clientProcState = client.curProcState; 16932 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16933 // If the other app is cached for any reason, for purposes here 16934 // we are going to consider it empty. 16935 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16936 } 16937 if (adj > clientAdj) { 16938 if (app.hasShownUi && app != mHomeProcess 16939 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16940 app.adjType = "cch-ui-provider"; 16941 } else { 16942 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16943 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16944 app.adjType = "provider"; 16945 } 16946 app.cached &= client.cached; 16947 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16948 .REASON_PROVIDER_IN_USE; 16949 app.adjSource = client; 16950 app.adjSourceProcState = clientProcState; 16951 app.adjTarget = cpr.name; 16952 } 16953 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16954 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16955 // Special handling of clients who are in the top state. 16956 // We *may* want to consider this process to be in the 16957 // top state as well, but only if there is not another 16958 // reason for it to be running. Being on the top is a 16959 // special state, meaning you are specifically running 16960 // for the current top app. If the process is already 16961 // running in the background for some other reason, it 16962 // is more important to continue considering it to be 16963 // in the background state. 16964 mayBeTop = true; 16965 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16966 } else { 16967 // Special handling for above-top states (persistent 16968 // processes). These should not bring the current process 16969 // into the top state, since they are not on top. Instead 16970 // give them the best state after that. 16971 clientProcState = 16972 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16973 } 16974 } 16975 if (procState > clientProcState) { 16976 procState = clientProcState; 16977 } 16978 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16979 schedGroup = Process.THREAD_GROUP_DEFAULT; 16980 } 16981 } 16982 // If the provider has external (non-framework) process 16983 // dependencies, ensure that its adjustment is at least 16984 // FOREGROUND_APP_ADJ. 16985 if (cpr.hasExternalProcessHandles()) { 16986 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16987 adj = ProcessList.FOREGROUND_APP_ADJ; 16988 schedGroup = Process.THREAD_GROUP_DEFAULT; 16989 app.cached = false; 16990 app.adjType = "provider"; 16991 app.adjTarget = cpr.name; 16992 } 16993 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16994 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16995 } 16996 } 16997 } 16998 16999 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 17000 // A client of one of our services or providers is in the top state. We 17001 // *may* want to be in the top state, but not if we are already running in 17002 // the background for some other reason. For the decision here, we are going 17003 // to pick out a few specific states that we want to remain in when a client 17004 // is top (states that tend to be longer-term) and otherwise allow it to go 17005 // to the top state. 17006 switch (procState) { 17007 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 17008 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 17009 case ActivityManager.PROCESS_STATE_SERVICE: 17010 // These all are longer-term states, so pull them up to the top 17011 // of the background states, but not all the way to the top state. 17012 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 17013 break; 17014 default: 17015 // Otherwise, top is a better choice, so take it. 17016 procState = ActivityManager.PROCESS_STATE_TOP; 17017 break; 17018 } 17019 } 17020 17021 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 17022 if (app.hasClientActivities) { 17023 // This is a cached process, but with client activities. Mark it so. 17024 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 17025 app.adjType = "cch-client-act"; 17026 } else if (app.treatLikeActivity) { 17027 // This is a cached process, but somebody wants us to treat it like it has 17028 // an activity, okay! 17029 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 17030 app.adjType = "cch-as-act"; 17031 } 17032 } 17033 17034 if (adj == ProcessList.SERVICE_ADJ) { 17035 if (doingAll) { 17036 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 17037 mNewNumServiceProcs++; 17038 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 17039 if (!app.serviceb) { 17040 // This service isn't far enough down on the LRU list to 17041 // normally be a B service, but if we are low on RAM and it 17042 // is large we want to force it down since we would prefer to 17043 // keep launcher over it. 17044 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 17045 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 17046 app.serviceHighRam = true; 17047 app.serviceb = true; 17048 //Slog.i(TAG, "ADJ " + app + " high ram!"); 17049 } else { 17050 mNewNumAServiceProcs++; 17051 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 17052 } 17053 } else { 17054 app.serviceHighRam = false; 17055 } 17056 } 17057 if (app.serviceb) { 17058 adj = ProcessList.SERVICE_B_ADJ; 17059 } 17060 } 17061 17062 app.curRawAdj = adj; 17063 17064 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 17065 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 17066 if (adj > app.maxAdj) { 17067 adj = app.maxAdj; 17068 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 17069 schedGroup = Process.THREAD_GROUP_DEFAULT; 17070 } 17071 } 17072 17073 // Do final modification to adj. Everything we do between here and applying 17074 // the final setAdj must be done in this function, because we will also use 17075 // it when computing the final cached adj later. Note that we don't need to 17076 // worry about this for max adj above, since max adj will always be used to 17077 // keep it out of the cached vaues. 17078 app.curAdj = app.modifyRawOomAdj(adj); 17079 app.curSchedGroup = schedGroup; 17080 app.curProcState = procState; 17081 app.foregroundActivities = foregroundActivities; 17082 17083 return app.curRawAdj; 17084 } 17085 17086 /** 17087 * Schedule PSS collection of a process. 17088 */ 17089 void requestPssLocked(ProcessRecord proc, int procState) { 17090 if (mPendingPssProcesses.contains(proc)) { 17091 return; 17092 } 17093 if (mPendingPssProcesses.size() == 0) { 17094 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17095 } 17096 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 17097 proc.pssProcState = procState; 17098 mPendingPssProcesses.add(proc); 17099 } 17100 17101 /** 17102 * Schedule PSS collection of all processes. 17103 */ 17104 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 17105 if (!always) { 17106 if (now < (mLastFullPssTime + 17107 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 17108 return; 17109 } 17110 } 17111 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 17112 mLastFullPssTime = now; 17113 mFullPssPending = true; 17114 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 17115 mPendingPssProcesses.clear(); 17116 for (int i=mLruProcesses.size()-1; i>=0; i--) { 17117 ProcessRecord app = mLruProcesses.get(i); 17118 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 17119 app.pssProcState = app.setProcState; 17120 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17121 isSleeping(), now); 17122 mPendingPssProcesses.add(app); 17123 } 17124 } 17125 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 17126 } 17127 17128 /** 17129 * Ask a given process to GC right now. 17130 */ 17131 final void performAppGcLocked(ProcessRecord app) { 17132 try { 17133 app.lastRequestedGc = SystemClock.uptimeMillis(); 17134 if (app.thread != null) { 17135 if (app.reportLowMemory) { 17136 app.reportLowMemory = false; 17137 app.thread.scheduleLowMemory(); 17138 } else { 17139 app.thread.processInBackground(); 17140 } 17141 } 17142 } catch (Exception e) { 17143 // whatever. 17144 } 17145 } 17146 17147 /** 17148 * Returns true if things are idle enough to perform GCs. 17149 */ 17150 private final boolean canGcNowLocked() { 17151 boolean processingBroadcasts = false; 17152 for (BroadcastQueue q : mBroadcastQueues) { 17153 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 17154 processingBroadcasts = true; 17155 } 17156 } 17157 return !processingBroadcasts 17158 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 17159 } 17160 17161 /** 17162 * Perform GCs on all processes that are waiting for it, but only 17163 * if things are idle. 17164 */ 17165 final void performAppGcsLocked() { 17166 final int N = mProcessesToGc.size(); 17167 if (N <= 0) { 17168 return; 17169 } 17170 if (canGcNowLocked()) { 17171 while (mProcessesToGc.size() > 0) { 17172 ProcessRecord proc = mProcessesToGc.remove(0); 17173 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17174 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17175 <= SystemClock.uptimeMillis()) { 17176 // To avoid spamming the system, we will GC processes one 17177 // at a time, waiting a few seconds between each. 17178 performAppGcLocked(proc); 17179 scheduleAppGcsLocked(); 17180 return; 17181 } else { 17182 // It hasn't been long enough since we last GCed this 17183 // process... put it in the list to wait for its time. 17184 addProcessToGcListLocked(proc); 17185 break; 17186 } 17187 } 17188 } 17189 17190 scheduleAppGcsLocked(); 17191 } 17192 } 17193 17194 /** 17195 * If all looks good, perform GCs on all processes waiting for them. 17196 */ 17197 final void performAppGcsIfAppropriateLocked() { 17198 if (canGcNowLocked()) { 17199 performAppGcsLocked(); 17200 return; 17201 } 17202 // Still not idle, wait some more. 17203 scheduleAppGcsLocked(); 17204 } 17205 17206 /** 17207 * Schedule the execution of all pending app GCs. 17208 */ 17209 final void scheduleAppGcsLocked() { 17210 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17211 17212 if (mProcessesToGc.size() > 0) { 17213 // Schedule a GC for the time to the next process. 17214 ProcessRecord proc = mProcessesToGc.get(0); 17215 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17216 17217 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17218 long now = SystemClock.uptimeMillis(); 17219 if (when < (now+GC_TIMEOUT)) { 17220 when = now + GC_TIMEOUT; 17221 } 17222 mHandler.sendMessageAtTime(msg, when); 17223 } 17224 } 17225 17226 /** 17227 * Add a process to the array of processes waiting to be GCed. Keeps the 17228 * list in sorted order by the last GC time. The process can't already be 17229 * on the list. 17230 */ 17231 final void addProcessToGcListLocked(ProcessRecord proc) { 17232 boolean added = false; 17233 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17234 if (mProcessesToGc.get(i).lastRequestedGc < 17235 proc.lastRequestedGc) { 17236 added = true; 17237 mProcessesToGc.add(i+1, proc); 17238 break; 17239 } 17240 } 17241 if (!added) { 17242 mProcessesToGc.add(0, proc); 17243 } 17244 } 17245 17246 /** 17247 * Set up to ask a process to GC itself. This will either do it 17248 * immediately, or put it on the list of processes to gc the next 17249 * time things are idle. 17250 */ 17251 final void scheduleAppGcLocked(ProcessRecord app) { 17252 long now = SystemClock.uptimeMillis(); 17253 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17254 return; 17255 } 17256 if (!mProcessesToGc.contains(app)) { 17257 addProcessToGcListLocked(app); 17258 scheduleAppGcsLocked(); 17259 } 17260 } 17261 17262 final void checkExcessivePowerUsageLocked(boolean doKills) { 17263 updateCpuStatsNow(); 17264 17265 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17266 boolean doWakeKills = doKills; 17267 boolean doCpuKills = doKills; 17268 if (mLastPowerCheckRealtime == 0) { 17269 doWakeKills = false; 17270 } 17271 if (mLastPowerCheckUptime == 0) { 17272 doCpuKills = false; 17273 } 17274 if (stats.isScreenOn()) { 17275 doWakeKills = false; 17276 } 17277 final long curRealtime = SystemClock.elapsedRealtime(); 17278 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17279 final long curUptime = SystemClock.uptimeMillis(); 17280 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17281 mLastPowerCheckRealtime = curRealtime; 17282 mLastPowerCheckUptime = curUptime; 17283 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17284 doWakeKills = false; 17285 } 17286 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17287 doCpuKills = false; 17288 } 17289 int i = mLruProcesses.size(); 17290 while (i > 0) { 17291 i--; 17292 ProcessRecord app = mLruProcesses.get(i); 17293 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17294 long wtime; 17295 synchronized (stats) { 17296 wtime = stats.getProcessWakeTime(app.info.uid, 17297 app.pid, curRealtime); 17298 } 17299 long wtimeUsed = wtime - app.lastWakeTime; 17300 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17301 if (DEBUG_POWER) { 17302 StringBuilder sb = new StringBuilder(128); 17303 sb.append("Wake for "); 17304 app.toShortString(sb); 17305 sb.append(": over "); 17306 TimeUtils.formatDuration(realtimeSince, sb); 17307 sb.append(" used "); 17308 TimeUtils.formatDuration(wtimeUsed, sb); 17309 sb.append(" ("); 17310 sb.append((wtimeUsed*100)/realtimeSince); 17311 sb.append("%)"); 17312 Slog.i(TAG, sb.toString()); 17313 sb.setLength(0); 17314 sb.append("CPU for "); 17315 app.toShortString(sb); 17316 sb.append(": over "); 17317 TimeUtils.formatDuration(uptimeSince, sb); 17318 sb.append(" used "); 17319 TimeUtils.formatDuration(cputimeUsed, sb); 17320 sb.append(" ("); 17321 sb.append((cputimeUsed*100)/uptimeSince); 17322 sb.append("%)"); 17323 Slog.i(TAG, sb.toString()); 17324 } 17325 // If a process has held a wake lock for more 17326 // than 50% of the time during this period, 17327 // that sounds bad. Kill! 17328 if (doWakeKills && realtimeSince > 0 17329 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17330 synchronized (stats) { 17331 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17332 realtimeSince, wtimeUsed); 17333 } 17334 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17335 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17336 } else if (doCpuKills && uptimeSince > 0 17337 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17338 synchronized (stats) { 17339 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17340 uptimeSince, cputimeUsed); 17341 } 17342 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17343 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17344 } else { 17345 app.lastWakeTime = wtime; 17346 app.lastCpuTime = app.curCpuTime; 17347 } 17348 } 17349 } 17350 } 17351 17352 private final boolean applyOomAdjLocked(ProcessRecord app, 17353 ProcessRecord TOP_APP, boolean doingAll, long now) { 17354 boolean success = true; 17355 17356 if (app.curRawAdj != app.setRawAdj) { 17357 app.setRawAdj = app.curRawAdj; 17358 } 17359 17360 int changes = 0; 17361 17362 if (app.curAdj != app.setAdj) { 17363 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17364 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17365 TAG, "Set " + app.pid + " " + app.processName + 17366 " adj " + app.curAdj + ": " + app.adjType); 17367 app.setAdj = app.curAdj; 17368 } 17369 17370 if (app.setSchedGroup != app.curSchedGroup) { 17371 app.setSchedGroup = app.curSchedGroup; 17372 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17373 "Setting process group of " + app.processName 17374 + " to " + app.curSchedGroup); 17375 if (app.waitingToKill != null && 17376 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17377 app.kill(app.waitingToKill, true); 17378 success = false; 17379 } else { 17380 if (true) { 17381 long oldId = Binder.clearCallingIdentity(); 17382 try { 17383 Process.setProcessGroup(app.pid, app.curSchedGroup); 17384 } catch (Exception e) { 17385 Slog.w(TAG, "Failed setting process group of " + app.pid 17386 + " to " + app.curSchedGroup); 17387 e.printStackTrace(); 17388 } finally { 17389 Binder.restoreCallingIdentity(oldId); 17390 } 17391 } else { 17392 if (app.thread != null) { 17393 try { 17394 app.thread.setSchedulingGroup(app.curSchedGroup); 17395 } catch (RemoteException e) { 17396 } 17397 } 17398 } 17399 Process.setSwappiness(app.pid, 17400 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17401 } 17402 } 17403 if (app.repForegroundActivities != app.foregroundActivities) { 17404 app.repForegroundActivities = app.foregroundActivities; 17405 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17406 } 17407 if (app.repProcState != app.curProcState) { 17408 app.repProcState = app.curProcState; 17409 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17410 if (app.thread != null) { 17411 try { 17412 if (false) { 17413 //RuntimeException h = new RuntimeException("here"); 17414 Slog.i(TAG, "Sending new process state " + app.repProcState 17415 + " to " + app /*, h*/); 17416 } 17417 app.thread.setProcessState(app.repProcState); 17418 } catch (RemoteException e) { 17419 } 17420 } 17421 } 17422 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17423 app.setProcState)) { 17424 app.lastStateTime = now; 17425 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17426 isSleeping(), now); 17427 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17428 + ProcessList.makeProcStateString(app.setProcState) + " to " 17429 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17430 + (app.nextPssTime-now) + ": " + app); 17431 } else { 17432 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17433 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17434 requestPssLocked(app, app.setProcState); 17435 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17436 isSleeping(), now); 17437 } else if (false && DEBUG_PSS) { 17438 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17439 } 17440 } 17441 if (app.setProcState != app.curProcState) { 17442 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17443 "Proc state change of " + app.processName 17444 + " to " + app.curProcState); 17445 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17446 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17447 if (setImportant && !curImportant) { 17448 // This app is no longer something we consider important enough to allow to 17449 // use arbitrary amounts of battery power. Note 17450 // its current wake lock time to later know to kill it if 17451 // it is not behaving well. 17452 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17453 synchronized (stats) { 17454 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17455 app.pid, SystemClock.elapsedRealtime()); 17456 } 17457 app.lastCpuTime = app.curCpuTime; 17458 17459 } 17460 app.setProcState = app.curProcState; 17461 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17462 app.notCachedSinceIdle = false; 17463 } 17464 if (!doingAll) { 17465 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17466 } else { 17467 app.procStateChanged = true; 17468 } 17469 } 17470 17471 if (changes != 0) { 17472 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17473 int i = mPendingProcessChanges.size()-1; 17474 ProcessChangeItem item = null; 17475 while (i >= 0) { 17476 item = mPendingProcessChanges.get(i); 17477 if (item.pid == app.pid) { 17478 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17479 break; 17480 } 17481 i--; 17482 } 17483 if (i < 0) { 17484 // No existing item in pending changes; need a new one. 17485 final int NA = mAvailProcessChanges.size(); 17486 if (NA > 0) { 17487 item = mAvailProcessChanges.remove(NA-1); 17488 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17489 } else { 17490 item = new ProcessChangeItem(); 17491 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17492 } 17493 item.changes = 0; 17494 item.pid = app.pid; 17495 item.uid = app.info.uid; 17496 if (mPendingProcessChanges.size() == 0) { 17497 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17498 "*** Enqueueing dispatch processes changed!"); 17499 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17500 } 17501 mPendingProcessChanges.add(item); 17502 } 17503 item.changes |= changes; 17504 item.processState = app.repProcState; 17505 item.foregroundActivities = app.repForegroundActivities; 17506 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17507 + Integer.toHexString(System.identityHashCode(item)) 17508 + " " + app.toShortString() + ": changes=" + item.changes 17509 + " procState=" + item.processState 17510 + " foreground=" + item.foregroundActivities 17511 + " type=" + app.adjType + " source=" + app.adjSource 17512 + " target=" + app.adjTarget); 17513 } 17514 17515 return success; 17516 } 17517 17518 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17519 if (proc.thread != null) { 17520 if (proc.baseProcessTracker != null) { 17521 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17522 } 17523 if (proc.repProcState >= 0) { 17524 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17525 proc.repProcState); 17526 } 17527 } 17528 } 17529 17530 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17531 ProcessRecord TOP_APP, boolean doingAll, long now) { 17532 if (app.thread == null) { 17533 return false; 17534 } 17535 17536 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17537 17538 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17539 } 17540 17541 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17542 boolean oomAdj) { 17543 if (isForeground != proc.foregroundServices) { 17544 proc.foregroundServices = isForeground; 17545 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17546 proc.info.uid); 17547 if (isForeground) { 17548 if (curProcs == null) { 17549 curProcs = new ArrayList<ProcessRecord>(); 17550 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17551 } 17552 if (!curProcs.contains(proc)) { 17553 curProcs.add(proc); 17554 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17555 proc.info.packageName, proc.info.uid); 17556 } 17557 } else { 17558 if (curProcs != null) { 17559 if (curProcs.remove(proc)) { 17560 mBatteryStatsService.noteEvent( 17561 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17562 proc.info.packageName, proc.info.uid); 17563 if (curProcs.size() <= 0) { 17564 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17565 } 17566 } 17567 } 17568 } 17569 if (oomAdj) { 17570 updateOomAdjLocked(); 17571 } 17572 } 17573 } 17574 17575 private final ActivityRecord resumedAppLocked() { 17576 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17577 String pkg; 17578 int uid; 17579 if (act != null) { 17580 pkg = act.packageName; 17581 uid = act.info.applicationInfo.uid; 17582 } else { 17583 pkg = null; 17584 uid = -1; 17585 } 17586 // Has the UID or resumed package name changed? 17587 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17588 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17589 if (mCurResumedPackage != null) { 17590 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17591 mCurResumedPackage, mCurResumedUid); 17592 } 17593 mCurResumedPackage = pkg; 17594 mCurResumedUid = uid; 17595 if (mCurResumedPackage != null) { 17596 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17597 mCurResumedPackage, mCurResumedUid); 17598 } 17599 } 17600 return act; 17601 } 17602 17603 final boolean updateOomAdjLocked(ProcessRecord app) { 17604 final ActivityRecord TOP_ACT = resumedAppLocked(); 17605 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17606 final boolean wasCached = app.cached; 17607 17608 mAdjSeq++; 17609 17610 // This is the desired cached adjusment we want to tell it to use. 17611 // If our app is currently cached, we know it, and that is it. Otherwise, 17612 // we don't know it yet, and it needs to now be cached we will then 17613 // need to do a complete oom adj. 17614 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17615 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17616 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17617 SystemClock.uptimeMillis()); 17618 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17619 // Changed to/from cached state, so apps after it in the LRU 17620 // list may also be changed. 17621 updateOomAdjLocked(); 17622 } 17623 return success; 17624 } 17625 17626 final void updateOomAdjLocked() { 17627 final ActivityRecord TOP_ACT = resumedAppLocked(); 17628 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17629 final long now = SystemClock.uptimeMillis(); 17630 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17631 final int N = mLruProcesses.size(); 17632 17633 if (false) { 17634 RuntimeException e = new RuntimeException(); 17635 e.fillInStackTrace(); 17636 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17637 } 17638 17639 mAdjSeq++; 17640 mNewNumServiceProcs = 0; 17641 mNewNumAServiceProcs = 0; 17642 17643 final int emptyProcessLimit; 17644 final int cachedProcessLimit; 17645 if (mProcessLimit <= 0) { 17646 emptyProcessLimit = cachedProcessLimit = 0; 17647 } else if (mProcessLimit == 1) { 17648 emptyProcessLimit = 1; 17649 cachedProcessLimit = 0; 17650 } else { 17651 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17652 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17653 } 17654 17655 // Let's determine how many processes we have running vs. 17656 // how many slots we have for background processes; we may want 17657 // to put multiple processes in a slot of there are enough of 17658 // them. 17659 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17660 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17661 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17662 if (numEmptyProcs > cachedProcessLimit) { 17663 // If there are more empty processes than our limit on cached 17664 // processes, then use the cached process limit for the factor. 17665 // This ensures that the really old empty processes get pushed 17666 // down to the bottom, so if we are running low on memory we will 17667 // have a better chance at keeping around more cached processes 17668 // instead of a gazillion empty processes. 17669 numEmptyProcs = cachedProcessLimit; 17670 } 17671 int emptyFactor = numEmptyProcs/numSlots; 17672 if (emptyFactor < 1) emptyFactor = 1; 17673 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17674 if (cachedFactor < 1) cachedFactor = 1; 17675 int stepCached = 0; 17676 int stepEmpty = 0; 17677 int numCached = 0; 17678 int numEmpty = 0; 17679 int numTrimming = 0; 17680 17681 mNumNonCachedProcs = 0; 17682 mNumCachedHiddenProcs = 0; 17683 17684 // First update the OOM adjustment for each of the 17685 // application processes based on their current state. 17686 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17687 int nextCachedAdj = curCachedAdj+1; 17688 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17689 int nextEmptyAdj = curEmptyAdj+2; 17690 for (int i=N-1; i>=0; i--) { 17691 ProcessRecord app = mLruProcesses.get(i); 17692 if (!app.killedByAm && app.thread != null) { 17693 app.procStateChanged = false; 17694 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17695 17696 // If we haven't yet assigned the final cached adj 17697 // to the process, do that now. 17698 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17699 switch (app.curProcState) { 17700 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17701 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17702 // This process is a cached process holding activities... 17703 // assign it the next cached value for that type, and then 17704 // step that cached level. 17705 app.curRawAdj = curCachedAdj; 17706 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17707 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17708 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17709 + ")"); 17710 if (curCachedAdj != nextCachedAdj) { 17711 stepCached++; 17712 if (stepCached >= cachedFactor) { 17713 stepCached = 0; 17714 curCachedAdj = nextCachedAdj; 17715 nextCachedAdj += 2; 17716 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17717 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17718 } 17719 } 17720 } 17721 break; 17722 default: 17723 // For everything else, assign next empty cached process 17724 // level and bump that up. Note that this means that 17725 // long-running services that have dropped down to the 17726 // cached level will be treated as empty (since their process 17727 // state is still as a service), which is what we want. 17728 app.curRawAdj = curEmptyAdj; 17729 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17730 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17731 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17732 + ")"); 17733 if (curEmptyAdj != nextEmptyAdj) { 17734 stepEmpty++; 17735 if (stepEmpty >= emptyFactor) { 17736 stepEmpty = 0; 17737 curEmptyAdj = nextEmptyAdj; 17738 nextEmptyAdj += 2; 17739 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17740 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17741 } 17742 } 17743 } 17744 break; 17745 } 17746 } 17747 17748 applyOomAdjLocked(app, TOP_APP, true, now); 17749 17750 // Count the number of process types. 17751 switch (app.curProcState) { 17752 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17753 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17754 mNumCachedHiddenProcs++; 17755 numCached++; 17756 if (numCached > cachedProcessLimit) { 17757 app.kill("cached #" + numCached, true); 17758 } 17759 break; 17760 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17761 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17762 && app.lastActivityTime < oldTime) { 17763 app.kill("empty for " 17764 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17765 / 1000) + "s", true); 17766 } else { 17767 numEmpty++; 17768 if (numEmpty > emptyProcessLimit) { 17769 app.kill("empty #" + numEmpty, true); 17770 } 17771 } 17772 break; 17773 default: 17774 mNumNonCachedProcs++; 17775 break; 17776 } 17777 17778 if (app.isolated && app.services.size() <= 0) { 17779 // If this is an isolated process, and there are no 17780 // services running in it, then the process is no longer 17781 // needed. We agressively kill these because we can by 17782 // definition not re-use the same process again, and it is 17783 // good to avoid having whatever code was running in them 17784 // left sitting around after no longer needed. 17785 app.kill("isolated not needed", true); 17786 } 17787 17788 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17789 && !app.killedByAm) { 17790 numTrimming++; 17791 } 17792 } 17793 } 17794 17795 mNumServiceProcs = mNewNumServiceProcs; 17796 17797 // Now determine the memory trimming level of background processes. 17798 // Unfortunately we need to start at the back of the list to do this 17799 // properly. We only do this if the number of background apps we 17800 // are managing to keep around is less than half the maximum we desire; 17801 // if we are keeping a good number around, we'll let them use whatever 17802 // memory they want. 17803 final int numCachedAndEmpty = numCached + numEmpty; 17804 int memFactor; 17805 if (numCached <= ProcessList.TRIM_CACHED_APPS 17806 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17807 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17808 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17809 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17810 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17811 } else { 17812 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17813 } 17814 } else { 17815 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17816 } 17817 // We always allow the memory level to go up (better). We only allow it to go 17818 // down if we are in a state where that is allowed, *and* the total number of processes 17819 // has gone down since last time. 17820 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17821 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17822 + " last=" + mLastNumProcesses); 17823 if (memFactor > mLastMemoryLevel) { 17824 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17825 memFactor = mLastMemoryLevel; 17826 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17827 } 17828 } 17829 mLastMemoryLevel = memFactor; 17830 mLastNumProcesses = mLruProcesses.size(); 17831 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17832 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17833 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17834 if (mLowRamStartTime == 0) { 17835 mLowRamStartTime = now; 17836 } 17837 int step = 0; 17838 int fgTrimLevel; 17839 switch (memFactor) { 17840 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17841 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17842 break; 17843 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17844 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17845 break; 17846 default: 17847 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17848 break; 17849 } 17850 int factor = numTrimming/3; 17851 int minFactor = 2; 17852 if (mHomeProcess != null) minFactor++; 17853 if (mPreviousProcess != null) minFactor++; 17854 if (factor < minFactor) factor = minFactor; 17855 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17856 for (int i=N-1; i>=0; i--) { 17857 ProcessRecord app = mLruProcesses.get(i); 17858 if (allChanged || app.procStateChanged) { 17859 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17860 app.procStateChanged = false; 17861 } 17862 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17863 && !app.killedByAm) { 17864 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17865 try { 17866 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17867 "Trimming memory of " + app.processName 17868 + " to " + curLevel); 17869 app.thread.scheduleTrimMemory(curLevel); 17870 } catch (RemoteException e) { 17871 } 17872 if (false) { 17873 // For now we won't do this; our memory trimming seems 17874 // to be good enough at this point that destroying 17875 // activities causes more harm than good. 17876 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17877 && app != mHomeProcess && app != mPreviousProcess) { 17878 // Need to do this on its own message because the stack may not 17879 // be in a consistent state at this point. 17880 // For these apps we will also finish their activities 17881 // to help them free memory. 17882 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17883 } 17884 } 17885 } 17886 app.trimMemoryLevel = curLevel; 17887 step++; 17888 if (step >= factor) { 17889 step = 0; 17890 switch (curLevel) { 17891 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17892 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17893 break; 17894 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17895 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17896 break; 17897 } 17898 } 17899 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17900 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17901 && app.thread != null) { 17902 try { 17903 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17904 "Trimming memory of heavy-weight " + app.processName 17905 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17906 app.thread.scheduleTrimMemory( 17907 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17908 } catch (RemoteException e) { 17909 } 17910 } 17911 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17912 } else { 17913 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17914 || app.systemNoUi) && app.pendingUiClean) { 17915 // If this application is now in the background and it 17916 // had done UI, then give it the special trim level to 17917 // have it free UI resources. 17918 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17919 if (app.trimMemoryLevel < level && app.thread != null) { 17920 try { 17921 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17922 "Trimming memory of bg-ui " + app.processName 17923 + " to " + level); 17924 app.thread.scheduleTrimMemory(level); 17925 } catch (RemoteException e) { 17926 } 17927 } 17928 app.pendingUiClean = false; 17929 } 17930 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17931 try { 17932 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17933 "Trimming memory of fg " + app.processName 17934 + " to " + fgTrimLevel); 17935 app.thread.scheduleTrimMemory(fgTrimLevel); 17936 } catch (RemoteException e) { 17937 } 17938 } 17939 app.trimMemoryLevel = fgTrimLevel; 17940 } 17941 } 17942 } else { 17943 if (mLowRamStartTime != 0) { 17944 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17945 mLowRamStartTime = 0; 17946 } 17947 for (int i=N-1; i>=0; i--) { 17948 ProcessRecord app = mLruProcesses.get(i); 17949 if (allChanged || app.procStateChanged) { 17950 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17951 app.procStateChanged = false; 17952 } 17953 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17954 || app.systemNoUi) && app.pendingUiClean) { 17955 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17956 && app.thread != null) { 17957 try { 17958 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17959 "Trimming memory of ui hidden " + app.processName 17960 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17961 app.thread.scheduleTrimMemory( 17962 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17963 } catch (RemoteException e) { 17964 } 17965 } 17966 app.pendingUiClean = false; 17967 } 17968 app.trimMemoryLevel = 0; 17969 } 17970 } 17971 17972 if (mAlwaysFinishActivities) { 17973 // Need to do this on its own message because the stack may not 17974 // be in a consistent state at this point. 17975 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17976 } 17977 17978 if (allChanged) { 17979 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17980 } 17981 17982 if (mProcessStats.shouldWriteNowLocked(now)) { 17983 mHandler.post(new Runnable() { 17984 @Override public void run() { 17985 synchronized (ActivityManagerService.this) { 17986 mProcessStats.writeStateAsyncLocked(); 17987 } 17988 } 17989 }); 17990 } 17991 17992 if (DEBUG_OOM_ADJ) { 17993 if (false) { 17994 RuntimeException here = new RuntimeException("here"); 17995 here.fillInStackTrace(); 17996 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17997 } else { 17998 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17999 } 18000 } 18001 } 18002 18003 final void trimApplications() { 18004 synchronized (this) { 18005 int i; 18006 18007 // First remove any unused application processes whose package 18008 // has been removed. 18009 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 18010 final ProcessRecord app = mRemovedProcesses.get(i); 18011 if (app.activities.size() == 0 18012 && app.curReceiver == null && app.services.size() == 0) { 18013 Slog.i( 18014 TAG, "Exiting empty application process " 18015 + app.processName + " (" 18016 + (app.thread != null ? app.thread.asBinder() : null) 18017 + ")\n"); 18018 if (app.pid > 0 && app.pid != MY_PID) { 18019 app.kill("empty", false); 18020 } else { 18021 try { 18022 app.thread.scheduleExit(); 18023 } catch (Exception e) { 18024 // Ignore exceptions. 18025 } 18026 } 18027 cleanUpApplicationRecordLocked(app, false, true, -1); 18028 mRemovedProcesses.remove(i); 18029 18030 if (app.persistent) { 18031 addAppLocked(app.info, false, null /* ABI override */); 18032 } 18033 } 18034 } 18035 18036 // Now update the oom adj for all processes. 18037 updateOomAdjLocked(); 18038 } 18039 } 18040 18041 /** This method sends the specified signal to each of the persistent apps */ 18042 public void signalPersistentProcesses(int sig) throws RemoteException { 18043 if (sig != Process.SIGNAL_USR1) { 18044 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 18045 } 18046 18047 synchronized (this) { 18048 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 18049 != PackageManager.PERMISSION_GRANTED) { 18050 throw new SecurityException("Requires permission " 18051 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 18052 } 18053 18054 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18055 ProcessRecord r = mLruProcesses.get(i); 18056 if (r.thread != null && r.persistent) { 18057 Process.sendSignal(r.pid, sig); 18058 } 18059 } 18060 } 18061 } 18062 18063 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 18064 if (proc == null || proc == mProfileProc) { 18065 proc = mProfileProc; 18066 profileType = mProfileType; 18067 clearProfilerLocked(); 18068 } 18069 if (proc == null) { 18070 return; 18071 } 18072 try { 18073 proc.thread.profilerControl(false, null, profileType); 18074 } catch (RemoteException e) { 18075 throw new IllegalStateException("Process disappeared"); 18076 } 18077 } 18078 18079 private void clearProfilerLocked() { 18080 if (mProfileFd != null) { 18081 try { 18082 mProfileFd.close(); 18083 } catch (IOException e) { 18084 } 18085 } 18086 mProfileApp = null; 18087 mProfileProc = null; 18088 mProfileFile = null; 18089 mProfileType = 0; 18090 mAutoStopProfiler = false; 18091 mSamplingInterval = 0; 18092 } 18093 18094 public boolean profileControl(String process, int userId, boolean start, 18095 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 18096 18097 try { 18098 synchronized (this) { 18099 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18100 // its own permission. 18101 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18102 != PackageManager.PERMISSION_GRANTED) { 18103 throw new SecurityException("Requires permission " 18104 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18105 } 18106 18107 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 18108 throw new IllegalArgumentException("null profile info or fd"); 18109 } 18110 18111 ProcessRecord proc = null; 18112 if (process != null) { 18113 proc = findProcessLocked(process, userId, "profileControl"); 18114 } 18115 18116 if (start && (proc == null || proc.thread == null)) { 18117 throw new IllegalArgumentException("Unknown process: " + process); 18118 } 18119 18120 if (start) { 18121 stopProfilerLocked(null, 0); 18122 setProfileApp(proc.info, proc.processName, profilerInfo); 18123 mProfileProc = proc; 18124 mProfileType = profileType; 18125 ParcelFileDescriptor fd = profilerInfo.profileFd; 18126 try { 18127 fd = fd.dup(); 18128 } catch (IOException e) { 18129 fd = null; 18130 } 18131 profilerInfo.profileFd = fd; 18132 proc.thread.profilerControl(start, profilerInfo, profileType); 18133 fd = null; 18134 mProfileFd = null; 18135 } else { 18136 stopProfilerLocked(proc, profileType); 18137 if (profilerInfo != null && profilerInfo.profileFd != null) { 18138 try { 18139 profilerInfo.profileFd.close(); 18140 } catch (IOException e) { 18141 } 18142 } 18143 } 18144 18145 return true; 18146 } 18147 } catch (RemoteException e) { 18148 throw new IllegalStateException("Process disappeared"); 18149 } finally { 18150 if (profilerInfo != null && profilerInfo.profileFd != null) { 18151 try { 18152 profilerInfo.profileFd.close(); 18153 } catch (IOException e) { 18154 } 18155 } 18156 } 18157 } 18158 18159 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 18160 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 18161 userId, true, ALLOW_FULL_ONLY, callName, null); 18162 ProcessRecord proc = null; 18163 try { 18164 int pid = Integer.parseInt(process); 18165 synchronized (mPidsSelfLocked) { 18166 proc = mPidsSelfLocked.get(pid); 18167 } 18168 } catch (NumberFormatException e) { 18169 } 18170 18171 if (proc == null) { 18172 ArrayMap<String, SparseArray<ProcessRecord>> all 18173 = mProcessNames.getMap(); 18174 SparseArray<ProcessRecord> procs = all.get(process); 18175 if (procs != null && procs.size() > 0) { 18176 proc = procs.valueAt(0); 18177 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18178 for (int i=1; i<procs.size(); i++) { 18179 ProcessRecord thisProc = procs.valueAt(i); 18180 if (thisProc.userId == userId) { 18181 proc = thisProc; 18182 break; 18183 } 18184 } 18185 } 18186 } 18187 } 18188 18189 return proc; 18190 } 18191 18192 public boolean dumpHeap(String process, int userId, boolean managed, 18193 String path, ParcelFileDescriptor fd) throws RemoteException { 18194 18195 try { 18196 synchronized (this) { 18197 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18198 // its own permission (same as profileControl). 18199 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18200 != PackageManager.PERMISSION_GRANTED) { 18201 throw new SecurityException("Requires permission " 18202 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18203 } 18204 18205 if (fd == null) { 18206 throw new IllegalArgumentException("null fd"); 18207 } 18208 18209 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18210 if (proc == null || proc.thread == null) { 18211 throw new IllegalArgumentException("Unknown process: " + process); 18212 } 18213 18214 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18215 if (!isDebuggable) { 18216 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18217 throw new SecurityException("Process not debuggable: " + proc); 18218 } 18219 } 18220 18221 proc.thread.dumpHeap(managed, path, fd); 18222 fd = null; 18223 return true; 18224 } 18225 } catch (RemoteException e) { 18226 throw new IllegalStateException("Process disappeared"); 18227 } finally { 18228 if (fd != null) { 18229 try { 18230 fd.close(); 18231 } catch (IOException e) { 18232 } 18233 } 18234 } 18235 } 18236 18237 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18238 public void monitor() { 18239 synchronized (this) { } 18240 } 18241 18242 void onCoreSettingsChange(Bundle settings) { 18243 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18244 ProcessRecord processRecord = mLruProcesses.get(i); 18245 try { 18246 if (processRecord.thread != null) { 18247 processRecord.thread.setCoreSettings(settings); 18248 } 18249 } catch (RemoteException re) { 18250 /* ignore */ 18251 } 18252 } 18253 } 18254 18255 // Multi-user methods 18256 18257 /** 18258 * Start user, if its not already running, but don't bring it to foreground. 18259 */ 18260 @Override 18261 public boolean startUserInBackground(final int userId) { 18262 return startUser(userId, /* foreground */ false); 18263 } 18264 18265 /** 18266 * Start user, if its not already running, and bring it to foreground. 18267 */ 18268 boolean startUserInForeground(final int userId, Dialog dlg) { 18269 boolean result = startUser(userId, /* foreground */ true); 18270 dlg.dismiss(); 18271 return result; 18272 } 18273 18274 /** 18275 * Refreshes the list of users related to the current user when either a 18276 * user switch happens or when a new related user is started in the 18277 * background. 18278 */ 18279 private void updateCurrentProfileIdsLocked() { 18280 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18281 mCurrentUserId, false /* enabledOnly */); 18282 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18283 for (int i = 0; i < currentProfileIds.length; i++) { 18284 currentProfileIds[i] = profiles.get(i).id; 18285 } 18286 mCurrentProfileIds = currentProfileIds; 18287 18288 synchronized (mUserProfileGroupIdsSelfLocked) { 18289 mUserProfileGroupIdsSelfLocked.clear(); 18290 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18291 for (int i = 0; i < users.size(); i++) { 18292 UserInfo user = users.get(i); 18293 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18294 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18295 } 18296 } 18297 } 18298 } 18299 18300 private Set getProfileIdsLocked(int userId) { 18301 Set userIds = new HashSet<Integer>(); 18302 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18303 userId, false /* enabledOnly */); 18304 for (UserInfo user : profiles) { 18305 userIds.add(Integer.valueOf(user.id)); 18306 } 18307 return userIds; 18308 } 18309 18310 @Override 18311 public boolean switchUser(final int userId) { 18312 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18313 String userName; 18314 synchronized (this) { 18315 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18316 if (userInfo == null) { 18317 Slog.w(TAG, "No user info for user #" + userId); 18318 return false; 18319 } 18320 if (userInfo.isManagedProfile()) { 18321 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18322 return false; 18323 } 18324 userName = userInfo.name; 18325 mTargetUserId = userId; 18326 } 18327 mHandler.removeMessages(START_USER_SWITCH_MSG); 18328 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18329 return true; 18330 } 18331 18332 private void showUserSwitchDialog(int userId, String userName) { 18333 // The dialog will show and then initiate the user switch by calling startUserInForeground 18334 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18335 true /* above system */); 18336 d.show(); 18337 } 18338 18339 private boolean startUser(final int userId, final boolean foreground) { 18340 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18341 != PackageManager.PERMISSION_GRANTED) { 18342 String msg = "Permission Denial: switchUser() from pid=" 18343 + Binder.getCallingPid() 18344 + ", uid=" + Binder.getCallingUid() 18345 + " requires " + INTERACT_ACROSS_USERS_FULL; 18346 Slog.w(TAG, msg); 18347 throw new SecurityException(msg); 18348 } 18349 18350 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18351 18352 final long ident = Binder.clearCallingIdentity(); 18353 try { 18354 synchronized (this) { 18355 final int oldUserId = mCurrentUserId; 18356 if (oldUserId == userId) { 18357 return true; 18358 } 18359 18360 mStackSupervisor.setLockTaskModeLocked(null, false); 18361 18362 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18363 if (userInfo == null) { 18364 Slog.w(TAG, "No user info for user #" + userId); 18365 return false; 18366 } 18367 if (foreground && userInfo.isManagedProfile()) { 18368 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18369 return false; 18370 } 18371 18372 if (foreground) { 18373 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18374 R.anim.screen_user_enter); 18375 } 18376 18377 boolean needStart = false; 18378 18379 // If the user we are switching to is not currently started, then 18380 // we need to start it now. 18381 if (mStartedUsers.get(userId) == null) { 18382 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18383 updateStartedUserArrayLocked(); 18384 needStart = true; 18385 } 18386 18387 final Integer userIdInt = Integer.valueOf(userId); 18388 mUserLru.remove(userIdInt); 18389 mUserLru.add(userIdInt); 18390 18391 if (foreground) { 18392 mCurrentUserId = userId; 18393 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18394 updateCurrentProfileIdsLocked(); 18395 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18396 // Once the internal notion of the active user has switched, we lock the device 18397 // with the option to show the user switcher on the keyguard. 18398 mWindowManager.lockNow(null); 18399 } else { 18400 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18401 updateCurrentProfileIdsLocked(); 18402 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18403 mUserLru.remove(currentUserIdInt); 18404 mUserLru.add(currentUserIdInt); 18405 } 18406 18407 final UserStartedState uss = mStartedUsers.get(userId); 18408 18409 // Make sure user is in the started state. If it is currently 18410 // stopping, we need to knock that off. 18411 if (uss.mState == UserStartedState.STATE_STOPPING) { 18412 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18413 // so we can just fairly silently bring the user back from 18414 // the almost-dead. 18415 uss.mState = UserStartedState.STATE_RUNNING; 18416 updateStartedUserArrayLocked(); 18417 needStart = true; 18418 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18419 // This means ACTION_SHUTDOWN has been sent, so we will 18420 // need to treat this as a new boot of the user. 18421 uss.mState = UserStartedState.STATE_BOOTING; 18422 updateStartedUserArrayLocked(); 18423 needStart = true; 18424 } 18425 18426 if (uss.mState == UserStartedState.STATE_BOOTING) { 18427 // Booting up a new user, need to tell system services about it. 18428 // Note that this is on the same handler as scheduling of broadcasts, 18429 // which is important because it needs to go first. 18430 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18431 } 18432 18433 if (foreground) { 18434 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18435 oldUserId)); 18436 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18437 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18438 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18439 oldUserId, userId, uss)); 18440 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18441 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18442 } 18443 18444 if (needStart) { 18445 // Send USER_STARTED broadcast 18446 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18447 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18448 | Intent.FLAG_RECEIVER_FOREGROUND); 18449 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18450 broadcastIntentLocked(null, null, intent, 18451 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18452 false, false, MY_PID, Process.SYSTEM_UID, userId); 18453 } 18454 18455 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18456 if (userId != UserHandle.USER_OWNER) { 18457 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18458 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18459 broadcastIntentLocked(null, null, intent, null, 18460 new IIntentReceiver.Stub() { 18461 public void performReceive(Intent intent, int resultCode, 18462 String data, Bundle extras, boolean ordered, 18463 boolean sticky, int sendingUser) { 18464 onUserInitialized(uss, foreground, oldUserId, userId); 18465 } 18466 }, 0, null, null, null, AppOpsManager.OP_NONE, 18467 true, false, MY_PID, Process.SYSTEM_UID, 18468 userId); 18469 uss.initializing = true; 18470 } else { 18471 getUserManagerLocked().makeInitialized(userInfo.id); 18472 } 18473 } 18474 18475 if (foreground) { 18476 if (!uss.initializing) { 18477 moveUserToForeground(uss, oldUserId, userId); 18478 } 18479 } else { 18480 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18481 } 18482 18483 if (needStart) { 18484 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18485 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18486 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18487 broadcastIntentLocked(null, null, intent, 18488 null, new IIntentReceiver.Stub() { 18489 @Override 18490 public void performReceive(Intent intent, int resultCode, String data, 18491 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18492 throws RemoteException { 18493 } 18494 }, 0, null, null, 18495 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18496 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18497 } 18498 } 18499 } finally { 18500 Binder.restoreCallingIdentity(ident); 18501 } 18502 18503 return true; 18504 } 18505 18506 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18507 long ident = Binder.clearCallingIdentity(); 18508 try { 18509 Intent intent; 18510 if (oldUserId >= 0) { 18511 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18512 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18513 int count = profiles.size(); 18514 for (int i = 0; i < count; i++) { 18515 int profileUserId = profiles.get(i).id; 18516 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18517 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18518 | Intent.FLAG_RECEIVER_FOREGROUND); 18519 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18520 broadcastIntentLocked(null, null, intent, 18521 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18522 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18523 } 18524 } 18525 if (newUserId >= 0) { 18526 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18527 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18528 int count = profiles.size(); 18529 for (int i = 0; i < count; i++) { 18530 int profileUserId = profiles.get(i).id; 18531 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18532 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18533 | Intent.FLAG_RECEIVER_FOREGROUND); 18534 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18535 broadcastIntentLocked(null, null, intent, 18536 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18537 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18538 } 18539 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18540 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18541 | Intent.FLAG_RECEIVER_FOREGROUND); 18542 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18543 broadcastIntentLocked(null, null, intent, 18544 null, null, 0, null, null, 18545 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18546 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18547 } 18548 } finally { 18549 Binder.restoreCallingIdentity(ident); 18550 } 18551 } 18552 18553 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18554 final int newUserId) { 18555 final int N = mUserSwitchObservers.beginBroadcast(); 18556 if (N > 0) { 18557 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18558 int mCount = 0; 18559 @Override 18560 public void sendResult(Bundle data) throws RemoteException { 18561 synchronized (ActivityManagerService.this) { 18562 if (mCurUserSwitchCallback == this) { 18563 mCount++; 18564 if (mCount == N) { 18565 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18566 } 18567 } 18568 } 18569 } 18570 }; 18571 synchronized (this) { 18572 uss.switching = true; 18573 mCurUserSwitchCallback = callback; 18574 } 18575 for (int i=0; i<N; i++) { 18576 try { 18577 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18578 newUserId, callback); 18579 } catch (RemoteException e) { 18580 } 18581 } 18582 } else { 18583 synchronized (this) { 18584 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18585 } 18586 } 18587 mUserSwitchObservers.finishBroadcast(); 18588 } 18589 18590 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18591 synchronized (this) { 18592 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18593 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18594 } 18595 } 18596 18597 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18598 mCurUserSwitchCallback = null; 18599 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18600 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18601 oldUserId, newUserId, uss)); 18602 } 18603 18604 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18605 synchronized (this) { 18606 if (foreground) { 18607 moveUserToForeground(uss, oldUserId, newUserId); 18608 } 18609 } 18610 18611 completeSwitchAndInitalize(uss, newUserId, true, false); 18612 } 18613 18614 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18615 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18616 if (homeInFront) { 18617 startHomeActivityLocked(newUserId); 18618 } else { 18619 mStackSupervisor.resumeTopActivitiesLocked(); 18620 } 18621 EventLogTags.writeAmSwitchUser(newUserId); 18622 getUserManagerLocked().userForeground(newUserId); 18623 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18624 } 18625 18626 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18627 completeSwitchAndInitalize(uss, newUserId, false, true); 18628 } 18629 18630 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18631 boolean clearInitializing, boolean clearSwitching) { 18632 boolean unfrozen = false; 18633 synchronized (this) { 18634 if (clearInitializing) { 18635 uss.initializing = false; 18636 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18637 } 18638 if (clearSwitching) { 18639 uss.switching = false; 18640 } 18641 if (!uss.switching && !uss.initializing) { 18642 mWindowManager.stopFreezingScreen(); 18643 unfrozen = true; 18644 } 18645 } 18646 if (unfrozen) { 18647 final int N = mUserSwitchObservers.beginBroadcast(); 18648 for (int i=0; i<N; i++) { 18649 try { 18650 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18651 } catch (RemoteException e) { 18652 } 18653 } 18654 mUserSwitchObservers.finishBroadcast(); 18655 } 18656 } 18657 18658 void scheduleStartProfilesLocked() { 18659 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18660 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18661 DateUtils.SECOND_IN_MILLIS); 18662 } 18663 } 18664 18665 void startProfilesLocked() { 18666 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18667 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18668 mCurrentUserId, false /* enabledOnly */); 18669 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18670 for (UserInfo user : profiles) { 18671 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18672 && user.id != mCurrentUserId) { 18673 toStart.add(user); 18674 } 18675 } 18676 final int n = toStart.size(); 18677 int i = 0; 18678 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18679 startUserInBackground(toStart.get(i).id); 18680 } 18681 if (i < n) { 18682 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18683 } 18684 } 18685 18686 void finishUserBoot(UserStartedState uss) { 18687 synchronized (this) { 18688 if (uss.mState == UserStartedState.STATE_BOOTING 18689 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18690 uss.mState = UserStartedState.STATE_RUNNING; 18691 final int userId = uss.mHandle.getIdentifier(); 18692 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18693 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18694 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18695 broadcastIntentLocked(null, null, intent, 18696 null, null, 0, null, null, 18697 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18698 true, false, MY_PID, Process.SYSTEM_UID, userId); 18699 } 18700 } 18701 } 18702 18703 void finishUserSwitch(UserStartedState uss) { 18704 synchronized (this) { 18705 finishUserBoot(uss); 18706 18707 startProfilesLocked(); 18708 18709 int num = mUserLru.size(); 18710 int i = 0; 18711 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18712 Integer oldUserId = mUserLru.get(i); 18713 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18714 if (oldUss == null) { 18715 // Shouldn't happen, but be sane if it does. 18716 mUserLru.remove(i); 18717 num--; 18718 continue; 18719 } 18720 if (oldUss.mState == UserStartedState.STATE_STOPPING 18721 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18722 // This user is already stopping, doesn't count. 18723 num--; 18724 i++; 18725 continue; 18726 } 18727 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18728 // Owner and current can't be stopped, but count as running. 18729 i++; 18730 continue; 18731 } 18732 // This is a user to be stopped. 18733 stopUserLocked(oldUserId, null); 18734 num--; 18735 i++; 18736 } 18737 } 18738 } 18739 18740 @Override 18741 public int stopUser(final int userId, final IStopUserCallback callback) { 18742 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18743 != PackageManager.PERMISSION_GRANTED) { 18744 String msg = "Permission Denial: switchUser() from pid=" 18745 + Binder.getCallingPid() 18746 + ", uid=" + Binder.getCallingUid() 18747 + " requires " + INTERACT_ACROSS_USERS_FULL; 18748 Slog.w(TAG, msg); 18749 throw new SecurityException(msg); 18750 } 18751 if (userId <= 0) { 18752 throw new IllegalArgumentException("Can't stop primary user " + userId); 18753 } 18754 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18755 synchronized (this) { 18756 return stopUserLocked(userId, callback); 18757 } 18758 } 18759 18760 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18761 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18762 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18763 return ActivityManager.USER_OP_IS_CURRENT; 18764 } 18765 18766 final UserStartedState uss = mStartedUsers.get(userId); 18767 if (uss == null) { 18768 // User is not started, nothing to do... but we do need to 18769 // callback if requested. 18770 if (callback != null) { 18771 mHandler.post(new Runnable() { 18772 @Override 18773 public void run() { 18774 try { 18775 callback.userStopped(userId); 18776 } catch (RemoteException e) { 18777 } 18778 } 18779 }); 18780 } 18781 return ActivityManager.USER_OP_SUCCESS; 18782 } 18783 18784 if (callback != null) { 18785 uss.mStopCallbacks.add(callback); 18786 } 18787 18788 if (uss.mState != UserStartedState.STATE_STOPPING 18789 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18790 uss.mState = UserStartedState.STATE_STOPPING; 18791 updateStartedUserArrayLocked(); 18792 18793 long ident = Binder.clearCallingIdentity(); 18794 try { 18795 // We are going to broadcast ACTION_USER_STOPPING and then 18796 // once that is done send a final ACTION_SHUTDOWN and then 18797 // stop the user. 18798 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18799 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18800 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18801 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18802 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18803 // This is the result receiver for the final shutdown broadcast. 18804 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18805 @Override 18806 public void performReceive(Intent intent, int resultCode, String data, 18807 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18808 finishUserStop(uss); 18809 } 18810 }; 18811 // This is the result receiver for the initial stopping broadcast. 18812 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18813 @Override 18814 public void performReceive(Intent intent, int resultCode, String data, 18815 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18816 // On to the next. 18817 synchronized (ActivityManagerService.this) { 18818 if (uss.mState != UserStartedState.STATE_STOPPING) { 18819 // Whoops, we are being started back up. Abort, abort! 18820 return; 18821 } 18822 uss.mState = UserStartedState.STATE_SHUTDOWN; 18823 } 18824 mBatteryStatsService.noteEvent( 18825 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18826 Integer.toString(userId), userId); 18827 mSystemServiceManager.stopUser(userId); 18828 broadcastIntentLocked(null, null, shutdownIntent, 18829 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18830 true, false, MY_PID, Process.SYSTEM_UID, userId); 18831 } 18832 }; 18833 // Kick things off. 18834 broadcastIntentLocked(null, null, stoppingIntent, 18835 null, stoppingReceiver, 0, null, null, 18836 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18837 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18838 } finally { 18839 Binder.restoreCallingIdentity(ident); 18840 } 18841 } 18842 18843 return ActivityManager.USER_OP_SUCCESS; 18844 } 18845 18846 void finishUserStop(UserStartedState uss) { 18847 final int userId = uss.mHandle.getIdentifier(); 18848 boolean stopped; 18849 ArrayList<IStopUserCallback> callbacks; 18850 synchronized (this) { 18851 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18852 if (mStartedUsers.get(userId) != uss) { 18853 stopped = false; 18854 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18855 stopped = false; 18856 } else { 18857 stopped = true; 18858 // User can no longer run. 18859 mStartedUsers.remove(userId); 18860 mUserLru.remove(Integer.valueOf(userId)); 18861 updateStartedUserArrayLocked(); 18862 18863 // Clean up all state and processes associated with the user. 18864 // Kill all the processes for the user. 18865 forceStopUserLocked(userId, "finish user"); 18866 } 18867 18868 // Explicitly remove the old information in mRecentTasks. 18869 removeRecentTasksForUserLocked(userId); 18870 } 18871 18872 for (int i=0; i<callbacks.size(); i++) { 18873 try { 18874 if (stopped) callbacks.get(i).userStopped(userId); 18875 else callbacks.get(i).userStopAborted(userId); 18876 } catch (RemoteException e) { 18877 } 18878 } 18879 18880 if (stopped) { 18881 mSystemServiceManager.cleanupUser(userId); 18882 synchronized (this) { 18883 mStackSupervisor.removeUserLocked(userId); 18884 } 18885 } 18886 } 18887 18888 @Override 18889 public UserInfo getCurrentUser() { 18890 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18891 != PackageManager.PERMISSION_GRANTED) && ( 18892 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18893 != PackageManager.PERMISSION_GRANTED)) { 18894 String msg = "Permission Denial: getCurrentUser() from pid=" 18895 + Binder.getCallingPid() 18896 + ", uid=" + Binder.getCallingUid() 18897 + " requires " + INTERACT_ACROSS_USERS; 18898 Slog.w(TAG, msg); 18899 throw new SecurityException(msg); 18900 } 18901 synchronized (this) { 18902 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18903 return getUserManagerLocked().getUserInfo(userId); 18904 } 18905 } 18906 18907 int getCurrentUserIdLocked() { 18908 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18909 } 18910 18911 @Override 18912 public boolean isUserRunning(int userId, boolean orStopped) { 18913 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18914 != PackageManager.PERMISSION_GRANTED) { 18915 String msg = "Permission Denial: isUserRunning() from pid=" 18916 + Binder.getCallingPid() 18917 + ", uid=" + Binder.getCallingUid() 18918 + " requires " + INTERACT_ACROSS_USERS; 18919 Slog.w(TAG, msg); 18920 throw new SecurityException(msg); 18921 } 18922 synchronized (this) { 18923 return isUserRunningLocked(userId, orStopped); 18924 } 18925 } 18926 18927 boolean isUserRunningLocked(int userId, boolean orStopped) { 18928 UserStartedState state = mStartedUsers.get(userId); 18929 if (state == null) { 18930 return false; 18931 } 18932 if (orStopped) { 18933 return true; 18934 } 18935 return state.mState != UserStartedState.STATE_STOPPING 18936 && state.mState != UserStartedState.STATE_SHUTDOWN; 18937 } 18938 18939 @Override 18940 public int[] getRunningUserIds() { 18941 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18942 != PackageManager.PERMISSION_GRANTED) { 18943 String msg = "Permission Denial: isUserRunning() from pid=" 18944 + Binder.getCallingPid() 18945 + ", uid=" + Binder.getCallingUid() 18946 + " requires " + INTERACT_ACROSS_USERS; 18947 Slog.w(TAG, msg); 18948 throw new SecurityException(msg); 18949 } 18950 synchronized (this) { 18951 return mStartedUserArray; 18952 } 18953 } 18954 18955 private void updateStartedUserArrayLocked() { 18956 int num = 0; 18957 for (int i=0; i<mStartedUsers.size(); i++) { 18958 UserStartedState uss = mStartedUsers.valueAt(i); 18959 // This list does not include stopping users. 18960 if (uss.mState != UserStartedState.STATE_STOPPING 18961 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18962 num++; 18963 } 18964 } 18965 mStartedUserArray = new int[num]; 18966 num = 0; 18967 for (int i=0; i<mStartedUsers.size(); i++) { 18968 UserStartedState uss = mStartedUsers.valueAt(i); 18969 if (uss.mState != UserStartedState.STATE_STOPPING 18970 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18971 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18972 num++; 18973 } 18974 } 18975 } 18976 18977 @Override 18978 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18979 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18980 != PackageManager.PERMISSION_GRANTED) { 18981 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18982 + Binder.getCallingPid() 18983 + ", uid=" + Binder.getCallingUid() 18984 + " requires " + INTERACT_ACROSS_USERS_FULL; 18985 Slog.w(TAG, msg); 18986 throw new SecurityException(msg); 18987 } 18988 18989 mUserSwitchObservers.register(observer); 18990 } 18991 18992 @Override 18993 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18994 mUserSwitchObservers.unregister(observer); 18995 } 18996 18997 private boolean userExists(int userId) { 18998 if (userId == 0) { 18999 return true; 19000 } 19001 UserManagerService ums = getUserManagerLocked(); 19002 return ums != null ? (ums.getUserInfo(userId) != null) : false; 19003 } 19004 19005 int[] getUsersLocked() { 19006 UserManagerService ums = getUserManagerLocked(); 19007 return ums != null ? ums.getUserIds() : new int[] { 0 }; 19008 } 19009 19010 UserManagerService getUserManagerLocked() { 19011 if (mUserManager == null) { 19012 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 19013 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 19014 } 19015 return mUserManager; 19016 } 19017 19018 private int applyUserId(int uid, int userId) { 19019 return UserHandle.getUid(userId, uid); 19020 } 19021 19022 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 19023 if (info == null) return null; 19024 ApplicationInfo newInfo = new ApplicationInfo(info); 19025 newInfo.uid = applyUserId(info.uid, userId); 19026 newInfo.dataDir = USER_DATA_DIR + userId + "/" 19027 + info.packageName; 19028 return newInfo; 19029 } 19030 19031 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 19032 if (aInfo == null 19033 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 19034 return aInfo; 19035 } 19036 19037 ActivityInfo info = new ActivityInfo(aInfo); 19038 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 19039 return info; 19040 } 19041 19042 private final class LocalService extends ActivityManagerInternal { 19043 @Override 19044 public void goingToSleep() { 19045 ActivityManagerService.this.goingToSleep(); 19046 } 19047 19048 @Override 19049 public void wakingUp() { 19050 ActivityManagerService.this.wakingUp(); 19051 } 19052 19053 @Override 19054 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 19055 String processName, String abiOverride, int uid, Runnable crashHandler) { 19056 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 19057 processName, abiOverride, uid, crashHandler); 19058 } 19059 } 19060 19061 /** 19062 * An implementation of IAppTask, that allows an app to manage its own tasks via 19063 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 19064 * only the process that calls getAppTasks() can call the AppTask methods. 19065 */ 19066 class AppTaskImpl extends IAppTask.Stub { 19067 private int mTaskId; 19068 private int mCallingUid; 19069 19070 public AppTaskImpl(int taskId, int callingUid) { 19071 mTaskId = taskId; 19072 mCallingUid = callingUid; 19073 } 19074 19075 private void checkCaller() { 19076 if (mCallingUid != Binder.getCallingUid()) { 19077 throw new SecurityException("Caller " + mCallingUid 19078 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19079 } 19080 } 19081 19082 @Override 19083 public void finishAndRemoveTask() { 19084 checkCaller(); 19085 19086 synchronized (ActivityManagerService.this) { 19087 long origId = Binder.clearCallingIdentity(); 19088 try { 19089 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19090 if (tr == null) { 19091 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19092 } 19093 // Only kill the process if we are not a new document 19094 int flags = tr.getBaseIntent().getFlags(); 19095 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 19096 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 19097 removeTaskByIdLocked(mTaskId, 19098 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 19099 } finally { 19100 Binder.restoreCallingIdentity(origId); 19101 } 19102 } 19103 } 19104 19105 @Override 19106 public ActivityManager.RecentTaskInfo getTaskInfo() { 19107 checkCaller(); 19108 19109 synchronized (ActivityManagerService.this) { 19110 long origId = Binder.clearCallingIdentity(); 19111 try { 19112 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19113 if (tr == null) { 19114 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19115 } 19116 return createRecentTaskInfoFromTaskRecord(tr); 19117 } finally { 19118 Binder.restoreCallingIdentity(origId); 19119 } 19120 } 19121 } 19122 19123 @Override 19124 public void moveToFront() { 19125 checkCaller(); 19126 19127 final TaskRecord tr; 19128 synchronized (ActivityManagerService.this) { 19129 tr = recentTaskForIdLocked(mTaskId); 19130 if (tr == null) { 19131 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19132 } 19133 if (tr.getRootActivity() != null) { 19134 moveTaskToFrontLocked(tr.taskId, 0, null); 19135 return; 19136 } 19137 } 19138 19139 startActivityFromRecentsInner(tr.taskId, null); 19140 } 19141 19142 @Override 19143 public int startActivity(IBinder whoThread, String callingPackage, 19144 Intent intent, String resolvedType, Bundle options) { 19145 checkCaller(); 19146 19147 int callingUser = UserHandle.getCallingUserId(); 19148 TaskRecord tr; 19149 IApplicationThread appThread; 19150 synchronized (ActivityManagerService.this) { 19151 tr = recentTaskForIdLocked(mTaskId); 19152 if (tr == null) { 19153 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19154 } 19155 appThread = ApplicationThreadNative.asInterface(whoThread); 19156 if (appThread == null) { 19157 throw new IllegalArgumentException("Bad app thread " + appThread); 19158 } 19159 } 19160 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 19161 resolvedType, null, null, null, null, 0, 0, null, null, 19162 null, options, callingUser, null, tr); 19163 } 19164 19165 @Override 19166 public void setExcludeFromRecents(boolean exclude) { 19167 checkCaller(); 19168 19169 synchronized (ActivityManagerService.this) { 19170 long origId = Binder.clearCallingIdentity(); 19171 try { 19172 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19173 if (tr == null) { 19174 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19175 } 19176 Intent intent = tr.getBaseIntent(); 19177 if (exclude) { 19178 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19179 } else { 19180 intent.setFlags(intent.getFlags() 19181 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19182 } 19183 } finally { 19184 Binder.restoreCallingIdentity(origId); 19185 } 19186 } 19187 } 19188 } 19189 } 19190