ActivityManagerService.java revision 465fa3963534e41ead0dce1273b71fd50c58c973
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.os.UserManager; 184import android.provider.Settings; 185import android.text.format.DateUtils; 186import android.text.format.Time; 187import android.util.AtomicFile; 188import android.util.EventLog; 189import android.util.Log; 190import android.util.Pair; 191import android.util.PrintWriterPrinter; 192import android.util.Slog; 193import android.util.SparseArray; 194import android.util.TimeUtils; 195import android.util.Xml; 196import android.view.Gravity; 197import android.view.LayoutInflater; 198import android.view.View; 199import android.view.WindowManager; 200import dalvik.system.VMRuntime; 201 202import java.io.BufferedInputStream; 203import java.io.BufferedOutputStream; 204import java.io.DataInputStream; 205import java.io.DataOutputStream; 206import java.io.File; 207import java.io.FileDescriptor; 208import java.io.FileInputStream; 209import java.io.FileNotFoundException; 210import java.io.FileOutputStream; 211import java.io.IOException; 212import java.io.InputStreamReader; 213import java.io.PrintWriter; 214import java.io.StringWriter; 215import java.lang.ref.WeakReference; 216import java.util.ArrayList; 217import java.util.Arrays; 218import java.util.Collections; 219import java.util.Comparator; 220import java.util.HashMap; 221import java.util.HashSet; 222import java.util.Iterator; 223import java.util.List; 224import java.util.Locale; 225import java.util.Map; 226import java.util.Set; 227import java.util.concurrent.atomic.AtomicBoolean; 228import java.util.concurrent.atomic.AtomicLong; 229 230public final class ActivityManagerService extends ActivityManagerNative 231 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 232 233 private static final String USER_DATA_DIR = "/data/user/"; 234 // File that stores last updated system version and called preboot receivers 235 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 236 237 static final String TAG = "ActivityManager"; 238 static final String TAG_MU = "ActivityManagerServiceMU"; 239 static final boolean DEBUG = false; 240 static final boolean localLOGV = DEBUG; 241 static final boolean DEBUG_BACKUP = localLOGV || false; 242 static final boolean DEBUG_BROADCAST = localLOGV || false; 243 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 245 static final boolean DEBUG_CLEANUP = localLOGV || false; 246 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 247 static final boolean DEBUG_FOCUS = false; 248 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 249 static final boolean DEBUG_MU = localLOGV || false; 250 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 251 static final boolean DEBUG_LRU = localLOGV || false; 252 static final boolean DEBUG_PAUSE = localLOGV || false; 253 static final boolean DEBUG_POWER = localLOGV || false; 254 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 255 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 256 static final boolean DEBUG_PROCESSES = localLOGV || false; 257 static final boolean DEBUG_PROVIDER = localLOGV || false; 258 static final boolean DEBUG_RESULTS = localLOGV || false; 259 static final boolean DEBUG_SERVICE = localLOGV || false; 260 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 261 static final boolean DEBUG_STACK = localLOGV || false; 262 static final boolean DEBUG_SWITCH = localLOGV || false; 263 static final boolean DEBUG_TASKS = localLOGV || false; 264 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 265 static final boolean DEBUG_TRANSITION = localLOGV || false; 266 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 267 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 268 static final boolean DEBUG_VISBILITY = localLOGV || false; 269 static final boolean DEBUG_PSS = localLOGV || false; 270 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 271 static final boolean DEBUG_RECENTS = localLOGV || false; 272 static final boolean VALIDATE_TOKENS = false; 273 static final boolean SHOW_ACTIVITY_START_TIME = true; 274 275 // Control over CPU and battery monitoring. 276 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 277 static final boolean MONITOR_CPU_USAGE = true; 278 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 279 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 280 static final boolean MONITOR_THREAD_CPU_USAGE = false; 281 282 // The flags that are set for all calls we make to the package manager. 283 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 284 285 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 286 287 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 288 289 // Maximum number recent bitmaps to keep in memory. 290 static final int MAX_RECENT_BITMAPS = 5; 291 292 // Amount of time after a call to stopAppSwitches() during which we will 293 // prevent further untrusted switches from happening. 294 static final long APP_SWITCH_DELAY_TIME = 5*1000; 295 296 // How long we wait for a launched process to attach to the activity manager 297 // before we decide it's never going to come up for real. 298 static final int PROC_START_TIMEOUT = 10*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real, when the process was 302 // started with a wrapper for instrumentation (such as Valgrind) because it 303 // could take much longer than usual. 304 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 305 306 // How long to wait after going idle before forcing apps to GC. 307 static final int GC_TIMEOUT = 5*1000; 308 309 // The minimum amount of time between successive GC requests for a process. 310 static final int GC_MIN_INTERVAL = 60*1000; 311 312 // The minimum amount of time between successive PSS requests for a process. 313 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 314 315 // The minimum amount of time between successive PSS requests for a process 316 // when the request is due to the memory state being lowered. 317 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 318 319 // The rate at which we check for apps using excessive power -- 15 mins. 320 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 321 322 // The minimum sample duration we will allow before deciding we have 323 // enough data on wake locks to start killing things. 324 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on CPU usage to start killing things. 328 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // How long we allow a receiver to run before giving up on it. 331 static final int BROADCAST_FG_TIMEOUT = 10*1000; 332 static final int BROADCAST_BG_TIMEOUT = 60*1000; 333 334 // How long we wait until we timeout on key dispatching. 335 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 336 337 // How long we wait until we timeout on key dispatching during instrumentation. 338 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 339 340 // Amount of time we wait for observers to handle a user switch before 341 // giving up on them and unfreezing the screen. 342 static final int USER_SWITCH_TIMEOUT = 2*1000; 343 344 // Maximum number of users we allow to be running at a time. 345 static final int MAX_RUNNING_USERS = 3; 346 347 // How long to wait in getAssistContextExtras for the activity and foreground services 348 // to respond with the result. 349 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 350 351 // Maximum number of persisted Uri grants a package is allowed 352 static final int MAX_PERSISTED_URI_GRANTS = 128; 353 354 static final int MY_PID = Process.myPid(); 355 356 static final String[] EMPTY_STRING_ARRAY = new String[0]; 357 358 // How many bytes to write into the dropbox log before truncating 359 static final int DROPBOX_MAX_SIZE = 256 * 1024; 360 361 // Access modes for handleIncomingUser. 362 static final int ALLOW_NON_FULL = 0; 363 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 364 static final int ALLOW_FULL_ONLY = 2; 365 366 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 367 368 /** All system services */ 369 SystemServiceManager mSystemServiceManager; 370 371 /** Run all ActivityStacks through this */ 372 ActivityStackSupervisor mStackSupervisor; 373 374 public IntentFirewall mIntentFirewall; 375 376 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 377 // default actuion automatically. Important for devices without direct input 378 // devices. 379 private boolean mShowDialogs = true; 380 381 BroadcastQueue mFgBroadcastQueue; 382 BroadcastQueue mBgBroadcastQueue; 383 // Convenient for easy iteration over the queues. Foreground is first 384 // so that dispatch of foreground broadcasts gets precedence. 385 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 386 387 BroadcastQueue broadcastQueueForIntent(Intent intent) { 388 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 389 if (DEBUG_BACKGROUND_BROADCAST) { 390 Slog.i(TAG, "Broadcast intent " + intent + " on " 391 + (isFg ? "foreground" : "background") 392 + " queue"); 393 } 394 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 395 } 396 397 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 398 for (BroadcastQueue queue : mBroadcastQueues) { 399 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 400 if (r != null) { 401 return r; 402 } 403 } 404 return null; 405 } 406 407 /** 408 * Activity we have told the window manager to have key focus. 409 */ 410 ActivityRecord mFocusedActivity = null; 411 412 /** 413 * List of intents that were used to start the most recent tasks. 414 */ 415 ArrayList<TaskRecord> mRecentTasks; 416 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 417 418 /** 419 * For addAppTask: cached of the last activity component that was added. 420 */ 421 ComponentName mLastAddedTaskComponent; 422 423 /** 424 * For addAppTask: cached of the last activity uid that was added. 425 */ 426 int mLastAddedTaskUid; 427 428 /** 429 * For addAppTask: cached of the last ActivityInfo that was added. 430 */ 431 ActivityInfo mLastAddedTaskActivity; 432 433 public class PendingAssistExtras extends Binder implements Runnable { 434 public final ActivityRecord activity; 435 public boolean haveResult = false; 436 public Bundle result = null; 437 public PendingAssistExtras(ActivityRecord _activity) { 438 activity = _activity; 439 } 440 @Override 441 public void run() { 442 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 443 synchronized (this) { 444 haveResult = true; 445 notifyAll(); 446 } 447 } 448 } 449 450 final ArrayList<PendingAssistExtras> mPendingAssistExtras 451 = new ArrayList<PendingAssistExtras>(); 452 453 /** 454 * Process management. 455 */ 456 final ProcessList mProcessList = new ProcessList(); 457 458 /** 459 * All of the applications we currently have running organized by name. 460 * The keys are strings of the application package name (as 461 * returned by the package manager), and the keys are ApplicationRecord 462 * objects. 463 */ 464 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 465 466 /** 467 * Tracking long-term execution of processes to look for abuse and other 468 * bad app behavior. 469 */ 470 final ProcessStatsService mProcessStats; 471 472 /** 473 * The currently running isolated processes. 474 */ 475 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 476 477 /** 478 * Counter for assigning isolated process uids, to avoid frequently reusing the 479 * same ones. 480 */ 481 int mNextIsolatedProcessUid = 0; 482 483 /** 484 * The currently running heavy-weight process, if any. 485 */ 486 ProcessRecord mHeavyWeightProcess = null; 487 488 /** 489 * The last time that various processes have crashed. 490 */ 491 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 492 493 /** 494 * Information about a process that is currently marked as bad. 495 */ 496 static final class BadProcessInfo { 497 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 498 this.time = time; 499 this.shortMsg = shortMsg; 500 this.longMsg = longMsg; 501 this.stack = stack; 502 } 503 504 final long time; 505 final String shortMsg; 506 final String longMsg; 507 final String stack; 508 } 509 510 /** 511 * Set of applications that we consider to be bad, and will reject 512 * incoming broadcasts from (which the user has no control over). 513 * Processes are added to this set when they have crashed twice within 514 * a minimum amount of time; they are removed from it when they are 515 * later restarted (hopefully due to some user action). The value is the 516 * time it was added to the list. 517 */ 518 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 519 520 /** 521 * All of the processes we currently have running organized by pid. 522 * The keys are the pid running the application. 523 * 524 * <p>NOTE: This object is protected by its own lock, NOT the global 525 * activity manager lock! 526 */ 527 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 528 529 /** 530 * All of the processes that have been forced to be foreground. The key 531 * is the pid of the caller who requested it (we hold a death 532 * link on it). 533 */ 534 abstract class ForegroundToken implements IBinder.DeathRecipient { 535 int pid; 536 IBinder token; 537 } 538 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 539 540 /** 541 * List of records for processes that someone had tried to start before the 542 * system was ready. We don't start them at that point, but ensure they 543 * are started by the time booting is complete. 544 */ 545 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 546 547 /** 548 * List of persistent applications that are in the process 549 * of being started. 550 */ 551 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Processes that are being forcibly torn down. 555 */ 556 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of running applications, sorted by recent usage. 560 * The first entry in the list is the least recently used. 561 */ 562 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Where in mLruProcesses that the processes hosting activities start. 566 */ 567 int mLruProcessActivityStart = 0; 568 569 /** 570 * Where in mLruProcesses that the processes hosting services start. 571 * This is after (lower index) than mLruProcessesActivityStart. 572 */ 573 int mLruProcessServiceStart = 0; 574 575 /** 576 * List of processes that should gc as soon as things are idle. 577 */ 578 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Processes we want to collect PSS data from. 582 */ 583 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 584 585 /** 586 * Last time we requested PSS data of all processes. 587 */ 588 long mLastFullPssTime = SystemClock.uptimeMillis(); 589 590 /** 591 * If set, the next time we collect PSS data we should do a full collection 592 * with data from native processes and the kernel. 593 */ 594 boolean mFullPssPending = false; 595 596 /** 597 * This is the process holding what we currently consider to be 598 * the "home" activity. 599 */ 600 ProcessRecord mHomeProcess; 601 602 /** 603 * This is the process holding the activity the user last visited that 604 * is in a different process from the one they are currently in. 605 */ 606 ProcessRecord mPreviousProcess; 607 608 /** 609 * The time at which the previous process was last visible. 610 */ 611 long mPreviousProcessVisibleTime; 612 613 /** 614 * Which uses have been started, so are allowed to run code. 615 */ 616 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 617 618 /** 619 * LRU list of history of current users. Most recently current is at the end. 620 */ 621 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 622 623 /** 624 * Constant array of the users that are currently started. 625 */ 626 int[] mStartedUserArray = new int[] { 0 }; 627 628 /** 629 * Registered observers of the user switching mechanics. 630 */ 631 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 632 = new RemoteCallbackList<IUserSwitchObserver>(); 633 634 /** 635 * Currently active user switch. 636 */ 637 Object mCurUserSwitchCallback; 638 639 /** 640 * Packages that the user has asked to have run in screen size 641 * compatibility mode instead of filling the screen. 642 */ 643 final CompatModePackages mCompatModePackages; 644 645 /** 646 * Set of IntentSenderRecord objects that are currently active. 647 */ 648 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 649 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 650 651 /** 652 * Fingerprints (hashCode()) of stack traces that we've 653 * already logged DropBox entries for. Guarded by itself. If 654 * something (rogue user app) forces this over 655 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 656 */ 657 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 658 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 659 660 /** 661 * Strict Mode background batched logging state. 662 * 663 * The string buffer is guarded by itself, and its lock is also 664 * used to determine if another batched write is already 665 * in-flight. 666 */ 667 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 668 669 /** 670 * Keeps track of all IIntentReceivers that have been registered for 671 * broadcasts. Hash keys are the receiver IBinder, hash value is 672 * a ReceiverList. 673 */ 674 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 675 new HashMap<IBinder, ReceiverList>(); 676 677 /** 678 * Resolver for broadcast intents to registered receivers. 679 * Holds BroadcastFilter (subclass of IntentFilter). 680 */ 681 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 682 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 683 @Override 684 protected boolean allowFilterResult( 685 BroadcastFilter filter, List<BroadcastFilter> dest) { 686 IBinder target = filter.receiverList.receiver.asBinder(); 687 for (int i=dest.size()-1; i>=0; i--) { 688 if (dest.get(i).receiverList.receiver.asBinder() == target) { 689 return false; 690 } 691 } 692 return true; 693 } 694 695 @Override 696 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 697 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 698 || userId == filter.owningUserId) { 699 return super.newResult(filter, match, userId); 700 } 701 return null; 702 } 703 704 @Override 705 protected BroadcastFilter[] newArray(int size) { 706 return new BroadcastFilter[size]; 707 } 708 709 @Override 710 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 711 return packageName.equals(filter.packageName); 712 } 713 }; 714 715 /** 716 * State of all active sticky broadcasts per user. Keys are the action of the 717 * sticky Intent, values are an ArrayList of all broadcasted intents with 718 * that action (which should usually be one). The SparseArray is keyed 719 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 720 * for stickies that are sent to all users. 721 */ 722 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 723 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 724 725 final ActiveServices mServices; 726 727 /** 728 * Backup/restore process management 729 */ 730 String mBackupAppName = null; 731 BackupRecord mBackupTarget = null; 732 733 final ProviderMap mProviderMap; 734 735 /** 736 * List of content providers who have clients waiting for them. The 737 * application is currently being launched and the provider will be 738 * removed from this list once it is published. 739 */ 740 final ArrayList<ContentProviderRecord> mLaunchingProviders 741 = new ArrayList<ContentProviderRecord>(); 742 743 /** 744 * File storing persisted {@link #mGrantedUriPermissions}. 745 */ 746 private final AtomicFile mGrantFile; 747 748 /** XML constants used in {@link #mGrantFile} */ 749 private static final String TAG_URI_GRANTS = "uri-grants"; 750 private static final String TAG_URI_GRANT = "uri-grant"; 751 private static final String ATTR_USER_HANDLE = "userHandle"; 752 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 753 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 754 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 755 private static final String ATTR_TARGET_PKG = "targetPkg"; 756 private static final String ATTR_URI = "uri"; 757 private static final String ATTR_MODE_FLAGS = "modeFlags"; 758 private static final String ATTR_CREATED_TIME = "createdTime"; 759 private static final String ATTR_PREFIX = "prefix"; 760 761 /** 762 * Global set of specific {@link Uri} permissions that have been granted. 763 * This optimized lookup structure maps from {@link UriPermission#targetUid} 764 * to {@link UriPermission#uri} to {@link UriPermission}. 765 */ 766 @GuardedBy("this") 767 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 768 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 769 770 public static class GrantUri { 771 public final int sourceUserId; 772 public final Uri uri; 773 public boolean prefix; 774 775 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 776 this.sourceUserId = sourceUserId; 777 this.uri = uri; 778 this.prefix = prefix; 779 } 780 781 @Override 782 public int hashCode() { 783 return toString().hashCode(); 784 } 785 786 @Override 787 public boolean equals(Object o) { 788 if (o instanceof GrantUri) { 789 GrantUri other = (GrantUri) o; 790 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 791 && prefix == other.prefix; 792 } 793 return false; 794 } 795 796 @Override 797 public String toString() { 798 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 799 if (prefix) result += " [prefix]"; 800 return result; 801 } 802 803 public String toSafeString() { 804 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 805 if (prefix) result += " [prefix]"; 806 return result; 807 } 808 809 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 810 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 811 ContentProvider.getUriWithoutUserId(uri), false); 812 } 813 } 814 815 CoreSettingsObserver mCoreSettingsObserver; 816 817 /** 818 * Thread-local storage used to carry caller permissions over through 819 * indirect content-provider access. 820 */ 821 private class Identity { 822 public int pid; 823 public int uid; 824 825 Identity(int _pid, int _uid) { 826 pid = _pid; 827 uid = _uid; 828 } 829 } 830 831 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 832 833 /** 834 * All information we have collected about the runtime performance of 835 * any user id that can impact battery performance. 836 */ 837 final BatteryStatsService mBatteryStatsService; 838 839 /** 840 * Information about component usage 841 */ 842 UsageStatsManagerInternal mUsageStatsService; 843 844 /** 845 * Information about and control over application operations 846 */ 847 final AppOpsService mAppOpsService; 848 849 /** 850 * Save recent tasks information across reboots. 851 */ 852 final TaskPersister mTaskPersister; 853 854 /** 855 * Current configuration information. HistoryRecord objects are given 856 * a reference to this object to indicate which configuration they are 857 * currently running in, so this object must be kept immutable. 858 */ 859 Configuration mConfiguration = new Configuration(); 860 861 /** 862 * Current sequencing integer of the configuration, for skipping old 863 * configurations. 864 */ 865 int mConfigurationSeq = 0; 866 867 /** 868 * Hardware-reported OpenGLES version. 869 */ 870 final int GL_ES_VERSION; 871 872 /** 873 * List of initialization arguments to pass to all processes when binding applications to them. 874 * For example, references to the commonly used services. 875 */ 876 HashMap<String, IBinder> mAppBindArgs; 877 878 /** 879 * Temporary to avoid allocations. Protected by main lock. 880 */ 881 final StringBuilder mStringBuilder = new StringBuilder(256); 882 883 /** 884 * Used to control how we initialize the service. 885 */ 886 ComponentName mTopComponent; 887 String mTopAction = Intent.ACTION_MAIN; 888 String mTopData; 889 boolean mProcessesReady = false; 890 boolean mSystemReady = false; 891 boolean mBooting = false; 892 boolean mCallFinishBooting = false; 893 boolean mBootAnimationComplete = false; 894 boolean mWaitingUpdate = false; 895 boolean mDidUpdate = false; 896 boolean mOnBattery = false; 897 boolean mLaunchWarningShown = false; 898 899 Context mContext; 900 901 int mFactoryTest; 902 903 boolean mCheckedForSetup; 904 905 /** 906 * The time at which we will allow normal application switches again, 907 * after a call to {@link #stopAppSwitches()}. 908 */ 909 long mAppSwitchesAllowedTime; 910 911 /** 912 * This is set to true after the first switch after mAppSwitchesAllowedTime 913 * is set; any switches after that will clear the time. 914 */ 915 boolean mDidAppSwitch; 916 917 /** 918 * Last time (in realtime) at which we checked for power usage. 919 */ 920 long mLastPowerCheckRealtime; 921 922 /** 923 * Last time (in uptime) at which we checked for power usage. 924 */ 925 long mLastPowerCheckUptime; 926 927 /** 928 * Set while we are wanting to sleep, to prevent any 929 * activities from being started/resumed. 930 */ 931 private boolean mSleeping = false; 932 933 /** 934 * Set while we are running a voice interaction. This overrides 935 * sleeping while it is active. 936 */ 937 private boolean mRunningVoice = false; 938 939 /** 940 * State of external calls telling us if the device is asleep. 941 */ 942 private boolean mWentToSleep = false; 943 944 /** 945 * State of external call telling us if the lock screen is shown. 946 */ 947 private boolean mLockScreenShown = false; 948 949 /** 950 * Set if we are shutting down the system, similar to sleeping. 951 */ 952 boolean mShuttingDown = false; 953 954 /** 955 * Current sequence id for oom_adj computation traversal. 956 */ 957 int mAdjSeq = 0; 958 959 /** 960 * Current sequence id for process LRU updating. 961 */ 962 int mLruSeq = 0; 963 964 /** 965 * Keep track of the non-cached/empty process we last found, to help 966 * determine how to distribute cached/empty processes next time. 967 */ 968 int mNumNonCachedProcs = 0; 969 970 /** 971 * Keep track of the number of cached hidden procs, to balance oom adj 972 * distribution between those and empty procs. 973 */ 974 int mNumCachedHiddenProcs = 0; 975 976 /** 977 * Keep track of the number of service processes we last found, to 978 * determine on the next iteration which should be B services. 979 */ 980 int mNumServiceProcs = 0; 981 int mNewNumAServiceProcs = 0; 982 int mNewNumServiceProcs = 0; 983 984 /** 985 * Allow the current computed overall memory level of the system to go down? 986 * This is set to false when we are killing processes for reasons other than 987 * memory management, so that the now smaller process list will not be taken as 988 * an indication that memory is tighter. 989 */ 990 boolean mAllowLowerMemLevel = false; 991 992 /** 993 * The last computed memory level, for holding when we are in a state that 994 * processes are going away for other reasons. 995 */ 996 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 997 998 /** 999 * The last total number of process we have, to determine if changes actually look 1000 * like a shrinking number of process due to lower RAM. 1001 */ 1002 int mLastNumProcesses; 1003 1004 /** 1005 * The uptime of the last time we performed idle maintenance. 1006 */ 1007 long mLastIdleTime = SystemClock.uptimeMillis(); 1008 1009 /** 1010 * Total time spent with RAM that has been added in the past since the last idle time. 1011 */ 1012 long mLowRamTimeSinceLastIdle = 0; 1013 1014 /** 1015 * If RAM is currently low, when that horrible situation started. 1016 */ 1017 long mLowRamStartTime = 0; 1018 1019 /** 1020 * For reporting to battery stats the current top application. 1021 */ 1022 private String mCurResumedPackage = null; 1023 private int mCurResumedUid = -1; 1024 1025 /** 1026 * For reporting to battery stats the apps currently running foreground 1027 * service. The ProcessMap is package/uid tuples; each of these contain 1028 * an array of the currently foreground processes. 1029 */ 1030 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1031 = new ProcessMap<ArrayList<ProcessRecord>>(); 1032 1033 /** 1034 * This is set if we had to do a delayed dexopt of an app before launching 1035 * it, to increase the ANR timeouts in that case. 1036 */ 1037 boolean mDidDexOpt; 1038 1039 /** 1040 * Set if the systemServer made a call to enterSafeMode. 1041 */ 1042 boolean mSafeMode; 1043 1044 String mDebugApp = null; 1045 boolean mWaitForDebugger = false; 1046 boolean mDebugTransient = false; 1047 String mOrigDebugApp = null; 1048 boolean mOrigWaitForDebugger = false; 1049 boolean mAlwaysFinishActivities = false; 1050 IActivityController mController = null; 1051 String mProfileApp = null; 1052 ProcessRecord mProfileProc = null; 1053 String mProfileFile; 1054 ParcelFileDescriptor mProfileFd; 1055 int mSamplingInterval = 0; 1056 boolean mAutoStopProfiler = false; 1057 int mProfileType = 0; 1058 String mOpenGlTraceApp = null; 1059 1060 static class ProcessChangeItem { 1061 static final int CHANGE_ACTIVITIES = 1<<0; 1062 static final int CHANGE_PROCESS_STATE = 1<<1; 1063 int changes; 1064 int uid; 1065 int pid; 1066 int processState; 1067 boolean foregroundActivities; 1068 } 1069 1070 final RemoteCallbackList<IProcessObserver> mProcessObservers 1071 = new RemoteCallbackList<IProcessObserver>(); 1072 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1073 1074 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1075 = new ArrayList<ProcessChangeItem>(); 1076 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1077 = new ArrayList<ProcessChangeItem>(); 1078 1079 /** 1080 * Runtime CPU use collection thread. This object's lock is used to 1081 * perform synchronization with the thread (notifying it to run). 1082 */ 1083 final Thread mProcessCpuThread; 1084 1085 /** 1086 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1087 * Must acquire this object's lock when accessing it. 1088 * NOTE: this lock will be held while doing long operations (trawling 1089 * through all processes in /proc), so it should never be acquired by 1090 * any critical paths such as when holding the main activity manager lock. 1091 */ 1092 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1093 MONITOR_THREAD_CPU_USAGE); 1094 final AtomicLong mLastCpuTime = new AtomicLong(0); 1095 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1096 1097 long mLastWriteTime = 0; 1098 1099 /** 1100 * Used to retain an update lock when the foreground activity is in 1101 * immersive mode. 1102 */ 1103 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1104 1105 /** 1106 * Set to true after the system has finished booting. 1107 */ 1108 boolean mBooted = false; 1109 1110 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1111 int mProcessLimitOverride = -1; 1112 1113 WindowManagerService mWindowManager; 1114 1115 final ActivityThread mSystemThread; 1116 1117 // Holds the current foreground user's id 1118 int mCurrentUserId = 0; 1119 // Holds the target user's id during a user switch 1120 int mTargetUserId = UserHandle.USER_NULL; 1121 // If there are multiple profiles for the current user, their ids are here 1122 // Currently only the primary user can have managed profiles 1123 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1124 1125 /** 1126 * Mapping from each known user ID to the profile group ID it is associated with. 1127 */ 1128 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1129 1130 private UserManagerService mUserManager; 1131 1132 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1133 final ProcessRecord mApp; 1134 final int mPid; 1135 final IApplicationThread mAppThread; 1136 1137 AppDeathRecipient(ProcessRecord app, int pid, 1138 IApplicationThread thread) { 1139 if (localLOGV) Slog.v( 1140 TAG, "New death recipient " + this 1141 + " for thread " + thread.asBinder()); 1142 mApp = app; 1143 mPid = pid; 1144 mAppThread = thread; 1145 } 1146 1147 @Override 1148 public void binderDied() { 1149 if (localLOGV) Slog.v( 1150 TAG, "Death received in " + this 1151 + " for thread " + mAppThread.asBinder()); 1152 synchronized(ActivityManagerService.this) { 1153 appDiedLocked(mApp, mPid, mAppThread); 1154 } 1155 } 1156 } 1157 1158 static final int SHOW_ERROR_MSG = 1; 1159 static final int SHOW_NOT_RESPONDING_MSG = 2; 1160 static final int SHOW_FACTORY_ERROR_MSG = 3; 1161 static final int UPDATE_CONFIGURATION_MSG = 4; 1162 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1163 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1164 static final int SERVICE_TIMEOUT_MSG = 12; 1165 static final int UPDATE_TIME_ZONE = 13; 1166 static final int SHOW_UID_ERROR_MSG = 14; 1167 static final int IM_FEELING_LUCKY_MSG = 15; 1168 static final int PROC_START_TIMEOUT_MSG = 20; 1169 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1170 static final int KILL_APPLICATION_MSG = 22; 1171 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1172 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1173 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1174 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1175 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1176 static final int CLEAR_DNS_CACHE_MSG = 28; 1177 static final int UPDATE_HTTP_PROXY_MSG = 29; 1178 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1179 static final int DISPATCH_PROCESSES_CHANGED = 31; 1180 static final int DISPATCH_PROCESS_DIED = 32; 1181 static final int REPORT_MEM_USAGE_MSG = 33; 1182 static final int REPORT_USER_SWITCH_MSG = 34; 1183 static final int CONTINUE_USER_SWITCH_MSG = 35; 1184 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1185 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1186 static final int PERSIST_URI_GRANTS_MSG = 38; 1187 static final int REQUEST_ALL_PSS_MSG = 39; 1188 static final int START_PROFILES_MSG = 40; 1189 static final int UPDATE_TIME = 41; 1190 static final int SYSTEM_USER_START_MSG = 42; 1191 static final int SYSTEM_USER_CURRENT_MSG = 43; 1192 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1193 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1194 static final int START_USER_SWITCH_MSG = 46; 1195 1196 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1197 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1198 static final int FIRST_COMPAT_MODE_MSG = 300; 1199 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1200 1201 AlertDialog mUidAlert; 1202 CompatModeDialog mCompatModeDialog; 1203 long mLastMemUsageReportTime = 0; 1204 1205 private LockToAppRequestDialog mLockToAppRequest; 1206 1207 /** 1208 * Flag whether the current user is a "monkey", i.e. whether 1209 * the UI is driven by a UI automation tool. 1210 */ 1211 private boolean mUserIsMonkey; 1212 1213 /** Flag whether the device has a Recents UI */ 1214 boolean mHasRecents; 1215 1216 /** The dimensions of the thumbnails in the Recents UI. */ 1217 int mThumbnailWidth; 1218 int mThumbnailHeight; 1219 1220 final ServiceThread mHandlerThread; 1221 final MainHandler mHandler; 1222 1223 final class MainHandler extends Handler { 1224 public MainHandler(Looper looper) { 1225 super(looper, null, true); 1226 } 1227 1228 @Override 1229 public void handleMessage(Message msg) { 1230 switch (msg.what) { 1231 case SHOW_ERROR_MSG: { 1232 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1233 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1234 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1235 synchronized (ActivityManagerService.this) { 1236 ProcessRecord proc = (ProcessRecord)data.get("app"); 1237 AppErrorResult res = (AppErrorResult) data.get("result"); 1238 if (proc != null && proc.crashDialog != null) { 1239 Slog.e(TAG, "App already has crash dialog: " + proc); 1240 if (res != null) { 1241 res.set(0); 1242 } 1243 return; 1244 } 1245 boolean isBackground = (UserHandle.getAppId(proc.uid) 1246 >= Process.FIRST_APPLICATION_UID 1247 && proc.pid != MY_PID); 1248 for (int userId : mCurrentProfileIds) { 1249 isBackground &= (proc.userId != userId); 1250 } 1251 if (isBackground && !showBackground) { 1252 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1253 if (res != null) { 1254 res.set(0); 1255 } 1256 return; 1257 } 1258 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1259 Dialog d = new AppErrorDialog(mContext, 1260 ActivityManagerService.this, res, proc); 1261 d.show(); 1262 proc.crashDialog = d; 1263 } else { 1264 // The device is asleep, so just pretend that the user 1265 // saw a crash dialog and hit "force quit". 1266 if (res != null) { 1267 res.set(0); 1268 } 1269 } 1270 } 1271 1272 ensureBootCompleted(); 1273 } break; 1274 case SHOW_NOT_RESPONDING_MSG: { 1275 synchronized (ActivityManagerService.this) { 1276 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1277 ProcessRecord proc = (ProcessRecord)data.get("app"); 1278 if (proc != null && proc.anrDialog != null) { 1279 Slog.e(TAG, "App already has anr dialog: " + proc); 1280 return; 1281 } 1282 1283 Intent intent = new Intent("android.intent.action.ANR"); 1284 if (!mProcessesReady) { 1285 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1286 | Intent.FLAG_RECEIVER_FOREGROUND); 1287 } 1288 broadcastIntentLocked(null, null, intent, 1289 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1290 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1291 1292 if (mShowDialogs) { 1293 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1294 mContext, proc, (ActivityRecord)data.get("activity"), 1295 msg.arg1 != 0); 1296 d.show(); 1297 proc.anrDialog = d; 1298 } else { 1299 // Just kill the app if there is no dialog to be shown. 1300 killAppAtUsersRequest(proc, null); 1301 } 1302 } 1303 1304 ensureBootCompleted(); 1305 } break; 1306 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1307 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1308 synchronized (ActivityManagerService.this) { 1309 ProcessRecord proc = (ProcessRecord) data.get("app"); 1310 if (proc == null) { 1311 Slog.e(TAG, "App not found when showing strict mode dialog."); 1312 break; 1313 } 1314 if (proc.crashDialog != null) { 1315 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1316 return; 1317 } 1318 AppErrorResult res = (AppErrorResult) data.get("result"); 1319 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1320 Dialog d = new StrictModeViolationDialog(mContext, 1321 ActivityManagerService.this, res, proc); 1322 d.show(); 1323 proc.crashDialog = d; 1324 } else { 1325 // The device is asleep, so just pretend that the user 1326 // saw a crash dialog and hit "force quit". 1327 res.set(0); 1328 } 1329 } 1330 ensureBootCompleted(); 1331 } break; 1332 case SHOW_FACTORY_ERROR_MSG: { 1333 Dialog d = new FactoryErrorDialog( 1334 mContext, msg.getData().getCharSequence("msg")); 1335 d.show(); 1336 ensureBootCompleted(); 1337 } break; 1338 case UPDATE_CONFIGURATION_MSG: { 1339 final ContentResolver resolver = mContext.getContentResolver(); 1340 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1341 } break; 1342 case GC_BACKGROUND_PROCESSES_MSG: { 1343 synchronized (ActivityManagerService.this) { 1344 performAppGcsIfAppropriateLocked(); 1345 } 1346 } break; 1347 case WAIT_FOR_DEBUGGER_MSG: { 1348 synchronized (ActivityManagerService.this) { 1349 ProcessRecord app = (ProcessRecord)msg.obj; 1350 if (msg.arg1 != 0) { 1351 if (!app.waitedForDebugger) { 1352 Dialog d = new AppWaitingForDebuggerDialog( 1353 ActivityManagerService.this, 1354 mContext, app); 1355 app.waitDialog = d; 1356 app.waitedForDebugger = true; 1357 d.show(); 1358 } 1359 } else { 1360 if (app.waitDialog != null) { 1361 app.waitDialog.dismiss(); 1362 app.waitDialog = null; 1363 } 1364 } 1365 } 1366 } break; 1367 case SERVICE_TIMEOUT_MSG: { 1368 if (mDidDexOpt) { 1369 mDidDexOpt = false; 1370 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1371 nmsg.obj = msg.obj; 1372 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1373 return; 1374 } 1375 mServices.serviceTimeout((ProcessRecord)msg.obj); 1376 } break; 1377 case UPDATE_TIME_ZONE: { 1378 synchronized (ActivityManagerService.this) { 1379 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1380 ProcessRecord r = mLruProcesses.get(i); 1381 if (r.thread != null) { 1382 try { 1383 r.thread.updateTimeZone(); 1384 } catch (RemoteException ex) { 1385 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1386 } 1387 } 1388 } 1389 } 1390 } break; 1391 case CLEAR_DNS_CACHE_MSG: { 1392 synchronized (ActivityManagerService.this) { 1393 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1394 ProcessRecord r = mLruProcesses.get(i); 1395 if (r.thread != null) { 1396 try { 1397 r.thread.clearDnsCache(); 1398 } catch (RemoteException ex) { 1399 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1400 } 1401 } 1402 } 1403 } 1404 } break; 1405 case UPDATE_HTTP_PROXY_MSG: { 1406 ProxyInfo proxy = (ProxyInfo)msg.obj; 1407 String host = ""; 1408 String port = ""; 1409 String exclList = ""; 1410 Uri pacFileUrl = Uri.EMPTY; 1411 if (proxy != null) { 1412 host = proxy.getHost(); 1413 port = Integer.toString(proxy.getPort()); 1414 exclList = proxy.getExclusionListAsString(); 1415 pacFileUrl = proxy.getPacFileUrl(); 1416 } 1417 synchronized (ActivityManagerService.this) { 1418 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1419 ProcessRecord r = mLruProcesses.get(i); 1420 if (r.thread != null) { 1421 try { 1422 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1423 } catch (RemoteException ex) { 1424 Slog.w(TAG, "Failed to update http proxy for: " + 1425 r.info.processName); 1426 } 1427 } 1428 } 1429 } 1430 } break; 1431 case SHOW_UID_ERROR_MSG: { 1432 String title = "System UIDs Inconsistent"; 1433 String text = "UIDs on the system are inconsistent, you need to wipe your" 1434 + " data partition or your device will be unstable."; 1435 Log.e(TAG, title + ": " + text); 1436 if (mShowDialogs) { 1437 // XXX This is a temporary dialog, no need to localize. 1438 AlertDialog d = new BaseErrorDialog(mContext); 1439 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1440 d.setCancelable(false); 1441 d.setTitle(title); 1442 d.setMessage(text); 1443 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1444 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1445 mUidAlert = d; 1446 d.show(); 1447 } 1448 } break; 1449 case IM_FEELING_LUCKY_MSG: { 1450 if (mUidAlert != null) { 1451 mUidAlert.dismiss(); 1452 mUidAlert = null; 1453 } 1454 } break; 1455 case PROC_START_TIMEOUT_MSG: { 1456 if (mDidDexOpt) { 1457 mDidDexOpt = false; 1458 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1459 nmsg.obj = msg.obj; 1460 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1461 return; 1462 } 1463 ProcessRecord app = (ProcessRecord)msg.obj; 1464 synchronized (ActivityManagerService.this) { 1465 processStartTimedOutLocked(app); 1466 } 1467 } break; 1468 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1469 synchronized (ActivityManagerService.this) { 1470 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1471 } 1472 } break; 1473 case KILL_APPLICATION_MSG: { 1474 synchronized (ActivityManagerService.this) { 1475 int appid = msg.arg1; 1476 boolean restart = (msg.arg2 == 1); 1477 Bundle bundle = (Bundle)msg.obj; 1478 String pkg = bundle.getString("pkg"); 1479 String reason = bundle.getString("reason"); 1480 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1481 false, UserHandle.USER_ALL, reason); 1482 } 1483 } break; 1484 case FINALIZE_PENDING_INTENT_MSG: { 1485 ((PendingIntentRecord)msg.obj).completeFinalize(); 1486 } break; 1487 case POST_HEAVY_NOTIFICATION_MSG: { 1488 INotificationManager inm = NotificationManager.getService(); 1489 if (inm == null) { 1490 return; 1491 } 1492 1493 ActivityRecord root = (ActivityRecord)msg.obj; 1494 ProcessRecord process = root.app; 1495 if (process == null) { 1496 return; 1497 } 1498 1499 try { 1500 Context context = mContext.createPackageContext(process.info.packageName, 0); 1501 String text = mContext.getString(R.string.heavy_weight_notification, 1502 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1503 Notification notification = new Notification(); 1504 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1505 notification.when = 0; 1506 notification.flags = Notification.FLAG_ONGOING_EVENT; 1507 notification.tickerText = text; 1508 notification.defaults = 0; // please be quiet 1509 notification.sound = null; 1510 notification.vibrate = null; 1511 notification.color = mContext.getResources().getColor( 1512 com.android.internal.R.color.system_notification_accent_color); 1513 notification.setLatestEventInfo(context, text, 1514 mContext.getText(R.string.heavy_weight_notification_detail), 1515 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1516 PendingIntent.FLAG_CANCEL_CURRENT, null, 1517 new UserHandle(root.userId))); 1518 1519 try { 1520 int[] outId = new int[1]; 1521 inm.enqueueNotificationWithTag("android", "android", null, 1522 R.string.heavy_weight_notification, 1523 notification, outId, root.userId); 1524 } catch (RuntimeException e) { 1525 Slog.w(ActivityManagerService.TAG, 1526 "Error showing notification for heavy-weight app", e); 1527 } catch (RemoteException e) { 1528 } 1529 } catch (NameNotFoundException e) { 1530 Slog.w(TAG, "Unable to create context for heavy notification", e); 1531 } 1532 } break; 1533 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1534 INotificationManager inm = NotificationManager.getService(); 1535 if (inm == null) { 1536 return; 1537 } 1538 try { 1539 inm.cancelNotificationWithTag("android", null, 1540 R.string.heavy_weight_notification, msg.arg1); 1541 } catch (RuntimeException e) { 1542 Slog.w(ActivityManagerService.TAG, 1543 "Error canceling notification for service", e); 1544 } catch (RemoteException e) { 1545 } 1546 } break; 1547 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1548 synchronized (ActivityManagerService.this) { 1549 checkExcessivePowerUsageLocked(true); 1550 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1551 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1552 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1553 } 1554 } break; 1555 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1556 synchronized (ActivityManagerService.this) { 1557 ActivityRecord ar = (ActivityRecord)msg.obj; 1558 if (mCompatModeDialog != null) { 1559 if (mCompatModeDialog.mAppInfo.packageName.equals( 1560 ar.info.applicationInfo.packageName)) { 1561 return; 1562 } 1563 mCompatModeDialog.dismiss(); 1564 mCompatModeDialog = null; 1565 } 1566 if (ar != null && false) { 1567 if (mCompatModePackages.getPackageAskCompatModeLocked( 1568 ar.packageName)) { 1569 int mode = mCompatModePackages.computeCompatModeLocked( 1570 ar.info.applicationInfo); 1571 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1572 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1573 mCompatModeDialog = new CompatModeDialog( 1574 ActivityManagerService.this, mContext, 1575 ar.info.applicationInfo); 1576 mCompatModeDialog.show(); 1577 } 1578 } 1579 } 1580 } 1581 break; 1582 } 1583 case DISPATCH_PROCESSES_CHANGED: { 1584 dispatchProcessesChanged(); 1585 break; 1586 } 1587 case DISPATCH_PROCESS_DIED: { 1588 final int pid = msg.arg1; 1589 final int uid = msg.arg2; 1590 dispatchProcessDied(pid, uid); 1591 break; 1592 } 1593 case REPORT_MEM_USAGE_MSG: { 1594 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1595 Thread thread = new Thread() { 1596 @Override public void run() { 1597 final SparseArray<ProcessMemInfo> infoMap 1598 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1599 for (int i=0, N=memInfos.size(); i<N; i++) { 1600 ProcessMemInfo mi = memInfos.get(i); 1601 infoMap.put(mi.pid, mi); 1602 } 1603 updateCpuStatsNow(); 1604 synchronized (mProcessCpuTracker) { 1605 final int N = mProcessCpuTracker.countStats(); 1606 for (int i=0; i<N; i++) { 1607 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1608 if (st.vsize > 0) { 1609 long pss = Debug.getPss(st.pid, null); 1610 if (pss > 0) { 1611 if (infoMap.indexOfKey(st.pid) < 0) { 1612 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1613 ProcessList.NATIVE_ADJ, -1, "native", null); 1614 mi.pss = pss; 1615 memInfos.add(mi); 1616 } 1617 } 1618 } 1619 } 1620 } 1621 1622 long totalPss = 0; 1623 for (int i=0, N=memInfos.size(); i<N; i++) { 1624 ProcessMemInfo mi = memInfos.get(i); 1625 if (mi.pss == 0) { 1626 mi.pss = Debug.getPss(mi.pid, null); 1627 } 1628 totalPss += mi.pss; 1629 } 1630 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1631 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1632 if (lhs.oomAdj != rhs.oomAdj) { 1633 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1634 } 1635 if (lhs.pss != rhs.pss) { 1636 return lhs.pss < rhs.pss ? 1 : -1; 1637 } 1638 return 0; 1639 } 1640 }); 1641 1642 StringBuilder tag = new StringBuilder(128); 1643 StringBuilder stack = new StringBuilder(128); 1644 tag.append("Low on memory -- "); 1645 appendMemBucket(tag, totalPss, "total", false); 1646 appendMemBucket(stack, totalPss, "total", true); 1647 1648 StringBuilder logBuilder = new StringBuilder(1024); 1649 logBuilder.append("Low on memory:\n"); 1650 1651 boolean firstLine = true; 1652 int lastOomAdj = Integer.MIN_VALUE; 1653 for (int i=0, N=memInfos.size(); i<N; i++) { 1654 ProcessMemInfo mi = memInfos.get(i); 1655 1656 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1657 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1658 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1659 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1660 if (lastOomAdj != mi.oomAdj) { 1661 lastOomAdj = mi.oomAdj; 1662 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1663 tag.append(" / "); 1664 } 1665 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1666 if (firstLine) { 1667 stack.append(":"); 1668 firstLine = false; 1669 } 1670 stack.append("\n\t at "); 1671 } else { 1672 stack.append("$"); 1673 } 1674 } else { 1675 tag.append(" "); 1676 stack.append("$"); 1677 } 1678 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1679 appendMemBucket(tag, mi.pss, mi.name, false); 1680 } 1681 appendMemBucket(stack, mi.pss, mi.name, true); 1682 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1683 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1684 stack.append("("); 1685 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1686 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1687 stack.append(DUMP_MEM_OOM_LABEL[k]); 1688 stack.append(":"); 1689 stack.append(DUMP_MEM_OOM_ADJ[k]); 1690 } 1691 } 1692 stack.append(")"); 1693 } 1694 } 1695 1696 logBuilder.append(" "); 1697 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1698 logBuilder.append(' '); 1699 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1700 logBuilder.append(' '); 1701 ProcessList.appendRamKb(logBuilder, mi.pss); 1702 logBuilder.append(" kB: "); 1703 logBuilder.append(mi.name); 1704 logBuilder.append(" ("); 1705 logBuilder.append(mi.pid); 1706 logBuilder.append(") "); 1707 logBuilder.append(mi.adjType); 1708 logBuilder.append('\n'); 1709 if (mi.adjReason != null) { 1710 logBuilder.append(" "); 1711 logBuilder.append(mi.adjReason); 1712 logBuilder.append('\n'); 1713 } 1714 } 1715 1716 logBuilder.append(" "); 1717 ProcessList.appendRamKb(logBuilder, totalPss); 1718 logBuilder.append(" kB: TOTAL\n"); 1719 1720 long[] infos = new long[Debug.MEMINFO_COUNT]; 1721 Debug.getMemInfo(infos); 1722 logBuilder.append(" MemInfo: "); 1723 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1724 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1725 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1726 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1727 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1728 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1729 logBuilder.append(" ZRAM: "); 1730 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1731 logBuilder.append(" kB RAM, "); 1732 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1733 logBuilder.append(" kB swap total, "); 1734 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1735 logBuilder.append(" kB swap free\n"); 1736 } 1737 Slog.i(TAG, logBuilder.toString()); 1738 1739 StringBuilder dropBuilder = new StringBuilder(1024); 1740 /* 1741 StringWriter oomSw = new StringWriter(); 1742 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1743 StringWriter catSw = new StringWriter(); 1744 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1745 String[] emptyArgs = new String[] { }; 1746 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1747 oomPw.flush(); 1748 String oomString = oomSw.toString(); 1749 */ 1750 dropBuilder.append(stack); 1751 dropBuilder.append('\n'); 1752 dropBuilder.append('\n'); 1753 dropBuilder.append(logBuilder); 1754 dropBuilder.append('\n'); 1755 /* 1756 dropBuilder.append(oomString); 1757 dropBuilder.append('\n'); 1758 */ 1759 StringWriter catSw = new StringWriter(); 1760 synchronized (ActivityManagerService.this) { 1761 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1762 String[] emptyArgs = new String[] { }; 1763 catPw.println(); 1764 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1765 catPw.println(); 1766 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1767 false, false, null); 1768 catPw.println(); 1769 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1770 catPw.flush(); 1771 } 1772 dropBuilder.append(catSw.toString()); 1773 addErrorToDropBox("lowmem", null, "system_server", null, 1774 null, tag.toString(), dropBuilder.toString(), null, null); 1775 //Slog.i(TAG, "Sent to dropbox:"); 1776 //Slog.i(TAG, dropBuilder.toString()); 1777 synchronized (ActivityManagerService.this) { 1778 long now = SystemClock.uptimeMillis(); 1779 if (mLastMemUsageReportTime < now) { 1780 mLastMemUsageReportTime = now; 1781 } 1782 } 1783 } 1784 }; 1785 thread.start(); 1786 break; 1787 } 1788 case START_USER_SWITCH_MSG: { 1789 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1790 break; 1791 } 1792 case REPORT_USER_SWITCH_MSG: { 1793 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1794 break; 1795 } 1796 case CONTINUE_USER_SWITCH_MSG: { 1797 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1798 break; 1799 } 1800 case USER_SWITCH_TIMEOUT_MSG: { 1801 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1802 break; 1803 } 1804 case IMMERSIVE_MODE_LOCK_MSG: { 1805 final boolean nextState = (msg.arg1 != 0); 1806 if (mUpdateLock.isHeld() != nextState) { 1807 if (DEBUG_IMMERSIVE) { 1808 final ActivityRecord r = (ActivityRecord) msg.obj; 1809 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1810 } 1811 if (nextState) { 1812 mUpdateLock.acquire(); 1813 } else { 1814 mUpdateLock.release(); 1815 } 1816 } 1817 break; 1818 } 1819 case PERSIST_URI_GRANTS_MSG: { 1820 writeGrantedUriPermissions(); 1821 break; 1822 } 1823 case REQUEST_ALL_PSS_MSG: { 1824 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1825 break; 1826 } 1827 case START_PROFILES_MSG: { 1828 synchronized (ActivityManagerService.this) { 1829 startProfilesLocked(); 1830 } 1831 break; 1832 } 1833 case UPDATE_TIME: { 1834 synchronized (ActivityManagerService.this) { 1835 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1836 ProcessRecord r = mLruProcesses.get(i); 1837 if (r.thread != null) { 1838 try { 1839 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1840 } catch (RemoteException ex) { 1841 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1842 } 1843 } 1844 } 1845 } 1846 break; 1847 } 1848 case SYSTEM_USER_START_MSG: { 1849 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1850 Integer.toString(msg.arg1), msg.arg1); 1851 mSystemServiceManager.startUser(msg.arg1); 1852 break; 1853 } 1854 case SYSTEM_USER_CURRENT_MSG: { 1855 mBatteryStatsService.noteEvent( 1856 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1857 Integer.toString(msg.arg2), msg.arg2); 1858 mBatteryStatsService.noteEvent( 1859 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1860 Integer.toString(msg.arg1), msg.arg1); 1861 mSystemServiceManager.switchUser(msg.arg1); 1862 mLockToAppRequest.clearPrompt(); 1863 break; 1864 } 1865 case ENTER_ANIMATION_COMPLETE_MSG: { 1866 synchronized (ActivityManagerService.this) { 1867 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1868 if (r != null && r.app != null && r.app.thread != null) { 1869 try { 1870 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1871 } catch (RemoteException e) { 1872 } 1873 } 1874 } 1875 break; 1876 } 1877 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1878 enableScreenAfterBoot(); 1879 break; 1880 } 1881 } 1882 } 1883 }; 1884 1885 static final int COLLECT_PSS_BG_MSG = 1; 1886 1887 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1888 @Override 1889 public void handleMessage(Message msg) { 1890 switch (msg.what) { 1891 case COLLECT_PSS_BG_MSG: { 1892 long start = SystemClock.uptimeMillis(); 1893 MemInfoReader memInfo = null; 1894 synchronized (ActivityManagerService.this) { 1895 if (mFullPssPending) { 1896 mFullPssPending = false; 1897 memInfo = new MemInfoReader(); 1898 } 1899 } 1900 if (memInfo != null) { 1901 updateCpuStatsNow(); 1902 long nativeTotalPss = 0; 1903 synchronized (mProcessCpuTracker) { 1904 final int N = mProcessCpuTracker.countStats(); 1905 for (int j=0; j<N; j++) { 1906 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1907 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1908 // This is definitely an application process; skip it. 1909 continue; 1910 } 1911 synchronized (mPidsSelfLocked) { 1912 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1913 // This is one of our own processes; skip it. 1914 continue; 1915 } 1916 } 1917 nativeTotalPss += Debug.getPss(st.pid, null); 1918 } 1919 } 1920 memInfo.readMemInfo(); 1921 synchronized (ActivityManagerService.this) { 1922 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1923 + (SystemClock.uptimeMillis()-start) + "ms"); 1924 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1925 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1926 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1927 +memInfo.getSlabSizeKb(), 1928 nativeTotalPss); 1929 } 1930 } 1931 1932 int i=0, num=0; 1933 long[] tmp = new long[1]; 1934 do { 1935 ProcessRecord proc; 1936 int procState; 1937 int pid; 1938 synchronized (ActivityManagerService.this) { 1939 if (i >= mPendingPssProcesses.size()) { 1940 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1941 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1942 mPendingPssProcesses.clear(); 1943 return; 1944 } 1945 proc = mPendingPssProcesses.get(i); 1946 procState = proc.pssProcState; 1947 if (proc.thread != null && procState == proc.setProcState) { 1948 pid = proc.pid; 1949 } else { 1950 proc = null; 1951 pid = 0; 1952 } 1953 i++; 1954 } 1955 if (proc != null) { 1956 long pss = Debug.getPss(pid, tmp); 1957 synchronized (ActivityManagerService.this) { 1958 if (proc.thread != null && proc.setProcState == procState 1959 && proc.pid == pid) { 1960 num++; 1961 proc.lastPssTime = SystemClock.uptimeMillis(); 1962 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1963 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1964 + ": " + pss + " lastPss=" + proc.lastPss 1965 + " state=" + ProcessList.makeProcStateString(procState)); 1966 if (proc.initialIdlePss == 0) { 1967 proc.initialIdlePss = pss; 1968 } 1969 proc.lastPss = pss; 1970 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1971 proc.lastCachedPss = pss; 1972 } 1973 } 1974 } 1975 } 1976 } while (true); 1977 } 1978 } 1979 } 1980 }; 1981 1982 /** 1983 * Monitor for package changes and update our internal state. 1984 */ 1985 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1986 @Override 1987 public void onPackageRemoved(String packageName, int uid) { 1988 // Remove all tasks with activities in the specified package from the list of recent tasks 1989 synchronized (ActivityManagerService.this) { 1990 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1991 TaskRecord tr = mRecentTasks.get(i); 1992 ComponentName cn = tr.intent.getComponent(); 1993 if (cn != null && cn.getPackageName().equals(packageName)) { 1994 // If the package name matches, remove the task and kill the process 1995 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1996 } 1997 } 1998 } 1999 } 2000 2001 @Override 2002 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2003 onPackageModified(packageName); 2004 return true; 2005 } 2006 2007 @Override 2008 public void onPackageModified(String packageName) { 2009 final PackageManager pm = mContext.getPackageManager(); 2010 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2011 new ArrayList<Pair<Intent, Integer>>(); 2012 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2013 // Copy the list of recent tasks so that we don't hold onto the lock on 2014 // ActivityManagerService for long periods while checking if components exist. 2015 synchronized (ActivityManagerService.this) { 2016 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2017 TaskRecord tr = mRecentTasks.get(i); 2018 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2019 } 2020 } 2021 // Check the recent tasks and filter out all tasks with components that no longer exist. 2022 Intent tmpI = new Intent(); 2023 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2024 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2025 ComponentName cn = p.first.getComponent(); 2026 if (cn != null && cn.getPackageName().equals(packageName)) { 2027 try { 2028 // Add the task to the list to remove if the component no longer exists 2029 tmpI.setComponent(cn); 2030 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2031 tasksToRemove.add(p.second); 2032 } 2033 } catch (Exception e) {} 2034 } 2035 } 2036 // Prune all the tasks with removed components from the list of recent tasks 2037 synchronized (ActivityManagerService.this) { 2038 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2039 // Remove the task but don't kill the process (since other components in that 2040 // package may still be running and in the background) 2041 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2042 } 2043 } 2044 } 2045 2046 @Override 2047 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2048 // Force stop the specified packages 2049 if (packages != null) { 2050 for (String pkg : packages) { 2051 synchronized (ActivityManagerService.this) { 2052 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2053 "finished booting")) { 2054 return true; 2055 } 2056 } 2057 } 2058 } 2059 return false; 2060 } 2061 }; 2062 2063 public void setSystemProcess() { 2064 try { 2065 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2066 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2067 ServiceManager.addService("meminfo", new MemBinder(this)); 2068 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2069 ServiceManager.addService("dbinfo", new DbBinder(this)); 2070 if (MONITOR_CPU_USAGE) { 2071 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2072 } 2073 ServiceManager.addService("permission", new PermissionController(this)); 2074 2075 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2076 "android", STOCK_PM_FLAGS); 2077 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2078 2079 synchronized (this) { 2080 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2081 app.persistent = true; 2082 app.pid = MY_PID; 2083 app.maxAdj = ProcessList.SYSTEM_ADJ; 2084 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2085 mProcessNames.put(app.processName, app.uid, app); 2086 synchronized (mPidsSelfLocked) { 2087 mPidsSelfLocked.put(app.pid, app); 2088 } 2089 updateLruProcessLocked(app, false, null); 2090 updateOomAdjLocked(); 2091 } 2092 } catch (PackageManager.NameNotFoundException e) { 2093 throw new RuntimeException( 2094 "Unable to find android system package", e); 2095 } 2096 } 2097 2098 public void setWindowManager(WindowManagerService wm) { 2099 mWindowManager = wm; 2100 mStackSupervisor.setWindowManager(wm); 2101 } 2102 2103 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2104 mUsageStatsService = usageStatsManager; 2105 } 2106 2107 public void startObservingNativeCrashes() { 2108 final NativeCrashListener ncl = new NativeCrashListener(this); 2109 ncl.start(); 2110 } 2111 2112 public IAppOpsService getAppOpsService() { 2113 return mAppOpsService; 2114 } 2115 2116 static class MemBinder extends Binder { 2117 ActivityManagerService mActivityManagerService; 2118 MemBinder(ActivityManagerService activityManagerService) { 2119 mActivityManagerService = activityManagerService; 2120 } 2121 2122 @Override 2123 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2124 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2125 != PackageManager.PERMISSION_GRANTED) { 2126 pw.println("Permission Denial: can't dump meminfo from from pid=" 2127 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2128 + " without permission " + android.Manifest.permission.DUMP); 2129 return; 2130 } 2131 2132 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2133 } 2134 } 2135 2136 static class GraphicsBinder extends Binder { 2137 ActivityManagerService mActivityManagerService; 2138 GraphicsBinder(ActivityManagerService activityManagerService) { 2139 mActivityManagerService = activityManagerService; 2140 } 2141 2142 @Override 2143 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2144 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2145 != PackageManager.PERMISSION_GRANTED) { 2146 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2147 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2148 + " without permission " + android.Manifest.permission.DUMP); 2149 return; 2150 } 2151 2152 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2153 } 2154 } 2155 2156 static class DbBinder extends Binder { 2157 ActivityManagerService mActivityManagerService; 2158 DbBinder(ActivityManagerService activityManagerService) { 2159 mActivityManagerService = activityManagerService; 2160 } 2161 2162 @Override 2163 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2164 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2165 != PackageManager.PERMISSION_GRANTED) { 2166 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2167 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2168 + " without permission " + android.Manifest.permission.DUMP); 2169 return; 2170 } 2171 2172 mActivityManagerService.dumpDbInfo(fd, pw, args); 2173 } 2174 } 2175 2176 static class CpuBinder extends Binder { 2177 ActivityManagerService mActivityManagerService; 2178 CpuBinder(ActivityManagerService activityManagerService) { 2179 mActivityManagerService = activityManagerService; 2180 } 2181 2182 @Override 2183 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2184 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2185 != PackageManager.PERMISSION_GRANTED) { 2186 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2187 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2188 + " without permission " + android.Manifest.permission.DUMP); 2189 return; 2190 } 2191 2192 synchronized (mActivityManagerService.mProcessCpuTracker) { 2193 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2194 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2195 SystemClock.uptimeMillis())); 2196 } 2197 } 2198 } 2199 2200 public static final class Lifecycle extends SystemService { 2201 private final ActivityManagerService mService; 2202 2203 public Lifecycle(Context context) { 2204 super(context); 2205 mService = new ActivityManagerService(context); 2206 } 2207 2208 @Override 2209 public void onStart() { 2210 mService.start(); 2211 } 2212 2213 public ActivityManagerService getService() { 2214 return mService; 2215 } 2216 } 2217 2218 // Note: This method is invoked on the main thread but may need to attach various 2219 // handlers to other threads. So take care to be explicit about the looper. 2220 public ActivityManagerService(Context systemContext) { 2221 mContext = systemContext; 2222 mFactoryTest = FactoryTest.getMode(); 2223 mSystemThread = ActivityThread.currentActivityThread(); 2224 2225 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2226 2227 mHandlerThread = new ServiceThread(TAG, 2228 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2229 mHandlerThread.start(); 2230 mHandler = new MainHandler(mHandlerThread.getLooper()); 2231 2232 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2233 "foreground", BROADCAST_FG_TIMEOUT, false); 2234 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2235 "background", BROADCAST_BG_TIMEOUT, true); 2236 mBroadcastQueues[0] = mFgBroadcastQueue; 2237 mBroadcastQueues[1] = mBgBroadcastQueue; 2238 2239 mServices = new ActiveServices(this); 2240 mProviderMap = new ProviderMap(this); 2241 2242 // TODO: Move creation of battery stats service outside of activity manager service. 2243 File dataDir = Environment.getDataDirectory(); 2244 File systemDir = new File(dataDir, "system"); 2245 systemDir.mkdirs(); 2246 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2247 mBatteryStatsService.getActiveStatistics().readLocked(); 2248 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2249 mOnBattery = DEBUG_POWER ? true 2250 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2251 mBatteryStatsService.getActiveStatistics().setCallback(this); 2252 2253 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2254 2255 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2256 2257 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2258 2259 // User 0 is the first and only user that runs at boot. 2260 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2261 mUserLru.add(Integer.valueOf(0)); 2262 updateStartedUserArrayLocked(); 2263 2264 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2265 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2266 2267 mConfiguration.setToDefaults(); 2268 mConfiguration.setLocale(Locale.getDefault()); 2269 2270 mConfigurationSeq = mConfiguration.seq = 1; 2271 mProcessCpuTracker.init(); 2272 2273 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2274 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2275 mStackSupervisor = new ActivityStackSupervisor(this); 2276 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2277 2278 mProcessCpuThread = new Thread("CpuTracker") { 2279 @Override 2280 public void run() { 2281 while (true) { 2282 try { 2283 try { 2284 synchronized(this) { 2285 final long now = SystemClock.uptimeMillis(); 2286 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2287 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2288 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2289 // + ", write delay=" + nextWriteDelay); 2290 if (nextWriteDelay < nextCpuDelay) { 2291 nextCpuDelay = nextWriteDelay; 2292 } 2293 if (nextCpuDelay > 0) { 2294 mProcessCpuMutexFree.set(true); 2295 this.wait(nextCpuDelay); 2296 } 2297 } 2298 } catch (InterruptedException e) { 2299 } 2300 updateCpuStatsNow(); 2301 } catch (Exception e) { 2302 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2303 } 2304 } 2305 } 2306 }; 2307 2308 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2309 2310 Watchdog.getInstance().addMonitor(this); 2311 Watchdog.getInstance().addThread(mHandler); 2312 } 2313 2314 public void setSystemServiceManager(SystemServiceManager mgr) { 2315 mSystemServiceManager = mgr; 2316 } 2317 2318 private void start() { 2319 Process.removeAllProcessGroups(); 2320 mProcessCpuThread.start(); 2321 2322 mBatteryStatsService.publish(mContext); 2323 mAppOpsService.publish(mContext); 2324 Slog.d("AppOps", "AppOpsService published"); 2325 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2326 } 2327 2328 public void initPowerManagement() { 2329 mStackSupervisor.initPowerManagement(); 2330 mBatteryStatsService.initPowerManagement(); 2331 } 2332 2333 @Override 2334 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2335 throws RemoteException { 2336 if (code == SYSPROPS_TRANSACTION) { 2337 // We need to tell all apps about the system property change. 2338 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2339 synchronized(this) { 2340 final int NP = mProcessNames.getMap().size(); 2341 for (int ip=0; ip<NP; ip++) { 2342 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2343 final int NA = apps.size(); 2344 for (int ia=0; ia<NA; ia++) { 2345 ProcessRecord app = apps.valueAt(ia); 2346 if (app.thread != null) { 2347 procs.add(app.thread.asBinder()); 2348 } 2349 } 2350 } 2351 } 2352 2353 int N = procs.size(); 2354 for (int i=0; i<N; i++) { 2355 Parcel data2 = Parcel.obtain(); 2356 try { 2357 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2358 } catch (RemoteException e) { 2359 } 2360 data2.recycle(); 2361 } 2362 } 2363 try { 2364 return super.onTransact(code, data, reply, flags); 2365 } catch (RuntimeException e) { 2366 // The activity manager only throws security exceptions, so let's 2367 // log all others. 2368 if (!(e instanceof SecurityException)) { 2369 Slog.wtf(TAG, "Activity Manager Crash", e); 2370 } 2371 throw e; 2372 } 2373 } 2374 2375 void updateCpuStats() { 2376 final long now = SystemClock.uptimeMillis(); 2377 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2378 return; 2379 } 2380 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2381 synchronized (mProcessCpuThread) { 2382 mProcessCpuThread.notify(); 2383 } 2384 } 2385 } 2386 2387 void updateCpuStatsNow() { 2388 synchronized (mProcessCpuTracker) { 2389 mProcessCpuMutexFree.set(false); 2390 final long now = SystemClock.uptimeMillis(); 2391 boolean haveNewCpuStats = false; 2392 2393 if (MONITOR_CPU_USAGE && 2394 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2395 mLastCpuTime.set(now); 2396 haveNewCpuStats = true; 2397 mProcessCpuTracker.update(); 2398 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2399 //Slog.i(TAG, "Total CPU usage: " 2400 // + mProcessCpu.getTotalCpuPercent() + "%"); 2401 2402 // Slog the cpu usage if the property is set. 2403 if ("true".equals(SystemProperties.get("events.cpu"))) { 2404 int user = mProcessCpuTracker.getLastUserTime(); 2405 int system = mProcessCpuTracker.getLastSystemTime(); 2406 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2407 int irq = mProcessCpuTracker.getLastIrqTime(); 2408 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2409 int idle = mProcessCpuTracker.getLastIdleTime(); 2410 2411 int total = user + system + iowait + irq + softIrq + idle; 2412 if (total == 0) total = 1; 2413 2414 EventLog.writeEvent(EventLogTags.CPU, 2415 ((user+system+iowait+irq+softIrq) * 100) / total, 2416 (user * 100) / total, 2417 (system * 100) / total, 2418 (iowait * 100) / total, 2419 (irq * 100) / total, 2420 (softIrq * 100) / total); 2421 } 2422 } 2423 2424 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2425 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2426 synchronized(bstats) { 2427 synchronized(mPidsSelfLocked) { 2428 if (haveNewCpuStats) { 2429 if (mOnBattery) { 2430 int perc = bstats.startAddingCpuLocked(); 2431 int totalUTime = 0; 2432 int totalSTime = 0; 2433 final int N = mProcessCpuTracker.countStats(); 2434 for (int i=0; i<N; i++) { 2435 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2436 if (!st.working) { 2437 continue; 2438 } 2439 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2440 int otherUTime = (st.rel_utime*perc)/100; 2441 int otherSTime = (st.rel_stime*perc)/100; 2442 totalUTime += otherUTime; 2443 totalSTime += otherSTime; 2444 if (pr != null) { 2445 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2446 if (ps == null || !ps.isActive()) { 2447 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2448 pr.info.uid, pr.processName); 2449 } 2450 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2451 st.rel_stime-otherSTime); 2452 ps.addSpeedStepTimes(cpuSpeedTimes); 2453 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2454 } else { 2455 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2456 if (ps == null || !ps.isActive()) { 2457 st.batteryStats = ps = bstats.getProcessStatsLocked( 2458 bstats.mapUid(st.uid), st.name); 2459 } 2460 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2461 st.rel_stime-otherSTime); 2462 ps.addSpeedStepTimes(cpuSpeedTimes); 2463 } 2464 } 2465 bstats.finishAddingCpuLocked(perc, totalUTime, 2466 totalSTime, cpuSpeedTimes); 2467 } 2468 } 2469 } 2470 2471 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2472 mLastWriteTime = now; 2473 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2474 } 2475 } 2476 } 2477 } 2478 2479 @Override 2480 public void batteryNeedsCpuUpdate() { 2481 updateCpuStatsNow(); 2482 } 2483 2484 @Override 2485 public void batteryPowerChanged(boolean onBattery) { 2486 // When plugging in, update the CPU stats first before changing 2487 // the plug state. 2488 updateCpuStatsNow(); 2489 synchronized (this) { 2490 synchronized(mPidsSelfLocked) { 2491 mOnBattery = DEBUG_POWER ? true : onBattery; 2492 } 2493 } 2494 } 2495 2496 /** 2497 * Initialize the application bind args. These are passed to each 2498 * process when the bindApplication() IPC is sent to the process. They're 2499 * lazily setup to make sure the services are running when they're asked for. 2500 */ 2501 private HashMap<String, IBinder> getCommonServicesLocked() { 2502 if (mAppBindArgs == null) { 2503 mAppBindArgs = new HashMap<String, IBinder>(); 2504 2505 // Setup the application init args 2506 mAppBindArgs.put("package", ServiceManager.getService("package")); 2507 mAppBindArgs.put("window", ServiceManager.getService("window")); 2508 mAppBindArgs.put(Context.ALARM_SERVICE, 2509 ServiceManager.getService(Context.ALARM_SERVICE)); 2510 } 2511 return mAppBindArgs; 2512 } 2513 2514 final void setFocusedActivityLocked(ActivityRecord r) { 2515 if (mFocusedActivity != r) { 2516 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2517 mFocusedActivity = r; 2518 if (r.task != null && r.task.voiceInteractor != null) { 2519 startRunningVoiceLocked(); 2520 } else { 2521 finishRunningVoiceLocked(); 2522 } 2523 mStackSupervisor.setFocusedStack(r); 2524 if (r != null) { 2525 mWindowManager.setFocusedApp(r.appToken, true); 2526 } 2527 applyUpdateLockStateLocked(r); 2528 } 2529 } 2530 2531 final void clearFocusedActivity(ActivityRecord r) { 2532 if (mFocusedActivity == r) { 2533 mFocusedActivity = null; 2534 } 2535 } 2536 2537 @Override 2538 public void setFocusedStack(int stackId) { 2539 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2540 synchronized (ActivityManagerService.this) { 2541 ActivityStack stack = mStackSupervisor.getStack(stackId); 2542 if (stack != null) { 2543 ActivityRecord r = stack.topRunningActivityLocked(null); 2544 if (r != null) { 2545 setFocusedActivityLocked(r); 2546 } 2547 } 2548 } 2549 } 2550 2551 @Override 2552 public void notifyActivityDrawn(IBinder token) { 2553 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2554 synchronized (this) { 2555 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2556 if (r != null) { 2557 r.task.stack.notifyActivityDrawnLocked(r); 2558 } 2559 } 2560 } 2561 2562 final void applyUpdateLockStateLocked(ActivityRecord r) { 2563 // Modifications to the UpdateLock state are done on our handler, outside 2564 // the activity manager's locks. The new state is determined based on the 2565 // state *now* of the relevant activity record. The object is passed to 2566 // the handler solely for logging detail, not to be consulted/modified. 2567 final boolean nextState = r != null && r.immersive; 2568 mHandler.sendMessage( 2569 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2570 } 2571 2572 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2573 Message msg = Message.obtain(); 2574 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2575 msg.obj = r.task.askedCompatMode ? null : r; 2576 mHandler.sendMessage(msg); 2577 } 2578 2579 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2580 String what, Object obj, ProcessRecord srcApp) { 2581 app.lastActivityTime = now; 2582 2583 if (app.activities.size() > 0) { 2584 // Don't want to touch dependent processes that are hosting activities. 2585 return index; 2586 } 2587 2588 int lrui = mLruProcesses.lastIndexOf(app); 2589 if (lrui < 0) { 2590 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2591 + what + " " + obj + " from " + srcApp); 2592 return index; 2593 } 2594 2595 if (lrui >= index) { 2596 // Don't want to cause this to move dependent processes *back* in the 2597 // list as if they were less frequently used. 2598 return index; 2599 } 2600 2601 if (lrui >= mLruProcessActivityStart) { 2602 // Don't want to touch dependent processes that are hosting activities. 2603 return index; 2604 } 2605 2606 mLruProcesses.remove(lrui); 2607 if (index > 0) { 2608 index--; 2609 } 2610 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2611 + " in LRU list: " + app); 2612 mLruProcesses.add(index, app); 2613 return index; 2614 } 2615 2616 final void removeLruProcessLocked(ProcessRecord app) { 2617 int lrui = mLruProcesses.lastIndexOf(app); 2618 if (lrui >= 0) { 2619 if (lrui <= mLruProcessActivityStart) { 2620 mLruProcessActivityStart--; 2621 } 2622 if (lrui <= mLruProcessServiceStart) { 2623 mLruProcessServiceStart--; 2624 } 2625 mLruProcesses.remove(lrui); 2626 } 2627 } 2628 2629 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2630 ProcessRecord client) { 2631 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2632 || app.treatLikeActivity; 2633 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2634 if (!activityChange && hasActivity) { 2635 // The process has activities, so we are only allowing activity-based adjustments 2636 // to move it. It should be kept in the front of the list with other 2637 // processes that have activities, and we don't want those to change their 2638 // order except due to activity operations. 2639 return; 2640 } 2641 2642 mLruSeq++; 2643 final long now = SystemClock.uptimeMillis(); 2644 app.lastActivityTime = now; 2645 2646 // First a quick reject: if the app is already at the position we will 2647 // put it, then there is nothing to do. 2648 if (hasActivity) { 2649 final int N = mLruProcesses.size(); 2650 if (N > 0 && mLruProcesses.get(N-1) == app) { 2651 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2652 return; 2653 } 2654 } else { 2655 if (mLruProcessServiceStart > 0 2656 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2657 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2658 return; 2659 } 2660 } 2661 2662 int lrui = mLruProcesses.lastIndexOf(app); 2663 2664 if (app.persistent && lrui >= 0) { 2665 // We don't care about the position of persistent processes, as long as 2666 // they are in the list. 2667 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2668 return; 2669 } 2670 2671 /* In progress: compute new position first, so we can avoid doing work 2672 if the process is not actually going to move. Not yet working. 2673 int addIndex; 2674 int nextIndex; 2675 boolean inActivity = false, inService = false; 2676 if (hasActivity) { 2677 // Process has activities, put it at the very tipsy-top. 2678 addIndex = mLruProcesses.size(); 2679 nextIndex = mLruProcessServiceStart; 2680 inActivity = true; 2681 } else if (hasService) { 2682 // Process has services, put it at the top of the service list. 2683 addIndex = mLruProcessActivityStart; 2684 nextIndex = mLruProcessServiceStart; 2685 inActivity = true; 2686 inService = true; 2687 } else { 2688 // Process not otherwise of interest, it goes to the top of the non-service area. 2689 addIndex = mLruProcessServiceStart; 2690 if (client != null) { 2691 int clientIndex = mLruProcesses.lastIndexOf(client); 2692 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2693 + app); 2694 if (clientIndex >= 0 && addIndex > clientIndex) { 2695 addIndex = clientIndex; 2696 } 2697 } 2698 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2699 } 2700 2701 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2702 + mLruProcessActivityStart + "): " + app); 2703 */ 2704 2705 if (lrui >= 0) { 2706 if (lrui < mLruProcessActivityStart) { 2707 mLruProcessActivityStart--; 2708 } 2709 if (lrui < mLruProcessServiceStart) { 2710 mLruProcessServiceStart--; 2711 } 2712 /* 2713 if (addIndex > lrui) { 2714 addIndex--; 2715 } 2716 if (nextIndex > lrui) { 2717 nextIndex--; 2718 } 2719 */ 2720 mLruProcesses.remove(lrui); 2721 } 2722 2723 /* 2724 mLruProcesses.add(addIndex, app); 2725 if (inActivity) { 2726 mLruProcessActivityStart++; 2727 } 2728 if (inService) { 2729 mLruProcessActivityStart++; 2730 } 2731 */ 2732 2733 int nextIndex; 2734 if (hasActivity) { 2735 final int N = mLruProcesses.size(); 2736 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2737 // Process doesn't have activities, but has clients with 2738 // activities... move it up, but one below the top (the top 2739 // should always have a real activity). 2740 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2741 mLruProcesses.add(N-1, app); 2742 // To keep it from spamming the LRU list (by making a bunch of clients), 2743 // we will push down any other entries owned by the app. 2744 final int uid = app.info.uid; 2745 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2746 ProcessRecord subProc = mLruProcesses.get(i); 2747 if (subProc.info.uid == uid) { 2748 // We want to push this one down the list. If the process after 2749 // it is for the same uid, however, don't do so, because we don't 2750 // want them internally to be re-ordered. 2751 if (mLruProcesses.get(i-1).info.uid != uid) { 2752 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2753 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2754 ProcessRecord tmp = mLruProcesses.get(i); 2755 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2756 mLruProcesses.set(i-1, tmp); 2757 i--; 2758 } 2759 } else { 2760 // A gap, we can stop here. 2761 break; 2762 } 2763 } 2764 } else { 2765 // Process has activities, put it at the very tipsy-top. 2766 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2767 mLruProcesses.add(app); 2768 } 2769 nextIndex = mLruProcessServiceStart; 2770 } else if (hasService) { 2771 // Process has services, put it at the top of the service list. 2772 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2773 mLruProcesses.add(mLruProcessActivityStart, app); 2774 nextIndex = mLruProcessServiceStart; 2775 mLruProcessActivityStart++; 2776 } else { 2777 // Process not otherwise of interest, it goes to the top of the non-service area. 2778 int index = mLruProcessServiceStart; 2779 if (client != null) { 2780 // If there is a client, don't allow the process to be moved up higher 2781 // in the list than that client. 2782 int clientIndex = mLruProcesses.lastIndexOf(client); 2783 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2784 + " when updating " + app); 2785 if (clientIndex <= lrui) { 2786 // Don't allow the client index restriction to push it down farther in the 2787 // list than it already is. 2788 clientIndex = lrui; 2789 } 2790 if (clientIndex >= 0 && index > clientIndex) { 2791 index = clientIndex; 2792 } 2793 } 2794 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2795 mLruProcesses.add(index, app); 2796 nextIndex = index-1; 2797 mLruProcessActivityStart++; 2798 mLruProcessServiceStart++; 2799 } 2800 2801 // If the app is currently using a content provider or service, 2802 // bump those processes as well. 2803 for (int j=app.connections.size()-1; j>=0; j--) { 2804 ConnectionRecord cr = app.connections.valueAt(j); 2805 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2806 && cr.binding.service.app != null 2807 && cr.binding.service.app.lruSeq != mLruSeq 2808 && !cr.binding.service.app.persistent) { 2809 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2810 "service connection", cr, app); 2811 } 2812 } 2813 for (int j=app.conProviders.size()-1; j>=0; j--) { 2814 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2815 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2816 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2817 "provider reference", cpr, app); 2818 } 2819 } 2820 } 2821 2822 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2823 if (uid == Process.SYSTEM_UID) { 2824 // The system gets to run in any process. If there are multiple 2825 // processes with the same uid, just pick the first (this 2826 // should never happen). 2827 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2828 if (procs == null) return null; 2829 final int N = procs.size(); 2830 for (int i = 0; i < N; i++) { 2831 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2832 } 2833 } 2834 ProcessRecord proc = mProcessNames.get(processName, uid); 2835 if (false && proc != null && !keepIfLarge 2836 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2837 && proc.lastCachedPss >= 4000) { 2838 // Turn this condition on to cause killing to happen regularly, for testing. 2839 if (proc.baseProcessTracker != null) { 2840 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2841 } 2842 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2843 } else if (proc != null && !keepIfLarge 2844 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2845 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2846 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2847 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2848 if (proc.baseProcessTracker != null) { 2849 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2850 } 2851 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2852 } 2853 } 2854 return proc; 2855 } 2856 2857 void ensurePackageDexOpt(String packageName) { 2858 IPackageManager pm = AppGlobals.getPackageManager(); 2859 try { 2860 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2861 mDidDexOpt = true; 2862 } 2863 } catch (RemoteException e) { 2864 } 2865 } 2866 2867 boolean isNextTransitionForward() { 2868 int transit = mWindowManager.getPendingAppTransition(); 2869 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2870 || transit == AppTransition.TRANSIT_TASK_OPEN 2871 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2872 } 2873 2874 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2875 String processName, String abiOverride, int uid, Runnable crashHandler) { 2876 synchronized(this) { 2877 ApplicationInfo info = new ApplicationInfo(); 2878 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2879 // For isolated processes, the former contains the parent's uid and the latter the 2880 // actual uid of the isolated process. 2881 // In the special case introduced by this method (which is, starting an isolated 2882 // process directly from the SystemServer without an actual parent app process) the 2883 // closest thing to a parent's uid is SYSTEM_UID. 2884 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2885 // the |isolated| logic in the ProcessRecord constructor. 2886 info.uid = Process.SYSTEM_UID; 2887 info.processName = processName; 2888 info.className = entryPoint; 2889 info.packageName = "android"; 2890 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2891 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2892 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2893 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2894 crashHandler); 2895 return proc != null ? proc.pid : 0; 2896 } 2897 } 2898 2899 final ProcessRecord startProcessLocked(String processName, 2900 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2901 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2902 boolean isolated, boolean keepIfLarge) { 2903 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2904 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2905 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2906 null /* crashHandler */); 2907 } 2908 2909 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2910 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2911 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2912 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2913 long startTime = SystemClock.elapsedRealtime(); 2914 ProcessRecord app; 2915 if (!isolated) { 2916 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2917 checkTime(startTime, "startProcess: after getProcessRecord"); 2918 } else { 2919 // If this is an isolated process, it can't re-use an existing process. 2920 app = null; 2921 } 2922 // We don't have to do anything more if: 2923 // (1) There is an existing application record; and 2924 // (2) The caller doesn't think it is dead, OR there is no thread 2925 // object attached to it so we know it couldn't have crashed; and 2926 // (3) There is a pid assigned to it, so it is either starting or 2927 // already running. 2928 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2929 + " app=" + app + " knownToBeDead=" + knownToBeDead 2930 + " thread=" + (app != null ? app.thread : null) 2931 + " pid=" + (app != null ? app.pid : -1)); 2932 if (app != null && app.pid > 0) { 2933 if (!knownToBeDead || app.thread == null) { 2934 // We already have the app running, or are waiting for it to 2935 // come up (we have a pid but not yet its thread), so keep it. 2936 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2937 // If this is a new package in the process, add the package to the list 2938 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2939 checkTime(startTime, "startProcess: done, added package to proc"); 2940 return app; 2941 } 2942 2943 // An application record is attached to a previous process, 2944 // clean it up now. 2945 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2946 checkTime(startTime, "startProcess: bad proc running, killing"); 2947 Process.killProcessGroup(app.info.uid, app.pid); 2948 handleAppDiedLocked(app, true, true); 2949 checkTime(startTime, "startProcess: done killing old proc"); 2950 } 2951 2952 String hostingNameStr = hostingName != null 2953 ? hostingName.flattenToShortString() : null; 2954 2955 if (!isolated) { 2956 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2957 // If we are in the background, then check to see if this process 2958 // is bad. If so, we will just silently fail. 2959 if (mBadProcesses.get(info.processName, info.uid) != null) { 2960 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2961 + "/" + info.processName); 2962 return null; 2963 } 2964 } else { 2965 // When the user is explicitly starting a process, then clear its 2966 // crash count so that we won't make it bad until they see at 2967 // least one crash dialog again, and make the process good again 2968 // if it had been bad. 2969 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2970 + "/" + info.processName); 2971 mProcessCrashTimes.remove(info.processName, info.uid); 2972 if (mBadProcesses.get(info.processName, info.uid) != null) { 2973 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2974 UserHandle.getUserId(info.uid), info.uid, 2975 info.processName); 2976 mBadProcesses.remove(info.processName, info.uid); 2977 if (app != null) { 2978 app.bad = false; 2979 } 2980 } 2981 } 2982 } 2983 2984 if (app == null) { 2985 checkTime(startTime, "startProcess: creating new process record"); 2986 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2987 app.crashHandler = crashHandler; 2988 if (app == null) { 2989 Slog.w(TAG, "Failed making new process record for " 2990 + processName + "/" + info.uid + " isolated=" + isolated); 2991 return null; 2992 } 2993 mProcessNames.put(processName, app.uid, app); 2994 if (isolated) { 2995 mIsolatedProcesses.put(app.uid, app); 2996 } 2997 checkTime(startTime, "startProcess: done creating new process record"); 2998 } else { 2999 // If this is a new package in the process, add the package to the list 3000 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3001 checkTime(startTime, "startProcess: added package to existing proc"); 3002 } 3003 3004 // If the system is not ready yet, then hold off on starting this 3005 // process until it is. 3006 if (!mProcessesReady 3007 && !isAllowedWhileBooting(info) 3008 && !allowWhileBooting) { 3009 if (!mProcessesOnHold.contains(app)) { 3010 mProcessesOnHold.add(app); 3011 } 3012 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3013 checkTime(startTime, "startProcess: returning with proc on hold"); 3014 return app; 3015 } 3016 3017 checkTime(startTime, "startProcess: stepping in to startProcess"); 3018 startProcessLocked( 3019 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3020 checkTime(startTime, "startProcess: done starting proc!"); 3021 return (app.pid != 0) ? app : null; 3022 } 3023 3024 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3025 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3026 } 3027 3028 private final void startProcessLocked(ProcessRecord app, 3029 String hostingType, String hostingNameStr) { 3030 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3031 null /* entryPoint */, null /* entryPointArgs */); 3032 } 3033 3034 private final void startProcessLocked(ProcessRecord app, String hostingType, 3035 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3036 long startTime = SystemClock.elapsedRealtime(); 3037 if (app.pid > 0 && app.pid != MY_PID) { 3038 checkTime(startTime, "startProcess: removing from pids map"); 3039 synchronized (mPidsSelfLocked) { 3040 mPidsSelfLocked.remove(app.pid); 3041 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3042 } 3043 checkTime(startTime, "startProcess: done removing from pids map"); 3044 app.setPid(0); 3045 } 3046 3047 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3048 "startProcessLocked removing on hold: " + app); 3049 mProcessesOnHold.remove(app); 3050 3051 checkTime(startTime, "startProcess: starting to update cpu stats"); 3052 updateCpuStats(); 3053 checkTime(startTime, "startProcess: done updating cpu stats"); 3054 3055 try { 3056 int uid = app.uid; 3057 3058 int[] gids = null; 3059 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3060 if (!app.isolated) { 3061 int[] permGids = null; 3062 try { 3063 checkTime(startTime, "startProcess: getting gids from package manager"); 3064 final PackageManager pm = mContext.getPackageManager(); 3065 permGids = pm.getPackageGids(app.info.packageName); 3066 3067 if (Environment.isExternalStorageEmulated()) { 3068 checkTime(startTime, "startProcess: checking external storage perm"); 3069 if (pm.checkPermission( 3070 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3071 app.info.packageName) == PERMISSION_GRANTED) { 3072 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3073 } else { 3074 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3075 } 3076 } 3077 } catch (PackageManager.NameNotFoundException e) { 3078 Slog.w(TAG, "Unable to retrieve gids", e); 3079 } 3080 3081 /* 3082 * Add shared application and profile GIDs so applications can share some 3083 * resources like shared libraries and access user-wide resources 3084 */ 3085 if (permGids == null) { 3086 gids = new int[2]; 3087 } else { 3088 gids = new int[permGids.length + 2]; 3089 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3090 } 3091 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3092 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3093 } 3094 checkTime(startTime, "startProcess: building args"); 3095 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3096 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3097 && mTopComponent != null 3098 && app.processName.equals(mTopComponent.getPackageName())) { 3099 uid = 0; 3100 } 3101 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3102 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3103 uid = 0; 3104 } 3105 } 3106 int debugFlags = 0; 3107 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3108 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3109 // Also turn on CheckJNI for debuggable apps. It's quite 3110 // awkward to turn on otherwise. 3111 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3112 } 3113 // Run the app in safe mode if its manifest requests so or the 3114 // system is booted in safe mode. 3115 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3116 mSafeMode == true) { 3117 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3118 } 3119 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3120 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3121 } 3122 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3123 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3124 } 3125 if ("1".equals(SystemProperties.get("debug.assert"))) { 3126 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3127 } 3128 3129 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3130 if (requiredAbi == null) { 3131 requiredAbi = Build.SUPPORTED_ABIS[0]; 3132 } 3133 3134 String instructionSet = null; 3135 if (app.info.primaryCpuAbi != null) { 3136 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3137 } 3138 3139 // Start the process. It will either succeed and return a result containing 3140 // the PID of the new process, or else throw a RuntimeException. 3141 boolean isActivityProcess = (entryPoint == null); 3142 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3143 checkTime(startTime, "startProcess: asking zygote to start proc"); 3144 Process.ProcessStartResult startResult = Process.start(entryPoint, 3145 app.processName, uid, uid, gids, debugFlags, mountExternal, 3146 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3147 entryPointArgs); 3148 checkTime(startTime, "startProcess: returned from zygote!"); 3149 3150 if (app.isolated) { 3151 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3152 } 3153 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3154 checkTime(startTime, "startProcess: done updating battery stats"); 3155 3156 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3157 UserHandle.getUserId(uid), startResult.pid, uid, 3158 app.processName, hostingType, 3159 hostingNameStr != null ? hostingNameStr : ""); 3160 3161 if (app.persistent) { 3162 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3163 } 3164 3165 checkTime(startTime, "startProcess: building log message"); 3166 StringBuilder buf = mStringBuilder; 3167 buf.setLength(0); 3168 buf.append("Start proc "); 3169 buf.append(app.processName); 3170 if (!isActivityProcess) { 3171 buf.append(" ["); 3172 buf.append(entryPoint); 3173 buf.append("]"); 3174 } 3175 buf.append(" for "); 3176 buf.append(hostingType); 3177 if (hostingNameStr != null) { 3178 buf.append(" "); 3179 buf.append(hostingNameStr); 3180 } 3181 buf.append(": pid="); 3182 buf.append(startResult.pid); 3183 buf.append(" uid="); 3184 buf.append(uid); 3185 buf.append(" gids={"); 3186 if (gids != null) { 3187 for (int gi=0; gi<gids.length; gi++) { 3188 if (gi != 0) buf.append(", "); 3189 buf.append(gids[gi]); 3190 3191 } 3192 } 3193 buf.append("}"); 3194 if (requiredAbi != null) { 3195 buf.append(" abi="); 3196 buf.append(requiredAbi); 3197 } 3198 Slog.i(TAG, buf.toString()); 3199 app.setPid(startResult.pid); 3200 app.usingWrapper = startResult.usingWrapper; 3201 app.removed = false; 3202 app.killedByAm = false; 3203 checkTime(startTime, "startProcess: starting to update pids map"); 3204 synchronized (mPidsSelfLocked) { 3205 this.mPidsSelfLocked.put(startResult.pid, app); 3206 if (isActivityProcess) { 3207 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3208 msg.obj = app; 3209 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3210 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3211 } 3212 } 3213 checkTime(startTime, "startProcess: done updating pids map"); 3214 } catch (RuntimeException e) { 3215 // XXX do better error recovery. 3216 app.setPid(0); 3217 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3218 if (app.isolated) { 3219 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3220 } 3221 Slog.e(TAG, "Failure starting process " + app.processName, e); 3222 } 3223 } 3224 3225 void updateUsageStats(ActivityRecord component, boolean resumed) { 3226 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3227 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3228 if (resumed) { 3229 if (mUsageStatsService != null) { 3230 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3231 UsageEvents.Event.MOVE_TO_FOREGROUND); 3232 } 3233 synchronized (stats) { 3234 stats.noteActivityResumedLocked(component.app.uid); 3235 } 3236 } else { 3237 if (mUsageStatsService != null) { 3238 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3239 UsageEvents.Event.MOVE_TO_BACKGROUND); 3240 } 3241 synchronized (stats) { 3242 stats.noteActivityPausedLocked(component.app.uid); 3243 } 3244 } 3245 } 3246 3247 Intent getHomeIntent() { 3248 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3249 intent.setComponent(mTopComponent); 3250 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3251 intent.addCategory(Intent.CATEGORY_HOME); 3252 } 3253 return intent; 3254 } 3255 3256 boolean startHomeActivityLocked(int userId) { 3257 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3258 && mTopAction == null) { 3259 // We are running in factory test mode, but unable to find 3260 // the factory test app, so just sit around displaying the 3261 // error message and don't try to start anything. 3262 return false; 3263 } 3264 Intent intent = getHomeIntent(); 3265 ActivityInfo aInfo = 3266 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3267 if (aInfo != null) { 3268 intent.setComponent(new ComponentName( 3269 aInfo.applicationInfo.packageName, aInfo.name)); 3270 // Don't do this if the home app is currently being 3271 // instrumented. 3272 aInfo = new ActivityInfo(aInfo); 3273 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3274 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3275 aInfo.applicationInfo.uid, true); 3276 if (app == null || app.instrumentationClass == null) { 3277 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3278 mStackSupervisor.startHomeActivity(intent, aInfo); 3279 } 3280 } 3281 3282 return true; 3283 } 3284 3285 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3286 ActivityInfo ai = null; 3287 ComponentName comp = intent.getComponent(); 3288 try { 3289 if (comp != null) { 3290 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3291 } else { 3292 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3293 intent, 3294 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3295 flags, userId); 3296 3297 if (info != null) { 3298 ai = info.activityInfo; 3299 } 3300 } 3301 } catch (RemoteException e) { 3302 // ignore 3303 } 3304 3305 return ai; 3306 } 3307 3308 /** 3309 * Starts the "new version setup screen" if appropriate. 3310 */ 3311 void startSetupActivityLocked() { 3312 // Only do this once per boot. 3313 if (mCheckedForSetup) { 3314 return; 3315 } 3316 3317 // We will show this screen if the current one is a different 3318 // version than the last one shown, and we are not running in 3319 // low-level factory test mode. 3320 final ContentResolver resolver = mContext.getContentResolver(); 3321 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3322 Settings.Global.getInt(resolver, 3323 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3324 mCheckedForSetup = true; 3325 3326 // See if we should be showing the platform update setup UI. 3327 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3328 List<ResolveInfo> ris = mContext.getPackageManager() 3329 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3330 3331 // We don't allow third party apps to replace this. 3332 ResolveInfo ri = null; 3333 for (int i=0; ris != null && i<ris.size(); i++) { 3334 if ((ris.get(i).activityInfo.applicationInfo.flags 3335 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3336 ri = ris.get(i); 3337 break; 3338 } 3339 } 3340 3341 if (ri != null) { 3342 String vers = ri.activityInfo.metaData != null 3343 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3344 : null; 3345 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3346 vers = ri.activityInfo.applicationInfo.metaData.getString( 3347 Intent.METADATA_SETUP_VERSION); 3348 } 3349 String lastVers = Settings.Secure.getString( 3350 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3351 if (vers != null && !vers.equals(lastVers)) { 3352 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3353 intent.setComponent(new ComponentName( 3354 ri.activityInfo.packageName, ri.activityInfo.name)); 3355 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3356 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3357 null); 3358 } 3359 } 3360 } 3361 } 3362 3363 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3364 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3365 } 3366 3367 void enforceNotIsolatedCaller(String caller) { 3368 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3369 throw new SecurityException("Isolated process not allowed to call " + caller); 3370 } 3371 } 3372 3373 void enforceShellRestriction(String restriction, int userHandle) { 3374 if (Binder.getCallingUid() == Process.SHELL_UID) { 3375 if (userHandle < 0 3376 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3377 throw new SecurityException("Shell does not have permission to access user " 3378 + userHandle); 3379 } 3380 } 3381 } 3382 3383 @Override 3384 public int getFrontActivityScreenCompatMode() { 3385 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3386 synchronized (this) { 3387 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3388 } 3389 } 3390 3391 @Override 3392 public void setFrontActivityScreenCompatMode(int mode) { 3393 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3394 "setFrontActivityScreenCompatMode"); 3395 synchronized (this) { 3396 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3397 } 3398 } 3399 3400 @Override 3401 public int getPackageScreenCompatMode(String packageName) { 3402 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3403 synchronized (this) { 3404 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3405 } 3406 } 3407 3408 @Override 3409 public void setPackageScreenCompatMode(String packageName, int mode) { 3410 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3411 "setPackageScreenCompatMode"); 3412 synchronized (this) { 3413 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3414 } 3415 } 3416 3417 @Override 3418 public boolean getPackageAskScreenCompat(String packageName) { 3419 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3420 synchronized (this) { 3421 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3422 } 3423 } 3424 3425 @Override 3426 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3427 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3428 "setPackageAskScreenCompat"); 3429 synchronized (this) { 3430 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3431 } 3432 } 3433 3434 private void dispatchProcessesChanged() { 3435 int N; 3436 synchronized (this) { 3437 N = mPendingProcessChanges.size(); 3438 if (mActiveProcessChanges.length < N) { 3439 mActiveProcessChanges = new ProcessChangeItem[N]; 3440 } 3441 mPendingProcessChanges.toArray(mActiveProcessChanges); 3442 mAvailProcessChanges.addAll(mPendingProcessChanges); 3443 mPendingProcessChanges.clear(); 3444 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3445 } 3446 3447 int i = mProcessObservers.beginBroadcast(); 3448 while (i > 0) { 3449 i--; 3450 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3451 if (observer != null) { 3452 try { 3453 for (int j=0; j<N; j++) { 3454 ProcessChangeItem item = mActiveProcessChanges[j]; 3455 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3456 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3457 + item.pid + " uid=" + item.uid + ": " 3458 + item.foregroundActivities); 3459 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3460 item.foregroundActivities); 3461 } 3462 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3463 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3464 + item.pid + " uid=" + item.uid + ": " + item.processState); 3465 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3466 } 3467 } 3468 } catch (RemoteException e) { 3469 } 3470 } 3471 } 3472 mProcessObservers.finishBroadcast(); 3473 } 3474 3475 private void dispatchProcessDied(int pid, int uid) { 3476 int i = mProcessObservers.beginBroadcast(); 3477 while (i > 0) { 3478 i--; 3479 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3480 if (observer != null) { 3481 try { 3482 observer.onProcessDied(pid, uid); 3483 } catch (RemoteException e) { 3484 } 3485 } 3486 } 3487 mProcessObservers.finishBroadcast(); 3488 } 3489 3490 @Override 3491 public final int startActivity(IApplicationThread caller, String callingPackage, 3492 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3493 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3494 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3495 resultWho, requestCode, startFlags, profilerInfo, options, 3496 UserHandle.getCallingUserId()); 3497 } 3498 3499 @Override 3500 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3501 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3502 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3503 enforceNotIsolatedCaller("startActivity"); 3504 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3505 false, ALLOW_FULL_ONLY, "startActivity", null); 3506 // TODO: Switch to user app stacks here. 3507 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3508 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3509 profilerInfo, null, null, options, userId, null, null); 3510 } 3511 3512 @Override 3513 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3514 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3515 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3516 3517 // This is very dangerous -- it allows you to perform a start activity (including 3518 // permission grants) as any app that may launch one of your own activities. So 3519 // we will only allow this to be done from activities that are part of the core framework, 3520 // and then only when they are running as the system. 3521 final ActivityRecord sourceRecord; 3522 final int targetUid; 3523 final String targetPackage; 3524 synchronized (this) { 3525 if (resultTo == null) { 3526 throw new SecurityException("Must be called from an activity"); 3527 } 3528 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3529 if (sourceRecord == null) { 3530 throw new SecurityException("Called with bad activity token: " + resultTo); 3531 } 3532 if (!sourceRecord.info.packageName.equals("android")) { 3533 throw new SecurityException( 3534 "Must be called from an activity that is declared in the android package"); 3535 } 3536 if (sourceRecord.app == null) { 3537 throw new SecurityException("Called without a process attached to activity"); 3538 } 3539 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3540 // This is still okay, as long as this activity is running under the 3541 // uid of the original calling activity. 3542 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3543 throw new SecurityException( 3544 "Calling activity in uid " + sourceRecord.app.uid 3545 + " must be system uid or original calling uid " 3546 + sourceRecord.launchedFromUid); 3547 } 3548 } 3549 targetUid = sourceRecord.launchedFromUid; 3550 targetPackage = sourceRecord.launchedFromPackage; 3551 } 3552 3553 // TODO: Switch to user app stacks here. 3554 try { 3555 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3556 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3557 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3558 return ret; 3559 } catch (SecurityException e) { 3560 // XXX need to figure out how to propagate to original app. 3561 // A SecurityException here is generally actually a fault of the original 3562 // calling activity (such as a fairly granting permissions), so propagate it 3563 // back to them. 3564 /* 3565 StringBuilder msg = new StringBuilder(); 3566 msg.append("While launching"); 3567 msg.append(intent.toString()); 3568 msg.append(": "); 3569 msg.append(e.getMessage()); 3570 */ 3571 throw e; 3572 } 3573 } 3574 3575 @Override 3576 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3577 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3578 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3579 enforceNotIsolatedCaller("startActivityAndWait"); 3580 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3581 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3582 WaitResult res = new WaitResult(); 3583 // TODO: Switch to user app stacks here. 3584 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3585 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3586 options, userId, null, null); 3587 return res; 3588 } 3589 3590 @Override 3591 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3592 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3593 int startFlags, Configuration config, Bundle options, int userId) { 3594 enforceNotIsolatedCaller("startActivityWithConfig"); 3595 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3596 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3597 // TODO: Switch to user app stacks here. 3598 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3599 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3600 null, null, config, options, userId, null, null); 3601 return ret; 3602 } 3603 3604 @Override 3605 public int startActivityIntentSender(IApplicationThread caller, 3606 IntentSender intent, Intent fillInIntent, String resolvedType, 3607 IBinder resultTo, String resultWho, int requestCode, 3608 int flagsMask, int flagsValues, Bundle options) { 3609 enforceNotIsolatedCaller("startActivityIntentSender"); 3610 // Refuse possible leaked file descriptors 3611 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3612 throw new IllegalArgumentException("File descriptors passed in Intent"); 3613 } 3614 3615 IIntentSender sender = intent.getTarget(); 3616 if (!(sender instanceof PendingIntentRecord)) { 3617 throw new IllegalArgumentException("Bad PendingIntent object"); 3618 } 3619 3620 PendingIntentRecord pir = (PendingIntentRecord)sender; 3621 3622 synchronized (this) { 3623 // If this is coming from the currently resumed activity, it is 3624 // effectively saying that app switches are allowed at this point. 3625 final ActivityStack stack = getFocusedStack(); 3626 if (stack.mResumedActivity != null && 3627 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3628 mAppSwitchesAllowedTime = 0; 3629 } 3630 } 3631 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3632 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3633 return ret; 3634 } 3635 3636 @Override 3637 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3638 Intent intent, String resolvedType, IVoiceInteractionSession session, 3639 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3640 Bundle options, int userId) { 3641 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3642 != PackageManager.PERMISSION_GRANTED) { 3643 String msg = "Permission Denial: startVoiceActivity() from pid=" 3644 + Binder.getCallingPid() 3645 + ", uid=" + Binder.getCallingUid() 3646 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3647 Slog.w(TAG, msg); 3648 throw new SecurityException(msg); 3649 } 3650 if (session == null || interactor == null) { 3651 throw new NullPointerException("null session or interactor"); 3652 } 3653 userId = handleIncomingUser(callingPid, callingUid, userId, 3654 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3655 // TODO: Switch to user app stacks here. 3656 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3657 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3658 null, options, userId, null, null); 3659 } 3660 3661 @Override 3662 public boolean startNextMatchingActivity(IBinder callingActivity, 3663 Intent intent, Bundle options) { 3664 // Refuse possible leaked file descriptors 3665 if (intent != null && intent.hasFileDescriptors() == true) { 3666 throw new IllegalArgumentException("File descriptors passed in Intent"); 3667 } 3668 3669 synchronized (this) { 3670 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3671 if (r == null) { 3672 ActivityOptions.abort(options); 3673 return false; 3674 } 3675 if (r.app == null || r.app.thread == null) { 3676 // The caller is not running... d'oh! 3677 ActivityOptions.abort(options); 3678 return false; 3679 } 3680 intent = new Intent(intent); 3681 // The caller is not allowed to change the data. 3682 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3683 // And we are resetting to find the next component... 3684 intent.setComponent(null); 3685 3686 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3687 3688 ActivityInfo aInfo = null; 3689 try { 3690 List<ResolveInfo> resolves = 3691 AppGlobals.getPackageManager().queryIntentActivities( 3692 intent, r.resolvedType, 3693 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3694 UserHandle.getCallingUserId()); 3695 3696 // Look for the original activity in the list... 3697 final int N = resolves != null ? resolves.size() : 0; 3698 for (int i=0; i<N; i++) { 3699 ResolveInfo rInfo = resolves.get(i); 3700 if (rInfo.activityInfo.packageName.equals(r.packageName) 3701 && rInfo.activityInfo.name.equals(r.info.name)) { 3702 // We found the current one... the next matching is 3703 // after it. 3704 i++; 3705 if (i<N) { 3706 aInfo = resolves.get(i).activityInfo; 3707 } 3708 if (debug) { 3709 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3710 + "/" + r.info.name); 3711 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3712 + "/" + aInfo.name); 3713 } 3714 break; 3715 } 3716 } 3717 } catch (RemoteException e) { 3718 } 3719 3720 if (aInfo == null) { 3721 // Nobody who is next! 3722 ActivityOptions.abort(options); 3723 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3724 return false; 3725 } 3726 3727 intent.setComponent(new ComponentName( 3728 aInfo.applicationInfo.packageName, aInfo.name)); 3729 intent.setFlags(intent.getFlags()&~( 3730 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3731 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3732 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3733 Intent.FLAG_ACTIVITY_NEW_TASK)); 3734 3735 // Okay now we need to start the new activity, replacing the 3736 // currently running activity. This is a little tricky because 3737 // we want to start the new one as if the current one is finished, 3738 // but not finish the current one first so that there is no flicker. 3739 // And thus... 3740 final boolean wasFinishing = r.finishing; 3741 r.finishing = true; 3742 3743 // Propagate reply information over to the new activity. 3744 final ActivityRecord resultTo = r.resultTo; 3745 final String resultWho = r.resultWho; 3746 final int requestCode = r.requestCode; 3747 r.resultTo = null; 3748 if (resultTo != null) { 3749 resultTo.removeResultsLocked(r, resultWho, requestCode); 3750 } 3751 3752 final long origId = Binder.clearCallingIdentity(); 3753 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3754 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3755 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3756 options, false, null, null, null); 3757 Binder.restoreCallingIdentity(origId); 3758 3759 r.finishing = wasFinishing; 3760 if (res != ActivityManager.START_SUCCESS) { 3761 return false; 3762 } 3763 return true; 3764 } 3765 } 3766 3767 @Override 3768 public final int startActivityFromRecents(int taskId, Bundle options) { 3769 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3770 String msg = "Permission Denial: startActivityFromRecents called without " + 3771 START_TASKS_FROM_RECENTS; 3772 Slog.w(TAG, msg); 3773 throw new SecurityException(msg); 3774 } 3775 return startActivityFromRecentsInner(taskId, options); 3776 } 3777 3778 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3779 final TaskRecord task; 3780 final int callingUid; 3781 final String callingPackage; 3782 final Intent intent; 3783 final int userId; 3784 synchronized (this) { 3785 task = recentTaskForIdLocked(taskId); 3786 if (task == null) { 3787 throw new IllegalArgumentException("Task " + taskId + " not found."); 3788 } 3789 callingUid = task.mCallingUid; 3790 callingPackage = task.mCallingPackage; 3791 intent = task.intent; 3792 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3793 userId = task.userId; 3794 } 3795 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3796 options, userId, null, task); 3797 } 3798 3799 final int startActivityInPackage(int uid, String callingPackage, 3800 Intent intent, String resolvedType, IBinder resultTo, 3801 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3802 IActivityContainer container, TaskRecord inTask) { 3803 3804 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3805 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3806 3807 // TODO: Switch to user app stacks here. 3808 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3809 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3810 null, null, null, options, userId, container, inTask); 3811 return ret; 3812 } 3813 3814 @Override 3815 public final int startActivities(IApplicationThread caller, String callingPackage, 3816 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3817 int userId) { 3818 enforceNotIsolatedCaller("startActivities"); 3819 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3820 false, ALLOW_FULL_ONLY, "startActivity", null); 3821 // TODO: Switch to user app stacks here. 3822 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3823 resolvedTypes, resultTo, options, userId); 3824 return ret; 3825 } 3826 3827 final int startActivitiesInPackage(int uid, String callingPackage, 3828 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3829 Bundle options, int userId) { 3830 3831 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3832 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3833 // TODO: Switch to user app stacks here. 3834 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3835 resultTo, options, userId); 3836 return ret; 3837 } 3838 3839 //explicitly remove thd old information in mRecentTasks when removing existing user. 3840 private void removeRecentTasksForUserLocked(int userId) { 3841 if(userId <= 0) { 3842 Slog.i(TAG, "Can't remove recent task on user " + userId); 3843 return; 3844 } 3845 3846 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3847 TaskRecord tr = mRecentTasks.get(i); 3848 if (tr.userId == userId) { 3849 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3850 + " when finishing user" + userId); 3851 mRecentTasks.remove(i); 3852 tr.removedFromRecents(mTaskPersister); 3853 } 3854 } 3855 3856 // Remove tasks from persistent storage. 3857 mTaskPersister.wakeup(null, true); 3858 } 3859 3860 // Sort by taskId 3861 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3862 @Override 3863 public int compare(TaskRecord lhs, TaskRecord rhs) { 3864 return rhs.taskId - lhs.taskId; 3865 } 3866 }; 3867 3868 // Extract the affiliates of the chain containing mRecentTasks[start]. 3869 private int processNextAffiliateChain(int start) { 3870 final TaskRecord startTask = mRecentTasks.get(start); 3871 final int affiliateId = startTask.mAffiliatedTaskId; 3872 3873 // Quick identification of isolated tasks. I.e. those not launched behind. 3874 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3875 startTask.mNextAffiliate == null) { 3876 // There is still a slim chance that there are other tasks that point to this task 3877 // and that the chain is so messed up that this task no longer points to them but 3878 // the gain of this optimization outweighs the risk. 3879 startTask.inRecents = true; 3880 return start + 1; 3881 } 3882 3883 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3884 mTmpRecents.clear(); 3885 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3886 final TaskRecord task = mRecentTasks.get(i); 3887 if (task.mAffiliatedTaskId == affiliateId) { 3888 mRecentTasks.remove(i); 3889 mTmpRecents.add(task); 3890 } 3891 } 3892 3893 // Sort them all by taskId. That is the order they were create in and that order will 3894 // always be correct. 3895 Collections.sort(mTmpRecents, mTaskRecordComparator); 3896 3897 // Go through and fix up the linked list. 3898 // The first one is the end of the chain and has no next. 3899 final TaskRecord first = mTmpRecents.get(0); 3900 first.inRecents = true; 3901 if (first.mNextAffiliate != null) { 3902 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3903 first.setNextAffiliate(null); 3904 mTaskPersister.wakeup(first, false); 3905 } 3906 // Everything in the middle is doubly linked from next to prev. 3907 final int tmpSize = mTmpRecents.size(); 3908 for (int i = 0; i < tmpSize - 1; ++i) { 3909 final TaskRecord next = mTmpRecents.get(i); 3910 final TaskRecord prev = mTmpRecents.get(i + 1); 3911 if (next.mPrevAffiliate != prev) { 3912 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3913 " setting prev=" + prev); 3914 next.setPrevAffiliate(prev); 3915 mTaskPersister.wakeup(next, false); 3916 } 3917 if (prev.mNextAffiliate != next) { 3918 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3919 " setting next=" + next); 3920 prev.setNextAffiliate(next); 3921 mTaskPersister.wakeup(prev, false); 3922 } 3923 prev.inRecents = true; 3924 } 3925 // The last one is the beginning of the list and has no prev. 3926 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3927 if (last.mPrevAffiliate != null) { 3928 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3929 last.setPrevAffiliate(null); 3930 mTaskPersister.wakeup(last, false); 3931 } 3932 3933 // Insert the group back into mRecentTasks at start. 3934 mRecentTasks.addAll(start, mTmpRecents); 3935 3936 // Let the caller know where we left off. 3937 return start + tmpSize; 3938 } 3939 3940 /** 3941 * Update the recent tasks lists: make sure tasks should still be here (their 3942 * applications / activities still exist), update their availability, fixup ordering 3943 * of affiliations. 3944 */ 3945 void cleanupRecentTasksLocked(int userId) { 3946 if (mRecentTasks == null) { 3947 // Happens when called from the packagemanager broadcast before boot. 3948 return; 3949 } 3950 3951 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3952 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3953 final IPackageManager pm = AppGlobals.getPackageManager(); 3954 final ActivityInfo dummyAct = new ActivityInfo(); 3955 final ApplicationInfo dummyApp = new ApplicationInfo(); 3956 3957 int N = mRecentTasks.size(); 3958 3959 int[] users = userId == UserHandle.USER_ALL 3960 ? getUsersLocked() : new int[] { userId }; 3961 for (int user : users) { 3962 for (int i = 0; i < N; i++) { 3963 TaskRecord task = mRecentTasks.get(i); 3964 if (task.userId != user) { 3965 // Only look at tasks for the user ID of interest. 3966 continue; 3967 } 3968 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3969 // This situation is broken, and we should just get rid of it now. 3970 mRecentTasks.remove(i); 3971 task.removedFromRecents(mTaskPersister); 3972 i--; 3973 N--; 3974 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3975 continue; 3976 } 3977 // Check whether this activity is currently available. 3978 if (task.realActivity != null) { 3979 ActivityInfo ai = availActCache.get(task.realActivity); 3980 if (ai == null) { 3981 try { 3982 ai = pm.getActivityInfo(task.realActivity, 3983 PackageManager.GET_UNINSTALLED_PACKAGES 3984 | PackageManager.GET_DISABLED_COMPONENTS, user); 3985 } catch (RemoteException e) { 3986 // Will never happen. 3987 continue; 3988 } 3989 if (ai == null) { 3990 ai = dummyAct; 3991 } 3992 availActCache.put(task.realActivity, ai); 3993 } 3994 if (ai == dummyAct) { 3995 // This could be either because the activity no longer exists, or the 3996 // app is temporarily gone. For the former we want to remove the recents 3997 // entry; for the latter we want to mark it as unavailable. 3998 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3999 if (app == null) { 4000 try { 4001 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4002 PackageManager.GET_UNINSTALLED_PACKAGES 4003 | PackageManager.GET_DISABLED_COMPONENTS, user); 4004 } catch (RemoteException e) { 4005 // Will never happen. 4006 continue; 4007 } 4008 if (app == null) { 4009 app = dummyApp; 4010 } 4011 availAppCache.put(task.realActivity.getPackageName(), app); 4012 } 4013 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4014 // Doesn't exist any more! Good-bye. 4015 mRecentTasks.remove(i); 4016 task.removedFromRecents(mTaskPersister); 4017 i--; 4018 N--; 4019 Slog.w(TAG, "Removing no longer valid recent: " + task); 4020 continue; 4021 } else { 4022 // Otherwise just not available for now. 4023 if (task.isAvailable) { 4024 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4025 + task); 4026 } 4027 task.isAvailable = false; 4028 } 4029 } else { 4030 if (!ai.enabled || !ai.applicationInfo.enabled 4031 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4032 if (task.isAvailable) { 4033 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4034 + task + " (enabled=" + ai.enabled + "/" 4035 + ai.applicationInfo.enabled + " flags=" 4036 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4037 } 4038 task.isAvailable = false; 4039 } else { 4040 if (!task.isAvailable) { 4041 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4042 + task); 4043 } 4044 task.isAvailable = true; 4045 } 4046 } 4047 } 4048 } 4049 } 4050 4051 // Verify the affiliate chain for each task. 4052 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4053 } 4054 4055 mTmpRecents.clear(); 4056 // mRecentTasks is now in sorted, affiliated order. 4057 } 4058 4059 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4060 int N = mRecentTasks.size(); 4061 TaskRecord top = task; 4062 int topIndex = taskIndex; 4063 while (top.mNextAffiliate != null && topIndex > 0) { 4064 top = top.mNextAffiliate; 4065 topIndex--; 4066 } 4067 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4068 + topIndex + " from intial " + taskIndex); 4069 // Find the end of the chain, doing a sanity check along the way. 4070 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4071 int endIndex = topIndex; 4072 TaskRecord prev = top; 4073 while (endIndex < N) { 4074 TaskRecord cur = mRecentTasks.get(endIndex); 4075 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4076 + endIndex + " " + cur); 4077 if (cur == top) { 4078 // Verify start of the chain. 4079 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4080 Slog.wtf(TAG, "Bad chain @" + endIndex 4081 + ": first task has next affiliate: " + prev); 4082 sane = false; 4083 break; 4084 } 4085 } else { 4086 // Verify middle of the chain's next points back to the one before. 4087 if (cur.mNextAffiliate != prev 4088 || cur.mNextAffiliateTaskId != prev.taskId) { 4089 Slog.wtf(TAG, "Bad chain @" + endIndex 4090 + ": middle task " + cur + " @" + endIndex 4091 + " has bad next affiliate " 4092 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4093 + ", expected " + prev); 4094 sane = false; 4095 break; 4096 } 4097 } 4098 if (cur.mPrevAffiliateTaskId == -1) { 4099 // Chain ends here. 4100 if (cur.mPrevAffiliate != null) { 4101 Slog.wtf(TAG, "Bad chain @" + endIndex 4102 + ": last task " + cur + " has previous affiliate " 4103 + cur.mPrevAffiliate); 4104 sane = false; 4105 } 4106 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4107 break; 4108 } else { 4109 // Verify middle of the chain's prev points to a valid item. 4110 if (cur.mPrevAffiliate == null) { 4111 Slog.wtf(TAG, "Bad chain @" + endIndex 4112 + ": task " + cur + " has previous affiliate " 4113 + cur.mPrevAffiliate + " but should be id " 4114 + cur.mPrevAffiliate); 4115 sane = false; 4116 break; 4117 } 4118 } 4119 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4120 Slog.wtf(TAG, "Bad chain @" + endIndex 4121 + ": task " + cur + " has affiliated id " 4122 + cur.mAffiliatedTaskId + " but should be " 4123 + task.mAffiliatedTaskId); 4124 sane = false; 4125 break; 4126 } 4127 prev = cur; 4128 endIndex++; 4129 if (endIndex >= N) { 4130 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4131 + ": last task " + prev); 4132 sane = false; 4133 break; 4134 } 4135 } 4136 if (sane) { 4137 if (endIndex < taskIndex) { 4138 Slog.wtf(TAG, "Bad chain @" + endIndex 4139 + ": did not extend to task " + task + " @" + taskIndex); 4140 sane = false; 4141 } 4142 } 4143 if (sane) { 4144 // All looks good, we can just move all of the affiliated tasks 4145 // to the top. 4146 for (int i=topIndex; i<=endIndex; i++) { 4147 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4148 + " from " + i + " to " + (i-topIndex)); 4149 TaskRecord cur = mRecentTasks.remove(i); 4150 mRecentTasks.add(i-topIndex, cur); 4151 } 4152 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4153 + " to " + endIndex); 4154 return true; 4155 } 4156 4157 // Whoops, couldn't do it. 4158 return false; 4159 } 4160 4161 final void addRecentTaskLocked(TaskRecord task) { 4162 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4163 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4164 4165 int N = mRecentTasks.size(); 4166 // Quick case: check if the top-most recent task is the same. 4167 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4168 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4169 return; 4170 } 4171 // Another quick case: check if this is part of a set of affiliated 4172 // tasks that are at the top. 4173 if (isAffiliated && N > 0 && task.inRecents 4174 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4175 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4176 + " at top when adding " + task); 4177 return; 4178 } 4179 // Another quick case: never add voice sessions. 4180 if (task.voiceSession != null) { 4181 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4182 return; 4183 } 4184 4185 boolean needAffiliationFix = false; 4186 4187 // Slightly less quick case: the task is already in recents, so all we need 4188 // to do is move it. 4189 if (task.inRecents) { 4190 int taskIndex = mRecentTasks.indexOf(task); 4191 if (taskIndex >= 0) { 4192 if (!isAffiliated) { 4193 // Simple case: this is not an affiliated task, so we just move it to the front. 4194 mRecentTasks.remove(taskIndex); 4195 mRecentTasks.add(0, task); 4196 notifyTaskPersisterLocked(task, false); 4197 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4198 + " from " + taskIndex); 4199 return; 4200 } else { 4201 // More complicated: need to keep all affiliated tasks together. 4202 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4203 // All went well. 4204 return; 4205 } 4206 4207 // Uh oh... something bad in the affiliation chain, try to rebuild 4208 // everything and then go through our general path of adding a new task. 4209 needAffiliationFix = true; 4210 } 4211 } else { 4212 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4213 needAffiliationFix = true; 4214 } 4215 } 4216 4217 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4218 trimRecentsForTask(task, true); 4219 4220 N = mRecentTasks.size(); 4221 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4222 final TaskRecord tr = mRecentTasks.remove(N - 1); 4223 tr.removedFromRecents(mTaskPersister); 4224 N--; 4225 } 4226 task.inRecents = true; 4227 if (!isAffiliated || needAffiliationFix) { 4228 // If this is a simple non-affiliated task, or we had some failure trying to 4229 // handle it as part of an affilated task, then just place it at the top. 4230 mRecentTasks.add(0, task); 4231 } else if (isAffiliated) { 4232 // If this is a new affiliated task, then move all of the affiliated tasks 4233 // to the front and insert this new one. 4234 TaskRecord other = task.mNextAffiliate; 4235 if (other == null) { 4236 other = task.mPrevAffiliate; 4237 } 4238 if (other != null) { 4239 int otherIndex = mRecentTasks.indexOf(other); 4240 if (otherIndex >= 0) { 4241 // Insert new task at appropriate location. 4242 int taskIndex; 4243 if (other == task.mNextAffiliate) { 4244 // We found the index of our next affiliation, which is who is 4245 // before us in the list, so add after that point. 4246 taskIndex = otherIndex+1; 4247 } else { 4248 // We found the index of our previous affiliation, which is who is 4249 // after us in the list, so add at their position. 4250 taskIndex = otherIndex; 4251 } 4252 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4253 + taskIndex + ": " + task); 4254 mRecentTasks.add(taskIndex, task); 4255 4256 // Now move everything to the front. 4257 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4258 // All went well. 4259 return; 4260 } 4261 4262 // Uh oh... something bad in the affiliation chain, try to rebuild 4263 // everything and then go through our general path of adding a new task. 4264 needAffiliationFix = true; 4265 } else { 4266 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4267 + other); 4268 needAffiliationFix = true; 4269 } 4270 } else { 4271 if (DEBUG_RECENTS) Slog.d(TAG, 4272 "addRecent: adding affiliated task without next/prev:" + task); 4273 needAffiliationFix = true; 4274 } 4275 } 4276 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4277 4278 if (needAffiliationFix) { 4279 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4280 cleanupRecentTasksLocked(task.userId); 4281 } 4282 } 4283 4284 /** 4285 * If needed, remove oldest existing entries in recents that are for the same kind 4286 * of task as the given one. 4287 */ 4288 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4289 int N = mRecentTasks.size(); 4290 final Intent intent = task.intent; 4291 final boolean document = intent != null && intent.isDocument(); 4292 4293 int maxRecents = task.maxRecents - 1; 4294 for (int i=0; i<N; i++) { 4295 final TaskRecord tr = mRecentTasks.get(i); 4296 if (task != tr) { 4297 if (task.userId != tr.userId) { 4298 continue; 4299 } 4300 if (i > MAX_RECENT_BITMAPS) { 4301 tr.freeLastThumbnail(); 4302 } 4303 final Intent trIntent = tr.intent; 4304 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4305 (intent == null || !intent.filterEquals(trIntent))) { 4306 continue; 4307 } 4308 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4309 if (document && trIsDocument) { 4310 // These are the same document activity (not necessarily the same doc). 4311 if (maxRecents > 0) { 4312 --maxRecents; 4313 continue; 4314 } 4315 // Hit the maximum number of documents for this task. Fall through 4316 // and remove this document from recents. 4317 } else if (document || trIsDocument) { 4318 // Only one of these is a document. Not the droid we're looking for. 4319 continue; 4320 } 4321 } 4322 4323 if (!doTrim) { 4324 // If the caller is not actually asking for a trim, just tell them we reached 4325 // a point where the trim would happen. 4326 return i; 4327 } 4328 4329 // Either task and tr are the same or, their affinities match or their intents match 4330 // and neither of them is a document, or they are documents using the same activity 4331 // and their maxRecents has been reached. 4332 tr.disposeThumbnail(); 4333 mRecentTasks.remove(i); 4334 if (task != tr) { 4335 tr.removedFromRecents(mTaskPersister); 4336 } 4337 i--; 4338 N--; 4339 if (task.intent == null) { 4340 // If the new recent task we are adding is not fully 4341 // specified, then replace it with the existing recent task. 4342 task = tr; 4343 } 4344 notifyTaskPersisterLocked(tr, false); 4345 } 4346 4347 return -1; 4348 } 4349 4350 @Override 4351 public void reportActivityFullyDrawn(IBinder token) { 4352 synchronized (this) { 4353 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4354 if (r == null) { 4355 return; 4356 } 4357 r.reportFullyDrawnLocked(); 4358 } 4359 } 4360 4361 @Override 4362 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4363 synchronized (this) { 4364 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4365 if (r == null) { 4366 return; 4367 } 4368 final long origId = Binder.clearCallingIdentity(); 4369 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4370 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4371 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4372 if (config != null) { 4373 r.frozenBeforeDestroy = true; 4374 if (!updateConfigurationLocked(config, r, false, false)) { 4375 mStackSupervisor.resumeTopActivitiesLocked(); 4376 } 4377 } 4378 Binder.restoreCallingIdentity(origId); 4379 } 4380 } 4381 4382 @Override 4383 public int getRequestedOrientation(IBinder token) { 4384 synchronized (this) { 4385 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4386 if (r == null) { 4387 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4388 } 4389 return mWindowManager.getAppOrientation(r.appToken); 4390 } 4391 } 4392 4393 /** 4394 * This is the internal entry point for handling Activity.finish(). 4395 * 4396 * @param token The Binder token referencing the Activity we want to finish. 4397 * @param resultCode Result code, if any, from this Activity. 4398 * @param resultData Result data (Intent), if any, from this Activity. 4399 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4400 * the root Activity in the task. 4401 * 4402 * @return Returns true if the activity successfully finished, or false if it is still running. 4403 */ 4404 @Override 4405 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4406 boolean finishTask) { 4407 // Refuse possible leaked file descriptors 4408 if (resultData != null && resultData.hasFileDescriptors() == true) { 4409 throw new IllegalArgumentException("File descriptors passed in Intent"); 4410 } 4411 4412 synchronized(this) { 4413 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4414 if (r == null) { 4415 return true; 4416 } 4417 // Keep track of the root activity of the task before we finish it 4418 TaskRecord tr = r.task; 4419 ActivityRecord rootR = tr.getRootActivity(); 4420 // Do not allow task to finish in Lock Task mode. 4421 if (tr == mStackSupervisor.mLockTaskModeTask) { 4422 if (rootR == r) { 4423 mStackSupervisor.showLockTaskToast(); 4424 return false; 4425 } 4426 } 4427 if (mController != null) { 4428 // Find the first activity that is not finishing. 4429 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4430 if (next != null) { 4431 // ask watcher if this is allowed 4432 boolean resumeOK = true; 4433 try { 4434 resumeOK = mController.activityResuming(next.packageName); 4435 } catch (RemoteException e) { 4436 mController = null; 4437 Watchdog.getInstance().setActivityController(null); 4438 } 4439 4440 if (!resumeOK) { 4441 return false; 4442 } 4443 } 4444 } 4445 final long origId = Binder.clearCallingIdentity(); 4446 try { 4447 boolean res; 4448 if (finishTask && r == rootR) { 4449 // If requested, remove the task that is associated to this activity only if it 4450 // was the root activity in the task. The result code and data is ignored because 4451 // we don't support returning them across task boundaries. 4452 res = removeTaskByIdLocked(tr.taskId, 0); 4453 } else { 4454 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4455 resultData, "app-request", true); 4456 } 4457 return res; 4458 } finally { 4459 Binder.restoreCallingIdentity(origId); 4460 } 4461 } 4462 } 4463 4464 @Override 4465 public final void finishHeavyWeightApp() { 4466 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4467 != PackageManager.PERMISSION_GRANTED) { 4468 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4469 + Binder.getCallingPid() 4470 + ", uid=" + Binder.getCallingUid() 4471 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4472 Slog.w(TAG, msg); 4473 throw new SecurityException(msg); 4474 } 4475 4476 synchronized(this) { 4477 if (mHeavyWeightProcess == null) { 4478 return; 4479 } 4480 4481 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4482 mHeavyWeightProcess.activities); 4483 for (int i=0; i<activities.size(); i++) { 4484 ActivityRecord r = activities.get(i); 4485 if (!r.finishing) { 4486 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4487 null, "finish-heavy", true); 4488 } 4489 } 4490 4491 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4492 mHeavyWeightProcess.userId, 0)); 4493 mHeavyWeightProcess = null; 4494 } 4495 } 4496 4497 @Override 4498 public void crashApplication(int uid, int initialPid, String packageName, 4499 String message) { 4500 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4501 != PackageManager.PERMISSION_GRANTED) { 4502 String msg = "Permission Denial: crashApplication() from pid=" 4503 + Binder.getCallingPid() 4504 + ", uid=" + Binder.getCallingUid() 4505 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4506 Slog.w(TAG, msg); 4507 throw new SecurityException(msg); 4508 } 4509 4510 synchronized(this) { 4511 ProcessRecord proc = null; 4512 4513 // Figure out which process to kill. We don't trust that initialPid 4514 // still has any relation to current pids, so must scan through the 4515 // list. 4516 synchronized (mPidsSelfLocked) { 4517 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4518 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4519 if (p.uid != uid) { 4520 continue; 4521 } 4522 if (p.pid == initialPid) { 4523 proc = p; 4524 break; 4525 } 4526 if (p.pkgList.containsKey(packageName)) { 4527 proc = p; 4528 } 4529 } 4530 } 4531 4532 if (proc == null) { 4533 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4534 + " initialPid=" + initialPid 4535 + " packageName=" + packageName); 4536 return; 4537 } 4538 4539 if (proc.thread != null) { 4540 if (proc.pid == Process.myPid()) { 4541 Log.w(TAG, "crashApplication: trying to crash self!"); 4542 return; 4543 } 4544 long ident = Binder.clearCallingIdentity(); 4545 try { 4546 proc.thread.scheduleCrash(message); 4547 } catch (RemoteException e) { 4548 } 4549 Binder.restoreCallingIdentity(ident); 4550 } 4551 } 4552 } 4553 4554 @Override 4555 public final void finishSubActivity(IBinder token, String resultWho, 4556 int requestCode) { 4557 synchronized(this) { 4558 final long origId = Binder.clearCallingIdentity(); 4559 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4560 if (r != null) { 4561 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4562 } 4563 Binder.restoreCallingIdentity(origId); 4564 } 4565 } 4566 4567 @Override 4568 public boolean finishActivityAffinity(IBinder token) { 4569 synchronized(this) { 4570 final long origId = Binder.clearCallingIdentity(); 4571 try { 4572 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4573 4574 ActivityRecord rootR = r.task.getRootActivity(); 4575 // Do not allow task to finish in Lock Task mode. 4576 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4577 if (rootR == r) { 4578 mStackSupervisor.showLockTaskToast(); 4579 return false; 4580 } 4581 } 4582 boolean res = false; 4583 if (r != null) { 4584 res = r.task.stack.finishActivityAffinityLocked(r); 4585 } 4586 return res; 4587 } finally { 4588 Binder.restoreCallingIdentity(origId); 4589 } 4590 } 4591 } 4592 4593 @Override 4594 public void finishVoiceTask(IVoiceInteractionSession session) { 4595 synchronized(this) { 4596 final long origId = Binder.clearCallingIdentity(); 4597 try { 4598 mStackSupervisor.finishVoiceTask(session); 4599 } finally { 4600 Binder.restoreCallingIdentity(origId); 4601 } 4602 } 4603 4604 } 4605 4606 @Override 4607 public boolean releaseActivityInstance(IBinder token) { 4608 synchronized(this) { 4609 final long origId = Binder.clearCallingIdentity(); 4610 try { 4611 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4612 if (r.task == null || r.task.stack == null) { 4613 return false; 4614 } 4615 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4616 } finally { 4617 Binder.restoreCallingIdentity(origId); 4618 } 4619 } 4620 } 4621 4622 @Override 4623 public void releaseSomeActivities(IApplicationThread appInt) { 4624 synchronized(this) { 4625 final long origId = Binder.clearCallingIdentity(); 4626 try { 4627 ProcessRecord app = getRecordForAppLocked(appInt); 4628 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4629 } finally { 4630 Binder.restoreCallingIdentity(origId); 4631 } 4632 } 4633 } 4634 4635 @Override 4636 public boolean willActivityBeVisible(IBinder token) { 4637 synchronized(this) { 4638 ActivityStack stack = ActivityRecord.getStackLocked(token); 4639 if (stack != null) { 4640 return stack.willActivityBeVisibleLocked(token); 4641 } 4642 return false; 4643 } 4644 } 4645 4646 @Override 4647 public void overridePendingTransition(IBinder token, String packageName, 4648 int enterAnim, int exitAnim) { 4649 synchronized(this) { 4650 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4651 if (self == null) { 4652 return; 4653 } 4654 4655 final long origId = Binder.clearCallingIdentity(); 4656 4657 if (self.state == ActivityState.RESUMED 4658 || self.state == ActivityState.PAUSING) { 4659 mWindowManager.overridePendingAppTransition(packageName, 4660 enterAnim, exitAnim, null); 4661 } 4662 4663 Binder.restoreCallingIdentity(origId); 4664 } 4665 } 4666 4667 /** 4668 * Main function for removing an existing process from the activity manager 4669 * as a result of that process going away. Clears out all connections 4670 * to the process. 4671 */ 4672 private final void handleAppDiedLocked(ProcessRecord app, 4673 boolean restarting, boolean allowRestart) { 4674 int pid = app.pid; 4675 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4676 if (!restarting) { 4677 removeLruProcessLocked(app); 4678 if (pid > 0) { 4679 ProcessList.remove(pid); 4680 } 4681 } 4682 4683 if (mProfileProc == app) { 4684 clearProfilerLocked(); 4685 } 4686 4687 // Remove this application's activities from active lists. 4688 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4689 4690 app.activities.clear(); 4691 4692 if (app.instrumentationClass != null) { 4693 Slog.w(TAG, "Crash of app " + app.processName 4694 + " running instrumentation " + app.instrumentationClass); 4695 Bundle info = new Bundle(); 4696 info.putString("shortMsg", "Process crashed."); 4697 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4698 } 4699 4700 if (!restarting) { 4701 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4702 // If there was nothing to resume, and we are not already 4703 // restarting this process, but there is a visible activity that 4704 // is hosted by the process... then make sure all visible 4705 // activities are running, taking care of restarting this 4706 // process. 4707 if (hasVisibleActivities) { 4708 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4709 } 4710 } 4711 } 4712 } 4713 4714 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4715 IBinder threadBinder = thread.asBinder(); 4716 // Find the application record. 4717 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4718 ProcessRecord rec = mLruProcesses.get(i); 4719 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4720 return i; 4721 } 4722 } 4723 return -1; 4724 } 4725 4726 final ProcessRecord getRecordForAppLocked( 4727 IApplicationThread thread) { 4728 if (thread == null) { 4729 return null; 4730 } 4731 4732 int appIndex = getLRURecordIndexForAppLocked(thread); 4733 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4734 } 4735 4736 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4737 // If there are no longer any background processes running, 4738 // and the app that died was not running instrumentation, 4739 // then tell everyone we are now low on memory. 4740 boolean haveBg = false; 4741 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4742 ProcessRecord rec = mLruProcesses.get(i); 4743 if (rec.thread != null 4744 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4745 haveBg = true; 4746 break; 4747 } 4748 } 4749 4750 if (!haveBg) { 4751 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4752 if (doReport) { 4753 long now = SystemClock.uptimeMillis(); 4754 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4755 doReport = false; 4756 } else { 4757 mLastMemUsageReportTime = now; 4758 } 4759 } 4760 final ArrayList<ProcessMemInfo> memInfos 4761 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4762 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4763 long now = SystemClock.uptimeMillis(); 4764 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4765 ProcessRecord rec = mLruProcesses.get(i); 4766 if (rec == dyingProc || rec.thread == null) { 4767 continue; 4768 } 4769 if (doReport) { 4770 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4771 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4772 } 4773 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4774 // The low memory report is overriding any current 4775 // state for a GC request. Make sure to do 4776 // heavy/important/visible/foreground processes first. 4777 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4778 rec.lastRequestedGc = 0; 4779 } else { 4780 rec.lastRequestedGc = rec.lastLowMemory; 4781 } 4782 rec.reportLowMemory = true; 4783 rec.lastLowMemory = now; 4784 mProcessesToGc.remove(rec); 4785 addProcessToGcListLocked(rec); 4786 } 4787 } 4788 if (doReport) { 4789 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4790 mHandler.sendMessage(msg); 4791 } 4792 scheduleAppGcsLocked(); 4793 } 4794 } 4795 4796 final void appDiedLocked(ProcessRecord app) { 4797 appDiedLocked(app, app.pid, app.thread); 4798 } 4799 4800 final void appDiedLocked(ProcessRecord app, int pid, 4801 IApplicationThread thread) { 4802 4803 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4804 synchronized (stats) { 4805 stats.noteProcessDiedLocked(app.info.uid, pid); 4806 } 4807 4808 Process.killProcessGroup(app.info.uid, pid); 4809 4810 // Clean up already done if the process has been re-started. 4811 if (app.pid == pid && app.thread != null && 4812 app.thread.asBinder() == thread.asBinder()) { 4813 boolean doLowMem = app.instrumentationClass == null; 4814 boolean doOomAdj = doLowMem; 4815 if (!app.killedByAm) { 4816 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4817 + ") has died."); 4818 mAllowLowerMemLevel = true; 4819 } else { 4820 // Note that we always want to do oom adj to update our state with the 4821 // new number of procs. 4822 mAllowLowerMemLevel = false; 4823 doLowMem = false; 4824 } 4825 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4826 if (DEBUG_CLEANUP) Slog.v( 4827 TAG, "Dying app: " + app + ", pid: " + pid 4828 + ", thread: " + thread.asBinder()); 4829 handleAppDiedLocked(app, false, true); 4830 4831 if (doOomAdj) { 4832 updateOomAdjLocked(); 4833 } 4834 if (doLowMem) { 4835 doLowMemReportIfNeededLocked(app); 4836 } 4837 } else if (app.pid != pid) { 4838 // A new process has already been started. 4839 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4840 + ") has died and restarted (pid " + app.pid + ")."); 4841 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4842 } else if (DEBUG_PROCESSES) { 4843 Slog.d(TAG, "Received spurious death notification for thread " 4844 + thread.asBinder()); 4845 } 4846 } 4847 4848 /** 4849 * If a stack trace dump file is configured, dump process stack traces. 4850 * @param clearTraces causes the dump file to be erased prior to the new 4851 * traces being written, if true; when false, the new traces will be 4852 * appended to any existing file content. 4853 * @param firstPids of dalvik VM processes to dump stack traces for first 4854 * @param lastPids of dalvik VM processes to dump stack traces for last 4855 * @param nativeProcs optional list of native process names to dump stack crawls 4856 * @return file containing stack traces, or null if no dump file is configured 4857 */ 4858 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4859 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4860 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4861 if (tracesPath == null || tracesPath.length() == 0) { 4862 return null; 4863 } 4864 4865 File tracesFile = new File(tracesPath); 4866 try { 4867 File tracesDir = tracesFile.getParentFile(); 4868 if (!tracesDir.exists()) { 4869 tracesFile.mkdirs(); 4870 if (!SELinux.restorecon(tracesDir)) { 4871 return null; 4872 } 4873 } 4874 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4875 4876 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4877 tracesFile.createNewFile(); 4878 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4879 } catch (IOException e) { 4880 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4881 return null; 4882 } 4883 4884 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4885 return tracesFile; 4886 } 4887 4888 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4889 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4890 // Use a FileObserver to detect when traces finish writing. 4891 // The order of traces is considered important to maintain for legibility. 4892 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4893 @Override 4894 public synchronized void onEvent(int event, String path) { notify(); } 4895 }; 4896 4897 try { 4898 observer.startWatching(); 4899 4900 // First collect all of the stacks of the most important pids. 4901 if (firstPids != null) { 4902 try { 4903 int num = firstPids.size(); 4904 for (int i = 0; i < num; i++) { 4905 synchronized (observer) { 4906 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4907 observer.wait(200); // Wait for write-close, give up after 200msec 4908 } 4909 } 4910 } catch (InterruptedException e) { 4911 Log.wtf(TAG, e); 4912 } 4913 } 4914 4915 // Next collect the stacks of the native pids 4916 if (nativeProcs != null) { 4917 int[] pids = Process.getPidsForCommands(nativeProcs); 4918 if (pids != null) { 4919 for (int pid : pids) { 4920 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4921 } 4922 } 4923 } 4924 4925 // Lastly, measure CPU usage. 4926 if (processCpuTracker != null) { 4927 processCpuTracker.init(); 4928 System.gc(); 4929 processCpuTracker.update(); 4930 try { 4931 synchronized (processCpuTracker) { 4932 processCpuTracker.wait(500); // measure over 1/2 second. 4933 } 4934 } catch (InterruptedException e) { 4935 } 4936 processCpuTracker.update(); 4937 4938 // We'll take the stack crawls of just the top apps using CPU. 4939 final int N = processCpuTracker.countWorkingStats(); 4940 int numProcs = 0; 4941 for (int i=0; i<N && numProcs<5; i++) { 4942 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4943 if (lastPids.indexOfKey(stats.pid) >= 0) { 4944 numProcs++; 4945 try { 4946 synchronized (observer) { 4947 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4948 observer.wait(200); // Wait for write-close, give up after 200msec 4949 } 4950 } catch (InterruptedException e) { 4951 Log.wtf(TAG, e); 4952 } 4953 4954 } 4955 } 4956 } 4957 } finally { 4958 observer.stopWatching(); 4959 } 4960 } 4961 4962 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4963 if (true || IS_USER_BUILD) { 4964 return; 4965 } 4966 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4967 if (tracesPath == null || tracesPath.length() == 0) { 4968 return; 4969 } 4970 4971 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4972 StrictMode.allowThreadDiskWrites(); 4973 try { 4974 final File tracesFile = new File(tracesPath); 4975 final File tracesDir = tracesFile.getParentFile(); 4976 final File tracesTmp = new File(tracesDir, "__tmp__"); 4977 try { 4978 if (!tracesDir.exists()) { 4979 tracesFile.mkdirs(); 4980 if (!SELinux.restorecon(tracesDir.getPath())) { 4981 return; 4982 } 4983 } 4984 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4985 4986 if (tracesFile.exists()) { 4987 tracesTmp.delete(); 4988 tracesFile.renameTo(tracesTmp); 4989 } 4990 StringBuilder sb = new StringBuilder(); 4991 Time tobj = new Time(); 4992 tobj.set(System.currentTimeMillis()); 4993 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4994 sb.append(": "); 4995 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4996 sb.append(" since "); 4997 sb.append(msg); 4998 FileOutputStream fos = new FileOutputStream(tracesFile); 4999 fos.write(sb.toString().getBytes()); 5000 if (app == null) { 5001 fos.write("\n*** No application process!".getBytes()); 5002 } 5003 fos.close(); 5004 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5005 } catch (IOException e) { 5006 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5007 return; 5008 } 5009 5010 if (app != null) { 5011 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5012 firstPids.add(app.pid); 5013 dumpStackTraces(tracesPath, firstPids, null, null, null); 5014 } 5015 5016 File lastTracesFile = null; 5017 File curTracesFile = null; 5018 for (int i=9; i>=0; i--) { 5019 String name = String.format(Locale.US, "slow%02d.txt", i); 5020 curTracesFile = new File(tracesDir, name); 5021 if (curTracesFile.exists()) { 5022 if (lastTracesFile != null) { 5023 curTracesFile.renameTo(lastTracesFile); 5024 } else { 5025 curTracesFile.delete(); 5026 } 5027 } 5028 lastTracesFile = curTracesFile; 5029 } 5030 tracesFile.renameTo(curTracesFile); 5031 if (tracesTmp.exists()) { 5032 tracesTmp.renameTo(tracesFile); 5033 } 5034 } finally { 5035 StrictMode.setThreadPolicy(oldPolicy); 5036 } 5037 } 5038 5039 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5040 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5041 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5042 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5043 5044 if (mController != null) { 5045 try { 5046 // 0 == continue, -1 = kill process immediately 5047 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5048 if (res < 0 && app.pid != MY_PID) { 5049 app.kill("anr", true); 5050 } 5051 } catch (RemoteException e) { 5052 mController = null; 5053 Watchdog.getInstance().setActivityController(null); 5054 } 5055 } 5056 5057 long anrTime = SystemClock.uptimeMillis(); 5058 if (MONITOR_CPU_USAGE) { 5059 updateCpuStatsNow(); 5060 } 5061 5062 synchronized (this) { 5063 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5064 if (mShuttingDown) { 5065 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5066 return; 5067 } else if (app.notResponding) { 5068 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5069 return; 5070 } else if (app.crashing) { 5071 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5072 return; 5073 } 5074 5075 // In case we come through here for the same app before completing 5076 // this one, mark as anring now so we will bail out. 5077 app.notResponding = true; 5078 5079 // Log the ANR to the event log. 5080 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5081 app.processName, app.info.flags, annotation); 5082 5083 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5084 firstPids.add(app.pid); 5085 5086 int parentPid = app.pid; 5087 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5088 if (parentPid != app.pid) firstPids.add(parentPid); 5089 5090 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5091 5092 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5093 ProcessRecord r = mLruProcesses.get(i); 5094 if (r != null && r.thread != null) { 5095 int pid = r.pid; 5096 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5097 if (r.persistent) { 5098 firstPids.add(pid); 5099 } else { 5100 lastPids.put(pid, Boolean.TRUE); 5101 } 5102 } 5103 } 5104 } 5105 } 5106 5107 // Log the ANR to the main log. 5108 StringBuilder info = new StringBuilder(); 5109 info.setLength(0); 5110 info.append("ANR in ").append(app.processName); 5111 if (activity != null && activity.shortComponentName != null) { 5112 info.append(" (").append(activity.shortComponentName).append(")"); 5113 } 5114 info.append("\n"); 5115 info.append("PID: ").append(app.pid).append("\n"); 5116 if (annotation != null) { 5117 info.append("Reason: ").append(annotation).append("\n"); 5118 } 5119 if (parent != null && parent != activity) { 5120 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5121 } 5122 5123 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5124 5125 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5126 NATIVE_STACKS_OF_INTEREST); 5127 5128 String cpuInfo = null; 5129 if (MONITOR_CPU_USAGE) { 5130 updateCpuStatsNow(); 5131 synchronized (mProcessCpuTracker) { 5132 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5133 } 5134 info.append(processCpuTracker.printCurrentLoad()); 5135 info.append(cpuInfo); 5136 } 5137 5138 info.append(processCpuTracker.printCurrentState(anrTime)); 5139 5140 Slog.e(TAG, info.toString()); 5141 if (tracesFile == null) { 5142 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5143 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5144 } 5145 5146 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5147 cpuInfo, tracesFile, null); 5148 5149 if (mController != null) { 5150 try { 5151 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5152 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5153 if (res != 0) { 5154 if (res < 0 && app.pid != MY_PID) { 5155 app.kill("anr", true); 5156 } else { 5157 synchronized (this) { 5158 mServices.scheduleServiceTimeoutLocked(app); 5159 } 5160 } 5161 return; 5162 } 5163 } catch (RemoteException e) { 5164 mController = null; 5165 Watchdog.getInstance().setActivityController(null); 5166 } 5167 } 5168 5169 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5170 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5171 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5172 5173 synchronized (this) { 5174 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5175 app.kill("bg anr", true); 5176 return; 5177 } 5178 5179 // Set the app's notResponding state, and look up the errorReportReceiver 5180 makeAppNotRespondingLocked(app, 5181 activity != null ? activity.shortComponentName : null, 5182 annotation != null ? "ANR " + annotation : "ANR", 5183 info.toString()); 5184 5185 // Bring up the infamous App Not Responding dialog 5186 Message msg = Message.obtain(); 5187 HashMap<String, Object> map = new HashMap<String, Object>(); 5188 msg.what = SHOW_NOT_RESPONDING_MSG; 5189 msg.obj = map; 5190 msg.arg1 = aboveSystem ? 1 : 0; 5191 map.put("app", app); 5192 if (activity != null) { 5193 map.put("activity", activity); 5194 } 5195 5196 mHandler.sendMessage(msg); 5197 } 5198 } 5199 5200 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5201 if (!mLaunchWarningShown) { 5202 mLaunchWarningShown = true; 5203 mHandler.post(new Runnable() { 5204 @Override 5205 public void run() { 5206 synchronized (ActivityManagerService.this) { 5207 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5208 d.show(); 5209 mHandler.postDelayed(new Runnable() { 5210 @Override 5211 public void run() { 5212 synchronized (ActivityManagerService.this) { 5213 d.dismiss(); 5214 mLaunchWarningShown = false; 5215 } 5216 } 5217 }, 4000); 5218 } 5219 } 5220 }); 5221 } 5222 } 5223 5224 @Override 5225 public boolean clearApplicationUserData(final String packageName, 5226 final IPackageDataObserver observer, int userId) { 5227 enforceNotIsolatedCaller("clearApplicationUserData"); 5228 int uid = Binder.getCallingUid(); 5229 int pid = Binder.getCallingPid(); 5230 userId = handleIncomingUser(pid, uid, 5231 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5232 long callingId = Binder.clearCallingIdentity(); 5233 try { 5234 IPackageManager pm = AppGlobals.getPackageManager(); 5235 int pkgUid = -1; 5236 synchronized(this) { 5237 try { 5238 pkgUid = pm.getPackageUid(packageName, userId); 5239 } catch (RemoteException e) { 5240 } 5241 if (pkgUid == -1) { 5242 Slog.w(TAG, "Invalid packageName: " + packageName); 5243 if (observer != null) { 5244 try { 5245 observer.onRemoveCompleted(packageName, false); 5246 } catch (RemoteException e) { 5247 Slog.i(TAG, "Observer no longer exists."); 5248 } 5249 } 5250 return false; 5251 } 5252 if (uid == pkgUid || checkComponentPermission( 5253 android.Manifest.permission.CLEAR_APP_USER_DATA, 5254 pid, uid, -1, true) 5255 == PackageManager.PERMISSION_GRANTED) { 5256 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5257 } else { 5258 throw new SecurityException("PID " + pid + " does not have permission " 5259 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5260 + " of package " + packageName); 5261 } 5262 5263 // Remove all tasks match the cleared application package and user 5264 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5265 final TaskRecord tr = mRecentTasks.get(i); 5266 final String taskPackageName = 5267 tr.getBaseIntent().getComponent().getPackageName(); 5268 if (tr.userId != userId) continue; 5269 if (!taskPackageName.equals(packageName)) continue; 5270 removeTaskByIdLocked(tr.taskId, 0); 5271 } 5272 } 5273 5274 try { 5275 // Clear application user data 5276 pm.clearApplicationUserData(packageName, observer, userId); 5277 5278 synchronized(this) { 5279 // Remove all permissions granted from/to this package 5280 removeUriPermissionsForPackageLocked(packageName, userId, true); 5281 } 5282 5283 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5284 Uri.fromParts("package", packageName, null)); 5285 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5286 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5287 null, null, 0, null, null, null, false, false, userId); 5288 } catch (RemoteException e) { 5289 } 5290 } finally { 5291 Binder.restoreCallingIdentity(callingId); 5292 } 5293 return true; 5294 } 5295 5296 @Override 5297 public void killBackgroundProcesses(final String packageName, int userId) { 5298 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5299 != PackageManager.PERMISSION_GRANTED && 5300 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5301 != PackageManager.PERMISSION_GRANTED) { 5302 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5303 + Binder.getCallingPid() 5304 + ", uid=" + Binder.getCallingUid() 5305 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5306 Slog.w(TAG, msg); 5307 throw new SecurityException(msg); 5308 } 5309 5310 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5311 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5312 long callingId = Binder.clearCallingIdentity(); 5313 try { 5314 IPackageManager pm = AppGlobals.getPackageManager(); 5315 synchronized(this) { 5316 int appId = -1; 5317 try { 5318 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5319 } catch (RemoteException e) { 5320 } 5321 if (appId == -1) { 5322 Slog.w(TAG, "Invalid packageName: " + packageName); 5323 return; 5324 } 5325 killPackageProcessesLocked(packageName, appId, userId, 5326 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5327 } 5328 } finally { 5329 Binder.restoreCallingIdentity(callingId); 5330 } 5331 } 5332 5333 @Override 5334 public void killAllBackgroundProcesses() { 5335 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5336 != PackageManager.PERMISSION_GRANTED) { 5337 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5338 + Binder.getCallingPid() 5339 + ", uid=" + Binder.getCallingUid() 5340 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5341 Slog.w(TAG, msg); 5342 throw new SecurityException(msg); 5343 } 5344 5345 long callingId = Binder.clearCallingIdentity(); 5346 try { 5347 synchronized(this) { 5348 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5349 final int NP = mProcessNames.getMap().size(); 5350 for (int ip=0; ip<NP; ip++) { 5351 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5352 final int NA = apps.size(); 5353 for (int ia=0; ia<NA; ia++) { 5354 ProcessRecord app = apps.valueAt(ia); 5355 if (app.persistent) { 5356 // we don't kill persistent processes 5357 continue; 5358 } 5359 if (app.removed) { 5360 procs.add(app); 5361 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5362 app.removed = true; 5363 procs.add(app); 5364 } 5365 } 5366 } 5367 5368 int N = procs.size(); 5369 for (int i=0; i<N; i++) { 5370 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5371 } 5372 mAllowLowerMemLevel = true; 5373 updateOomAdjLocked(); 5374 doLowMemReportIfNeededLocked(null); 5375 } 5376 } finally { 5377 Binder.restoreCallingIdentity(callingId); 5378 } 5379 } 5380 5381 @Override 5382 public void forceStopPackage(final String packageName, int userId) { 5383 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5384 != PackageManager.PERMISSION_GRANTED) { 5385 String msg = "Permission Denial: forceStopPackage() from pid=" 5386 + Binder.getCallingPid() 5387 + ", uid=" + Binder.getCallingUid() 5388 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5389 Slog.w(TAG, msg); 5390 throw new SecurityException(msg); 5391 } 5392 final int callingPid = Binder.getCallingPid(); 5393 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5394 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5395 long callingId = Binder.clearCallingIdentity(); 5396 try { 5397 IPackageManager pm = AppGlobals.getPackageManager(); 5398 synchronized(this) { 5399 int[] users = userId == UserHandle.USER_ALL 5400 ? getUsersLocked() : new int[] { userId }; 5401 for (int user : users) { 5402 int pkgUid = -1; 5403 try { 5404 pkgUid = pm.getPackageUid(packageName, user); 5405 } catch (RemoteException e) { 5406 } 5407 if (pkgUid == -1) { 5408 Slog.w(TAG, "Invalid packageName: " + packageName); 5409 continue; 5410 } 5411 try { 5412 pm.setPackageStoppedState(packageName, true, user); 5413 } catch (RemoteException e) { 5414 } catch (IllegalArgumentException e) { 5415 Slog.w(TAG, "Failed trying to unstop package " 5416 + packageName + ": " + e); 5417 } 5418 if (isUserRunningLocked(user, false)) { 5419 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5420 } 5421 } 5422 } 5423 } finally { 5424 Binder.restoreCallingIdentity(callingId); 5425 } 5426 } 5427 5428 @Override 5429 public void addPackageDependency(String packageName) { 5430 synchronized (this) { 5431 int callingPid = Binder.getCallingPid(); 5432 if (callingPid == Process.myPid()) { 5433 // Yeah, um, no. 5434 Slog.w(TAG, "Can't addPackageDependency on system process"); 5435 return; 5436 } 5437 ProcessRecord proc; 5438 synchronized (mPidsSelfLocked) { 5439 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5440 } 5441 if (proc != null) { 5442 if (proc.pkgDeps == null) { 5443 proc.pkgDeps = new ArraySet<String>(1); 5444 } 5445 proc.pkgDeps.add(packageName); 5446 } 5447 } 5448 } 5449 5450 /* 5451 * The pkg name and app id have to be specified. 5452 */ 5453 @Override 5454 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5455 if (pkg == null) { 5456 return; 5457 } 5458 // Make sure the uid is valid. 5459 if (appid < 0) { 5460 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5461 return; 5462 } 5463 int callerUid = Binder.getCallingUid(); 5464 // Only the system server can kill an application 5465 if (callerUid == Process.SYSTEM_UID) { 5466 // Post an aysnc message to kill the application 5467 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5468 msg.arg1 = appid; 5469 msg.arg2 = 0; 5470 Bundle bundle = new Bundle(); 5471 bundle.putString("pkg", pkg); 5472 bundle.putString("reason", reason); 5473 msg.obj = bundle; 5474 mHandler.sendMessage(msg); 5475 } else { 5476 throw new SecurityException(callerUid + " cannot kill pkg: " + 5477 pkg); 5478 } 5479 } 5480 5481 @Override 5482 public void closeSystemDialogs(String reason) { 5483 enforceNotIsolatedCaller("closeSystemDialogs"); 5484 5485 final int pid = Binder.getCallingPid(); 5486 final int uid = Binder.getCallingUid(); 5487 final long origId = Binder.clearCallingIdentity(); 5488 try { 5489 synchronized (this) { 5490 // Only allow this from foreground processes, so that background 5491 // applications can't abuse it to prevent system UI from being shown. 5492 if (uid >= Process.FIRST_APPLICATION_UID) { 5493 ProcessRecord proc; 5494 synchronized (mPidsSelfLocked) { 5495 proc = mPidsSelfLocked.get(pid); 5496 } 5497 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5498 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5499 + " from background process " + proc); 5500 return; 5501 } 5502 } 5503 closeSystemDialogsLocked(reason); 5504 } 5505 } finally { 5506 Binder.restoreCallingIdentity(origId); 5507 } 5508 } 5509 5510 void closeSystemDialogsLocked(String reason) { 5511 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5512 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5513 | Intent.FLAG_RECEIVER_FOREGROUND); 5514 if (reason != null) { 5515 intent.putExtra("reason", reason); 5516 } 5517 mWindowManager.closeSystemDialogs(reason); 5518 5519 mStackSupervisor.closeSystemDialogsLocked(); 5520 5521 broadcastIntentLocked(null, null, intent, null, 5522 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5523 Process.SYSTEM_UID, UserHandle.USER_ALL); 5524 } 5525 5526 @Override 5527 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5528 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5529 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5530 for (int i=pids.length-1; i>=0; i--) { 5531 ProcessRecord proc; 5532 int oomAdj; 5533 synchronized (this) { 5534 synchronized (mPidsSelfLocked) { 5535 proc = mPidsSelfLocked.get(pids[i]); 5536 oomAdj = proc != null ? proc.setAdj : 0; 5537 } 5538 } 5539 infos[i] = new Debug.MemoryInfo(); 5540 Debug.getMemoryInfo(pids[i], infos[i]); 5541 if (proc != null) { 5542 synchronized (this) { 5543 if (proc.thread != null && proc.setAdj == oomAdj) { 5544 // Record this for posterity if the process has been stable. 5545 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5546 infos[i].getTotalUss(), false, proc.pkgList); 5547 } 5548 } 5549 } 5550 } 5551 return infos; 5552 } 5553 5554 @Override 5555 public long[] getProcessPss(int[] pids) { 5556 enforceNotIsolatedCaller("getProcessPss"); 5557 long[] pss = new long[pids.length]; 5558 for (int i=pids.length-1; i>=0; i--) { 5559 ProcessRecord proc; 5560 int oomAdj; 5561 synchronized (this) { 5562 synchronized (mPidsSelfLocked) { 5563 proc = mPidsSelfLocked.get(pids[i]); 5564 oomAdj = proc != null ? proc.setAdj : 0; 5565 } 5566 } 5567 long[] tmpUss = new long[1]; 5568 pss[i] = Debug.getPss(pids[i], tmpUss); 5569 if (proc != null) { 5570 synchronized (this) { 5571 if (proc.thread != null && proc.setAdj == oomAdj) { 5572 // Record this for posterity if the process has been stable. 5573 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5574 } 5575 } 5576 } 5577 } 5578 return pss; 5579 } 5580 5581 @Override 5582 public void killApplicationProcess(String processName, int uid) { 5583 if (processName == null) { 5584 return; 5585 } 5586 5587 int callerUid = Binder.getCallingUid(); 5588 // Only the system server can kill an application 5589 if (callerUid == Process.SYSTEM_UID) { 5590 synchronized (this) { 5591 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5592 if (app != null && app.thread != null) { 5593 try { 5594 app.thread.scheduleSuicide(); 5595 } catch (RemoteException e) { 5596 // If the other end already died, then our work here is done. 5597 } 5598 } else { 5599 Slog.w(TAG, "Process/uid not found attempting kill of " 5600 + processName + " / " + uid); 5601 } 5602 } 5603 } else { 5604 throw new SecurityException(callerUid + " cannot kill app process: " + 5605 processName); 5606 } 5607 } 5608 5609 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5610 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5611 false, true, false, false, UserHandle.getUserId(uid), reason); 5612 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5613 Uri.fromParts("package", packageName, null)); 5614 if (!mProcessesReady) { 5615 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5616 | Intent.FLAG_RECEIVER_FOREGROUND); 5617 } 5618 intent.putExtra(Intent.EXTRA_UID, uid); 5619 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5620 broadcastIntentLocked(null, null, intent, 5621 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5622 false, false, 5623 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5624 } 5625 5626 private void forceStopUserLocked(int userId, String reason) { 5627 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5628 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5630 | Intent.FLAG_RECEIVER_FOREGROUND); 5631 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5632 broadcastIntentLocked(null, null, intent, 5633 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5634 false, false, 5635 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5636 } 5637 5638 private final boolean killPackageProcessesLocked(String packageName, int appId, 5639 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5640 boolean doit, boolean evenPersistent, String reason) { 5641 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5642 5643 // Remove all processes this package may have touched: all with the 5644 // same UID (except for the system or root user), and all whose name 5645 // matches the package name. 5646 final int NP = mProcessNames.getMap().size(); 5647 for (int ip=0; ip<NP; ip++) { 5648 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5649 final int NA = apps.size(); 5650 for (int ia=0; ia<NA; ia++) { 5651 ProcessRecord app = apps.valueAt(ia); 5652 if (app.persistent && !evenPersistent) { 5653 // we don't kill persistent processes 5654 continue; 5655 } 5656 if (app.removed) { 5657 if (doit) { 5658 procs.add(app); 5659 } 5660 continue; 5661 } 5662 5663 // Skip process if it doesn't meet our oom adj requirement. 5664 if (app.setAdj < minOomAdj) { 5665 continue; 5666 } 5667 5668 // If no package is specified, we call all processes under the 5669 // give user id. 5670 if (packageName == null) { 5671 if (app.userId != userId) { 5672 continue; 5673 } 5674 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5675 continue; 5676 } 5677 // Package has been specified, we want to hit all processes 5678 // that match it. We need to qualify this by the processes 5679 // that are running under the specified app and user ID. 5680 } else { 5681 final boolean isDep = app.pkgDeps != null 5682 && app.pkgDeps.contains(packageName); 5683 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5684 continue; 5685 } 5686 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5687 continue; 5688 } 5689 if (!app.pkgList.containsKey(packageName) && !isDep) { 5690 continue; 5691 } 5692 } 5693 5694 // Process has passed all conditions, kill it! 5695 if (!doit) { 5696 return true; 5697 } 5698 app.removed = true; 5699 procs.add(app); 5700 } 5701 } 5702 5703 int N = procs.size(); 5704 for (int i=0; i<N; i++) { 5705 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5706 } 5707 updateOomAdjLocked(); 5708 return N > 0; 5709 } 5710 5711 private final boolean forceStopPackageLocked(String name, int appId, 5712 boolean callerWillRestart, boolean purgeCache, boolean doit, 5713 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5714 int i; 5715 int N; 5716 5717 if (userId == UserHandle.USER_ALL && name == null) { 5718 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5719 } 5720 5721 if (appId < 0 && name != null) { 5722 try { 5723 appId = UserHandle.getAppId( 5724 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5725 } catch (RemoteException e) { 5726 } 5727 } 5728 5729 if (doit) { 5730 if (name != null) { 5731 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5732 + " user=" + userId + ": " + reason); 5733 } else { 5734 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5735 } 5736 5737 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5738 for (int ip=pmap.size()-1; ip>=0; ip--) { 5739 SparseArray<Long> ba = pmap.valueAt(ip); 5740 for (i=ba.size()-1; i>=0; i--) { 5741 boolean remove = false; 5742 final int entUid = ba.keyAt(i); 5743 if (name != null) { 5744 if (userId == UserHandle.USER_ALL) { 5745 if (UserHandle.getAppId(entUid) == appId) { 5746 remove = true; 5747 } 5748 } else { 5749 if (entUid == UserHandle.getUid(userId, appId)) { 5750 remove = true; 5751 } 5752 } 5753 } else if (UserHandle.getUserId(entUid) == userId) { 5754 remove = true; 5755 } 5756 if (remove) { 5757 ba.removeAt(i); 5758 } 5759 } 5760 if (ba.size() == 0) { 5761 pmap.removeAt(ip); 5762 } 5763 } 5764 } 5765 5766 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5767 -100, callerWillRestart, true, doit, evenPersistent, 5768 name == null ? ("stop user " + userId) : ("stop " + name)); 5769 5770 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5771 if (!doit) { 5772 return true; 5773 } 5774 didSomething = true; 5775 } 5776 5777 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5778 if (!doit) { 5779 return true; 5780 } 5781 didSomething = true; 5782 } 5783 5784 if (name == null) { 5785 // Remove all sticky broadcasts from this user. 5786 mStickyBroadcasts.remove(userId); 5787 } 5788 5789 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5790 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5791 userId, providers)) { 5792 if (!doit) { 5793 return true; 5794 } 5795 didSomething = true; 5796 } 5797 N = providers.size(); 5798 for (i=0; i<N; i++) { 5799 removeDyingProviderLocked(null, providers.get(i), true); 5800 } 5801 5802 // Remove transient permissions granted from/to this package/user 5803 removeUriPermissionsForPackageLocked(name, userId, false); 5804 5805 if (name == null || uninstalling) { 5806 // Remove pending intents. For now we only do this when force 5807 // stopping users, because we have some problems when doing this 5808 // for packages -- app widgets are not currently cleaned up for 5809 // such packages, so they can be left with bad pending intents. 5810 if (mIntentSenderRecords.size() > 0) { 5811 Iterator<WeakReference<PendingIntentRecord>> it 5812 = mIntentSenderRecords.values().iterator(); 5813 while (it.hasNext()) { 5814 WeakReference<PendingIntentRecord> wpir = it.next(); 5815 if (wpir == null) { 5816 it.remove(); 5817 continue; 5818 } 5819 PendingIntentRecord pir = wpir.get(); 5820 if (pir == null) { 5821 it.remove(); 5822 continue; 5823 } 5824 if (name == null) { 5825 // Stopping user, remove all objects for the user. 5826 if (pir.key.userId != userId) { 5827 // Not the same user, skip it. 5828 continue; 5829 } 5830 } else { 5831 if (UserHandle.getAppId(pir.uid) != appId) { 5832 // Different app id, skip it. 5833 continue; 5834 } 5835 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5836 // Different user, skip it. 5837 continue; 5838 } 5839 if (!pir.key.packageName.equals(name)) { 5840 // Different package, skip it. 5841 continue; 5842 } 5843 } 5844 if (!doit) { 5845 return true; 5846 } 5847 didSomething = true; 5848 it.remove(); 5849 pir.canceled = true; 5850 if (pir.key.activity != null) { 5851 pir.key.activity.pendingResults.remove(pir.ref); 5852 } 5853 } 5854 } 5855 } 5856 5857 if (doit) { 5858 if (purgeCache && name != null) { 5859 AttributeCache ac = AttributeCache.instance(); 5860 if (ac != null) { 5861 ac.removePackage(name); 5862 } 5863 } 5864 if (mBooted) { 5865 mStackSupervisor.resumeTopActivitiesLocked(); 5866 mStackSupervisor.scheduleIdleLocked(); 5867 } 5868 } 5869 5870 return didSomething; 5871 } 5872 5873 private final boolean removeProcessLocked(ProcessRecord app, 5874 boolean callerWillRestart, boolean allowRestart, String reason) { 5875 final String name = app.processName; 5876 final int uid = app.uid; 5877 if (DEBUG_PROCESSES) Slog.d( 5878 TAG, "Force removing proc " + app.toShortString() + " (" + name 5879 + "/" + uid + ")"); 5880 5881 mProcessNames.remove(name, uid); 5882 mIsolatedProcesses.remove(app.uid); 5883 if (mHeavyWeightProcess == app) { 5884 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5885 mHeavyWeightProcess.userId, 0)); 5886 mHeavyWeightProcess = null; 5887 } 5888 boolean needRestart = false; 5889 if (app.pid > 0 && app.pid != MY_PID) { 5890 int pid = app.pid; 5891 synchronized (mPidsSelfLocked) { 5892 mPidsSelfLocked.remove(pid); 5893 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5894 } 5895 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5896 if (app.isolated) { 5897 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5898 } 5899 app.kill(reason, true); 5900 handleAppDiedLocked(app, true, allowRestart); 5901 removeLruProcessLocked(app); 5902 5903 if (app.persistent && !app.isolated) { 5904 if (!callerWillRestart) { 5905 addAppLocked(app.info, false, null /* ABI override */); 5906 } else { 5907 needRestart = true; 5908 } 5909 } 5910 } else { 5911 mRemovedProcesses.add(app); 5912 } 5913 5914 return needRestart; 5915 } 5916 5917 private final void processStartTimedOutLocked(ProcessRecord app) { 5918 final int pid = app.pid; 5919 boolean gone = false; 5920 synchronized (mPidsSelfLocked) { 5921 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5922 if (knownApp != null && knownApp.thread == null) { 5923 mPidsSelfLocked.remove(pid); 5924 gone = true; 5925 } 5926 } 5927 5928 if (gone) { 5929 Slog.w(TAG, "Process " + app + " failed to attach"); 5930 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5931 pid, app.uid, app.processName); 5932 mProcessNames.remove(app.processName, app.uid); 5933 mIsolatedProcesses.remove(app.uid); 5934 if (mHeavyWeightProcess == app) { 5935 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5936 mHeavyWeightProcess.userId, 0)); 5937 mHeavyWeightProcess = null; 5938 } 5939 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5940 if (app.isolated) { 5941 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5942 } 5943 // Take care of any launching providers waiting for this process. 5944 checkAppInLaunchingProvidersLocked(app, true); 5945 // Take care of any services that are waiting for the process. 5946 mServices.processStartTimedOutLocked(app); 5947 app.kill("start timeout", true); 5948 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5949 Slog.w(TAG, "Unattached app died before backup, skipping"); 5950 try { 5951 IBackupManager bm = IBackupManager.Stub.asInterface( 5952 ServiceManager.getService(Context.BACKUP_SERVICE)); 5953 bm.agentDisconnected(app.info.packageName); 5954 } catch (RemoteException e) { 5955 // Can't happen; the backup manager is local 5956 } 5957 } 5958 if (isPendingBroadcastProcessLocked(pid)) { 5959 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5960 skipPendingBroadcastLocked(pid); 5961 } 5962 } else { 5963 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5964 } 5965 } 5966 5967 private final boolean attachApplicationLocked(IApplicationThread thread, 5968 int pid) { 5969 5970 // Find the application record that is being attached... either via 5971 // the pid if we are running in multiple processes, or just pull the 5972 // next app record if we are emulating process with anonymous threads. 5973 ProcessRecord app; 5974 if (pid != MY_PID && pid >= 0) { 5975 synchronized (mPidsSelfLocked) { 5976 app = mPidsSelfLocked.get(pid); 5977 } 5978 } else { 5979 app = null; 5980 } 5981 5982 if (app == null) { 5983 Slog.w(TAG, "No pending application record for pid " + pid 5984 + " (IApplicationThread " + thread + "); dropping process"); 5985 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5986 if (pid > 0 && pid != MY_PID) { 5987 Process.killProcessQuiet(pid); 5988 //TODO: Process.killProcessGroup(app.info.uid, pid); 5989 } else { 5990 try { 5991 thread.scheduleExit(); 5992 } catch (Exception e) { 5993 // Ignore exceptions. 5994 } 5995 } 5996 return false; 5997 } 5998 5999 // If this application record is still attached to a previous 6000 // process, clean it up now. 6001 if (app.thread != null) { 6002 handleAppDiedLocked(app, true, true); 6003 } 6004 6005 // Tell the process all about itself. 6006 6007 if (localLOGV) Slog.v( 6008 TAG, "Binding process pid " + pid + " to record " + app); 6009 6010 final String processName = app.processName; 6011 try { 6012 AppDeathRecipient adr = new AppDeathRecipient( 6013 app, pid, thread); 6014 thread.asBinder().linkToDeath(adr, 0); 6015 app.deathRecipient = adr; 6016 } catch (RemoteException e) { 6017 app.resetPackageList(mProcessStats); 6018 startProcessLocked(app, "link fail", processName); 6019 return false; 6020 } 6021 6022 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6023 6024 app.makeActive(thread, mProcessStats); 6025 app.curAdj = app.setAdj = -100; 6026 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6027 app.forcingToForeground = null; 6028 updateProcessForegroundLocked(app, false, false); 6029 app.hasShownUi = false; 6030 app.debugging = false; 6031 app.cached = false; 6032 6033 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6034 6035 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6036 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6037 6038 if (!normalMode) { 6039 Slog.i(TAG, "Launching preboot mode app: " + app); 6040 } 6041 6042 if (localLOGV) Slog.v( 6043 TAG, "New app record " + app 6044 + " thread=" + thread.asBinder() + " pid=" + pid); 6045 try { 6046 int testMode = IApplicationThread.DEBUG_OFF; 6047 if (mDebugApp != null && mDebugApp.equals(processName)) { 6048 testMode = mWaitForDebugger 6049 ? IApplicationThread.DEBUG_WAIT 6050 : IApplicationThread.DEBUG_ON; 6051 app.debugging = true; 6052 if (mDebugTransient) { 6053 mDebugApp = mOrigDebugApp; 6054 mWaitForDebugger = mOrigWaitForDebugger; 6055 } 6056 } 6057 String profileFile = app.instrumentationProfileFile; 6058 ParcelFileDescriptor profileFd = null; 6059 int samplingInterval = 0; 6060 boolean profileAutoStop = false; 6061 if (mProfileApp != null && mProfileApp.equals(processName)) { 6062 mProfileProc = app; 6063 profileFile = mProfileFile; 6064 profileFd = mProfileFd; 6065 samplingInterval = mSamplingInterval; 6066 profileAutoStop = mAutoStopProfiler; 6067 } 6068 boolean enableOpenGlTrace = false; 6069 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6070 enableOpenGlTrace = true; 6071 mOpenGlTraceApp = null; 6072 } 6073 6074 // If the app is being launched for restore or full backup, set it up specially 6075 boolean isRestrictedBackupMode = false; 6076 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6077 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6078 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6079 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6080 } 6081 6082 ensurePackageDexOpt(app.instrumentationInfo != null 6083 ? app.instrumentationInfo.packageName 6084 : app.info.packageName); 6085 if (app.instrumentationClass != null) { 6086 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6087 } 6088 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6089 + processName + " with config " + mConfiguration); 6090 ApplicationInfo appInfo = app.instrumentationInfo != null 6091 ? app.instrumentationInfo : app.info; 6092 app.compat = compatibilityInfoForPackageLocked(appInfo); 6093 if (profileFd != null) { 6094 profileFd = profileFd.dup(); 6095 } 6096 ProfilerInfo profilerInfo = profileFile == null ? null 6097 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6098 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6099 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6100 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6101 isRestrictedBackupMode || !normalMode, app.persistent, 6102 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6103 mCoreSettingsObserver.getCoreSettingsLocked()); 6104 updateLruProcessLocked(app, false, null); 6105 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6106 } catch (Exception e) { 6107 // todo: Yikes! What should we do? For now we will try to 6108 // start another process, but that could easily get us in 6109 // an infinite loop of restarting processes... 6110 Slog.w(TAG, "Exception thrown during bind!", e); 6111 6112 app.resetPackageList(mProcessStats); 6113 app.unlinkDeathRecipient(); 6114 startProcessLocked(app, "bind fail", processName); 6115 return false; 6116 } 6117 6118 // Remove this record from the list of starting applications. 6119 mPersistentStartingProcesses.remove(app); 6120 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6121 "Attach application locked removing on hold: " + app); 6122 mProcessesOnHold.remove(app); 6123 6124 boolean badApp = false; 6125 boolean didSomething = false; 6126 6127 // See if the top visible activity is waiting to run in this process... 6128 if (normalMode) { 6129 try { 6130 if (mStackSupervisor.attachApplicationLocked(app)) { 6131 didSomething = true; 6132 } 6133 } catch (Exception e) { 6134 badApp = true; 6135 } 6136 } 6137 6138 // Find any services that should be running in this process... 6139 if (!badApp) { 6140 try { 6141 didSomething |= mServices.attachApplicationLocked(app, processName); 6142 } catch (Exception e) { 6143 badApp = true; 6144 } 6145 } 6146 6147 // Check if a next-broadcast receiver is in this process... 6148 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6149 try { 6150 didSomething |= sendPendingBroadcastsLocked(app); 6151 } catch (Exception e) { 6152 // If the app died trying to launch the receiver we declare it 'bad' 6153 badApp = true; 6154 } 6155 } 6156 6157 // Check whether the next backup agent is in this process... 6158 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6159 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6160 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6161 try { 6162 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6163 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6164 mBackupTarget.backupMode); 6165 } catch (Exception e) { 6166 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6167 e.printStackTrace(); 6168 } 6169 } 6170 6171 if (badApp) { 6172 // todo: Also need to kill application to deal with all 6173 // kinds of exceptions. 6174 handleAppDiedLocked(app, false, true); 6175 return false; 6176 } 6177 6178 if (!didSomething) { 6179 updateOomAdjLocked(); 6180 } 6181 6182 return true; 6183 } 6184 6185 @Override 6186 public final void attachApplication(IApplicationThread thread) { 6187 synchronized (this) { 6188 int callingPid = Binder.getCallingPid(); 6189 final long origId = Binder.clearCallingIdentity(); 6190 attachApplicationLocked(thread, callingPid); 6191 Binder.restoreCallingIdentity(origId); 6192 } 6193 } 6194 6195 @Override 6196 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6197 final long origId = Binder.clearCallingIdentity(); 6198 synchronized (this) { 6199 ActivityStack stack = ActivityRecord.getStackLocked(token); 6200 if (stack != null) { 6201 ActivityRecord r = 6202 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6203 if (stopProfiling) { 6204 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6205 try { 6206 mProfileFd.close(); 6207 } catch (IOException e) { 6208 } 6209 clearProfilerLocked(); 6210 } 6211 } 6212 } 6213 } 6214 Binder.restoreCallingIdentity(origId); 6215 } 6216 6217 void postEnableScreenAfterBootLocked() { 6218 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6219 } 6220 6221 void enableScreenAfterBoot() { 6222 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6223 SystemClock.uptimeMillis()); 6224 mWindowManager.enableScreenAfterBoot(); 6225 6226 synchronized (this) { 6227 updateEventDispatchingLocked(); 6228 } 6229 } 6230 6231 @Override 6232 public void showBootMessage(final CharSequence msg, final boolean always) { 6233 enforceNotIsolatedCaller("showBootMessage"); 6234 mWindowManager.showBootMessage(msg, always); 6235 } 6236 6237 @Override 6238 public void keyguardWaitingForActivityDrawn() { 6239 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6240 final long token = Binder.clearCallingIdentity(); 6241 try { 6242 synchronized (this) { 6243 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6244 mWindowManager.keyguardWaitingForActivityDrawn(); 6245 } 6246 } finally { 6247 Binder.restoreCallingIdentity(token); 6248 } 6249 } 6250 6251 final void finishBooting() { 6252 synchronized (this) { 6253 if (!mBootAnimationComplete) { 6254 mCallFinishBooting = true; 6255 return; 6256 } 6257 mCallFinishBooting = false; 6258 } 6259 6260 // Register receivers to handle package update events 6261 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6262 6263 // Let system services know. 6264 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6265 6266 synchronized (this) { 6267 // Ensure that any processes we had put on hold are now started 6268 // up. 6269 final int NP = mProcessesOnHold.size(); 6270 if (NP > 0) { 6271 ArrayList<ProcessRecord> procs = 6272 new ArrayList<ProcessRecord>(mProcessesOnHold); 6273 for (int ip=0; ip<NP; ip++) { 6274 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6275 + procs.get(ip)); 6276 startProcessLocked(procs.get(ip), "on-hold", null); 6277 } 6278 } 6279 6280 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6281 // Start looking for apps that are abusing wake locks. 6282 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6283 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6284 // Tell anyone interested that we are done booting! 6285 SystemProperties.set("sys.boot_completed", "1"); 6286 SystemProperties.set("dev.bootcomplete", "1"); 6287 for (int i=0; i<mStartedUsers.size(); i++) { 6288 UserStartedState uss = mStartedUsers.valueAt(i); 6289 if (uss.mState == UserStartedState.STATE_BOOTING) { 6290 uss.mState = UserStartedState.STATE_RUNNING; 6291 final int userId = mStartedUsers.keyAt(i); 6292 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6293 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6294 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6295 broadcastIntentLocked(null, null, intent, null, 6296 new IIntentReceiver.Stub() { 6297 @Override 6298 public void performReceive(Intent intent, int resultCode, 6299 String data, Bundle extras, boolean ordered, 6300 boolean sticky, int sendingUser) { 6301 synchronized (ActivityManagerService.this) { 6302 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6303 true, false); 6304 } 6305 } 6306 }, 6307 0, null, null, 6308 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6309 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6310 userId); 6311 } 6312 } 6313 scheduleStartProfilesLocked(); 6314 } 6315 } 6316 } 6317 6318 @Override 6319 public void bootAnimationComplete() { 6320 final boolean callFinishBooting; 6321 synchronized (this) { 6322 callFinishBooting = mCallFinishBooting; 6323 mBootAnimationComplete = true; 6324 } 6325 if (callFinishBooting) { 6326 finishBooting(); 6327 } 6328 } 6329 6330 final void ensureBootCompleted() { 6331 boolean booting; 6332 boolean enableScreen; 6333 synchronized (this) { 6334 booting = mBooting; 6335 mBooting = false; 6336 enableScreen = !mBooted; 6337 mBooted = true; 6338 } 6339 6340 if (booting) { 6341 finishBooting(); 6342 } 6343 6344 if (enableScreen) { 6345 enableScreenAfterBoot(); 6346 } 6347 } 6348 6349 @Override 6350 public final void activityResumed(IBinder token) { 6351 final long origId = Binder.clearCallingIdentity(); 6352 synchronized(this) { 6353 ActivityStack stack = ActivityRecord.getStackLocked(token); 6354 if (stack != null) { 6355 ActivityRecord.activityResumedLocked(token); 6356 } 6357 } 6358 Binder.restoreCallingIdentity(origId); 6359 } 6360 6361 @Override 6362 public final void activityPaused(IBinder token) { 6363 final long origId = Binder.clearCallingIdentity(); 6364 synchronized(this) { 6365 ActivityStack stack = ActivityRecord.getStackLocked(token); 6366 if (stack != null) { 6367 stack.activityPausedLocked(token, false); 6368 } 6369 } 6370 Binder.restoreCallingIdentity(origId); 6371 } 6372 6373 @Override 6374 public final void activityStopped(IBinder token, Bundle icicle, 6375 PersistableBundle persistentState, CharSequence description) { 6376 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6377 6378 // Refuse possible leaked file descriptors 6379 if (icicle != null && icicle.hasFileDescriptors()) { 6380 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6381 } 6382 6383 final long origId = Binder.clearCallingIdentity(); 6384 6385 synchronized (this) { 6386 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6387 if (r != null) { 6388 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6389 } 6390 } 6391 6392 trimApplications(); 6393 6394 Binder.restoreCallingIdentity(origId); 6395 } 6396 6397 @Override 6398 public final void activityDestroyed(IBinder token) { 6399 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6400 synchronized (this) { 6401 ActivityStack stack = ActivityRecord.getStackLocked(token); 6402 if (stack != null) { 6403 stack.activityDestroyedLocked(token); 6404 } 6405 } 6406 } 6407 6408 @Override 6409 public final void backgroundResourcesReleased(IBinder token) { 6410 final long origId = Binder.clearCallingIdentity(); 6411 try { 6412 synchronized (this) { 6413 ActivityStack stack = ActivityRecord.getStackLocked(token); 6414 if (stack != null) { 6415 stack.backgroundResourcesReleased(token); 6416 } 6417 } 6418 } finally { 6419 Binder.restoreCallingIdentity(origId); 6420 } 6421 } 6422 6423 @Override 6424 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6425 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6426 } 6427 6428 @Override 6429 public final void notifyEnterAnimationComplete(IBinder token) { 6430 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6431 } 6432 6433 @Override 6434 public String getCallingPackage(IBinder token) { 6435 synchronized (this) { 6436 ActivityRecord r = getCallingRecordLocked(token); 6437 return r != null ? r.info.packageName : null; 6438 } 6439 } 6440 6441 @Override 6442 public ComponentName getCallingActivity(IBinder token) { 6443 synchronized (this) { 6444 ActivityRecord r = getCallingRecordLocked(token); 6445 return r != null ? r.intent.getComponent() : null; 6446 } 6447 } 6448 6449 private ActivityRecord getCallingRecordLocked(IBinder token) { 6450 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6451 if (r == null) { 6452 return null; 6453 } 6454 return r.resultTo; 6455 } 6456 6457 @Override 6458 public ComponentName getActivityClassForToken(IBinder token) { 6459 synchronized(this) { 6460 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6461 if (r == null) { 6462 return null; 6463 } 6464 return r.intent.getComponent(); 6465 } 6466 } 6467 6468 @Override 6469 public String getPackageForToken(IBinder token) { 6470 synchronized(this) { 6471 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6472 if (r == null) { 6473 return null; 6474 } 6475 return r.packageName; 6476 } 6477 } 6478 6479 @Override 6480 public IIntentSender getIntentSender(int type, 6481 String packageName, IBinder token, String resultWho, 6482 int requestCode, Intent[] intents, String[] resolvedTypes, 6483 int flags, Bundle options, int userId) { 6484 enforceNotIsolatedCaller("getIntentSender"); 6485 // Refuse possible leaked file descriptors 6486 if (intents != null) { 6487 if (intents.length < 1) { 6488 throw new IllegalArgumentException("Intents array length must be >= 1"); 6489 } 6490 for (int i=0; i<intents.length; i++) { 6491 Intent intent = intents[i]; 6492 if (intent != null) { 6493 if (intent.hasFileDescriptors()) { 6494 throw new IllegalArgumentException("File descriptors passed in Intent"); 6495 } 6496 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6497 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6498 throw new IllegalArgumentException( 6499 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6500 } 6501 intents[i] = new Intent(intent); 6502 } 6503 } 6504 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6505 throw new IllegalArgumentException( 6506 "Intent array length does not match resolvedTypes length"); 6507 } 6508 } 6509 if (options != null) { 6510 if (options.hasFileDescriptors()) { 6511 throw new IllegalArgumentException("File descriptors passed in options"); 6512 } 6513 } 6514 6515 synchronized(this) { 6516 int callingUid = Binder.getCallingUid(); 6517 int origUserId = userId; 6518 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6519 type == ActivityManager.INTENT_SENDER_BROADCAST, 6520 ALLOW_NON_FULL, "getIntentSender", null); 6521 if (origUserId == UserHandle.USER_CURRENT) { 6522 // We don't want to evaluate this until the pending intent is 6523 // actually executed. However, we do want to always do the 6524 // security checking for it above. 6525 userId = UserHandle.USER_CURRENT; 6526 } 6527 try { 6528 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6529 int uid = AppGlobals.getPackageManager() 6530 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6531 if (!UserHandle.isSameApp(callingUid, uid)) { 6532 String msg = "Permission Denial: getIntentSender() from pid=" 6533 + Binder.getCallingPid() 6534 + ", uid=" + Binder.getCallingUid() 6535 + ", (need uid=" + uid + ")" 6536 + " is not allowed to send as package " + packageName; 6537 Slog.w(TAG, msg); 6538 throw new SecurityException(msg); 6539 } 6540 } 6541 6542 return getIntentSenderLocked(type, packageName, callingUid, userId, 6543 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6544 6545 } catch (RemoteException e) { 6546 throw new SecurityException(e); 6547 } 6548 } 6549 } 6550 6551 IIntentSender getIntentSenderLocked(int type, String packageName, 6552 int callingUid, int userId, IBinder token, String resultWho, 6553 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6554 Bundle options) { 6555 if (DEBUG_MU) 6556 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6557 ActivityRecord activity = null; 6558 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6559 activity = ActivityRecord.isInStackLocked(token); 6560 if (activity == null) { 6561 return null; 6562 } 6563 if (activity.finishing) { 6564 return null; 6565 } 6566 } 6567 6568 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6569 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6570 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6571 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6572 |PendingIntent.FLAG_UPDATE_CURRENT); 6573 6574 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6575 type, packageName, activity, resultWho, 6576 requestCode, intents, resolvedTypes, flags, options, userId); 6577 WeakReference<PendingIntentRecord> ref; 6578 ref = mIntentSenderRecords.get(key); 6579 PendingIntentRecord rec = ref != null ? ref.get() : null; 6580 if (rec != null) { 6581 if (!cancelCurrent) { 6582 if (updateCurrent) { 6583 if (rec.key.requestIntent != null) { 6584 rec.key.requestIntent.replaceExtras(intents != null ? 6585 intents[intents.length - 1] : null); 6586 } 6587 if (intents != null) { 6588 intents[intents.length-1] = rec.key.requestIntent; 6589 rec.key.allIntents = intents; 6590 rec.key.allResolvedTypes = resolvedTypes; 6591 } else { 6592 rec.key.allIntents = null; 6593 rec.key.allResolvedTypes = null; 6594 } 6595 } 6596 return rec; 6597 } 6598 rec.canceled = true; 6599 mIntentSenderRecords.remove(key); 6600 } 6601 if (noCreate) { 6602 return rec; 6603 } 6604 rec = new PendingIntentRecord(this, key, callingUid); 6605 mIntentSenderRecords.put(key, rec.ref); 6606 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6607 if (activity.pendingResults == null) { 6608 activity.pendingResults 6609 = new HashSet<WeakReference<PendingIntentRecord>>(); 6610 } 6611 activity.pendingResults.add(rec.ref); 6612 } 6613 return rec; 6614 } 6615 6616 @Override 6617 public void cancelIntentSender(IIntentSender sender) { 6618 if (!(sender instanceof PendingIntentRecord)) { 6619 return; 6620 } 6621 synchronized(this) { 6622 PendingIntentRecord rec = (PendingIntentRecord)sender; 6623 try { 6624 int uid = AppGlobals.getPackageManager() 6625 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6626 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6627 String msg = "Permission Denial: cancelIntentSender() from pid=" 6628 + Binder.getCallingPid() 6629 + ", uid=" + Binder.getCallingUid() 6630 + " is not allowed to cancel packges " 6631 + rec.key.packageName; 6632 Slog.w(TAG, msg); 6633 throw new SecurityException(msg); 6634 } 6635 } catch (RemoteException e) { 6636 throw new SecurityException(e); 6637 } 6638 cancelIntentSenderLocked(rec, true); 6639 } 6640 } 6641 6642 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6643 rec.canceled = true; 6644 mIntentSenderRecords.remove(rec.key); 6645 if (cleanActivity && rec.key.activity != null) { 6646 rec.key.activity.pendingResults.remove(rec.ref); 6647 } 6648 } 6649 6650 @Override 6651 public String getPackageForIntentSender(IIntentSender pendingResult) { 6652 if (!(pendingResult instanceof PendingIntentRecord)) { 6653 return null; 6654 } 6655 try { 6656 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6657 return res.key.packageName; 6658 } catch (ClassCastException e) { 6659 } 6660 return null; 6661 } 6662 6663 @Override 6664 public int getUidForIntentSender(IIntentSender sender) { 6665 if (sender instanceof PendingIntentRecord) { 6666 try { 6667 PendingIntentRecord res = (PendingIntentRecord)sender; 6668 return res.uid; 6669 } catch (ClassCastException e) { 6670 } 6671 } 6672 return -1; 6673 } 6674 6675 @Override 6676 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6677 if (!(pendingResult instanceof PendingIntentRecord)) { 6678 return false; 6679 } 6680 try { 6681 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6682 if (res.key.allIntents == null) { 6683 return false; 6684 } 6685 for (int i=0; i<res.key.allIntents.length; i++) { 6686 Intent intent = res.key.allIntents[i]; 6687 if (intent.getPackage() != null && intent.getComponent() != null) { 6688 return false; 6689 } 6690 } 6691 return true; 6692 } catch (ClassCastException e) { 6693 } 6694 return false; 6695 } 6696 6697 @Override 6698 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6699 if (!(pendingResult instanceof PendingIntentRecord)) { 6700 return false; 6701 } 6702 try { 6703 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6704 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6705 return true; 6706 } 6707 return false; 6708 } catch (ClassCastException e) { 6709 } 6710 return false; 6711 } 6712 6713 @Override 6714 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6715 if (!(pendingResult instanceof PendingIntentRecord)) { 6716 return null; 6717 } 6718 try { 6719 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6720 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6721 } catch (ClassCastException e) { 6722 } 6723 return null; 6724 } 6725 6726 @Override 6727 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6728 if (!(pendingResult instanceof PendingIntentRecord)) { 6729 return null; 6730 } 6731 try { 6732 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6733 Intent intent = res.key.requestIntent; 6734 if (intent != null) { 6735 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6736 || res.lastTagPrefix.equals(prefix))) { 6737 return res.lastTag; 6738 } 6739 res.lastTagPrefix = prefix; 6740 StringBuilder sb = new StringBuilder(128); 6741 if (prefix != null) { 6742 sb.append(prefix); 6743 } 6744 if (intent.getAction() != null) { 6745 sb.append(intent.getAction()); 6746 } else if (intent.getComponent() != null) { 6747 intent.getComponent().appendShortString(sb); 6748 } else { 6749 sb.append("?"); 6750 } 6751 return res.lastTag = sb.toString(); 6752 } 6753 } catch (ClassCastException e) { 6754 } 6755 return null; 6756 } 6757 6758 @Override 6759 public void setProcessLimit(int max) { 6760 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6761 "setProcessLimit()"); 6762 synchronized (this) { 6763 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6764 mProcessLimitOverride = max; 6765 } 6766 trimApplications(); 6767 } 6768 6769 @Override 6770 public int getProcessLimit() { 6771 synchronized (this) { 6772 return mProcessLimitOverride; 6773 } 6774 } 6775 6776 void foregroundTokenDied(ForegroundToken token) { 6777 synchronized (ActivityManagerService.this) { 6778 synchronized (mPidsSelfLocked) { 6779 ForegroundToken cur 6780 = mForegroundProcesses.get(token.pid); 6781 if (cur != token) { 6782 return; 6783 } 6784 mForegroundProcesses.remove(token.pid); 6785 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6786 if (pr == null) { 6787 return; 6788 } 6789 pr.forcingToForeground = null; 6790 updateProcessForegroundLocked(pr, false, false); 6791 } 6792 updateOomAdjLocked(); 6793 } 6794 } 6795 6796 @Override 6797 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6798 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6799 "setProcessForeground()"); 6800 synchronized(this) { 6801 boolean changed = false; 6802 6803 synchronized (mPidsSelfLocked) { 6804 ProcessRecord pr = mPidsSelfLocked.get(pid); 6805 if (pr == null && isForeground) { 6806 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6807 return; 6808 } 6809 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6810 if (oldToken != null) { 6811 oldToken.token.unlinkToDeath(oldToken, 0); 6812 mForegroundProcesses.remove(pid); 6813 if (pr != null) { 6814 pr.forcingToForeground = null; 6815 } 6816 changed = true; 6817 } 6818 if (isForeground && token != null) { 6819 ForegroundToken newToken = new ForegroundToken() { 6820 @Override 6821 public void binderDied() { 6822 foregroundTokenDied(this); 6823 } 6824 }; 6825 newToken.pid = pid; 6826 newToken.token = token; 6827 try { 6828 token.linkToDeath(newToken, 0); 6829 mForegroundProcesses.put(pid, newToken); 6830 pr.forcingToForeground = token; 6831 changed = true; 6832 } catch (RemoteException e) { 6833 // If the process died while doing this, we will later 6834 // do the cleanup with the process death link. 6835 } 6836 } 6837 } 6838 6839 if (changed) { 6840 updateOomAdjLocked(); 6841 } 6842 } 6843 } 6844 6845 // ========================================================= 6846 // PERMISSIONS 6847 // ========================================================= 6848 6849 static class PermissionController extends IPermissionController.Stub { 6850 ActivityManagerService mActivityManagerService; 6851 PermissionController(ActivityManagerService activityManagerService) { 6852 mActivityManagerService = activityManagerService; 6853 } 6854 6855 @Override 6856 public boolean checkPermission(String permission, int pid, int uid) { 6857 return mActivityManagerService.checkPermission(permission, pid, 6858 uid) == PackageManager.PERMISSION_GRANTED; 6859 } 6860 } 6861 6862 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6863 @Override 6864 public int checkComponentPermission(String permission, int pid, int uid, 6865 int owningUid, boolean exported) { 6866 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6867 owningUid, exported); 6868 } 6869 6870 @Override 6871 public Object getAMSLock() { 6872 return ActivityManagerService.this; 6873 } 6874 } 6875 6876 /** 6877 * This can be called with or without the global lock held. 6878 */ 6879 int checkComponentPermission(String permission, int pid, int uid, 6880 int owningUid, boolean exported) { 6881 // We might be performing an operation on behalf of an indirect binder 6882 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6883 // client identity accordingly before proceeding. 6884 Identity tlsIdentity = sCallerIdentity.get(); 6885 if (tlsIdentity != null) { 6886 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6887 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6888 uid = tlsIdentity.uid; 6889 pid = tlsIdentity.pid; 6890 } 6891 6892 if (pid == MY_PID) { 6893 return PackageManager.PERMISSION_GRANTED; 6894 } 6895 6896 return ActivityManager.checkComponentPermission(permission, uid, 6897 owningUid, exported); 6898 } 6899 6900 /** 6901 * As the only public entry point for permissions checking, this method 6902 * can enforce the semantic that requesting a check on a null global 6903 * permission is automatically denied. (Internally a null permission 6904 * string is used when calling {@link #checkComponentPermission} in cases 6905 * when only uid-based security is needed.) 6906 * 6907 * This can be called with or without the global lock held. 6908 */ 6909 @Override 6910 public int checkPermission(String permission, int pid, int uid) { 6911 if (permission == null) { 6912 return PackageManager.PERMISSION_DENIED; 6913 } 6914 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6915 } 6916 6917 /** 6918 * Binder IPC calls go through the public entry point. 6919 * This can be called with or without the global lock held. 6920 */ 6921 int checkCallingPermission(String permission) { 6922 return checkPermission(permission, 6923 Binder.getCallingPid(), 6924 UserHandle.getAppId(Binder.getCallingUid())); 6925 } 6926 6927 /** 6928 * This can be called with or without the global lock held. 6929 */ 6930 void enforceCallingPermission(String permission, String func) { 6931 if (checkCallingPermission(permission) 6932 == PackageManager.PERMISSION_GRANTED) { 6933 return; 6934 } 6935 6936 String msg = "Permission Denial: " + func + " from pid=" 6937 + Binder.getCallingPid() 6938 + ", uid=" + Binder.getCallingUid() 6939 + " requires " + permission; 6940 Slog.w(TAG, msg); 6941 throw new SecurityException(msg); 6942 } 6943 6944 /** 6945 * Determine if UID is holding permissions required to access {@link Uri} in 6946 * the given {@link ProviderInfo}. Final permission checking is always done 6947 * in {@link ContentProvider}. 6948 */ 6949 private final boolean checkHoldingPermissionsLocked( 6950 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6951 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6952 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6953 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6954 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6955 != PERMISSION_GRANTED) { 6956 return false; 6957 } 6958 } 6959 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6960 } 6961 6962 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6963 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6964 if (pi.applicationInfo.uid == uid) { 6965 return true; 6966 } else if (!pi.exported) { 6967 return false; 6968 } 6969 6970 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6971 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6972 try { 6973 // check if target holds top-level <provider> permissions 6974 if (!readMet && pi.readPermission != null && considerUidPermissions 6975 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6976 readMet = true; 6977 } 6978 if (!writeMet && pi.writePermission != null && considerUidPermissions 6979 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6980 writeMet = true; 6981 } 6982 6983 // track if unprotected read/write is allowed; any denied 6984 // <path-permission> below removes this ability 6985 boolean allowDefaultRead = pi.readPermission == null; 6986 boolean allowDefaultWrite = pi.writePermission == null; 6987 6988 // check if target holds any <path-permission> that match uri 6989 final PathPermission[] pps = pi.pathPermissions; 6990 if (pps != null) { 6991 final String path = grantUri.uri.getPath(); 6992 int i = pps.length; 6993 while (i > 0 && (!readMet || !writeMet)) { 6994 i--; 6995 PathPermission pp = pps[i]; 6996 if (pp.match(path)) { 6997 if (!readMet) { 6998 final String pprperm = pp.getReadPermission(); 6999 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7000 + pprperm + " for " + pp.getPath() 7001 + ": match=" + pp.match(path) 7002 + " check=" + pm.checkUidPermission(pprperm, uid)); 7003 if (pprperm != null) { 7004 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7005 == PERMISSION_GRANTED) { 7006 readMet = true; 7007 } else { 7008 allowDefaultRead = false; 7009 } 7010 } 7011 } 7012 if (!writeMet) { 7013 final String ppwperm = pp.getWritePermission(); 7014 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7015 + ppwperm + " for " + pp.getPath() 7016 + ": match=" + pp.match(path) 7017 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7018 if (ppwperm != null) { 7019 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7020 == PERMISSION_GRANTED) { 7021 writeMet = true; 7022 } else { 7023 allowDefaultWrite = false; 7024 } 7025 } 7026 } 7027 } 7028 } 7029 } 7030 7031 // grant unprotected <provider> read/write, if not blocked by 7032 // <path-permission> above 7033 if (allowDefaultRead) readMet = true; 7034 if (allowDefaultWrite) writeMet = true; 7035 7036 } catch (RemoteException e) { 7037 return false; 7038 } 7039 7040 return readMet && writeMet; 7041 } 7042 7043 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7044 ProviderInfo pi = null; 7045 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7046 if (cpr != null) { 7047 pi = cpr.info; 7048 } else { 7049 try { 7050 pi = AppGlobals.getPackageManager().resolveContentProvider( 7051 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7052 } catch (RemoteException ex) { 7053 } 7054 } 7055 return pi; 7056 } 7057 7058 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7059 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7060 if (targetUris != null) { 7061 return targetUris.get(grantUri); 7062 } 7063 return null; 7064 } 7065 7066 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7067 String targetPkg, int targetUid, GrantUri grantUri) { 7068 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7069 if (targetUris == null) { 7070 targetUris = Maps.newArrayMap(); 7071 mGrantedUriPermissions.put(targetUid, targetUris); 7072 } 7073 7074 UriPermission perm = targetUris.get(grantUri); 7075 if (perm == null) { 7076 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7077 targetUris.put(grantUri, perm); 7078 } 7079 7080 return perm; 7081 } 7082 7083 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7084 final int modeFlags) { 7085 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7086 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7087 : UriPermission.STRENGTH_OWNED; 7088 7089 // Root gets to do everything. 7090 if (uid == 0) { 7091 return true; 7092 } 7093 7094 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7095 if (perms == null) return false; 7096 7097 // First look for exact match 7098 final UriPermission exactPerm = perms.get(grantUri); 7099 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7100 return true; 7101 } 7102 7103 // No exact match, look for prefixes 7104 final int N = perms.size(); 7105 for (int i = 0; i < N; i++) { 7106 final UriPermission perm = perms.valueAt(i); 7107 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7108 && perm.getStrength(modeFlags) >= minStrength) { 7109 return true; 7110 } 7111 } 7112 7113 return false; 7114 } 7115 7116 /** 7117 * @param uri This uri must NOT contain an embedded userId. 7118 * @param userId The userId in which the uri is to be resolved. 7119 */ 7120 @Override 7121 public int checkUriPermission(Uri uri, int pid, int uid, 7122 final int modeFlags, int userId) { 7123 enforceNotIsolatedCaller("checkUriPermission"); 7124 7125 // Another redirected-binder-call permissions check as in 7126 // {@link checkComponentPermission}. 7127 Identity tlsIdentity = sCallerIdentity.get(); 7128 if (tlsIdentity != null) { 7129 uid = tlsIdentity.uid; 7130 pid = tlsIdentity.pid; 7131 } 7132 7133 // Our own process gets to do everything. 7134 if (pid == MY_PID) { 7135 return PackageManager.PERMISSION_GRANTED; 7136 } 7137 synchronized (this) { 7138 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7139 ? PackageManager.PERMISSION_GRANTED 7140 : PackageManager.PERMISSION_DENIED; 7141 } 7142 } 7143 7144 /** 7145 * Check if the targetPkg can be granted permission to access uri by 7146 * the callingUid using the given modeFlags. Throws a security exception 7147 * if callingUid is not allowed to do this. Returns the uid of the target 7148 * if the URI permission grant should be performed; returns -1 if it is not 7149 * needed (for example targetPkg already has permission to access the URI). 7150 * If you already know the uid of the target, you can supply it in 7151 * lastTargetUid else set that to -1. 7152 */ 7153 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7154 final int modeFlags, int lastTargetUid) { 7155 if (!Intent.isAccessUriMode(modeFlags)) { 7156 return -1; 7157 } 7158 7159 if (targetPkg != null) { 7160 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7161 "Checking grant " + targetPkg + " permission to " + grantUri); 7162 } 7163 7164 final IPackageManager pm = AppGlobals.getPackageManager(); 7165 7166 // If this is not a content: uri, we can't do anything with it. 7167 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7168 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7169 "Can't grant URI permission for non-content URI: " + grantUri); 7170 return -1; 7171 } 7172 7173 final String authority = grantUri.uri.getAuthority(); 7174 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7175 if (pi == null) { 7176 Slog.w(TAG, "No content provider found for permission check: " + 7177 grantUri.uri.toSafeString()); 7178 return -1; 7179 } 7180 7181 int targetUid = lastTargetUid; 7182 if (targetUid < 0 && targetPkg != null) { 7183 try { 7184 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7185 if (targetUid < 0) { 7186 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7187 "Can't grant URI permission no uid for: " + targetPkg); 7188 return -1; 7189 } 7190 } catch (RemoteException ex) { 7191 return -1; 7192 } 7193 } 7194 7195 if (targetUid >= 0) { 7196 // First... does the target actually need this permission? 7197 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7198 // No need to grant the target this permission. 7199 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7200 "Target " + targetPkg + " already has full permission to " + grantUri); 7201 return -1; 7202 } 7203 } else { 7204 // First... there is no target package, so can anyone access it? 7205 boolean allowed = pi.exported; 7206 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7207 if (pi.readPermission != null) { 7208 allowed = false; 7209 } 7210 } 7211 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7212 if (pi.writePermission != null) { 7213 allowed = false; 7214 } 7215 } 7216 if (allowed) { 7217 return -1; 7218 } 7219 } 7220 7221 /* There is a special cross user grant if: 7222 * - The target is on another user. 7223 * - Apps on the current user can access the uri without any uid permissions. 7224 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7225 * grant uri permissions. 7226 */ 7227 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7228 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7229 modeFlags, false /*without considering the uid permissions*/); 7230 7231 // Second... is the provider allowing granting of URI permissions? 7232 if (!specialCrossUserGrant) { 7233 if (!pi.grantUriPermissions) { 7234 throw new SecurityException("Provider " + pi.packageName 7235 + "/" + pi.name 7236 + " does not allow granting of Uri permissions (uri " 7237 + grantUri + ")"); 7238 } 7239 if (pi.uriPermissionPatterns != null) { 7240 final int N = pi.uriPermissionPatterns.length; 7241 boolean allowed = false; 7242 for (int i=0; i<N; i++) { 7243 if (pi.uriPermissionPatterns[i] != null 7244 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7245 allowed = true; 7246 break; 7247 } 7248 } 7249 if (!allowed) { 7250 throw new SecurityException("Provider " + pi.packageName 7251 + "/" + pi.name 7252 + " does not allow granting of permission to path of Uri " 7253 + grantUri); 7254 } 7255 } 7256 } 7257 7258 // Third... does the caller itself have permission to access 7259 // this uri? 7260 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7261 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7262 // Require they hold a strong enough Uri permission 7263 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7264 throw new SecurityException("Uid " + callingUid 7265 + " does not have permission to uri " + grantUri); 7266 } 7267 } 7268 } 7269 return targetUid; 7270 } 7271 7272 /** 7273 * @param uri This uri must NOT contain an embedded userId. 7274 * @param userId The userId in which the uri is to be resolved. 7275 */ 7276 @Override 7277 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7278 final int modeFlags, int userId) { 7279 enforceNotIsolatedCaller("checkGrantUriPermission"); 7280 synchronized(this) { 7281 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7282 new GrantUri(userId, uri, false), modeFlags, -1); 7283 } 7284 } 7285 7286 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7287 final int modeFlags, UriPermissionOwner owner) { 7288 if (!Intent.isAccessUriMode(modeFlags)) { 7289 return; 7290 } 7291 7292 // So here we are: the caller has the assumed permission 7293 // to the uri, and the target doesn't. Let's now give this to 7294 // the target. 7295 7296 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7297 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7298 7299 final String authority = grantUri.uri.getAuthority(); 7300 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7301 if (pi == null) { 7302 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7303 return; 7304 } 7305 7306 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7307 grantUri.prefix = true; 7308 } 7309 final UriPermission perm = findOrCreateUriPermissionLocked( 7310 pi.packageName, targetPkg, targetUid, grantUri); 7311 perm.grantModes(modeFlags, owner); 7312 } 7313 7314 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7315 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7316 if (targetPkg == null) { 7317 throw new NullPointerException("targetPkg"); 7318 } 7319 int targetUid; 7320 final IPackageManager pm = AppGlobals.getPackageManager(); 7321 try { 7322 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7323 } catch (RemoteException ex) { 7324 return; 7325 } 7326 7327 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7328 targetUid); 7329 if (targetUid < 0) { 7330 return; 7331 } 7332 7333 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7334 owner); 7335 } 7336 7337 static class NeededUriGrants extends ArrayList<GrantUri> { 7338 final String targetPkg; 7339 final int targetUid; 7340 final int flags; 7341 7342 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7343 this.targetPkg = targetPkg; 7344 this.targetUid = targetUid; 7345 this.flags = flags; 7346 } 7347 } 7348 7349 /** 7350 * Like checkGrantUriPermissionLocked, but takes an Intent. 7351 */ 7352 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7353 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7354 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7355 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7356 + " clip=" + (intent != null ? intent.getClipData() : null) 7357 + " from " + intent + "; flags=0x" 7358 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7359 7360 if (targetPkg == null) { 7361 throw new NullPointerException("targetPkg"); 7362 } 7363 7364 if (intent == null) { 7365 return null; 7366 } 7367 Uri data = intent.getData(); 7368 ClipData clip = intent.getClipData(); 7369 if (data == null && clip == null) { 7370 return null; 7371 } 7372 // Default userId for uris in the intent (if they don't specify it themselves) 7373 int contentUserHint = intent.getContentUserHint(); 7374 if (contentUserHint == UserHandle.USER_CURRENT) { 7375 contentUserHint = UserHandle.getUserId(callingUid); 7376 } 7377 final IPackageManager pm = AppGlobals.getPackageManager(); 7378 int targetUid; 7379 if (needed != null) { 7380 targetUid = needed.targetUid; 7381 } else { 7382 try { 7383 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7384 } catch (RemoteException ex) { 7385 return null; 7386 } 7387 if (targetUid < 0) { 7388 if (DEBUG_URI_PERMISSION) { 7389 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7390 + " on user " + targetUserId); 7391 } 7392 return null; 7393 } 7394 } 7395 if (data != null) { 7396 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7397 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7398 targetUid); 7399 if (targetUid > 0) { 7400 if (needed == null) { 7401 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7402 } 7403 needed.add(grantUri); 7404 } 7405 } 7406 if (clip != null) { 7407 for (int i=0; i<clip.getItemCount(); i++) { 7408 Uri uri = clip.getItemAt(i).getUri(); 7409 if (uri != null) { 7410 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7411 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7412 targetUid); 7413 if (targetUid > 0) { 7414 if (needed == null) { 7415 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7416 } 7417 needed.add(grantUri); 7418 } 7419 } else { 7420 Intent clipIntent = clip.getItemAt(i).getIntent(); 7421 if (clipIntent != null) { 7422 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7423 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7424 if (newNeeded != null) { 7425 needed = newNeeded; 7426 } 7427 } 7428 } 7429 } 7430 } 7431 7432 return needed; 7433 } 7434 7435 /** 7436 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7437 */ 7438 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7439 UriPermissionOwner owner) { 7440 if (needed != null) { 7441 for (int i=0; i<needed.size(); i++) { 7442 GrantUri grantUri = needed.get(i); 7443 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7444 grantUri, needed.flags, owner); 7445 } 7446 } 7447 } 7448 7449 void grantUriPermissionFromIntentLocked(int callingUid, 7450 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7451 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7452 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7453 if (needed == null) { 7454 return; 7455 } 7456 7457 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7458 } 7459 7460 /** 7461 * @param uri This uri must NOT contain an embedded userId. 7462 * @param userId The userId in which the uri is to be resolved. 7463 */ 7464 @Override 7465 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7466 final int modeFlags, int userId) { 7467 enforceNotIsolatedCaller("grantUriPermission"); 7468 GrantUri grantUri = new GrantUri(userId, uri, false); 7469 synchronized(this) { 7470 final ProcessRecord r = getRecordForAppLocked(caller); 7471 if (r == null) { 7472 throw new SecurityException("Unable to find app for caller " 7473 + caller 7474 + " when granting permission to uri " + grantUri); 7475 } 7476 if (targetPkg == null) { 7477 throw new IllegalArgumentException("null target"); 7478 } 7479 if (grantUri == null) { 7480 throw new IllegalArgumentException("null uri"); 7481 } 7482 7483 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7484 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7485 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7486 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7487 7488 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7489 UserHandle.getUserId(r.uid)); 7490 } 7491 } 7492 7493 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7494 if (perm.modeFlags == 0) { 7495 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7496 perm.targetUid); 7497 if (perms != null) { 7498 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7499 "Removing " + perm.targetUid + " permission to " + perm.uri); 7500 7501 perms.remove(perm.uri); 7502 if (perms.isEmpty()) { 7503 mGrantedUriPermissions.remove(perm.targetUid); 7504 } 7505 } 7506 } 7507 } 7508 7509 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7510 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7511 7512 final IPackageManager pm = AppGlobals.getPackageManager(); 7513 final String authority = grantUri.uri.getAuthority(); 7514 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7515 if (pi == null) { 7516 Slog.w(TAG, "No content provider found for permission revoke: " 7517 + grantUri.toSafeString()); 7518 return; 7519 } 7520 7521 // Does the caller have this permission on the URI? 7522 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7523 // Have they don't have direct access to the URI, then revoke any URI 7524 // permissions that have been granted to them. 7525 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7526 if (perms != null) { 7527 boolean persistChanged = false; 7528 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7529 final UriPermission perm = it.next(); 7530 if (perm.uri.sourceUserId == grantUri.sourceUserId 7531 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7532 if (DEBUG_URI_PERMISSION) 7533 Slog.v(TAG, 7534 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7535 persistChanged |= perm.revokeModes( 7536 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7537 if (perm.modeFlags == 0) { 7538 it.remove(); 7539 } 7540 } 7541 } 7542 if (perms.isEmpty()) { 7543 mGrantedUriPermissions.remove(callingUid); 7544 } 7545 if (persistChanged) { 7546 schedulePersistUriGrants(); 7547 } 7548 } 7549 return; 7550 } 7551 7552 boolean persistChanged = false; 7553 7554 // Go through all of the permissions and remove any that match. 7555 int N = mGrantedUriPermissions.size(); 7556 for (int i = 0; i < N; i++) { 7557 final int targetUid = mGrantedUriPermissions.keyAt(i); 7558 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7559 7560 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7561 final UriPermission perm = it.next(); 7562 if (perm.uri.sourceUserId == grantUri.sourceUserId 7563 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7564 if (DEBUG_URI_PERMISSION) 7565 Slog.v(TAG, 7566 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7567 persistChanged |= perm.revokeModes( 7568 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7569 if (perm.modeFlags == 0) { 7570 it.remove(); 7571 } 7572 } 7573 } 7574 7575 if (perms.isEmpty()) { 7576 mGrantedUriPermissions.remove(targetUid); 7577 N--; 7578 i--; 7579 } 7580 } 7581 7582 if (persistChanged) { 7583 schedulePersistUriGrants(); 7584 } 7585 } 7586 7587 /** 7588 * @param uri This uri must NOT contain an embedded userId. 7589 * @param userId The userId in which the uri is to be resolved. 7590 */ 7591 @Override 7592 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7593 int userId) { 7594 enforceNotIsolatedCaller("revokeUriPermission"); 7595 synchronized(this) { 7596 final ProcessRecord r = getRecordForAppLocked(caller); 7597 if (r == null) { 7598 throw new SecurityException("Unable to find app for caller " 7599 + caller 7600 + " when revoking permission to uri " + uri); 7601 } 7602 if (uri == null) { 7603 Slog.w(TAG, "revokeUriPermission: null uri"); 7604 return; 7605 } 7606 7607 if (!Intent.isAccessUriMode(modeFlags)) { 7608 return; 7609 } 7610 7611 final IPackageManager pm = AppGlobals.getPackageManager(); 7612 final String authority = uri.getAuthority(); 7613 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7614 if (pi == null) { 7615 Slog.w(TAG, "No content provider found for permission revoke: " 7616 + uri.toSafeString()); 7617 return; 7618 } 7619 7620 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7621 } 7622 } 7623 7624 /** 7625 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7626 * given package. 7627 * 7628 * @param packageName Package name to match, or {@code null} to apply to all 7629 * packages. 7630 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7631 * to all users. 7632 * @param persistable If persistable grants should be removed. 7633 */ 7634 private void removeUriPermissionsForPackageLocked( 7635 String packageName, int userHandle, boolean persistable) { 7636 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7637 throw new IllegalArgumentException("Must narrow by either package or user"); 7638 } 7639 7640 boolean persistChanged = false; 7641 7642 int N = mGrantedUriPermissions.size(); 7643 for (int i = 0; i < N; i++) { 7644 final int targetUid = mGrantedUriPermissions.keyAt(i); 7645 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7646 7647 // Only inspect grants matching user 7648 if (userHandle == UserHandle.USER_ALL 7649 || userHandle == UserHandle.getUserId(targetUid)) { 7650 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7651 final UriPermission perm = it.next(); 7652 7653 // Only inspect grants matching package 7654 if (packageName == null || perm.sourcePkg.equals(packageName) 7655 || perm.targetPkg.equals(packageName)) { 7656 persistChanged |= perm.revokeModes( 7657 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7658 7659 // Only remove when no modes remain; any persisted grants 7660 // will keep this alive. 7661 if (perm.modeFlags == 0) { 7662 it.remove(); 7663 } 7664 } 7665 } 7666 7667 if (perms.isEmpty()) { 7668 mGrantedUriPermissions.remove(targetUid); 7669 N--; 7670 i--; 7671 } 7672 } 7673 } 7674 7675 if (persistChanged) { 7676 schedulePersistUriGrants(); 7677 } 7678 } 7679 7680 @Override 7681 public IBinder newUriPermissionOwner(String name) { 7682 enforceNotIsolatedCaller("newUriPermissionOwner"); 7683 synchronized(this) { 7684 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7685 return owner.getExternalTokenLocked(); 7686 } 7687 } 7688 7689 /** 7690 * @param uri This uri must NOT contain an embedded userId. 7691 * @param sourceUserId The userId in which the uri is to be resolved. 7692 * @param targetUserId The userId of the app that receives the grant. 7693 */ 7694 @Override 7695 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7696 final int modeFlags, int sourceUserId, int targetUserId) { 7697 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7698 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7699 synchronized(this) { 7700 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7701 if (owner == null) { 7702 throw new IllegalArgumentException("Unknown owner: " + token); 7703 } 7704 if (fromUid != Binder.getCallingUid()) { 7705 if (Binder.getCallingUid() != Process.myUid()) { 7706 // Only system code can grant URI permissions on behalf 7707 // of other users. 7708 throw new SecurityException("nice try"); 7709 } 7710 } 7711 if (targetPkg == null) { 7712 throw new IllegalArgumentException("null target"); 7713 } 7714 if (uri == null) { 7715 throw new IllegalArgumentException("null uri"); 7716 } 7717 7718 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7719 modeFlags, owner, targetUserId); 7720 } 7721 } 7722 7723 /** 7724 * @param uri This uri must NOT contain an embedded userId. 7725 * @param userId The userId in which the uri is to be resolved. 7726 */ 7727 @Override 7728 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7729 synchronized(this) { 7730 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7731 if (owner == null) { 7732 throw new IllegalArgumentException("Unknown owner: " + token); 7733 } 7734 7735 if (uri == null) { 7736 owner.removeUriPermissionsLocked(mode); 7737 } else { 7738 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7739 } 7740 } 7741 } 7742 7743 private void schedulePersistUriGrants() { 7744 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7745 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7746 10 * DateUtils.SECOND_IN_MILLIS); 7747 } 7748 } 7749 7750 private void writeGrantedUriPermissions() { 7751 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7752 7753 // Snapshot permissions so we can persist without lock 7754 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7755 synchronized (this) { 7756 final int size = mGrantedUriPermissions.size(); 7757 for (int i = 0; i < size; i++) { 7758 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7759 for (UriPermission perm : perms.values()) { 7760 if (perm.persistedModeFlags != 0) { 7761 persist.add(perm.snapshot()); 7762 } 7763 } 7764 } 7765 } 7766 7767 FileOutputStream fos = null; 7768 try { 7769 fos = mGrantFile.startWrite(); 7770 7771 XmlSerializer out = new FastXmlSerializer(); 7772 out.setOutput(fos, "utf-8"); 7773 out.startDocument(null, true); 7774 out.startTag(null, TAG_URI_GRANTS); 7775 for (UriPermission.Snapshot perm : persist) { 7776 out.startTag(null, TAG_URI_GRANT); 7777 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7778 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7779 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7780 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7781 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7782 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7783 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7784 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7785 out.endTag(null, TAG_URI_GRANT); 7786 } 7787 out.endTag(null, TAG_URI_GRANTS); 7788 out.endDocument(); 7789 7790 mGrantFile.finishWrite(fos); 7791 } catch (IOException e) { 7792 if (fos != null) { 7793 mGrantFile.failWrite(fos); 7794 } 7795 } 7796 } 7797 7798 private void readGrantedUriPermissionsLocked() { 7799 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7800 7801 final long now = System.currentTimeMillis(); 7802 7803 FileInputStream fis = null; 7804 try { 7805 fis = mGrantFile.openRead(); 7806 final XmlPullParser in = Xml.newPullParser(); 7807 in.setInput(fis, null); 7808 7809 int type; 7810 while ((type = in.next()) != END_DOCUMENT) { 7811 final String tag = in.getName(); 7812 if (type == START_TAG) { 7813 if (TAG_URI_GRANT.equals(tag)) { 7814 final int sourceUserId; 7815 final int targetUserId; 7816 final int userHandle = readIntAttribute(in, 7817 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7818 if (userHandle != UserHandle.USER_NULL) { 7819 // For backwards compatibility. 7820 sourceUserId = userHandle; 7821 targetUserId = userHandle; 7822 } else { 7823 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7824 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7825 } 7826 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7827 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7828 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7829 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7830 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7831 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7832 7833 // Sanity check that provider still belongs to source package 7834 final ProviderInfo pi = getProviderInfoLocked( 7835 uri.getAuthority(), sourceUserId); 7836 if (pi != null && sourcePkg.equals(pi.packageName)) { 7837 int targetUid = -1; 7838 try { 7839 targetUid = AppGlobals.getPackageManager() 7840 .getPackageUid(targetPkg, targetUserId); 7841 } catch (RemoteException e) { 7842 } 7843 if (targetUid != -1) { 7844 final UriPermission perm = findOrCreateUriPermissionLocked( 7845 sourcePkg, targetPkg, targetUid, 7846 new GrantUri(sourceUserId, uri, prefix)); 7847 perm.initPersistedModes(modeFlags, createdTime); 7848 } 7849 } else { 7850 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7851 + " but instead found " + pi); 7852 } 7853 } 7854 } 7855 } 7856 } catch (FileNotFoundException e) { 7857 // Missing grants is okay 7858 } catch (IOException e) { 7859 Log.wtf(TAG, "Failed reading Uri grants", e); 7860 } catch (XmlPullParserException e) { 7861 Log.wtf(TAG, "Failed reading Uri grants", e); 7862 } finally { 7863 IoUtils.closeQuietly(fis); 7864 } 7865 } 7866 7867 /** 7868 * @param uri This uri must NOT contain an embedded userId. 7869 * @param userId The userId in which the uri is to be resolved. 7870 */ 7871 @Override 7872 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7873 enforceNotIsolatedCaller("takePersistableUriPermission"); 7874 7875 Preconditions.checkFlagsArgument(modeFlags, 7876 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7877 7878 synchronized (this) { 7879 final int callingUid = Binder.getCallingUid(); 7880 boolean persistChanged = false; 7881 GrantUri grantUri = new GrantUri(userId, uri, false); 7882 7883 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7884 new GrantUri(userId, uri, false)); 7885 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7886 new GrantUri(userId, uri, true)); 7887 7888 final boolean exactValid = (exactPerm != null) 7889 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7890 final boolean prefixValid = (prefixPerm != null) 7891 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7892 7893 if (!(exactValid || prefixValid)) { 7894 throw new SecurityException("No persistable permission grants found for UID " 7895 + callingUid + " and Uri " + grantUri.toSafeString()); 7896 } 7897 7898 if (exactValid) { 7899 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7900 } 7901 if (prefixValid) { 7902 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7903 } 7904 7905 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7906 7907 if (persistChanged) { 7908 schedulePersistUriGrants(); 7909 } 7910 } 7911 } 7912 7913 /** 7914 * @param uri This uri must NOT contain an embedded userId. 7915 * @param userId The userId in which the uri is to be resolved. 7916 */ 7917 @Override 7918 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7919 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7920 7921 Preconditions.checkFlagsArgument(modeFlags, 7922 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7923 7924 synchronized (this) { 7925 final int callingUid = Binder.getCallingUid(); 7926 boolean persistChanged = false; 7927 7928 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7929 new GrantUri(userId, uri, false)); 7930 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7931 new GrantUri(userId, uri, true)); 7932 if (exactPerm == null && prefixPerm == null) { 7933 throw new SecurityException("No permission grants found for UID " + callingUid 7934 + " and Uri " + uri.toSafeString()); 7935 } 7936 7937 if (exactPerm != null) { 7938 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7939 removeUriPermissionIfNeededLocked(exactPerm); 7940 } 7941 if (prefixPerm != null) { 7942 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7943 removeUriPermissionIfNeededLocked(prefixPerm); 7944 } 7945 7946 if (persistChanged) { 7947 schedulePersistUriGrants(); 7948 } 7949 } 7950 } 7951 7952 /** 7953 * Prune any older {@link UriPermission} for the given UID until outstanding 7954 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7955 * 7956 * @return if any mutations occured that require persisting. 7957 */ 7958 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7959 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7960 if (perms == null) return false; 7961 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7962 7963 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7964 for (UriPermission perm : perms.values()) { 7965 if (perm.persistedModeFlags != 0) { 7966 persisted.add(perm); 7967 } 7968 } 7969 7970 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7971 if (trimCount <= 0) return false; 7972 7973 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7974 for (int i = 0; i < trimCount; i++) { 7975 final UriPermission perm = persisted.get(i); 7976 7977 if (DEBUG_URI_PERMISSION) { 7978 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7979 } 7980 7981 perm.releasePersistableModes(~0); 7982 removeUriPermissionIfNeededLocked(perm); 7983 } 7984 7985 return true; 7986 } 7987 7988 @Override 7989 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7990 String packageName, boolean incoming) { 7991 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7992 Preconditions.checkNotNull(packageName, "packageName"); 7993 7994 final int callingUid = Binder.getCallingUid(); 7995 final IPackageManager pm = AppGlobals.getPackageManager(); 7996 try { 7997 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7998 if (packageUid != callingUid) { 7999 throw new SecurityException( 8000 "Package " + packageName + " does not belong to calling UID " + callingUid); 8001 } 8002 } catch (RemoteException e) { 8003 throw new SecurityException("Failed to verify package name ownership"); 8004 } 8005 8006 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8007 synchronized (this) { 8008 if (incoming) { 8009 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8010 callingUid); 8011 if (perms == null) { 8012 Slog.w(TAG, "No permission grants found for " + packageName); 8013 } else { 8014 for (UriPermission perm : perms.values()) { 8015 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8016 result.add(perm.buildPersistedPublicApiObject()); 8017 } 8018 } 8019 } 8020 } else { 8021 final int size = mGrantedUriPermissions.size(); 8022 for (int i = 0; i < size; i++) { 8023 final ArrayMap<GrantUri, UriPermission> perms = 8024 mGrantedUriPermissions.valueAt(i); 8025 for (UriPermission perm : perms.values()) { 8026 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8027 result.add(perm.buildPersistedPublicApiObject()); 8028 } 8029 } 8030 } 8031 } 8032 } 8033 return new ParceledListSlice<android.content.UriPermission>(result); 8034 } 8035 8036 @Override 8037 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8038 synchronized (this) { 8039 ProcessRecord app = 8040 who != null ? getRecordForAppLocked(who) : null; 8041 if (app == null) return; 8042 8043 Message msg = Message.obtain(); 8044 msg.what = WAIT_FOR_DEBUGGER_MSG; 8045 msg.obj = app; 8046 msg.arg1 = waiting ? 1 : 0; 8047 mHandler.sendMessage(msg); 8048 } 8049 } 8050 8051 @Override 8052 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8053 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8054 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8055 outInfo.availMem = Process.getFreeMemory(); 8056 outInfo.totalMem = Process.getTotalMemory(); 8057 outInfo.threshold = homeAppMem; 8058 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8059 outInfo.hiddenAppThreshold = cachedAppMem; 8060 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8061 ProcessList.SERVICE_ADJ); 8062 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8063 ProcessList.VISIBLE_APP_ADJ); 8064 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8065 ProcessList.FOREGROUND_APP_ADJ); 8066 } 8067 8068 // ========================================================= 8069 // TASK MANAGEMENT 8070 // ========================================================= 8071 8072 @Override 8073 public List<IAppTask> getAppTasks(String callingPackage) { 8074 int callingUid = Binder.getCallingUid(); 8075 long ident = Binder.clearCallingIdentity(); 8076 8077 synchronized(this) { 8078 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8079 try { 8080 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8081 8082 final int N = mRecentTasks.size(); 8083 for (int i = 0; i < N; i++) { 8084 TaskRecord tr = mRecentTasks.get(i); 8085 // Skip tasks that do not match the caller. We don't need to verify 8086 // callingPackage, because we are also limiting to callingUid and know 8087 // that will limit to the correct security sandbox. 8088 if (tr.effectiveUid != callingUid) { 8089 continue; 8090 } 8091 Intent intent = tr.getBaseIntent(); 8092 if (intent == null || 8093 !callingPackage.equals(intent.getComponent().getPackageName())) { 8094 continue; 8095 } 8096 ActivityManager.RecentTaskInfo taskInfo = 8097 createRecentTaskInfoFromTaskRecord(tr); 8098 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8099 list.add(taskImpl); 8100 } 8101 } finally { 8102 Binder.restoreCallingIdentity(ident); 8103 } 8104 return list; 8105 } 8106 } 8107 8108 @Override 8109 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8110 final int callingUid = Binder.getCallingUid(); 8111 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8112 8113 synchronized(this) { 8114 if (localLOGV) Slog.v( 8115 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8116 8117 final boolean allowed = checkCallingPermission( 8118 android.Manifest.permission.GET_TASKS) 8119 == PackageManager.PERMISSION_GRANTED; 8120 if (!allowed) { 8121 Slog.w(TAG, "getTasks: caller " + callingUid 8122 + " does not hold GET_TASKS; limiting output"); 8123 } 8124 8125 // TODO: Improve with MRU list from all ActivityStacks. 8126 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8127 } 8128 8129 return list; 8130 } 8131 8132 TaskRecord getMostRecentTask() { 8133 return mRecentTasks.get(0); 8134 } 8135 8136 /** 8137 * Creates a new RecentTaskInfo from a TaskRecord. 8138 */ 8139 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8140 // Update the task description to reflect any changes in the task stack 8141 tr.updateTaskDescription(); 8142 8143 // Compose the recent task info 8144 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8145 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8146 rti.persistentId = tr.taskId; 8147 rti.baseIntent = new Intent(tr.getBaseIntent()); 8148 rti.origActivity = tr.origActivity; 8149 rti.description = tr.lastDescription; 8150 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8151 rti.userId = tr.userId; 8152 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8153 rti.firstActiveTime = tr.firstActiveTime; 8154 rti.lastActiveTime = tr.lastActiveTime; 8155 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8156 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8157 return rti; 8158 } 8159 8160 @Override 8161 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8162 final int callingUid = Binder.getCallingUid(); 8163 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8164 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8165 8166 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8167 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8168 synchronized (this) { 8169 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8170 == PackageManager.PERMISSION_GRANTED; 8171 if (!allowed) { 8172 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8173 + " does not hold GET_TASKS; limiting output"); 8174 } 8175 final boolean detailed = checkCallingPermission( 8176 android.Manifest.permission.GET_DETAILED_TASKS) 8177 == PackageManager.PERMISSION_GRANTED; 8178 8179 final int N = mRecentTasks.size(); 8180 ArrayList<ActivityManager.RecentTaskInfo> res 8181 = new ArrayList<ActivityManager.RecentTaskInfo>( 8182 maxNum < N ? maxNum : N); 8183 8184 final Set<Integer> includedUsers; 8185 if (includeProfiles) { 8186 includedUsers = getProfileIdsLocked(userId); 8187 } else { 8188 includedUsers = new HashSet<Integer>(); 8189 } 8190 includedUsers.add(Integer.valueOf(userId)); 8191 8192 for (int i=0; i<N && maxNum > 0; i++) { 8193 TaskRecord tr = mRecentTasks.get(i); 8194 // Only add calling user or related users recent tasks 8195 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8196 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8197 continue; 8198 } 8199 8200 // Return the entry if desired by the caller. We always return 8201 // the first entry, because callers always expect this to be the 8202 // foreground app. We may filter others if the caller has 8203 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8204 // we should exclude the entry. 8205 8206 if (i == 0 8207 || withExcluded 8208 || (tr.intent == null) 8209 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8210 == 0)) { 8211 if (!allowed) { 8212 // If the caller doesn't have the GET_TASKS permission, then only 8213 // allow them to see a small subset of tasks -- their own and home. 8214 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8215 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8216 continue; 8217 } 8218 } 8219 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8220 if (tr.stack != null && tr.stack.isHomeStack()) { 8221 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8222 continue; 8223 } 8224 } 8225 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8226 // Don't include auto remove tasks that are finished or finishing. 8227 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8228 + tr); 8229 continue; 8230 } 8231 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8232 && !tr.isAvailable) { 8233 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8234 continue; 8235 } 8236 8237 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8238 if (!detailed) { 8239 rti.baseIntent.replaceExtras((Bundle)null); 8240 } 8241 8242 res.add(rti); 8243 maxNum--; 8244 } 8245 } 8246 return res; 8247 } 8248 } 8249 8250 private TaskRecord recentTaskForIdLocked(int id) { 8251 final int N = mRecentTasks.size(); 8252 for (int i=0; i<N; i++) { 8253 TaskRecord tr = mRecentTasks.get(i); 8254 if (tr.taskId == id) { 8255 return tr; 8256 } 8257 } 8258 return null; 8259 } 8260 8261 @Override 8262 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8263 synchronized (this) { 8264 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8265 "getTaskThumbnail()"); 8266 TaskRecord tr = recentTaskForIdLocked(id); 8267 if (tr != null) { 8268 return tr.getTaskThumbnailLocked(); 8269 } 8270 } 8271 return null; 8272 } 8273 8274 @Override 8275 public int addAppTask(IBinder activityToken, Intent intent, 8276 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8277 final int callingUid = Binder.getCallingUid(); 8278 final long callingIdent = Binder.clearCallingIdentity(); 8279 8280 try { 8281 synchronized (this) { 8282 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8283 if (r == null) { 8284 throw new IllegalArgumentException("Activity does not exist; token=" 8285 + activityToken); 8286 } 8287 ComponentName comp = intent.getComponent(); 8288 if (comp == null) { 8289 throw new IllegalArgumentException("Intent " + intent 8290 + " must specify explicit component"); 8291 } 8292 if (thumbnail.getWidth() != mThumbnailWidth 8293 || thumbnail.getHeight() != mThumbnailHeight) { 8294 throw new IllegalArgumentException("Bad thumbnail size: got " 8295 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8296 + mThumbnailWidth + "x" + mThumbnailHeight); 8297 } 8298 if (intent.getSelector() != null) { 8299 intent.setSelector(null); 8300 } 8301 if (intent.getSourceBounds() != null) { 8302 intent.setSourceBounds(null); 8303 } 8304 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8305 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8306 // The caller has added this as an auto-remove task... that makes no 8307 // sense, so turn off auto-remove. 8308 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8309 } 8310 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8311 // Must be a new task. 8312 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8313 } 8314 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8315 mLastAddedTaskActivity = null; 8316 } 8317 ActivityInfo ainfo = mLastAddedTaskActivity; 8318 if (ainfo == null) { 8319 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8320 comp, 0, UserHandle.getUserId(callingUid)); 8321 if (ainfo.applicationInfo.uid != callingUid) { 8322 throw new SecurityException( 8323 "Can't add task for another application: target uid=" 8324 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8325 } 8326 } 8327 8328 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8329 intent, description); 8330 8331 int trimIdx = trimRecentsForTask(task, false); 8332 if (trimIdx >= 0) { 8333 // If this would have caused a trim, then we'll abort because that 8334 // means it would be added at the end of the list but then just removed. 8335 return -1; 8336 } 8337 8338 final int N = mRecentTasks.size(); 8339 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8340 final TaskRecord tr = mRecentTasks.remove(N - 1); 8341 tr.removedFromRecents(mTaskPersister); 8342 } 8343 8344 task.inRecents = true; 8345 mRecentTasks.add(task); 8346 r.task.stack.addTask(task, false, false); 8347 8348 task.setLastThumbnail(thumbnail); 8349 task.freeLastThumbnail(); 8350 8351 return task.taskId; 8352 } 8353 } finally { 8354 Binder.restoreCallingIdentity(callingIdent); 8355 } 8356 } 8357 8358 @Override 8359 public Point getAppTaskThumbnailSize() { 8360 synchronized (this) { 8361 return new Point(mThumbnailWidth, mThumbnailHeight); 8362 } 8363 } 8364 8365 @Override 8366 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8367 synchronized (this) { 8368 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8369 if (r != null) { 8370 r.taskDescription = td; 8371 r.task.updateTaskDescription(); 8372 } 8373 } 8374 } 8375 8376 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8377 mRecentTasks.remove(tr); 8378 tr.removedFromRecents(mTaskPersister); 8379 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8380 Intent baseIntent = new Intent( 8381 tr.intent != null ? tr.intent : tr.affinityIntent); 8382 ComponentName component = baseIntent.getComponent(); 8383 if (component == null) { 8384 Slog.w(TAG, "Now component for base intent of task: " + tr); 8385 return; 8386 } 8387 8388 // Find any running services associated with this app. 8389 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8390 8391 if (killProcesses) { 8392 // Find any running processes associated with this app. 8393 final String pkg = component.getPackageName(); 8394 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8395 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8396 for (int i=0; i<pmap.size(); i++) { 8397 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8398 for (int j=0; j<uids.size(); j++) { 8399 ProcessRecord proc = uids.valueAt(j); 8400 if (proc.userId != tr.userId) { 8401 continue; 8402 } 8403 if (!proc.pkgList.containsKey(pkg)) { 8404 continue; 8405 } 8406 procs.add(proc); 8407 } 8408 } 8409 8410 // Kill the running processes. 8411 for (int i=0; i<procs.size(); i++) { 8412 ProcessRecord pr = procs.get(i); 8413 if (pr == mHomeProcess) { 8414 // Don't kill the home process along with tasks from the same package. 8415 continue; 8416 } 8417 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8418 pr.kill("remove task", true); 8419 } else { 8420 pr.waitingToKill = "remove task"; 8421 } 8422 } 8423 } 8424 } 8425 8426 /** 8427 * Removes the task with the specified task id. 8428 * 8429 * @param taskId Identifier of the task to be removed. 8430 * @param flags Additional operational flags. May be 0 or 8431 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8432 * @return Returns true if the given task was found and removed. 8433 */ 8434 private boolean removeTaskByIdLocked(int taskId, int flags) { 8435 TaskRecord tr = recentTaskForIdLocked(taskId); 8436 if (tr != null) { 8437 tr.removeTaskActivitiesLocked(); 8438 cleanUpRemovedTaskLocked(tr, flags); 8439 if (tr.isPersistable) { 8440 notifyTaskPersisterLocked(null, true); 8441 } 8442 return true; 8443 } 8444 return false; 8445 } 8446 8447 @Override 8448 public boolean removeTask(int taskId, int flags) { 8449 synchronized (this) { 8450 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8451 "removeTask()"); 8452 long ident = Binder.clearCallingIdentity(); 8453 try { 8454 return removeTaskByIdLocked(taskId, flags); 8455 } finally { 8456 Binder.restoreCallingIdentity(ident); 8457 } 8458 } 8459 } 8460 8461 /** 8462 * TODO: Add mController hook 8463 */ 8464 @Override 8465 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8466 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8467 "moveTaskToFront()"); 8468 8469 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8470 synchronized(this) { 8471 moveTaskToFrontLocked(taskId, flags, options); 8472 } 8473 } 8474 8475 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8476 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8477 Binder.getCallingUid(), "Task to front")) { 8478 ActivityOptions.abort(options); 8479 return; 8480 } 8481 final long origId = Binder.clearCallingIdentity(); 8482 try { 8483 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8484 if (task == null) { 8485 return; 8486 } 8487 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8488 mStackSupervisor.showLockTaskToast(); 8489 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8490 return; 8491 } 8492 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8493 if (prev != null && prev.isRecentsActivity()) { 8494 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8495 } 8496 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8497 } finally { 8498 Binder.restoreCallingIdentity(origId); 8499 } 8500 ActivityOptions.abort(options); 8501 } 8502 8503 @Override 8504 public void moveTaskToBack(int taskId) { 8505 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8506 "moveTaskToBack()"); 8507 8508 synchronized(this) { 8509 TaskRecord tr = recentTaskForIdLocked(taskId); 8510 if (tr != null) { 8511 if (tr == mStackSupervisor.mLockTaskModeTask) { 8512 mStackSupervisor.showLockTaskToast(); 8513 return; 8514 } 8515 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8516 ActivityStack stack = tr.stack; 8517 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8518 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8519 Binder.getCallingUid(), "Task to back")) { 8520 return; 8521 } 8522 } 8523 final long origId = Binder.clearCallingIdentity(); 8524 try { 8525 stack.moveTaskToBackLocked(taskId, null); 8526 } finally { 8527 Binder.restoreCallingIdentity(origId); 8528 } 8529 } 8530 } 8531 } 8532 8533 /** 8534 * Moves an activity, and all of the other activities within the same task, to the bottom 8535 * of the history stack. The activity's order within the task is unchanged. 8536 * 8537 * @param token A reference to the activity we wish to move 8538 * @param nonRoot If false then this only works if the activity is the root 8539 * of a task; if true it will work for any activity in a task. 8540 * @return Returns true if the move completed, false if not. 8541 */ 8542 @Override 8543 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8544 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8545 synchronized(this) { 8546 final long origId = Binder.clearCallingIdentity(); 8547 try { 8548 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8549 if (taskId >= 0) { 8550 if ((mStackSupervisor.mLockTaskModeTask != null) 8551 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8552 mStackSupervisor.showLockTaskToast(); 8553 return false; 8554 } 8555 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8556 } 8557 } finally { 8558 Binder.restoreCallingIdentity(origId); 8559 } 8560 } 8561 return false; 8562 } 8563 8564 @Override 8565 public void moveTaskBackwards(int task) { 8566 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8567 "moveTaskBackwards()"); 8568 8569 synchronized(this) { 8570 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8571 Binder.getCallingUid(), "Task backwards")) { 8572 return; 8573 } 8574 final long origId = Binder.clearCallingIdentity(); 8575 moveTaskBackwardsLocked(task); 8576 Binder.restoreCallingIdentity(origId); 8577 } 8578 } 8579 8580 private final void moveTaskBackwardsLocked(int task) { 8581 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8582 } 8583 8584 @Override 8585 public IBinder getHomeActivityToken() throws RemoteException { 8586 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8587 "getHomeActivityToken()"); 8588 synchronized (this) { 8589 return mStackSupervisor.getHomeActivityToken(); 8590 } 8591 } 8592 8593 @Override 8594 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8595 IActivityContainerCallback callback) throws RemoteException { 8596 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8597 "createActivityContainer()"); 8598 synchronized (this) { 8599 if (parentActivityToken == null) { 8600 throw new IllegalArgumentException("parent token must not be null"); 8601 } 8602 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8603 if (r == null) { 8604 return null; 8605 } 8606 if (callback == null) { 8607 throw new IllegalArgumentException("callback must not be null"); 8608 } 8609 return mStackSupervisor.createActivityContainer(r, callback); 8610 } 8611 } 8612 8613 @Override 8614 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8615 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8616 "deleteActivityContainer()"); 8617 synchronized (this) { 8618 mStackSupervisor.deleteActivityContainer(container); 8619 } 8620 } 8621 8622 @Override 8623 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8624 throws RemoteException { 8625 synchronized (this) { 8626 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8627 if (stack != null) { 8628 return stack.mActivityContainer; 8629 } 8630 return null; 8631 } 8632 } 8633 8634 @Override 8635 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8636 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8637 "moveTaskToStack()"); 8638 if (stackId == HOME_STACK_ID) { 8639 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8640 new RuntimeException("here").fillInStackTrace()); 8641 } 8642 synchronized (this) { 8643 long ident = Binder.clearCallingIdentity(); 8644 try { 8645 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8646 + stackId + " toTop=" + toTop); 8647 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8648 } finally { 8649 Binder.restoreCallingIdentity(ident); 8650 } 8651 } 8652 } 8653 8654 @Override 8655 public void resizeStack(int stackBoxId, Rect bounds) { 8656 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8657 "resizeStackBox()"); 8658 long ident = Binder.clearCallingIdentity(); 8659 try { 8660 mWindowManager.resizeStack(stackBoxId, bounds); 8661 } finally { 8662 Binder.restoreCallingIdentity(ident); 8663 } 8664 } 8665 8666 @Override 8667 public List<StackInfo> getAllStackInfos() { 8668 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8669 "getAllStackInfos()"); 8670 long ident = Binder.clearCallingIdentity(); 8671 try { 8672 synchronized (this) { 8673 return mStackSupervisor.getAllStackInfosLocked(); 8674 } 8675 } finally { 8676 Binder.restoreCallingIdentity(ident); 8677 } 8678 } 8679 8680 @Override 8681 public StackInfo getStackInfo(int stackId) { 8682 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8683 "getStackInfo()"); 8684 long ident = Binder.clearCallingIdentity(); 8685 try { 8686 synchronized (this) { 8687 return mStackSupervisor.getStackInfoLocked(stackId); 8688 } 8689 } finally { 8690 Binder.restoreCallingIdentity(ident); 8691 } 8692 } 8693 8694 @Override 8695 public boolean isInHomeStack(int taskId) { 8696 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8697 "getStackInfo()"); 8698 long ident = Binder.clearCallingIdentity(); 8699 try { 8700 synchronized (this) { 8701 TaskRecord tr = recentTaskForIdLocked(taskId); 8702 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8703 } 8704 } finally { 8705 Binder.restoreCallingIdentity(ident); 8706 } 8707 } 8708 8709 @Override 8710 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8711 synchronized(this) { 8712 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8713 } 8714 } 8715 8716 private boolean isLockTaskAuthorized(String pkg) { 8717 final DevicePolicyManager dpm = (DevicePolicyManager) 8718 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8719 try { 8720 int uid = mContext.getPackageManager().getPackageUid(pkg, 8721 Binder.getCallingUserHandle().getIdentifier()); 8722 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8723 } catch (NameNotFoundException e) { 8724 return false; 8725 } 8726 } 8727 8728 void startLockTaskMode(TaskRecord task) { 8729 final String pkg; 8730 synchronized (this) { 8731 pkg = task.intent.getComponent().getPackageName(); 8732 } 8733 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8734 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8735 final TaskRecord taskRecord = task; 8736 mHandler.post(new Runnable() { 8737 @Override 8738 public void run() { 8739 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8740 } 8741 }); 8742 return; 8743 } 8744 long ident = Binder.clearCallingIdentity(); 8745 try { 8746 synchronized (this) { 8747 // Since we lost lock on task, make sure it is still there. 8748 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8749 if (task != null) { 8750 if (!isSystemInitiated 8751 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8752 throw new IllegalArgumentException("Invalid task, not in foreground"); 8753 } 8754 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8755 } 8756 } 8757 } finally { 8758 Binder.restoreCallingIdentity(ident); 8759 } 8760 } 8761 8762 @Override 8763 public void startLockTaskMode(int taskId) { 8764 final TaskRecord task; 8765 long ident = Binder.clearCallingIdentity(); 8766 try { 8767 synchronized (this) { 8768 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8769 } 8770 } finally { 8771 Binder.restoreCallingIdentity(ident); 8772 } 8773 if (task != null) { 8774 startLockTaskMode(task); 8775 } 8776 } 8777 8778 @Override 8779 public void startLockTaskMode(IBinder token) { 8780 final TaskRecord task; 8781 long ident = Binder.clearCallingIdentity(); 8782 try { 8783 synchronized (this) { 8784 final ActivityRecord r = ActivityRecord.forToken(token); 8785 if (r == null) { 8786 return; 8787 } 8788 task = r.task; 8789 } 8790 } finally { 8791 Binder.restoreCallingIdentity(ident); 8792 } 8793 if (task != null) { 8794 startLockTaskMode(task); 8795 } 8796 } 8797 8798 @Override 8799 public void startLockTaskModeOnCurrent() throws RemoteException { 8800 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8801 "startLockTaskModeOnCurrent"); 8802 ActivityRecord r = null; 8803 synchronized (this) { 8804 r = mStackSupervisor.topRunningActivityLocked(); 8805 } 8806 startLockTaskMode(r.task); 8807 } 8808 8809 @Override 8810 public void stopLockTaskMode() { 8811 // Verify that the user matches the package of the intent for the TaskRecord 8812 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8813 // and stopLockTaskMode. 8814 final int callingUid = Binder.getCallingUid(); 8815 if (callingUid != Process.SYSTEM_UID) { 8816 try { 8817 String pkg = 8818 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8819 int uid = mContext.getPackageManager().getPackageUid(pkg, 8820 Binder.getCallingUserHandle().getIdentifier()); 8821 if (uid != callingUid) { 8822 throw new SecurityException("Invalid uid, expected " + uid); 8823 } 8824 } catch (NameNotFoundException e) { 8825 Log.d(TAG, "stopLockTaskMode " + e); 8826 return; 8827 } 8828 } 8829 long ident = Binder.clearCallingIdentity(); 8830 try { 8831 Log.d(TAG, "stopLockTaskMode"); 8832 // Stop lock task 8833 synchronized (this) { 8834 mStackSupervisor.setLockTaskModeLocked(null, false); 8835 } 8836 } finally { 8837 Binder.restoreCallingIdentity(ident); 8838 } 8839 } 8840 8841 @Override 8842 public void stopLockTaskModeOnCurrent() throws RemoteException { 8843 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8844 "stopLockTaskModeOnCurrent"); 8845 long ident = Binder.clearCallingIdentity(); 8846 try { 8847 stopLockTaskMode(); 8848 } finally { 8849 Binder.restoreCallingIdentity(ident); 8850 } 8851 } 8852 8853 @Override 8854 public boolean isInLockTaskMode() { 8855 synchronized (this) { 8856 return mStackSupervisor.isInLockTaskMode(); 8857 } 8858 } 8859 8860 // ========================================================= 8861 // CONTENT PROVIDERS 8862 // ========================================================= 8863 8864 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8865 List<ProviderInfo> providers = null; 8866 try { 8867 providers = AppGlobals.getPackageManager(). 8868 queryContentProviders(app.processName, app.uid, 8869 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8870 } catch (RemoteException ex) { 8871 } 8872 if (DEBUG_MU) 8873 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8874 int userId = app.userId; 8875 if (providers != null) { 8876 int N = providers.size(); 8877 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8878 for (int i=0; i<N; i++) { 8879 ProviderInfo cpi = 8880 (ProviderInfo)providers.get(i); 8881 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8882 cpi.name, cpi.flags); 8883 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8884 // This is a singleton provider, but a user besides the 8885 // default user is asking to initialize a process it runs 8886 // in... well, no, it doesn't actually run in this process, 8887 // it runs in the process of the default user. Get rid of it. 8888 providers.remove(i); 8889 N--; 8890 i--; 8891 continue; 8892 } 8893 8894 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8895 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8896 if (cpr == null) { 8897 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8898 mProviderMap.putProviderByClass(comp, cpr); 8899 } 8900 if (DEBUG_MU) 8901 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8902 app.pubProviders.put(cpi.name, cpr); 8903 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8904 // Don't add this if it is a platform component that is marked 8905 // to run in multiple processes, because this is actually 8906 // part of the framework so doesn't make sense to track as a 8907 // separate apk in the process. 8908 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8909 mProcessStats); 8910 } 8911 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8912 } 8913 } 8914 return providers; 8915 } 8916 8917 /** 8918 * Check if {@link ProcessRecord} has a possible chance at accessing the 8919 * given {@link ProviderInfo}. Final permission checking is always done 8920 * in {@link ContentProvider}. 8921 */ 8922 private final String checkContentProviderPermissionLocked( 8923 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8924 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8925 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8926 boolean checkedGrants = false; 8927 if (checkUser) { 8928 // Looking for cross-user grants before enforcing the typical cross-users permissions 8929 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8930 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8931 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8932 return null; 8933 } 8934 checkedGrants = true; 8935 } 8936 userId = handleIncomingUser(callingPid, callingUid, userId, 8937 false, ALLOW_NON_FULL, 8938 "checkContentProviderPermissionLocked " + cpi.authority, null); 8939 if (userId != tmpTargetUserId) { 8940 // When we actually went to determine the final targer user ID, this ended 8941 // up different than our initial check for the authority. This is because 8942 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8943 // SELF. So we need to re-check the grants again. 8944 checkedGrants = false; 8945 } 8946 } 8947 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8948 cpi.applicationInfo.uid, cpi.exported) 8949 == PackageManager.PERMISSION_GRANTED) { 8950 return null; 8951 } 8952 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8953 cpi.applicationInfo.uid, cpi.exported) 8954 == PackageManager.PERMISSION_GRANTED) { 8955 return null; 8956 } 8957 8958 PathPermission[] pps = cpi.pathPermissions; 8959 if (pps != null) { 8960 int i = pps.length; 8961 while (i > 0) { 8962 i--; 8963 PathPermission pp = pps[i]; 8964 String pprperm = pp.getReadPermission(); 8965 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8966 cpi.applicationInfo.uid, cpi.exported) 8967 == PackageManager.PERMISSION_GRANTED) { 8968 return null; 8969 } 8970 String ppwperm = pp.getWritePermission(); 8971 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8972 cpi.applicationInfo.uid, cpi.exported) 8973 == PackageManager.PERMISSION_GRANTED) { 8974 return null; 8975 } 8976 } 8977 } 8978 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8979 return null; 8980 } 8981 8982 String msg; 8983 if (!cpi.exported) { 8984 msg = "Permission Denial: opening provider " + cpi.name 8985 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8986 + ", uid=" + callingUid + ") that is not exported from uid " 8987 + cpi.applicationInfo.uid; 8988 } else { 8989 msg = "Permission Denial: opening provider " + cpi.name 8990 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8991 + ", uid=" + callingUid + ") requires " 8992 + cpi.readPermission + " or " + cpi.writePermission; 8993 } 8994 Slog.w(TAG, msg); 8995 return msg; 8996 } 8997 8998 /** 8999 * Returns if the ContentProvider has granted a uri to callingUid 9000 */ 9001 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9002 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9003 if (perms != null) { 9004 for (int i=perms.size()-1; i>=0; i--) { 9005 GrantUri grantUri = perms.keyAt(i); 9006 if (grantUri.sourceUserId == userId || !checkUser) { 9007 if (matchesProvider(grantUri.uri, cpi)) { 9008 return true; 9009 } 9010 } 9011 } 9012 } 9013 return false; 9014 } 9015 9016 /** 9017 * Returns true if the uri authority is one of the authorities specified in the provider. 9018 */ 9019 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9020 String uriAuth = uri.getAuthority(); 9021 String cpiAuth = cpi.authority; 9022 if (cpiAuth.indexOf(';') == -1) { 9023 return cpiAuth.equals(uriAuth); 9024 } 9025 String[] cpiAuths = cpiAuth.split(";"); 9026 int length = cpiAuths.length; 9027 for (int i = 0; i < length; i++) { 9028 if (cpiAuths[i].equals(uriAuth)) return true; 9029 } 9030 return false; 9031 } 9032 9033 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9034 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9035 if (r != null) { 9036 for (int i=0; i<r.conProviders.size(); i++) { 9037 ContentProviderConnection conn = r.conProviders.get(i); 9038 if (conn.provider == cpr) { 9039 if (DEBUG_PROVIDER) Slog.v(TAG, 9040 "Adding provider requested by " 9041 + r.processName + " from process " 9042 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9043 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9044 if (stable) { 9045 conn.stableCount++; 9046 conn.numStableIncs++; 9047 } else { 9048 conn.unstableCount++; 9049 conn.numUnstableIncs++; 9050 } 9051 return conn; 9052 } 9053 } 9054 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9055 if (stable) { 9056 conn.stableCount = 1; 9057 conn.numStableIncs = 1; 9058 } else { 9059 conn.unstableCount = 1; 9060 conn.numUnstableIncs = 1; 9061 } 9062 cpr.connections.add(conn); 9063 r.conProviders.add(conn); 9064 return conn; 9065 } 9066 cpr.addExternalProcessHandleLocked(externalProcessToken); 9067 return null; 9068 } 9069 9070 boolean decProviderCountLocked(ContentProviderConnection conn, 9071 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9072 if (conn != null) { 9073 cpr = conn.provider; 9074 if (DEBUG_PROVIDER) Slog.v(TAG, 9075 "Removing provider requested by " 9076 + conn.client.processName + " from process " 9077 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9078 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9079 if (stable) { 9080 conn.stableCount--; 9081 } else { 9082 conn.unstableCount--; 9083 } 9084 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9085 cpr.connections.remove(conn); 9086 conn.client.conProviders.remove(conn); 9087 return true; 9088 } 9089 return false; 9090 } 9091 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9092 return false; 9093 } 9094 9095 private void checkTime(long startTime, String where) { 9096 long now = SystemClock.elapsedRealtime(); 9097 if ((now-startTime) > 1000) { 9098 // If we are taking more than a second, log about it. 9099 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9100 } 9101 } 9102 9103 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9104 String name, IBinder token, boolean stable, int userId) { 9105 ContentProviderRecord cpr; 9106 ContentProviderConnection conn = null; 9107 ProviderInfo cpi = null; 9108 9109 synchronized(this) { 9110 long startTime = SystemClock.elapsedRealtime(); 9111 9112 ProcessRecord r = null; 9113 if (caller != null) { 9114 r = getRecordForAppLocked(caller); 9115 if (r == null) { 9116 throw new SecurityException( 9117 "Unable to find app for caller " + caller 9118 + " (pid=" + Binder.getCallingPid() 9119 + ") when getting content provider " + name); 9120 } 9121 } 9122 9123 boolean checkCrossUser = true; 9124 9125 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9126 9127 // First check if this content provider has been published... 9128 cpr = mProviderMap.getProviderByName(name, userId); 9129 // If that didn't work, check if it exists for user 0 and then 9130 // verify that it's a singleton provider before using it. 9131 if (cpr == null && userId != UserHandle.USER_OWNER) { 9132 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9133 if (cpr != null) { 9134 cpi = cpr.info; 9135 if (isSingleton(cpi.processName, cpi.applicationInfo, 9136 cpi.name, cpi.flags) 9137 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9138 userId = UserHandle.USER_OWNER; 9139 checkCrossUser = false; 9140 } else { 9141 cpr = null; 9142 cpi = null; 9143 } 9144 } 9145 } 9146 9147 boolean providerRunning = cpr != null; 9148 if (providerRunning) { 9149 cpi = cpr.info; 9150 String msg; 9151 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9152 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9153 != null) { 9154 throw new SecurityException(msg); 9155 } 9156 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9157 9158 if (r != null && cpr.canRunHere(r)) { 9159 // This provider has been published or is in the process 9160 // of being published... but it is also allowed to run 9161 // in the caller's process, so don't make a connection 9162 // and just let the caller instantiate its own instance. 9163 ContentProviderHolder holder = cpr.newHolder(null); 9164 // don't give caller the provider object, it needs 9165 // to make its own. 9166 holder.provider = null; 9167 return holder; 9168 } 9169 9170 final long origId = Binder.clearCallingIdentity(); 9171 9172 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9173 9174 // In this case the provider instance already exists, so we can 9175 // return it right away. 9176 conn = incProviderCountLocked(r, cpr, token, stable); 9177 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9178 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9179 // If this is a perceptible app accessing the provider, 9180 // make sure to count it as being accessed and thus 9181 // back up on the LRU list. This is good because 9182 // content providers are often expensive to start. 9183 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9184 updateLruProcessLocked(cpr.proc, false, null); 9185 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9186 } 9187 } 9188 9189 if (cpr.proc != null) { 9190 if (false) { 9191 if (cpr.name.flattenToShortString().equals( 9192 "com.android.providers.calendar/.CalendarProvider2")) { 9193 Slog.v(TAG, "****************** KILLING " 9194 + cpr.name.flattenToShortString()); 9195 Process.killProcess(cpr.proc.pid); 9196 } 9197 } 9198 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9199 boolean success = updateOomAdjLocked(cpr.proc); 9200 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9201 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9202 // NOTE: there is still a race here where a signal could be 9203 // pending on the process even though we managed to update its 9204 // adj level. Not sure what to do about this, but at least 9205 // the race is now smaller. 9206 if (!success) { 9207 // Uh oh... it looks like the provider's process 9208 // has been killed on us. We need to wait for a new 9209 // process to be started, and make sure its death 9210 // doesn't kill our process. 9211 Slog.i(TAG, 9212 "Existing provider " + cpr.name.flattenToShortString() 9213 + " is crashing; detaching " + r); 9214 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9215 checkTime(startTime, "getContentProviderImpl: before appDied"); 9216 appDiedLocked(cpr.proc); 9217 checkTime(startTime, "getContentProviderImpl: after appDied"); 9218 if (!lastRef) { 9219 // This wasn't the last ref our process had on 9220 // the provider... we have now been killed, bail. 9221 return null; 9222 } 9223 providerRunning = false; 9224 conn = null; 9225 } 9226 } 9227 9228 Binder.restoreCallingIdentity(origId); 9229 } 9230 9231 boolean singleton; 9232 if (!providerRunning) { 9233 try { 9234 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9235 cpi = AppGlobals.getPackageManager(). 9236 resolveContentProvider(name, 9237 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9238 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9239 } catch (RemoteException ex) { 9240 } 9241 if (cpi == null) { 9242 return null; 9243 } 9244 // If the provider is a singleton AND 9245 // (it's a call within the same user || the provider is a 9246 // privileged app) 9247 // Then allow connecting to the singleton provider 9248 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9249 cpi.name, cpi.flags) 9250 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9251 if (singleton) { 9252 userId = UserHandle.USER_OWNER; 9253 } 9254 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9255 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9256 9257 String msg; 9258 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9259 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9260 != null) { 9261 throw new SecurityException(msg); 9262 } 9263 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9264 9265 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9266 && !cpi.processName.equals("system")) { 9267 // If this content provider does not run in the system 9268 // process, and the system is not yet ready to run other 9269 // processes, then fail fast instead of hanging. 9270 throw new IllegalArgumentException( 9271 "Attempt to launch content provider before system ready"); 9272 } 9273 9274 // Make sure that the user who owns this provider is started. If not, 9275 // we don't want to allow it to run. 9276 if (mStartedUsers.get(userId) == null) { 9277 Slog.w(TAG, "Unable to launch app " 9278 + cpi.applicationInfo.packageName + "/" 9279 + cpi.applicationInfo.uid + " for provider " 9280 + name + ": user " + userId + " is stopped"); 9281 return null; 9282 } 9283 9284 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9285 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9286 cpr = mProviderMap.getProviderByClass(comp, userId); 9287 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9288 final boolean firstClass = cpr == null; 9289 if (firstClass) { 9290 try { 9291 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9292 ApplicationInfo ai = 9293 AppGlobals.getPackageManager(). 9294 getApplicationInfo( 9295 cpi.applicationInfo.packageName, 9296 STOCK_PM_FLAGS, userId); 9297 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9298 if (ai == null) { 9299 Slog.w(TAG, "No package info for content provider " 9300 + cpi.name); 9301 return null; 9302 } 9303 ai = getAppInfoForUser(ai, userId); 9304 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9305 } catch (RemoteException ex) { 9306 // pm is in same process, this will never happen. 9307 } 9308 } 9309 9310 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9311 9312 if (r != null && cpr.canRunHere(r)) { 9313 // If this is a multiprocess provider, then just return its 9314 // info and allow the caller to instantiate it. Only do 9315 // this if the provider is the same user as the caller's 9316 // process, or can run as root (so can be in any process). 9317 return cpr.newHolder(null); 9318 } 9319 9320 if (DEBUG_PROVIDER) { 9321 RuntimeException e = new RuntimeException("here"); 9322 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9323 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9324 } 9325 9326 // This is single process, and our app is now connecting to it. 9327 // See if we are already in the process of launching this 9328 // provider. 9329 final int N = mLaunchingProviders.size(); 9330 int i; 9331 for (i=0; i<N; i++) { 9332 if (mLaunchingProviders.get(i) == cpr) { 9333 break; 9334 } 9335 } 9336 9337 // If the provider is not already being launched, then get it 9338 // started. 9339 if (i >= N) { 9340 final long origId = Binder.clearCallingIdentity(); 9341 9342 try { 9343 // Content provider is now in use, its package can't be stopped. 9344 try { 9345 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9346 AppGlobals.getPackageManager().setPackageStoppedState( 9347 cpr.appInfo.packageName, false, userId); 9348 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9349 } catch (RemoteException e) { 9350 } catch (IllegalArgumentException e) { 9351 Slog.w(TAG, "Failed trying to unstop package " 9352 + cpr.appInfo.packageName + ": " + e); 9353 } 9354 9355 // Use existing process if already started 9356 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9357 ProcessRecord proc = getProcessRecordLocked( 9358 cpi.processName, cpr.appInfo.uid, false); 9359 if (proc != null && proc.thread != null) { 9360 if (DEBUG_PROVIDER) { 9361 Slog.d(TAG, "Installing in existing process " + proc); 9362 } 9363 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9364 proc.pubProviders.put(cpi.name, cpr); 9365 try { 9366 proc.thread.scheduleInstallProvider(cpi); 9367 } catch (RemoteException e) { 9368 } 9369 } else { 9370 checkTime(startTime, "getContentProviderImpl: before start process"); 9371 proc = startProcessLocked(cpi.processName, 9372 cpr.appInfo, false, 0, "content provider", 9373 new ComponentName(cpi.applicationInfo.packageName, 9374 cpi.name), false, false, false); 9375 checkTime(startTime, "getContentProviderImpl: after start process"); 9376 if (proc == null) { 9377 Slog.w(TAG, "Unable to launch app " 9378 + cpi.applicationInfo.packageName + "/" 9379 + cpi.applicationInfo.uid + " for provider " 9380 + name + ": process is bad"); 9381 return null; 9382 } 9383 } 9384 cpr.launchingApp = proc; 9385 mLaunchingProviders.add(cpr); 9386 } finally { 9387 Binder.restoreCallingIdentity(origId); 9388 } 9389 } 9390 9391 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9392 9393 // Make sure the provider is published (the same provider class 9394 // may be published under multiple names). 9395 if (firstClass) { 9396 mProviderMap.putProviderByClass(comp, cpr); 9397 } 9398 9399 mProviderMap.putProviderByName(name, cpr); 9400 conn = incProviderCountLocked(r, cpr, token, stable); 9401 if (conn != null) { 9402 conn.waiting = true; 9403 } 9404 } 9405 checkTime(startTime, "getContentProviderImpl: done!"); 9406 } 9407 9408 // Wait for the provider to be published... 9409 synchronized (cpr) { 9410 while (cpr.provider == null) { 9411 if (cpr.launchingApp == null) { 9412 Slog.w(TAG, "Unable to launch app " 9413 + cpi.applicationInfo.packageName + "/" 9414 + cpi.applicationInfo.uid + " for provider " 9415 + name + ": launching app became null"); 9416 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9417 UserHandle.getUserId(cpi.applicationInfo.uid), 9418 cpi.applicationInfo.packageName, 9419 cpi.applicationInfo.uid, name); 9420 return null; 9421 } 9422 try { 9423 if (DEBUG_MU) { 9424 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9425 + cpr.launchingApp); 9426 } 9427 if (conn != null) { 9428 conn.waiting = true; 9429 } 9430 cpr.wait(); 9431 } catch (InterruptedException ex) { 9432 } finally { 9433 if (conn != null) { 9434 conn.waiting = false; 9435 } 9436 } 9437 } 9438 } 9439 return cpr != null ? cpr.newHolder(conn) : null; 9440 } 9441 9442 @Override 9443 public final ContentProviderHolder getContentProvider( 9444 IApplicationThread caller, String name, int userId, boolean stable) { 9445 enforceNotIsolatedCaller("getContentProvider"); 9446 if (caller == null) { 9447 String msg = "null IApplicationThread when getting content provider " 9448 + name; 9449 Slog.w(TAG, msg); 9450 throw new SecurityException(msg); 9451 } 9452 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9453 // with cross-user grant. 9454 return getContentProviderImpl(caller, name, null, stable, userId); 9455 } 9456 9457 public ContentProviderHolder getContentProviderExternal( 9458 String name, int userId, IBinder token) { 9459 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9460 "Do not have permission in call getContentProviderExternal()"); 9461 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9462 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9463 return getContentProviderExternalUnchecked(name, token, userId); 9464 } 9465 9466 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9467 IBinder token, int userId) { 9468 return getContentProviderImpl(null, name, token, true, userId); 9469 } 9470 9471 /** 9472 * Drop a content provider from a ProcessRecord's bookkeeping 9473 */ 9474 public void removeContentProvider(IBinder connection, boolean stable) { 9475 enforceNotIsolatedCaller("removeContentProvider"); 9476 long ident = Binder.clearCallingIdentity(); 9477 try { 9478 synchronized (this) { 9479 ContentProviderConnection conn; 9480 try { 9481 conn = (ContentProviderConnection)connection; 9482 } catch (ClassCastException e) { 9483 String msg ="removeContentProvider: " + connection 9484 + " not a ContentProviderConnection"; 9485 Slog.w(TAG, msg); 9486 throw new IllegalArgumentException(msg); 9487 } 9488 if (conn == null) { 9489 throw new NullPointerException("connection is null"); 9490 } 9491 if (decProviderCountLocked(conn, null, null, stable)) { 9492 updateOomAdjLocked(); 9493 } 9494 } 9495 } finally { 9496 Binder.restoreCallingIdentity(ident); 9497 } 9498 } 9499 9500 public void removeContentProviderExternal(String name, IBinder token) { 9501 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9502 "Do not have permission in call removeContentProviderExternal()"); 9503 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9504 } 9505 9506 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9507 synchronized (this) { 9508 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9509 if(cpr == null) { 9510 //remove from mProvidersByClass 9511 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9512 return; 9513 } 9514 9515 //update content provider record entry info 9516 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9517 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9518 if (localCpr.hasExternalProcessHandles()) { 9519 if (localCpr.removeExternalProcessHandleLocked(token)) { 9520 updateOomAdjLocked(); 9521 } else { 9522 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9523 + " with no external reference for token: " 9524 + token + "."); 9525 } 9526 } else { 9527 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9528 + " with no external references."); 9529 } 9530 } 9531 } 9532 9533 public final void publishContentProviders(IApplicationThread caller, 9534 List<ContentProviderHolder> providers) { 9535 if (providers == null) { 9536 return; 9537 } 9538 9539 enforceNotIsolatedCaller("publishContentProviders"); 9540 synchronized (this) { 9541 final ProcessRecord r = getRecordForAppLocked(caller); 9542 if (DEBUG_MU) 9543 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9544 if (r == null) { 9545 throw new SecurityException( 9546 "Unable to find app for caller " + caller 9547 + " (pid=" + Binder.getCallingPid() 9548 + ") when publishing content providers"); 9549 } 9550 9551 final long origId = Binder.clearCallingIdentity(); 9552 9553 final int N = providers.size(); 9554 for (int i=0; i<N; i++) { 9555 ContentProviderHolder src = providers.get(i); 9556 if (src == null || src.info == null || src.provider == null) { 9557 continue; 9558 } 9559 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9560 if (DEBUG_MU) 9561 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9562 if (dst != null) { 9563 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9564 mProviderMap.putProviderByClass(comp, dst); 9565 String names[] = dst.info.authority.split(";"); 9566 for (int j = 0; j < names.length; j++) { 9567 mProviderMap.putProviderByName(names[j], dst); 9568 } 9569 9570 int NL = mLaunchingProviders.size(); 9571 int j; 9572 for (j=0; j<NL; j++) { 9573 if (mLaunchingProviders.get(j) == dst) { 9574 mLaunchingProviders.remove(j); 9575 j--; 9576 NL--; 9577 } 9578 } 9579 synchronized (dst) { 9580 dst.provider = src.provider; 9581 dst.proc = r; 9582 dst.notifyAll(); 9583 } 9584 updateOomAdjLocked(r); 9585 } 9586 } 9587 9588 Binder.restoreCallingIdentity(origId); 9589 } 9590 } 9591 9592 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9593 ContentProviderConnection conn; 9594 try { 9595 conn = (ContentProviderConnection)connection; 9596 } catch (ClassCastException e) { 9597 String msg ="refContentProvider: " + connection 9598 + " not a ContentProviderConnection"; 9599 Slog.w(TAG, msg); 9600 throw new IllegalArgumentException(msg); 9601 } 9602 if (conn == null) { 9603 throw new NullPointerException("connection is null"); 9604 } 9605 9606 synchronized (this) { 9607 if (stable > 0) { 9608 conn.numStableIncs += stable; 9609 } 9610 stable = conn.stableCount + stable; 9611 if (stable < 0) { 9612 throw new IllegalStateException("stableCount < 0: " + stable); 9613 } 9614 9615 if (unstable > 0) { 9616 conn.numUnstableIncs += unstable; 9617 } 9618 unstable = conn.unstableCount + unstable; 9619 if (unstable < 0) { 9620 throw new IllegalStateException("unstableCount < 0: " + unstable); 9621 } 9622 9623 if ((stable+unstable) <= 0) { 9624 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9625 + stable + " unstable=" + unstable); 9626 } 9627 conn.stableCount = stable; 9628 conn.unstableCount = unstable; 9629 return !conn.dead; 9630 } 9631 } 9632 9633 public void unstableProviderDied(IBinder connection) { 9634 ContentProviderConnection conn; 9635 try { 9636 conn = (ContentProviderConnection)connection; 9637 } catch (ClassCastException e) { 9638 String msg ="refContentProvider: " + connection 9639 + " not a ContentProviderConnection"; 9640 Slog.w(TAG, msg); 9641 throw new IllegalArgumentException(msg); 9642 } 9643 if (conn == null) { 9644 throw new NullPointerException("connection is null"); 9645 } 9646 9647 // Safely retrieve the content provider associated with the connection. 9648 IContentProvider provider; 9649 synchronized (this) { 9650 provider = conn.provider.provider; 9651 } 9652 9653 if (provider == null) { 9654 // Um, yeah, we're way ahead of you. 9655 return; 9656 } 9657 9658 // Make sure the caller is being honest with us. 9659 if (provider.asBinder().pingBinder()) { 9660 // Er, no, still looks good to us. 9661 synchronized (this) { 9662 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9663 + " says " + conn + " died, but we don't agree"); 9664 return; 9665 } 9666 } 9667 9668 // Well look at that! It's dead! 9669 synchronized (this) { 9670 if (conn.provider.provider != provider) { 9671 // But something changed... good enough. 9672 return; 9673 } 9674 9675 ProcessRecord proc = conn.provider.proc; 9676 if (proc == null || proc.thread == null) { 9677 // Seems like the process is already cleaned up. 9678 return; 9679 } 9680 9681 // As far as we're concerned, this is just like receiving a 9682 // death notification... just a bit prematurely. 9683 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9684 + ") early provider death"); 9685 final long ident = Binder.clearCallingIdentity(); 9686 try { 9687 appDiedLocked(proc); 9688 } finally { 9689 Binder.restoreCallingIdentity(ident); 9690 } 9691 } 9692 } 9693 9694 @Override 9695 public void appNotRespondingViaProvider(IBinder connection) { 9696 enforceCallingPermission( 9697 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9698 9699 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9700 if (conn == null) { 9701 Slog.w(TAG, "ContentProviderConnection is null"); 9702 return; 9703 } 9704 9705 final ProcessRecord host = conn.provider.proc; 9706 if (host == null) { 9707 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9708 return; 9709 } 9710 9711 final long token = Binder.clearCallingIdentity(); 9712 try { 9713 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9714 } finally { 9715 Binder.restoreCallingIdentity(token); 9716 } 9717 } 9718 9719 public final void installSystemProviders() { 9720 List<ProviderInfo> providers; 9721 synchronized (this) { 9722 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9723 providers = generateApplicationProvidersLocked(app); 9724 if (providers != null) { 9725 for (int i=providers.size()-1; i>=0; i--) { 9726 ProviderInfo pi = (ProviderInfo)providers.get(i); 9727 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9728 Slog.w(TAG, "Not installing system proc provider " + pi.name 9729 + ": not system .apk"); 9730 providers.remove(i); 9731 } 9732 } 9733 } 9734 } 9735 if (providers != null) { 9736 mSystemThread.installSystemProviders(providers); 9737 } 9738 9739 mCoreSettingsObserver = new CoreSettingsObserver(this); 9740 9741 //mUsageStatsService.monitorPackages(); 9742 } 9743 9744 /** 9745 * Allows apps to retrieve the MIME type of a URI. 9746 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9747 * users, then it does not need permission to access the ContentProvider. 9748 * Either, it needs cross-user uri grants. 9749 * 9750 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9751 * 9752 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9753 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9754 */ 9755 public String getProviderMimeType(Uri uri, int userId) { 9756 enforceNotIsolatedCaller("getProviderMimeType"); 9757 final String name = uri.getAuthority(); 9758 int callingUid = Binder.getCallingUid(); 9759 int callingPid = Binder.getCallingPid(); 9760 long ident = 0; 9761 boolean clearedIdentity = false; 9762 userId = unsafeConvertIncomingUser(userId); 9763 if (canClearIdentity(callingPid, callingUid, userId)) { 9764 clearedIdentity = true; 9765 ident = Binder.clearCallingIdentity(); 9766 } 9767 ContentProviderHolder holder = null; 9768 try { 9769 holder = getContentProviderExternalUnchecked(name, null, userId); 9770 if (holder != null) { 9771 return holder.provider.getType(uri); 9772 } 9773 } catch (RemoteException e) { 9774 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9775 return null; 9776 } finally { 9777 // We need to clear the identity to call removeContentProviderExternalUnchecked 9778 if (!clearedIdentity) { 9779 ident = Binder.clearCallingIdentity(); 9780 } 9781 try { 9782 if (holder != null) { 9783 removeContentProviderExternalUnchecked(name, null, userId); 9784 } 9785 } finally { 9786 Binder.restoreCallingIdentity(ident); 9787 } 9788 } 9789 9790 return null; 9791 } 9792 9793 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9794 if (UserHandle.getUserId(callingUid) == userId) { 9795 return true; 9796 } 9797 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9798 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9799 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9800 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9801 return true; 9802 } 9803 return false; 9804 } 9805 9806 // ========================================================= 9807 // GLOBAL MANAGEMENT 9808 // ========================================================= 9809 9810 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9811 boolean isolated, int isolatedUid) { 9812 String proc = customProcess != null ? customProcess : info.processName; 9813 BatteryStatsImpl.Uid.Proc ps = null; 9814 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9815 int uid = info.uid; 9816 if (isolated) { 9817 if (isolatedUid == 0) { 9818 int userId = UserHandle.getUserId(uid); 9819 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9820 while (true) { 9821 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9822 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9823 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9824 } 9825 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9826 mNextIsolatedProcessUid++; 9827 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9828 // No process for this uid, use it. 9829 break; 9830 } 9831 stepsLeft--; 9832 if (stepsLeft <= 0) { 9833 return null; 9834 } 9835 } 9836 } else { 9837 // Special case for startIsolatedProcess (internal only), where 9838 // the uid of the isolated process is specified by the caller. 9839 uid = isolatedUid; 9840 } 9841 } 9842 return new ProcessRecord(stats, info, proc, uid); 9843 } 9844 9845 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9846 String abiOverride) { 9847 ProcessRecord app; 9848 if (!isolated) { 9849 app = getProcessRecordLocked(info.processName, info.uid, true); 9850 } else { 9851 app = null; 9852 } 9853 9854 if (app == null) { 9855 app = newProcessRecordLocked(info, null, isolated, 0); 9856 mProcessNames.put(info.processName, app.uid, app); 9857 if (isolated) { 9858 mIsolatedProcesses.put(app.uid, app); 9859 } 9860 updateLruProcessLocked(app, false, null); 9861 updateOomAdjLocked(); 9862 } 9863 9864 // This package really, really can not be stopped. 9865 try { 9866 AppGlobals.getPackageManager().setPackageStoppedState( 9867 info.packageName, false, UserHandle.getUserId(app.uid)); 9868 } catch (RemoteException e) { 9869 } catch (IllegalArgumentException e) { 9870 Slog.w(TAG, "Failed trying to unstop package " 9871 + info.packageName + ": " + e); 9872 } 9873 9874 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9875 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9876 app.persistent = true; 9877 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9878 } 9879 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9880 mPersistentStartingProcesses.add(app); 9881 startProcessLocked(app, "added application", app.processName, abiOverride, 9882 null /* entryPoint */, null /* entryPointArgs */); 9883 } 9884 9885 return app; 9886 } 9887 9888 public void unhandledBack() { 9889 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9890 "unhandledBack()"); 9891 9892 synchronized(this) { 9893 final long origId = Binder.clearCallingIdentity(); 9894 try { 9895 getFocusedStack().unhandledBackLocked(); 9896 } finally { 9897 Binder.restoreCallingIdentity(origId); 9898 } 9899 } 9900 } 9901 9902 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9903 enforceNotIsolatedCaller("openContentUri"); 9904 final int userId = UserHandle.getCallingUserId(); 9905 String name = uri.getAuthority(); 9906 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9907 ParcelFileDescriptor pfd = null; 9908 if (cph != null) { 9909 // We record the binder invoker's uid in thread-local storage before 9910 // going to the content provider to open the file. Later, in the code 9911 // that handles all permissions checks, we look for this uid and use 9912 // that rather than the Activity Manager's own uid. The effect is that 9913 // we do the check against the caller's permissions even though it looks 9914 // to the content provider like the Activity Manager itself is making 9915 // the request. 9916 sCallerIdentity.set(new Identity( 9917 Binder.getCallingPid(), Binder.getCallingUid())); 9918 try { 9919 pfd = cph.provider.openFile(null, uri, "r", null); 9920 } catch (FileNotFoundException e) { 9921 // do nothing; pfd will be returned null 9922 } finally { 9923 // Ensure that whatever happens, we clean up the identity state 9924 sCallerIdentity.remove(); 9925 } 9926 9927 // We've got the fd now, so we're done with the provider. 9928 removeContentProviderExternalUnchecked(name, null, userId); 9929 } else { 9930 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9931 } 9932 return pfd; 9933 } 9934 9935 // Actually is sleeping or shutting down or whatever else in the future 9936 // is an inactive state. 9937 public boolean isSleepingOrShuttingDown() { 9938 return mSleeping || mShuttingDown; 9939 } 9940 9941 public boolean isSleeping() { 9942 return mSleeping; 9943 } 9944 9945 void goingToSleep() { 9946 synchronized(this) { 9947 mWentToSleep = true; 9948 updateEventDispatchingLocked(); 9949 goToSleepIfNeededLocked(); 9950 } 9951 } 9952 9953 void finishRunningVoiceLocked() { 9954 if (mRunningVoice) { 9955 mRunningVoice = false; 9956 goToSleepIfNeededLocked(); 9957 } 9958 } 9959 9960 void goToSleepIfNeededLocked() { 9961 if (mWentToSleep && !mRunningVoice) { 9962 if (!mSleeping) { 9963 mSleeping = true; 9964 mStackSupervisor.goingToSleepLocked(); 9965 9966 // Initialize the wake times of all processes. 9967 checkExcessivePowerUsageLocked(false); 9968 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9969 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9970 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9971 } 9972 } 9973 } 9974 9975 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9976 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9977 // Never persist the home stack. 9978 return; 9979 } 9980 mTaskPersister.wakeup(task, flush); 9981 } 9982 9983 @Override 9984 public boolean shutdown(int timeout) { 9985 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9986 != PackageManager.PERMISSION_GRANTED) { 9987 throw new SecurityException("Requires permission " 9988 + android.Manifest.permission.SHUTDOWN); 9989 } 9990 9991 boolean timedout = false; 9992 9993 synchronized(this) { 9994 mShuttingDown = true; 9995 updateEventDispatchingLocked(); 9996 timedout = mStackSupervisor.shutdownLocked(timeout); 9997 } 9998 9999 mAppOpsService.shutdown(); 10000 if (mUsageStatsService != null) { 10001 mUsageStatsService.prepareShutdown(); 10002 } 10003 mBatteryStatsService.shutdown(); 10004 synchronized (this) { 10005 mProcessStats.shutdownLocked(); 10006 } 10007 notifyTaskPersisterLocked(null, true); 10008 10009 return timedout; 10010 } 10011 10012 public final void activitySlept(IBinder token) { 10013 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10014 10015 final long origId = Binder.clearCallingIdentity(); 10016 10017 synchronized (this) { 10018 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10019 if (r != null) { 10020 mStackSupervisor.activitySleptLocked(r); 10021 } 10022 } 10023 10024 Binder.restoreCallingIdentity(origId); 10025 } 10026 10027 void logLockScreen(String msg) { 10028 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10029 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10030 mWentToSleep + " mSleeping=" + mSleeping); 10031 } 10032 10033 private void comeOutOfSleepIfNeededLocked() { 10034 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10035 if (mSleeping) { 10036 mSleeping = false; 10037 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10038 } 10039 } 10040 } 10041 10042 void wakingUp() { 10043 synchronized(this) { 10044 mWentToSleep = false; 10045 updateEventDispatchingLocked(); 10046 comeOutOfSleepIfNeededLocked(); 10047 } 10048 } 10049 10050 void startRunningVoiceLocked() { 10051 if (!mRunningVoice) { 10052 mRunningVoice = true; 10053 comeOutOfSleepIfNeededLocked(); 10054 } 10055 } 10056 10057 private void updateEventDispatchingLocked() { 10058 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10059 } 10060 10061 public void setLockScreenShown(boolean shown) { 10062 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10063 != PackageManager.PERMISSION_GRANTED) { 10064 throw new SecurityException("Requires permission " 10065 + android.Manifest.permission.DEVICE_POWER); 10066 } 10067 10068 synchronized(this) { 10069 long ident = Binder.clearCallingIdentity(); 10070 try { 10071 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10072 mLockScreenShown = shown; 10073 comeOutOfSleepIfNeededLocked(); 10074 } finally { 10075 Binder.restoreCallingIdentity(ident); 10076 } 10077 } 10078 } 10079 10080 @Override 10081 public void stopAppSwitches() { 10082 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10083 != PackageManager.PERMISSION_GRANTED) { 10084 throw new SecurityException("Requires permission " 10085 + android.Manifest.permission.STOP_APP_SWITCHES); 10086 } 10087 10088 synchronized(this) { 10089 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10090 + APP_SWITCH_DELAY_TIME; 10091 mDidAppSwitch = false; 10092 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10093 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10094 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10095 } 10096 } 10097 10098 public void resumeAppSwitches() { 10099 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10100 != PackageManager.PERMISSION_GRANTED) { 10101 throw new SecurityException("Requires permission " 10102 + android.Manifest.permission.STOP_APP_SWITCHES); 10103 } 10104 10105 synchronized(this) { 10106 // Note that we don't execute any pending app switches... we will 10107 // let those wait until either the timeout, or the next start 10108 // activity request. 10109 mAppSwitchesAllowedTime = 0; 10110 } 10111 } 10112 10113 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 10114 String name) { 10115 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10116 return true; 10117 } 10118 10119 final int perm = checkComponentPermission( 10120 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10121 callingUid, -1, true); 10122 if (perm == PackageManager.PERMISSION_GRANTED) { 10123 return true; 10124 } 10125 10126 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 10127 return false; 10128 } 10129 10130 public void setDebugApp(String packageName, boolean waitForDebugger, 10131 boolean persistent) { 10132 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10133 "setDebugApp()"); 10134 10135 long ident = Binder.clearCallingIdentity(); 10136 try { 10137 // Note that this is not really thread safe if there are multiple 10138 // callers into it at the same time, but that's not a situation we 10139 // care about. 10140 if (persistent) { 10141 final ContentResolver resolver = mContext.getContentResolver(); 10142 Settings.Global.putString( 10143 resolver, Settings.Global.DEBUG_APP, 10144 packageName); 10145 Settings.Global.putInt( 10146 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10147 waitForDebugger ? 1 : 0); 10148 } 10149 10150 synchronized (this) { 10151 if (!persistent) { 10152 mOrigDebugApp = mDebugApp; 10153 mOrigWaitForDebugger = mWaitForDebugger; 10154 } 10155 mDebugApp = packageName; 10156 mWaitForDebugger = waitForDebugger; 10157 mDebugTransient = !persistent; 10158 if (packageName != null) { 10159 forceStopPackageLocked(packageName, -1, false, false, true, true, 10160 false, UserHandle.USER_ALL, "set debug app"); 10161 } 10162 } 10163 } finally { 10164 Binder.restoreCallingIdentity(ident); 10165 } 10166 } 10167 10168 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10169 synchronized (this) { 10170 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10171 if (!isDebuggable) { 10172 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10173 throw new SecurityException("Process not debuggable: " + app.packageName); 10174 } 10175 } 10176 10177 mOpenGlTraceApp = processName; 10178 } 10179 } 10180 10181 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10182 synchronized (this) { 10183 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10184 if (!isDebuggable) { 10185 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10186 throw new SecurityException("Process not debuggable: " + app.packageName); 10187 } 10188 } 10189 mProfileApp = processName; 10190 mProfileFile = profilerInfo.profileFile; 10191 if (mProfileFd != null) { 10192 try { 10193 mProfileFd.close(); 10194 } catch (IOException e) { 10195 } 10196 mProfileFd = null; 10197 } 10198 mProfileFd = profilerInfo.profileFd; 10199 mSamplingInterval = profilerInfo.samplingInterval; 10200 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10201 mProfileType = 0; 10202 } 10203 } 10204 10205 @Override 10206 public void setAlwaysFinish(boolean enabled) { 10207 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10208 "setAlwaysFinish()"); 10209 10210 Settings.Global.putInt( 10211 mContext.getContentResolver(), 10212 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10213 10214 synchronized (this) { 10215 mAlwaysFinishActivities = enabled; 10216 } 10217 } 10218 10219 @Override 10220 public void setActivityController(IActivityController controller) { 10221 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10222 "setActivityController()"); 10223 synchronized (this) { 10224 mController = controller; 10225 Watchdog.getInstance().setActivityController(controller); 10226 } 10227 } 10228 10229 @Override 10230 public void setUserIsMonkey(boolean userIsMonkey) { 10231 synchronized (this) { 10232 synchronized (mPidsSelfLocked) { 10233 final int callingPid = Binder.getCallingPid(); 10234 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10235 if (precessRecord == null) { 10236 throw new SecurityException("Unknown process: " + callingPid); 10237 } 10238 if (precessRecord.instrumentationUiAutomationConnection == null) { 10239 throw new SecurityException("Only an instrumentation process " 10240 + "with a UiAutomation can call setUserIsMonkey"); 10241 } 10242 } 10243 mUserIsMonkey = userIsMonkey; 10244 } 10245 } 10246 10247 @Override 10248 public boolean isUserAMonkey() { 10249 synchronized (this) { 10250 // If there is a controller also implies the user is a monkey. 10251 return (mUserIsMonkey || mController != null); 10252 } 10253 } 10254 10255 public void requestBugReport() { 10256 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10257 SystemProperties.set("ctl.start", "bugreport"); 10258 } 10259 10260 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10261 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10262 } 10263 10264 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10265 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10266 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10267 } 10268 return KEY_DISPATCHING_TIMEOUT; 10269 } 10270 10271 @Override 10272 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10273 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10274 != PackageManager.PERMISSION_GRANTED) { 10275 throw new SecurityException("Requires permission " 10276 + android.Manifest.permission.FILTER_EVENTS); 10277 } 10278 ProcessRecord proc; 10279 long timeout; 10280 synchronized (this) { 10281 synchronized (mPidsSelfLocked) { 10282 proc = mPidsSelfLocked.get(pid); 10283 } 10284 timeout = getInputDispatchingTimeoutLocked(proc); 10285 } 10286 10287 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10288 return -1; 10289 } 10290 10291 return timeout; 10292 } 10293 10294 /** 10295 * Handle input dispatching timeouts. 10296 * Returns whether input dispatching should be aborted or not. 10297 */ 10298 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10299 final ActivityRecord activity, final ActivityRecord parent, 10300 final boolean aboveSystem, String reason) { 10301 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10302 != PackageManager.PERMISSION_GRANTED) { 10303 throw new SecurityException("Requires permission " 10304 + android.Manifest.permission.FILTER_EVENTS); 10305 } 10306 10307 final String annotation; 10308 if (reason == null) { 10309 annotation = "Input dispatching timed out"; 10310 } else { 10311 annotation = "Input dispatching timed out (" + reason + ")"; 10312 } 10313 10314 if (proc != null) { 10315 synchronized (this) { 10316 if (proc.debugging) { 10317 return false; 10318 } 10319 10320 if (mDidDexOpt) { 10321 // Give more time since we were dexopting. 10322 mDidDexOpt = false; 10323 return false; 10324 } 10325 10326 if (proc.instrumentationClass != null) { 10327 Bundle info = new Bundle(); 10328 info.putString("shortMsg", "keyDispatchingTimedOut"); 10329 info.putString("longMsg", annotation); 10330 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10331 return true; 10332 } 10333 } 10334 mHandler.post(new Runnable() { 10335 @Override 10336 public void run() { 10337 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10338 } 10339 }); 10340 } 10341 10342 return true; 10343 } 10344 10345 public Bundle getAssistContextExtras(int requestType) { 10346 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10347 "getAssistContextExtras()"); 10348 PendingAssistExtras pae; 10349 Bundle extras = new Bundle(); 10350 synchronized (this) { 10351 ActivityRecord activity = getFocusedStack().mResumedActivity; 10352 if (activity == null) { 10353 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10354 return null; 10355 } 10356 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10357 if (activity.app == null || activity.app.thread == null) { 10358 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10359 return extras; 10360 } 10361 if (activity.app.pid == Binder.getCallingPid()) { 10362 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10363 return extras; 10364 } 10365 pae = new PendingAssistExtras(activity); 10366 try { 10367 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10368 requestType); 10369 mPendingAssistExtras.add(pae); 10370 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10371 } catch (RemoteException e) { 10372 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10373 return extras; 10374 } 10375 } 10376 synchronized (pae) { 10377 while (!pae.haveResult) { 10378 try { 10379 pae.wait(); 10380 } catch (InterruptedException e) { 10381 } 10382 } 10383 if (pae.result != null) { 10384 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10385 } 10386 } 10387 synchronized (this) { 10388 mPendingAssistExtras.remove(pae); 10389 mHandler.removeCallbacks(pae); 10390 } 10391 return extras; 10392 } 10393 10394 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10395 PendingAssistExtras pae = (PendingAssistExtras)token; 10396 synchronized (pae) { 10397 pae.result = extras; 10398 pae.haveResult = true; 10399 pae.notifyAll(); 10400 } 10401 } 10402 10403 public void registerProcessObserver(IProcessObserver observer) { 10404 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10405 "registerProcessObserver()"); 10406 synchronized (this) { 10407 mProcessObservers.register(observer); 10408 } 10409 } 10410 10411 @Override 10412 public void unregisterProcessObserver(IProcessObserver observer) { 10413 synchronized (this) { 10414 mProcessObservers.unregister(observer); 10415 } 10416 } 10417 10418 @Override 10419 public boolean convertFromTranslucent(IBinder token) { 10420 final long origId = Binder.clearCallingIdentity(); 10421 try { 10422 synchronized (this) { 10423 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10424 if (r == null) { 10425 return false; 10426 } 10427 final boolean translucentChanged = r.changeWindowTranslucency(true); 10428 if (translucentChanged) { 10429 r.task.stack.releaseBackgroundResources(); 10430 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10431 } 10432 mWindowManager.setAppFullscreen(token, true); 10433 return translucentChanged; 10434 } 10435 } finally { 10436 Binder.restoreCallingIdentity(origId); 10437 } 10438 } 10439 10440 @Override 10441 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10442 final long origId = Binder.clearCallingIdentity(); 10443 try { 10444 synchronized (this) { 10445 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10446 if (r == null) { 10447 return false; 10448 } 10449 int index = r.task.mActivities.lastIndexOf(r); 10450 if (index > 0) { 10451 ActivityRecord under = r.task.mActivities.get(index - 1); 10452 under.returningOptions = options; 10453 } 10454 final boolean translucentChanged = r.changeWindowTranslucency(false); 10455 if (translucentChanged) { 10456 r.task.stack.convertToTranslucent(r); 10457 } 10458 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10459 mWindowManager.setAppFullscreen(token, false); 10460 return translucentChanged; 10461 } 10462 } finally { 10463 Binder.restoreCallingIdentity(origId); 10464 } 10465 } 10466 10467 @Override 10468 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10469 final long origId = Binder.clearCallingIdentity(); 10470 try { 10471 synchronized (this) { 10472 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10473 if (r != null) { 10474 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10475 } 10476 } 10477 return false; 10478 } finally { 10479 Binder.restoreCallingIdentity(origId); 10480 } 10481 } 10482 10483 @Override 10484 public boolean isBackgroundVisibleBehind(IBinder token) { 10485 final long origId = Binder.clearCallingIdentity(); 10486 try { 10487 synchronized (this) { 10488 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10489 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10490 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10491 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10492 return visible; 10493 } 10494 } finally { 10495 Binder.restoreCallingIdentity(origId); 10496 } 10497 } 10498 10499 @Override 10500 public ActivityOptions getActivityOptions(IBinder token) { 10501 final long origId = Binder.clearCallingIdentity(); 10502 try { 10503 synchronized (this) { 10504 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10505 if (r != null) { 10506 final ActivityOptions activityOptions = r.pendingOptions; 10507 r.pendingOptions = null; 10508 return activityOptions; 10509 } 10510 return null; 10511 } 10512 } finally { 10513 Binder.restoreCallingIdentity(origId); 10514 } 10515 } 10516 10517 @Override 10518 public void setImmersive(IBinder token, boolean immersive) { 10519 synchronized(this) { 10520 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10521 if (r == null) { 10522 throw new IllegalArgumentException(); 10523 } 10524 r.immersive = immersive; 10525 10526 // update associated state if we're frontmost 10527 if (r == mFocusedActivity) { 10528 if (DEBUG_IMMERSIVE) { 10529 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10530 } 10531 applyUpdateLockStateLocked(r); 10532 } 10533 } 10534 } 10535 10536 @Override 10537 public boolean isImmersive(IBinder token) { 10538 synchronized (this) { 10539 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10540 if (r == null) { 10541 throw new IllegalArgumentException(); 10542 } 10543 return r.immersive; 10544 } 10545 } 10546 10547 public boolean isTopActivityImmersive() { 10548 enforceNotIsolatedCaller("startActivity"); 10549 synchronized (this) { 10550 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10551 return (r != null) ? r.immersive : false; 10552 } 10553 } 10554 10555 @Override 10556 public boolean isTopOfTask(IBinder token) { 10557 synchronized (this) { 10558 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10559 if (r == null) { 10560 throw new IllegalArgumentException(); 10561 } 10562 return r.task.getTopActivity() == r; 10563 } 10564 } 10565 10566 public final void enterSafeMode() { 10567 synchronized(this) { 10568 // It only makes sense to do this before the system is ready 10569 // and started launching other packages. 10570 if (!mSystemReady) { 10571 try { 10572 AppGlobals.getPackageManager().enterSafeMode(); 10573 } catch (RemoteException e) { 10574 } 10575 } 10576 10577 mSafeMode = true; 10578 } 10579 } 10580 10581 public final void showSafeModeOverlay() { 10582 View v = LayoutInflater.from(mContext).inflate( 10583 com.android.internal.R.layout.safe_mode, null); 10584 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10585 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10586 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10587 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10588 lp.gravity = Gravity.BOTTOM | Gravity.START; 10589 lp.format = v.getBackground().getOpacity(); 10590 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10591 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10592 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10593 ((WindowManager)mContext.getSystemService( 10594 Context.WINDOW_SERVICE)).addView(v, lp); 10595 } 10596 10597 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10598 if (!(sender instanceof PendingIntentRecord)) { 10599 return; 10600 } 10601 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10602 synchronized (stats) { 10603 if (mBatteryStatsService.isOnBattery()) { 10604 mBatteryStatsService.enforceCallingPermission(); 10605 PendingIntentRecord rec = (PendingIntentRecord)sender; 10606 int MY_UID = Binder.getCallingUid(); 10607 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10608 BatteryStatsImpl.Uid.Pkg pkg = 10609 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10610 sourcePkg != null ? sourcePkg : rec.key.packageName); 10611 pkg.incWakeupsLocked(); 10612 } 10613 } 10614 } 10615 10616 public boolean killPids(int[] pids, String pReason, boolean secure) { 10617 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10618 throw new SecurityException("killPids only available to the system"); 10619 } 10620 String reason = (pReason == null) ? "Unknown" : pReason; 10621 // XXX Note: don't acquire main activity lock here, because the window 10622 // manager calls in with its locks held. 10623 10624 boolean killed = false; 10625 synchronized (mPidsSelfLocked) { 10626 int[] types = new int[pids.length]; 10627 int worstType = 0; 10628 for (int i=0; i<pids.length; i++) { 10629 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10630 if (proc != null) { 10631 int type = proc.setAdj; 10632 types[i] = type; 10633 if (type > worstType) { 10634 worstType = type; 10635 } 10636 } 10637 } 10638 10639 // If the worst oom_adj is somewhere in the cached proc LRU range, 10640 // then constrain it so we will kill all cached procs. 10641 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10642 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10643 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10644 } 10645 10646 // If this is not a secure call, don't let it kill processes that 10647 // are important. 10648 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10649 worstType = ProcessList.SERVICE_ADJ; 10650 } 10651 10652 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10653 for (int i=0; i<pids.length; i++) { 10654 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10655 if (proc == null) { 10656 continue; 10657 } 10658 int adj = proc.setAdj; 10659 if (adj >= worstType && !proc.killedByAm) { 10660 proc.kill(reason, true); 10661 killed = true; 10662 } 10663 } 10664 } 10665 return killed; 10666 } 10667 10668 @Override 10669 public void killUid(int uid, String reason) { 10670 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10671 throw new SecurityException("killUid only available to the system"); 10672 } 10673 synchronized (this) { 10674 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10675 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10676 reason != null ? reason : "kill uid"); 10677 } 10678 } 10679 10680 @Override 10681 public boolean killProcessesBelowForeground(String reason) { 10682 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10683 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10684 } 10685 10686 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10687 } 10688 10689 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10690 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10691 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10692 } 10693 10694 boolean killed = false; 10695 synchronized (mPidsSelfLocked) { 10696 final int size = mPidsSelfLocked.size(); 10697 for (int i = 0; i < size; i++) { 10698 final int pid = mPidsSelfLocked.keyAt(i); 10699 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10700 if (proc == null) continue; 10701 10702 final int adj = proc.setAdj; 10703 if (adj > belowAdj && !proc.killedByAm) { 10704 proc.kill(reason, true); 10705 killed = true; 10706 } 10707 } 10708 } 10709 return killed; 10710 } 10711 10712 @Override 10713 public void hang(final IBinder who, boolean allowRestart) { 10714 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10715 != PackageManager.PERMISSION_GRANTED) { 10716 throw new SecurityException("Requires permission " 10717 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10718 } 10719 10720 final IBinder.DeathRecipient death = new DeathRecipient() { 10721 @Override 10722 public void binderDied() { 10723 synchronized (this) { 10724 notifyAll(); 10725 } 10726 } 10727 }; 10728 10729 try { 10730 who.linkToDeath(death, 0); 10731 } catch (RemoteException e) { 10732 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10733 return; 10734 } 10735 10736 synchronized (this) { 10737 Watchdog.getInstance().setAllowRestart(allowRestart); 10738 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10739 synchronized (death) { 10740 while (who.isBinderAlive()) { 10741 try { 10742 death.wait(); 10743 } catch (InterruptedException e) { 10744 } 10745 } 10746 } 10747 Watchdog.getInstance().setAllowRestart(true); 10748 } 10749 } 10750 10751 @Override 10752 public void restart() { 10753 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10754 != PackageManager.PERMISSION_GRANTED) { 10755 throw new SecurityException("Requires permission " 10756 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10757 } 10758 10759 Log.i(TAG, "Sending shutdown broadcast..."); 10760 10761 BroadcastReceiver br = new BroadcastReceiver() { 10762 @Override public void onReceive(Context context, Intent intent) { 10763 // Now the broadcast is done, finish up the low-level shutdown. 10764 Log.i(TAG, "Shutting down activity manager..."); 10765 shutdown(10000); 10766 Log.i(TAG, "Shutdown complete, restarting!"); 10767 Process.killProcess(Process.myPid()); 10768 System.exit(10); 10769 } 10770 }; 10771 10772 // First send the high-level shut down broadcast. 10773 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10774 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10775 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10776 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10777 mContext.sendOrderedBroadcastAsUser(intent, 10778 UserHandle.ALL, null, br, mHandler, 0, null, null); 10779 */ 10780 br.onReceive(mContext, intent); 10781 } 10782 10783 private long getLowRamTimeSinceIdle(long now) { 10784 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10785 } 10786 10787 @Override 10788 public void performIdleMaintenance() { 10789 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10790 != PackageManager.PERMISSION_GRANTED) { 10791 throw new SecurityException("Requires permission " 10792 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10793 } 10794 10795 synchronized (this) { 10796 final long now = SystemClock.uptimeMillis(); 10797 final long timeSinceLastIdle = now - mLastIdleTime; 10798 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10799 mLastIdleTime = now; 10800 mLowRamTimeSinceLastIdle = 0; 10801 if (mLowRamStartTime != 0) { 10802 mLowRamStartTime = now; 10803 } 10804 10805 StringBuilder sb = new StringBuilder(128); 10806 sb.append("Idle maintenance over "); 10807 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10808 sb.append(" low RAM for "); 10809 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10810 Slog.i(TAG, sb.toString()); 10811 10812 // If at least 1/3 of our time since the last idle period has been spent 10813 // with RAM low, then we want to kill processes. 10814 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10815 10816 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10817 ProcessRecord proc = mLruProcesses.get(i); 10818 if (proc.notCachedSinceIdle) { 10819 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10820 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10821 if (doKilling && proc.initialIdlePss != 0 10822 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10823 proc.kill("idle maint (pss " + proc.lastPss 10824 + " from " + proc.initialIdlePss + ")", true); 10825 } 10826 } 10827 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10828 proc.notCachedSinceIdle = true; 10829 proc.initialIdlePss = 0; 10830 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10831 isSleeping(), now); 10832 } 10833 } 10834 10835 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10836 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10837 } 10838 } 10839 10840 private void retrieveSettings() { 10841 final ContentResolver resolver = mContext.getContentResolver(); 10842 String debugApp = Settings.Global.getString( 10843 resolver, Settings.Global.DEBUG_APP); 10844 boolean waitForDebugger = Settings.Global.getInt( 10845 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10846 boolean alwaysFinishActivities = Settings.Global.getInt( 10847 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10848 boolean forceRtl = Settings.Global.getInt( 10849 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10850 // Transfer any global setting for forcing RTL layout, into a System Property 10851 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10852 10853 Configuration configuration = new Configuration(); 10854 Settings.System.getConfiguration(resolver, configuration); 10855 if (forceRtl) { 10856 // This will take care of setting the correct layout direction flags 10857 configuration.setLayoutDirection(configuration.locale); 10858 } 10859 10860 synchronized (this) { 10861 mDebugApp = mOrigDebugApp = debugApp; 10862 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10863 mAlwaysFinishActivities = alwaysFinishActivities; 10864 // This happens before any activities are started, so we can 10865 // change mConfiguration in-place. 10866 updateConfigurationLocked(configuration, null, false, true); 10867 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10868 } 10869 } 10870 10871 /** Loads resources after the current configuration has been set. */ 10872 private void loadResourcesOnSystemReady() { 10873 final Resources res = mContext.getResources(); 10874 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10875 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10876 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10877 } 10878 10879 public boolean testIsSystemReady() { 10880 // no need to synchronize(this) just to read & return the value 10881 return mSystemReady; 10882 } 10883 10884 private static File getCalledPreBootReceiversFile() { 10885 File dataDir = Environment.getDataDirectory(); 10886 File systemDir = new File(dataDir, "system"); 10887 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10888 return fname; 10889 } 10890 10891 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10892 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10893 File file = getCalledPreBootReceiversFile(); 10894 FileInputStream fis = null; 10895 try { 10896 fis = new FileInputStream(file); 10897 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10898 int fvers = dis.readInt(); 10899 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10900 String vers = dis.readUTF(); 10901 String codename = dis.readUTF(); 10902 String build = dis.readUTF(); 10903 if (android.os.Build.VERSION.RELEASE.equals(vers) 10904 && android.os.Build.VERSION.CODENAME.equals(codename) 10905 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10906 int num = dis.readInt(); 10907 while (num > 0) { 10908 num--; 10909 String pkg = dis.readUTF(); 10910 String cls = dis.readUTF(); 10911 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10912 } 10913 } 10914 } 10915 } catch (FileNotFoundException e) { 10916 } catch (IOException e) { 10917 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10918 } finally { 10919 if (fis != null) { 10920 try { 10921 fis.close(); 10922 } catch (IOException e) { 10923 } 10924 } 10925 } 10926 return lastDoneReceivers; 10927 } 10928 10929 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10930 File file = getCalledPreBootReceiversFile(); 10931 FileOutputStream fos = null; 10932 DataOutputStream dos = null; 10933 try { 10934 fos = new FileOutputStream(file); 10935 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10936 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10937 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10938 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10939 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10940 dos.writeInt(list.size()); 10941 for (int i=0; i<list.size(); i++) { 10942 dos.writeUTF(list.get(i).getPackageName()); 10943 dos.writeUTF(list.get(i).getClassName()); 10944 } 10945 } catch (IOException e) { 10946 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10947 file.delete(); 10948 } finally { 10949 FileUtils.sync(fos); 10950 if (dos != null) { 10951 try { 10952 dos.close(); 10953 } catch (IOException e) { 10954 // TODO Auto-generated catch block 10955 e.printStackTrace(); 10956 } 10957 } 10958 } 10959 } 10960 10961 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10962 ArrayList<ComponentName> doneReceivers, int userId) { 10963 boolean waitingUpdate = false; 10964 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10965 List<ResolveInfo> ris = null; 10966 try { 10967 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10968 intent, null, 0, userId); 10969 } catch (RemoteException e) { 10970 } 10971 if (ris != null) { 10972 for (int i=ris.size()-1; i>=0; i--) { 10973 if ((ris.get(i).activityInfo.applicationInfo.flags 10974 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10975 ris.remove(i); 10976 } 10977 } 10978 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10979 10980 // For User 0, load the version number. When delivering to a new user, deliver 10981 // to all receivers. 10982 if (userId == UserHandle.USER_OWNER) { 10983 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10984 for (int i=0; i<ris.size(); i++) { 10985 ActivityInfo ai = ris.get(i).activityInfo; 10986 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10987 if (lastDoneReceivers.contains(comp)) { 10988 // We already did the pre boot receiver for this app with the current 10989 // platform version, so don't do it again... 10990 ris.remove(i); 10991 i--; 10992 // ...however, do keep it as one that has been done, so we don't 10993 // forget about it when rewriting the file of last done receivers. 10994 doneReceivers.add(comp); 10995 } 10996 } 10997 } 10998 10999 // If primary user, send broadcast to all available users, else just to userId 11000 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11001 : new int[] { userId }; 11002 for (int i = 0; i < ris.size(); i++) { 11003 ActivityInfo ai = ris.get(i).activityInfo; 11004 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11005 doneReceivers.add(comp); 11006 intent.setComponent(comp); 11007 for (int j=0; j<users.length; j++) { 11008 IIntentReceiver finisher = null; 11009 // On last receiver and user, set up a completion callback 11010 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11011 finisher = new IIntentReceiver.Stub() { 11012 public void performReceive(Intent intent, int resultCode, 11013 String data, Bundle extras, boolean ordered, 11014 boolean sticky, int sendingUser) { 11015 // The raw IIntentReceiver interface is called 11016 // with the AM lock held, so redispatch to 11017 // execute our code without the lock. 11018 mHandler.post(onFinishCallback); 11019 } 11020 }; 11021 } 11022 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11023 + " for user " + users[j]); 11024 broadcastIntentLocked(null, null, intent, null, finisher, 11025 0, null, null, null, AppOpsManager.OP_NONE, 11026 true, false, MY_PID, Process.SYSTEM_UID, 11027 users[j]); 11028 if (finisher != null) { 11029 waitingUpdate = true; 11030 } 11031 } 11032 } 11033 } 11034 11035 return waitingUpdate; 11036 } 11037 11038 public void systemReady(final Runnable goingCallback) { 11039 synchronized(this) { 11040 if (mSystemReady) { 11041 // If we're done calling all the receivers, run the next "boot phase" passed in 11042 // by the SystemServer 11043 if (goingCallback != null) { 11044 goingCallback.run(); 11045 } 11046 return; 11047 } 11048 11049 // Make sure we have the current profile info, since it is needed for 11050 // security checks. 11051 updateCurrentProfileIdsLocked(); 11052 11053 if (mRecentTasks == null) { 11054 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11055 if (!mRecentTasks.isEmpty()) { 11056 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11057 } 11058 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11059 mTaskPersister.startPersisting(); 11060 } 11061 11062 // Check to see if there are any update receivers to run. 11063 if (!mDidUpdate) { 11064 if (mWaitingUpdate) { 11065 return; 11066 } 11067 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11068 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11069 public void run() { 11070 synchronized (ActivityManagerService.this) { 11071 mDidUpdate = true; 11072 } 11073 writeLastDonePreBootReceivers(doneReceivers); 11074 showBootMessage(mContext.getText( 11075 R.string.android_upgrading_complete), 11076 false); 11077 systemReady(goingCallback); 11078 } 11079 }, doneReceivers, UserHandle.USER_OWNER); 11080 11081 if (mWaitingUpdate) { 11082 return; 11083 } 11084 mDidUpdate = true; 11085 } 11086 11087 mAppOpsService.systemReady(); 11088 mSystemReady = true; 11089 } 11090 11091 ArrayList<ProcessRecord> procsToKill = null; 11092 synchronized(mPidsSelfLocked) { 11093 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11094 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11095 if (!isAllowedWhileBooting(proc.info)){ 11096 if (procsToKill == null) { 11097 procsToKill = new ArrayList<ProcessRecord>(); 11098 } 11099 procsToKill.add(proc); 11100 } 11101 } 11102 } 11103 11104 synchronized(this) { 11105 if (procsToKill != null) { 11106 for (int i=procsToKill.size()-1; i>=0; i--) { 11107 ProcessRecord proc = procsToKill.get(i); 11108 Slog.i(TAG, "Removing system update proc: " + proc); 11109 removeProcessLocked(proc, true, false, "system update done"); 11110 } 11111 } 11112 11113 // Now that we have cleaned up any update processes, we 11114 // are ready to start launching real processes and know that 11115 // we won't trample on them any more. 11116 mProcessesReady = true; 11117 } 11118 11119 Slog.i(TAG, "System now ready"); 11120 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11121 SystemClock.uptimeMillis()); 11122 11123 synchronized(this) { 11124 // Make sure we have no pre-ready processes sitting around. 11125 11126 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11127 ResolveInfo ri = mContext.getPackageManager() 11128 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11129 STOCK_PM_FLAGS); 11130 CharSequence errorMsg = null; 11131 if (ri != null) { 11132 ActivityInfo ai = ri.activityInfo; 11133 ApplicationInfo app = ai.applicationInfo; 11134 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11135 mTopAction = Intent.ACTION_FACTORY_TEST; 11136 mTopData = null; 11137 mTopComponent = new ComponentName(app.packageName, 11138 ai.name); 11139 } else { 11140 errorMsg = mContext.getResources().getText( 11141 com.android.internal.R.string.factorytest_not_system); 11142 } 11143 } else { 11144 errorMsg = mContext.getResources().getText( 11145 com.android.internal.R.string.factorytest_no_action); 11146 } 11147 if (errorMsg != null) { 11148 mTopAction = null; 11149 mTopData = null; 11150 mTopComponent = null; 11151 Message msg = Message.obtain(); 11152 msg.what = SHOW_FACTORY_ERROR_MSG; 11153 msg.getData().putCharSequence("msg", errorMsg); 11154 mHandler.sendMessage(msg); 11155 } 11156 } 11157 } 11158 11159 retrieveSettings(); 11160 loadResourcesOnSystemReady(); 11161 11162 synchronized (this) { 11163 readGrantedUriPermissionsLocked(); 11164 } 11165 11166 if (goingCallback != null) goingCallback.run(); 11167 11168 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11169 Integer.toString(mCurrentUserId), mCurrentUserId); 11170 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11171 Integer.toString(mCurrentUserId), mCurrentUserId); 11172 mSystemServiceManager.startUser(mCurrentUserId); 11173 11174 synchronized (this) { 11175 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11176 try { 11177 List apps = AppGlobals.getPackageManager(). 11178 getPersistentApplications(STOCK_PM_FLAGS); 11179 if (apps != null) { 11180 int N = apps.size(); 11181 int i; 11182 for (i=0; i<N; i++) { 11183 ApplicationInfo info 11184 = (ApplicationInfo)apps.get(i); 11185 if (info != null && 11186 !info.packageName.equals("android")) { 11187 addAppLocked(info, false, null /* ABI override */); 11188 } 11189 } 11190 } 11191 } catch (RemoteException ex) { 11192 // pm is in same process, this will never happen. 11193 } 11194 } 11195 11196 // Start up initial activity. 11197 mBooting = true; 11198 11199 try { 11200 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11201 Message msg = Message.obtain(); 11202 msg.what = SHOW_UID_ERROR_MSG; 11203 mHandler.sendMessage(msg); 11204 } 11205 } catch (RemoteException e) { 11206 } 11207 11208 long ident = Binder.clearCallingIdentity(); 11209 try { 11210 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11211 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11212 | Intent.FLAG_RECEIVER_FOREGROUND); 11213 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11214 broadcastIntentLocked(null, null, intent, 11215 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11216 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11217 intent = new Intent(Intent.ACTION_USER_STARTING); 11218 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11219 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11220 broadcastIntentLocked(null, null, intent, 11221 null, new IIntentReceiver.Stub() { 11222 @Override 11223 public void performReceive(Intent intent, int resultCode, String data, 11224 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11225 throws RemoteException { 11226 } 11227 }, 0, null, null, 11228 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11229 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11230 } catch (Throwable t) { 11231 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11232 } finally { 11233 Binder.restoreCallingIdentity(ident); 11234 } 11235 mStackSupervisor.resumeTopActivitiesLocked(); 11236 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11237 } 11238 } 11239 11240 private boolean makeAppCrashingLocked(ProcessRecord app, 11241 String shortMsg, String longMsg, String stackTrace) { 11242 app.crashing = true; 11243 app.crashingReport = generateProcessError(app, 11244 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11245 startAppProblemLocked(app); 11246 app.stopFreezingAllLocked(); 11247 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11248 } 11249 11250 private void makeAppNotRespondingLocked(ProcessRecord app, 11251 String activity, String shortMsg, String longMsg) { 11252 app.notResponding = true; 11253 app.notRespondingReport = generateProcessError(app, 11254 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11255 activity, shortMsg, longMsg, null); 11256 startAppProblemLocked(app); 11257 app.stopFreezingAllLocked(); 11258 } 11259 11260 /** 11261 * Generate a process error record, suitable for attachment to a ProcessRecord. 11262 * 11263 * @param app The ProcessRecord in which the error occurred. 11264 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11265 * ActivityManager.AppErrorStateInfo 11266 * @param activity The activity associated with the crash, if known. 11267 * @param shortMsg Short message describing the crash. 11268 * @param longMsg Long message describing the crash. 11269 * @param stackTrace Full crash stack trace, may be null. 11270 * 11271 * @return Returns a fully-formed AppErrorStateInfo record. 11272 */ 11273 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11274 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11275 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11276 11277 report.condition = condition; 11278 report.processName = app.processName; 11279 report.pid = app.pid; 11280 report.uid = app.info.uid; 11281 report.tag = activity; 11282 report.shortMsg = shortMsg; 11283 report.longMsg = longMsg; 11284 report.stackTrace = stackTrace; 11285 11286 return report; 11287 } 11288 11289 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11290 synchronized (this) { 11291 app.crashing = false; 11292 app.crashingReport = null; 11293 app.notResponding = false; 11294 app.notRespondingReport = null; 11295 if (app.anrDialog == fromDialog) { 11296 app.anrDialog = null; 11297 } 11298 if (app.waitDialog == fromDialog) { 11299 app.waitDialog = null; 11300 } 11301 if (app.pid > 0 && app.pid != MY_PID) { 11302 handleAppCrashLocked(app, null, null, null); 11303 app.kill("user request after error", true); 11304 } 11305 } 11306 } 11307 11308 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11309 String stackTrace) { 11310 long now = SystemClock.uptimeMillis(); 11311 11312 Long crashTime; 11313 if (!app.isolated) { 11314 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11315 } else { 11316 crashTime = null; 11317 } 11318 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11319 // This process loses! 11320 Slog.w(TAG, "Process " + app.info.processName 11321 + " has crashed too many times: killing!"); 11322 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11323 app.userId, app.info.processName, app.uid); 11324 mStackSupervisor.handleAppCrashLocked(app); 11325 if (!app.persistent) { 11326 // We don't want to start this process again until the user 11327 // explicitly does so... but for persistent process, we really 11328 // need to keep it running. If a persistent process is actually 11329 // repeatedly crashing, then badness for everyone. 11330 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11331 app.info.processName); 11332 if (!app.isolated) { 11333 // XXX We don't have a way to mark isolated processes 11334 // as bad, since they don't have a peristent identity. 11335 mBadProcesses.put(app.info.processName, app.uid, 11336 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11337 mProcessCrashTimes.remove(app.info.processName, app.uid); 11338 } 11339 app.bad = true; 11340 app.removed = true; 11341 // Don't let services in this process be restarted and potentially 11342 // annoy the user repeatedly. Unless it is persistent, since those 11343 // processes run critical code. 11344 removeProcessLocked(app, false, false, "crash"); 11345 mStackSupervisor.resumeTopActivitiesLocked(); 11346 return false; 11347 } 11348 mStackSupervisor.resumeTopActivitiesLocked(); 11349 } else { 11350 mStackSupervisor.finishTopRunningActivityLocked(app); 11351 } 11352 11353 // Bump up the crash count of any services currently running in the proc. 11354 for (int i=app.services.size()-1; i>=0; i--) { 11355 // Any services running in the application need to be placed 11356 // back in the pending list. 11357 ServiceRecord sr = app.services.valueAt(i); 11358 sr.crashCount++; 11359 } 11360 11361 // If the crashing process is what we consider to be the "home process" and it has been 11362 // replaced by a third-party app, clear the package preferred activities from packages 11363 // with a home activity running in the process to prevent a repeatedly crashing app 11364 // from blocking the user to manually clear the list. 11365 final ArrayList<ActivityRecord> activities = app.activities; 11366 if (app == mHomeProcess && activities.size() > 0 11367 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11368 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11369 final ActivityRecord r = activities.get(activityNdx); 11370 if (r.isHomeActivity()) { 11371 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11372 try { 11373 ActivityThread.getPackageManager() 11374 .clearPackagePreferredActivities(r.packageName); 11375 } catch (RemoteException c) { 11376 // pm is in same process, this will never happen. 11377 } 11378 } 11379 } 11380 } 11381 11382 if (!app.isolated) { 11383 // XXX Can't keep track of crash times for isolated processes, 11384 // because they don't have a perisistent identity. 11385 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11386 } 11387 11388 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11389 return true; 11390 } 11391 11392 void startAppProblemLocked(ProcessRecord app) { 11393 // If this app is not running under the current user, then we 11394 // can't give it a report button because that would require 11395 // launching the report UI under a different user. 11396 app.errorReportReceiver = null; 11397 11398 for (int userId : mCurrentProfileIds) { 11399 if (app.userId == userId) { 11400 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11401 mContext, app.info.packageName, app.info.flags); 11402 } 11403 } 11404 skipCurrentReceiverLocked(app); 11405 } 11406 11407 void skipCurrentReceiverLocked(ProcessRecord app) { 11408 for (BroadcastQueue queue : mBroadcastQueues) { 11409 queue.skipCurrentReceiverLocked(app); 11410 } 11411 } 11412 11413 /** 11414 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11415 * The application process will exit immediately after this call returns. 11416 * @param app object of the crashing app, null for the system server 11417 * @param crashInfo describing the exception 11418 */ 11419 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11420 ProcessRecord r = findAppProcess(app, "Crash"); 11421 final String processName = app == null ? "system_server" 11422 : (r == null ? "unknown" : r.processName); 11423 11424 handleApplicationCrashInner("crash", r, processName, crashInfo); 11425 } 11426 11427 /* Native crash reporting uses this inner version because it needs to be somewhat 11428 * decoupled from the AM-managed cleanup lifecycle 11429 */ 11430 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11431 ApplicationErrorReport.CrashInfo crashInfo) { 11432 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11433 UserHandle.getUserId(Binder.getCallingUid()), processName, 11434 r == null ? -1 : r.info.flags, 11435 crashInfo.exceptionClassName, 11436 crashInfo.exceptionMessage, 11437 crashInfo.throwFileName, 11438 crashInfo.throwLineNumber); 11439 11440 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11441 11442 crashApplication(r, crashInfo); 11443 } 11444 11445 public void handleApplicationStrictModeViolation( 11446 IBinder app, 11447 int violationMask, 11448 StrictMode.ViolationInfo info) { 11449 ProcessRecord r = findAppProcess(app, "StrictMode"); 11450 if (r == null) { 11451 return; 11452 } 11453 11454 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11455 Integer stackFingerprint = info.hashCode(); 11456 boolean logIt = true; 11457 synchronized (mAlreadyLoggedViolatedStacks) { 11458 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11459 logIt = false; 11460 // TODO: sub-sample into EventLog for these, with 11461 // the info.durationMillis? Then we'd get 11462 // the relative pain numbers, without logging all 11463 // the stack traces repeatedly. We'd want to do 11464 // likewise in the client code, which also does 11465 // dup suppression, before the Binder call. 11466 } else { 11467 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11468 mAlreadyLoggedViolatedStacks.clear(); 11469 } 11470 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11471 } 11472 } 11473 if (logIt) { 11474 logStrictModeViolationToDropBox(r, info); 11475 } 11476 } 11477 11478 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11479 AppErrorResult result = new AppErrorResult(); 11480 synchronized (this) { 11481 final long origId = Binder.clearCallingIdentity(); 11482 11483 Message msg = Message.obtain(); 11484 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11485 HashMap<String, Object> data = new HashMap<String, Object>(); 11486 data.put("result", result); 11487 data.put("app", r); 11488 data.put("violationMask", violationMask); 11489 data.put("info", info); 11490 msg.obj = data; 11491 mHandler.sendMessage(msg); 11492 11493 Binder.restoreCallingIdentity(origId); 11494 } 11495 int res = result.get(); 11496 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11497 } 11498 } 11499 11500 // Depending on the policy in effect, there could be a bunch of 11501 // these in quick succession so we try to batch these together to 11502 // minimize disk writes, number of dropbox entries, and maximize 11503 // compression, by having more fewer, larger records. 11504 private void logStrictModeViolationToDropBox( 11505 ProcessRecord process, 11506 StrictMode.ViolationInfo info) { 11507 if (info == null) { 11508 return; 11509 } 11510 final boolean isSystemApp = process == null || 11511 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11512 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11513 final String processName = process == null ? "unknown" : process.processName; 11514 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11515 final DropBoxManager dbox = (DropBoxManager) 11516 mContext.getSystemService(Context.DROPBOX_SERVICE); 11517 11518 // Exit early if the dropbox isn't configured to accept this report type. 11519 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11520 11521 boolean bufferWasEmpty; 11522 boolean needsFlush; 11523 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11524 synchronized (sb) { 11525 bufferWasEmpty = sb.length() == 0; 11526 appendDropBoxProcessHeaders(process, processName, sb); 11527 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11528 sb.append("System-App: ").append(isSystemApp).append("\n"); 11529 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11530 if (info.violationNumThisLoop != 0) { 11531 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11532 } 11533 if (info.numAnimationsRunning != 0) { 11534 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11535 } 11536 if (info.broadcastIntentAction != null) { 11537 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11538 } 11539 if (info.durationMillis != -1) { 11540 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11541 } 11542 if (info.numInstances != -1) { 11543 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11544 } 11545 if (info.tags != null) { 11546 for (String tag : info.tags) { 11547 sb.append("Span-Tag: ").append(tag).append("\n"); 11548 } 11549 } 11550 sb.append("\n"); 11551 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11552 sb.append(info.crashInfo.stackTrace); 11553 } 11554 sb.append("\n"); 11555 11556 // Only buffer up to ~64k. Various logging bits truncate 11557 // things at 128k. 11558 needsFlush = (sb.length() > 64 * 1024); 11559 } 11560 11561 // Flush immediately if the buffer's grown too large, or this 11562 // is a non-system app. Non-system apps are isolated with a 11563 // different tag & policy and not batched. 11564 // 11565 // Batching is useful during internal testing with 11566 // StrictMode settings turned up high. Without batching, 11567 // thousands of separate files could be created on boot. 11568 if (!isSystemApp || needsFlush) { 11569 new Thread("Error dump: " + dropboxTag) { 11570 @Override 11571 public void run() { 11572 String report; 11573 synchronized (sb) { 11574 report = sb.toString(); 11575 sb.delete(0, sb.length()); 11576 sb.trimToSize(); 11577 } 11578 if (report.length() != 0) { 11579 dbox.addText(dropboxTag, report); 11580 } 11581 } 11582 }.start(); 11583 return; 11584 } 11585 11586 // System app batching: 11587 if (!bufferWasEmpty) { 11588 // An existing dropbox-writing thread is outstanding, so 11589 // we don't need to start it up. The existing thread will 11590 // catch the buffer appends we just did. 11591 return; 11592 } 11593 11594 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11595 // (After this point, we shouldn't access AMS internal data structures.) 11596 new Thread("Error dump: " + dropboxTag) { 11597 @Override 11598 public void run() { 11599 // 5 second sleep to let stacks arrive and be batched together 11600 try { 11601 Thread.sleep(5000); // 5 seconds 11602 } catch (InterruptedException e) {} 11603 11604 String errorReport; 11605 synchronized (mStrictModeBuffer) { 11606 errorReport = mStrictModeBuffer.toString(); 11607 if (errorReport.length() == 0) { 11608 return; 11609 } 11610 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11611 mStrictModeBuffer.trimToSize(); 11612 } 11613 dbox.addText(dropboxTag, errorReport); 11614 } 11615 }.start(); 11616 } 11617 11618 /** 11619 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11620 * @param app object of the crashing app, null for the system server 11621 * @param tag reported by the caller 11622 * @param system whether this wtf is coming from the system 11623 * @param crashInfo describing the context of the error 11624 * @return true if the process should exit immediately (WTF is fatal) 11625 */ 11626 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11627 final ApplicationErrorReport.CrashInfo crashInfo) { 11628 final ProcessRecord r = findAppProcess(app, "WTF"); 11629 final String processName = app == null ? "system_server" 11630 : (r == null ? "unknown" : r.processName); 11631 11632 EventLog.writeEvent(EventLogTags.AM_WTF, 11633 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11634 processName, 11635 r == null ? -1 : r.info.flags, 11636 tag, crashInfo.exceptionMessage); 11637 11638 if (system) { 11639 // If this is coming from the system, we could very well have low-level 11640 // system locks held, so we want to do this all asynchronously. And we 11641 // never want this to become fatal, so there is that too. 11642 mHandler.post(new Runnable() { 11643 @Override public void run() { 11644 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11645 crashInfo); 11646 } 11647 }); 11648 return false; 11649 } 11650 11651 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11652 11653 if (r != null && r.pid != Process.myPid() && 11654 Settings.Global.getInt(mContext.getContentResolver(), 11655 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11656 crashApplication(r, crashInfo); 11657 return true; 11658 } else { 11659 return false; 11660 } 11661 } 11662 11663 /** 11664 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11665 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11666 */ 11667 private ProcessRecord findAppProcess(IBinder app, String reason) { 11668 if (app == null) { 11669 return null; 11670 } 11671 11672 synchronized (this) { 11673 final int NP = mProcessNames.getMap().size(); 11674 for (int ip=0; ip<NP; ip++) { 11675 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11676 final int NA = apps.size(); 11677 for (int ia=0; ia<NA; ia++) { 11678 ProcessRecord p = apps.valueAt(ia); 11679 if (p.thread != null && p.thread.asBinder() == app) { 11680 return p; 11681 } 11682 } 11683 } 11684 11685 Slog.w(TAG, "Can't find mystery application for " + reason 11686 + " from pid=" + Binder.getCallingPid() 11687 + " uid=" + Binder.getCallingUid() + ": " + app); 11688 return null; 11689 } 11690 } 11691 11692 /** 11693 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11694 * to append various headers to the dropbox log text. 11695 */ 11696 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11697 StringBuilder sb) { 11698 // Watchdog thread ends up invoking this function (with 11699 // a null ProcessRecord) to add the stack file to dropbox. 11700 // Do not acquire a lock on this (am) in such cases, as it 11701 // could cause a potential deadlock, if and when watchdog 11702 // is invoked due to unavailability of lock on am and it 11703 // would prevent watchdog from killing system_server. 11704 if (process == null) { 11705 sb.append("Process: ").append(processName).append("\n"); 11706 return; 11707 } 11708 // Note: ProcessRecord 'process' is guarded by the service 11709 // instance. (notably process.pkgList, which could otherwise change 11710 // concurrently during execution of this method) 11711 synchronized (this) { 11712 sb.append("Process: ").append(processName).append("\n"); 11713 int flags = process.info.flags; 11714 IPackageManager pm = AppGlobals.getPackageManager(); 11715 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11716 for (int ip=0; ip<process.pkgList.size(); ip++) { 11717 String pkg = process.pkgList.keyAt(ip); 11718 sb.append("Package: ").append(pkg); 11719 try { 11720 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11721 if (pi != null) { 11722 sb.append(" v").append(pi.versionCode); 11723 if (pi.versionName != null) { 11724 sb.append(" (").append(pi.versionName).append(")"); 11725 } 11726 } 11727 } catch (RemoteException e) { 11728 Slog.e(TAG, "Error getting package info: " + pkg, e); 11729 } 11730 sb.append("\n"); 11731 } 11732 } 11733 } 11734 11735 private static String processClass(ProcessRecord process) { 11736 if (process == null || process.pid == MY_PID) { 11737 return "system_server"; 11738 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11739 return "system_app"; 11740 } else { 11741 return "data_app"; 11742 } 11743 } 11744 11745 /** 11746 * Write a description of an error (crash, WTF, ANR) to the drop box. 11747 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11748 * @param process which caused the error, null means the system server 11749 * @param activity which triggered the error, null if unknown 11750 * @param parent activity related to the error, null if unknown 11751 * @param subject line related to the error, null if absent 11752 * @param report in long form describing the error, null if absent 11753 * @param logFile to include in the report, null if none 11754 * @param crashInfo giving an application stack trace, null if absent 11755 */ 11756 public void addErrorToDropBox(String eventType, 11757 ProcessRecord process, String processName, ActivityRecord activity, 11758 ActivityRecord parent, String subject, 11759 final String report, final File logFile, 11760 final ApplicationErrorReport.CrashInfo crashInfo) { 11761 // NOTE -- this must never acquire the ActivityManagerService lock, 11762 // otherwise the watchdog may be prevented from resetting the system. 11763 11764 final String dropboxTag = processClass(process) + "_" + eventType; 11765 final DropBoxManager dbox = (DropBoxManager) 11766 mContext.getSystemService(Context.DROPBOX_SERVICE); 11767 11768 // Exit early if the dropbox isn't configured to accept this report type. 11769 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11770 11771 final StringBuilder sb = new StringBuilder(1024); 11772 appendDropBoxProcessHeaders(process, processName, sb); 11773 if (activity != null) { 11774 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11775 } 11776 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11777 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11778 } 11779 if (parent != null && parent != activity) { 11780 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11781 } 11782 if (subject != null) { 11783 sb.append("Subject: ").append(subject).append("\n"); 11784 } 11785 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11786 if (Debug.isDebuggerConnected()) { 11787 sb.append("Debugger: Connected\n"); 11788 } 11789 sb.append("\n"); 11790 11791 // Do the rest in a worker thread to avoid blocking the caller on I/O 11792 // (After this point, we shouldn't access AMS internal data structures.) 11793 Thread worker = new Thread("Error dump: " + dropboxTag) { 11794 @Override 11795 public void run() { 11796 if (report != null) { 11797 sb.append(report); 11798 } 11799 if (logFile != null) { 11800 try { 11801 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11802 "\n\n[[TRUNCATED]]")); 11803 } catch (IOException e) { 11804 Slog.e(TAG, "Error reading " + logFile, e); 11805 } 11806 } 11807 if (crashInfo != null && crashInfo.stackTrace != null) { 11808 sb.append(crashInfo.stackTrace); 11809 } 11810 11811 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11812 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11813 if (lines > 0) { 11814 sb.append("\n"); 11815 11816 // Merge several logcat streams, and take the last N lines 11817 InputStreamReader input = null; 11818 try { 11819 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11820 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11821 "-b", "crash", 11822 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11823 11824 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11825 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11826 input = new InputStreamReader(logcat.getInputStream()); 11827 11828 int num; 11829 char[] buf = new char[8192]; 11830 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11831 } catch (IOException e) { 11832 Slog.e(TAG, "Error running logcat", e); 11833 } finally { 11834 if (input != null) try { input.close(); } catch (IOException e) {} 11835 } 11836 } 11837 11838 dbox.addText(dropboxTag, sb.toString()); 11839 } 11840 }; 11841 11842 if (process == null) { 11843 // If process is null, we are being called from some internal code 11844 // and may be about to die -- run this synchronously. 11845 worker.run(); 11846 } else { 11847 worker.start(); 11848 } 11849 } 11850 11851 /** 11852 * Bring up the "unexpected error" dialog box for a crashing app. 11853 * Deal with edge cases (intercepts from instrumented applications, 11854 * ActivityController, error intent receivers, that sort of thing). 11855 * @param r the application crashing 11856 * @param crashInfo describing the failure 11857 */ 11858 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11859 long timeMillis = System.currentTimeMillis(); 11860 String shortMsg = crashInfo.exceptionClassName; 11861 String longMsg = crashInfo.exceptionMessage; 11862 String stackTrace = crashInfo.stackTrace; 11863 if (shortMsg != null && longMsg != null) { 11864 longMsg = shortMsg + ": " + longMsg; 11865 } else if (shortMsg != null) { 11866 longMsg = shortMsg; 11867 } 11868 11869 AppErrorResult result = new AppErrorResult(); 11870 synchronized (this) { 11871 if (mController != null) { 11872 try { 11873 String name = r != null ? r.processName : null; 11874 int pid = r != null ? r.pid : Binder.getCallingPid(); 11875 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11876 if (!mController.appCrashed(name, pid, 11877 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11878 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11879 && "Native crash".equals(crashInfo.exceptionClassName)) { 11880 Slog.w(TAG, "Skip killing native crashed app " + name 11881 + "(" + pid + ") during testing"); 11882 } else { 11883 Slog.w(TAG, "Force-killing crashed app " + name 11884 + " at watcher's request"); 11885 if (r != null) { 11886 r.kill("crash", true); 11887 } else { 11888 // Huh. 11889 Process.killProcess(pid); 11890 Process.killProcessGroup(uid, pid); 11891 } 11892 } 11893 return; 11894 } 11895 } catch (RemoteException e) { 11896 mController = null; 11897 Watchdog.getInstance().setActivityController(null); 11898 } 11899 } 11900 11901 final long origId = Binder.clearCallingIdentity(); 11902 11903 // If this process is running instrumentation, finish it. 11904 if (r != null && r.instrumentationClass != null) { 11905 Slog.w(TAG, "Error in app " + r.processName 11906 + " running instrumentation " + r.instrumentationClass + ":"); 11907 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11908 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11909 Bundle info = new Bundle(); 11910 info.putString("shortMsg", shortMsg); 11911 info.putString("longMsg", longMsg); 11912 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11913 Binder.restoreCallingIdentity(origId); 11914 return; 11915 } 11916 11917 // If we can't identify the process or it's already exceeded its crash quota, 11918 // quit right away without showing a crash dialog. 11919 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11920 Binder.restoreCallingIdentity(origId); 11921 return; 11922 } 11923 11924 Message msg = Message.obtain(); 11925 msg.what = SHOW_ERROR_MSG; 11926 HashMap data = new HashMap(); 11927 data.put("result", result); 11928 data.put("app", r); 11929 msg.obj = data; 11930 mHandler.sendMessage(msg); 11931 11932 Binder.restoreCallingIdentity(origId); 11933 } 11934 11935 int res = result.get(); 11936 11937 Intent appErrorIntent = null; 11938 synchronized (this) { 11939 if (r != null && !r.isolated) { 11940 // XXX Can't keep track of crash time for isolated processes, 11941 // since they don't have a persistent identity. 11942 mProcessCrashTimes.put(r.info.processName, r.uid, 11943 SystemClock.uptimeMillis()); 11944 } 11945 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11946 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11947 } 11948 } 11949 11950 if (appErrorIntent != null) { 11951 try { 11952 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11953 } catch (ActivityNotFoundException e) { 11954 Slog.w(TAG, "bug report receiver dissappeared", e); 11955 } 11956 } 11957 } 11958 11959 Intent createAppErrorIntentLocked(ProcessRecord r, 11960 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11961 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11962 if (report == null) { 11963 return null; 11964 } 11965 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11966 result.setComponent(r.errorReportReceiver); 11967 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11968 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11969 return result; 11970 } 11971 11972 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11973 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11974 if (r.errorReportReceiver == null) { 11975 return null; 11976 } 11977 11978 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11979 return null; 11980 } 11981 11982 ApplicationErrorReport report = new ApplicationErrorReport(); 11983 report.packageName = r.info.packageName; 11984 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11985 report.processName = r.processName; 11986 report.time = timeMillis; 11987 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11988 11989 if (r.crashing || r.forceCrashReport) { 11990 report.type = ApplicationErrorReport.TYPE_CRASH; 11991 report.crashInfo = crashInfo; 11992 } else if (r.notResponding) { 11993 report.type = ApplicationErrorReport.TYPE_ANR; 11994 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11995 11996 report.anrInfo.activity = r.notRespondingReport.tag; 11997 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11998 report.anrInfo.info = r.notRespondingReport.longMsg; 11999 } 12000 12001 return report; 12002 } 12003 12004 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12005 enforceNotIsolatedCaller("getProcessesInErrorState"); 12006 // assume our apps are happy - lazy create the list 12007 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12008 12009 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12010 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12011 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12012 12013 synchronized (this) { 12014 12015 // iterate across all processes 12016 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12017 ProcessRecord app = mLruProcesses.get(i); 12018 if (!allUsers && app.userId != userId) { 12019 continue; 12020 } 12021 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12022 // This one's in trouble, so we'll generate a report for it 12023 // crashes are higher priority (in case there's a crash *and* an anr) 12024 ActivityManager.ProcessErrorStateInfo report = null; 12025 if (app.crashing) { 12026 report = app.crashingReport; 12027 } else if (app.notResponding) { 12028 report = app.notRespondingReport; 12029 } 12030 12031 if (report != null) { 12032 if (errList == null) { 12033 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12034 } 12035 errList.add(report); 12036 } else { 12037 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12038 " crashing = " + app.crashing + 12039 " notResponding = " + app.notResponding); 12040 } 12041 } 12042 } 12043 } 12044 12045 return errList; 12046 } 12047 12048 static int procStateToImportance(int procState, int memAdj, 12049 ActivityManager.RunningAppProcessInfo currApp) { 12050 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12051 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12052 currApp.lru = memAdj; 12053 } else { 12054 currApp.lru = 0; 12055 } 12056 return imp; 12057 } 12058 12059 private void fillInProcMemInfo(ProcessRecord app, 12060 ActivityManager.RunningAppProcessInfo outInfo) { 12061 outInfo.pid = app.pid; 12062 outInfo.uid = app.info.uid; 12063 if (mHeavyWeightProcess == app) { 12064 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12065 } 12066 if (app.persistent) { 12067 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12068 } 12069 if (app.activities.size() > 0) { 12070 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12071 } 12072 outInfo.lastTrimLevel = app.trimMemoryLevel; 12073 int adj = app.curAdj; 12074 int procState = app.curProcState; 12075 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12076 outInfo.importanceReasonCode = app.adjTypeCode; 12077 outInfo.processState = app.curProcState; 12078 } 12079 12080 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12081 enforceNotIsolatedCaller("getRunningAppProcesses"); 12082 // Lazy instantiation of list 12083 List<ActivityManager.RunningAppProcessInfo> runList = null; 12084 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12085 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12086 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12087 synchronized (this) { 12088 // Iterate across all processes 12089 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12090 ProcessRecord app = mLruProcesses.get(i); 12091 if (!allUsers && app.userId != userId) { 12092 continue; 12093 } 12094 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12095 // Generate process state info for running application 12096 ActivityManager.RunningAppProcessInfo currApp = 12097 new ActivityManager.RunningAppProcessInfo(app.processName, 12098 app.pid, app.getPackageList()); 12099 fillInProcMemInfo(app, currApp); 12100 if (app.adjSource instanceof ProcessRecord) { 12101 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12102 currApp.importanceReasonImportance = 12103 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12104 app.adjSourceProcState); 12105 } else if (app.adjSource instanceof ActivityRecord) { 12106 ActivityRecord r = (ActivityRecord)app.adjSource; 12107 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12108 } 12109 if (app.adjTarget instanceof ComponentName) { 12110 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12111 } 12112 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12113 // + " lru=" + currApp.lru); 12114 if (runList == null) { 12115 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12116 } 12117 runList.add(currApp); 12118 } 12119 } 12120 } 12121 return runList; 12122 } 12123 12124 public List<ApplicationInfo> getRunningExternalApplications() { 12125 enforceNotIsolatedCaller("getRunningExternalApplications"); 12126 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12127 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12128 if (runningApps != null && runningApps.size() > 0) { 12129 Set<String> extList = new HashSet<String>(); 12130 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12131 if (app.pkgList != null) { 12132 for (String pkg : app.pkgList) { 12133 extList.add(pkg); 12134 } 12135 } 12136 } 12137 IPackageManager pm = AppGlobals.getPackageManager(); 12138 for (String pkg : extList) { 12139 try { 12140 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12141 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12142 retList.add(info); 12143 } 12144 } catch (RemoteException e) { 12145 } 12146 } 12147 } 12148 return retList; 12149 } 12150 12151 @Override 12152 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12153 enforceNotIsolatedCaller("getMyMemoryState"); 12154 synchronized (this) { 12155 ProcessRecord proc; 12156 synchronized (mPidsSelfLocked) { 12157 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12158 } 12159 fillInProcMemInfo(proc, outInfo); 12160 } 12161 } 12162 12163 @Override 12164 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12165 if (checkCallingPermission(android.Manifest.permission.DUMP) 12166 != PackageManager.PERMISSION_GRANTED) { 12167 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12168 + Binder.getCallingPid() 12169 + ", uid=" + Binder.getCallingUid() 12170 + " without permission " 12171 + android.Manifest.permission.DUMP); 12172 return; 12173 } 12174 12175 boolean dumpAll = false; 12176 boolean dumpClient = false; 12177 String dumpPackage = null; 12178 12179 int opti = 0; 12180 while (opti < args.length) { 12181 String opt = args[opti]; 12182 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12183 break; 12184 } 12185 opti++; 12186 if ("-a".equals(opt)) { 12187 dumpAll = true; 12188 } else if ("-c".equals(opt)) { 12189 dumpClient = true; 12190 } else if ("-h".equals(opt)) { 12191 pw.println("Activity manager dump options:"); 12192 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12193 pw.println(" cmd may be one of:"); 12194 pw.println(" a[ctivities]: activity stack state"); 12195 pw.println(" r[recents]: recent activities state"); 12196 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12197 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12198 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12199 pw.println(" o[om]: out of memory management"); 12200 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12201 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12202 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12203 pw.println(" service [COMP_SPEC]: service client-side state"); 12204 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12205 pw.println(" all: dump all activities"); 12206 pw.println(" top: dump the top activity"); 12207 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12208 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12209 pw.println(" a partial substring in a component name, a"); 12210 pw.println(" hex object identifier."); 12211 pw.println(" -a: include all available server state."); 12212 pw.println(" -c: include client state."); 12213 return; 12214 } else { 12215 pw.println("Unknown argument: " + opt + "; use -h for help"); 12216 } 12217 } 12218 12219 long origId = Binder.clearCallingIdentity(); 12220 boolean more = false; 12221 // Is the caller requesting to dump a particular piece of data? 12222 if (opti < args.length) { 12223 String cmd = args[opti]; 12224 opti++; 12225 if ("activities".equals(cmd) || "a".equals(cmd)) { 12226 synchronized (this) { 12227 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12228 } 12229 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12230 synchronized (this) { 12231 dumpRecentsLocked(fd, pw, args, opti, true, null); 12232 } 12233 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12234 String[] newArgs; 12235 String name; 12236 if (opti >= args.length) { 12237 name = null; 12238 newArgs = EMPTY_STRING_ARRAY; 12239 } else { 12240 name = args[opti]; 12241 opti++; 12242 newArgs = new String[args.length - opti]; 12243 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12244 args.length - opti); 12245 } 12246 synchronized (this) { 12247 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12248 } 12249 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12250 String[] newArgs; 12251 String name; 12252 if (opti >= args.length) { 12253 name = null; 12254 newArgs = EMPTY_STRING_ARRAY; 12255 } else { 12256 name = args[opti]; 12257 opti++; 12258 newArgs = new String[args.length - opti]; 12259 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12260 args.length - opti); 12261 } 12262 synchronized (this) { 12263 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12264 } 12265 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12266 String[] newArgs; 12267 String name; 12268 if (opti >= args.length) { 12269 name = null; 12270 newArgs = EMPTY_STRING_ARRAY; 12271 } else { 12272 name = args[opti]; 12273 opti++; 12274 newArgs = new String[args.length - opti]; 12275 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12276 args.length - opti); 12277 } 12278 synchronized (this) { 12279 dumpProcessesLocked(fd, pw, args, opti, true, name); 12280 } 12281 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12282 synchronized (this) { 12283 dumpOomLocked(fd, pw, args, opti, true); 12284 } 12285 } else if ("provider".equals(cmd)) { 12286 String[] newArgs; 12287 String name; 12288 if (opti >= args.length) { 12289 name = null; 12290 newArgs = EMPTY_STRING_ARRAY; 12291 } else { 12292 name = args[opti]; 12293 opti++; 12294 newArgs = new String[args.length - opti]; 12295 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12296 } 12297 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12298 pw.println("No providers match: " + name); 12299 pw.println("Use -h for help."); 12300 } 12301 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12302 synchronized (this) { 12303 dumpProvidersLocked(fd, pw, args, opti, true, null); 12304 } 12305 } else if ("service".equals(cmd)) { 12306 String[] newArgs; 12307 String name; 12308 if (opti >= args.length) { 12309 name = null; 12310 newArgs = EMPTY_STRING_ARRAY; 12311 } else { 12312 name = args[opti]; 12313 opti++; 12314 newArgs = new String[args.length - opti]; 12315 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12316 args.length - opti); 12317 } 12318 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12319 pw.println("No services match: " + name); 12320 pw.println("Use -h for help."); 12321 } 12322 } else if ("package".equals(cmd)) { 12323 String[] newArgs; 12324 if (opti >= args.length) { 12325 pw.println("package: no package name specified"); 12326 pw.println("Use -h for help."); 12327 } else { 12328 dumpPackage = args[opti]; 12329 opti++; 12330 newArgs = new String[args.length - opti]; 12331 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12332 args.length - opti); 12333 args = newArgs; 12334 opti = 0; 12335 more = true; 12336 } 12337 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12338 synchronized (this) { 12339 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12340 } 12341 } else { 12342 // Dumping a single activity? 12343 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12344 pw.println("Bad activity command, or no activities match: " + cmd); 12345 pw.println("Use -h for help."); 12346 } 12347 } 12348 if (!more) { 12349 Binder.restoreCallingIdentity(origId); 12350 return; 12351 } 12352 } 12353 12354 // No piece of data specified, dump everything. 12355 synchronized (this) { 12356 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12357 pw.println(); 12358 if (dumpAll) { 12359 pw.println("-------------------------------------------------------------------------------"); 12360 } 12361 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12362 pw.println(); 12363 if (dumpAll) { 12364 pw.println("-------------------------------------------------------------------------------"); 12365 } 12366 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12367 pw.println(); 12368 if (dumpAll) { 12369 pw.println("-------------------------------------------------------------------------------"); 12370 } 12371 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12372 pw.println(); 12373 if (dumpAll) { 12374 pw.println("-------------------------------------------------------------------------------"); 12375 } 12376 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12377 pw.println(); 12378 if (dumpAll) { 12379 pw.println("-------------------------------------------------------------------------------"); 12380 } 12381 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12382 pw.println(); 12383 if (dumpAll) { 12384 pw.println("-------------------------------------------------------------------------------"); 12385 } 12386 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12387 } 12388 Binder.restoreCallingIdentity(origId); 12389 } 12390 12391 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12392 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12393 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12394 12395 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12396 dumpPackage); 12397 boolean needSep = printedAnything; 12398 12399 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12400 dumpPackage, needSep, " mFocusedActivity: "); 12401 if (printed) { 12402 printedAnything = true; 12403 needSep = false; 12404 } 12405 12406 if (dumpPackage == null) { 12407 if (needSep) { 12408 pw.println(); 12409 } 12410 needSep = true; 12411 printedAnything = true; 12412 mStackSupervisor.dump(pw, " "); 12413 } 12414 12415 if (!printedAnything) { 12416 pw.println(" (nothing)"); 12417 } 12418 } 12419 12420 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12421 int opti, boolean dumpAll, String dumpPackage) { 12422 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12423 12424 boolean printedAnything = false; 12425 12426 if (mRecentTasks.size() > 0) { 12427 boolean printedHeader = false; 12428 12429 final int N = mRecentTasks.size(); 12430 for (int i=0; i<N; i++) { 12431 TaskRecord tr = mRecentTasks.get(i); 12432 if (dumpPackage != null) { 12433 if (tr.realActivity == null || 12434 !dumpPackage.equals(tr.realActivity)) { 12435 continue; 12436 } 12437 } 12438 if (!printedHeader) { 12439 pw.println(" Recent tasks:"); 12440 printedHeader = true; 12441 printedAnything = true; 12442 } 12443 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12444 pw.println(tr); 12445 if (dumpAll) { 12446 mRecentTasks.get(i).dump(pw, " "); 12447 } 12448 } 12449 } 12450 12451 if (!printedAnything) { 12452 pw.println(" (nothing)"); 12453 } 12454 } 12455 12456 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12457 int opti, boolean dumpAll, String dumpPackage) { 12458 boolean needSep = false; 12459 boolean printedAnything = false; 12460 int numPers = 0; 12461 12462 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12463 12464 if (dumpAll) { 12465 final int NP = mProcessNames.getMap().size(); 12466 for (int ip=0; ip<NP; ip++) { 12467 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12468 final int NA = procs.size(); 12469 for (int ia=0; ia<NA; ia++) { 12470 ProcessRecord r = procs.valueAt(ia); 12471 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12472 continue; 12473 } 12474 if (!needSep) { 12475 pw.println(" All known processes:"); 12476 needSep = true; 12477 printedAnything = true; 12478 } 12479 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12480 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12481 pw.print(" "); pw.println(r); 12482 r.dump(pw, " "); 12483 if (r.persistent) { 12484 numPers++; 12485 } 12486 } 12487 } 12488 } 12489 12490 if (mIsolatedProcesses.size() > 0) { 12491 boolean printed = false; 12492 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12493 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12494 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12495 continue; 12496 } 12497 if (!printed) { 12498 if (needSep) { 12499 pw.println(); 12500 } 12501 pw.println(" Isolated process list (sorted by uid):"); 12502 printedAnything = true; 12503 printed = true; 12504 needSep = true; 12505 } 12506 pw.println(String.format("%sIsolated #%2d: %s", 12507 " ", i, r.toString())); 12508 } 12509 } 12510 12511 if (mLruProcesses.size() > 0) { 12512 if (needSep) { 12513 pw.println(); 12514 } 12515 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12516 pw.print(" total, non-act at "); 12517 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12518 pw.print(", non-svc at "); 12519 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12520 pw.println("):"); 12521 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12522 needSep = true; 12523 printedAnything = true; 12524 } 12525 12526 if (dumpAll || dumpPackage != null) { 12527 synchronized (mPidsSelfLocked) { 12528 boolean printed = false; 12529 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12530 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12531 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12532 continue; 12533 } 12534 if (!printed) { 12535 if (needSep) pw.println(); 12536 needSep = true; 12537 pw.println(" PID mappings:"); 12538 printed = true; 12539 printedAnything = true; 12540 } 12541 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12542 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12543 } 12544 } 12545 } 12546 12547 if (mForegroundProcesses.size() > 0) { 12548 synchronized (mPidsSelfLocked) { 12549 boolean printed = false; 12550 for (int i=0; i<mForegroundProcesses.size(); i++) { 12551 ProcessRecord r = mPidsSelfLocked.get( 12552 mForegroundProcesses.valueAt(i).pid); 12553 if (dumpPackage != null && (r == null 12554 || !r.pkgList.containsKey(dumpPackage))) { 12555 continue; 12556 } 12557 if (!printed) { 12558 if (needSep) pw.println(); 12559 needSep = true; 12560 pw.println(" Foreground Processes:"); 12561 printed = true; 12562 printedAnything = true; 12563 } 12564 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12565 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12566 } 12567 } 12568 } 12569 12570 if (mPersistentStartingProcesses.size() > 0) { 12571 if (needSep) pw.println(); 12572 needSep = true; 12573 printedAnything = true; 12574 pw.println(" Persisent processes that are starting:"); 12575 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12576 "Starting Norm", "Restarting PERS", dumpPackage); 12577 } 12578 12579 if (mRemovedProcesses.size() > 0) { 12580 if (needSep) pw.println(); 12581 needSep = true; 12582 printedAnything = true; 12583 pw.println(" Processes that are being removed:"); 12584 dumpProcessList(pw, this, mRemovedProcesses, " ", 12585 "Removed Norm", "Removed PERS", dumpPackage); 12586 } 12587 12588 if (mProcessesOnHold.size() > 0) { 12589 if (needSep) pw.println(); 12590 needSep = true; 12591 printedAnything = true; 12592 pw.println(" Processes that are on old until the system is ready:"); 12593 dumpProcessList(pw, this, mProcessesOnHold, " ", 12594 "OnHold Norm", "OnHold PERS", dumpPackage); 12595 } 12596 12597 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12598 12599 if (mProcessCrashTimes.getMap().size() > 0) { 12600 boolean printed = false; 12601 long now = SystemClock.uptimeMillis(); 12602 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12603 final int NP = pmap.size(); 12604 for (int ip=0; ip<NP; ip++) { 12605 String pname = pmap.keyAt(ip); 12606 SparseArray<Long> uids = pmap.valueAt(ip); 12607 final int N = uids.size(); 12608 for (int i=0; i<N; i++) { 12609 int puid = uids.keyAt(i); 12610 ProcessRecord r = mProcessNames.get(pname, puid); 12611 if (dumpPackage != null && (r == null 12612 || !r.pkgList.containsKey(dumpPackage))) { 12613 continue; 12614 } 12615 if (!printed) { 12616 if (needSep) pw.println(); 12617 needSep = true; 12618 pw.println(" Time since processes crashed:"); 12619 printed = true; 12620 printedAnything = true; 12621 } 12622 pw.print(" Process "); pw.print(pname); 12623 pw.print(" uid "); pw.print(puid); 12624 pw.print(": last crashed "); 12625 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12626 pw.println(" ago"); 12627 } 12628 } 12629 } 12630 12631 if (mBadProcesses.getMap().size() > 0) { 12632 boolean printed = false; 12633 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12634 final int NP = pmap.size(); 12635 for (int ip=0; ip<NP; ip++) { 12636 String pname = pmap.keyAt(ip); 12637 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12638 final int N = uids.size(); 12639 for (int i=0; i<N; i++) { 12640 int puid = uids.keyAt(i); 12641 ProcessRecord r = mProcessNames.get(pname, puid); 12642 if (dumpPackage != null && (r == null 12643 || !r.pkgList.containsKey(dumpPackage))) { 12644 continue; 12645 } 12646 if (!printed) { 12647 if (needSep) pw.println(); 12648 needSep = true; 12649 pw.println(" Bad processes:"); 12650 printedAnything = true; 12651 } 12652 BadProcessInfo info = uids.valueAt(i); 12653 pw.print(" Bad process "); pw.print(pname); 12654 pw.print(" uid "); pw.print(puid); 12655 pw.print(": crashed at time "); pw.println(info.time); 12656 if (info.shortMsg != null) { 12657 pw.print(" Short msg: "); pw.println(info.shortMsg); 12658 } 12659 if (info.longMsg != null) { 12660 pw.print(" Long msg: "); pw.println(info.longMsg); 12661 } 12662 if (info.stack != null) { 12663 pw.println(" Stack:"); 12664 int lastPos = 0; 12665 for (int pos=0; pos<info.stack.length(); pos++) { 12666 if (info.stack.charAt(pos) == '\n') { 12667 pw.print(" "); 12668 pw.write(info.stack, lastPos, pos-lastPos); 12669 pw.println(); 12670 lastPos = pos+1; 12671 } 12672 } 12673 if (lastPos < info.stack.length()) { 12674 pw.print(" "); 12675 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12676 pw.println(); 12677 } 12678 } 12679 } 12680 } 12681 } 12682 12683 if (dumpPackage == null) { 12684 pw.println(); 12685 needSep = false; 12686 pw.println(" mStartedUsers:"); 12687 for (int i=0; i<mStartedUsers.size(); i++) { 12688 UserStartedState uss = mStartedUsers.valueAt(i); 12689 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12690 pw.print(": "); uss.dump("", pw); 12691 } 12692 pw.print(" mStartedUserArray: ["); 12693 for (int i=0; i<mStartedUserArray.length; i++) { 12694 if (i > 0) pw.print(", "); 12695 pw.print(mStartedUserArray[i]); 12696 } 12697 pw.println("]"); 12698 pw.print(" mUserLru: ["); 12699 for (int i=0; i<mUserLru.size(); i++) { 12700 if (i > 0) pw.print(", "); 12701 pw.print(mUserLru.get(i)); 12702 } 12703 pw.println("]"); 12704 if (dumpAll) { 12705 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12706 } 12707 synchronized (mUserProfileGroupIdsSelfLocked) { 12708 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12709 pw.println(" mUserProfileGroupIds:"); 12710 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12711 pw.print(" User #"); 12712 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12713 pw.print(" -> profile #"); 12714 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12715 } 12716 } 12717 } 12718 } 12719 if (mHomeProcess != null && (dumpPackage == null 12720 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12721 if (needSep) { 12722 pw.println(); 12723 needSep = false; 12724 } 12725 pw.println(" mHomeProcess: " + mHomeProcess); 12726 } 12727 if (mPreviousProcess != null && (dumpPackage == null 12728 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12729 if (needSep) { 12730 pw.println(); 12731 needSep = false; 12732 } 12733 pw.println(" mPreviousProcess: " + mPreviousProcess); 12734 } 12735 if (dumpAll) { 12736 StringBuilder sb = new StringBuilder(128); 12737 sb.append(" mPreviousProcessVisibleTime: "); 12738 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12739 pw.println(sb); 12740 } 12741 if (mHeavyWeightProcess != null && (dumpPackage == null 12742 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12743 if (needSep) { 12744 pw.println(); 12745 needSep = false; 12746 } 12747 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12748 } 12749 if (dumpPackage == null) { 12750 pw.println(" mConfiguration: " + mConfiguration); 12751 } 12752 if (dumpAll) { 12753 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12754 if (mCompatModePackages.getPackages().size() > 0) { 12755 boolean printed = false; 12756 for (Map.Entry<String, Integer> entry 12757 : mCompatModePackages.getPackages().entrySet()) { 12758 String pkg = entry.getKey(); 12759 int mode = entry.getValue(); 12760 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12761 continue; 12762 } 12763 if (!printed) { 12764 pw.println(" mScreenCompatPackages:"); 12765 printed = true; 12766 } 12767 pw.print(" "); pw.print(pkg); pw.print(": "); 12768 pw.print(mode); pw.println(); 12769 } 12770 } 12771 } 12772 if (dumpPackage == null) { 12773 if (mSleeping || mWentToSleep || mLockScreenShown) { 12774 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12775 + " mLockScreenShown " + mLockScreenShown); 12776 } 12777 if (mShuttingDown || mRunningVoice) { 12778 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12779 } 12780 } 12781 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12782 || mOrigWaitForDebugger) { 12783 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12784 || dumpPackage.equals(mOrigDebugApp)) { 12785 if (needSep) { 12786 pw.println(); 12787 needSep = false; 12788 } 12789 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12790 + " mDebugTransient=" + mDebugTransient 12791 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12792 } 12793 } 12794 if (mOpenGlTraceApp != null) { 12795 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12796 if (needSep) { 12797 pw.println(); 12798 needSep = false; 12799 } 12800 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12801 } 12802 } 12803 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12804 || mProfileFd != null) { 12805 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12806 if (needSep) { 12807 pw.println(); 12808 needSep = false; 12809 } 12810 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12811 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12812 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12813 + mAutoStopProfiler); 12814 pw.println(" mProfileType=" + mProfileType); 12815 } 12816 } 12817 if (dumpPackage == null) { 12818 if (mAlwaysFinishActivities || mController != null) { 12819 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12820 + " mController=" + mController); 12821 } 12822 if (dumpAll) { 12823 pw.println(" Total persistent processes: " + numPers); 12824 pw.println(" mProcessesReady=" + mProcessesReady 12825 + " mSystemReady=" + mSystemReady); 12826 pw.println(" mBooting=" + mBooting 12827 + " mBooted=" + mBooted 12828 + " mFactoryTest=" + mFactoryTest); 12829 pw.print(" mLastPowerCheckRealtime="); 12830 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12831 pw.println(""); 12832 pw.print(" mLastPowerCheckUptime="); 12833 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12834 pw.println(""); 12835 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12836 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12837 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12838 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12839 + " (" + mLruProcesses.size() + " total)" 12840 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12841 + " mNumServiceProcs=" + mNumServiceProcs 12842 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12843 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12844 + " mLastMemoryLevel" + mLastMemoryLevel 12845 + " mLastNumProcesses" + mLastNumProcesses); 12846 long now = SystemClock.uptimeMillis(); 12847 pw.print(" mLastIdleTime="); 12848 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12849 pw.print(" mLowRamSinceLastIdle="); 12850 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12851 pw.println(); 12852 } 12853 } 12854 12855 if (!printedAnything) { 12856 pw.println(" (nothing)"); 12857 } 12858 } 12859 12860 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12861 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12862 if (mProcessesToGc.size() > 0) { 12863 boolean printed = false; 12864 long now = SystemClock.uptimeMillis(); 12865 for (int i=0; i<mProcessesToGc.size(); i++) { 12866 ProcessRecord proc = mProcessesToGc.get(i); 12867 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12868 continue; 12869 } 12870 if (!printed) { 12871 if (needSep) pw.println(); 12872 needSep = true; 12873 pw.println(" Processes that are waiting to GC:"); 12874 printed = true; 12875 } 12876 pw.print(" Process "); pw.println(proc); 12877 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12878 pw.print(", last gced="); 12879 pw.print(now-proc.lastRequestedGc); 12880 pw.print(" ms ago, last lowMem="); 12881 pw.print(now-proc.lastLowMemory); 12882 pw.println(" ms ago"); 12883 12884 } 12885 } 12886 return needSep; 12887 } 12888 12889 void printOomLevel(PrintWriter pw, String name, int adj) { 12890 pw.print(" "); 12891 if (adj >= 0) { 12892 pw.print(' '); 12893 if (adj < 10) pw.print(' '); 12894 } else { 12895 if (adj > -10) pw.print(' '); 12896 } 12897 pw.print(adj); 12898 pw.print(": "); 12899 pw.print(name); 12900 pw.print(" ("); 12901 pw.print(mProcessList.getMemLevel(adj)/1024); 12902 pw.println(" kB)"); 12903 } 12904 12905 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12906 int opti, boolean dumpAll) { 12907 boolean needSep = false; 12908 12909 if (mLruProcesses.size() > 0) { 12910 if (needSep) pw.println(); 12911 needSep = true; 12912 pw.println(" OOM levels:"); 12913 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12914 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12915 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12916 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12917 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12918 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12919 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12920 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12921 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12922 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12923 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12924 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12925 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12926 12927 if (needSep) pw.println(); 12928 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12929 pw.print(" total, non-act at "); 12930 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12931 pw.print(", non-svc at "); 12932 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12933 pw.println("):"); 12934 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12935 needSep = true; 12936 } 12937 12938 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12939 12940 pw.println(); 12941 pw.println(" mHomeProcess: " + mHomeProcess); 12942 pw.println(" mPreviousProcess: " + mPreviousProcess); 12943 if (mHeavyWeightProcess != null) { 12944 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12945 } 12946 12947 return true; 12948 } 12949 12950 /** 12951 * There are three ways to call this: 12952 * - no provider specified: dump all the providers 12953 * - a flattened component name that matched an existing provider was specified as the 12954 * first arg: dump that one provider 12955 * - the first arg isn't the flattened component name of an existing provider: 12956 * dump all providers whose component contains the first arg as a substring 12957 */ 12958 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12959 int opti, boolean dumpAll) { 12960 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12961 } 12962 12963 static class ItemMatcher { 12964 ArrayList<ComponentName> components; 12965 ArrayList<String> strings; 12966 ArrayList<Integer> objects; 12967 boolean all; 12968 12969 ItemMatcher() { 12970 all = true; 12971 } 12972 12973 void build(String name) { 12974 ComponentName componentName = ComponentName.unflattenFromString(name); 12975 if (componentName != null) { 12976 if (components == null) { 12977 components = new ArrayList<ComponentName>(); 12978 } 12979 components.add(componentName); 12980 all = false; 12981 } else { 12982 int objectId = 0; 12983 // Not a '/' separated full component name; maybe an object ID? 12984 try { 12985 objectId = Integer.parseInt(name, 16); 12986 if (objects == null) { 12987 objects = new ArrayList<Integer>(); 12988 } 12989 objects.add(objectId); 12990 all = false; 12991 } catch (RuntimeException e) { 12992 // Not an integer; just do string match. 12993 if (strings == null) { 12994 strings = new ArrayList<String>(); 12995 } 12996 strings.add(name); 12997 all = false; 12998 } 12999 } 13000 } 13001 13002 int build(String[] args, int opti) { 13003 for (; opti<args.length; opti++) { 13004 String name = args[opti]; 13005 if ("--".equals(name)) { 13006 return opti+1; 13007 } 13008 build(name); 13009 } 13010 return opti; 13011 } 13012 13013 boolean match(Object object, ComponentName comp) { 13014 if (all) { 13015 return true; 13016 } 13017 if (components != null) { 13018 for (int i=0; i<components.size(); i++) { 13019 if (components.get(i).equals(comp)) { 13020 return true; 13021 } 13022 } 13023 } 13024 if (objects != null) { 13025 for (int i=0; i<objects.size(); i++) { 13026 if (System.identityHashCode(object) == objects.get(i)) { 13027 return true; 13028 } 13029 } 13030 } 13031 if (strings != null) { 13032 String flat = comp.flattenToString(); 13033 for (int i=0; i<strings.size(); i++) { 13034 if (flat.contains(strings.get(i))) { 13035 return true; 13036 } 13037 } 13038 } 13039 return false; 13040 } 13041 } 13042 13043 /** 13044 * There are three things that cmd can be: 13045 * - a flattened component name that matches an existing activity 13046 * - the cmd arg isn't the flattened component name of an existing activity: 13047 * dump all activity whose component contains the cmd as a substring 13048 * - A hex number of the ActivityRecord object instance. 13049 */ 13050 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13051 int opti, boolean dumpAll) { 13052 ArrayList<ActivityRecord> activities; 13053 13054 synchronized (this) { 13055 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13056 } 13057 13058 if (activities.size() <= 0) { 13059 return false; 13060 } 13061 13062 String[] newArgs = new String[args.length - opti]; 13063 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13064 13065 TaskRecord lastTask = null; 13066 boolean needSep = false; 13067 for (int i=activities.size()-1; i>=0; i--) { 13068 ActivityRecord r = activities.get(i); 13069 if (needSep) { 13070 pw.println(); 13071 } 13072 needSep = true; 13073 synchronized (this) { 13074 if (lastTask != r.task) { 13075 lastTask = r.task; 13076 pw.print("TASK "); pw.print(lastTask.affinity); 13077 pw.print(" id="); pw.println(lastTask.taskId); 13078 if (dumpAll) { 13079 lastTask.dump(pw, " "); 13080 } 13081 } 13082 } 13083 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13084 } 13085 return true; 13086 } 13087 13088 /** 13089 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13090 * there is a thread associated with the activity. 13091 */ 13092 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13093 final ActivityRecord r, String[] args, boolean dumpAll) { 13094 String innerPrefix = prefix + " "; 13095 synchronized (this) { 13096 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13097 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13098 pw.print(" pid="); 13099 if (r.app != null) pw.println(r.app.pid); 13100 else pw.println("(not running)"); 13101 if (dumpAll) { 13102 r.dump(pw, innerPrefix); 13103 } 13104 } 13105 if (r.app != null && r.app.thread != null) { 13106 // flush anything that is already in the PrintWriter since the thread is going 13107 // to write to the file descriptor directly 13108 pw.flush(); 13109 try { 13110 TransferPipe tp = new TransferPipe(); 13111 try { 13112 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13113 r.appToken, innerPrefix, args); 13114 tp.go(fd); 13115 } finally { 13116 tp.kill(); 13117 } 13118 } catch (IOException e) { 13119 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13120 } catch (RemoteException e) { 13121 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13122 } 13123 } 13124 } 13125 13126 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13127 int opti, boolean dumpAll, String dumpPackage) { 13128 boolean needSep = false; 13129 boolean onlyHistory = false; 13130 boolean printedAnything = false; 13131 13132 if ("history".equals(dumpPackage)) { 13133 if (opti < args.length && "-s".equals(args[opti])) { 13134 dumpAll = false; 13135 } 13136 onlyHistory = true; 13137 dumpPackage = null; 13138 } 13139 13140 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13141 if (!onlyHistory && dumpAll) { 13142 if (mRegisteredReceivers.size() > 0) { 13143 boolean printed = false; 13144 Iterator it = mRegisteredReceivers.values().iterator(); 13145 while (it.hasNext()) { 13146 ReceiverList r = (ReceiverList)it.next(); 13147 if (dumpPackage != null && (r.app == null || 13148 !dumpPackage.equals(r.app.info.packageName))) { 13149 continue; 13150 } 13151 if (!printed) { 13152 pw.println(" Registered Receivers:"); 13153 needSep = true; 13154 printed = true; 13155 printedAnything = true; 13156 } 13157 pw.print(" * "); pw.println(r); 13158 r.dump(pw, " "); 13159 } 13160 } 13161 13162 if (mReceiverResolver.dump(pw, needSep ? 13163 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13164 " ", dumpPackage, false)) { 13165 needSep = true; 13166 printedAnything = true; 13167 } 13168 } 13169 13170 for (BroadcastQueue q : mBroadcastQueues) { 13171 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13172 printedAnything |= needSep; 13173 } 13174 13175 needSep = true; 13176 13177 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13178 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13179 if (needSep) { 13180 pw.println(); 13181 } 13182 needSep = true; 13183 printedAnything = true; 13184 pw.print(" Sticky broadcasts for user "); 13185 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13186 StringBuilder sb = new StringBuilder(128); 13187 for (Map.Entry<String, ArrayList<Intent>> ent 13188 : mStickyBroadcasts.valueAt(user).entrySet()) { 13189 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13190 if (dumpAll) { 13191 pw.println(":"); 13192 ArrayList<Intent> intents = ent.getValue(); 13193 final int N = intents.size(); 13194 for (int i=0; i<N; i++) { 13195 sb.setLength(0); 13196 sb.append(" Intent: "); 13197 intents.get(i).toShortString(sb, false, true, false, false); 13198 pw.println(sb.toString()); 13199 Bundle bundle = intents.get(i).getExtras(); 13200 if (bundle != null) { 13201 pw.print(" "); 13202 pw.println(bundle.toString()); 13203 } 13204 } 13205 } else { 13206 pw.println(""); 13207 } 13208 } 13209 } 13210 } 13211 13212 if (!onlyHistory && dumpAll) { 13213 pw.println(); 13214 for (BroadcastQueue queue : mBroadcastQueues) { 13215 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13216 + queue.mBroadcastsScheduled); 13217 } 13218 pw.println(" mHandler:"); 13219 mHandler.dump(new PrintWriterPrinter(pw), " "); 13220 needSep = true; 13221 printedAnything = true; 13222 } 13223 13224 if (!printedAnything) { 13225 pw.println(" (nothing)"); 13226 } 13227 } 13228 13229 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13230 int opti, boolean dumpAll, String dumpPackage) { 13231 boolean needSep; 13232 boolean printedAnything = false; 13233 13234 ItemMatcher matcher = new ItemMatcher(); 13235 matcher.build(args, opti); 13236 13237 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13238 13239 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13240 printedAnything |= needSep; 13241 13242 if (mLaunchingProviders.size() > 0) { 13243 boolean printed = false; 13244 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13245 ContentProviderRecord r = mLaunchingProviders.get(i); 13246 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13247 continue; 13248 } 13249 if (!printed) { 13250 if (needSep) pw.println(); 13251 needSep = true; 13252 pw.println(" Launching content providers:"); 13253 printed = true; 13254 printedAnything = true; 13255 } 13256 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13257 pw.println(r); 13258 } 13259 } 13260 13261 if (mGrantedUriPermissions.size() > 0) { 13262 boolean printed = false; 13263 int dumpUid = -2; 13264 if (dumpPackage != null) { 13265 try { 13266 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13267 } catch (NameNotFoundException e) { 13268 dumpUid = -1; 13269 } 13270 } 13271 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13272 int uid = mGrantedUriPermissions.keyAt(i); 13273 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13274 continue; 13275 } 13276 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13277 if (!printed) { 13278 if (needSep) pw.println(); 13279 needSep = true; 13280 pw.println(" Granted Uri Permissions:"); 13281 printed = true; 13282 printedAnything = true; 13283 } 13284 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13285 for (UriPermission perm : perms.values()) { 13286 pw.print(" "); pw.println(perm); 13287 if (dumpAll) { 13288 perm.dump(pw, " "); 13289 } 13290 } 13291 } 13292 } 13293 13294 if (!printedAnything) { 13295 pw.println(" (nothing)"); 13296 } 13297 } 13298 13299 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13300 int opti, boolean dumpAll, String dumpPackage) { 13301 boolean printed = false; 13302 13303 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13304 13305 if (mIntentSenderRecords.size() > 0) { 13306 Iterator<WeakReference<PendingIntentRecord>> it 13307 = mIntentSenderRecords.values().iterator(); 13308 while (it.hasNext()) { 13309 WeakReference<PendingIntentRecord> ref = it.next(); 13310 PendingIntentRecord rec = ref != null ? ref.get(): null; 13311 if (dumpPackage != null && (rec == null 13312 || !dumpPackage.equals(rec.key.packageName))) { 13313 continue; 13314 } 13315 printed = true; 13316 if (rec != null) { 13317 pw.print(" * "); pw.println(rec); 13318 if (dumpAll) { 13319 rec.dump(pw, " "); 13320 } 13321 } else { 13322 pw.print(" * "); pw.println(ref); 13323 } 13324 } 13325 } 13326 13327 if (!printed) { 13328 pw.println(" (nothing)"); 13329 } 13330 } 13331 13332 private static final int dumpProcessList(PrintWriter pw, 13333 ActivityManagerService service, List list, 13334 String prefix, String normalLabel, String persistentLabel, 13335 String dumpPackage) { 13336 int numPers = 0; 13337 final int N = list.size()-1; 13338 for (int i=N; i>=0; i--) { 13339 ProcessRecord r = (ProcessRecord)list.get(i); 13340 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13341 continue; 13342 } 13343 pw.println(String.format("%s%s #%2d: %s", 13344 prefix, (r.persistent ? persistentLabel : normalLabel), 13345 i, r.toString())); 13346 if (r.persistent) { 13347 numPers++; 13348 } 13349 } 13350 return numPers; 13351 } 13352 13353 private static final boolean dumpProcessOomList(PrintWriter pw, 13354 ActivityManagerService service, List<ProcessRecord> origList, 13355 String prefix, String normalLabel, String persistentLabel, 13356 boolean inclDetails, String dumpPackage) { 13357 13358 ArrayList<Pair<ProcessRecord, Integer>> list 13359 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13360 for (int i=0; i<origList.size(); i++) { 13361 ProcessRecord r = origList.get(i); 13362 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13363 continue; 13364 } 13365 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13366 } 13367 13368 if (list.size() <= 0) { 13369 return false; 13370 } 13371 13372 Comparator<Pair<ProcessRecord, Integer>> comparator 13373 = new Comparator<Pair<ProcessRecord, Integer>>() { 13374 @Override 13375 public int compare(Pair<ProcessRecord, Integer> object1, 13376 Pair<ProcessRecord, Integer> object2) { 13377 if (object1.first.setAdj != object2.first.setAdj) { 13378 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13379 } 13380 if (object1.second.intValue() != object2.second.intValue()) { 13381 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13382 } 13383 return 0; 13384 } 13385 }; 13386 13387 Collections.sort(list, comparator); 13388 13389 final long curRealtime = SystemClock.elapsedRealtime(); 13390 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13391 final long curUptime = SystemClock.uptimeMillis(); 13392 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13393 13394 for (int i=list.size()-1; i>=0; i--) { 13395 ProcessRecord r = list.get(i).first; 13396 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13397 char schedGroup; 13398 switch (r.setSchedGroup) { 13399 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13400 schedGroup = 'B'; 13401 break; 13402 case Process.THREAD_GROUP_DEFAULT: 13403 schedGroup = 'F'; 13404 break; 13405 default: 13406 schedGroup = '?'; 13407 break; 13408 } 13409 char foreground; 13410 if (r.foregroundActivities) { 13411 foreground = 'A'; 13412 } else if (r.foregroundServices) { 13413 foreground = 'S'; 13414 } else { 13415 foreground = ' '; 13416 } 13417 String procState = ProcessList.makeProcStateString(r.curProcState); 13418 pw.print(prefix); 13419 pw.print(r.persistent ? persistentLabel : normalLabel); 13420 pw.print(" #"); 13421 int num = (origList.size()-1)-list.get(i).second; 13422 if (num < 10) pw.print(' '); 13423 pw.print(num); 13424 pw.print(": "); 13425 pw.print(oomAdj); 13426 pw.print(' '); 13427 pw.print(schedGroup); 13428 pw.print('/'); 13429 pw.print(foreground); 13430 pw.print('/'); 13431 pw.print(procState); 13432 pw.print(" trm:"); 13433 if (r.trimMemoryLevel < 10) pw.print(' '); 13434 pw.print(r.trimMemoryLevel); 13435 pw.print(' '); 13436 pw.print(r.toShortString()); 13437 pw.print(" ("); 13438 pw.print(r.adjType); 13439 pw.println(')'); 13440 if (r.adjSource != null || r.adjTarget != null) { 13441 pw.print(prefix); 13442 pw.print(" "); 13443 if (r.adjTarget instanceof ComponentName) { 13444 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13445 } else if (r.adjTarget != null) { 13446 pw.print(r.adjTarget.toString()); 13447 } else { 13448 pw.print("{null}"); 13449 } 13450 pw.print("<="); 13451 if (r.adjSource instanceof ProcessRecord) { 13452 pw.print("Proc{"); 13453 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13454 pw.println("}"); 13455 } else if (r.adjSource != null) { 13456 pw.println(r.adjSource.toString()); 13457 } else { 13458 pw.println("{null}"); 13459 } 13460 } 13461 if (inclDetails) { 13462 pw.print(prefix); 13463 pw.print(" "); 13464 pw.print("oom: max="); pw.print(r.maxAdj); 13465 pw.print(" curRaw="); pw.print(r.curRawAdj); 13466 pw.print(" setRaw="); pw.print(r.setRawAdj); 13467 pw.print(" cur="); pw.print(r.curAdj); 13468 pw.print(" set="); pw.println(r.setAdj); 13469 pw.print(prefix); 13470 pw.print(" "); 13471 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13472 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13473 pw.print(" lastPss="); pw.print(r.lastPss); 13474 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13475 pw.print(prefix); 13476 pw.print(" "); 13477 pw.print("cached="); pw.print(r.cached); 13478 pw.print(" empty="); pw.print(r.empty); 13479 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13480 13481 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13482 if (r.lastWakeTime != 0) { 13483 long wtime; 13484 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13485 synchronized (stats) { 13486 wtime = stats.getProcessWakeTime(r.info.uid, 13487 r.pid, curRealtime); 13488 } 13489 long timeUsed = wtime - r.lastWakeTime; 13490 pw.print(prefix); 13491 pw.print(" "); 13492 pw.print("keep awake over "); 13493 TimeUtils.formatDuration(realtimeSince, pw); 13494 pw.print(" used "); 13495 TimeUtils.formatDuration(timeUsed, pw); 13496 pw.print(" ("); 13497 pw.print((timeUsed*100)/realtimeSince); 13498 pw.println("%)"); 13499 } 13500 if (r.lastCpuTime != 0) { 13501 long timeUsed = r.curCpuTime - r.lastCpuTime; 13502 pw.print(prefix); 13503 pw.print(" "); 13504 pw.print("run cpu over "); 13505 TimeUtils.formatDuration(uptimeSince, pw); 13506 pw.print(" used "); 13507 TimeUtils.formatDuration(timeUsed, pw); 13508 pw.print(" ("); 13509 pw.print((timeUsed*100)/uptimeSince); 13510 pw.println("%)"); 13511 } 13512 } 13513 } 13514 } 13515 return true; 13516 } 13517 13518 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13519 ArrayList<ProcessRecord> procs; 13520 synchronized (this) { 13521 if (args != null && args.length > start 13522 && args[start].charAt(0) != '-') { 13523 procs = new ArrayList<ProcessRecord>(); 13524 int pid = -1; 13525 try { 13526 pid = Integer.parseInt(args[start]); 13527 } catch (NumberFormatException e) { 13528 } 13529 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13530 ProcessRecord proc = mLruProcesses.get(i); 13531 if (proc.pid == pid) { 13532 procs.add(proc); 13533 } else if (proc.processName.equals(args[start])) { 13534 procs.add(proc); 13535 } 13536 } 13537 if (procs.size() <= 0) { 13538 return null; 13539 } 13540 } else { 13541 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13542 } 13543 } 13544 return procs; 13545 } 13546 13547 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13548 PrintWriter pw, String[] args) { 13549 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13550 if (procs == null) { 13551 pw.println("No process found for: " + args[0]); 13552 return; 13553 } 13554 13555 long uptime = SystemClock.uptimeMillis(); 13556 long realtime = SystemClock.elapsedRealtime(); 13557 pw.println("Applications Graphics Acceleration Info:"); 13558 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13559 13560 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13561 ProcessRecord r = procs.get(i); 13562 if (r.thread != null) { 13563 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13564 pw.flush(); 13565 try { 13566 TransferPipe tp = new TransferPipe(); 13567 try { 13568 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13569 tp.go(fd); 13570 } finally { 13571 tp.kill(); 13572 } 13573 } catch (IOException e) { 13574 pw.println("Failure while dumping the app: " + r); 13575 pw.flush(); 13576 } catch (RemoteException e) { 13577 pw.println("Got a RemoteException while dumping the app " + r); 13578 pw.flush(); 13579 } 13580 } 13581 } 13582 } 13583 13584 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13585 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13586 if (procs == null) { 13587 pw.println("No process found for: " + args[0]); 13588 return; 13589 } 13590 13591 pw.println("Applications Database Info:"); 13592 13593 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13594 ProcessRecord r = procs.get(i); 13595 if (r.thread != null) { 13596 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13597 pw.flush(); 13598 try { 13599 TransferPipe tp = new TransferPipe(); 13600 try { 13601 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13602 tp.go(fd); 13603 } finally { 13604 tp.kill(); 13605 } 13606 } catch (IOException e) { 13607 pw.println("Failure while dumping the app: " + r); 13608 pw.flush(); 13609 } catch (RemoteException e) { 13610 pw.println("Got a RemoteException while dumping the app " + r); 13611 pw.flush(); 13612 } 13613 } 13614 } 13615 } 13616 13617 final static class MemItem { 13618 final boolean isProc; 13619 final String label; 13620 final String shortLabel; 13621 final long pss; 13622 final int id; 13623 final boolean hasActivities; 13624 ArrayList<MemItem> subitems; 13625 13626 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13627 boolean _hasActivities) { 13628 isProc = true; 13629 label = _label; 13630 shortLabel = _shortLabel; 13631 pss = _pss; 13632 id = _id; 13633 hasActivities = _hasActivities; 13634 } 13635 13636 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13637 isProc = false; 13638 label = _label; 13639 shortLabel = _shortLabel; 13640 pss = _pss; 13641 id = _id; 13642 hasActivities = false; 13643 } 13644 } 13645 13646 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13647 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13648 if (sort && !isCompact) { 13649 Collections.sort(items, new Comparator<MemItem>() { 13650 @Override 13651 public int compare(MemItem lhs, MemItem rhs) { 13652 if (lhs.pss < rhs.pss) { 13653 return 1; 13654 } else if (lhs.pss > rhs.pss) { 13655 return -1; 13656 } 13657 return 0; 13658 } 13659 }); 13660 } 13661 13662 for (int i=0; i<items.size(); i++) { 13663 MemItem mi = items.get(i); 13664 if (!isCompact) { 13665 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13666 } else if (mi.isProc) { 13667 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13668 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13669 pw.println(mi.hasActivities ? ",a" : ",e"); 13670 } else { 13671 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13672 pw.println(mi.pss); 13673 } 13674 if (mi.subitems != null) { 13675 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13676 true, isCompact); 13677 } 13678 } 13679 } 13680 13681 // These are in KB. 13682 static final long[] DUMP_MEM_BUCKETS = new long[] { 13683 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13684 120*1024, 160*1024, 200*1024, 13685 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13686 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13687 }; 13688 13689 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13690 boolean stackLike) { 13691 int start = label.lastIndexOf('.'); 13692 if (start >= 0) start++; 13693 else start = 0; 13694 int end = label.length(); 13695 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13696 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13697 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13698 out.append(bucket); 13699 out.append(stackLike ? "MB." : "MB "); 13700 out.append(label, start, end); 13701 return; 13702 } 13703 } 13704 out.append(memKB/1024); 13705 out.append(stackLike ? "MB." : "MB "); 13706 out.append(label, start, end); 13707 } 13708 13709 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13710 ProcessList.NATIVE_ADJ, 13711 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13712 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13713 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13714 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13715 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13716 }; 13717 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13718 "Native", 13719 "System", "Persistent", "Foreground", 13720 "Visible", "Perceptible", 13721 "Heavy Weight", "Backup", 13722 "A Services", "Home", 13723 "Previous", "B Services", "Cached" 13724 }; 13725 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13726 "native", 13727 "sys", "pers", "fore", 13728 "vis", "percept", 13729 "heavy", "backup", 13730 "servicea", "home", 13731 "prev", "serviceb", "cached" 13732 }; 13733 13734 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13735 long realtime, boolean isCheckinRequest, boolean isCompact) { 13736 if (isCheckinRequest || isCompact) { 13737 // short checkin version 13738 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13739 } else { 13740 pw.println("Applications Memory Usage (kB):"); 13741 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13742 } 13743 } 13744 13745 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13746 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13747 boolean dumpDetails = false; 13748 boolean dumpFullDetails = false; 13749 boolean dumpDalvik = false; 13750 boolean oomOnly = false; 13751 boolean isCompact = false; 13752 boolean localOnly = false; 13753 13754 int opti = 0; 13755 while (opti < args.length) { 13756 String opt = args[opti]; 13757 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13758 break; 13759 } 13760 opti++; 13761 if ("-a".equals(opt)) { 13762 dumpDetails = true; 13763 dumpFullDetails = true; 13764 dumpDalvik = true; 13765 } else if ("-d".equals(opt)) { 13766 dumpDalvik = true; 13767 } else if ("-c".equals(opt)) { 13768 isCompact = true; 13769 } else if ("--oom".equals(opt)) { 13770 oomOnly = true; 13771 } else if ("--local".equals(opt)) { 13772 localOnly = true; 13773 } else if ("-h".equals(opt)) { 13774 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13775 pw.println(" -a: include all available information for each process."); 13776 pw.println(" -d: include dalvik details when dumping process details."); 13777 pw.println(" -c: dump in a compact machine-parseable representation."); 13778 pw.println(" --oom: only show processes organized by oom adj."); 13779 pw.println(" --local: only collect details locally, don't call process."); 13780 pw.println("If [process] is specified it can be the name or "); 13781 pw.println("pid of a specific process to dump."); 13782 return; 13783 } else { 13784 pw.println("Unknown argument: " + opt + "; use -h for help"); 13785 } 13786 } 13787 13788 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13789 long uptime = SystemClock.uptimeMillis(); 13790 long realtime = SystemClock.elapsedRealtime(); 13791 final long[] tmpLong = new long[1]; 13792 13793 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13794 if (procs == null) { 13795 // No Java processes. Maybe they want to print a native process. 13796 if (args != null && args.length > opti 13797 && args[opti].charAt(0) != '-') { 13798 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13799 = new ArrayList<ProcessCpuTracker.Stats>(); 13800 updateCpuStatsNow(); 13801 int findPid = -1; 13802 try { 13803 findPid = Integer.parseInt(args[opti]); 13804 } catch (NumberFormatException e) { 13805 } 13806 synchronized (mProcessCpuTracker) { 13807 final int N = mProcessCpuTracker.countStats(); 13808 for (int i=0; i<N; i++) { 13809 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13810 if (st.pid == findPid || (st.baseName != null 13811 && st.baseName.equals(args[opti]))) { 13812 nativeProcs.add(st); 13813 } 13814 } 13815 } 13816 if (nativeProcs.size() > 0) { 13817 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13818 isCompact); 13819 Debug.MemoryInfo mi = null; 13820 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13821 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13822 final int pid = r.pid; 13823 if (!isCheckinRequest && dumpDetails) { 13824 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13825 } 13826 if (mi == null) { 13827 mi = new Debug.MemoryInfo(); 13828 } 13829 if (dumpDetails || (!brief && !oomOnly)) { 13830 Debug.getMemoryInfo(pid, mi); 13831 } else { 13832 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13833 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13834 } 13835 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13836 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13837 if (isCheckinRequest) { 13838 pw.println(); 13839 } 13840 } 13841 return; 13842 } 13843 } 13844 pw.println("No process found for: " + args[opti]); 13845 return; 13846 } 13847 13848 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13849 dumpDetails = true; 13850 } 13851 13852 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13853 13854 String[] innerArgs = new String[args.length-opti]; 13855 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13856 13857 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13858 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13859 long nativePss=0, dalvikPss=0, otherPss=0; 13860 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13861 13862 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13863 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13864 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13865 13866 long totalPss = 0; 13867 long cachedPss = 0; 13868 13869 Debug.MemoryInfo mi = null; 13870 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13871 final ProcessRecord r = procs.get(i); 13872 final IApplicationThread thread; 13873 final int pid; 13874 final int oomAdj; 13875 final boolean hasActivities; 13876 synchronized (this) { 13877 thread = r.thread; 13878 pid = r.pid; 13879 oomAdj = r.getSetAdjWithServices(); 13880 hasActivities = r.activities.size() > 0; 13881 } 13882 if (thread != null) { 13883 if (!isCheckinRequest && dumpDetails) { 13884 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13885 } 13886 if (mi == null) { 13887 mi = new Debug.MemoryInfo(); 13888 } 13889 if (dumpDetails || (!brief && !oomOnly)) { 13890 Debug.getMemoryInfo(pid, mi); 13891 } else { 13892 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13893 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13894 } 13895 if (dumpDetails) { 13896 if (localOnly) { 13897 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13898 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13899 if (isCheckinRequest) { 13900 pw.println(); 13901 } 13902 } else { 13903 try { 13904 pw.flush(); 13905 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13906 dumpDalvik, innerArgs); 13907 } catch (RemoteException e) { 13908 if (!isCheckinRequest) { 13909 pw.println("Got RemoteException!"); 13910 pw.flush(); 13911 } 13912 } 13913 } 13914 } 13915 13916 final long myTotalPss = mi.getTotalPss(); 13917 final long myTotalUss = mi.getTotalUss(); 13918 13919 synchronized (this) { 13920 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13921 // Record this for posterity if the process has been stable. 13922 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13923 } 13924 } 13925 13926 if (!isCheckinRequest && mi != null) { 13927 totalPss += myTotalPss; 13928 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13929 (hasActivities ? " / activities)" : ")"), 13930 r.processName, myTotalPss, pid, hasActivities); 13931 procMems.add(pssItem); 13932 procMemsMap.put(pid, pssItem); 13933 13934 nativePss += mi.nativePss; 13935 dalvikPss += mi.dalvikPss; 13936 otherPss += mi.otherPss; 13937 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13938 long mem = mi.getOtherPss(j); 13939 miscPss[j] += mem; 13940 otherPss -= mem; 13941 } 13942 13943 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13944 cachedPss += myTotalPss; 13945 } 13946 13947 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13948 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13949 || oomIndex == (oomPss.length-1)) { 13950 oomPss[oomIndex] += myTotalPss; 13951 if (oomProcs[oomIndex] == null) { 13952 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13953 } 13954 oomProcs[oomIndex].add(pssItem); 13955 break; 13956 } 13957 } 13958 } 13959 } 13960 } 13961 13962 long nativeProcTotalPss = 0; 13963 13964 if (!isCheckinRequest && procs.size() > 1) { 13965 // If we are showing aggregations, also look for native processes to 13966 // include so that our aggregations are more accurate. 13967 updateCpuStatsNow(); 13968 synchronized (mProcessCpuTracker) { 13969 final int N = mProcessCpuTracker.countStats(); 13970 for (int i=0; i<N; i++) { 13971 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13972 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13973 if (mi == null) { 13974 mi = new Debug.MemoryInfo(); 13975 } 13976 if (!brief && !oomOnly) { 13977 Debug.getMemoryInfo(st.pid, mi); 13978 } else { 13979 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13980 mi.nativePrivateDirty = (int)tmpLong[0]; 13981 } 13982 13983 final long myTotalPss = mi.getTotalPss(); 13984 totalPss += myTotalPss; 13985 nativeProcTotalPss += myTotalPss; 13986 13987 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13988 st.name, myTotalPss, st.pid, false); 13989 procMems.add(pssItem); 13990 13991 nativePss += mi.nativePss; 13992 dalvikPss += mi.dalvikPss; 13993 otherPss += mi.otherPss; 13994 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13995 long mem = mi.getOtherPss(j); 13996 miscPss[j] += mem; 13997 otherPss -= mem; 13998 } 13999 oomPss[0] += myTotalPss; 14000 if (oomProcs[0] == null) { 14001 oomProcs[0] = new ArrayList<MemItem>(); 14002 } 14003 oomProcs[0].add(pssItem); 14004 } 14005 } 14006 } 14007 14008 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14009 14010 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14011 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14012 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14013 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14014 String label = Debug.MemoryInfo.getOtherLabel(j); 14015 catMems.add(new MemItem(label, label, miscPss[j], j)); 14016 } 14017 14018 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14019 for (int j=0; j<oomPss.length; j++) { 14020 if (oomPss[j] != 0) { 14021 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14022 : DUMP_MEM_OOM_LABEL[j]; 14023 MemItem item = new MemItem(label, label, oomPss[j], 14024 DUMP_MEM_OOM_ADJ[j]); 14025 item.subitems = oomProcs[j]; 14026 oomMems.add(item); 14027 } 14028 } 14029 14030 if (!brief && !oomOnly && !isCompact) { 14031 pw.println(); 14032 pw.println("Total PSS by process:"); 14033 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14034 pw.println(); 14035 } 14036 if (!isCompact) { 14037 pw.println("Total PSS by OOM adjustment:"); 14038 } 14039 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14040 if (!brief && !oomOnly) { 14041 PrintWriter out = categoryPw != null ? categoryPw : pw; 14042 if (!isCompact) { 14043 out.println(); 14044 out.println("Total PSS by category:"); 14045 } 14046 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14047 } 14048 if (!isCompact) { 14049 pw.println(); 14050 } 14051 MemInfoReader memInfo = new MemInfoReader(); 14052 memInfo.readMemInfo(); 14053 if (nativeProcTotalPss > 0) { 14054 synchronized (this) { 14055 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14056 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14057 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14058 nativeProcTotalPss); 14059 } 14060 } 14061 if (!brief) { 14062 if (!isCompact) { 14063 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14064 pw.print(" kB (status "); 14065 switch (mLastMemoryLevel) { 14066 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14067 pw.println("normal)"); 14068 break; 14069 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14070 pw.println("moderate)"); 14071 break; 14072 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14073 pw.println("low)"); 14074 break; 14075 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14076 pw.println("critical)"); 14077 break; 14078 default: 14079 pw.print(mLastMemoryLevel); 14080 pw.println(")"); 14081 break; 14082 } 14083 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14084 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14085 pw.print(cachedPss); pw.print(" cached pss + "); 14086 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14087 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14088 } else { 14089 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14090 pw.print(cachedPss + memInfo.getCachedSizeKb() 14091 + memInfo.getFreeSizeKb()); pw.print(","); 14092 pw.println(totalPss - cachedPss); 14093 } 14094 } 14095 if (!isCompact) { 14096 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14097 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14098 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14099 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14100 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14101 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14102 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14103 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14104 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14105 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14106 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14107 } 14108 if (!brief) { 14109 if (memInfo.getZramTotalSizeKb() != 0) { 14110 if (!isCompact) { 14111 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14112 pw.print(" kB physical used for "); 14113 pw.print(memInfo.getSwapTotalSizeKb() 14114 - memInfo.getSwapFreeSizeKb()); 14115 pw.print(" kB in swap ("); 14116 pw.print(memInfo.getSwapTotalSizeKb()); 14117 pw.println(" kB total swap)"); 14118 } else { 14119 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14120 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14121 pw.println(memInfo.getSwapFreeSizeKb()); 14122 } 14123 } 14124 final int[] SINGLE_LONG_FORMAT = new int[] { 14125 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14126 }; 14127 long[] longOut = new long[1]; 14128 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14129 SINGLE_LONG_FORMAT, null, longOut, null); 14130 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14131 longOut[0] = 0; 14132 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14133 SINGLE_LONG_FORMAT, null, longOut, null); 14134 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14135 longOut[0] = 0; 14136 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14137 SINGLE_LONG_FORMAT, null, longOut, null); 14138 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14139 longOut[0] = 0; 14140 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14141 SINGLE_LONG_FORMAT, null, longOut, null); 14142 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14143 if (!isCompact) { 14144 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14145 pw.print(" KSM: "); pw.print(sharing); 14146 pw.print(" kB saved from shared "); 14147 pw.print(shared); pw.println(" kB"); 14148 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14149 pw.print(voltile); pw.println(" kB volatile"); 14150 } 14151 pw.print(" Tuning: "); 14152 pw.print(ActivityManager.staticGetMemoryClass()); 14153 pw.print(" (large "); 14154 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14155 pw.print("), oom "); 14156 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14157 pw.print(" kB"); 14158 pw.print(", restore limit "); 14159 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14160 pw.print(" kB"); 14161 if (ActivityManager.isLowRamDeviceStatic()) { 14162 pw.print(" (low-ram)"); 14163 } 14164 if (ActivityManager.isHighEndGfx()) { 14165 pw.print(" (high-end-gfx)"); 14166 } 14167 pw.println(); 14168 } else { 14169 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14170 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14171 pw.println(voltile); 14172 pw.print("tuning,"); 14173 pw.print(ActivityManager.staticGetMemoryClass()); 14174 pw.print(','); 14175 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14176 pw.print(','); 14177 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14178 if (ActivityManager.isLowRamDeviceStatic()) { 14179 pw.print(",low-ram"); 14180 } 14181 if (ActivityManager.isHighEndGfx()) { 14182 pw.print(",high-end-gfx"); 14183 } 14184 pw.println(); 14185 } 14186 } 14187 } 14188 } 14189 14190 /** 14191 * Searches array of arguments for the specified string 14192 * @param args array of argument strings 14193 * @param value value to search for 14194 * @return true if the value is contained in the array 14195 */ 14196 private static boolean scanArgs(String[] args, String value) { 14197 if (args != null) { 14198 for (String arg : args) { 14199 if (value.equals(arg)) { 14200 return true; 14201 } 14202 } 14203 } 14204 return false; 14205 } 14206 14207 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14208 ContentProviderRecord cpr, boolean always) { 14209 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14210 14211 if (!inLaunching || always) { 14212 synchronized (cpr) { 14213 cpr.launchingApp = null; 14214 cpr.notifyAll(); 14215 } 14216 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14217 String names[] = cpr.info.authority.split(";"); 14218 for (int j = 0; j < names.length; j++) { 14219 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14220 } 14221 } 14222 14223 for (int i=0; i<cpr.connections.size(); i++) { 14224 ContentProviderConnection conn = cpr.connections.get(i); 14225 if (conn.waiting) { 14226 // If this connection is waiting for the provider, then we don't 14227 // need to mess with its process unless we are always removing 14228 // or for some reason the provider is not currently launching. 14229 if (inLaunching && !always) { 14230 continue; 14231 } 14232 } 14233 ProcessRecord capp = conn.client; 14234 conn.dead = true; 14235 if (conn.stableCount > 0) { 14236 if (!capp.persistent && capp.thread != null 14237 && capp.pid != 0 14238 && capp.pid != MY_PID) { 14239 capp.kill("depends on provider " 14240 + cpr.name.flattenToShortString() 14241 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14242 } 14243 } else if (capp.thread != null && conn.provider.provider != null) { 14244 try { 14245 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14246 } catch (RemoteException e) { 14247 } 14248 // In the protocol here, we don't expect the client to correctly 14249 // clean up this connection, we'll just remove it. 14250 cpr.connections.remove(i); 14251 conn.client.conProviders.remove(conn); 14252 } 14253 } 14254 14255 if (inLaunching && always) { 14256 mLaunchingProviders.remove(cpr); 14257 } 14258 return inLaunching; 14259 } 14260 14261 /** 14262 * Main code for cleaning up a process when it has gone away. This is 14263 * called both as a result of the process dying, or directly when stopping 14264 * a process when running in single process mode. 14265 */ 14266 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14267 boolean restarting, boolean allowRestart, int index) { 14268 if (index >= 0) { 14269 removeLruProcessLocked(app); 14270 ProcessList.remove(app.pid); 14271 } 14272 14273 mProcessesToGc.remove(app); 14274 mPendingPssProcesses.remove(app); 14275 14276 // Dismiss any open dialogs. 14277 if (app.crashDialog != null && !app.forceCrashReport) { 14278 app.crashDialog.dismiss(); 14279 app.crashDialog = null; 14280 } 14281 if (app.anrDialog != null) { 14282 app.anrDialog.dismiss(); 14283 app.anrDialog = null; 14284 } 14285 if (app.waitDialog != null) { 14286 app.waitDialog.dismiss(); 14287 app.waitDialog = null; 14288 } 14289 14290 app.crashing = false; 14291 app.notResponding = false; 14292 14293 app.resetPackageList(mProcessStats); 14294 app.unlinkDeathRecipient(); 14295 app.makeInactive(mProcessStats); 14296 app.waitingToKill = null; 14297 app.forcingToForeground = null; 14298 updateProcessForegroundLocked(app, false, false); 14299 app.foregroundActivities = false; 14300 app.hasShownUi = false; 14301 app.treatLikeActivity = false; 14302 app.hasAboveClient = false; 14303 app.hasClientActivities = false; 14304 14305 mServices.killServicesLocked(app, allowRestart); 14306 14307 boolean restart = false; 14308 14309 // Remove published content providers. 14310 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14311 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14312 final boolean always = app.bad || !allowRestart; 14313 if (removeDyingProviderLocked(app, cpr, always) || always) { 14314 // We left the provider in the launching list, need to 14315 // restart it. 14316 restart = true; 14317 } 14318 14319 cpr.provider = null; 14320 cpr.proc = null; 14321 } 14322 app.pubProviders.clear(); 14323 14324 // Take care of any launching providers waiting for this process. 14325 if (checkAppInLaunchingProvidersLocked(app, false)) { 14326 restart = true; 14327 } 14328 14329 // Unregister from connected content providers. 14330 if (!app.conProviders.isEmpty()) { 14331 for (int i=0; i<app.conProviders.size(); i++) { 14332 ContentProviderConnection conn = app.conProviders.get(i); 14333 conn.provider.connections.remove(conn); 14334 } 14335 app.conProviders.clear(); 14336 } 14337 14338 // At this point there may be remaining entries in mLaunchingProviders 14339 // where we were the only one waiting, so they are no longer of use. 14340 // Look for these and clean up if found. 14341 // XXX Commented out for now. Trying to figure out a way to reproduce 14342 // the actual situation to identify what is actually going on. 14343 if (false) { 14344 for (int i=0; i<mLaunchingProviders.size(); i++) { 14345 ContentProviderRecord cpr = (ContentProviderRecord) 14346 mLaunchingProviders.get(i); 14347 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14348 synchronized (cpr) { 14349 cpr.launchingApp = null; 14350 cpr.notifyAll(); 14351 } 14352 } 14353 } 14354 } 14355 14356 skipCurrentReceiverLocked(app); 14357 14358 // Unregister any receivers. 14359 for (int i=app.receivers.size()-1; i>=0; i--) { 14360 removeReceiverLocked(app.receivers.valueAt(i)); 14361 } 14362 app.receivers.clear(); 14363 14364 // If the app is undergoing backup, tell the backup manager about it 14365 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14366 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14367 + mBackupTarget.appInfo + " died during backup"); 14368 try { 14369 IBackupManager bm = IBackupManager.Stub.asInterface( 14370 ServiceManager.getService(Context.BACKUP_SERVICE)); 14371 bm.agentDisconnected(app.info.packageName); 14372 } catch (RemoteException e) { 14373 // can't happen; backup manager is local 14374 } 14375 } 14376 14377 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14378 ProcessChangeItem item = mPendingProcessChanges.get(i); 14379 if (item.pid == app.pid) { 14380 mPendingProcessChanges.remove(i); 14381 mAvailProcessChanges.add(item); 14382 } 14383 } 14384 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14385 14386 // If the caller is restarting this app, then leave it in its 14387 // current lists and let the caller take care of it. 14388 if (restarting) { 14389 return; 14390 } 14391 14392 if (!app.persistent || app.isolated) { 14393 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14394 "Removing non-persistent process during cleanup: " + app); 14395 mProcessNames.remove(app.processName, app.uid); 14396 mIsolatedProcesses.remove(app.uid); 14397 if (mHeavyWeightProcess == app) { 14398 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14399 mHeavyWeightProcess.userId, 0)); 14400 mHeavyWeightProcess = null; 14401 } 14402 } else if (!app.removed) { 14403 // This app is persistent, so we need to keep its record around. 14404 // If it is not already on the pending app list, add it there 14405 // and start a new process for it. 14406 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14407 mPersistentStartingProcesses.add(app); 14408 restart = true; 14409 } 14410 } 14411 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14412 "Clean-up removing on hold: " + app); 14413 mProcessesOnHold.remove(app); 14414 14415 if (app == mHomeProcess) { 14416 mHomeProcess = null; 14417 } 14418 if (app == mPreviousProcess) { 14419 mPreviousProcess = null; 14420 } 14421 14422 if (restart && !app.isolated) { 14423 // We have components that still need to be running in the 14424 // process, so re-launch it. 14425 mProcessNames.put(app.processName, app.uid, app); 14426 startProcessLocked(app, "restart", app.processName); 14427 } else if (app.pid > 0 && app.pid != MY_PID) { 14428 // Goodbye! 14429 boolean removed; 14430 synchronized (mPidsSelfLocked) { 14431 mPidsSelfLocked.remove(app.pid); 14432 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14433 } 14434 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14435 if (app.isolated) { 14436 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14437 } 14438 app.setPid(0); 14439 } 14440 } 14441 14442 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14443 // Look through the content providers we are waiting to have launched, 14444 // and if any run in this process then either schedule a restart of 14445 // the process or kill the client waiting for it if this process has 14446 // gone bad. 14447 int NL = mLaunchingProviders.size(); 14448 boolean restart = false; 14449 for (int i=0; i<NL; i++) { 14450 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14451 if (cpr.launchingApp == app) { 14452 if (!alwaysBad && !app.bad) { 14453 restart = true; 14454 } else { 14455 removeDyingProviderLocked(app, cpr, true); 14456 // cpr should have been removed from mLaunchingProviders 14457 NL = mLaunchingProviders.size(); 14458 i--; 14459 } 14460 } 14461 } 14462 return restart; 14463 } 14464 14465 // ========================================================= 14466 // SERVICES 14467 // ========================================================= 14468 14469 @Override 14470 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14471 int flags) { 14472 enforceNotIsolatedCaller("getServices"); 14473 synchronized (this) { 14474 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14475 } 14476 } 14477 14478 @Override 14479 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14480 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14481 synchronized (this) { 14482 return mServices.getRunningServiceControlPanelLocked(name); 14483 } 14484 } 14485 14486 @Override 14487 public ComponentName startService(IApplicationThread caller, Intent service, 14488 String resolvedType, int userId) { 14489 enforceNotIsolatedCaller("startService"); 14490 // Refuse possible leaked file descriptors 14491 if (service != null && service.hasFileDescriptors() == true) { 14492 throw new IllegalArgumentException("File descriptors passed in Intent"); 14493 } 14494 14495 if (DEBUG_SERVICE) 14496 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14497 synchronized(this) { 14498 final int callingPid = Binder.getCallingPid(); 14499 final int callingUid = Binder.getCallingUid(); 14500 final long origId = Binder.clearCallingIdentity(); 14501 ComponentName res = mServices.startServiceLocked(caller, service, 14502 resolvedType, callingPid, callingUid, userId); 14503 Binder.restoreCallingIdentity(origId); 14504 return res; 14505 } 14506 } 14507 14508 ComponentName startServiceInPackage(int uid, 14509 Intent service, String resolvedType, int userId) { 14510 synchronized(this) { 14511 if (DEBUG_SERVICE) 14512 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14513 final long origId = Binder.clearCallingIdentity(); 14514 ComponentName res = mServices.startServiceLocked(null, service, 14515 resolvedType, -1, uid, userId); 14516 Binder.restoreCallingIdentity(origId); 14517 return res; 14518 } 14519 } 14520 14521 @Override 14522 public int stopService(IApplicationThread caller, Intent service, 14523 String resolvedType, int userId) { 14524 enforceNotIsolatedCaller("stopService"); 14525 // Refuse possible leaked file descriptors 14526 if (service != null && service.hasFileDescriptors() == true) { 14527 throw new IllegalArgumentException("File descriptors passed in Intent"); 14528 } 14529 14530 synchronized(this) { 14531 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14532 } 14533 } 14534 14535 @Override 14536 public IBinder peekService(Intent service, String resolvedType) { 14537 enforceNotIsolatedCaller("peekService"); 14538 // Refuse possible leaked file descriptors 14539 if (service != null && service.hasFileDescriptors() == true) { 14540 throw new IllegalArgumentException("File descriptors passed in Intent"); 14541 } 14542 synchronized(this) { 14543 return mServices.peekServiceLocked(service, resolvedType); 14544 } 14545 } 14546 14547 @Override 14548 public boolean stopServiceToken(ComponentName className, IBinder token, 14549 int startId) { 14550 synchronized(this) { 14551 return mServices.stopServiceTokenLocked(className, token, startId); 14552 } 14553 } 14554 14555 @Override 14556 public void setServiceForeground(ComponentName className, IBinder token, 14557 int id, Notification notification, boolean removeNotification) { 14558 synchronized(this) { 14559 mServices.setServiceForegroundLocked(className, token, id, notification, 14560 removeNotification); 14561 } 14562 } 14563 14564 @Override 14565 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14566 boolean requireFull, String name, String callerPackage) { 14567 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14568 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14569 } 14570 14571 int unsafeConvertIncomingUser(int userId) { 14572 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14573 ? mCurrentUserId : userId; 14574 } 14575 14576 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14577 int allowMode, String name, String callerPackage) { 14578 final int callingUserId = UserHandle.getUserId(callingUid); 14579 if (callingUserId == userId) { 14580 return userId; 14581 } 14582 14583 // Note that we may be accessing mCurrentUserId outside of a lock... 14584 // shouldn't be a big deal, if this is being called outside 14585 // of a locked context there is intrinsically a race with 14586 // the value the caller will receive and someone else changing it. 14587 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14588 // we will switch to the calling user if access to the current user fails. 14589 int targetUserId = unsafeConvertIncomingUser(userId); 14590 14591 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14592 final boolean allow; 14593 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14594 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14595 // If the caller has this permission, they always pass go. And collect $200. 14596 allow = true; 14597 } else if (allowMode == ALLOW_FULL_ONLY) { 14598 // We require full access, sucks to be you. 14599 allow = false; 14600 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14601 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14602 // If the caller does not have either permission, they are always doomed. 14603 allow = false; 14604 } else if (allowMode == ALLOW_NON_FULL) { 14605 // We are blanket allowing non-full access, you lucky caller! 14606 allow = true; 14607 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14608 // We may or may not allow this depending on whether the two users are 14609 // in the same profile. 14610 synchronized (mUserProfileGroupIdsSelfLocked) { 14611 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14612 UserInfo.NO_PROFILE_GROUP_ID); 14613 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14614 UserInfo.NO_PROFILE_GROUP_ID); 14615 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14616 && callingProfile == targetProfile; 14617 } 14618 } else { 14619 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14620 } 14621 if (!allow) { 14622 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14623 // In this case, they would like to just execute as their 14624 // owner user instead of failing. 14625 targetUserId = callingUserId; 14626 } else { 14627 StringBuilder builder = new StringBuilder(128); 14628 builder.append("Permission Denial: "); 14629 builder.append(name); 14630 if (callerPackage != null) { 14631 builder.append(" from "); 14632 builder.append(callerPackage); 14633 } 14634 builder.append(" asks to run as user "); 14635 builder.append(userId); 14636 builder.append(" but is calling from user "); 14637 builder.append(UserHandle.getUserId(callingUid)); 14638 builder.append("; this requires "); 14639 builder.append(INTERACT_ACROSS_USERS_FULL); 14640 if (allowMode != ALLOW_FULL_ONLY) { 14641 builder.append(" or "); 14642 builder.append(INTERACT_ACROSS_USERS); 14643 } 14644 String msg = builder.toString(); 14645 Slog.w(TAG, msg); 14646 throw new SecurityException(msg); 14647 } 14648 } 14649 } 14650 if (!allowAll && targetUserId < 0) { 14651 throw new IllegalArgumentException( 14652 "Call does not support special user #" + targetUserId); 14653 } 14654 // Check shell permission 14655 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14656 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14657 targetUserId)) { 14658 throw new SecurityException("Shell does not have permission to access user " 14659 + targetUserId + "\n " + Debug.getCallers(3)); 14660 } 14661 } 14662 return targetUserId; 14663 } 14664 14665 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14666 String className, int flags) { 14667 boolean result = false; 14668 // For apps that don't have pre-defined UIDs, check for permission 14669 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14670 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14671 if (ActivityManager.checkUidPermission( 14672 INTERACT_ACROSS_USERS, 14673 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14674 ComponentName comp = new ComponentName(aInfo.packageName, className); 14675 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14676 + " requests FLAG_SINGLE_USER, but app does not hold " 14677 + INTERACT_ACROSS_USERS; 14678 Slog.w(TAG, msg); 14679 throw new SecurityException(msg); 14680 } 14681 // Permission passed 14682 result = true; 14683 } 14684 } else if ("system".equals(componentProcessName)) { 14685 result = true; 14686 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14687 // Phone app and persistent apps are allowed to export singleuser providers. 14688 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14689 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14690 } 14691 if (DEBUG_MU) { 14692 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14693 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14694 } 14695 return result; 14696 } 14697 14698 /** 14699 * Checks to see if the caller is in the same app as the singleton 14700 * component, or the component is in a special app. It allows special apps 14701 * to export singleton components but prevents exporting singleton 14702 * components for regular apps. 14703 */ 14704 boolean isValidSingletonCall(int callingUid, int componentUid) { 14705 int componentAppId = UserHandle.getAppId(componentUid); 14706 return UserHandle.isSameApp(callingUid, componentUid) 14707 || componentAppId == Process.SYSTEM_UID 14708 || componentAppId == Process.PHONE_UID 14709 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14710 == PackageManager.PERMISSION_GRANTED; 14711 } 14712 14713 public int bindService(IApplicationThread caller, IBinder token, 14714 Intent service, String resolvedType, 14715 IServiceConnection connection, int flags, int userId) { 14716 enforceNotIsolatedCaller("bindService"); 14717 14718 // Refuse possible leaked file descriptors 14719 if (service != null && service.hasFileDescriptors() == true) { 14720 throw new IllegalArgumentException("File descriptors passed in Intent"); 14721 } 14722 14723 synchronized(this) { 14724 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14725 connection, flags, userId); 14726 } 14727 } 14728 14729 public boolean unbindService(IServiceConnection connection) { 14730 synchronized (this) { 14731 return mServices.unbindServiceLocked(connection); 14732 } 14733 } 14734 14735 public void publishService(IBinder token, Intent intent, IBinder service) { 14736 // Refuse possible leaked file descriptors 14737 if (intent != null && intent.hasFileDescriptors() == true) { 14738 throw new IllegalArgumentException("File descriptors passed in Intent"); 14739 } 14740 14741 synchronized(this) { 14742 if (!(token instanceof ServiceRecord)) { 14743 throw new IllegalArgumentException("Invalid service token"); 14744 } 14745 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14746 } 14747 } 14748 14749 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14750 // Refuse possible leaked file descriptors 14751 if (intent != null && intent.hasFileDescriptors() == true) { 14752 throw new IllegalArgumentException("File descriptors passed in Intent"); 14753 } 14754 14755 synchronized(this) { 14756 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14757 } 14758 } 14759 14760 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14761 synchronized(this) { 14762 if (!(token instanceof ServiceRecord)) { 14763 throw new IllegalArgumentException("Invalid service token"); 14764 } 14765 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14766 } 14767 } 14768 14769 // ========================================================= 14770 // BACKUP AND RESTORE 14771 // ========================================================= 14772 14773 // Cause the target app to be launched if necessary and its backup agent 14774 // instantiated. The backup agent will invoke backupAgentCreated() on the 14775 // activity manager to announce its creation. 14776 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14777 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14778 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14779 14780 synchronized(this) { 14781 // !!! TODO: currently no check here that we're already bound 14782 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14783 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14784 synchronized (stats) { 14785 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14786 } 14787 14788 // Backup agent is now in use, its package can't be stopped. 14789 try { 14790 AppGlobals.getPackageManager().setPackageStoppedState( 14791 app.packageName, false, UserHandle.getUserId(app.uid)); 14792 } catch (RemoteException e) { 14793 } catch (IllegalArgumentException e) { 14794 Slog.w(TAG, "Failed trying to unstop package " 14795 + app.packageName + ": " + e); 14796 } 14797 14798 BackupRecord r = new BackupRecord(ss, app, backupMode); 14799 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14800 ? new ComponentName(app.packageName, app.backupAgentName) 14801 : new ComponentName("android", "FullBackupAgent"); 14802 // startProcessLocked() returns existing proc's record if it's already running 14803 ProcessRecord proc = startProcessLocked(app.processName, app, 14804 false, 0, "backup", hostingName, false, false, false); 14805 if (proc == null) { 14806 Slog.e(TAG, "Unable to start backup agent process " + r); 14807 return false; 14808 } 14809 14810 r.app = proc; 14811 mBackupTarget = r; 14812 mBackupAppName = app.packageName; 14813 14814 // Try not to kill the process during backup 14815 updateOomAdjLocked(proc); 14816 14817 // If the process is already attached, schedule the creation of the backup agent now. 14818 // If it is not yet live, this will be done when it attaches to the framework. 14819 if (proc.thread != null) { 14820 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14821 try { 14822 proc.thread.scheduleCreateBackupAgent(app, 14823 compatibilityInfoForPackageLocked(app), backupMode); 14824 } catch (RemoteException e) { 14825 // Will time out on the backup manager side 14826 } 14827 } else { 14828 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14829 } 14830 // Invariants: at this point, the target app process exists and the application 14831 // is either already running or in the process of coming up. mBackupTarget and 14832 // mBackupAppName describe the app, so that when it binds back to the AM we 14833 // know that it's scheduled for a backup-agent operation. 14834 } 14835 14836 return true; 14837 } 14838 14839 @Override 14840 public void clearPendingBackup() { 14841 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14842 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14843 14844 synchronized (this) { 14845 mBackupTarget = null; 14846 mBackupAppName = null; 14847 } 14848 } 14849 14850 // A backup agent has just come up 14851 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14852 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14853 + " = " + agent); 14854 14855 synchronized(this) { 14856 if (!agentPackageName.equals(mBackupAppName)) { 14857 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14858 return; 14859 } 14860 } 14861 14862 long oldIdent = Binder.clearCallingIdentity(); 14863 try { 14864 IBackupManager bm = IBackupManager.Stub.asInterface( 14865 ServiceManager.getService(Context.BACKUP_SERVICE)); 14866 bm.agentConnected(agentPackageName, agent); 14867 } catch (RemoteException e) { 14868 // can't happen; the backup manager service is local 14869 } catch (Exception e) { 14870 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14871 e.printStackTrace(); 14872 } finally { 14873 Binder.restoreCallingIdentity(oldIdent); 14874 } 14875 } 14876 14877 // done with this agent 14878 public void unbindBackupAgent(ApplicationInfo appInfo) { 14879 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14880 if (appInfo == null) { 14881 Slog.w(TAG, "unbind backup agent for null app"); 14882 return; 14883 } 14884 14885 synchronized(this) { 14886 try { 14887 if (mBackupAppName == null) { 14888 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14889 return; 14890 } 14891 14892 if (!mBackupAppName.equals(appInfo.packageName)) { 14893 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14894 return; 14895 } 14896 14897 // Not backing this app up any more; reset its OOM adjustment 14898 final ProcessRecord proc = mBackupTarget.app; 14899 updateOomAdjLocked(proc); 14900 14901 // If the app crashed during backup, 'thread' will be null here 14902 if (proc.thread != null) { 14903 try { 14904 proc.thread.scheduleDestroyBackupAgent(appInfo, 14905 compatibilityInfoForPackageLocked(appInfo)); 14906 } catch (Exception e) { 14907 Slog.e(TAG, "Exception when unbinding backup agent:"); 14908 e.printStackTrace(); 14909 } 14910 } 14911 } finally { 14912 mBackupTarget = null; 14913 mBackupAppName = null; 14914 } 14915 } 14916 } 14917 // ========================================================= 14918 // BROADCASTS 14919 // ========================================================= 14920 14921 private final List getStickiesLocked(String action, IntentFilter filter, 14922 List cur, int userId) { 14923 final ContentResolver resolver = mContext.getContentResolver(); 14924 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14925 if (stickies == null) { 14926 return cur; 14927 } 14928 final ArrayList<Intent> list = stickies.get(action); 14929 if (list == null) { 14930 return cur; 14931 } 14932 int N = list.size(); 14933 for (int i=0; i<N; i++) { 14934 Intent intent = list.get(i); 14935 if (filter.match(resolver, intent, true, TAG) >= 0) { 14936 if (cur == null) { 14937 cur = new ArrayList<Intent>(); 14938 } 14939 cur.add(intent); 14940 } 14941 } 14942 return cur; 14943 } 14944 14945 boolean isPendingBroadcastProcessLocked(int pid) { 14946 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14947 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14948 } 14949 14950 void skipPendingBroadcastLocked(int pid) { 14951 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14952 for (BroadcastQueue queue : mBroadcastQueues) { 14953 queue.skipPendingBroadcastLocked(pid); 14954 } 14955 } 14956 14957 // The app just attached; send any pending broadcasts that it should receive 14958 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14959 boolean didSomething = false; 14960 for (BroadcastQueue queue : mBroadcastQueues) { 14961 didSomething |= queue.sendPendingBroadcastsLocked(app); 14962 } 14963 return didSomething; 14964 } 14965 14966 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14967 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14968 enforceNotIsolatedCaller("registerReceiver"); 14969 int callingUid; 14970 int callingPid; 14971 synchronized(this) { 14972 ProcessRecord callerApp = null; 14973 if (caller != null) { 14974 callerApp = getRecordForAppLocked(caller); 14975 if (callerApp == null) { 14976 throw new SecurityException( 14977 "Unable to find app for caller " + caller 14978 + " (pid=" + Binder.getCallingPid() 14979 + ") when registering receiver " + receiver); 14980 } 14981 if (callerApp.info.uid != Process.SYSTEM_UID && 14982 !callerApp.pkgList.containsKey(callerPackage) && 14983 !"android".equals(callerPackage)) { 14984 throw new SecurityException("Given caller package " + callerPackage 14985 + " is not running in process " + callerApp); 14986 } 14987 callingUid = callerApp.info.uid; 14988 callingPid = callerApp.pid; 14989 } else { 14990 callerPackage = null; 14991 callingUid = Binder.getCallingUid(); 14992 callingPid = Binder.getCallingPid(); 14993 } 14994 14995 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14996 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14997 14998 List allSticky = null; 14999 15000 // Look for any matching sticky broadcasts... 15001 Iterator actions = filter.actionsIterator(); 15002 if (actions != null) { 15003 while (actions.hasNext()) { 15004 String action = (String)actions.next(); 15005 allSticky = getStickiesLocked(action, filter, allSticky, 15006 UserHandle.USER_ALL); 15007 allSticky = getStickiesLocked(action, filter, allSticky, 15008 UserHandle.getUserId(callingUid)); 15009 } 15010 } else { 15011 allSticky = getStickiesLocked(null, filter, allSticky, 15012 UserHandle.USER_ALL); 15013 allSticky = getStickiesLocked(null, filter, allSticky, 15014 UserHandle.getUserId(callingUid)); 15015 } 15016 15017 // The first sticky in the list is returned directly back to 15018 // the client. 15019 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15020 15021 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15022 + ": " + sticky); 15023 15024 if (receiver == null) { 15025 return sticky; 15026 } 15027 15028 ReceiverList rl 15029 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15030 if (rl == null) { 15031 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15032 userId, receiver); 15033 if (rl.app != null) { 15034 rl.app.receivers.add(rl); 15035 } else { 15036 try { 15037 receiver.asBinder().linkToDeath(rl, 0); 15038 } catch (RemoteException e) { 15039 return sticky; 15040 } 15041 rl.linkedToDeath = true; 15042 } 15043 mRegisteredReceivers.put(receiver.asBinder(), rl); 15044 } else if (rl.uid != callingUid) { 15045 throw new IllegalArgumentException( 15046 "Receiver requested to register for uid " + callingUid 15047 + " was previously registered for uid " + rl.uid); 15048 } else if (rl.pid != callingPid) { 15049 throw new IllegalArgumentException( 15050 "Receiver requested to register for pid " + callingPid 15051 + " was previously registered for pid " + rl.pid); 15052 } else if (rl.userId != userId) { 15053 throw new IllegalArgumentException( 15054 "Receiver requested to register for user " + userId 15055 + " was previously registered for user " + rl.userId); 15056 } 15057 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15058 permission, callingUid, userId); 15059 rl.add(bf); 15060 if (!bf.debugCheck()) { 15061 Slog.w(TAG, "==> For Dynamic broadast"); 15062 } 15063 mReceiverResolver.addFilter(bf); 15064 15065 // Enqueue broadcasts for all existing stickies that match 15066 // this filter. 15067 if (allSticky != null) { 15068 ArrayList receivers = new ArrayList(); 15069 receivers.add(bf); 15070 15071 int N = allSticky.size(); 15072 for (int i=0; i<N; i++) { 15073 Intent intent = (Intent)allSticky.get(i); 15074 BroadcastQueue queue = broadcastQueueForIntent(intent); 15075 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15076 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15077 null, null, false, true, true, -1); 15078 queue.enqueueParallelBroadcastLocked(r); 15079 queue.scheduleBroadcastsLocked(); 15080 } 15081 } 15082 15083 return sticky; 15084 } 15085 } 15086 15087 public void unregisterReceiver(IIntentReceiver receiver) { 15088 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15089 15090 final long origId = Binder.clearCallingIdentity(); 15091 try { 15092 boolean doTrim = false; 15093 15094 synchronized(this) { 15095 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15096 if (rl != null) { 15097 if (rl.curBroadcast != null) { 15098 BroadcastRecord r = rl.curBroadcast; 15099 final boolean doNext = finishReceiverLocked( 15100 receiver.asBinder(), r.resultCode, r.resultData, 15101 r.resultExtras, r.resultAbort); 15102 if (doNext) { 15103 doTrim = true; 15104 r.queue.processNextBroadcast(false); 15105 } 15106 } 15107 15108 if (rl.app != null) { 15109 rl.app.receivers.remove(rl); 15110 } 15111 removeReceiverLocked(rl); 15112 if (rl.linkedToDeath) { 15113 rl.linkedToDeath = false; 15114 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15115 } 15116 } 15117 } 15118 15119 // If we actually concluded any broadcasts, we might now be able 15120 // to trim the recipients' apps from our working set 15121 if (doTrim) { 15122 trimApplications(); 15123 return; 15124 } 15125 15126 } finally { 15127 Binder.restoreCallingIdentity(origId); 15128 } 15129 } 15130 15131 void removeReceiverLocked(ReceiverList rl) { 15132 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15133 int N = rl.size(); 15134 for (int i=0; i<N; i++) { 15135 mReceiverResolver.removeFilter(rl.get(i)); 15136 } 15137 } 15138 15139 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15140 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15141 ProcessRecord r = mLruProcesses.get(i); 15142 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15143 try { 15144 r.thread.dispatchPackageBroadcast(cmd, packages); 15145 } catch (RemoteException ex) { 15146 } 15147 } 15148 } 15149 } 15150 15151 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15152 int callingUid, int[] users) { 15153 List<ResolveInfo> receivers = null; 15154 try { 15155 HashSet<ComponentName> singleUserReceivers = null; 15156 boolean scannedFirstReceivers = false; 15157 for (int user : users) { 15158 // Skip users that have Shell restrictions 15159 if (callingUid == Process.SHELL_UID 15160 && getUserManagerLocked().hasUserRestriction( 15161 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15162 continue; 15163 } 15164 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15165 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15166 if (user != 0 && newReceivers != null) { 15167 // If this is not the primary user, we need to check for 15168 // any receivers that should be filtered out. 15169 for (int i=0; i<newReceivers.size(); i++) { 15170 ResolveInfo ri = newReceivers.get(i); 15171 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15172 newReceivers.remove(i); 15173 i--; 15174 } 15175 } 15176 } 15177 if (newReceivers != null && newReceivers.size() == 0) { 15178 newReceivers = null; 15179 } 15180 if (receivers == null) { 15181 receivers = newReceivers; 15182 } else if (newReceivers != null) { 15183 // We need to concatenate the additional receivers 15184 // found with what we have do far. This would be easy, 15185 // but we also need to de-dup any receivers that are 15186 // singleUser. 15187 if (!scannedFirstReceivers) { 15188 // Collect any single user receivers we had already retrieved. 15189 scannedFirstReceivers = true; 15190 for (int i=0; i<receivers.size(); i++) { 15191 ResolveInfo ri = receivers.get(i); 15192 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15193 ComponentName cn = new ComponentName( 15194 ri.activityInfo.packageName, ri.activityInfo.name); 15195 if (singleUserReceivers == null) { 15196 singleUserReceivers = new HashSet<ComponentName>(); 15197 } 15198 singleUserReceivers.add(cn); 15199 } 15200 } 15201 } 15202 // Add the new results to the existing results, tracking 15203 // and de-dupping single user receivers. 15204 for (int i=0; i<newReceivers.size(); i++) { 15205 ResolveInfo ri = newReceivers.get(i); 15206 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15207 ComponentName cn = new ComponentName( 15208 ri.activityInfo.packageName, ri.activityInfo.name); 15209 if (singleUserReceivers == null) { 15210 singleUserReceivers = new HashSet<ComponentName>(); 15211 } 15212 if (!singleUserReceivers.contains(cn)) { 15213 singleUserReceivers.add(cn); 15214 receivers.add(ri); 15215 } 15216 } else { 15217 receivers.add(ri); 15218 } 15219 } 15220 } 15221 } 15222 } catch (RemoteException ex) { 15223 // pm is in same process, this will never happen. 15224 } 15225 return receivers; 15226 } 15227 15228 private final int broadcastIntentLocked(ProcessRecord callerApp, 15229 String callerPackage, Intent intent, String resolvedType, 15230 IIntentReceiver resultTo, int resultCode, String resultData, 15231 Bundle map, String requiredPermission, int appOp, 15232 boolean ordered, boolean sticky, int callingPid, int callingUid, 15233 int userId) { 15234 intent = new Intent(intent); 15235 15236 // By default broadcasts do not go to stopped apps. 15237 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15238 15239 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15240 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15241 + " ordered=" + ordered + " userid=" + userId); 15242 if ((resultTo != null) && !ordered) { 15243 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15244 } 15245 15246 userId = handleIncomingUser(callingPid, callingUid, userId, 15247 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15248 15249 // Make sure that the user who is receiving this broadcast is started. 15250 // If not, we will just skip it. 15251 15252 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15253 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15254 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15255 Slog.w(TAG, "Skipping broadcast of " + intent 15256 + ": user " + userId + " is stopped"); 15257 return ActivityManager.BROADCAST_SUCCESS; 15258 } 15259 } 15260 15261 /* 15262 * Prevent non-system code (defined here to be non-persistent 15263 * processes) from sending protected broadcasts. 15264 */ 15265 int callingAppId = UserHandle.getAppId(callingUid); 15266 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15267 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15268 || callingAppId == Process.NFC_UID || callingUid == 0) { 15269 // Always okay. 15270 } else if (callerApp == null || !callerApp.persistent) { 15271 try { 15272 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15273 intent.getAction())) { 15274 String msg = "Permission Denial: not allowed to send broadcast " 15275 + intent.getAction() + " from pid=" 15276 + callingPid + ", uid=" + callingUid; 15277 Slog.w(TAG, msg); 15278 throw new SecurityException(msg); 15279 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15280 // Special case for compatibility: we don't want apps to send this, 15281 // but historically it has not been protected and apps may be using it 15282 // to poke their own app widget. So, instead of making it protected, 15283 // just limit it to the caller. 15284 if (callerApp == null) { 15285 String msg = "Permission Denial: not allowed to send broadcast " 15286 + intent.getAction() + " from unknown caller."; 15287 Slog.w(TAG, msg); 15288 throw new SecurityException(msg); 15289 } else if (intent.getComponent() != null) { 15290 // They are good enough to send to an explicit component... verify 15291 // it is being sent to the calling app. 15292 if (!intent.getComponent().getPackageName().equals( 15293 callerApp.info.packageName)) { 15294 String msg = "Permission Denial: not allowed to send broadcast " 15295 + intent.getAction() + " to " 15296 + intent.getComponent().getPackageName() + " from " 15297 + callerApp.info.packageName; 15298 Slog.w(TAG, msg); 15299 throw new SecurityException(msg); 15300 } 15301 } else { 15302 // Limit broadcast to their own package. 15303 intent.setPackage(callerApp.info.packageName); 15304 } 15305 } 15306 } catch (RemoteException e) { 15307 Slog.w(TAG, "Remote exception", e); 15308 return ActivityManager.BROADCAST_SUCCESS; 15309 } 15310 } 15311 15312 // Handle special intents: if this broadcast is from the package 15313 // manager about a package being removed, we need to remove all of 15314 // its activities from the history stack. 15315 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15316 intent.getAction()); 15317 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15318 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15319 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15320 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15321 || uidRemoved) { 15322 if (checkComponentPermission( 15323 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15324 callingPid, callingUid, -1, true) 15325 == PackageManager.PERMISSION_GRANTED) { 15326 if (uidRemoved) { 15327 final Bundle intentExtras = intent.getExtras(); 15328 final int uid = intentExtras != null 15329 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15330 if (uid >= 0) { 15331 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15332 synchronized (bs) { 15333 bs.removeUidStatsLocked(uid); 15334 } 15335 mAppOpsService.uidRemoved(uid); 15336 } 15337 } else { 15338 // If resources are unavailable just force stop all 15339 // those packages and flush the attribute cache as well. 15340 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15341 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15342 if (list != null && (list.length > 0)) { 15343 for (String pkg : list) { 15344 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15345 "storage unmount"); 15346 } 15347 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15348 sendPackageBroadcastLocked( 15349 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15350 } 15351 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15352 intent.getAction())) { 15353 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15354 } else { 15355 Uri data = intent.getData(); 15356 String ssp; 15357 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15358 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15359 intent.getAction()); 15360 boolean fullUninstall = removed && 15361 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15362 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15363 forceStopPackageLocked(ssp, UserHandle.getAppId( 15364 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15365 false, fullUninstall, userId, 15366 removed ? "pkg removed" : "pkg changed"); 15367 } 15368 if (removed) { 15369 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15370 new String[] {ssp}, userId); 15371 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15372 mAppOpsService.packageRemoved( 15373 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15374 15375 // Remove all permissions granted from/to this package 15376 removeUriPermissionsForPackageLocked(ssp, userId, true); 15377 } 15378 } 15379 } 15380 } 15381 } 15382 } else { 15383 String msg = "Permission Denial: " + intent.getAction() 15384 + " broadcast from " + callerPackage + " (pid=" + callingPid 15385 + ", uid=" + callingUid + ")" 15386 + " requires " 15387 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15388 Slog.w(TAG, msg); 15389 throw new SecurityException(msg); 15390 } 15391 15392 // Special case for adding a package: by default turn on compatibility 15393 // mode. 15394 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15395 Uri data = intent.getData(); 15396 String ssp; 15397 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15398 mCompatModePackages.handlePackageAddedLocked(ssp, 15399 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15400 } 15401 } 15402 15403 /* 15404 * If this is the time zone changed action, queue up a message that will reset the timezone 15405 * of all currently running processes. This message will get queued up before the broadcast 15406 * happens. 15407 */ 15408 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15409 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15410 } 15411 15412 /* 15413 * If the user set the time, let all running processes know. 15414 */ 15415 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15416 final int is24Hour = intent.getBooleanExtra( 15417 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15418 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15419 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15420 synchronized (stats) { 15421 stats.noteCurrentTimeChangedLocked(); 15422 } 15423 } 15424 15425 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15426 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15427 } 15428 15429 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15430 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15431 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15432 } 15433 15434 // Add to the sticky list if requested. 15435 if (sticky) { 15436 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15437 callingPid, callingUid) 15438 != PackageManager.PERMISSION_GRANTED) { 15439 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15440 + callingPid + ", uid=" + callingUid 15441 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15442 Slog.w(TAG, msg); 15443 throw new SecurityException(msg); 15444 } 15445 if (requiredPermission != null) { 15446 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15447 + " and enforce permission " + requiredPermission); 15448 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15449 } 15450 if (intent.getComponent() != null) { 15451 throw new SecurityException( 15452 "Sticky broadcasts can't target a specific component"); 15453 } 15454 // We use userId directly here, since the "all" target is maintained 15455 // as a separate set of sticky broadcasts. 15456 if (userId != UserHandle.USER_ALL) { 15457 // But first, if this is not a broadcast to all users, then 15458 // make sure it doesn't conflict with an existing broadcast to 15459 // all users. 15460 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15461 UserHandle.USER_ALL); 15462 if (stickies != null) { 15463 ArrayList<Intent> list = stickies.get(intent.getAction()); 15464 if (list != null) { 15465 int N = list.size(); 15466 int i; 15467 for (i=0; i<N; i++) { 15468 if (intent.filterEquals(list.get(i))) { 15469 throw new IllegalArgumentException( 15470 "Sticky broadcast " + intent + " for user " 15471 + userId + " conflicts with existing global broadcast"); 15472 } 15473 } 15474 } 15475 } 15476 } 15477 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15478 if (stickies == null) { 15479 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15480 mStickyBroadcasts.put(userId, stickies); 15481 } 15482 ArrayList<Intent> list = stickies.get(intent.getAction()); 15483 if (list == null) { 15484 list = new ArrayList<Intent>(); 15485 stickies.put(intent.getAction(), list); 15486 } 15487 int N = list.size(); 15488 int i; 15489 for (i=0; i<N; i++) { 15490 if (intent.filterEquals(list.get(i))) { 15491 // This sticky already exists, replace it. 15492 list.set(i, new Intent(intent)); 15493 break; 15494 } 15495 } 15496 if (i >= N) { 15497 list.add(new Intent(intent)); 15498 } 15499 } 15500 15501 int[] users; 15502 if (userId == UserHandle.USER_ALL) { 15503 // Caller wants broadcast to go to all started users. 15504 users = mStartedUserArray; 15505 } else { 15506 // Caller wants broadcast to go to one specific user. 15507 users = new int[] {userId}; 15508 } 15509 15510 // Figure out who all will receive this broadcast. 15511 List receivers = null; 15512 List<BroadcastFilter> registeredReceivers = null; 15513 // Need to resolve the intent to interested receivers... 15514 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15515 == 0) { 15516 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15517 } 15518 if (intent.getComponent() == null) { 15519 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15520 // Query one target user at a time, excluding shell-restricted users 15521 UserManagerService ums = getUserManagerLocked(); 15522 for (int i = 0; i < users.length; i++) { 15523 if (ums.hasUserRestriction( 15524 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15525 continue; 15526 } 15527 List<BroadcastFilter> registeredReceiversForUser = 15528 mReceiverResolver.queryIntent(intent, 15529 resolvedType, false, users[i]); 15530 if (registeredReceivers == null) { 15531 registeredReceivers = registeredReceiversForUser; 15532 } else if (registeredReceiversForUser != null) { 15533 registeredReceivers.addAll(registeredReceiversForUser); 15534 } 15535 } 15536 } else { 15537 registeredReceivers = mReceiverResolver.queryIntent(intent, 15538 resolvedType, false, userId); 15539 } 15540 } 15541 15542 final boolean replacePending = 15543 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15544 15545 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15546 + " replacePending=" + replacePending); 15547 15548 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15549 if (!ordered && NR > 0) { 15550 // If we are not serializing this broadcast, then send the 15551 // registered receivers separately so they don't wait for the 15552 // components to be launched. 15553 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15554 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15555 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15556 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15557 ordered, sticky, false, userId); 15558 if (DEBUG_BROADCAST) Slog.v( 15559 TAG, "Enqueueing parallel broadcast " + r); 15560 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15561 if (!replaced) { 15562 queue.enqueueParallelBroadcastLocked(r); 15563 queue.scheduleBroadcastsLocked(); 15564 } 15565 registeredReceivers = null; 15566 NR = 0; 15567 } 15568 15569 // Merge into one list. 15570 int ir = 0; 15571 if (receivers != null) { 15572 // A special case for PACKAGE_ADDED: do not allow the package 15573 // being added to see this broadcast. This prevents them from 15574 // using this as a back door to get run as soon as they are 15575 // installed. Maybe in the future we want to have a special install 15576 // broadcast or such for apps, but we'd like to deliberately make 15577 // this decision. 15578 String skipPackages[] = null; 15579 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15580 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15581 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15582 Uri data = intent.getData(); 15583 if (data != null) { 15584 String pkgName = data.getSchemeSpecificPart(); 15585 if (pkgName != null) { 15586 skipPackages = new String[] { pkgName }; 15587 } 15588 } 15589 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15590 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15591 } 15592 if (skipPackages != null && (skipPackages.length > 0)) { 15593 for (String skipPackage : skipPackages) { 15594 if (skipPackage != null) { 15595 int NT = receivers.size(); 15596 for (int it=0; it<NT; it++) { 15597 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15598 if (curt.activityInfo.packageName.equals(skipPackage)) { 15599 receivers.remove(it); 15600 it--; 15601 NT--; 15602 } 15603 } 15604 } 15605 } 15606 } 15607 15608 int NT = receivers != null ? receivers.size() : 0; 15609 int it = 0; 15610 ResolveInfo curt = null; 15611 BroadcastFilter curr = null; 15612 while (it < NT && ir < NR) { 15613 if (curt == null) { 15614 curt = (ResolveInfo)receivers.get(it); 15615 } 15616 if (curr == null) { 15617 curr = registeredReceivers.get(ir); 15618 } 15619 if (curr.getPriority() >= curt.priority) { 15620 // Insert this broadcast record into the final list. 15621 receivers.add(it, curr); 15622 ir++; 15623 curr = null; 15624 it++; 15625 NT++; 15626 } else { 15627 // Skip to the next ResolveInfo in the final list. 15628 it++; 15629 curt = null; 15630 } 15631 } 15632 } 15633 while (ir < NR) { 15634 if (receivers == null) { 15635 receivers = new ArrayList(); 15636 } 15637 receivers.add(registeredReceivers.get(ir)); 15638 ir++; 15639 } 15640 15641 if ((receivers != null && receivers.size() > 0) 15642 || resultTo != null) { 15643 BroadcastQueue queue = broadcastQueueForIntent(intent); 15644 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15645 callerPackage, callingPid, callingUid, resolvedType, 15646 requiredPermission, appOp, receivers, resultTo, resultCode, 15647 resultData, map, ordered, sticky, false, userId); 15648 if (DEBUG_BROADCAST) Slog.v( 15649 TAG, "Enqueueing ordered broadcast " + r 15650 + ": prev had " + queue.mOrderedBroadcasts.size()); 15651 if (DEBUG_BROADCAST) { 15652 int seq = r.intent.getIntExtra("seq", -1); 15653 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15654 } 15655 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15656 if (!replaced) { 15657 queue.enqueueOrderedBroadcastLocked(r); 15658 queue.scheduleBroadcastsLocked(); 15659 } 15660 } 15661 15662 return ActivityManager.BROADCAST_SUCCESS; 15663 } 15664 15665 final Intent verifyBroadcastLocked(Intent intent) { 15666 // Refuse possible leaked file descriptors 15667 if (intent != null && intent.hasFileDescriptors() == true) { 15668 throw new IllegalArgumentException("File descriptors passed in Intent"); 15669 } 15670 15671 int flags = intent.getFlags(); 15672 15673 if (!mProcessesReady) { 15674 // if the caller really truly claims to know what they're doing, go 15675 // ahead and allow the broadcast without launching any receivers 15676 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15677 intent = new Intent(intent); 15678 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15679 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15680 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15681 + " before boot completion"); 15682 throw new IllegalStateException("Cannot broadcast before boot completed"); 15683 } 15684 } 15685 15686 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15687 throw new IllegalArgumentException( 15688 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15689 } 15690 15691 return intent; 15692 } 15693 15694 public final int broadcastIntent(IApplicationThread caller, 15695 Intent intent, String resolvedType, IIntentReceiver resultTo, 15696 int resultCode, String resultData, Bundle map, 15697 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15698 enforceNotIsolatedCaller("broadcastIntent"); 15699 synchronized(this) { 15700 intent = verifyBroadcastLocked(intent); 15701 15702 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15703 final int callingPid = Binder.getCallingPid(); 15704 final int callingUid = Binder.getCallingUid(); 15705 final long origId = Binder.clearCallingIdentity(); 15706 int res = broadcastIntentLocked(callerApp, 15707 callerApp != null ? callerApp.info.packageName : null, 15708 intent, resolvedType, resultTo, 15709 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15710 callingPid, callingUid, userId); 15711 Binder.restoreCallingIdentity(origId); 15712 return res; 15713 } 15714 } 15715 15716 int broadcastIntentInPackage(String packageName, int uid, 15717 Intent intent, String resolvedType, IIntentReceiver resultTo, 15718 int resultCode, String resultData, Bundle map, 15719 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15720 synchronized(this) { 15721 intent = verifyBroadcastLocked(intent); 15722 15723 final long origId = Binder.clearCallingIdentity(); 15724 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15725 resultTo, resultCode, resultData, map, requiredPermission, 15726 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15727 Binder.restoreCallingIdentity(origId); 15728 return res; 15729 } 15730 } 15731 15732 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15733 // Refuse possible leaked file descriptors 15734 if (intent != null && intent.hasFileDescriptors() == true) { 15735 throw new IllegalArgumentException("File descriptors passed in Intent"); 15736 } 15737 15738 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15739 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15740 15741 synchronized(this) { 15742 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15743 != PackageManager.PERMISSION_GRANTED) { 15744 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15745 + Binder.getCallingPid() 15746 + ", uid=" + Binder.getCallingUid() 15747 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15748 Slog.w(TAG, msg); 15749 throw new SecurityException(msg); 15750 } 15751 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15752 if (stickies != null) { 15753 ArrayList<Intent> list = stickies.get(intent.getAction()); 15754 if (list != null) { 15755 int N = list.size(); 15756 int i; 15757 for (i=0; i<N; i++) { 15758 if (intent.filterEquals(list.get(i))) { 15759 list.remove(i); 15760 break; 15761 } 15762 } 15763 if (list.size() <= 0) { 15764 stickies.remove(intent.getAction()); 15765 } 15766 } 15767 if (stickies.size() <= 0) { 15768 mStickyBroadcasts.remove(userId); 15769 } 15770 } 15771 } 15772 } 15773 15774 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15775 String resultData, Bundle resultExtras, boolean resultAbort) { 15776 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15777 if (r == null) { 15778 Slog.w(TAG, "finishReceiver called but not found on queue"); 15779 return false; 15780 } 15781 15782 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15783 } 15784 15785 void backgroundServicesFinishedLocked(int userId) { 15786 for (BroadcastQueue queue : mBroadcastQueues) { 15787 queue.backgroundServicesFinishedLocked(userId); 15788 } 15789 } 15790 15791 public void finishReceiver(IBinder who, int resultCode, String resultData, 15792 Bundle resultExtras, boolean resultAbort) { 15793 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15794 15795 // Refuse possible leaked file descriptors 15796 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15797 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15798 } 15799 15800 final long origId = Binder.clearCallingIdentity(); 15801 try { 15802 boolean doNext = false; 15803 BroadcastRecord r; 15804 15805 synchronized(this) { 15806 r = broadcastRecordForReceiverLocked(who); 15807 if (r != null) { 15808 doNext = r.queue.finishReceiverLocked(r, resultCode, 15809 resultData, resultExtras, resultAbort, true); 15810 } 15811 } 15812 15813 if (doNext) { 15814 r.queue.processNextBroadcast(false); 15815 } 15816 trimApplications(); 15817 } finally { 15818 Binder.restoreCallingIdentity(origId); 15819 } 15820 } 15821 15822 // ========================================================= 15823 // INSTRUMENTATION 15824 // ========================================================= 15825 15826 public boolean startInstrumentation(ComponentName className, 15827 String profileFile, int flags, Bundle arguments, 15828 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15829 int userId, String abiOverride) { 15830 enforceNotIsolatedCaller("startInstrumentation"); 15831 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15832 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15833 // Refuse possible leaked file descriptors 15834 if (arguments != null && arguments.hasFileDescriptors()) { 15835 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15836 } 15837 15838 synchronized(this) { 15839 InstrumentationInfo ii = null; 15840 ApplicationInfo ai = null; 15841 try { 15842 ii = mContext.getPackageManager().getInstrumentationInfo( 15843 className, STOCK_PM_FLAGS); 15844 ai = AppGlobals.getPackageManager().getApplicationInfo( 15845 ii.targetPackage, STOCK_PM_FLAGS, userId); 15846 } catch (PackageManager.NameNotFoundException e) { 15847 } catch (RemoteException e) { 15848 } 15849 if (ii == null) { 15850 reportStartInstrumentationFailure(watcher, className, 15851 "Unable to find instrumentation info for: " + className); 15852 return false; 15853 } 15854 if (ai == null) { 15855 reportStartInstrumentationFailure(watcher, className, 15856 "Unable to find instrumentation target package: " + ii.targetPackage); 15857 return false; 15858 } 15859 15860 int match = mContext.getPackageManager().checkSignatures( 15861 ii.targetPackage, ii.packageName); 15862 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15863 String msg = "Permission Denial: starting instrumentation " 15864 + className + " from pid=" 15865 + Binder.getCallingPid() 15866 + ", uid=" + Binder.getCallingPid() 15867 + " not allowed because package " + ii.packageName 15868 + " does not have a signature matching the target " 15869 + ii.targetPackage; 15870 reportStartInstrumentationFailure(watcher, className, msg); 15871 throw new SecurityException(msg); 15872 } 15873 15874 final long origId = Binder.clearCallingIdentity(); 15875 // Instrumentation can kill and relaunch even persistent processes 15876 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15877 "start instr"); 15878 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15879 app.instrumentationClass = className; 15880 app.instrumentationInfo = ai; 15881 app.instrumentationProfileFile = profileFile; 15882 app.instrumentationArguments = arguments; 15883 app.instrumentationWatcher = watcher; 15884 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15885 app.instrumentationResultClass = className; 15886 Binder.restoreCallingIdentity(origId); 15887 } 15888 15889 return true; 15890 } 15891 15892 /** 15893 * Report errors that occur while attempting to start Instrumentation. Always writes the 15894 * error to the logs, but if somebody is watching, send the report there too. This enables 15895 * the "am" command to report errors with more information. 15896 * 15897 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15898 * @param cn The component name of the instrumentation. 15899 * @param report The error report. 15900 */ 15901 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15902 ComponentName cn, String report) { 15903 Slog.w(TAG, report); 15904 try { 15905 if (watcher != null) { 15906 Bundle results = new Bundle(); 15907 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15908 results.putString("Error", report); 15909 watcher.instrumentationStatus(cn, -1, results); 15910 } 15911 } catch (RemoteException e) { 15912 Slog.w(TAG, e); 15913 } 15914 } 15915 15916 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15917 if (app.instrumentationWatcher != null) { 15918 try { 15919 // NOTE: IInstrumentationWatcher *must* be oneway here 15920 app.instrumentationWatcher.instrumentationFinished( 15921 app.instrumentationClass, 15922 resultCode, 15923 results); 15924 } catch (RemoteException e) { 15925 } 15926 } 15927 if (app.instrumentationUiAutomationConnection != null) { 15928 try { 15929 app.instrumentationUiAutomationConnection.shutdown(); 15930 } catch (RemoteException re) { 15931 /* ignore */ 15932 } 15933 // Only a UiAutomation can set this flag and now that 15934 // it is finished we make sure it is reset to its default. 15935 mUserIsMonkey = false; 15936 } 15937 app.instrumentationWatcher = null; 15938 app.instrumentationUiAutomationConnection = null; 15939 app.instrumentationClass = null; 15940 app.instrumentationInfo = null; 15941 app.instrumentationProfileFile = null; 15942 app.instrumentationArguments = null; 15943 15944 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15945 "finished inst"); 15946 } 15947 15948 public void finishInstrumentation(IApplicationThread target, 15949 int resultCode, Bundle results) { 15950 int userId = UserHandle.getCallingUserId(); 15951 // Refuse possible leaked file descriptors 15952 if (results != null && results.hasFileDescriptors()) { 15953 throw new IllegalArgumentException("File descriptors passed in Intent"); 15954 } 15955 15956 synchronized(this) { 15957 ProcessRecord app = getRecordForAppLocked(target); 15958 if (app == null) { 15959 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15960 return; 15961 } 15962 final long origId = Binder.clearCallingIdentity(); 15963 finishInstrumentationLocked(app, resultCode, results); 15964 Binder.restoreCallingIdentity(origId); 15965 } 15966 } 15967 15968 // ========================================================= 15969 // CONFIGURATION 15970 // ========================================================= 15971 15972 public ConfigurationInfo getDeviceConfigurationInfo() { 15973 ConfigurationInfo config = new ConfigurationInfo(); 15974 synchronized (this) { 15975 config.reqTouchScreen = mConfiguration.touchscreen; 15976 config.reqKeyboardType = mConfiguration.keyboard; 15977 config.reqNavigation = mConfiguration.navigation; 15978 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15979 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15980 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15981 } 15982 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15983 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15984 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15985 } 15986 config.reqGlEsVersion = GL_ES_VERSION; 15987 } 15988 return config; 15989 } 15990 15991 ActivityStack getFocusedStack() { 15992 return mStackSupervisor.getFocusedStack(); 15993 } 15994 15995 public Configuration getConfiguration() { 15996 Configuration ci; 15997 synchronized(this) { 15998 ci = new Configuration(mConfiguration); 15999 } 16000 return ci; 16001 } 16002 16003 public void updatePersistentConfiguration(Configuration values) { 16004 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16005 "updateConfiguration()"); 16006 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16007 "updateConfiguration()"); 16008 if (values == null) { 16009 throw new NullPointerException("Configuration must not be null"); 16010 } 16011 16012 synchronized(this) { 16013 final long origId = Binder.clearCallingIdentity(); 16014 updateConfigurationLocked(values, null, true, false); 16015 Binder.restoreCallingIdentity(origId); 16016 } 16017 } 16018 16019 public void updateConfiguration(Configuration values) { 16020 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16021 "updateConfiguration()"); 16022 16023 synchronized(this) { 16024 if (values == null && mWindowManager != null) { 16025 // sentinel: fetch the current configuration from the window manager 16026 values = mWindowManager.computeNewConfiguration(); 16027 } 16028 16029 if (mWindowManager != null) { 16030 mProcessList.applyDisplaySize(mWindowManager); 16031 } 16032 16033 final long origId = Binder.clearCallingIdentity(); 16034 if (values != null) { 16035 Settings.System.clearConfiguration(values); 16036 } 16037 updateConfigurationLocked(values, null, false, false); 16038 Binder.restoreCallingIdentity(origId); 16039 } 16040 } 16041 16042 /** 16043 * Do either or both things: (1) change the current configuration, and (2) 16044 * make sure the given activity is running with the (now) current 16045 * configuration. Returns true if the activity has been left running, or 16046 * false if <var>starting</var> is being destroyed to match the new 16047 * configuration. 16048 * @param persistent TODO 16049 */ 16050 boolean updateConfigurationLocked(Configuration values, 16051 ActivityRecord starting, boolean persistent, boolean initLocale) { 16052 int changes = 0; 16053 16054 if (values != null) { 16055 Configuration newConfig = new Configuration(mConfiguration); 16056 changes = newConfig.updateFrom(values); 16057 if (changes != 0) { 16058 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16059 Slog.i(TAG, "Updating configuration to: " + values); 16060 } 16061 16062 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16063 16064 if (values.locale != null && !initLocale) { 16065 saveLocaleLocked(values.locale, 16066 !values.locale.equals(mConfiguration.locale), 16067 values.userSetLocale); 16068 } 16069 16070 mConfigurationSeq++; 16071 if (mConfigurationSeq <= 0) { 16072 mConfigurationSeq = 1; 16073 } 16074 newConfig.seq = mConfigurationSeq; 16075 mConfiguration = newConfig; 16076 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16077 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16078 //mUsageStatsService.noteStartConfig(newConfig); 16079 16080 final Configuration configCopy = new Configuration(mConfiguration); 16081 16082 // TODO: If our config changes, should we auto dismiss any currently 16083 // showing dialogs? 16084 mShowDialogs = shouldShowDialogs(newConfig); 16085 16086 AttributeCache ac = AttributeCache.instance(); 16087 if (ac != null) { 16088 ac.updateConfiguration(configCopy); 16089 } 16090 16091 // Make sure all resources in our process are updated 16092 // right now, so that anyone who is going to retrieve 16093 // resource values after we return will be sure to get 16094 // the new ones. This is especially important during 16095 // boot, where the first config change needs to guarantee 16096 // all resources have that config before following boot 16097 // code is executed. 16098 mSystemThread.applyConfigurationToResources(configCopy); 16099 16100 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16101 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16102 msg.obj = new Configuration(configCopy); 16103 mHandler.sendMessage(msg); 16104 } 16105 16106 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16107 ProcessRecord app = mLruProcesses.get(i); 16108 try { 16109 if (app.thread != null) { 16110 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16111 + app.processName + " new config " + mConfiguration); 16112 app.thread.scheduleConfigurationChanged(configCopy); 16113 } 16114 } catch (Exception e) { 16115 } 16116 } 16117 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16118 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16119 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16120 | Intent.FLAG_RECEIVER_FOREGROUND); 16121 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16122 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16123 Process.SYSTEM_UID, UserHandle.USER_ALL); 16124 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16125 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16126 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16127 broadcastIntentLocked(null, null, intent, 16128 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16129 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16130 } 16131 } 16132 } 16133 16134 boolean kept = true; 16135 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16136 // mainStack is null during startup. 16137 if (mainStack != null) { 16138 if (changes != 0 && starting == null) { 16139 // If the configuration changed, and the caller is not already 16140 // in the process of starting an activity, then find the top 16141 // activity to check if its configuration needs to change. 16142 starting = mainStack.topRunningActivityLocked(null); 16143 } 16144 16145 if (starting != null) { 16146 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16147 // And we need to make sure at this point that all other activities 16148 // are made visible with the correct configuration. 16149 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16150 } 16151 } 16152 16153 if (values != null && mWindowManager != null) { 16154 mWindowManager.setNewConfiguration(mConfiguration); 16155 } 16156 16157 return kept; 16158 } 16159 16160 /** 16161 * Decide based on the configuration whether we should shouw the ANR, 16162 * crash, etc dialogs. The idea is that if there is no affordnace to 16163 * press the on-screen buttons, we shouldn't show the dialog. 16164 * 16165 * A thought: SystemUI might also want to get told about this, the Power 16166 * dialog / global actions also might want different behaviors. 16167 */ 16168 private static final boolean shouldShowDialogs(Configuration config) { 16169 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16170 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16171 } 16172 16173 /** 16174 * Save the locale. You must be inside a synchronized (this) block. 16175 */ 16176 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16177 if(isDiff) { 16178 SystemProperties.set("user.language", l.getLanguage()); 16179 SystemProperties.set("user.region", l.getCountry()); 16180 } 16181 16182 if(isPersist) { 16183 SystemProperties.set("persist.sys.language", l.getLanguage()); 16184 SystemProperties.set("persist.sys.country", l.getCountry()); 16185 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16186 } 16187 } 16188 16189 @Override 16190 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16191 synchronized (this) { 16192 ActivityRecord srec = ActivityRecord.forToken(token); 16193 if (srec.task != null && srec.task.stack != null) { 16194 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16195 } 16196 } 16197 return false; 16198 } 16199 16200 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16201 Intent resultData) { 16202 16203 synchronized (this) { 16204 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16205 if (stack != null) { 16206 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16207 } 16208 return false; 16209 } 16210 } 16211 16212 public int getLaunchedFromUid(IBinder activityToken) { 16213 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16214 if (srec == null) { 16215 return -1; 16216 } 16217 return srec.launchedFromUid; 16218 } 16219 16220 public String getLaunchedFromPackage(IBinder activityToken) { 16221 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16222 if (srec == null) { 16223 return null; 16224 } 16225 return srec.launchedFromPackage; 16226 } 16227 16228 // ========================================================= 16229 // LIFETIME MANAGEMENT 16230 // ========================================================= 16231 16232 // Returns which broadcast queue the app is the current [or imminent] receiver 16233 // on, or 'null' if the app is not an active broadcast recipient. 16234 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16235 BroadcastRecord r = app.curReceiver; 16236 if (r != null) { 16237 return r.queue; 16238 } 16239 16240 // It's not the current receiver, but it might be starting up to become one 16241 synchronized (this) { 16242 for (BroadcastQueue queue : mBroadcastQueues) { 16243 r = queue.mPendingBroadcast; 16244 if (r != null && r.curApp == app) { 16245 // found it; report which queue it's in 16246 return queue; 16247 } 16248 } 16249 } 16250 16251 return null; 16252 } 16253 16254 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16255 boolean doingAll, long now) { 16256 if (mAdjSeq == app.adjSeq) { 16257 // This adjustment has already been computed. 16258 return app.curRawAdj; 16259 } 16260 16261 if (app.thread == null) { 16262 app.adjSeq = mAdjSeq; 16263 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16264 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16265 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16266 } 16267 16268 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16269 app.adjSource = null; 16270 app.adjTarget = null; 16271 app.empty = false; 16272 app.cached = false; 16273 16274 final int activitiesSize = app.activities.size(); 16275 16276 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16277 // The max adjustment doesn't allow this app to be anything 16278 // below foreground, so it is not worth doing work for it. 16279 app.adjType = "fixed"; 16280 app.adjSeq = mAdjSeq; 16281 app.curRawAdj = app.maxAdj; 16282 app.foregroundActivities = false; 16283 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16284 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16285 // System processes can do UI, and when they do we want to have 16286 // them trim their memory after the user leaves the UI. To 16287 // facilitate this, here we need to determine whether or not it 16288 // is currently showing UI. 16289 app.systemNoUi = true; 16290 if (app == TOP_APP) { 16291 app.systemNoUi = false; 16292 } else if (activitiesSize > 0) { 16293 for (int j = 0; j < activitiesSize; j++) { 16294 final ActivityRecord r = app.activities.get(j); 16295 if (r.visible) { 16296 app.systemNoUi = false; 16297 } 16298 } 16299 } 16300 if (!app.systemNoUi) { 16301 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16302 } 16303 return (app.curAdj=app.maxAdj); 16304 } 16305 16306 app.systemNoUi = false; 16307 16308 // Determine the importance of the process, starting with most 16309 // important to least, and assign an appropriate OOM adjustment. 16310 int adj; 16311 int schedGroup; 16312 int procState; 16313 boolean foregroundActivities = false; 16314 BroadcastQueue queue; 16315 if (app == TOP_APP) { 16316 // The last app on the list is the foreground app. 16317 adj = ProcessList.FOREGROUND_APP_ADJ; 16318 schedGroup = Process.THREAD_GROUP_DEFAULT; 16319 app.adjType = "top-activity"; 16320 foregroundActivities = true; 16321 procState = ActivityManager.PROCESS_STATE_TOP; 16322 } else if (app.instrumentationClass != null) { 16323 // Don't want to kill running instrumentation. 16324 adj = ProcessList.FOREGROUND_APP_ADJ; 16325 schedGroup = Process.THREAD_GROUP_DEFAULT; 16326 app.adjType = "instrumentation"; 16327 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16328 } else if ((queue = isReceivingBroadcast(app)) != null) { 16329 // An app that is currently receiving a broadcast also 16330 // counts as being in the foreground for OOM killer purposes. 16331 // It's placed in a sched group based on the nature of the 16332 // broadcast as reflected by which queue it's active in. 16333 adj = ProcessList.FOREGROUND_APP_ADJ; 16334 schedGroup = (queue == mFgBroadcastQueue) 16335 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16336 app.adjType = "broadcast"; 16337 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16338 } else if (app.executingServices.size() > 0) { 16339 // An app that is currently executing a service callback also 16340 // counts as being in the foreground. 16341 adj = ProcessList.FOREGROUND_APP_ADJ; 16342 schedGroup = app.execServicesFg ? 16343 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16344 app.adjType = "exec-service"; 16345 procState = ActivityManager.PROCESS_STATE_SERVICE; 16346 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16347 } else { 16348 // As far as we know the process is empty. We may change our mind later. 16349 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16350 // At this point we don't actually know the adjustment. Use the cached adj 16351 // value that the caller wants us to. 16352 adj = cachedAdj; 16353 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16354 app.cached = true; 16355 app.empty = true; 16356 app.adjType = "cch-empty"; 16357 } 16358 16359 // Examine all activities if not already foreground. 16360 if (!foregroundActivities && activitiesSize > 0) { 16361 for (int j = 0; j < activitiesSize; j++) { 16362 final ActivityRecord r = app.activities.get(j); 16363 if (r.app != app) { 16364 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16365 + app + "?!?"); 16366 continue; 16367 } 16368 if (r.visible) { 16369 // App has a visible activity; only upgrade adjustment. 16370 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16371 adj = ProcessList.VISIBLE_APP_ADJ; 16372 app.adjType = "visible"; 16373 } 16374 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16375 procState = ActivityManager.PROCESS_STATE_TOP; 16376 } 16377 schedGroup = Process.THREAD_GROUP_DEFAULT; 16378 app.cached = false; 16379 app.empty = false; 16380 foregroundActivities = true; 16381 break; 16382 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16383 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16384 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16385 app.adjType = "pausing"; 16386 } 16387 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16388 procState = ActivityManager.PROCESS_STATE_TOP; 16389 } 16390 schedGroup = Process.THREAD_GROUP_DEFAULT; 16391 app.cached = false; 16392 app.empty = false; 16393 foregroundActivities = true; 16394 } else if (r.state == ActivityState.STOPPING) { 16395 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16396 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16397 app.adjType = "stopping"; 16398 } 16399 // For the process state, we will at this point consider the 16400 // process to be cached. It will be cached either as an activity 16401 // or empty depending on whether the activity is finishing. We do 16402 // this so that we can treat the process as cached for purposes of 16403 // memory trimming (determing current memory level, trim command to 16404 // send to process) since there can be an arbitrary number of stopping 16405 // processes and they should soon all go into the cached state. 16406 if (!r.finishing) { 16407 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16408 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16409 } 16410 } 16411 app.cached = false; 16412 app.empty = false; 16413 foregroundActivities = true; 16414 } else { 16415 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16416 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16417 app.adjType = "cch-act"; 16418 } 16419 } 16420 } 16421 } 16422 16423 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16424 if (app.foregroundServices) { 16425 // The user is aware of this app, so make it visible. 16426 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16427 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16428 app.cached = false; 16429 app.adjType = "fg-service"; 16430 schedGroup = Process.THREAD_GROUP_DEFAULT; 16431 } else if (app.forcingToForeground != null) { 16432 // The user is aware of this app, so make it visible. 16433 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16434 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16435 app.cached = false; 16436 app.adjType = "force-fg"; 16437 app.adjSource = app.forcingToForeground; 16438 schedGroup = Process.THREAD_GROUP_DEFAULT; 16439 } 16440 } 16441 16442 if (app == mHeavyWeightProcess) { 16443 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16444 // We don't want to kill the current heavy-weight process. 16445 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16446 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16447 app.cached = false; 16448 app.adjType = "heavy"; 16449 } 16450 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16451 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16452 } 16453 } 16454 16455 if (app == mHomeProcess) { 16456 if (adj > ProcessList.HOME_APP_ADJ) { 16457 // This process is hosting what we currently consider to be the 16458 // home app, so we don't want to let it go into the background. 16459 adj = ProcessList.HOME_APP_ADJ; 16460 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16461 app.cached = false; 16462 app.adjType = "home"; 16463 } 16464 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16465 procState = ActivityManager.PROCESS_STATE_HOME; 16466 } 16467 } 16468 16469 if (app == mPreviousProcess && app.activities.size() > 0) { 16470 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16471 // This was the previous process that showed UI to the user. 16472 // We want to try to keep it around more aggressively, to give 16473 // a good experience around switching between two apps. 16474 adj = ProcessList.PREVIOUS_APP_ADJ; 16475 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16476 app.cached = false; 16477 app.adjType = "previous"; 16478 } 16479 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16480 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16481 } 16482 } 16483 16484 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16485 + " reason=" + app.adjType); 16486 16487 // By default, we use the computed adjustment. It may be changed if 16488 // there are applications dependent on our services or providers, but 16489 // this gives us a baseline and makes sure we don't get into an 16490 // infinite recursion. 16491 app.adjSeq = mAdjSeq; 16492 app.curRawAdj = adj; 16493 app.hasStartedServices = false; 16494 16495 if (mBackupTarget != null && app == mBackupTarget.app) { 16496 // If possible we want to avoid killing apps while they're being backed up 16497 if (adj > ProcessList.BACKUP_APP_ADJ) { 16498 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16499 adj = ProcessList.BACKUP_APP_ADJ; 16500 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16501 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16502 } 16503 app.adjType = "backup"; 16504 app.cached = false; 16505 } 16506 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16507 procState = ActivityManager.PROCESS_STATE_BACKUP; 16508 } 16509 } 16510 16511 boolean mayBeTop = false; 16512 16513 for (int is = app.services.size()-1; 16514 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16515 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16516 || procState > ActivityManager.PROCESS_STATE_TOP); 16517 is--) { 16518 ServiceRecord s = app.services.valueAt(is); 16519 if (s.startRequested) { 16520 app.hasStartedServices = true; 16521 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16522 procState = ActivityManager.PROCESS_STATE_SERVICE; 16523 } 16524 if (app.hasShownUi && app != mHomeProcess) { 16525 // If this process has shown some UI, let it immediately 16526 // go to the LRU list because it may be pretty heavy with 16527 // UI stuff. We'll tag it with a label just to help 16528 // debug and understand what is going on. 16529 if (adj > ProcessList.SERVICE_ADJ) { 16530 app.adjType = "cch-started-ui-services"; 16531 } 16532 } else { 16533 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16534 // This service has seen some activity within 16535 // recent memory, so we will keep its process ahead 16536 // of the background processes. 16537 if (adj > ProcessList.SERVICE_ADJ) { 16538 adj = ProcessList.SERVICE_ADJ; 16539 app.adjType = "started-services"; 16540 app.cached = false; 16541 } 16542 } 16543 // If we have let the service slide into the background 16544 // state, still have some text describing what it is doing 16545 // even though the service no longer has an impact. 16546 if (adj > ProcessList.SERVICE_ADJ) { 16547 app.adjType = "cch-started-services"; 16548 } 16549 } 16550 } 16551 for (int conni = s.connections.size()-1; 16552 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16553 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16554 || procState > ActivityManager.PROCESS_STATE_TOP); 16555 conni--) { 16556 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16557 for (int i = 0; 16558 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16559 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16560 || procState > ActivityManager.PROCESS_STATE_TOP); 16561 i++) { 16562 // XXX should compute this based on the max of 16563 // all connected clients. 16564 ConnectionRecord cr = clist.get(i); 16565 if (cr.binding.client == app) { 16566 // Binding to ourself is not interesting. 16567 continue; 16568 } 16569 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16570 ProcessRecord client = cr.binding.client; 16571 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16572 TOP_APP, doingAll, now); 16573 int clientProcState = client.curProcState; 16574 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16575 // If the other app is cached for any reason, for purposes here 16576 // we are going to consider it empty. The specific cached state 16577 // doesn't propagate except under certain conditions. 16578 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16579 } 16580 String adjType = null; 16581 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16582 // Not doing bind OOM management, so treat 16583 // this guy more like a started service. 16584 if (app.hasShownUi && app != mHomeProcess) { 16585 // If this process has shown some UI, let it immediately 16586 // go to the LRU list because it may be pretty heavy with 16587 // UI stuff. We'll tag it with a label just to help 16588 // debug and understand what is going on. 16589 if (adj > clientAdj) { 16590 adjType = "cch-bound-ui-services"; 16591 } 16592 app.cached = false; 16593 clientAdj = adj; 16594 clientProcState = procState; 16595 } else { 16596 if (now >= (s.lastActivity 16597 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16598 // This service has not seen activity within 16599 // recent memory, so allow it to drop to the 16600 // LRU list if there is no other reason to keep 16601 // it around. We'll also tag it with a label just 16602 // to help debug and undertand what is going on. 16603 if (adj > clientAdj) { 16604 adjType = "cch-bound-services"; 16605 } 16606 clientAdj = adj; 16607 } 16608 } 16609 } 16610 if (adj > clientAdj) { 16611 // If this process has recently shown UI, and 16612 // the process that is binding to it is less 16613 // important than being visible, then we don't 16614 // care about the binding as much as we care 16615 // about letting this process get into the LRU 16616 // list to be killed and restarted if needed for 16617 // memory. 16618 if (app.hasShownUi && app != mHomeProcess 16619 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16620 adjType = "cch-bound-ui-services"; 16621 } else { 16622 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16623 |Context.BIND_IMPORTANT)) != 0) { 16624 adj = clientAdj; 16625 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16626 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16627 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16628 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16629 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16630 adj = clientAdj; 16631 } else { 16632 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16633 adj = ProcessList.VISIBLE_APP_ADJ; 16634 } 16635 } 16636 if (!client.cached) { 16637 app.cached = false; 16638 } 16639 adjType = "service"; 16640 } 16641 } 16642 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16643 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16644 schedGroup = Process.THREAD_GROUP_DEFAULT; 16645 } 16646 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16647 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16648 // Special handling of clients who are in the top state. 16649 // We *may* want to consider this process to be in the 16650 // top state as well, but only if there is not another 16651 // reason for it to be running. Being on the top is a 16652 // special state, meaning you are specifically running 16653 // for the current top app. If the process is already 16654 // running in the background for some other reason, it 16655 // is more important to continue considering it to be 16656 // in the background state. 16657 mayBeTop = true; 16658 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16659 } else { 16660 // Special handling for above-top states (persistent 16661 // processes). These should not bring the current process 16662 // into the top state, since they are not on top. Instead 16663 // give them the best state after that. 16664 clientProcState = 16665 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16666 } 16667 } 16668 } else { 16669 if (clientProcState < 16670 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16671 clientProcState = 16672 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16673 } 16674 } 16675 if (procState > clientProcState) { 16676 procState = clientProcState; 16677 } 16678 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16679 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16680 app.pendingUiClean = true; 16681 } 16682 if (adjType != null) { 16683 app.adjType = adjType; 16684 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16685 .REASON_SERVICE_IN_USE; 16686 app.adjSource = cr.binding.client; 16687 app.adjSourceProcState = clientProcState; 16688 app.adjTarget = s.name; 16689 } 16690 } 16691 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16692 app.treatLikeActivity = true; 16693 } 16694 final ActivityRecord a = cr.activity; 16695 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16696 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16697 (a.visible || a.state == ActivityState.RESUMED 16698 || a.state == ActivityState.PAUSING)) { 16699 adj = ProcessList.FOREGROUND_APP_ADJ; 16700 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16701 schedGroup = Process.THREAD_GROUP_DEFAULT; 16702 } 16703 app.cached = false; 16704 app.adjType = "service"; 16705 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16706 .REASON_SERVICE_IN_USE; 16707 app.adjSource = a; 16708 app.adjSourceProcState = procState; 16709 app.adjTarget = s.name; 16710 } 16711 } 16712 } 16713 } 16714 } 16715 16716 for (int provi = app.pubProviders.size()-1; 16717 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16718 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16719 || procState > ActivityManager.PROCESS_STATE_TOP); 16720 provi--) { 16721 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16722 for (int i = cpr.connections.size()-1; 16723 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16724 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16725 || procState > ActivityManager.PROCESS_STATE_TOP); 16726 i--) { 16727 ContentProviderConnection conn = cpr.connections.get(i); 16728 ProcessRecord client = conn.client; 16729 if (client == app) { 16730 // Being our own client is not interesting. 16731 continue; 16732 } 16733 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16734 int clientProcState = client.curProcState; 16735 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16736 // If the other app is cached for any reason, for purposes here 16737 // we are going to consider it empty. 16738 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16739 } 16740 if (adj > clientAdj) { 16741 if (app.hasShownUi && app != mHomeProcess 16742 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16743 app.adjType = "cch-ui-provider"; 16744 } else { 16745 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16746 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16747 app.adjType = "provider"; 16748 } 16749 app.cached &= client.cached; 16750 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16751 .REASON_PROVIDER_IN_USE; 16752 app.adjSource = client; 16753 app.adjSourceProcState = clientProcState; 16754 app.adjTarget = cpr.name; 16755 } 16756 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16757 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16758 // Special handling of clients who are in the top state. 16759 // We *may* want to consider this process to be in the 16760 // top state as well, but only if there is not another 16761 // reason for it to be running. Being on the top is a 16762 // special state, meaning you are specifically running 16763 // for the current top app. If the process is already 16764 // running in the background for some other reason, it 16765 // is more important to continue considering it to be 16766 // in the background state. 16767 mayBeTop = true; 16768 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16769 } else { 16770 // Special handling for above-top states (persistent 16771 // processes). These should not bring the current process 16772 // into the top state, since they are not on top. Instead 16773 // give them the best state after that. 16774 clientProcState = 16775 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16776 } 16777 } 16778 if (procState > clientProcState) { 16779 procState = clientProcState; 16780 } 16781 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16782 schedGroup = Process.THREAD_GROUP_DEFAULT; 16783 } 16784 } 16785 // If the provider has external (non-framework) process 16786 // dependencies, ensure that its adjustment is at least 16787 // FOREGROUND_APP_ADJ. 16788 if (cpr.hasExternalProcessHandles()) { 16789 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16790 adj = ProcessList.FOREGROUND_APP_ADJ; 16791 schedGroup = Process.THREAD_GROUP_DEFAULT; 16792 app.cached = false; 16793 app.adjType = "provider"; 16794 app.adjTarget = cpr.name; 16795 } 16796 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16797 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16798 } 16799 } 16800 } 16801 16802 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16803 // A client of one of our services or providers is in the top state. We 16804 // *may* want to be in the top state, but not if we are already running in 16805 // the background for some other reason. For the decision here, we are going 16806 // to pick out a few specific states that we want to remain in when a client 16807 // is top (states that tend to be longer-term) and otherwise allow it to go 16808 // to the top state. 16809 switch (procState) { 16810 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16811 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16812 case ActivityManager.PROCESS_STATE_SERVICE: 16813 // These all are longer-term states, so pull them up to the top 16814 // of the background states, but not all the way to the top state. 16815 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16816 break; 16817 default: 16818 // Otherwise, top is a better choice, so take it. 16819 procState = ActivityManager.PROCESS_STATE_TOP; 16820 break; 16821 } 16822 } 16823 16824 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16825 if (app.hasClientActivities) { 16826 // This is a cached process, but with client activities. Mark it so. 16827 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16828 app.adjType = "cch-client-act"; 16829 } else if (app.treatLikeActivity) { 16830 // This is a cached process, but somebody wants us to treat it like it has 16831 // an activity, okay! 16832 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16833 app.adjType = "cch-as-act"; 16834 } 16835 } 16836 16837 if (adj == ProcessList.SERVICE_ADJ) { 16838 if (doingAll) { 16839 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16840 mNewNumServiceProcs++; 16841 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16842 if (!app.serviceb) { 16843 // This service isn't far enough down on the LRU list to 16844 // normally be a B service, but if we are low on RAM and it 16845 // is large we want to force it down since we would prefer to 16846 // keep launcher over it. 16847 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16848 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16849 app.serviceHighRam = true; 16850 app.serviceb = true; 16851 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16852 } else { 16853 mNewNumAServiceProcs++; 16854 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16855 } 16856 } else { 16857 app.serviceHighRam = false; 16858 } 16859 } 16860 if (app.serviceb) { 16861 adj = ProcessList.SERVICE_B_ADJ; 16862 } 16863 } 16864 16865 app.curRawAdj = adj; 16866 16867 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16868 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16869 if (adj > app.maxAdj) { 16870 adj = app.maxAdj; 16871 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16872 schedGroup = Process.THREAD_GROUP_DEFAULT; 16873 } 16874 } 16875 16876 // Do final modification to adj. Everything we do between here and applying 16877 // the final setAdj must be done in this function, because we will also use 16878 // it when computing the final cached adj later. Note that we don't need to 16879 // worry about this for max adj above, since max adj will always be used to 16880 // keep it out of the cached vaues. 16881 app.curAdj = app.modifyRawOomAdj(adj); 16882 app.curSchedGroup = schedGroup; 16883 app.curProcState = procState; 16884 app.foregroundActivities = foregroundActivities; 16885 16886 return app.curRawAdj; 16887 } 16888 16889 /** 16890 * Schedule PSS collection of a process. 16891 */ 16892 void requestPssLocked(ProcessRecord proc, int procState) { 16893 if (mPendingPssProcesses.contains(proc)) { 16894 return; 16895 } 16896 if (mPendingPssProcesses.size() == 0) { 16897 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16898 } 16899 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16900 proc.pssProcState = procState; 16901 mPendingPssProcesses.add(proc); 16902 } 16903 16904 /** 16905 * Schedule PSS collection of all processes. 16906 */ 16907 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16908 if (!always) { 16909 if (now < (mLastFullPssTime + 16910 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16911 return; 16912 } 16913 } 16914 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16915 mLastFullPssTime = now; 16916 mFullPssPending = true; 16917 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16918 mPendingPssProcesses.clear(); 16919 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16920 ProcessRecord app = mLruProcesses.get(i); 16921 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16922 app.pssProcState = app.setProcState; 16923 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16924 isSleeping(), now); 16925 mPendingPssProcesses.add(app); 16926 } 16927 } 16928 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16929 } 16930 16931 /** 16932 * Ask a given process to GC right now. 16933 */ 16934 final void performAppGcLocked(ProcessRecord app) { 16935 try { 16936 app.lastRequestedGc = SystemClock.uptimeMillis(); 16937 if (app.thread != null) { 16938 if (app.reportLowMemory) { 16939 app.reportLowMemory = false; 16940 app.thread.scheduleLowMemory(); 16941 } else { 16942 app.thread.processInBackground(); 16943 } 16944 } 16945 } catch (Exception e) { 16946 // whatever. 16947 } 16948 } 16949 16950 /** 16951 * Returns true if things are idle enough to perform GCs. 16952 */ 16953 private final boolean canGcNowLocked() { 16954 boolean processingBroadcasts = false; 16955 for (BroadcastQueue q : mBroadcastQueues) { 16956 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16957 processingBroadcasts = true; 16958 } 16959 } 16960 return !processingBroadcasts 16961 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16962 } 16963 16964 /** 16965 * Perform GCs on all processes that are waiting for it, but only 16966 * if things are idle. 16967 */ 16968 final void performAppGcsLocked() { 16969 final int N = mProcessesToGc.size(); 16970 if (N <= 0) { 16971 return; 16972 } 16973 if (canGcNowLocked()) { 16974 while (mProcessesToGc.size() > 0) { 16975 ProcessRecord proc = mProcessesToGc.remove(0); 16976 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16977 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16978 <= SystemClock.uptimeMillis()) { 16979 // To avoid spamming the system, we will GC processes one 16980 // at a time, waiting a few seconds between each. 16981 performAppGcLocked(proc); 16982 scheduleAppGcsLocked(); 16983 return; 16984 } else { 16985 // It hasn't been long enough since we last GCed this 16986 // process... put it in the list to wait for its time. 16987 addProcessToGcListLocked(proc); 16988 break; 16989 } 16990 } 16991 } 16992 16993 scheduleAppGcsLocked(); 16994 } 16995 } 16996 16997 /** 16998 * If all looks good, perform GCs on all processes waiting for them. 16999 */ 17000 final void performAppGcsIfAppropriateLocked() { 17001 if (canGcNowLocked()) { 17002 performAppGcsLocked(); 17003 return; 17004 } 17005 // Still not idle, wait some more. 17006 scheduleAppGcsLocked(); 17007 } 17008 17009 /** 17010 * Schedule the execution of all pending app GCs. 17011 */ 17012 final void scheduleAppGcsLocked() { 17013 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17014 17015 if (mProcessesToGc.size() > 0) { 17016 // Schedule a GC for the time to the next process. 17017 ProcessRecord proc = mProcessesToGc.get(0); 17018 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17019 17020 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17021 long now = SystemClock.uptimeMillis(); 17022 if (when < (now+GC_TIMEOUT)) { 17023 when = now + GC_TIMEOUT; 17024 } 17025 mHandler.sendMessageAtTime(msg, when); 17026 } 17027 } 17028 17029 /** 17030 * Add a process to the array of processes waiting to be GCed. Keeps the 17031 * list in sorted order by the last GC time. The process can't already be 17032 * on the list. 17033 */ 17034 final void addProcessToGcListLocked(ProcessRecord proc) { 17035 boolean added = false; 17036 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17037 if (mProcessesToGc.get(i).lastRequestedGc < 17038 proc.lastRequestedGc) { 17039 added = true; 17040 mProcessesToGc.add(i+1, proc); 17041 break; 17042 } 17043 } 17044 if (!added) { 17045 mProcessesToGc.add(0, proc); 17046 } 17047 } 17048 17049 /** 17050 * Set up to ask a process to GC itself. This will either do it 17051 * immediately, or put it on the list of processes to gc the next 17052 * time things are idle. 17053 */ 17054 final void scheduleAppGcLocked(ProcessRecord app) { 17055 long now = SystemClock.uptimeMillis(); 17056 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17057 return; 17058 } 17059 if (!mProcessesToGc.contains(app)) { 17060 addProcessToGcListLocked(app); 17061 scheduleAppGcsLocked(); 17062 } 17063 } 17064 17065 final void checkExcessivePowerUsageLocked(boolean doKills) { 17066 updateCpuStatsNow(); 17067 17068 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17069 boolean doWakeKills = doKills; 17070 boolean doCpuKills = doKills; 17071 if (mLastPowerCheckRealtime == 0) { 17072 doWakeKills = false; 17073 } 17074 if (mLastPowerCheckUptime == 0) { 17075 doCpuKills = false; 17076 } 17077 if (stats.isScreenOn()) { 17078 doWakeKills = false; 17079 } 17080 final long curRealtime = SystemClock.elapsedRealtime(); 17081 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17082 final long curUptime = SystemClock.uptimeMillis(); 17083 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17084 mLastPowerCheckRealtime = curRealtime; 17085 mLastPowerCheckUptime = curUptime; 17086 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17087 doWakeKills = false; 17088 } 17089 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17090 doCpuKills = false; 17091 } 17092 int i = mLruProcesses.size(); 17093 while (i > 0) { 17094 i--; 17095 ProcessRecord app = mLruProcesses.get(i); 17096 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17097 long wtime; 17098 synchronized (stats) { 17099 wtime = stats.getProcessWakeTime(app.info.uid, 17100 app.pid, curRealtime); 17101 } 17102 long wtimeUsed = wtime - app.lastWakeTime; 17103 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17104 if (DEBUG_POWER) { 17105 StringBuilder sb = new StringBuilder(128); 17106 sb.append("Wake for "); 17107 app.toShortString(sb); 17108 sb.append(": over "); 17109 TimeUtils.formatDuration(realtimeSince, sb); 17110 sb.append(" used "); 17111 TimeUtils.formatDuration(wtimeUsed, sb); 17112 sb.append(" ("); 17113 sb.append((wtimeUsed*100)/realtimeSince); 17114 sb.append("%)"); 17115 Slog.i(TAG, sb.toString()); 17116 sb.setLength(0); 17117 sb.append("CPU for "); 17118 app.toShortString(sb); 17119 sb.append(": over "); 17120 TimeUtils.formatDuration(uptimeSince, sb); 17121 sb.append(" used "); 17122 TimeUtils.formatDuration(cputimeUsed, sb); 17123 sb.append(" ("); 17124 sb.append((cputimeUsed*100)/uptimeSince); 17125 sb.append("%)"); 17126 Slog.i(TAG, sb.toString()); 17127 } 17128 // If a process has held a wake lock for more 17129 // than 50% of the time during this period, 17130 // that sounds bad. Kill! 17131 if (doWakeKills && realtimeSince > 0 17132 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17133 synchronized (stats) { 17134 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17135 realtimeSince, wtimeUsed); 17136 } 17137 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17138 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17139 } else if (doCpuKills && uptimeSince > 0 17140 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17141 synchronized (stats) { 17142 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17143 uptimeSince, cputimeUsed); 17144 } 17145 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17146 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17147 } else { 17148 app.lastWakeTime = wtime; 17149 app.lastCpuTime = app.curCpuTime; 17150 } 17151 } 17152 } 17153 } 17154 17155 private final boolean applyOomAdjLocked(ProcessRecord app, 17156 ProcessRecord TOP_APP, boolean doingAll, long now) { 17157 boolean success = true; 17158 17159 if (app.curRawAdj != app.setRawAdj) { 17160 app.setRawAdj = app.curRawAdj; 17161 } 17162 17163 int changes = 0; 17164 17165 if (app.curAdj != app.setAdj) { 17166 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17167 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17168 TAG, "Set " + app.pid + " " + app.processName + 17169 " adj " + app.curAdj + ": " + app.adjType); 17170 app.setAdj = app.curAdj; 17171 } 17172 17173 if (app.setSchedGroup != app.curSchedGroup) { 17174 app.setSchedGroup = app.curSchedGroup; 17175 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17176 "Setting process group of " + app.processName 17177 + " to " + app.curSchedGroup); 17178 if (app.waitingToKill != null && 17179 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17180 app.kill(app.waitingToKill, true); 17181 success = false; 17182 } else { 17183 if (true) { 17184 long oldId = Binder.clearCallingIdentity(); 17185 try { 17186 Process.setProcessGroup(app.pid, app.curSchedGroup); 17187 } catch (Exception e) { 17188 Slog.w(TAG, "Failed setting process group of " + app.pid 17189 + " to " + app.curSchedGroup); 17190 e.printStackTrace(); 17191 } finally { 17192 Binder.restoreCallingIdentity(oldId); 17193 } 17194 } else { 17195 if (app.thread != null) { 17196 try { 17197 app.thread.setSchedulingGroup(app.curSchedGroup); 17198 } catch (RemoteException e) { 17199 } 17200 } 17201 } 17202 Process.setSwappiness(app.pid, 17203 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17204 } 17205 } 17206 if (app.repForegroundActivities != app.foregroundActivities) { 17207 app.repForegroundActivities = app.foregroundActivities; 17208 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17209 } 17210 if (app.repProcState != app.curProcState) { 17211 app.repProcState = app.curProcState; 17212 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17213 if (app.thread != null) { 17214 try { 17215 if (false) { 17216 //RuntimeException h = new RuntimeException("here"); 17217 Slog.i(TAG, "Sending new process state " + app.repProcState 17218 + " to " + app /*, h*/); 17219 } 17220 app.thread.setProcessState(app.repProcState); 17221 } catch (RemoteException e) { 17222 } 17223 } 17224 } 17225 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17226 app.setProcState)) { 17227 app.lastStateTime = now; 17228 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17229 isSleeping(), now); 17230 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17231 + ProcessList.makeProcStateString(app.setProcState) + " to " 17232 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17233 + (app.nextPssTime-now) + ": " + app); 17234 } else { 17235 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17236 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17237 requestPssLocked(app, app.setProcState); 17238 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17239 isSleeping(), now); 17240 } else if (false && DEBUG_PSS) { 17241 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17242 } 17243 } 17244 if (app.setProcState != app.curProcState) { 17245 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17246 "Proc state change of " + app.processName 17247 + " to " + app.curProcState); 17248 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17249 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17250 if (setImportant && !curImportant) { 17251 // This app is no longer something we consider important enough to allow to 17252 // use arbitrary amounts of battery power. Note 17253 // its current wake lock time to later know to kill it if 17254 // it is not behaving well. 17255 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17256 synchronized (stats) { 17257 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17258 app.pid, SystemClock.elapsedRealtime()); 17259 } 17260 app.lastCpuTime = app.curCpuTime; 17261 17262 } 17263 app.setProcState = app.curProcState; 17264 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17265 app.notCachedSinceIdle = false; 17266 } 17267 if (!doingAll) { 17268 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17269 } else { 17270 app.procStateChanged = true; 17271 } 17272 } 17273 17274 if (changes != 0) { 17275 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17276 int i = mPendingProcessChanges.size()-1; 17277 ProcessChangeItem item = null; 17278 while (i >= 0) { 17279 item = mPendingProcessChanges.get(i); 17280 if (item.pid == app.pid) { 17281 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17282 break; 17283 } 17284 i--; 17285 } 17286 if (i < 0) { 17287 // No existing item in pending changes; need a new one. 17288 final int NA = mAvailProcessChanges.size(); 17289 if (NA > 0) { 17290 item = mAvailProcessChanges.remove(NA-1); 17291 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17292 } else { 17293 item = new ProcessChangeItem(); 17294 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17295 } 17296 item.changes = 0; 17297 item.pid = app.pid; 17298 item.uid = app.info.uid; 17299 if (mPendingProcessChanges.size() == 0) { 17300 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17301 "*** Enqueueing dispatch processes changed!"); 17302 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17303 } 17304 mPendingProcessChanges.add(item); 17305 } 17306 item.changes |= changes; 17307 item.processState = app.repProcState; 17308 item.foregroundActivities = app.repForegroundActivities; 17309 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17310 + Integer.toHexString(System.identityHashCode(item)) 17311 + " " + app.toShortString() + ": changes=" + item.changes 17312 + " procState=" + item.processState 17313 + " foreground=" + item.foregroundActivities 17314 + " type=" + app.adjType + " source=" + app.adjSource 17315 + " target=" + app.adjTarget); 17316 } 17317 17318 return success; 17319 } 17320 17321 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17322 if (proc.thread != null) { 17323 if (proc.baseProcessTracker != null) { 17324 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17325 } 17326 if (proc.repProcState >= 0) { 17327 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17328 proc.repProcState); 17329 } 17330 } 17331 } 17332 17333 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17334 ProcessRecord TOP_APP, boolean doingAll, long now) { 17335 if (app.thread == null) { 17336 return false; 17337 } 17338 17339 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17340 17341 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17342 } 17343 17344 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17345 boolean oomAdj) { 17346 if (isForeground != proc.foregroundServices) { 17347 proc.foregroundServices = isForeground; 17348 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17349 proc.info.uid); 17350 if (isForeground) { 17351 if (curProcs == null) { 17352 curProcs = new ArrayList<ProcessRecord>(); 17353 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17354 } 17355 if (!curProcs.contains(proc)) { 17356 curProcs.add(proc); 17357 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17358 proc.info.packageName, proc.info.uid); 17359 } 17360 } else { 17361 if (curProcs != null) { 17362 if (curProcs.remove(proc)) { 17363 mBatteryStatsService.noteEvent( 17364 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17365 proc.info.packageName, proc.info.uid); 17366 if (curProcs.size() <= 0) { 17367 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17368 } 17369 } 17370 } 17371 } 17372 if (oomAdj) { 17373 updateOomAdjLocked(); 17374 } 17375 } 17376 } 17377 17378 private final ActivityRecord resumedAppLocked() { 17379 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17380 String pkg; 17381 int uid; 17382 if (act != null) { 17383 pkg = act.packageName; 17384 uid = act.info.applicationInfo.uid; 17385 } else { 17386 pkg = null; 17387 uid = -1; 17388 } 17389 // Has the UID or resumed package name changed? 17390 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17391 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17392 if (mCurResumedPackage != null) { 17393 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17394 mCurResumedPackage, mCurResumedUid); 17395 } 17396 mCurResumedPackage = pkg; 17397 mCurResumedUid = uid; 17398 if (mCurResumedPackage != null) { 17399 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17400 mCurResumedPackage, mCurResumedUid); 17401 } 17402 } 17403 return act; 17404 } 17405 17406 final boolean updateOomAdjLocked(ProcessRecord app) { 17407 final ActivityRecord TOP_ACT = resumedAppLocked(); 17408 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17409 final boolean wasCached = app.cached; 17410 17411 mAdjSeq++; 17412 17413 // This is the desired cached adjusment we want to tell it to use. 17414 // If our app is currently cached, we know it, and that is it. Otherwise, 17415 // we don't know it yet, and it needs to now be cached we will then 17416 // need to do a complete oom adj. 17417 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17418 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17419 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17420 SystemClock.uptimeMillis()); 17421 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17422 // Changed to/from cached state, so apps after it in the LRU 17423 // list may also be changed. 17424 updateOomAdjLocked(); 17425 } 17426 return success; 17427 } 17428 17429 final void updateOomAdjLocked() { 17430 final ActivityRecord TOP_ACT = resumedAppLocked(); 17431 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17432 final long now = SystemClock.uptimeMillis(); 17433 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17434 final int N = mLruProcesses.size(); 17435 17436 if (false) { 17437 RuntimeException e = new RuntimeException(); 17438 e.fillInStackTrace(); 17439 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17440 } 17441 17442 mAdjSeq++; 17443 mNewNumServiceProcs = 0; 17444 mNewNumAServiceProcs = 0; 17445 17446 final int emptyProcessLimit; 17447 final int cachedProcessLimit; 17448 if (mProcessLimit <= 0) { 17449 emptyProcessLimit = cachedProcessLimit = 0; 17450 } else if (mProcessLimit == 1) { 17451 emptyProcessLimit = 1; 17452 cachedProcessLimit = 0; 17453 } else { 17454 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17455 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17456 } 17457 17458 // Let's determine how many processes we have running vs. 17459 // how many slots we have for background processes; we may want 17460 // to put multiple processes in a slot of there are enough of 17461 // them. 17462 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17463 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17464 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17465 if (numEmptyProcs > cachedProcessLimit) { 17466 // If there are more empty processes than our limit on cached 17467 // processes, then use the cached process limit for the factor. 17468 // This ensures that the really old empty processes get pushed 17469 // down to the bottom, so if we are running low on memory we will 17470 // have a better chance at keeping around more cached processes 17471 // instead of a gazillion empty processes. 17472 numEmptyProcs = cachedProcessLimit; 17473 } 17474 int emptyFactor = numEmptyProcs/numSlots; 17475 if (emptyFactor < 1) emptyFactor = 1; 17476 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17477 if (cachedFactor < 1) cachedFactor = 1; 17478 int stepCached = 0; 17479 int stepEmpty = 0; 17480 int numCached = 0; 17481 int numEmpty = 0; 17482 int numTrimming = 0; 17483 17484 mNumNonCachedProcs = 0; 17485 mNumCachedHiddenProcs = 0; 17486 17487 // First update the OOM adjustment for each of the 17488 // application processes based on their current state. 17489 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17490 int nextCachedAdj = curCachedAdj+1; 17491 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17492 int nextEmptyAdj = curEmptyAdj+2; 17493 for (int i=N-1; i>=0; i--) { 17494 ProcessRecord app = mLruProcesses.get(i); 17495 if (!app.killedByAm && app.thread != null) { 17496 app.procStateChanged = false; 17497 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17498 17499 // If we haven't yet assigned the final cached adj 17500 // to the process, do that now. 17501 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17502 switch (app.curProcState) { 17503 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17504 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17505 // This process is a cached process holding activities... 17506 // assign it the next cached value for that type, and then 17507 // step that cached level. 17508 app.curRawAdj = curCachedAdj; 17509 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17510 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17511 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17512 + ")"); 17513 if (curCachedAdj != nextCachedAdj) { 17514 stepCached++; 17515 if (stepCached >= cachedFactor) { 17516 stepCached = 0; 17517 curCachedAdj = nextCachedAdj; 17518 nextCachedAdj += 2; 17519 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17520 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17521 } 17522 } 17523 } 17524 break; 17525 default: 17526 // For everything else, assign next empty cached process 17527 // level and bump that up. Note that this means that 17528 // long-running services that have dropped down to the 17529 // cached level will be treated as empty (since their process 17530 // state is still as a service), which is what we want. 17531 app.curRawAdj = curEmptyAdj; 17532 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17533 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17534 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17535 + ")"); 17536 if (curEmptyAdj != nextEmptyAdj) { 17537 stepEmpty++; 17538 if (stepEmpty >= emptyFactor) { 17539 stepEmpty = 0; 17540 curEmptyAdj = nextEmptyAdj; 17541 nextEmptyAdj += 2; 17542 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17543 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17544 } 17545 } 17546 } 17547 break; 17548 } 17549 } 17550 17551 applyOomAdjLocked(app, TOP_APP, true, now); 17552 17553 // Count the number of process types. 17554 switch (app.curProcState) { 17555 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17556 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17557 mNumCachedHiddenProcs++; 17558 numCached++; 17559 if (numCached > cachedProcessLimit) { 17560 app.kill("cached #" + numCached, true); 17561 } 17562 break; 17563 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17564 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17565 && app.lastActivityTime < oldTime) { 17566 app.kill("empty for " 17567 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17568 / 1000) + "s", true); 17569 } else { 17570 numEmpty++; 17571 if (numEmpty > emptyProcessLimit) { 17572 app.kill("empty #" + numEmpty, true); 17573 } 17574 } 17575 break; 17576 default: 17577 mNumNonCachedProcs++; 17578 break; 17579 } 17580 17581 if (app.isolated && app.services.size() <= 0) { 17582 // If this is an isolated process, and there are no 17583 // services running in it, then the process is no longer 17584 // needed. We agressively kill these because we can by 17585 // definition not re-use the same process again, and it is 17586 // good to avoid having whatever code was running in them 17587 // left sitting around after no longer needed. 17588 app.kill("isolated not needed", true); 17589 } 17590 17591 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17592 && !app.killedByAm) { 17593 numTrimming++; 17594 } 17595 } 17596 } 17597 17598 mNumServiceProcs = mNewNumServiceProcs; 17599 17600 // Now determine the memory trimming level of background processes. 17601 // Unfortunately we need to start at the back of the list to do this 17602 // properly. We only do this if the number of background apps we 17603 // are managing to keep around is less than half the maximum we desire; 17604 // if we are keeping a good number around, we'll let them use whatever 17605 // memory they want. 17606 final int numCachedAndEmpty = numCached + numEmpty; 17607 int memFactor; 17608 if (numCached <= ProcessList.TRIM_CACHED_APPS 17609 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17610 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17611 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17612 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17613 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17614 } else { 17615 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17616 } 17617 } else { 17618 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17619 } 17620 // We always allow the memory level to go up (better). We only allow it to go 17621 // down if we are in a state where that is allowed, *and* the total number of processes 17622 // has gone down since last time. 17623 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17624 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17625 + " last=" + mLastNumProcesses); 17626 if (memFactor > mLastMemoryLevel) { 17627 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17628 memFactor = mLastMemoryLevel; 17629 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17630 } 17631 } 17632 mLastMemoryLevel = memFactor; 17633 mLastNumProcesses = mLruProcesses.size(); 17634 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17635 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17636 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17637 if (mLowRamStartTime == 0) { 17638 mLowRamStartTime = now; 17639 } 17640 int step = 0; 17641 int fgTrimLevel; 17642 switch (memFactor) { 17643 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17644 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17645 break; 17646 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17647 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17648 break; 17649 default: 17650 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17651 break; 17652 } 17653 int factor = numTrimming/3; 17654 int minFactor = 2; 17655 if (mHomeProcess != null) minFactor++; 17656 if (mPreviousProcess != null) minFactor++; 17657 if (factor < minFactor) factor = minFactor; 17658 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17659 for (int i=N-1; i>=0; i--) { 17660 ProcessRecord app = mLruProcesses.get(i); 17661 if (allChanged || app.procStateChanged) { 17662 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17663 app.procStateChanged = false; 17664 } 17665 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17666 && !app.killedByAm) { 17667 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17668 try { 17669 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17670 "Trimming memory of " + app.processName 17671 + " to " + curLevel); 17672 app.thread.scheduleTrimMemory(curLevel); 17673 } catch (RemoteException e) { 17674 } 17675 if (false) { 17676 // For now we won't do this; our memory trimming seems 17677 // to be good enough at this point that destroying 17678 // activities causes more harm than good. 17679 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17680 && app != mHomeProcess && app != mPreviousProcess) { 17681 // Need to do this on its own message because the stack may not 17682 // be in a consistent state at this point. 17683 // For these apps we will also finish their activities 17684 // to help them free memory. 17685 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17686 } 17687 } 17688 } 17689 app.trimMemoryLevel = curLevel; 17690 step++; 17691 if (step >= factor) { 17692 step = 0; 17693 switch (curLevel) { 17694 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17695 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17696 break; 17697 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17698 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17699 break; 17700 } 17701 } 17702 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17703 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17704 && app.thread != null) { 17705 try { 17706 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17707 "Trimming memory of heavy-weight " + app.processName 17708 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17709 app.thread.scheduleTrimMemory( 17710 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17711 } catch (RemoteException e) { 17712 } 17713 } 17714 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17715 } else { 17716 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17717 || app.systemNoUi) && app.pendingUiClean) { 17718 // If this application is now in the background and it 17719 // had done UI, then give it the special trim level to 17720 // have it free UI resources. 17721 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17722 if (app.trimMemoryLevel < level && app.thread != null) { 17723 try { 17724 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17725 "Trimming memory of bg-ui " + app.processName 17726 + " to " + level); 17727 app.thread.scheduleTrimMemory(level); 17728 } catch (RemoteException e) { 17729 } 17730 } 17731 app.pendingUiClean = false; 17732 } 17733 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17734 try { 17735 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17736 "Trimming memory of fg " + app.processName 17737 + " to " + fgTrimLevel); 17738 app.thread.scheduleTrimMemory(fgTrimLevel); 17739 } catch (RemoteException e) { 17740 } 17741 } 17742 app.trimMemoryLevel = fgTrimLevel; 17743 } 17744 } 17745 } else { 17746 if (mLowRamStartTime != 0) { 17747 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17748 mLowRamStartTime = 0; 17749 } 17750 for (int i=N-1; i>=0; i--) { 17751 ProcessRecord app = mLruProcesses.get(i); 17752 if (allChanged || app.procStateChanged) { 17753 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17754 app.procStateChanged = false; 17755 } 17756 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17757 || app.systemNoUi) && app.pendingUiClean) { 17758 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17759 && app.thread != null) { 17760 try { 17761 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17762 "Trimming memory of ui hidden " + app.processName 17763 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17764 app.thread.scheduleTrimMemory( 17765 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17766 } catch (RemoteException e) { 17767 } 17768 } 17769 app.pendingUiClean = false; 17770 } 17771 app.trimMemoryLevel = 0; 17772 } 17773 } 17774 17775 if (mAlwaysFinishActivities) { 17776 // Need to do this on its own message because the stack may not 17777 // be in a consistent state at this point. 17778 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17779 } 17780 17781 if (allChanged) { 17782 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17783 } 17784 17785 if (mProcessStats.shouldWriteNowLocked(now)) { 17786 mHandler.post(new Runnable() { 17787 @Override public void run() { 17788 synchronized (ActivityManagerService.this) { 17789 mProcessStats.writeStateAsyncLocked(); 17790 } 17791 } 17792 }); 17793 } 17794 17795 if (DEBUG_OOM_ADJ) { 17796 if (false) { 17797 RuntimeException here = new RuntimeException("here"); 17798 here.fillInStackTrace(); 17799 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17800 } else { 17801 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17802 } 17803 } 17804 } 17805 17806 final void trimApplications() { 17807 synchronized (this) { 17808 int i; 17809 17810 // First remove any unused application processes whose package 17811 // has been removed. 17812 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17813 final ProcessRecord app = mRemovedProcesses.get(i); 17814 if (app.activities.size() == 0 17815 && app.curReceiver == null && app.services.size() == 0) { 17816 Slog.i( 17817 TAG, "Exiting empty application process " 17818 + app.processName + " (" 17819 + (app.thread != null ? app.thread.asBinder() : null) 17820 + ")\n"); 17821 if (app.pid > 0 && app.pid != MY_PID) { 17822 app.kill("empty", false); 17823 } else { 17824 try { 17825 app.thread.scheduleExit(); 17826 } catch (Exception e) { 17827 // Ignore exceptions. 17828 } 17829 } 17830 cleanUpApplicationRecordLocked(app, false, true, -1); 17831 mRemovedProcesses.remove(i); 17832 17833 if (app.persistent) { 17834 addAppLocked(app.info, false, null /* ABI override */); 17835 } 17836 } 17837 } 17838 17839 // Now update the oom adj for all processes. 17840 updateOomAdjLocked(); 17841 } 17842 } 17843 17844 /** This method sends the specified signal to each of the persistent apps */ 17845 public void signalPersistentProcesses(int sig) throws RemoteException { 17846 if (sig != Process.SIGNAL_USR1) { 17847 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17848 } 17849 17850 synchronized (this) { 17851 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17852 != PackageManager.PERMISSION_GRANTED) { 17853 throw new SecurityException("Requires permission " 17854 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17855 } 17856 17857 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17858 ProcessRecord r = mLruProcesses.get(i); 17859 if (r.thread != null && r.persistent) { 17860 Process.sendSignal(r.pid, sig); 17861 } 17862 } 17863 } 17864 } 17865 17866 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17867 if (proc == null || proc == mProfileProc) { 17868 proc = mProfileProc; 17869 profileType = mProfileType; 17870 clearProfilerLocked(); 17871 } 17872 if (proc == null) { 17873 return; 17874 } 17875 try { 17876 proc.thread.profilerControl(false, null, profileType); 17877 } catch (RemoteException e) { 17878 throw new IllegalStateException("Process disappeared"); 17879 } 17880 } 17881 17882 private void clearProfilerLocked() { 17883 if (mProfileFd != null) { 17884 try { 17885 mProfileFd.close(); 17886 } catch (IOException e) { 17887 } 17888 } 17889 mProfileApp = null; 17890 mProfileProc = null; 17891 mProfileFile = null; 17892 mProfileType = 0; 17893 mAutoStopProfiler = false; 17894 mSamplingInterval = 0; 17895 } 17896 17897 public boolean profileControl(String process, int userId, boolean start, 17898 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17899 17900 try { 17901 synchronized (this) { 17902 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17903 // its own permission. 17904 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17905 != PackageManager.PERMISSION_GRANTED) { 17906 throw new SecurityException("Requires permission " 17907 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17908 } 17909 17910 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17911 throw new IllegalArgumentException("null profile info or fd"); 17912 } 17913 17914 ProcessRecord proc = null; 17915 if (process != null) { 17916 proc = findProcessLocked(process, userId, "profileControl"); 17917 } 17918 17919 if (start && (proc == null || proc.thread == null)) { 17920 throw new IllegalArgumentException("Unknown process: " + process); 17921 } 17922 17923 if (start) { 17924 stopProfilerLocked(null, 0); 17925 setProfileApp(proc.info, proc.processName, profilerInfo); 17926 mProfileProc = proc; 17927 mProfileType = profileType; 17928 ParcelFileDescriptor fd = profilerInfo.profileFd; 17929 try { 17930 fd = fd.dup(); 17931 } catch (IOException e) { 17932 fd = null; 17933 } 17934 profilerInfo.profileFd = fd; 17935 proc.thread.profilerControl(start, profilerInfo, profileType); 17936 fd = null; 17937 mProfileFd = null; 17938 } else { 17939 stopProfilerLocked(proc, profileType); 17940 if (profilerInfo != null && profilerInfo.profileFd != null) { 17941 try { 17942 profilerInfo.profileFd.close(); 17943 } catch (IOException e) { 17944 } 17945 } 17946 } 17947 17948 return true; 17949 } 17950 } catch (RemoteException e) { 17951 throw new IllegalStateException("Process disappeared"); 17952 } finally { 17953 if (profilerInfo != null && profilerInfo.profileFd != null) { 17954 try { 17955 profilerInfo.profileFd.close(); 17956 } catch (IOException e) { 17957 } 17958 } 17959 } 17960 } 17961 17962 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17963 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17964 userId, true, ALLOW_FULL_ONLY, callName, null); 17965 ProcessRecord proc = null; 17966 try { 17967 int pid = Integer.parseInt(process); 17968 synchronized (mPidsSelfLocked) { 17969 proc = mPidsSelfLocked.get(pid); 17970 } 17971 } catch (NumberFormatException e) { 17972 } 17973 17974 if (proc == null) { 17975 ArrayMap<String, SparseArray<ProcessRecord>> all 17976 = mProcessNames.getMap(); 17977 SparseArray<ProcessRecord> procs = all.get(process); 17978 if (procs != null && procs.size() > 0) { 17979 proc = procs.valueAt(0); 17980 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17981 for (int i=1; i<procs.size(); i++) { 17982 ProcessRecord thisProc = procs.valueAt(i); 17983 if (thisProc.userId == userId) { 17984 proc = thisProc; 17985 break; 17986 } 17987 } 17988 } 17989 } 17990 } 17991 17992 return proc; 17993 } 17994 17995 public boolean dumpHeap(String process, int userId, boolean managed, 17996 String path, ParcelFileDescriptor fd) throws RemoteException { 17997 17998 try { 17999 synchronized (this) { 18000 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18001 // its own permission (same as profileControl). 18002 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18003 != PackageManager.PERMISSION_GRANTED) { 18004 throw new SecurityException("Requires permission " 18005 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18006 } 18007 18008 if (fd == null) { 18009 throw new IllegalArgumentException("null fd"); 18010 } 18011 18012 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18013 if (proc == null || proc.thread == null) { 18014 throw new IllegalArgumentException("Unknown process: " + process); 18015 } 18016 18017 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18018 if (!isDebuggable) { 18019 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18020 throw new SecurityException("Process not debuggable: " + proc); 18021 } 18022 } 18023 18024 proc.thread.dumpHeap(managed, path, fd); 18025 fd = null; 18026 return true; 18027 } 18028 } catch (RemoteException e) { 18029 throw new IllegalStateException("Process disappeared"); 18030 } finally { 18031 if (fd != null) { 18032 try { 18033 fd.close(); 18034 } catch (IOException e) { 18035 } 18036 } 18037 } 18038 } 18039 18040 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18041 public void monitor() { 18042 synchronized (this) { } 18043 } 18044 18045 void onCoreSettingsChange(Bundle settings) { 18046 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18047 ProcessRecord processRecord = mLruProcesses.get(i); 18048 try { 18049 if (processRecord.thread != null) { 18050 processRecord.thread.setCoreSettings(settings); 18051 } 18052 } catch (RemoteException re) { 18053 /* ignore */ 18054 } 18055 } 18056 } 18057 18058 // Multi-user methods 18059 18060 /** 18061 * Start user, if its not already running, but don't bring it to foreground. 18062 */ 18063 @Override 18064 public boolean startUserInBackground(final int userId) { 18065 return startUser(userId, /* foreground */ false); 18066 } 18067 18068 /** 18069 * Start user, if its not already running, and bring it to foreground. 18070 */ 18071 boolean startUserInForeground(final int userId, Dialog dlg) { 18072 boolean result = startUser(userId, /* foreground */ true); 18073 dlg.dismiss(); 18074 return result; 18075 } 18076 18077 /** 18078 * Refreshes the list of users related to the current user when either a 18079 * user switch happens or when a new related user is started in the 18080 * background. 18081 */ 18082 private void updateCurrentProfileIdsLocked() { 18083 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18084 mCurrentUserId, false /* enabledOnly */); 18085 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18086 for (int i = 0; i < currentProfileIds.length; i++) { 18087 currentProfileIds[i] = profiles.get(i).id; 18088 } 18089 mCurrentProfileIds = currentProfileIds; 18090 18091 synchronized (mUserProfileGroupIdsSelfLocked) { 18092 mUserProfileGroupIdsSelfLocked.clear(); 18093 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18094 for (int i = 0; i < users.size(); i++) { 18095 UserInfo user = users.get(i); 18096 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18097 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18098 } 18099 } 18100 } 18101 } 18102 18103 private Set getProfileIdsLocked(int userId) { 18104 Set userIds = new HashSet<Integer>(); 18105 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18106 userId, false /* enabledOnly */); 18107 for (UserInfo user : profiles) { 18108 userIds.add(Integer.valueOf(user.id)); 18109 } 18110 return userIds; 18111 } 18112 18113 @Override 18114 public boolean switchUser(final int userId) { 18115 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18116 String userName; 18117 synchronized (this) { 18118 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18119 if (userInfo == null) { 18120 Slog.w(TAG, "No user info for user #" + userId); 18121 return false; 18122 } 18123 if (userInfo.isManagedProfile()) { 18124 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18125 return false; 18126 } 18127 userName = userInfo.name; 18128 mTargetUserId = userId; 18129 } 18130 mHandler.removeMessages(START_USER_SWITCH_MSG); 18131 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18132 return true; 18133 } 18134 18135 private void showUserSwitchDialog(int userId, String userName) { 18136 // The dialog will show and then initiate the user switch by calling startUserInForeground 18137 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18138 true /* above system */); 18139 d.show(); 18140 } 18141 18142 private boolean startUser(final int userId, final boolean foreground) { 18143 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18144 != PackageManager.PERMISSION_GRANTED) { 18145 String msg = "Permission Denial: switchUser() from pid=" 18146 + Binder.getCallingPid() 18147 + ", uid=" + Binder.getCallingUid() 18148 + " requires " + INTERACT_ACROSS_USERS_FULL; 18149 Slog.w(TAG, msg); 18150 throw new SecurityException(msg); 18151 } 18152 18153 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18154 18155 final long ident = Binder.clearCallingIdentity(); 18156 try { 18157 synchronized (this) { 18158 final int oldUserId = mCurrentUserId; 18159 if (oldUserId == userId) { 18160 return true; 18161 } 18162 18163 mStackSupervisor.setLockTaskModeLocked(null, false); 18164 18165 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18166 if (userInfo == null) { 18167 Slog.w(TAG, "No user info for user #" + userId); 18168 return false; 18169 } 18170 if (foreground && userInfo.isManagedProfile()) { 18171 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18172 return false; 18173 } 18174 18175 if (foreground) { 18176 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18177 R.anim.screen_user_enter); 18178 } 18179 18180 boolean needStart = false; 18181 18182 // If the user we are switching to is not currently started, then 18183 // we need to start it now. 18184 if (mStartedUsers.get(userId) == null) { 18185 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18186 updateStartedUserArrayLocked(); 18187 needStart = true; 18188 } 18189 18190 final Integer userIdInt = Integer.valueOf(userId); 18191 mUserLru.remove(userIdInt); 18192 mUserLru.add(userIdInt); 18193 18194 if (foreground) { 18195 mCurrentUserId = userId; 18196 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18197 updateCurrentProfileIdsLocked(); 18198 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18199 // Once the internal notion of the active user has switched, we lock the device 18200 // with the option to show the user switcher on the keyguard. 18201 mWindowManager.lockNow(null); 18202 } else { 18203 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18204 updateCurrentProfileIdsLocked(); 18205 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18206 mUserLru.remove(currentUserIdInt); 18207 mUserLru.add(currentUserIdInt); 18208 } 18209 18210 final UserStartedState uss = mStartedUsers.get(userId); 18211 18212 // Make sure user is in the started state. If it is currently 18213 // stopping, we need to knock that off. 18214 if (uss.mState == UserStartedState.STATE_STOPPING) { 18215 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18216 // so we can just fairly silently bring the user back from 18217 // the almost-dead. 18218 uss.mState = UserStartedState.STATE_RUNNING; 18219 updateStartedUserArrayLocked(); 18220 needStart = true; 18221 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18222 // This means ACTION_SHUTDOWN has been sent, so we will 18223 // need to treat this as a new boot of the user. 18224 uss.mState = UserStartedState.STATE_BOOTING; 18225 updateStartedUserArrayLocked(); 18226 needStart = true; 18227 } 18228 18229 if (uss.mState == UserStartedState.STATE_BOOTING) { 18230 // Booting up a new user, need to tell system services about it. 18231 // Note that this is on the same handler as scheduling of broadcasts, 18232 // which is important because it needs to go first. 18233 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18234 } 18235 18236 if (foreground) { 18237 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18238 oldUserId)); 18239 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18240 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18241 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18242 oldUserId, userId, uss)); 18243 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18244 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18245 } 18246 18247 if (needStart) { 18248 // Send USER_STARTED broadcast 18249 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18250 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18251 | Intent.FLAG_RECEIVER_FOREGROUND); 18252 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18253 broadcastIntentLocked(null, null, intent, 18254 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18255 false, false, MY_PID, Process.SYSTEM_UID, userId); 18256 } 18257 18258 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18259 if (userId != UserHandle.USER_OWNER) { 18260 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18261 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18262 broadcastIntentLocked(null, null, intent, null, 18263 new IIntentReceiver.Stub() { 18264 public void performReceive(Intent intent, int resultCode, 18265 String data, Bundle extras, boolean ordered, 18266 boolean sticky, int sendingUser) { 18267 onUserInitialized(uss, foreground, oldUserId, userId); 18268 } 18269 }, 0, null, null, null, AppOpsManager.OP_NONE, 18270 true, false, MY_PID, Process.SYSTEM_UID, 18271 userId); 18272 uss.initializing = true; 18273 } else { 18274 getUserManagerLocked().makeInitialized(userInfo.id); 18275 } 18276 } 18277 18278 if (foreground) { 18279 if (!uss.initializing) { 18280 moveUserToForeground(uss, oldUserId, userId); 18281 } 18282 } else { 18283 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18284 } 18285 18286 if (needStart) { 18287 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18288 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18289 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18290 broadcastIntentLocked(null, null, intent, 18291 null, new IIntentReceiver.Stub() { 18292 @Override 18293 public void performReceive(Intent intent, int resultCode, String data, 18294 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18295 throws RemoteException { 18296 } 18297 }, 0, null, null, 18298 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18299 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18300 } 18301 } 18302 } finally { 18303 Binder.restoreCallingIdentity(ident); 18304 } 18305 18306 return true; 18307 } 18308 18309 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18310 long ident = Binder.clearCallingIdentity(); 18311 try { 18312 Intent intent; 18313 if (oldUserId >= 0) { 18314 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18315 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18316 int count = profiles.size(); 18317 for (int i = 0; i < count; i++) { 18318 int profileUserId = profiles.get(i).id; 18319 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18320 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18321 | Intent.FLAG_RECEIVER_FOREGROUND); 18322 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18323 broadcastIntentLocked(null, null, intent, 18324 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18325 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18326 } 18327 } 18328 if (newUserId >= 0) { 18329 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18330 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18331 int count = profiles.size(); 18332 for (int i = 0; i < count; i++) { 18333 int profileUserId = profiles.get(i).id; 18334 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18335 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18336 | Intent.FLAG_RECEIVER_FOREGROUND); 18337 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18338 broadcastIntentLocked(null, null, intent, 18339 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18340 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18341 } 18342 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18343 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18344 | Intent.FLAG_RECEIVER_FOREGROUND); 18345 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18346 broadcastIntentLocked(null, null, intent, 18347 null, null, 0, null, null, 18348 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18349 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18350 } 18351 } finally { 18352 Binder.restoreCallingIdentity(ident); 18353 } 18354 } 18355 18356 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18357 final int newUserId) { 18358 final int N = mUserSwitchObservers.beginBroadcast(); 18359 if (N > 0) { 18360 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18361 int mCount = 0; 18362 @Override 18363 public void sendResult(Bundle data) throws RemoteException { 18364 synchronized (ActivityManagerService.this) { 18365 if (mCurUserSwitchCallback == this) { 18366 mCount++; 18367 if (mCount == N) { 18368 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18369 } 18370 } 18371 } 18372 } 18373 }; 18374 synchronized (this) { 18375 uss.switching = true; 18376 mCurUserSwitchCallback = callback; 18377 } 18378 for (int i=0; i<N; i++) { 18379 try { 18380 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18381 newUserId, callback); 18382 } catch (RemoteException e) { 18383 } 18384 } 18385 } else { 18386 synchronized (this) { 18387 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18388 } 18389 } 18390 mUserSwitchObservers.finishBroadcast(); 18391 } 18392 18393 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18394 synchronized (this) { 18395 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18396 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18397 } 18398 } 18399 18400 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18401 mCurUserSwitchCallback = null; 18402 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18403 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18404 oldUserId, newUserId, uss)); 18405 } 18406 18407 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18408 synchronized (this) { 18409 if (foreground) { 18410 moveUserToForeground(uss, oldUserId, newUserId); 18411 } 18412 } 18413 18414 completeSwitchAndInitalize(uss, newUserId, true, false); 18415 } 18416 18417 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18418 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18419 if (homeInFront) { 18420 startHomeActivityLocked(newUserId); 18421 } else { 18422 mStackSupervisor.resumeTopActivitiesLocked(); 18423 } 18424 EventLogTags.writeAmSwitchUser(newUserId); 18425 getUserManagerLocked().userForeground(newUserId); 18426 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18427 } 18428 18429 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18430 completeSwitchAndInitalize(uss, newUserId, false, true); 18431 } 18432 18433 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18434 boolean clearInitializing, boolean clearSwitching) { 18435 boolean unfrozen = false; 18436 synchronized (this) { 18437 if (clearInitializing) { 18438 uss.initializing = false; 18439 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18440 } 18441 if (clearSwitching) { 18442 uss.switching = false; 18443 } 18444 if (!uss.switching && !uss.initializing) { 18445 mWindowManager.stopFreezingScreen(); 18446 unfrozen = true; 18447 } 18448 } 18449 if (unfrozen) { 18450 final int N = mUserSwitchObservers.beginBroadcast(); 18451 for (int i=0; i<N; i++) { 18452 try { 18453 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18454 } catch (RemoteException e) { 18455 } 18456 } 18457 mUserSwitchObservers.finishBroadcast(); 18458 } 18459 } 18460 18461 void scheduleStartProfilesLocked() { 18462 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18463 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18464 DateUtils.SECOND_IN_MILLIS); 18465 } 18466 } 18467 18468 void startProfilesLocked() { 18469 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18470 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18471 mCurrentUserId, false /* enabledOnly */); 18472 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18473 for (UserInfo user : profiles) { 18474 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18475 && user.id != mCurrentUserId) { 18476 toStart.add(user); 18477 } 18478 } 18479 final int n = toStart.size(); 18480 int i = 0; 18481 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18482 startUserInBackground(toStart.get(i).id); 18483 } 18484 if (i < n) { 18485 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18486 } 18487 } 18488 18489 void finishUserBoot(UserStartedState uss) { 18490 synchronized (this) { 18491 if (uss.mState == UserStartedState.STATE_BOOTING 18492 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18493 uss.mState = UserStartedState.STATE_RUNNING; 18494 final int userId = uss.mHandle.getIdentifier(); 18495 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18496 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18497 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18498 broadcastIntentLocked(null, null, intent, 18499 null, null, 0, null, null, 18500 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18501 true, false, MY_PID, Process.SYSTEM_UID, userId); 18502 } 18503 } 18504 } 18505 18506 void finishUserSwitch(UserStartedState uss) { 18507 synchronized (this) { 18508 finishUserBoot(uss); 18509 18510 startProfilesLocked(); 18511 18512 int num = mUserLru.size(); 18513 int i = 0; 18514 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18515 Integer oldUserId = mUserLru.get(i); 18516 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18517 if (oldUss == null) { 18518 // Shouldn't happen, but be sane if it does. 18519 mUserLru.remove(i); 18520 num--; 18521 continue; 18522 } 18523 if (oldUss.mState == UserStartedState.STATE_STOPPING 18524 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18525 // This user is already stopping, doesn't count. 18526 num--; 18527 i++; 18528 continue; 18529 } 18530 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18531 // Owner and current can't be stopped, but count as running. 18532 i++; 18533 continue; 18534 } 18535 // This is a user to be stopped. 18536 stopUserLocked(oldUserId, null); 18537 num--; 18538 i++; 18539 } 18540 } 18541 } 18542 18543 @Override 18544 public int stopUser(final int userId, final IStopUserCallback callback) { 18545 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18546 != PackageManager.PERMISSION_GRANTED) { 18547 String msg = "Permission Denial: switchUser() from pid=" 18548 + Binder.getCallingPid() 18549 + ", uid=" + Binder.getCallingUid() 18550 + " requires " + INTERACT_ACROSS_USERS_FULL; 18551 Slog.w(TAG, msg); 18552 throw new SecurityException(msg); 18553 } 18554 if (userId <= 0) { 18555 throw new IllegalArgumentException("Can't stop primary user " + userId); 18556 } 18557 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18558 synchronized (this) { 18559 return stopUserLocked(userId, callback); 18560 } 18561 } 18562 18563 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18564 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18565 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18566 return ActivityManager.USER_OP_IS_CURRENT; 18567 } 18568 18569 final UserStartedState uss = mStartedUsers.get(userId); 18570 if (uss == null) { 18571 // User is not started, nothing to do... but we do need to 18572 // callback if requested. 18573 if (callback != null) { 18574 mHandler.post(new Runnable() { 18575 @Override 18576 public void run() { 18577 try { 18578 callback.userStopped(userId); 18579 } catch (RemoteException e) { 18580 } 18581 } 18582 }); 18583 } 18584 return ActivityManager.USER_OP_SUCCESS; 18585 } 18586 18587 if (callback != null) { 18588 uss.mStopCallbacks.add(callback); 18589 } 18590 18591 if (uss.mState != UserStartedState.STATE_STOPPING 18592 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18593 uss.mState = UserStartedState.STATE_STOPPING; 18594 updateStartedUserArrayLocked(); 18595 18596 long ident = Binder.clearCallingIdentity(); 18597 try { 18598 // We are going to broadcast ACTION_USER_STOPPING and then 18599 // once that is done send a final ACTION_SHUTDOWN and then 18600 // stop the user. 18601 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18602 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18603 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18604 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18605 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18606 // This is the result receiver for the final shutdown broadcast. 18607 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18608 @Override 18609 public void performReceive(Intent intent, int resultCode, String data, 18610 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18611 finishUserStop(uss); 18612 } 18613 }; 18614 // This is the result receiver for the initial stopping broadcast. 18615 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18616 @Override 18617 public void performReceive(Intent intent, int resultCode, String data, 18618 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18619 // On to the next. 18620 synchronized (ActivityManagerService.this) { 18621 if (uss.mState != UserStartedState.STATE_STOPPING) { 18622 // Whoops, we are being started back up. Abort, abort! 18623 return; 18624 } 18625 uss.mState = UserStartedState.STATE_SHUTDOWN; 18626 } 18627 mBatteryStatsService.noteEvent( 18628 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18629 Integer.toString(userId), userId); 18630 mSystemServiceManager.stopUser(userId); 18631 broadcastIntentLocked(null, null, shutdownIntent, 18632 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18633 true, false, MY_PID, Process.SYSTEM_UID, userId); 18634 } 18635 }; 18636 // Kick things off. 18637 broadcastIntentLocked(null, null, stoppingIntent, 18638 null, stoppingReceiver, 0, null, null, 18639 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18640 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18641 } finally { 18642 Binder.restoreCallingIdentity(ident); 18643 } 18644 } 18645 18646 return ActivityManager.USER_OP_SUCCESS; 18647 } 18648 18649 void finishUserStop(UserStartedState uss) { 18650 final int userId = uss.mHandle.getIdentifier(); 18651 boolean stopped; 18652 ArrayList<IStopUserCallback> callbacks; 18653 synchronized (this) { 18654 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18655 if (mStartedUsers.get(userId) != uss) { 18656 stopped = false; 18657 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18658 stopped = false; 18659 } else { 18660 stopped = true; 18661 // User can no longer run. 18662 mStartedUsers.remove(userId); 18663 mUserLru.remove(Integer.valueOf(userId)); 18664 updateStartedUserArrayLocked(); 18665 18666 // Clean up all state and processes associated with the user. 18667 // Kill all the processes for the user. 18668 forceStopUserLocked(userId, "finish user"); 18669 } 18670 18671 // Explicitly remove the old information in mRecentTasks. 18672 removeRecentTasksForUserLocked(userId); 18673 } 18674 18675 for (int i=0; i<callbacks.size(); i++) { 18676 try { 18677 if (stopped) callbacks.get(i).userStopped(userId); 18678 else callbacks.get(i).userStopAborted(userId); 18679 } catch (RemoteException e) { 18680 } 18681 } 18682 18683 if (stopped) { 18684 mSystemServiceManager.cleanupUser(userId); 18685 synchronized (this) { 18686 mStackSupervisor.removeUserLocked(userId); 18687 } 18688 } 18689 } 18690 18691 @Override 18692 public UserInfo getCurrentUser() { 18693 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18694 != PackageManager.PERMISSION_GRANTED) && ( 18695 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18696 != PackageManager.PERMISSION_GRANTED)) { 18697 String msg = "Permission Denial: getCurrentUser() from pid=" 18698 + Binder.getCallingPid() 18699 + ", uid=" + Binder.getCallingUid() 18700 + " requires " + INTERACT_ACROSS_USERS; 18701 Slog.w(TAG, msg); 18702 throw new SecurityException(msg); 18703 } 18704 synchronized (this) { 18705 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18706 return getUserManagerLocked().getUserInfo(userId); 18707 } 18708 } 18709 18710 int getCurrentUserIdLocked() { 18711 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18712 } 18713 18714 @Override 18715 public boolean isUserRunning(int userId, boolean orStopped) { 18716 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18717 != PackageManager.PERMISSION_GRANTED) { 18718 String msg = "Permission Denial: isUserRunning() from pid=" 18719 + Binder.getCallingPid() 18720 + ", uid=" + Binder.getCallingUid() 18721 + " requires " + INTERACT_ACROSS_USERS; 18722 Slog.w(TAG, msg); 18723 throw new SecurityException(msg); 18724 } 18725 synchronized (this) { 18726 return isUserRunningLocked(userId, orStopped); 18727 } 18728 } 18729 18730 boolean isUserRunningLocked(int userId, boolean orStopped) { 18731 UserStartedState state = mStartedUsers.get(userId); 18732 if (state == null) { 18733 return false; 18734 } 18735 if (orStopped) { 18736 return true; 18737 } 18738 return state.mState != UserStartedState.STATE_STOPPING 18739 && state.mState != UserStartedState.STATE_SHUTDOWN; 18740 } 18741 18742 @Override 18743 public int[] getRunningUserIds() { 18744 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18745 != PackageManager.PERMISSION_GRANTED) { 18746 String msg = "Permission Denial: isUserRunning() from pid=" 18747 + Binder.getCallingPid() 18748 + ", uid=" + Binder.getCallingUid() 18749 + " requires " + INTERACT_ACROSS_USERS; 18750 Slog.w(TAG, msg); 18751 throw new SecurityException(msg); 18752 } 18753 synchronized (this) { 18754 return mStartedUserArray; 18755 } 18756 } 18757 18758 private void updateStartedUserArrayLocked() { 18759 int num = 0; 18760 for (int i=0; i<mStartedUsers.size(); i++) { 18761 UserStartedState uss = mStartedUsers.valueAt(i); 18762 // This list does not include stopping users. 18763 if (uss.mState != UserStartedState.STATE_STOPPING 18764 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18765 num++; 18766 } 18767 } 18768 mStartedUserArray = new int[num]; 18769 num = 0; 18770 for (int i=0; i<mStartedUsers.size(); i++) { 18771 UserStartedState uss = mStartedUsers.valueAt(i); 18772 if (uss.mState != UserStartedState.STATE_STOPPING 18773 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18774 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18775 num++; 18776 } 18777 } 18778 } 18779 18780 @Override 18781 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18782 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18783 != PackageManager.PERMISSION_GRANTED) { 18784 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18785 + Binder.getCallingPid() 18786 + ", uid=" + Binder.getCallingUid() 18787 + " requires " + INTERACT_ACROSS_USERS_FULL; 18788 Slog.w(TAG, msg); 18789 throw new SecurityException(msg); 18790 } 18791 18792 mUserSwitchObservers.register(observer); 18793 } 18794 18795 @Override 18796 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18797 mUserSwitchObservers.unregister(observer); 18798 } 18799 18800 private boolean userExists(int userId) { 18801 if (userId == 0) { 18802 return true; 18803 } 18804 UserManagerService ums = getUserManagerLocked(); 18805 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18806 } 18807 18808 int[] getUsersLocked() { 18809 UserManagerService ums = getUserManagerLocked(); 18810 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18811 } 18812 18813 UserManagerService getUserManagerLocked() { 18814 if (mUserManager == null) { 18815 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18816 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18817 } 18818 return mUserManager; 18819 } 18820 18821 private int applyUserId(int uid, int userId) { 18822 return UserHandle.getUid(userId, uid); 18823 } 18824 18825 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18826 if (info == null) return null; 18827 ApplicationInfo newInfo = new ApplicationInfo(info); 18828 newInfo.uid = applyUserId(info.uid, userId); 18829 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18830 + info.packageName; 18831 return newInfo; 18832 } 18833 18834 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18835 if (aInfo == null 18836 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18837 return aInfo; 18838 } 18839 18840 ActivityInfo info = new ActivityInfo(aInfo); 18841 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18842 return info; 18843 } 18844 18845 private final class LocalService extends ActivityManagerInternal { 18846 @Override 18847 public void goingToSleep() { 18848 ActivityManagerService.this.goingToSleep(); 18849 } 18850 18851 @Override 18852 public void wakingUp() { 18853 ActivityManagerService.this.wakingUp(); 18854 } 18855 18856 @Override 18857 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18858 String processName, String abiOverride, int uid, Runnable crashHandler) { 18859 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18860 processName, abiOverride, uid, crashHandler); 18861 } 18862 } 18863 18864 /** 18865 * An implementation of IAppTask, that allows an app to manage its own tasks via 18866 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18867 * only the process that calls getAppTasks() can call the AppTask methods. 18868 */ 18869 class AppTaskImpl extends IAppTask.Stub { 18870 private int mTaskId; 18871 private int mCallingUid; 18872 18873 public AppTaskImpl(int taskId, int callingUid) { 18874 mTaskId = taskId; 18875 mCallingUid = callingUid; 18876 } 18877 18878 private void checkCaller() { 18879 if (mCallingUid != Binder.getCallingUid()) { 18880 throw new SecurityException("Caller " + mCallingUid 18881 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18882 } 18883 } 18884 18885 @Override 18886 public void finishAndRemoveTask() { 18887 checkCaller(); 18888 18889 synchronized (ActivityManagerService.this) { 18890 long origId = Binder.clearCallingIdentity(); 18891 try { 18892 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18893 if (tr == null) { 18894 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18895 } 18896 // Only kill the process if we are not a new document 18897 int flags = tr.getBaseIntent().getFlags(); 18898 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18899 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18900 removeTaskByIdLocked(mTaskId, 18901 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18902 } finally { 18903 Binder.restoreCallingIdentity(origId); 18904 } 18905 } 18906 } 18907 18908 @Override 18909 public ActivityManager.RecentTaskInfo getTaskInfo() { 18910 checkCaller(); 18911 18912 synchronized (ActivityManagerService.this) { 18913 long origId = Binder.clearCallingIdentity(); 18914 try { 18915 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18916 if (tr == null) { 18917 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18918 } 18919 return createRecentTaskInfoFromTaskRecord(tr); 18920 } finally { 18921 Binder.restoreCallingIdentity(origId); 18922 } 18923 } 18924 } 18925 18926 @Override 18927 public void moveToFront() { 18928 checkCaller(); 18929 18930 final TaskRecord tr; 18931 synchronized (ActivityManagerService.this) { 18932 tr = recentTaskForIdLocked(mTaskId); 18933 if (tr == null) { 18934 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18935 } 18936 if (tr.getRootActivity() != null) { 18937 long origId = Binder.clearCallingIdentity(); 18938 try { 18939 moveTaskToFrontLocked(tr.taskId, 0, null); 18940 return; 18941 } finally { 18942 Binder.restoreCallingIdentity(origId); 18943 } 18944 } 18945 } 18946 18947 startActivityFromRecentsInner(tr.taskId, null); 18948 } 18949 18950 @Override 18951 public int startActivity(IBinder whoThread, String callingPackage, 18952 Intent intent, String resolvedType, Bundle options) { 18953 checkCaller(); 18954 18955 int callingUser = UserHandle.getCallingUserId(); 18956 TaskRecord tr; 18957 IApplicationThread appThread; 18958 synchronized (ActivityManagerService.this) { 18959 tr = recentTaskForIdLocked(mTaskId); 18960 if (tr == null) { 18961 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18962 } 18963 appThread = ApplicationThreadNative.asInterface(whoThread); 18964 if (appThread == null) { 18965 throw new IllegalArgumentException("Bad app thread " + appThread); 18966 } 18967 } 18968 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18969 resolvedType, null, null, null, null, 0, 0, null, null, 18970 null, options, callingUser, null, tr); 18971 } 18972 18973 @Override 18974 public void setExcludeFromRecents(boolean exclude) { 18975 checkCaller(); 18976 18977 synchronized (ActivityManagerService.this) { 18978 long origId = Binder.clearCallingIdentity(); 18979 try { 18980 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18981 if (tr == null) { 18982 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18983 } 18984 Intent intent = tr.getBaseIntent(); 18985 if (exclude) { 18986 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18987 } else { 18988 intent.setFlags(intent.getFlags() 18989 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18990 } 18991 } finally { 18992 Binder.restoreCallingIdentity(origId); 18993 } 18994 } 18995 } 18996 } 18997} 18998