ActivityManagerService.java revision 337abb3b4e705b06f9385df063be4cc06604be04
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 (!app.killed) { 2620 Slog.wtf(TAG, "Removing process that hasn't been killed: " + app); 2621 Process.killProcessQuiet(app.pid); 2622 Process.killProcessGroup(app.info.uid, app.pid); 2623 } 2624 if (lrui <= mLruProcessActivityStart) { 2625 mLruProcessActivityStart--; 2626 } 2627 if (lrui <= mLruProcessServiceStart) { 2628 mLruProcessServiceStart--; 2629 } 2630 mLruProcesses.remove(lrui); 2631 } 2632 } 2633 2634 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2635 ProcessRecord client) { 2636 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2637 || app.treatLikeActivity; 2638 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2639 if (!activityChange && hasActivity) { 2640 // The process has activities, so we are only allowing activity-based adjustments 2641 // to move it. It should be kept in the front of the list with other 2642 // processes that have activities, and we don't want those to change their 2643 // order except due to activity operations. 2644 return; 2645 } 2646 2647 mLruSeq++; 2648 final long now = SystemClock.uptimeMillis(); 2649 app.lastActivityTime = now; 2650 2651 // First a quick reject: if the app is already at the position we will 2652 // put it, then there is nothing to do. 2653 if (hasActivity) { 2654 final int N = mLruProcesses.size(); 2655 if (N > 0 && mLruProcesses.get(N-1) == app) { 2656 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2657 return; 2658 } 2659 } else { 2660 if (mLruProcessServiceStart > 0 2661 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2662 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2663 return; 2664 } 2665 } 2666 2667 int lrui = mLruProcesses.lastIndexOf(app); 2668 2669 if (app.persistent && lrui >= 0) { 2670 // We don't care about the position of persistent processes, as long as 2671 // they are in the list. 2672 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2673 return; 2674 } 2675 2676 /* In progress: compute new position first, so we can avoid doing work 2677 if the process is not actually going to move. Not yet working. 2678 int addIndex; 2679 int nextIndex; 2680 boolean inActivity = false, inService = false; 2681 if (hasActivity) { 2682 // Process has activities, put it at the very tipsy-top. 2683 addIndex = mLruProcesses.size(); 2684 nextIndex = mLruProcessServiceStart; 2685 inActivity = true; 2686 } else if (hasService) { 2687 // Process has services, put it at the top of the service list. 2688 addIndex = mLruProcessActivityStart; 2689 nextIndex = mLruProcessServiceStart; 2690 inActivity = true; 2691 inService = true; 2692 } else { 2693 // Process not otherwise of interest, it goes to the top of the non-service area. 2694 addIndex = mLruProcessServiceStart; 2695 if (client != null) { 2696 int clientIndex = mLruProcesses.lastIndexOf(client); 2697 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2698 + app); 2699 if (clientIndex >= 0 && addIndex > clientIndex) { 2700 addIndex = clientIndex; 2701 } 2702 } 2703 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2704 } 2705 2706 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2707 + mLruProcessActivityStart + "): " + app); 2708 */ 2709 2710 if (lrui >= 0) { 2711 if (lrui < mLruProcessActivityStart) { 2712 mLruProcessActivityStart--; 2713 } 2714 if (lrui < mLruProcessServiceStart) { 2715 mLruProcessServiceStart--; 2716 } 2717 /* 2718 if (addIndex > lrui) { 2719 addIndex--; 2720 } 2721 if (nextIndex > lrui) { 2722 nextIndex--; 2723 } 2724 */ 2725 mLruProcesses.remove(lrui); 2726 } 2727 2728 /* 2729 mLruProcesses.add(addIndex, app); 2730 if (inActivity) { 2731 mLruProcessActivityStart++; 2732 } 2733 if (inService) { 2734 mLruProcessActivityStart++; 2735 } 2736 */ 2737 2738 int nextIndex; 2739 if (hasActivity) { 2740 final int N = mLruProcesses.size(); 2741 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2742 // Process doesn't have activities, but has clients with 2743 // activities... move it up, but one below the top (the top 2744 // should always have a real activity). 2745 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2746 mLruProcesses.add(N-1, app); 2747 // To keep it from spamming the LRU list (by making a bunch of clients), 2748 // we will push down any other entries owned by the app. 2749 final int uid = app.info.uid; 2750 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2751 ProcessRecord subProc = mLruProcesses.get(i); 2752 if (subProc.info.uid == uid) { 2753 // We want to push this one down the list. If the process after 2754 // it is for the same uid, however, don't do so, because we don't 2755 // want them internally to be re-ordered. 2756 if (mLruProcesses.get(i-1).info.uid != uid) { 2757 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2758 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2759 ProcessRecord tmp = mLruProcesses.get(i); 2760 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2761 mLruProcesses.set(i-1, tmp); 2762 i--; 2763 } 2764 } else { 2765 // A gap, we can stop here. 2766 break; 2767 } 2768 } 2769 } else { 2770 // Process has activities, put it at the very tipsy-top. 2771 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2772 mLruProcesses.add(app); 2773 } 2774 nextIndex = mLruProcessServiceStart; 2775 } else if (hasService) { 2776 // Process has services, put it at the top of the service list. 2777 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2778 mLruProcesses.add(mLruProcessActivityStart, app); 2779 nextIndex = mLruProcessServiceStart; 2780 mLruProcessActivityStart++; 2781 } else { 2782 // Process not otherwise of interest, it goes to the top of the non-service area. 2783 int index = mLruProcessServiceStart; 2784 if (client != null) { 2785 // If there is a client, don't allow the process to be moved up higher 2786 // in the list than that client. 2787 int clientIndex = mLruProcesses.lastIndexOf(client); 2788 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2789 + " when updating " + app); 2790 if (clientIndex <= lrui) { 2791 // Don't allow the client index restriction to push it down farther in the 2792 // list than it already is. 2793 clientIndex = lrui; 2794 } 2795 if (clientIndex >= 0 && index > clientIndex) { 2796 index = clientIndex; 2797 } 2798 } 2799 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2800 mLruProcesses.add(index, app); 2801 nextIndex = index-1; 2802 mLruProcessActivityStart++; 2803 mLruProcessServiceStart++; 2804 } 2805 2806 // If the app is currently using a content provider or service, 2807 // bump those processes as well. 2808 for (int j=app.connections.size()-1; j>=0; j--) { 2809 ConnectionRecord cr = app.connections.valueAt(j); 2810 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2811 && cr.binding.service.app != null 2812 && cr.binding.service.app.lruSeq != mLruSeq 2813 && !cr.binding.service.app.persistent) { 2814 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2815 "service connection", cr, app); 2816 } 2817 } 2818 for (int j=app.conProviders.size()-1; j>=0; j--) { 2819 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2820 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2821 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2822 "provider reference", cpr, app); 2823 } 2824 } 2825 } 2826 2827 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2828 if (uid == Process.SYSTEM_UID) { 2829 // The system gets to run in any process. If there are multiple 2830 // processes with the same uid, just pick the first (this 2831 // should never happen). 2832 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2833 if (procs == null) return null; 2834 final int N = procs.size(); 2835 for (int i = 0; i < N; i++) { 2836 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2837 } 2838 } 2839 ProcessRecord proc = mProcessNames.get(processName, uid); 2840 if (false && proc != null && !keepIfLarge 2841 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2842 && proc.lastCachedPss >= 4000) { 2843 // Turn this condition on to cause killing to happen regularly, for testing. 2844 if (proc.baseProcessTracker != null) { 2845 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2846 } 2847 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2848 } else if (proc != null && !keepIfLarge 2849 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2850 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2851 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2852 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2853 if (proc.baseProcessTracker != null) { 2854 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2855 } 2856 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2857 } 2858 } 2859 return proc; 2860 } 2861 2862 void ensurePackageDexOpt(String packageName) { 2863 IPackageManager pm = AppGlobals.getPackageManager(); 2864 try { 2865 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2866 mDidDexOpt = true; 2867 } 2868 } catch (RemoteException e) { 2869 } 2870 } 2871 2872 boolean isNextTransitionForward() { 2873 int transit = mWindowManager.getPendingAppTransition(); 2874 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2875 || transit == AppTransition.TRANSIT_TASK_OPEN 2876 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2877 } 2878 2879 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2880 String processName, String abiOverride, int uid, Runnable crashHandler) { 2881 synchronized(this) { 2882 ApplicationInfo info = new ApplicationInfo(); 2883 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2884 // For isolated processes, the former contains the parent's uid and the latter the 2885 // actual uid of the isolated process. 2886 // In the special case introduced by this method (which is, starting an isolated 2887 // process directly from the SystemServer without an actual parent app process) the 2888 // closest thing to a parent's uid is SYSTEM_UID. 2889 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2890 // the |isolated| logic in the ProcessRecord constructor. 2891 info.uid = Process.SYSTEM_UID; 2892 info.processName = processName; 2893 info.className = entryPoint; 2894 info.packageName = "android"; 2895 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2896 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2897 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2898 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2899 crashHandler); 2900 return proc != null ? proc.pid : 0; 2901 } 2902 } 2903 2904 final ProcessRecord startProcessLocked(String processName, 2905 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2906 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2907 boolean isolated, boolean keepIfLarge) { 2908 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2909 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2910 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2911 null /* crashHandler */); 2912 } 2913 2914 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2915 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2916 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2917 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2918 long startTime = SystemClock.elapsedRealtime(); 2919 ProcessRecord app; 2920 if (!isolated) { 2921 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2922 checkTime(startTime, "startProcess: after getProcessRecord"); 2923 } else { 2924 // If this is an isolated process, it can't re-use an existing process. 2925 app = null; 2926 } 2927 // We don't have to do anything more if: 2928 // (1) There is an existing application record; and 2929 // (2) The caller doesn't think it is dead, OR there is no thread 2930 // object attached to it so we know it couldn't have crashed; and 2931 // (3) There is a pid assigned to it, so it is either starting or 2932 // already running. 2933 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2934 + " app=" + app + " knownToBeDead=" + knownToBeDead 2935 + " thread=" + (app != null ? app.thread : null) 2936 + " pid=" + (app != null ? app.pid : -1)); 2937 if (app != null && app.pid > 0) { 2938 if (!knownToBeDead || app.thread == null) { 2939 // We already have the app running, or are waiting for it to 2940 // come up (we have a pid but not yet its thread), so keep it. 2941 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2942 // If this is a new package in the process, add the package to the list 2943 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2944 checkTime(startTime, "startProcess: done, added package to proc"); 2945 return app; 2946 } 2947 2948 // An application record is attached to a previous process, 2949 // clean it up now. 2950 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2951 checkTime(startTime, "startProcess: bad proc running, killing"); 2952 Process.killProcessGroup(app.info.uid, app.pid); 2953 handleAppDiedLocked(app, true, true); 2954 checkTime(startTime, "startProcess: done killing old proc"); 2955 } 2956 2957 String hostingNameStr = hostingName != null 2958 ? hostingName.flattenToShortString() : null; 2959 2960 if (!isolated) { 2961 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2962 // If we are in the background, then check to see if this process 2963 // is bad. If so, we will just silently fail. 2964 if (mBadProcesses.get(info.processName, info.uid) != null) { 2965 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2966 + "/" + info.processName); 2967 return null; 2968 } 2969 } else { 2970 // When the user is explicitly starting a process, then clear its 2971 // crash count so that we won't make it bad until they see at 2972 // least one crash dialog again, and make the process good again 2973 // if it had been bad. 2974 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2975 + "/" + info.processName); 2976 mProcessCrashTimes.remove(info.processName, info.uid); 2977 if (mBadProcesses.get(info.processName, info.uid) != null) { 2978 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2979 UserHandle.getUserId(info.uid), info.uid, 2980 info.processName); 2981 mBadProcesses.remove(info.processName, info.uid); 2982 if (app != null) { 2983 app.bad = false; 2984 } 2985 } 2986 } 2987 } 2988 2989 if (app == null) { 2990 checkTime(startTime, "startProcess: creating new process record"); 2991 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2992 app.crashHandler = crashHandler; 2993 if (app == null) { 2994 Slog.w(TAG, "Failed making new process record for " 2995 + processName + "/" + info.uid + " isolated=" + isolated); 2996 return null; 2997 } 2998 mProcessNames.put(processName, app.uid, app); 2999 if (isolated) { 3000 mIsolatedProcesses.put(app.uid, app); 3001 } 3002 checkTime(startTime, "startProcess: done creating new process record"); 3003 } else { 3004 // If this is a new package in the process, add the package to the list 3005 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3006 checkTime(startTime, "startProcess: added package to existing proc"); 3007 } 3008 3009 // If the system is not ready yet, then hold off on starting this 3010 // process until it is. 3011 if (!mProcessesReady 3012 && !isAllowedWhileBooting(info) 3013 && !allowWhileBooting) { 3014 if (!mProcessesOnHold.contains(app)) { 3015 mProcessesOnHold.add(app); 3016 } 3017 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3018 checkTime(startTime, "startProcess: returning with proc on hold"); 3019 return app; 3020 } 3021 3022 checkTime(startTime, "startProcess: stepping in to startProcess"); 3023 startProcessLocked( 3024 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3025 checkTime(startTime, "startProcess: done starting proc!"); 3026 return (app.pid != 0) ? app : null; 3027 } 3028 3029 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3030 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3031 } 3032 3033 private final void startProcessLocked(ProcessRecord app, 3034 String hostingType, String hostingNameStr) { 3035 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3036 null /* entryPoint */, null /* entryPointArgs */); 3037 } 3038 3039 private final void startProcessLocked(ProcessRecord app, String hostingType, 3040 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3041 long startTime = SystemClock.elapsedRealtime(); 3042 if (app.pid > 0 && app.pid != MY_PID) { 3043 checkTime(startTime, "startProcess: removing from pids map"); 3044 synchronized (mPidsSelfLocked) { 3045 mPidsSelfLocked.remove(app.pid); 3046 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3047 } 3048 checkTime(startTime, "startProcess: done removing from pids map"); 3049 app.setPid(0); 3050 } 3051 3052 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3053 "startProcessLocked removing on hold: " + app); 3054 mProcessesOnHold.remove(app); 3055 3056 checkTime(startTime, "startProcess: starting to update cpu stats"); 3057 updateCpuStats(); 3058 checkTime(startTime, "startProcess: done updating cpu stats"); 3059 3060 try { 3061 int uid = app.uid; 3062 3063 int[] gids = null; 3064 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3065 if (!app.isolated) { 3066 int[] permGids = null; 3067 try { 3068 checkTime(startTime, "startProcess: getting gids from package manager"); 3069 final PackageManager pm = mContext.getPackageManager(); 3070 permGids = pm.getPackageGids(app.info.packageName); 3071 3072 if (Environment.isExternalStorageEmulated()) { 3073 checkTime(startTime, "startProcess: checking external storage perm"); 3074 if (pm.checkPermission( 3075 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3076 app.info.packageName) == PERMISSION_GRANTED) { 3077 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3078 } else { 3079 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3080 } 3081 } 3082 } catch (PackageManager.NameNotFoundException e) { 3083 Slog.w(TAG, "Unable to retrieve gids", e); 3084 } 3085 3086 /* 3087 * Add shared application and profile GIDs so applications can share some 3088 * resources like shared libraries and access user-wide resources 3089 */ 3090 if (permGids == null) { 3091 gids = new int[2]; 3092 } else { 3093 gids = new int[permGids.length + 2]; 3094 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3095 } 3096 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3097 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3098 } 3099 checkTime(startTime, "startProcess: building args"); 3100 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3101 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3102 && mTopComponent != null 3103 && app.processName.equals(mTopComponent.getPackageName())) { 3104 uid = 0; 3105 } 3106 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3107 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3108 uid = 0; 3109 } 3110 } 3111 int debugFlags = 0; 3112 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3113 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3114 // Also turn on CheckJNI for debuggable apps. It's quite 3115 // awkward to turn on otherwise. 3116 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3117 } 3118 // Run the app in safe mode if its manifest requests so or the 3119 // system is booted in safe mode. 3120 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3121 mSafeMode == true) { 3122 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3123 } 3124 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3125 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3126 } 3127 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3128 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3129 } 3130 if ("1".equals(SystemProperties.get("debug.assert"))) { 3131 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3132 } 3133 3134 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3135 if (requiredAbi == null) { 3136 requiredAbi = Build.SUPPORTED_ABIS[0]; 3137 } 3138 3139 String instructionSet = null; 3140 if (app.info.primaryCpuAbi != null) { 3141 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3142 } 3143 3144 // Start the process. It will either succeed and return a result containing 3145 // the PID of the new process, or else throw a RuntimeException. 3146 boolean isActivityProcess = (entryPoint == null); 3147 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3148 checkTime(startTime, "startProcess: asking zygote to start proc"); 3149 Process.ProcessStartResult startResult = Process.start(entryPoint, 3150 app.processName, uid, uid, gids, debugFlags, mountExternal, 3151 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3152 entryPointArgs); 3153 checkTime(startTime, "startProcess: returned from zygote!"); 3154 3155 if (app.isolated) { 3156 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3157 } 3158 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3159 checkTime(startTime, "startProcess: done updating battery stats"); 3160 3161 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3162 UserHandle.getUserId(uid), startResult.pid, uid, 3163 app.processName, hostingType, 3164 hostingNameStr != null ? hostingNameStr : ""); 3165 3166 if (app.persistent) { 3167 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3168 } 3169 3170 checkTime(startTime, "startProcess: building log message"); 3171 StringBuilder buf = mStringBuilder; 3172 buf.setLength(0); 3173 buf.append("Start proc "); 3174 buf.append(app.processName); 3175 if (!isActivityProcess) { 3176 buf.append(" ["); 3177 buf.append(entryPoint); 3178 buf.append("]"); 3179 } 3180 buf.append(" for "); 3181 buf.append(hostingType); 3182 if (hostingNameStr != null) { 3183 buf.append(" "); 3184 buf.append(hostingNameStr); 3185 } 3186 buf.append(": pid="); 3187 buf.append(startResult.pid); 3188 buf.append(" uid="); 3189 buf.append(uid); 3190 buf.append(" gids={"); 3191 if (gids != null) { 3192 for (int gi=0; gi<gids.length; gi++) { 3193 if (gi != 0) buf.append(", "); 3194 buf.append(gids[gi]); 3195 3196 } 3197 } 3198 buf.append("}"); 3199 if (requiredAbi != null) { 3200 buf.append(" abi="); 3201 buf.append(requiredAbi); 3202 } 3203 Slog.i(TAG, buf.toString()); 3204 app.setPid(startResult.pid); 3205 app.usingWrapper = startResult.usingWrapper; 3206 app.removed = false; 3207 app.killed = false; 3208 app.killedByAm = false; 3209 checkTime(startTime, "startProcess: starting to update pids map"); 3210 synchronized (mPidsSelfLocked) { 3211 this.mPidsSelfLocked.put(startResult.pid, app); 3212 if (isActivityProcess) { 3213 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3214 msg.obj = app; 3215 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3216 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3217 } 3218 } 3219 checkTime(startTime, "startProcess: done updating pids map"); 3220 } catch (RuntimeException e) { 3221 // XXX do better error recovery. 3222 app.setPid(0); 3223 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3224 if (app.isolated) { 3225 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3226 } 3227 Slog.e(TAG, "Failure starting process " + app.processName, e); 3228 } 3229 } 3230 3231 void updateUsageStats(ActivityRecord component, boolean resumed) { 3232 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3233 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3234 if (resumed) { 3235 if (mUsageStatsService != null) { 3236 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3237 UsageEvents.Event.MOVE_TO_FOREGROUND); 3238 } 3239 synchronized (stats) { 3240 stats.noteActivityResumedLocked(component.app.uid); 3241 } 3242 } else { 3243 if (mUsageStatsService != null) { 3244 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3245 UsageEvents.Event.MOVE_TO_BACKGROUND); 3246 } 3247 synchronized (stats) { 3248 stats.noteActivityPausedLocked(component.app.uid); 3249 } 3250 } 3251 } 3252 3253 Intent getHomeIntent() { 3254 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3255 intent.setComponent(mTopComponent); 3256 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3257 intent.addCategory(Intent.CATEGORY_HOME); 3258 } 3259 return intent; 3260 } 3261 3262 boolean startHomeActivityLocked(int userId) { 3263 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3264 && mTopAction == null) { 3265 // We are running in factory test mode, but unable to find 3266 // the factory test app, so just sit around displaying the 3267 // error message and don't try to start anything. 3268 return false; 3269 } 3270 Intent intent = getHomeIntent(); 3271 ActivityInfo aInfo = 3272 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3273 if (aInfo != null) { 3274 intent.setComponent(new ComponentName( 3275 aInfo.applicationInfo.packageName, aInfo.name)); 3276 // Don't do this if the home app is currently being 3277 // instrumented. 3278 aInfo = new ActivityInfo(aInfo); 3279 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3280 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3281 aInfo.applicationInfo.uid, true); 3282 if (app == null || app.instrumentationClass == null) { 3283 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3284 mStackSupervisor.startHomeActivity(intent, aInfo); 3285 } 3286 } 3287 3288 return true; 3289 } 3290 3291 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3292 ActivityInfo ai = null; 3293 ComponentName comp = intent.getComponent(); 3294 try { 3295 if (comp != null) { 3296 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3297 } else { 3298 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3299 intent, 3300 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3301 flags, userId); 3302 3303 if (info != null) { 3304 ai = info.activityInfo; 3305 } 3306 } 3307 } catch (RemoteException e) { 3308 // ignore 3309 } 3310 3311 return ai; 3312 } 3313 3314 /** 3315 * Starts the "new version setup screen" if appropriate. 3316 */ 3317 void startSetupActivityLocked() { 3318 // Only do this once per boot. 3319 if (mCheckedForSetup) { 3320 return; 3321 } 3322 3323 // We will show this screen if the current one is a different 3324 // version than the last one shown, and we are not running in 3325 // low-level factory test mode. 3326 final ContentResolver resolver = mContext.getContentResolver(); 3327 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3328 Settings.Global.getInt(resolver, 3329 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3330 mCheckedForSetup = true; 3331 3332 // See if we should be showing the platform update setup UI. 3333 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3334 List<ResolveInfo> ris = mContext.getPackageManager() 3335 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3336 3337 // We don't allow third party apps to replace this. 3338 ResolveInfo ri = null; 3339 for (int i=0; ris != null && i<ris.size(); i++) { 3340 if ((ris.get(i).activityInfo.applicationInfo.flags 3341 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3342 ri = ris.get(i); 3343 break; 3344 } 3345 } 3346 3347 if (ri != null) { 3348 String vers = ri.activityInfo.metaData != null 3349 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3350 : null; 3351 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3352 vers = ri.activityInfo.applicationInfo.metaData.getString( 3353 Intent.METADATA_SETUP_VERSION); 3354 } 3355 String lastVers = Settings.Secure.getString( 3356 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3357 if (vers != null && !vers.equals(lastVers)) { 3358 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3359 intent.setComponent(new ComponentName( 3360 ri.activityInfo.packageName, ri.activityInfo.name)); 3361 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3362 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3363 null); 3364 } 3365 } 3366 } 3367 } 3368 3369 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3370 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3371 } 3372 3373 void enforceNotIsolatedCaller(String caller) { 3374 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3375 throw new SecurityException("Isolated process not allowed to call " + caller); 3376 } 3377 } 3378 3379 void enforceShellRestriction(String restriction, int userHandle) { 3380 if (Binder.getCallingUid() == Process.SHELL_UID) { 3381 if (userHandle < 0 3382 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3383 throw new SecurityException("Shell does not have permission to access user " 3384 + userHandle); 3385 } 3386 } 3387 } 3388 3389 @Override 3390 public int getFrontActivityScreenCompatMode() { 3391 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3392 synchronized (this) { 3393 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3394 } 3395 } 3396 3397 @Override 3398 public void setFrontActivityScreenCompatMode(int mode) { 3399 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3400 "setFrontActivityScreenCompatMode"); 3401 synchronized (this) { 3402 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3403 } 3404 } 3405 3406 @Override 3407 public int getPackageScreenCompatMode(String packageName) { 3408 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3409 synchronized (this) { 3410 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3411 } 3412 } 3413 3414 @Override 3415 public void setPackageScreenCompatMode(String packageName, int mode) { 3416 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3417 "setPackageScreenCompatMode"); 3418 synchronized (this) { 3419 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3420 } 3421 } 3422 3423 @Override 3424 public boolean getPackageAskScreenCompat(String packageName) { 3425 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3426 synchronized (this) { 3427 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3428 } 3429 } 3430 3431 @Override 3432 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3433 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3434 "setPackageAskScreenCompat"); 3435 synchronized (this) { 3436 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3437 } 3438 } 3439 3440 private void dispatchProcessesChanged() { 3441 int N; 3442 synchronized (this) { 3443 N = mPendingProcessChanges.size(); 3444 if (mActiveProcessChanges.length < N) { 3445 mActiveProcessChanges = new ProcessChangeItem[N]; 3446 } 3447 mPendingProcessChanges.toArray(mActiveProcessChanges); 3448 mAvailProcessChanges.addAll(mPendingProcessChanges); 3449 mPendingProcessChanges.clear(); 3450 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3451 } 3452 3453 int i = mProcessObservers.beginBroadcast(); 3454 while (i > 0) { 3455 i--; 3456 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3457 if (observer != null) { 3458 try { 3459 for (int j=0; j<N; j++) { 3460 ProcessChangeItem item = mActiveProcessChanges[j]; 3461 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3462 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3463 + item.pid + " uid=" + item.uid + ": " 3464 + item.foregroundActivities); 3465 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3466 item.foregroundActivities); 3467 } 3468 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3469 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3470 + item.pid + " uid=" + item.uid + ": " + item.processState); 3471 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3472 } 3473 } 3474 } catch (RemoteException e) { 3475 } 3476 } 3477 } 3478 mProcessObservers.finishBroadcast(); 3479 } 3480 3481 private void dispatchProcessDied(int pid, int uid) { 3482 int i = mProcessObservers.beginBroadcast(); 3483 while (i > 0) { 3484 i--; 3485 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3486 if (observer != null) { 3487 try { 3488 observer.onProcessDied(pid, uid); 3489 } catch (RemoteException e) { 3490 } 3491 } 3492 } 3493 mProcessObservers.finishBroadcast(); 3494 } 3495 3496 @Override 3497 public final int startActivity(IApplicationThread caller, String callingPackage, 3498 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3499 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3500 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3501 resultWho, requestCode, startFlags, profilerInfo, options, 3502 UserHandle.getCallingUserId()); 3503 } 3504 3505 @Override 3506 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3507 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3508 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3509 enforceNotIsolatedCaller("startActivity"); 3510 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3511 false, ALLOW_FULL_ONLY, "startActivity", null); 3512 // TODO: Switch to user app stacks here. 3513 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3514 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3515 profilerInfo, null, null, options, userId, null, null); 3516 } 3517 3518 @Override 3519 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3520 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3521 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3522 3523 // This is very dangerous -- it allows you to perform a start activity (including 3524 // permission grants) as any app that may launch one of your own activities. So 3525 // we will only allow this to be done from activities that are part of the core framework, 3526 // and then only when they are running as the system. 3527 final ActivityRecord sourceRecord; 3528 final int targetUid; 3529 final String targetPackage; 3530 synchronized (this) { 3531 if (resultTo == null) { 3532 throw new SecurityException("Must be called from an activity"); 3533 } 3534 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3535 if (sourceRecord == null) { 3536 throw new SecurityException("Called with bad activity token: " + resultTo); 3537 } 3538 if (!sourceRecord.info.packageName.equals("android")) { 3539 throw new SecurityException( 3540 "Must be called from an activity that is declared in the android package"); 3541 } 3542 if (sourceRecord.app == null) { 3543 throw new SecurityException("Called without a process attached to activity"); 3544 } 3545 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3546 // This is still okay, as long as this activity is running under the 3547 // uid of the original calling activity. 3548 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3549 throw new SecurityException( 3550 "Calling activity in uid " + sourceRecord.app.uid 3551 + " must be system uid or original calling uid " 3552 + sourceRecord.launchedFromUid); 3553 } 3554 } 3555 targetUid = sourceRecord.launchedFromUid; 3556 targetPackage = sourceRecord.launchedFromPackage; 3557 } 3558 3559 // TODO: Switch to user app stacks here. 3560 try { 3561 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3562 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3563 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3564 return ret; 3565 } catch (SecurityException e) { 3566 // XXX need to figure out how to propagate to original app. 3567 // A SecurityException here is generally actually a fault of the original 3568 // calling activity (such as a fairly granting permissions), so propagate it 3569 // back to them. 3570 /* 3571 StringBuilder msg = new StringBuilder(); 3572 msg.append("While launching"); 3573 msg.append(intent.toString()); 3574 msg.append(": "); 3575 msg.append(e.getMessage()); 3576 */ 3577 throw e; 3578 } 3579 } 3580 3581 @Override 3582 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3583 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3584 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3585 enforceNotIsolatedCaller("startActivityAndWait"); 3586 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3587 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3588 WaitResult res = new WaitResult(); 3589 // TODO: Switch to user app stacks here. 3590 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3591 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3592 options, userId, null, null); 3593 return res; 3594 } 3595 3596 @Override 3597 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3598 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3599 int startFlags, Configuration config, Bundle options, int userId) { 3600 enforceNotIsolatedCaller("startActivityWithConfig"); 3601 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3602 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3603 // TODO: Switch to user app stacks here. 3604 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3605 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3606 null, null, config, options, userId, null, null); 3607 return ret; 3608 } 3609 3610 @Override 3611 public int startActivityIntentSender(IApplicationThread caller, 3612 IntentSender intent, Intent fillInIntent, String resolvedType, 3613 IBinder resultTo, String resultWho, int requestCode, 3614 int flagsMask, int flagsValues, Bundle options) { 3615 enforceNotIsolatedCaller("startActivityIntentSender"); 3616 // Refuse possible leaked file descriptors 3617 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3618 throw new IllegalArgumentException("File descriptors passed in Intent"); 3619 } 3620 3621 IIntentSender sender = intent.getTarget(); 3622 if (!(sender instanceof PendingIntentRecord)) { 3623 throw new IllegalArgumentException("Bad PendingIntent object"); 3624 } 3625 3626 PendingIntentRecord pir = (PendingIntentRecord)sender; 3627 3628 synchronized (this) { 3629 // If this is coming from the currently resumed activity, it is 3630 // effectively saying that app switches are allowed at this point. 3631 final ActivityStack stack = getFocusedStack(); 3632 if (stack.mResumedActivity != null && 3633 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3634 mAppSwitchesAllowedTime = 0; 3635 } 3636 } 3637 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3638 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3639 return ret; 3640 } 3641 3642 @Override 3643 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3644 Intent intent, String resolvedType, IVoiceInteractionSession session, 3645 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3646 Bundle options, int userId) { 3647 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3648 != PackageManager.PERMISSION_GRANTED) { 3649 String msg = "Permission Denial: startVoiceActivity() from pid=" 3650 + Binder.getCallingPid() 3651 + ", uid=" + Binder.getCallingUid() 3652 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3653 Slog.w(TAG, msg); 3654 throw new SecurityException(msg); 3655 } 3656 if (session == null || interactor == null) { 3657 throw new NullPointerException("null session or interactor"); 3658 } 3659 userId = handleIncomingUser(callingPid, callingUid, userId, 3660 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3661 // TODO: Switch to user app stacks here. 3662 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3663 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3664 null, options, userId, null, null); 3665 } 3666 3667 @Override 3668 public boolean startNextMatchingActivity(IBinder callingActivity, 3669 Intent intent, Bundle options) { 3670 // Refuse possible leaked file descriptors 3671 if (intent != null && intent.hasFileDescriptors() == true) { 3672 throw new IllegalArgumentException("File descriptors passed in Intent"); 3673 } 3674 3675 synchronized (this) { 3676 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3677 if (r == null) { 3678 ActivityOptions.abort(options); 3679 return false; 3680 } 3681 if (r.app == null || r.app.thread == null) { 3682 // The caller is not running... d'oh! 3683 ActivityOptions.abort(options); 3684 return false; 3685 } 3686 intent = new Intent(intent); 3687 // The caller is not allowed to change the data. 3688 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3689 // And we are resetting to find the next component... 3690 intent.setComponent(null); 3691 3692 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3693 3694 ActivityInfo aInfo = null; 3695 try { 3696 List<ResolveInfo> resolves = 3697 AppGlobals.getPackageManager().queryIntentActivities( 3698 intent, r.resolvedType, 3699 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3700 UserHandle.getCallingUserId()); 3701 3702 // Look for the original activity in the list... 3703 final int N = resolves != null ? resolves.size() : 0; 3704 for (int i=0; i<N; i++) { 3705 ResolveInfo rInfo = resolves.get(i); 3706 if (rInfo.activityInfo.packageName.equals(r.packageName) 3707 && rInfo.activityInfo.name.equals(r.info.name)) { 3708 // We found the current one... the next matching is 3709 // after it. 3710 i++; 3711 if (i<N) { 3712 aInfo = resolves.get(i).activityInfo; 3713 } 3714 if (debug) { 3715 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3716 + "/" + r.info.name); 3717 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3718 + "/" + aInfo.name); 3719 } 3720 break; 3721 } 3722 } 3723 } catch (RemoteException e) { 3724 } 3725 3726 if (aInfo == null) { 3727 // Nobody who is next! 3728 ActivityOptions.abort(options); 3729 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3730 return false; 3731 } 3732 3733 intent.setComponent(new ComponentName( 3734 aInfo.applicationInfo.packageName, aInfo.name)); 3735 intent.setFlags(intent.getFlags()&~( 3736 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3737 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3738 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3739 Intent.FLAG_ACTIVITY_NEW_TASK)); 3740 3741 // Okay now we need to start the new activity, replacing the 3742 // currently running activity. This is a little tricky because 3743 // we want to start the new one as if the current one is finished, 3744 // but not finish the current one first so that there is no flicker. 3745 // And thus... 3746 final boolean wasFinishing = r.finishing; 3747 r.finishing = true; 3748 3749 // Propagate reply information over to the new activity. 3750 final ActivityRecord resultTo = r.resultTo; 3751 final String resultWho = r.resultWho; 3752 final int requestCode = r.requestCode; 3753 r.resultTo = null; 3754 if (resultTo != null) { 3755 resultTo.removeResultsLocked(r, resultWho, requestCode); 3756 } 3757 3758 final long origId = Binder.clearCallingIdentity(); 3759 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3760 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3761 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3762 -1, r.launchedFromUid, 0, options, false, null, null, null); 3763 Binder.restoreCallingIdentity(origId); 3764 3765 r.finishing = wasFinishing; 3766 if (res != ActivityManager.START_SUCCESS) { 3767 return false; 3768 } 3769 return true; 3770 } 3771 } 3772 3773 @Override 3774 public final int startActivityFromRecents(int taskId, Bundle options) { 3775 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3776 String msg = "Permission Denial: startActivityFromRecents called without " + 3777 START_TASKS_FROM_RECENTS; 3778 Slog.w(TAG, msg); 3779 throw new SecurityException(msg); 3780 } 3781 return startActivityFromRecentsInner(taskId, options); 3782 } 3783 3784 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3785 final TaskRecord task; 3786 final int callingUid; 3787 final String callingPackage; 3788 final Intent intent; 3789 final int userId; 3790 synchronized (this) { 3791 task = recentTaskForIdLocked(taskId); 3792 if (task == null) { 3793 throw new IllegalArgumentException("Task " + taskId + " not found."); 3794 } 3795 callingUid = task.mCallingUid; 3796 callingPackage = task.mCallingPackage; 3797 intent = task.intent; 3798 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3799 userId = task.userId; 3800 } 3801 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3802 options, userId, null, task); 3803 } 3804 3805 final int startActivityInPackage(int uid, String callingPackage, 3806 Intent intent, String resolvedType, IBinder resultTo, 3807 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3808 IActivityContainer container, TaskRecord inTask) { 3809 3810 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3811 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3812 3813 // TODO: Switch to user app stacks here. 3814 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3815 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3816 null, null, null, options, userId, container, inTask); 3817 return ret; 3818 } 3819 3820 @Override 3821 public final int startActivities(IApplicationThread caller, String callingPackage, 3822 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3823 int userId) { 3824 enforceNotIsolatedCaller("startActivities"); 3825 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3826 false, ALLOW_FULL_ONLY, "startActivity", null); 3827 // TODO: Switch to user app stacks here. 3828 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3829 resolvedTypes, resultTo, options, userId); 3830 return ret; 3831 } 3832 3833 final int startActivitiesInPackage(int uid, String callingPackage, 3834 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3835 Bundle options, int userId) { 3836 3837 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3838 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3839 // TODO: Switch to user app stacks here. 3840 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3841 resultTo, options, userId); 3842 return ret; 3843 } 3844 3845 //explicitly remove thd old information in mRecentTasks when removing existing user. 3846 private void removeRecentTasksForUserLocked(int userId) { 3847 if(userId <= 0) { 3848 Slog.i(TAG, "Can't remove recent task on user " + userId); 3849 return; 3850 } 3851 3852 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3853 TaskRecord tr = mRecentTasks.get(i); 3854 if (tr.userId == userId) { 3855 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3856 + " when finishing user" + userId); 3857 mRecentTasks.remove(i); 3858 tr.removedFromRecents(mTaskPersister); 3859 } 3860 } 3861 3862 // Remove tasks from persistent storage. 3863 mTaskPersister.wakeup(null, true); 3864 } 3865 3866 // Sort by taskId 3867 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3868 @Override 3869 public int compare(TaskRecord lhs, TaskRecord rhs) { 3870 return rhs.taskId - lhs.taskId; 3871 } 3872 }; 3873 3874 // Extract the affiliates of the chain containing mRecentTasks[start]. 3875 private int processNextAffiliateChain(int start) { 3876 final TaskRecord startTask = mRecentTasks.get(start); 3877 final int affiliateId = startTask.mAffiliatedTaskId; 3878 3879 // Quick identification of isolated tasks. I.e. those not launched behind. 3880 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3881 startTask.mNextAffiliate == null) { 3882 // There is still a slim chance that there are other tasks that point to this task 3883 // and that the chain is so messed up that this task no longer points to them but 3884 // the gain of this optimization outweighs the risk. 3885 startTask.inRecents = true; 3886 return start + 1; 3887 } 3888 3889 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3890 mTmpRecents.clear(); 3891 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3892 final TaskRecord task = mRecentTasks.get(i); 3893 if (task.mAffiliatedTaskId == affiliateId) { 3894 mRecentTasks.remove(i); 3895 mTmpRecents.add(task); 3896 } 3897 } 3898 3899 // Sort them all by taskId. That is the order they were create in and that order will 3900 // always be correct. 3901 Collections.sort(mTmpRecents, mTaskRecordComparator); 3902 3903 // Go through and fix up the linked list. 3904 // The first one is the end of the chain and has no next. 3905 final TaskRecord first = mTmpRecents.get(0); 3906 first.inRecents = true; 3907 if (first.mNextAffiliate != null) { 3908 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3909 first.setNextAffiliate(null); 3910 mTaskPersister.wakeup(first, false); 3911 } 3912 // Everything in the middle is doubly linked from next to prev. 3913 final int tmpSize = mTmpRecents.size(); 3914 for (int i = 0; i < tmpSize - 1; ++i) { 3915 final TaskRecord next = mTmpRecents.get(i); 3916 final TaskRecord prev = mTmpRecents.get(i + 1); 3917 if (next.mPrevAffiliate != prev) { 3918 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3919 " setting prev=" + prev); 3920 next.setPrevAffiliate(prev); 3921 mTaskPersister.wakeup(next, false); 3922 } 3923 if (prev.mNextAffiliate != next) { 3924 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3925 " setting next=" + next); 3926 prev.setNextAffiliate(next); 3927 mTaskPersister.wakeup(prev, false); 3928 } 3929 prev.inRecents = true; 3930 } 3931 // The last one is the beginning of the list and has no prev. 3932 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3933 if (last.mPrevAffiliate != null) { 3934 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3935 last.setPrevAffiliate(null); 3936 mTaskPersister.wakeup(last, false); 3937 } 3938 3939 // Insert the group back into mRecentTasks at start. 3940 mRecentTasks.addAll(start, mTmpRecents); 3941 3942 // Let the caller know where we left off. 3943 return start + tmpSize; 3944 } 3945 3946 /** 3947 * Update the recent tasks lists: make sure tasks should still be here (their 3948 * applications / activities still exist), update their availability, fixup ordering 3949 * of affiliations. 3950 */ 3951 void cleanupRecentTasksLocked(int userId) { 3952 if (mRecentTasks == null) { 3953 // Happens when called from the packagemanager broadcast before boot. 3954 return; 3955 } 3956 3957 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3958 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3959 final IPackageManager pm = AppGlobals.getPackageManager(); 3960 final ActivityInfo dummyAct = new ActivityInfo(); 3961 final ApplicationInfo dummyApp = new ApplicationInfo(); 3962 3963 int N = mRecentTasks.size(); 3964 3965 int[] users = userId == UserHandle.USER_ALL 3966 ? getUsersLocked() : new int[] { userId }; 3967 for (int user : users) { 3968 for (int i = 0; i < N; i++) { 3969 TaskRecord task = mRecentTasks.get(i); 3970 if (task.userId != user) { 3971 // Only look at tasks for the user ID of interest. 3972 continue; 3973 } 3974 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3975 // This situation is broken, and we should just get rid of it now. 3976 mRecentTasks.remove(i); 3977 task.removedFromRecents(mTaskPersister); 3978 i--; 3979 N--; 3980 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3981 continue; 3982 } 3983 // Check whether this activity is currently available. 3984 if (task.realActivity != null) { 3985 ActivityInfo ai = availActCache.get(task.realActivity); 3986 if (ai == null) { 3987 try { 3988 ai = pm.getActivityInfo(task.realActivity, 3989 PackageManager.GET_UNINSTALLED_PACKAGES 3990 | PackageManager.GET_DISABLED_COMPONENTS, user); 3991 } catch (RemoteException e) { 3992 // Will never happen. 3993 continue; 3994 } 3995 if (ai == null) { 3996 ai = dummyAct; 3997 } 3998 availActCache.put(task.realActivity, ai); 3999 } 4000 if (ai == dummyAct) { 4001 // This could be either because the activity no longer exists, or the 4002 // app is temporarily gone. For the former we want to remove the recents 4003 // entry; for the latter we want to mark it as unavailable. 4004 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 4005 if (app == null) { 4006 try { 4007 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4008 PackageManager.GET_UNINSTALLED_PACKAGES 4009 | PackageManager.GET_DISABLED_COMPONENTS, user); 4010 } catch (RemoteException e) { 4011 // Will never happen. 4012 continue; 4013 } 4014 if (app == null) { 4015 app = dummyApp; 4016 } 4017 availAppCache.put(task.realActivity.getPackageName(), app); 4018 } 4019 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4020 // Doesn't exist any more! Good-bye. 4021 mRecentTasks.remove(i); 4022 task.removedFromRecents(mTaskPersister); 4023 i--; 4024 N--; 4025 Slog.w(TAG, "Removing no longer valid recent: " + task); 4026 continue; 4027 } else { 4028 // Otherwise just not available for now. 4029 if (task.isAvailable) { 4030 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4031 + task); 4032 } 4033 task.isAvailable = false; 4034 } 4035 } else { 4036 if (!ai.enabled || !ai.applicationInfo.enabled 4037 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4038 if (task.isAvailable) { 4039 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4040 + task + " (enabled=" + ai.enabled + "/" 4041 + ai.applicationInfo.enabled + " flags=" 4042 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4043 } 4044 task.isAvailable = false; 4045 } else { 4046 if (!task.isAvailable) { 4047 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4048 + task); 4049 } 4050 task.isAvailable = true; 4051 } 4052 } 4053 } 4054 } 4055 } 4056 4057 // Verify the affiliate chain for each task. 4058 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4059 } 4060 4061 mTmpRecents.clear(); 4062 // mRecentTasks is now in sorted, affiliated order. 4063 } 4064 4065 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4066 int N = mRecentTasks.size(); 4067 TaskRecord top = task; 4068 int topIndex = taskIndex; 4069 while (top.mNextAffiliate != null && topIndex > 0) { 4070 top = top.mNextAffiliate; 4071 topIndex--; 4072 } 4073 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4074 + topIndex + " from intial " + taskIndex); 4075 // Find the end of the chain, doing a sanity check along the way. 4076 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4077 int endIndex = topIndex; 4078 TaskRecord prev = top; 4079 while (endIndex < N) { 4080 TaskRecord cur = mRecentTasks.get(endIndex); 4081 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4082 + endIndex + " " + cur); 4083 if (cur == top) { 4084 // Verify start of the chain. 4085 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4086 Slog.wtf(TAG, "Bad chain @" + endIndex 4087 + ": first task has next affiliate: " + prev); 4088 sane = false; 4089 break; 4090 } 4091 } else { 4092 // Verify middle of the chain's next points back to the one before. 4093 if (cur.mNextAffiliate != prev 4094 || cur.mNextAffiliateTaskId != prev.taskId) { 4095 Slog.wtf(TAG, "Bad chain @" + endIndex 4096 + ": middle task " + cur + " @" + endIndex 4097 + " has bad next affiliate " 4098 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4099 + ", expected " + prev); 4100 sane = false; 4101 break; 4102 } 4103 } 4104 if (cur.mPrevAffiliateTaskId == -1) { 4105 // Chain ends here. 4106 if (cur.mPrevAffiliate != null) { 4107 Slog.wtf(TAG, "Bad chain @" + endIndex 4108 + ": last task " + cur + " has previous affiliate " 4109 + cur.mPrevAffiliate); 4110 sane = false; 4111 } 4112 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4113 break; 4114 } else { 4115 // Verify middle of the chain's prev points to a valid item. 4116 if (cur.mPrevAffiliate == null) { 4117 Slog.wtf(TAG, "Bad chain @" + endIndex 4118 + ": task " + cur + " has previous affiliate " 4119 + cur.mPrevAffiliate + " but should be id " 4120 + cur.mPrevAffiliate); 4121 sane = false; 4122 break; 4123 } 4124 } 4125 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4126 Slog.wtf(TAG, "Bad chain @" + endIndex 4127 + ": task " + cur + " has affiliated id " 4128 + cur.mAffiliatedTaskId + " but should be " 4129 + task.mAffiliatedTaskId); 4130 sane = false; 4131 break; 4132 } 4133 prev = cur; 4134 endIndex++; 4135 if (endIndex >= N) { 4136 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4137 + ": last task " + prev); 4138 sane = false; 4139 break; 4140 } 4141 } 4142 if (sane) { 4143 if (endIndex < taskIndex) { 4144 Slog.wtf(TAG, "Bad chain @" + endIndex 4145 + ": did not extend to task " + task + " @" + taskIndex); 4146 sane = false; 4147 } 4148 } 4149 if (sane) { 4150 // All looks good, we can just move all of the affiliated tasks 4151 // to the top. 4152 for (int i=topIndex; i<=endIndex; i++) { 4153 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4154 + " from " + i + " to " + (i-topIndex)); 4155 TaskRecord cur = mRecentTasks.remove(i); 4156 mRecentTasks.add(i-topIndex, cur); 4157 } 4158 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4159 + " to " + endIndex); 4160 return true; 4161 } 4162 4163 // Whoops, couldn't do it. 4164 return false; 4165 } 4166 4167 final void addRecentTaskLocked(TaskRecord task) { 4168 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4169 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4170 4171 int N = mRecentTasks.size(); 4172 // Quick case: check if the top-most recent task is the same. 4173 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4174 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4175 return; 4176 } 4177 // Another quick case: check if this is part of a set of affiliated 4178 // tasks that are at the top. 4179 if (isAffiliated && N > 0 && task.inRecents 4180 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4181 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4182 + " at top when adding " + task); 4183 return; 4184 } 4185 // Another quick case: never add voice sessions. 4186 if (task.voiceSession != null) { 4187 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4188 return; 4189 } 4190 4191 boolean needAffiliationFix = false; 4192 4193 // Slightly less quick case: the task is already in recents, so all we need 4194 // to do is move it. 4195 if (task.inRecents) { 4196 int taskIndex = mRecentTasks.indexOf(task); 4197 if (taskIndex >= 0) { 4198 if (!isAffiliated) { 4199 // Simple case: this is not an affiliated task, so we just move it to the front. 4200 mRecentTasks.remove(taskIndex); 4201 mRecentTasks.add(0, task); 4202 notifyTaskPersisterLocked(task, false); 4203 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4204 + " from " + taskIndex); 4205 return; 4206 } else { 4207 // More complicated: need to keep all affiliated tasks together. 4208 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4209 // All went well. 4210 return; 4211 } 4212 4213 // Uh oh... something bad in the affiliation chain, try to rebuild 4214 // everything and then go through our general path of adding a new task. 4215 needAffiliationFix = true; 4216 } 4217 } else { 4218 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4219 needAffiliationFix = true; 4220 } 4221 } 4222 4223 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4224 trimRecentsForTask(task, true); 4225 4226 N = mRecentTasks.size(); 4227 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4228 final TaskRecord tr = mRecentTasks.remove(N - 1); 4229 tr.removedFromRecents(mTaskPersister); 4230 N--; 4231 } 4232 task.inRecents = true; 4233 if (!isAffiliated || needAffiliationFix) { 4234 // If this is a simple non-affiliated task, or we had some failure trying to 4235 // handle it as part of an affilated task, then just place it at the top. 4236 mRecentTasks.add(0, task); 4237 } else if (isAffiliated) { 4238 // If this is a new affiliated task, then move all of the affiliated tasks 4239 // to the front and insert this new one. 4240 TaskRecord other = task.mNextAffiliate; 4241 if (other == null) { 4242 other = task.mPrevAffiliate; 4243 } 4244 if (other != null) { 4245 int otherIndex = mRecentTasks.indexOf(other); 4246 if (otherIndex >= 0) { 4247 // Insert new task at appropriate location. 4248 int taskIndex; 4249 if (other == task.mNextAffiliate) { 4250 // We found the index of our next affiliation, which is who is 4251 // before us in the list, so add after that point. 4252 taskIndex = otherIndex+1; 4253 } else { 4254 // We found the index of our previous affiliation, which is who is 4255 // after us in the list, so add at their position. 4256 taskIndex = otherIndex; 4257 } 4258 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4259 + taskIndex + ": " + task); 4260 mRecentTasks.add(taskIndex, task); 4261 4262 // Now move everything to the front. 4263 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4264 // All went well. 4265 return; 4266 } 4267 4268 // Uh oh... something bad in the affiliation chain, try to rebuild 4269 // everything and then go through our general path of adding a new task. 4270 needAffiliationFix = true; 4271 } else { 4272 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4273 + other); 4274 needAffiliationFix = true; 4275 } 4276 } else { 4277 if (DEBUG_RECENTS) Slog.d(TAG, 4278 "addRecent: adding affiliated task without next/prev:" + task); 4279 needAffiliationFix = true; 4280 } 4281 } 4282 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4283 4284 if (needAffiliationFix) { 4285 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4286 cleanupRecentTasksLocked(task.userId); 4287 } 4288 } 4289 4290 /** 4291 * If needed, remove oldest existing entries in recents that are for the same kind 4292 * of task as the given one. 4293 */ 4294 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4295 int N = mRecentTasks.size(); 4296 final Intent intent = task.intent; 4297 final boolean document = intent != null && intent.isDocument(); 4298 4299 int maxRecents = task.maxRecents - 1; 4300 for (int i=0; i<N; i++) { 4301 final TaskRecord tr = mRecentTasks.get(i); 4302 if (task != tr) { 4303 if (task.userId != tr.userId) { 4304 continue; 4305 } 4306 if (i > MAX_RECENT_BITMAPS) { 4307 tr.freeLastThumbnail(); 4308 } 4309 final Intent trIntent = tr.intent; 4310 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4311 (intent == null || !intent.filterEquals(trIntent))) { 4312 continue; 4313 } 4314 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4315 if (document && trIsDocument) { 4316 // These are the same document activity (not necessarily the same doc). 4317 if (maxRecents > 0) { 4318 --maxRecents; 4319 continue; 4320 } 4321 // Hit the maximum number of documents for this task. Fall through 4322 // and remove this document from recents. 4323 } else if (document || trIsDocument) { 4324 // Only one of these is a document. Not the droid we're looking for. 4325 continue; 4326 } 4327 } 4328 4329 if (!doTrim) { 4330 // If the caller is not actually asking for a trim, just tell them we reached 4331 // a point where the trim would happen. 4332 return i; 4333 } 4334 4335 // Either task and tr are the same or, their affinities match or their intents match 4336 // and neither of them is a document, or they are documents using the same activity 4337 // and their maxRecents has been reached. 4338 tr.disposeThumbnail(); 4339 mRecentTasks.remove(i); 4340 if (task != tr) { 4341 tr.removedFromRecents(mTaskPersister); 4342 } 4343 i--; 4344 N--; 4345 if (task.intent == null) { 4346 // If the new recent task we are adding is not fully 4347 // specified, then replace it with the existing recent task. 4348 task = tr; 4349 } 4350 notifyTaskPersisterLocked(tr, false); 4351 } 4352 4353 return -1; 4354 } 4355 4356 @Override 4357 public void reportActivityFullyDrawn(IBinder token) { 4358 synchronized (this) { 4359 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4360 if (r == null) { 4361 return; 4362 } 4363 r.reportFullyDrawnLocked(); 4364 } 4365 } 4366 4367 @Override 4368 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4369 synchronized (this) { 4370 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4371 if (r == null) { 4372 return; 4373 } 4374 final long origId = Binder.clearCallingIdentity(); 4375 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4376 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4377 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4378 if (config != null) { 4379 r.frozenBeforeDestroy = true; 4380 if (!updateConfigurationLocked(config, r, false, false)) { 4381 mStackSupervisor.resumeTopActivitiesLocked(); 4382 } 4383 } 4384 Binder.restoreCallingIdentity(origId); 4385 } 4386 } 4387 4388 @Override 4389 public int getRequestedOrientation(IBinder token) { 4390 synchronized (this) { 4391 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4392 if (r == null) { 4393 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4394 } 4395 return mWindowManager.getAppOrientation(r.appToken); 4396 } 4397 } 4398 4399 /** 4400 * This is the internal entry point for handling Activity.finish(). 4401 * 4402 * @param token The Binder token referencing the Activity we want to finish. 4403 * @param resultCode Result code, if any, from this Activity. 4404 * @param resultData Result data (Intent), if any, from this Activity. 4405 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4406 * the root Activity in the task. 4407 * 4408 * @return Returns true if the activity successfully finished, or false if it is still running. 4409 */ 4410 @Override 4411 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4412 boolean finishTask) { 4413 // Refuse possible leaked file descriptors 4414 if (resultData != null && resultData.hasFileDescriptors() == true) { 4415 throw new IllegalArgumentException("File descriptors passed in Intent"); 4416 } 4417 4418 synchronized(this) { 4419 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4420 if (r == null) { 4421 return true; 4422 } 4423 // Keep track of the root activity of the task before we finish it 4424 TaskRecord tr = r.task; 4425 ActivityRecord rootR = tr.getRootActivity(); 4426 // Do not allow task to finish in Lock Task mode. 4427 if (tr == mStackSupervisor.mLockTaskModeTask) { 4428 if (rootR == r) { 4429 mStackSupervisor.showLockTaskToast(); 4430 return false; 4431 } 4432 } 4433 if (mController != null) { 4434 // Find the first activity that is not finishing. 4435 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4436 if (next != null) { 4437 // ask watcher if this is allowed 4438 boolean resumeOK = true; 4439 try { 4440 resumeOK = mController.activityResuming(next.packageName); 4441 } catch (RemoteException e) { 4442 mController = null; 4443 Watchdog.getInstance().setActivityController(null); 4444 } 4445 4446 if (!resumeOK) { 4447 return false; 4448 } 4449 } 4450 } 4451 final long origId = Binder.clearCallingIdentity(); 4452 try { 4453 boolean res; 4454 if (finishTask && r == rootR) { 4455 // If requested, remove the task that is associated to this activity only if it 4456 // was the root activity in the task. The result code and data is ignored because 4457 // we don't support returning them across task boundaries. 4458 res = removeTaskByIdLocked(tr.taskId, 0); 4459 } else { 4460 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4461 resultData, "app-request", true); 4462 } 4463 return res; 4464 } finally { 4465 Binder.restoreCallingIdentity(origId); 4466 } 4467 } 4468 } 4469 4470 @Override 4471 public final void finishHeavyWeightApp() { 4472 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4473 != PackageManager.PERMISSION_GRANTED) { 4474 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4475 + Binder.getCallingPid() 4476 + ", uid=" + Binder.getCallingUid() 4477 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4478 Slog.w(TAG, msg); 4479 throw new SecurityException(msg); 4480 } 4481 4482 synchronized(this) { 4483 if (mHeavyWeightProcess == null) { 4484 return; 4485 } 4486 4487 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4488 mHeavyWeightProcess.activities); 4489 for (int i=0; i<activities.size(); i++) { 4490 ActivityRecord r = activities.get(i); 4491 if (!r.finishing) { 4492 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4493 null, "finish-heavy", true); 4494 } 4495 } 4496 4497 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4498 mHeavyWeightProcess.userId, 0)); 4499 mHeavyWeightProcess = null; 4500 } 4501 } 4502 4503 @Override 4504 public void crashApplication(int uid, int initialPid, String packageName, 4505 String message) { 4506 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4507 != PackageManager.PERMISSION_GRANTED) { 4508 String msg = "Permission Denial: crashApplication() from pid=" 4509 + Binder.getCallingPid() 4510 + ", uid=" + Binder.getCallingUid() 4511 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4512 Slog.w(TAG, msg); 4513 throw new SecurityException(msg); 4514 } 4515 4516 synchronized(this) { 4517 ProcessRecord proc = null; 4518 4519 // Figure out which process to kill. We don't trust that initialPid 4520 // still has any relation to current pids, so must scan through the 4521 // list. 4522 synchronized (mPidsSelfLocked) { 4523 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4524 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4525 if (p.uid != uid) { 4526 continue; 4527 } 4528 if (p.pid == initialPid) { 4529 proc = p; 4530 break; 4531 } 4532 if (p.pkgList.containsKey(packageName)) { 4533 proc = p; 4534 } 4535 } 4536 } 4537 4538 if (proc == null) { 4539 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4540 + " initialPid=" + initialPid 4541 + " packageName=" + packageName); 4542 return; 4543 } 4544 4545 if (proc.thread != null) { 4546 if (proc.pid == Process.myPid()) { 4547 Log.w(TAG, "crashApplication: trying to crash self!"); 4548 return; 4549 } 4550 long ident = Binder.clearCallingIdentity(); 4551 try { 4552 proc.thread.scheduleCrash(message); 4553 } catch (RemoteException e) { 4554 } 4555 Binder.restoreCallingIdentity(ident); 4556 } 4557 } 4558 } 4559 4560 @Override 4561 public final void finishSubActivity(IBinder token, String resultWho, 4562 int requestCode) { 4563 synchronized(this) { 4564 final long origId = Binder.clearCallingIdentity(); 4565 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4566 if (r != null) { 4567 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4568 } 4569 Binder.restoreCallingIdentity(origId); 4570 } 4571 } 4572 4573 @Override 4574 public boolean finishActivityAffinity(IBinder token) { 4575 synchronized(this) { 4576 final long origId = Binder.clearCallingIdentity(); 4577 try { 4578 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4579 4580 ActivityRecord rootR = r.task.getRootActivity(); 4581 // Do not allow task to finish in Lock Task mode. 4582 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4583 if (rootR == r) { 4584 mStackSupervisor.showLockTaskToast(); 4585 return false; 4586 } 4587 } 4588 boolean res = false; 4589 if (r != null) { 4590 res = r.task.stack.finishActivityAffinityLocked(r); 4591 } 4592 return res; 4593 } finally { 4594 Binder.restoreCallingIdentity(origId); 4595 } 4596 } 4597 } 4598 4599 @Override 4600 public void finishVoiceTask(IVoiceInteractionSession session) { 4601 synchronized(this) { 4602 final long origId = Binder.clearCallingIdentity(); 4603 try { 4604 mStackSupervisor.finishVoiceTask(session); 4605 } finally { 4606 Binder.restoreCallingIdentity(origId); 4607 } 4608 } 4609 4610 } 4611 4612 @Override 4613 public boolean releaseActivityInstance(IBinder token) { 4614 synchronized(this) { 4615 final long origId = Binder.clearCallingIdentity(); 4616 try { 4617 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4618 if (r.task == null || r.task.stack == null) { 4619 return false; 4620 } 4621 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4622 } finally { 4623 Binder.restoreCallingIdentity(origId); 4624 } 4625 } 4626 } 4627 4628 @Override 4629 public void releaseSomeActivities(IApplicationThread appInt) { 4630 synchronized(this) { 4631 final long origId = Binder.clearCallingIdentity(); 4632 try { 4633 ProcessRecord app = getRecordForAppLocked(appInt); 4634 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4635 } finally { 4636 Binder.restoreCallingIdentity(origId); 4637 } 4638 } 4639 } 4640 4641 @Override 4642 public boolean willActivityBeVisible(IBinder token) { 4643 synchronized(this) { 4644 ActivityStack stack = ActivityRecord.getStackLocked(token); 4645 if (stack != null) { 4646 return stack.willActivityBeVisibleLocked(token); 4647 } 4648 return false; 4649 } 4650 } 4651 4652 @Override 4653 public void overridePendingTransition(IBinder token, String packageName, 4654 int enterAnim, int exitAnim) { 4655 synchronized(this) { 4656 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4657 if (self == null) { 4658 return; 4659 } 4660 4661 final long origId = Binder.clearCallingIdentity(); 4662 4663 if (self.state == ActivityState.RESUMED 4664 || self.state == ActivityState.PAUSING) { 4665 mWindowManager.overridePendingAppTransition(packageName, 4666 enterAnim, exitAnim, null); 4667 } 4668 4669 Binder.restoreCallingIdentity(origId); 4670 } 4671 } 4672 4673 /** 4674 * Main function for removing an existing process from the activity manager 4675 * as a result of that process going away. Clears out all connections 4676 * to the process. 4677 */ 4678 private final void handleAppDiedLocked(ProcessRecord app, 4679 boolean restarting, boolean allowRestart) { 4680 int pid = app.pid; 4681 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4682 if (!restarting) { 4683 removeLruProcessLocked(app); 4684 if (pid > 0) { 4685 ProcessList.remove(pid); 4686 } 4687 } 4688 4689 if (mProfileProc == app) { 4690 clearProfilerLocked(); 4691 } 4692 4693 // Remove this application's activities from active lists. 4694 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4695 4696 app.activities.clear(); 4697 4698 if (app.instrumentationClass != null) { 4699 Slog.w(TAG, "Crash of app " + app.processName 4700 + " running instrumentation " + app.instrumentationClass); 4701 Bundle info = new Bundle(); 4702 info.putString("shortMsg", "Process crashed."); 4703 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4704 } 4705 4706 if (!restarting) { 4707 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4708 // If there was nothing to resume, and we are not already 4709 // restarting this process, but there is a visible activity that 4710 // is hosted by the process... then make sure all visible 4711 // activities are running, taking care of restarting this 4712 // process. 4713 if (hasVisibleActivities) { 4714 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4715 } 4716 } 4717 } 4718 } 4719 4720 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4721 IBinder threadBinder = thread.asBinder(); 4722 // Find the application record. 4723 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4724 ProcessRecord rec = mLruProcesses.get(i); 4725 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4726 return i; 4727 } 4728 } 4729 return -1; 4730 } 4731 4732 final ProcessRecord getRecordForAppLocked( 4733 IApplicationThread thread) { 4734 if (thread == null) { 4735 return null; 4736 } 4737 4738 int appIndex = getLRURecordIndexForAppLocked(thread); 4739 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4740 } 4741 4742 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4743 // If there are no longer any background processes running, 4744 // and the app that died was not running instrumentation, 4745 // then tell everyone we are now low on memory. 4746 boolean haveBg = false; 4747 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4748 ProcessRecord rec = mLruProcesses.get(i); 4749 if (rec.thread != null 4750 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4751 haveBg = true; 4752 break; 4753 } 4754 } 4755 4756 if (!haveBg) { 4757 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4758 if (doReport) { 4759 long now = SystemClock.uptimeMillis(); 4760 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4761 doReport = false; 4762 } else { 4763 mLastMemUsageReportTime = now; 4764 } 4765 } 4766 final ArrayList<ProcessMemInfo> memInfos 4767 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4768 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4769 long now = SystemClock.uptimeMillis(); 4770 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4771 ProcessRecord rec = mLruProcesses.get(i); 4772 if (rec == dyingProc || rec.thread == null) { 4773 continue; 4774 } 4775 if (doReport) { 4776 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4777 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4778 } 4779 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4780 // The low memory report is overriding any current 4781 // state for a GC request. Make sure to do 4782 // heavy/important/visible/foreground processes first. 4783 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4784 rec.lastRequestedGc = 0; 4785 } else { 4786 rec.lastRequestedGc = rec.lastLowMemory; 4787 } 4788 rec.reportLowMemory = true; 4789 rec.lastLowMemory = now; 4790 mProcessesToGc.remove(rec); 4791 addProcessToGcListLocked(rec); 4792 } 4793 } 4794 if (doReport) { 4795 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4796 mHandler.sendMessage(msg); 4797 } 4798 scheduleAppGcsLocked(); 4799 } 4800 } 4801 4802 final void appDiedLocked(ProcessRecord app) { 4803 appDiedLocked(app, app.pid, app.thread); 4804 } 4805 4806 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { 4807 4808 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4809 synchronized (stats) { 4810 stats.noteProcessDiedLocked(app.info.uid, pid); 4811 } 4812 4813 Process.killProcessQuiet(pid); 4814 Process.killProcessGroup(app.info.uid, pid); 4815 app.killed = true; 4816 4817 // Clean up already done if the process has been re-started. 4818 if (app.pid == pid && app.thread != null && 4819 app.thread.asBinder() == thread.asBinder()) { 4820 boolean doLowMem = app.instrumentationClass == null; 4821 boolean doOomAdj = doLowMem; 4822 if (!app.killedByAm) { 4823 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4824 + ") has died."); 4825 mAllowLowerMemLevel = true; 4826 } else { 4827 // Note that we always want to do oom adj to update our state with the 4828 // new number of procs. 4829 mAllowLowerMemLevel = false; 4830 doLowMem = false; 4831 } 4832 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4833 if (DEBUG_CLEANUP) Slog.v( 4834 TAG, "Dying app: " + app + ", pid: " + pid 4835 + ", thread: " + thread.asBinder()); 4836 handleAppDiedLocked(app, false, true); 4837 4838 if (doOomAdj) { 4839 updateOomAdjLocked(); 4840 } 4841 if (doLowMem) { 4842 doLowMemReportIfNeededLocked(app); 4843 } 4844 } else if (app.pid != pid) { 4845 // A new process has already been started. 4846 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4847 + ") has died and restarted (pid " + app.pid + ")."); 4848 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4849 } else if (DEBUG_PROCESSES) { 4850 Slog.d(TAG, "Received spurious death notification for thread " 4851 + thread.asBinder()); 4852 } 4853 } 4854 4855 /** 4856 * If a stack trace dump file is configured, dump process stack traces. 4857 * @param clearTraces causes the dump file to be erased prior to the new 4858 * traces being written, if true; when false, the new traces will be 4859 * appended to any existing file content. 4860 * @param firstPids of dalvik VM processes to dump stack traces for first 4861 * @param lastPids of dalvik VM processes to dump stack traces for last 4862 * @param nativeProcs optional list of native process names to dump stack crawls 4863 * @return file containing stack traces, or null if no dump file is configured 4864 */ 4865 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4866 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4867 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4868 if (tracesPath == null || tracesPath.length() == 0) { 4869 return null; 4870 } 4871 4872 File tracesFile = new File(tracesPath); 4873 try { 4874 File tracesDir = tracesFile.getParentFile(); 4875 if (!tracesDir.exists()) { 4876 tracesDir.mkdirs(); 4877 if (!SELinux.restorecon(tracesDir)) { 4878 return null; 4879 } 4880 } 4881 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4882 4883 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4884 tracesFile.createNewFile(); 4885 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4886 } catch (IOException e) { 4887 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4888 return null; 4889 } 4890 4891 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4892 return tracesFile; 4893 } 4894 4895 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4896 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4897 // Use a FileObserver to detect when traces finish writing. 4898 // The order of traces is considered important to maintain for legibility. 4899 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4900 @Override 4901 public synchronized void onEvent(int event, String path) { notify(); } 4902 }; 4903 4904 try { 4905 observer.startWatching(); 4906 4907 // First collect all of the stacks of the most important pids. 4908 if (firstPids != null) { 4909 try { 4910 int num = firstPids.size(); 4911 for (int i = 0; i < num; i++) { 4912 synchronized (observer) { 4913 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4914 observer.wait(200); // Wait for write-close, give up after 200msec 4915 } 4916 } 4917 } catch (InterruptedException e) { 4918 Log.wtf(TAG, e); 4919 } 4920 } 4921 4922 // Next collect the stacks of the native pids 4923 if (nativeProcs != null) { 4924 int[] pids = Process.getPidsForCommands(nativeProcs); 4925 if (pids != null) { 4926 for (int pid : pids) { 4927 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4928 } 4929 } 4930 } 4931 4932 // Lastly, measure CPU usage. 4933 if (processCpuTracker != null) { 4934 processCpuTracker.init(); 4935 System.gc(); 4936 processCpuTracker.update(); 4937 try { 4938 synchronized (processCpuTracker) { 4939 processCpuTracker.wait(500); // measure over 1/2 second. 4940 } 4941 } catch (InterruptedException e) { 4942 } 4943 processCpuTracker.update(); 4944 4945 // We'll take the stack crawls of just the top apps using CPU. 4946 final int N = processCpuTracker.countWorkingStats(); 4947 int numProcs = 0; 4948 for (int i=0; i<N && numProcs<5; i++) { 4949 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4950 if (lastPids.indexOfKey(stats.pid) >= 0) { 4951 numProcs++; 4952 try { 4953 synchronized (observer) { 4954 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4955 observer.wait(200); // Wait for write-close, give up after 200msec 4956 } 4957 } catch (InterruptedException e) { 4958 Log.wtf(TAG, e); 4959 } 4960 4961 } 4962 } 4963 } 4964 } finally { 4965 observer.stopWatching(); 4966 } 4967 } 4968 4969 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4970 if (true || IS_USER_BUILD) { 4971 return; 4972 } 4973 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4974 if (tracesPath == null || tracesPath.length() == 0) { 4975 return; 4976 } 4977 4978 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4979 StrictMode.allowThreadDiskWrites(); 4980 try { 4981 final File tracesFile = new File(tracesPath); 4982 final File tracesDir = tracesFile.getParentFile(); 4983 final File tracesTmp = new File(tracesDir, "__tmp__"); 4984 try { 4985 if (!tracesDir.exists()) { 4986 tracesDir.mkdirs(); 4987 if (!SELinux.restorecon(tracesDir.getPath())) { 4988 return; 4989 } 4990 } 4991 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4992 4993 if (tracesFile.exists()) { 4994 tracesTmp.delete(); 4995 tracesFile.renameTo(tracesTmp); 4996 } 4997 StringBuilder sb = new StringBuilder(); 4998 Time tobj = new Time(); 4999 tobj.set(System.currentTimeMillis()); 5000 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5001 sb.append(": "); 5002 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5003 sb.append(" since "); 5004 sb.append(msg); 5005 FileOutputStream fos = new FileOutputStream(tracesFile); 5006 fos.write(sb.toString().getBytes()); 5007 if (app == null) { 5008 fos.write("\n*** No application process!".getBytes()); 5009 } 5010 fos.close(); 5011 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5012 } catch (IOException e) { 5013 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5014 return; 5015 } 5016 5017 if (app != null) { 5018 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5019 firstPids.add(app.pid); 5020 dumpStackTraces(tracesPath, firstPids, null, null, null); 5021 } 5022 5023 File lastTracesFile = null; 5024 File curTracesFile = null; 5025 for (int i=9; i>=0; i--) { 5026 String name = String.format(Locale.US, "slow%02d.txt", i); 5027 curTracesFile = new File(tracesDir, name); 5028 if (curTracesFile.exists()) { 5029 if (lastTracesFile != null) { 5030 curTracesFile.renameTo(lastTracesFile); 5031 } else { 5032 curTracesFile.delete(); 5033 } 5034 } 5035 lastTracesFile = curTracesFile; 5036 } 5037 tracesFile.renameTo(curTracesFile); 5038 if (tracesTmp.exists()) { 5039 tracesTmp.renameTo(tracesFile); 5040 } 5041 } finally { 5042 StrictMode.setThreadPolicy(oldPolicy); 5043 } 5044 } 5045 5046 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5047 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5048 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5049 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5050 5051 if (mController != null) { 5052 try { 5053 // 0 == continue, -1 = kill process immediately 5054 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5055 if (res < 0 && app.pid != MY_PID) { 5056 app.kill("anr", true); 5057 } 5058 } catch (RemoteException e) { 5059 mController = null; 5060 Watchdog.getInstance().setActivityController(null); 5061 } 5062 } 5063 5064 long anrTime = SystemClock.uptimeMillis(); 5065 if (MONITOR_CPU_USAGE) { 5066 updateCpuStatsNow(); 5067 } 5068 5069 synchronized (this) { 5070 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5071 if (mShuttingDown) { 5072 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5073 return; 5074 } else if (app.notResponding) { 5075 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5076 return; 5077 } else if (app.crashing) { 5078 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5079 return; 5080 } 5081 5082 // In case we come through here for the same app before completing 5083 // this one, mark as anring now so we will bail out. 5084 app.notResponding = true; 5085 5086 // Log the ANR to the event log. 5087 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5088 app.processName, app.info.flags, annotation); 5089 5090 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5091 firstPids.add(app.pid); 5092 5093 int parentPid = app.pid; 5094 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5095 if (parentPid != app.pid) firstPids.add(parentPid); 5096 5097 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5098 5099 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5100 ProcessRecord r = mLruProcesses.get(i); 5101 if (r != null && r.thread != null) { 5102 int pid = r.pid; 5103 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5104 if (r.persistent) { 5105 firstPids.add(pid); 5106 } else { 5107 lastPids.put(pid, Boolean.TRUE); 5108 } 5109 } 5110 } 5111 } 5112 } 5113 5114 // Log the ANR to the main log. 5115 StringBuilder info = new StringBuilder(); 5116 info.setLength(0); 5117 info.append("ANR in ").append(app.processName); 5118 if (activity != null && activity.shortComponentName != null) { 5119 info.append(" (").append(activity.shortComponentName).append(")"); 5120 } 5121 info.append("\n"); 5122 info.append("PID: ").append(app.pid).append("\n"); 5123 if (annotation != null) { 5124 info.append("Reason: ").append(annotation).append("\n"); 5125 } 5126 if (parent != null && parent != activity) { 5127 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5128 } 5129 5130 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5131 5132 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5133 NATIVE_STACKS_OF_INTEREST); 5134 5135 String cpuInfo = null; 5136 if (MONITOR_CPU_USAGE) { 5137 updateCpuStatsNow(); 5138 synchronized (mProcessCpuTracker) { 5139 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5140 } 5141 info.append(processCpuTracker.printCurrentLoad()); 5142 info.append(cpuInfo); 5143 } 5144 5145 info.append(processCpuTracker.printCurrentState(anrTime)); 5146 5147 Slog.e(TAG, info.toString()); 5148 if (tracesFile == null) { 5149 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5150 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5151 } 5152 5153 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5154 cpuInfo, tracesFile, null); 5155 5156 if (mController != null) { 5157 try { 5158 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5159 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5160 if (res != 0) { 5161 if (res < 0 && app.pid != MY_PID) { 5162 app.kill("anr", true); 5163 } else { 5164 synchronized (this) { 5165 mServices.scheduleServiceTimeoutLocked(app); 5166 } 5167 } 5168 return; 5169 } 5170 } catch (RemoteException e) { 5171 mController = null; 5172 Watchdog.getInstance().setActivityController(null); 5173 } 5174 } 5175 5176 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5177 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5178 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5179 5180 synchronized (this) { 5181 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5182 app.kill("bg anr", true); 5183 return; 5184 } 5185 5186 // Set the app's notResponding state, and look up the errorReportReceiver 5187 makeAppNotRespondingLocked(app, 5188 activity != null ? activity.shortComponentName : null, 5189 annotation != null ? "ANR " + annotation : "ANR", 5190 info.toString()); 5191 5192 // Bring up the infamous App Not Responding dialog 5193 Message msg = Message.obtain(); 5194 HashMap<String, Object> map = new HashMap<String, Object>(); 5195 msg.what = SHOW_NOT_RESPONDING_MSG; 5196 msg.obj = map; 5197 msg.arg1 = aboveSystem ? 1 : 0; 5198 map.put("app", app); 5199 if (activity != null) { 5200 map.put("activity", activity); 5201 } 5202 5203 mHandler.sendMessage(msg); 5204 } 5205 } 5206 5207 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5208 if (!mLaunchWarningShown) { 5209 mLaunchWarningShown = true; 5210 mHandler.post(new Runnable() { 5211 @Override 5212 public void run() { 5213 synchronized (ActivityManagerService.this) { 5214 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5215 d.show(); 5216 mHandler.postDelayed(new Runnable() { 5217 @Override 5218 public void run() { 5219 synchronized (ActivityManagerService.this) { 5220 d.dismiss(); 5221 mLaunchWarningShown = false; 5222 } 5223 } 5224 }, 4000); 5225 } 5226 } 5227 }); 5228 } 5229 } 5230 5231 @Override 5232 public boolean clearApplicationUserData(final String packageName, 5233 final IPackageDataObserver observer, int userId) { 5234 enforceNotIsolatedCaller("clearApplicationUserData"); 5235 int uid = Binder.getCallingUid(); 5236 int pid = Binder.getCallingPid(); 5237 userId = handleIncomingUser(pid, uid, 5238 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5239 long callingId = Binder.clearCallingIdentity(); 5240 try { 5241 IPackageManager pm = AppGlobals.getPackageManager(); 5242 int pkgUid = -1; 5243 synchronized(this) { 5244 try { 5245 pkgUid = pm.getPackageUid(packageName, userId); 5246 } catch (RemoteException e) { 5247 } 5248 if (pkgUid == -1) { 5249 Slog.w(TAG, "Invalid packageName: " + packageName); 5250 if (observer != null) { 5251 try { 5252 observer.onRemoveCompleted(packageName, false); 5253 } catch (RemoteException e) { 5254 Slog.i(TAG, "Observer no longer exists."); 5255 } 5256 } 5257 return false; 5258 } 5259 if (uid == pkgUid || checkComponentPermission( 5260 android.Manifest.permission.CLEAR_APP_USER_DATA, 5261 pid, uid, -1, true) 5262 == PackageManager.PERMISSION_GRANTED) { 5263 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5264 } else { 5265 throw new SecurityException("PID " + pid + " does not have permission " 5266 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5267 + " of package " + packageName); 5268 } 5269 5270 // Remove all tasks match the cleared application package and user 5271 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5272 final TaskRecord tr = mRecentTasks.get(i); 5273 final String taskPackageName = 5274 tr.getBaseIntent().getComponent().getPackageName(); 5275 if (tr.userId != userId) continue; 5276 if (!taskPackageName.equals(packageName)) continue; 5277 removeTaskByIdLocked(tr.taskId, 0); 5278 } 5279 } 5280 5281 try { 5282 // Clear application user data 5283 pm.clearApplicationUserData(packageName, observer, userId); 5284 5285 synchronized(this) { 5286 // Remove all permissions granted from/to this package 5287 removeUriPermissionsForPackageLocked(packageName, userId, true); 5288 } 5289 5290 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5291 Uri.fromParts("package", packageName, null)); 5292 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5293 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5294 null, null, 0, null, null, null, false, false, userId); 5295 } catch (RemoteException e) { 5296 } 5297 } finally { 5298 Binder.restoreCallingIdentity(callingId); 5299 } 5300 return true; 5301 } 5302 5303 @Override 5304 public void killBackgroundProcesses(final String packageName, int userId) { 5305 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5306 != PackageManager.PERMISSION_GRANTED && 5307 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5308 != PackageManager.PERMISSION_GRANTED) { 5309 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5310 + Binder.getCallingPid() 5311 + ", uid=" + Binder.getCallingUid() 5312 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5313 Slog.w(TAG, msg); 5314 throw new SecurityException(msg); 5315 } 5316 5317 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5318 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5319 long callingId = Binder.clearCallingIdentity(); 5320 try { 5321 IPackageManager pm = AppGlobals.getPackageManager(); 5322 synchronized(this) { 5323 int appId = -1; 5324 try { 5325 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5326 } catch (RemoteException e) { 5327 } 5328 if (appId == -1) { 5329 Slog.w(TAG, "Invalid packageName: " + packageName); 5330 return; 5331 } 5332 killPackageProcessesLocked(packageName, appId, userId, 5333 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5334 } 5335 } finally { 5336 Binder.restoreCallingIdentity(callingId); 5337 } 5338 } 5339 5340 @Override 5341 public void killAllBackgroundProcesses() { 5342 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5343 != PackageManager.PERMISSION_GRANTED) { 5344 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5345 + Binder.getCallingPid() 5346 + ", uid=" + Binder.getCallingUid() 5347 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5348 Slog.w(TAG, msg); 5349 throw new SecurityException(msg); 5350 } 5351 5352 long callingId = Binder.clearCallingIdentity(); 5353 try { 5354 synchronized(this) { 5355 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5356 final int NP = mProcessNames.getMap().size(); 5357 for (int ip=0; ip<NP; ip++) { 5358 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5359 final int NA = apps.size(); 5360 for (int ia=0; ia<NA; ia++) { 5361 ProcessRecord app = apps.valueAt(ia); 5362 if (app.persistent) { 5363 // we don't kill persistent processes 5364 continue; 5365 } 5366 if (app.removed) { 5367 procs.add(app); 5368 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5369 app.removed = true; 5370 procs.add(app); 5371 } 5372 } 5373 } 5374 5375 int N = procs.size(); 5376 for (int i=0; i<N; i++) { 5377 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5378 } 5379 mAllowLowerMemLevel = true; 5380 updateOomAdjLocked(); 5381 doLowMemReportIfNeededLocked(null); 5382 } 5383 } finally { 5384 Binder.restoreCallingIdentity(callingId); 5385 } 5386 } 5387 5388 @Override 5389 public void forceStopPackage(final String packageName, int userId) { 5390 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5391 != PackageManager.PERMISSION_GRANTED) { 5392 String msg = "Permission Denial: forceStopPackage() from pid=" 5393 + Binder.getCallingPid() 5394 + ", uid=" + Binder.getCallingUid() 5395 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5396 Slog.w(TAG, msg); 5397 throw new SecurityException(msg); 5398 } 5399 final int callingPid = Binder.getCallingPid(); 5400 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5401 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5402 long callingId = Binder.clearCallingIdentity(); 5403 try { 5404 IPackageManager pm = AppGlobals.getPackageManager(); 5405 synchronized(this) { 5406 int[] users = userId == UserHandle.USER_ALL 5407 ? getUsersLocked() : new int[] { userId }; 5408 for (int user : users) { 5409 int pkgUid = -1; 5410 try { 5411 pkgUid = pm.getPackageUid(packageName, user); 5412 } catch (RemoteException e) { 5413 } 5414 if (pkgUid == -1) { 5415 Slog.w(TAG, "Invalid packageName: " + packageName); 5416 continue; 5417 } 5418 try { 5419 pm.setPackageStoppedState(packageName, true, user); 5420 } catch (RemoteException e) { 5421 } catch (IllegalArgumentException e) { 5422 Slog.w(TAG, "Failed trying to unstop package " 5423 + packageName + ": " + e); 5424 } 5425 if (isUserRunningLocked(user, false)) { 5426 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5427 } 5428 } 5429 } 5430 } finally { 5431 Binder.restoreCallingIdentity(callingId); 5432 } 5433 } 5434 5435 @Override 5436 public void addPackageDependency(String packageName) { 5437 synchronized (this) { 5438 int callingPid = Binder.getCallingPid(); 5439 if (callingPid == Process.myPid()) { 5440 // Yeah, um, no. 5441 Slog.w(TAG, "Can't addPackageDependency on system process"); 5442 return; 5443 } 5444 ProcessRecord proc; 5445 synchronized (mPidsSelfLocked) { 5446 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5447 } 5448 if (proc != null) { 5449 if (proc.pkgDeps == null) { 5450 proc.pkgDeps = new ArraySet<String>(1); 5451 } 5452 proc.pkgDeps.add(packageName); 5453 } 5454 } 5455 } 5456 5457 /* 5458 * The pkg name and app id have to be specified. 5459 */ 5460 @Override 5461 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5462 if (pkg == null) { 5463 return; 5464 } 5465 // Make sure the uid is valid. 5466 if (appid < 0) { 5467 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5468 return; 5469 } 5470 int callerUid = Binder.getCallingUid(); 5471 // Only the system server can kill an application 5472 if (callerUid == Process.SYSTEM_UID) { 5473 // Post an aysnc message to kill the application 5474 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5475 msg.arg1 = appid; 5476 msg.arg2 = 0; 5477 Bundle bundle = new Bundle(); 5478 bundle.putString("pkg", pkg); 5479 bundle.putString("reason", reason); 5480 msg.obj = bundle; 5481 mHandler.sendMessage(msg); 5482 } else { 5483 throw new SecurityException(callerUid + " cannot kill pkg: " + 5484 pkg); 5485 } 5486 } 5487 5488 @Override 5489 public void closeSystemDialogs(String reason) { 5490 enforceNotIsolatedCaller("closeSystemDialogs"); 5491 5492 final int pid = Binder.getCallingPid(); 5493 final int uid = Binder.getCallingUid(); 5494 final long origId = Binder.clearCallingIdentity(); 5495 try { 5496 synchronized (this) { 5497 // Only allow this from foreground processes, so that background 5498 // applications can't abuse it to prevent system UI from being shown. 5499 if (uid >= Process.FIRST_APPLICATION_UID) { 5500 ProcessRecord proc; 5501 synchronized (mPidsSelfLocked) { 5502 proc = mPidsSelfLocked.get(pid); 5503 } 5504 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5505 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5506 + " from background process " + proc); 5507 return; 5508 } 5509 } 5510 closeSystemDialogsLocked(reason); 5511 } 5512 } finally { 5513 Binder.restoreCallingIdentity(origId); 5514 } 5515 } 5516 5517 void closeSystemDialogsLocked(String reason) { 5518 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5519 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5520 | Intent.FLAG_RECEIVER_FOREGROUND); 5521 if (reason != null) { 5522 intent.putExtra("reason", reason); 5523 } 5524 mWindowManager.closeSystemDialogs(reason); 5525 5526 mStackSupervisor.closeSystemDialogsLocked(); 5527 5528 broadcastIntentLocked(null, null, intent, null, 5529 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5530 Process.SYSTEM_UID, UserHandle.USER_ALL); 5531 } 5532 5533 @Override 5534 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5535 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5536 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5537 for (int i=pids.length-1; i>=0; i--) { 5538 ProcessRecord proc; 5539 int oomAdj; 5540 synchronized (this) { 5541 synchronized (mPidsSelfLocked) { 5542 proc = mPidsSelfLocked.get(pids[i]); 5543 oomAdj = proc != null ? proc.setAdj : 0; 5544 } 5545 } 5546 infos[i] = new Debug.MemoryInfo(); 5547 Debug.getMemoryInfo(pids[i], infos[i]); 5548 if (proc != null) { 5549 synchronized (this) { 5550 if (proc.thread != null && proc.setAdj == oomAdj) { 5551 // Record this for posterity if the process has been stable. 5552 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5553 infos[i].getTotalUss(), false, proc.pkgList); 5554 } 5555 } 5556 } 5557 } 5558 return infos; 5559 } 5560 5561 @Override 5562 public long[] getProcessPss(int[] pids) { 5563 enforceNotIsolatedCaller("getProcessPss"); 5564 long[] pss = new long[pids.length]; 5565 for (int i=pids.length-1; i>=0; i--) { 5566 ProcessRecord proc; 5567 int oomAdj; 5568 synchronized (this) { 5569 synchronized (mPidsSelfLocked) { 5570 proc = mPidsSelfLocked.get(pids[i]); 5571 oomAdj = proc != null ? proc.setAdj : 0; 5572 } 5573 } 5574 long[] tmpUss = new long[1]; 5575 pss[i] = Debug.getPss(pids[i], tmpUss); 5576 if (proc != null) { 5577 synchronized (this) { 5578 if (proc.thread != null && proc.setAdj == oomAdj) { 5579 // Record this for posterity if the process has been stable. 5580 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5581 } 5582 } 5583 } 5584 } 5585 return pss; 5586 } 5587 5588 @Override 5589 public void killApplicationProcess(String processName, int uid) { 5590 if (processName == null) { 5591 return; 5592 } 5593 5594 int callerUid = Binder.getCallingUid(); 5595 // Only the system server can kill an application 5596 if (callerUid == Process.SYSTEM_UID) { 5597 synchronized (this) { 5598 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5599 if (app != null && app.thread != null) { 5600 try { 5601 app.thread.scheduleSuicide(); 5602 } catch (RemoteException e) { 5603 // If the other end already died, then our work here is done. 5604 } 5605 } else { 5606 Slog.w(TAG, "Process/uid not found attempting kill of " 5607 + processName + " / " + uid); 5608 } 5609 } 5610 } else { 5611 throw new SecurityException(callerUid + " cannot kill app process: " + 5612 processName); 5613 } 5614 } 5615 5616 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5617 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5618 false, true, false, false, UserHandle.getUserId(uid), reason); 5619 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5620 Uri.fromParts("package", packageName, null)); 5621 if (!mProcessesReady) { 5622 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5623 | Intent.FLAG_RECEIVER_FOREGROUND); 5624 } 5625 intent.putExtra(Intent.EXTRA_UID, uid); 5626 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5627 broadcastIntentLocked(null, null, intent, 5628 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5629 false, false, 5630 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5631 } 5632 5633 private void forceStopUserLocked(int userId, String reason) { 5634 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5635 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5636 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5637 | Intent.FLAG_RECEIVER_FOREGROUND); 5638 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5639 broadcastIntentLocked(null, null, intent, 5640 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5641 false, false, 5642 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5643 } 5644 5645 private final boolean killPackageProcessesLocked(String packageName, int appId, 5646 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5647 boolean doit, boolean evenPersistent, String reason) { 5648 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5649 5650 // Remove all processes this package may have touched: all with the 5651 // same UID (except for the system or root user), and all whose name 5652 // matches the package name. 5653 final int NP = mProcessNames.getMap().size(); 5654 for (int ip=0; ip<NP; ip++) { 5655 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5656 final int NA = apps.size(); 5657 for (int ia=0; ia<NA; ia++) { 5658 ProcessRecord app = apps.valueAt(ia); 5659 if (app.persistent && !evenPersistent) { 5660 // we don't kill persistent processes 5661 continue; 5662 } 5663 if (app.removed) { 5664 if (doit) { 5665 procs.add(app); 5666 } 5667 continue; 5668 } 5669 5670 // Skip process if it doesn't meet our oom adj requirement. 5671 if (app.setAdj < minOomAdj) { 5672 continue; 5673 } 5674 5675 // If no package is specified, we call all processes under the 5676 // give user id. 5677 if (packageName == null) { 5678 if (app.userId != userId) { 5679 continue; 5680 } 5681 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5682 continue; 5683 } 5684 // Package has been specified, we want to hit all processes 5685 // that match it. We need to qualify this by the processes 5686 // that are running under the specified app and user ID. 5687 } else { 5688 final boolean isDep = app.pkgDeps != null 5689 && app.pkgDeps.contains(packageName); 5690 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5691 continue; 5692 } 5693 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5694 continue; 5695 } 5696 if (!app.pkgList.containsKey(packageName) && !isDep) { 5697 continue; 5698 } 5699 } 5700 5701 // Process has passed all conditions, kill it! 5702 if (!doit) { 5703 return true; 5704 } 5705 app.removed = true; 5706 procs.add(app); 5707 } 5708 } 5709 5710 int N = procs.size(); 5711 for (int i=0; i<N; i++) { 5712 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5713 } 5714 updateOomAdjLocked(); 5715 return N > 0; 5716 } 5717 5718 private final boolean forceStopPackageLocked(String name, int appId, 5719 boolean callerWillRestart, boolean purgeCache, boolean doit, 5720 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5721 int i; 5722 int N; 5723 5724 if (userId == UserHandle.USER_ALL && name == null) { 5725 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5726 } 5727 5728 if (appId < 0 && name != null) { 5729 try { 5730 appId = UserHandle.getAppId( 5731 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5732 } catch (RemoteException e) { 5733 } 5734 } 5735 5736 if (doit) { 5737 if (name != null) { 5738 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5739 + " user=" + userId + ": " + reason); 5740 } else { 5741 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5742 } 5743 5744 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5745 for (int ip=pmap.size()-1; ip>=0; ip--) { 5746 SparseArray<Long> ba = pmap.valueAt(ip); 5747 for (i=ba.size()-1; i>=0; i--) { 5748 boolean remove = false; 5749 final int entUid = ba.keyAt(i); 5750 if (name != null) { 5751 if (userId == UserHandle.USER_ALL) { 5752 if (UserHandle.getAppId(entUid) == appId) { 5753 remove = true; 5754 } 5755 } else { 5756 if (entUid == UserHandle.getUid(userId, appId)) { 5757 remove = true; 5758 } 5759 } 5760 } else if (UserHandle.getUserId(entUid) == userId) { 5761 remove = true; 5762 } 5763 if (remove) { 5764 ba.removeAt(i); 5765 } 5766 } 5767 if (ba.size() == 0) { 5768 pmap.removeAt(ip); 5769 } 5770 } 5771 } 5772 5773 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5774 -100, callerWillRestart, true, doit, evenPersistent, 5775 name == null ? ("stop user " + userId) : ("stop " + name)); 5776 5777 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5778 if (!doit) { 5779 return true; 5780 } 5781 didSomething = true; 5782 } 5783 5784 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5785 if (!doit) { 5786 return true; 5787 } 5788 didSomething = true; 5789 } 5790 5791 if (name == null) { 5792 // Remove all sticky broadcasts from this user. 5793 mStickyBroadcasts.remove(userId); 5794 } 5795 5796 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5797 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5798 userId, providers)) { 5799 if (!doit) { 5800 return true; 5801 } 5802 didSomething = true; 5803 } 5804 N = providers.size(); 5805 for (i=0; i<N; i++) { 5806 removeDyingProviderLocked(null, providers.get(i), true); 5807 } 5808 5809 // Remove transient permissions granted from/to this package/user 5810 removeUriPermissionsForPackageLocked(name, userId, false); 5811 5812 if (name == null || uninstalling) { 5813 // Remove pending intents. For now we only do this when force 5814 // stopping users, because we have some problems when doing this 5815 // for packages -- app widgets are not currently cleaned up for 5816 // such packages, so they can be left with bad pending intents. 5817 if (mIntentSenderRecords.size() > 0) { 5818 Iterator<WeakReference<PendingIntentRecord>> it 5819 = mIntentSenderRecords.values().iterator(); 5820 while (it.hasNext()) { 5821 WeakReference<PendingIntentRecord> wpir = it.next(); 5822 if (wpir == null) { 5823 it.remove(); 5824 continue; 5825 } 5826 PendingIntentRecord pir = wpir.get(); 5827 if (pir == null) { 5828 it.remove(); 5829 continue; 5830 } 5831 if (name == null) { 5832 // Stopping user, remove all objects for the user. 5833 if (pir.key.userId != userId) { 5834 // Not the same user, skip it. 5835 continue; 5836 } 5837 } else { 5838 if (UserHandle.getAppId(pir.uid) != appId) { 5839 // Different app id, skip it. 5840 continue; 5841 } 5842 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5843 // Different user, skip it. 5844 continue; 5845 } 5846 if (!pir.key.packageName.equals(name)) { 5847 // Different package, skip it. 5848 continue; 5849 } 5850 } 5851 if (!doit) { 5852 return true; 5853 } 5854 didSomething = true; 5855 it.remove(); 5856 pir.canceled = true; 5857 if (pir.key.activity != null) { 5858 pir.key.activity.pendingResults.remove(pir.ref); 5859 } 5860 } 5861 } 5862 } 5863 5864 if (doit) { 5865 if (purgeCache && name != null) { 5866 AttributeCache ac = AttributeCache.instance(); 5867 if (ac != null) { 5868 ac.removePackage(name); 5869 } 5870 } 5871 if (mBooted) { 5872 mStackSupervisor.resumeTopActivitiesLocked(); 5873 mStackSupervisor.scheduleIdleLocked(); 5874 } 5875 } 5876 5877 return didSomething; 5878 } 5879 5880 private final boolean removeProcessLocked(ProcessRecord app, 5881 boolean callerWillRestart, boolean allowRestart, String reason) { 5882 final String name = app.processName; 5883 final int uid = app.uid; 5884 if (DEBUG_PROCESSES) Slog.d( 5885 TAG, "Force removing proc " + app.toShortString() + " (" + name 5886 + "/" + uid + ")"); 5887 5888 mProcessNames.remove(name, uid); 5889 mIsolatedProcesses.remove(app.uid); 5890 if (mHeavyWeightProcess == app) { 5891 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5892 mHeavyWeightProcess.userId, 0)); 5893 mHeavyWeightProcess = null; 5894 } 5895 boolean needRestart = false; 5896 if (app.pid > 0 && app.pid != MY_PID) { 5897 int pid = app.pid; 5898 synchronized (mPidsSelfLocked) { 5899 mPidsSelfLocked.remove(pid); 5900 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5901 } 5902 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5903 if (app.isolated) { 5904 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5905 } 5906 app.kill(reason, true); 5907 handleAppDiedLocked(app, true, allowRestart); 5908 removeLruProcessLocked(app); 5909 5910 if (app.persistent && !app.isolated) { 5911 if (!callerWillRestart) { 5912 addAppLocked(app.info, false, null /* ABI override */); 5913 } else { 5914 needRestart = true; 5915 } 5916 } 5917 } else { 5918 mRemovedProcesses.add(app); 5919 } 5920 5921 return needRestart; 5922 } 5923 5924 private final void processStartTimedOutLocked(ProcessRecord app) { 5925 final int pid = app.pid; 5926 boolean gone = false; 5927 synchronized (mPidsSelfLocked) { 5928 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5929 if (knownApp != null && knownApp.thread == null) { 5930 mPidsSelfLocked.remove(pid); 5931 gone = true; 5932 } 5933 } 5934 5935 if (gone) { 5936 Slog.w(TAG, "Process " + app + " failed to attach"); 5937 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5938 pid, app.uid, app.processName); 5939 mProcessNames.remove(app.processName, app.uid); 5940 mIsolatedProcesses.remove(app.uid); 5941 if (mHeavyWeightProcess == app) { 5942 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5943 mHeavyWeightProcess.userId, 0)); 5944 mHeavyWeightProcess = null; 5945 } 5946 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5947 if (app.isolated) { 5948 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5949 } 5950 // Take care of any launching providers waiting for this process. 5951 checkAppInLaunchingProvidersLocked(app, true); 5952 // Take care of any services that are waiting for the process. 5953 mServices.processStartTimedOutLocked(app); 5954 app.kill("start timeout", true); 5955 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5956 Slog.w(TAG, "Unattached app died before backup, skipping"); 5957 try { 5958 IBackupManager bm = IBackupManager.Stub.asInterface( 5959 ServiceManager.getService(Context.BACKUP_SERVICE)); 5960 bm.agentDisconnected(app.info.packageName); 5961 } catch (RemoteException e) { 5962 // Can't happen; the backup manager is local 5963 } 5964 } 5965 if (isPendingBroadcastProcessLocked(pid)) { 5966 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5967 skipPendingBroadcastLocked(pid); 5968 } 5969 } else { 5970 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5971 } 5972 } 5973 5974 private final boolean attachApplicationLocked(IApplicationThread thread, 5975 int pid) { 5976 5977 // Find the application record that is being attached... either via 5978 // the pid if we are running in multiple processes, or just pull the 5979 // next app record if we are emulating process with anonymous threads. 5980 ProcessRecord app; 5981 if (pid != MY_PID && pid >= 0) { 5982 synchronized (mPidsSelfLocked) { 5983 app = mPidsSelfLocked.get(pid); 5984 } 5985 } else { 5986 app = null; 5987 } 5988 5989 if (app == null) { 5990 Slog.w(TAG, "No pending application record for pid " + pid 5991 + " (IApplicationThread " + thread + "); dropping process"); 5992 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5993 if (pid > 0 && pid != MY_PID) { 5994 Process.killProcessQuiet(pid); 5995 //TODO: Process.killProcessGroup(app.info.uid, pid); 5996 } else { 5997 try { 5998 thread.scheduleExit(); 5999 } catch (Exception e) { 6000 // Ignore exceptions. 6001 } 6002 } 6003 return false; 6004 } 6005 6006 // If this application record is still attached to a previous 6007 // process, clean it up now. 6008 if (app.thread != null) { 6009 handleAppDiedLocked(app, true, true); 6010 } 6011 6012 // Tell the process all about itself. 6013 6014 if (localLOGV) Slog.v( 6015 TAG, "Binding process pid " + pid + " to record " + app); 6016 6017 final String processName = app.processName; 6018 try { 6019 AppDeathRecipient adr = new AppDeathRecipient( 6020 app, pid, thread); 6021 thread.asBinder().linkToDeath(adr, 0); 6022 app.deathRecipient = adr; 6023 } catch (RemoteException e) { 6024 app.resetPackageList(mProcessStats); 6025 startProcessLocked(app, "link fail", processName); 6026 return false; 6027 } 6028 6029 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6030 6031 app.makeActive(thread, mProcessStats); 6032 app.curAdj = app.setAdj = -100; 6033 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6034 app.forcingToForeground = null; 6035 updateProcessForegroundLocked(app, false, false); 6036 app.hasShownUi = false; 6037 app.debugging = false; 6038 app.cached = false; 6039 6040 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6041 6042 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6043 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6044 6045 if (!normalMode) { 6046 Slog.i(TAG, "Launching preboot mode app: " + app); 6047 } 6048 6049 if (localLOGV) Slog.v( 6050 TAG, "New app record " + app 6051 + " thread=" + thread.asBinder() + " pid=" + pid); 6052 try { 6053 int testMode = IApplicationThread.DEBUG_OFF; 6054 if (mDebugApp != null && mDebugApp.equals(processName)) { 6055 testMode = mWaitForDebugger 6056 ? IApplicationThread.DEBUG_WAIT 6057 : IApplicationThread.DEBUG_ON; 6058 app.debugging = true; 6059 if (mDebugTransient) { 6060 mDebugApp = mOrigDebugApp; 6061 mWaitForDebugger = mOrigWaitForDebugger; 6062 } 6063 } 6064 String profileFile = app.instrumentationProfileFile; 6065 ParcelFileDescriptor profileFd = null; 6066 int samplingInterval = 0; 6067 boolean profileAutoStop = false; 6068 if (mProfileApp != null && mProfileApp.equals(processName)) { 6069 mProfileProc = app; 6070 profileFile = mProfileFile; 6071 profileFd = mProfileFd; 6072 samplingInterval = mSamplingInterval; 6073 profileAutoStop = mAutoStopProfiler; 6074 } 6075 boolean enableOpenGlTrace = false; 6076 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6077 enableOpenGlTrace = true; 6078 mOpenGlTraceApp = null; 6079 } 6080 6081 // If the app is being launched for restore or full backup, set it up specially 6082 boolean isRestrictedBackupMode = false; 6083 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6084 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6085 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6086 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6087 } 6088 6089 ensurePackageDexOpt(app.instrumentationInfo != null 6090 ? app.instrumentationInfo.packageName 6091 : app.info.packageName); 6092 if (app.instrumentationClass != null) { 6093 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6094 } 6095 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6096 + processName + " with config " + mConfiguration); 6097 ApplicationInfo appInfo = app.instrumentationInfo != null 6098 ? app.instrumentationInfo : app.info; 6099 app.compat = compatibilityInfoForPackageLocked(appInfo); 6100 if (profileFd != null) { 6101 profileFd = profileFd.dup(); 6102 } 6103 ProfilerInfo profilerInfo = profileFile == null ? null 6104 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6105 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6106 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6107 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6108 isRestrictedBackupMode || !normalMode, app.persistent, 6109 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6110 mCoreSettingsObserver.getCoreSettingsLocked()); 6111 updateLruProcessLocked(app, false, null); 6112 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6113 } catch (Exception e) { 6114 // todo: Yikes! What should we do? For now we will try to 6115 // start another process, but that could easily get us in 6116 // an infinite loop of restarting processes... 6117 Slog.w(TAG, "Exception thrown during bind!", e); 6118 6119 app.resetPackageList(mProcessStats); 6120 app.unlinkDeathRecipient(); 6121 startProcessLocked(app, "bind fail", processName); 6122 return false; 6123 } 6124 6125 // Remove this record from the list of starting applications. 6126 mPersistentStartingProcesses.remove(app); 6127 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6128 "Attach application locked removing on hold: " + app); 6129 mProcessesOnHold.remove(app); 6130 6131 boolean badApp = false; 6132 boolean didSomething = false; 6133 6134 // See if the top visible activity is waiting to run in this process... 6135 if (normalMode) { 6136 try { 6137 if (mStackSupervisor.attachApplicationLocked(app)) { 6138 didSomething = true; 6139 } 6140 } catch (Exception e) { 6141 badApp = true; 6142 } 6143 } 6144 6145 // Find any services that should be running in this process... 6146 if (!badApp) { 6147 try { 6148 didSomething |= mServices.attachApplicationLocked(app, processName); 6149 } catch (Exception e) { 6150 badApp = true; 6151 } 6152 } 6153 6154 // Check if a next-broadcast receiver is in this process... 6155 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6156 try { 6157 didSomething |= sendPendingBroadcastsLocked(app); 6158 } catch (Exception e) { 6159 // If the app died trying to launch the receiver we declare it 'bad' 6160 badApp = true; 6161 } 6162 } 6163 6164 // Check whether the next backup agent is in this process... 6165 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6166 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6167 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6168 try { 6169 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6170 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6171 mBackupTarget.backupMode); 6172 } catch (Exception e) { 6173 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6174 e.printStackTrace(); 6175 } 6176 } 6177 6178 if (badApp) { 6179 // todo: Also need to kill application to deal with all 6180 // kinds of exceptions. 6181 handleAppDiedLocked(app, false, true); 6182 return false; 6183 } 6184 6185 if (!didSomething) { 6186 updateOomAdjLocked(); 6187 } 6188 6189 return true; 6190 } 6191 6192 @Override 6193 public final void attachApplication(IApplicationThread thread) { 6194 synchronized (this) { 6195 int callingPid = Binder.getCallingPid(); 6196 final long origId = Binder.clearCallingIdentity(); 6197 attachApplicationLocked(thread, callingPid); 6198 Binder.restoreCallingIdentity(origId); 6199 } 6200 } 6201 6202 @Override 6203 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6204 final long origId = Binder.clearCallingIdentity(); 6205 synchronized (this) { 6206 ActivityStack stack = ActivityRecord.getStackLocked(token); 6207 if (stack != null) { 6208 ActivityRecord r = 6209 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6210 if (stopProfiling) { 6211 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6212 try { 6213 mProfileFd.close(); 6214 } catch (IOException e) { 6215 } 6216 clearProfilerLocked(); 6217 } 6218 } 6219 } 6220 } 6221 Binder.restoreCallingIdentity(origId); 6222 } 6223 6224 void postEnableScreenAfterBootLocked() { 6225 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6226 } 6227 6228 void enableScreenAfterBoot() { 6229 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6230 SystemClock.uptimeMillis()); 6231 mWindowManager.enableScreenAfterBoot(); 6232 6233 synchronized (this) { 6234 updateEventDispatchingLocked(); 6235 } 6236 } 6237 6238 @Override 6239 public void showBootMessage(final CharSequence msg, final boolean always) { 6240 enforceNotIsolatedCaller("showBootMessage"); 6241 mWindowManager.showBootMessage(msg, always); 6242 } 6243 6244 @Override 6245 public void keyguardWaitingForActivityDrawn() { 6246 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6247 final long token = Binder.clearCallingIdentity(); 6248 try { 6249 synchronized (this) { 6250 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6251 mWindowManager.keyguardWaitingForActivityDrawn(); 6252 if (mLockScreenShown) { 6253 mLockScreenShown = false; 6254 comeOutOfSleepIfNeededLocked(); 6255 } 6256 } 6257 } finally { 6258 Binder.restoreCallingIdentity(token); 6259 } 6260 } 6261 6262 final void finishBooting() { 6263 synchronized (this) { 6264 if (!mBootAnimationComplete) { 6265 mCallFinishBooting = true; 6266 return; 6267 } 6268 mCallFinishBooting = false; 6269 } 6270 6271 // Register receivers to handle package update events 6272 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6273 6274 // Let system services know. 6275 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6276 6277 synchronized (this) { 6278 // Ensure that any processes we had put on hold are now started 6279 // up. 6280 final int NP = mProcessesOnHold.size(); 6281 if (NP > 0) { 6282 ArrayList<ProcessRecord> procs = 6283 new ArrayList<ProcessRecord>(mProcessesOnHold); 6284 for (int ip=0; ip<NP; ip++) { 6285 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6286 + procs.get(ip)); 6287 startProcessLocked(procs.get(ip), "on-hold", null); 6288 } 6289 } 6290 6291 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6292 // Start looking for apps that are abusing wake locks. 6293 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6294 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6295 // Tell anyone interested that we are done booting! 6296 SystemProperties.set("sys.boot_completed", "1"); 6297 SystemProperties.set("dev.bootcomplete", "1"); 6298 for (int i=0; i<mStartedUsers.size(); i++) { 6299 UserStartedState uss = mStartedUsers.valueAt(i); 6300 if (uss.mState == UserStartedState.STATE_BOOTING) { 6301 uss.mState = UserStartedState.STATE_RUNNING; 6302 final int userId = mStartedUsers.keyAt(i); 6303 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6304 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6305 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6306 broadcastIntentLocked(null, null, intent, null, 6307 new IIntentReceiver.Stub() { 6308 @Override 6309 public void performReceive(Intent intent, int resultCode, 6310 String data, Bundle extras, boolean ordered, 6311 boolean sticky, int sendingUser) { 6312 synchronized (ActivityManagerService.this) { 6313 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6314 true, false); 6315 } 6316 } 6317 }, 6318 0, null, null, 6319 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6320 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6321 userId); 6322 } 6323 } 6324 scheduleStartProfilesLocked(); 6325 } 6326 } 6327 } 6328 6329 @Override 6330 public void bootAnimationComplete() { 6331 final boolean callFinishBooting; 6332 synchronized (this) { 6333 callFinishBooting = mCallFinishBooting; 6334 mBootAnimationComplete = true; 6335 } 6336 if (callFinishBooting) { 6337 finishBooting(); 6338 } 6339 } 6340 6341 final void ensureBootCompleted() { 6342 boolean booting; 6343 boolean enableScreen; 6344 synchronized (this) { 6345 booting = mBooting; 6346 mBooting = false; 6347 enableScreen = !mBooted; 6348 mBooted = true; 6349 } 6350 6351 if (booting) { 6352 finishBooting(); 6353 } 6354 6355 if (enableScreen) { 6356 enableScreenAfterBoot(); 6357 } 6358 } 6359 6360 @Override 6361 public final void activityResumed(IBinder token) { 6362 final long origId = Binder.clearCallingIdentity(); 6363 synchronized(this) { 6364 ActivityStack stack = ActivityRecord.getStackLocked(token); 6365 if (stack != null) { 6366 ActivityRecord.activityResumedLocked(token); 6367 } 6368 } 6369 Binder.restoreCallingIdentity(origId); 6370 } 6371 6372 @Override 6373 public final void activityPaused(IBinder token) { 6374 final long origId = Binder.clearCallingIdentity(); 6375 synchronized(this) { 6376 ActivityStack stack = ActivityRecord.getStackLocked(token); 6377 if (stack != null) { 6378 stack.activityPausedLocked(token, false); 6379 } 6380 } 6381 Binder.restoreCallingIdentity(origId); 6382 } 6383 6384 @Override 6385 public final void activityStopped(IBinder token, Bundle icicle, 6386 PersistableBundle persistentState, CharSequence description) { 6387 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6388 6389 // Refuse possible leaked file descriptors 6390 if (icicle != null && icicle.hasFileDescriptors()) { 6391 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6392 } 6393 6394 final long origId = Binder.clearCallingIdentity(); 6395 6396 synchronized (this) { 6397 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6398 if (r != null) { 6399 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6400 } 6401 } 6402 6403 trimApplications(); 6404 6405 Binder.restoreCallingIdentity(origId); 6406 } 6407 6408 @Override 6409 public final void activityDestroyed(IBinder token) { 6410 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6411 synchronized (this) { 6412 ActivityStack stack = ActivityRecord.getStackLocked(token); 6413 if (stack != null) { 6414 stack.activityDestroyedLocked(token); 6415 } 6416 } 6417 } 6418 6419 @Override 6420 public final void backgroundResourcesReleased(IBinder token) { 6421 final long origId = Binder.clearCallingIdentity(); 6422 try { 6423 synchronized (this) { 6424 ActivityStack stack = ActivityRecord.getStackLocked(token); 6425 if (stack != null) { 6426 stack.backgroundResourcesReleased(token); 6427 } 6428 } 6429 } finally { 6430 Binder.restoreCallingIdentity(origId); 6431 } 6432 } 6433 6434 @Override 6435 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6436 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6437 } 6438 6439 @Override 6440 public final void notifyEnterAnimationComplete(IBinder token) { 6441 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6442 } 6443 6444 @Override 6445 public String getCallingPackage(IBinder token) { 6446 synchronized (this) { 6447 ActivityRecord r = getCallingRecordLocked(token); 6448 return r != null ? r.info.packageName : null; 6449 } 6450 } 6451 6452 @Override 6453 public ComponentName getCallingActivity(IBinder token) { 6454 synchronized (this) { 6455 ActivityRecord r = getCallingRecordLocked(token); 6456 return r != null ? r.intent.getComponent() : null; 6457 } 6458 } 6459 6460 private ActivityRecord getCallingRecordLocked(IBinder token) { 6461 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6462 if (r == null) { 6463 return null; 6464 } 6465 return r.resultTo; 6466 } 6467 6468 @Override 6469 public ComponentName getActivityClassForToken(IBinder token) { 6470 synchronized(this) { 6471 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6472 if (r == null) { 6473 return null; 6474 } 6475 return r.intent.getComponent(); 6476 } 6477 } 6478 6479 @Override 6480 public String getPackageForToken(IBinder token) { 6481 synchronized(this) { 6482 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6483 if (r == null) { 6484 return null; 6485 } 6486 return r.packageName; 6487 } 6488 } 6489 6490 @Override 6491 public IIntentSender getIntentSender(int type, 6492 String packageName, IBinder token, String resultWho, 6493 int requestCode, Intent[] intents, String[] resolvedTypes, 6494 int flags, Bundle options, int userId) { 6495 enforceNotIsolatedCaller("getIntentSender"); 6496 // Refuse possible leaked file descriptors 6497 if (intents != null) { 6498 if (intents.length < 1) { 6499 throw new IllegalArgumentException("Intents array length must be >= 1"); 6500 } 6501 for (int i=0; i<intents.length; i++) { 6502 Intent intent = intents[i]; 6503 if (intent != null) { 6504 if (intent.hasFileDescriptors()) { 6505 throw new IllegalArgumentException("File descriptors passed in Intent"); 6506 } 6507 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6508 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6509 throw new IllegalArgumentException( 6510 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6511 } 6512 intents[i] = new Intent(intent); 6513 } 6514 } 6515 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6516 throw new IllegalArgumentException( 6517 "Intent array length does not match resolvedTypes length"); 6518 } 6519 } 6520 if (options != null) { 6521 if (options.hasFileDescriptors()) { 6522 throw new IllegalArgumentException("File descriptors passed in options"); 6523 } 6524 } 6525 6526 synchronized(this) { 6527 int callingUid = Binder.getCallingUid(); 6528 int origUserId = userId; 6529 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6530 type == ActivityManager.INTENT_SENDER_BROADCAST, 6531 ALLOW_NON_FULL, "getIntentSender", null); 6532 if (origUserId == UserHandle.USER_CURRENT) { 6533 // We don't want to evaluate this until the pending intent is 6534 // actually executed. However, we do want to always do the 6535 // security checking for it above. 6536 userId = UserHandle.USER_CURRENT; 6537 } 6538 try { 6539 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6540 int uid = AppGlobals.getPackageManager() 6541 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6542 if (!UserHandle.isSameApp(callingUid, uid)) { 6543 String msg = "Permission Denial: getIntentSender() from pid=" 6544 + Binder.getCallingPid() 6545 + ", uid=" + Binder.getCallingUid() 6546 + ", (need uid=" + uid + ")" 6547 + " is not allowed to send as package " + packageName; 6548 Slog.w(TAG, msg); 6549 throw new SecurityException(msg); 6550 } 6551 } 6552 6553 return getIntentSenderLocked(type, packageName, callingUid, userId, 6554 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6555 6556 } catch (RemoteException e) { 6557 throw new SecurityException(e); 6558 } 6559 } 6560 } 6561 6562 IIntentSender getIntentSenderLocked(int type, String packageName, 6563 int callingUid, int userId, IBinder token, String resultWho, 6564 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6565 Bundle options) { 6566 if (DEBUG_MU) 6567 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6568 ActivityRecord activity = null; 6569 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6570 activity = ActivityRecord.isInStackLocked(token); 6571 if (activity == null) { 6572 return null; 6573 } 6574 if (activity.finishing) { 6575 return null; 6576 } 6577 } 6578 6579 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6580 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6581 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6582 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6583 |PendingIntent.FLAG_UPDATE_CURRENT); 6584 6585 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6586 type, packageName, activity, resultWho, 6587 requestCode, intents, resolvedTypes, flags, options, userId); 6588 WeakReference<PendingIntentRecord> ref; 6589 ref = mIntentSenderRecords.get(key); 6590 PendingIntentRecord rec = ref != null ? ref.get() : null; 6591 if (rec != null) { 6592 if (!cancelCurrent) { 6593 if (updateCurrent) { 6594 if (rec.key.requestIntent != null) { 6595 rec.key.requestIntent.replaceExtras(intents != null ? 6596 intents[intents.length - 1] : null); 6597 } 6598 if (intents != null) { 6599 intents[intents.length-1] = rec.key.requestIntent; 6600 rec.key.allIntents = intents; 6601 rec.key.allResolvedTypes = resolvedTypes; 6602 } else { 6603 rec.key.allIntents = null; 6604 rec.key.allResolvedTypes = null; 6605 } 6606 } 6607 return rec; 6608 } 6609 rec.canceled = true; 6610 mIntentSenderRecords.remove(key); 6611 } 6612 if (noCreate) { 6613 return rec; 6614 } 6615 rec = new PendingIntentRecord(this, key, callingUid); 6616 mIntentSenderRecords.put(key, rec.ref); 6617 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6618 if (activity.pendingResults == null) { 6619 activity.pendingResults 6620 = new HashSet<WeakReference<PendingIntentRecord>>(); 6621 } 6622 activity.pendingResults.add(rec.ref); 6623 } 6624 return rec; 6625 } 6626 6627 @Override 6628 public void cancelIntentSender(IIntentSender sender) { 6629 if (!(sender instanceof PendingIntentRecord)) { 6630 return; 6631 } 6632 synchronized(this) { 6633 PendingIntentRecord rec = (PendingIntentRecord)sender; 6634 try { 6635 int uid = AppGlobals.getPackageManager() 6636 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6637 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6638 String msg = "Permission Denial: cancelIntentSender() from pid=" 6639 + Binder.getCallingPid() 6640 + ", uid=" + Binder.getCallingUid() 6641 + " is not allowed to cancel packges " 6642 + rec.key.packageName; 6643 Slog.w(TAG, msg); 6644 throw new SecurityException(msg); 6645 } 6646 } catch (RemoteException e) { 6647 throw new SecurityException(e); 6648 } 6649 cancelIntentSenderLocked(rec, true); 6650 } 6651 } 6652 6653 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6654 rec.canceled = true; 6655 mIntentSenderRecords.remove(rec.key); 6656 if (cleanActivity && rec.key.activity != null) { 6657 rec.key.activity.pendingResults.remove(rec.ref); 6658 } 6659 } 6660 6661 @Override 6662 public String getPackageForIntentSender(IIntentSender pendingResult) { 6663 if (!(pendingResult instanceof PendingIntentRecord)) { 6664 return null; 6665 } 6666 try { 6667 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6668 return res.key.packageName; 6669 } catch (ClassCastException e) { 6670 } 6671 return null; 6672 } 6673 6674 @Override 6675 public int getUidForIntentSender(IIntentSender sender) { 6676 if (sender instanceof PendingIntentRecord) { 6677 try { 6678 PendingIntentRecord res = (PendingIntentRecord)sender; 6679 return res.uid; 6680 } catch (ClassCastException e) { 6681 } 6682 } 6683 return -1; 6684 } 6685 6686 @Override 6687 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6688 if (!(pendingResult instanceof PendingIntentRecord)) { 6689 return false; 6690 } 6691 try { 6692 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6693 if (res.key.allIntents == null) { 6694 return false; 6695 } 6696 for (int i=0; i<res.key.allIntents.length; i++) { 6697 Intent intent = res.key.allIntents[i]; 6698 if (intent.getPackage() != null && intent.getComponent() != null) { 6699 return false; 6700 } 6701 } 6702 return true; 6703 } catch (ClassCastException e) { 6704 } 6705 return false; 6706 } 6707 6708 @Override 6709 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6710 if (!(pendingResult instanceof PendingIntentRecord)) { 6711 return false; 6712 } 6713 try { 6714 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6715 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6716 return true; 6717 } 6718 return false; 6719 } catch (ClassCastException e) { 6720 } 6721 return false; 6722 } 6723 6724 @Override 6725 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6726 if (!(pendingResult instanceof PendingIntentRecord)) { 6727 return null; 6728 } 6729 try { 6730 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6731 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6732 } catch (ClassCastException e) { 6733 } 6734 return null; 6735 } 6736 6737 @Override 6738 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6739 if (!(pendingResult instanceof PendingIntentRecord)) { 6740 return null; 6741 } 6742 try { 6743 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6744 Intent intent = res.key.requestIntent; 6745 if (intent != null) { 6746 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6747 || res.lastTagPrefix.equals(prefix))) { 6748 return res.lastTag; 6749 } 6750 res.lastTagPrefix = prefix; 6751 StringBuilder sb = new StringBuilder(128); 6752 if (prefix != null) { 6753 sb.append(prefix); 6754 } 6755 if (intent.getAction() != null) { 6756 sb.append(intent.getAction()); 6757 } else if (intent.getComponent() != null) { 6758 intent.getComponent().appendShortString(sb); 6759 } else { 6760 sb.append("?"); 6761 } 6762 return res.lastTag = sb.toString(); 6763 } 6764 } catch (ClassCastException e) { 6765 } 6766 return null; 6767 } 6768 6769 @Override 6770 public void setProcessLimit(int max) { 6771 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6772 "setProcessLimit()"); 6773 synchronized (this) { 6774 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6775 mProcessLimitOverride = max; 6776 } 6777 trimApplications(); 6778 } 6779 6780 @Override 6781 public int getProcessLimit() { 6782 synchronized (this) { 6783 return mProcessLimitOverride; 6784 } 6785 } 6786 6787 void foregroundTokenDied(ForegroundToken token) { 6788 synchronized (ActivityManagerService.this) { 6789 synchronized (mPidsSelfLocked) { 6790 ForegroundToken cur 6791 = mForegroundProcesses.get(token.pid); 6792 if (cur != token) { 6793 return; 6794 } 6795 mForegroundProcesses.remove(token.pid); 6796 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6797 if (pr == null) { 6798 return; 6799 } 6800 pr.forcingToForeground = null; 6801 updateProcessForegroundLocked(pr, false, false); 6802 } 6803 updateOomAdjLocked(); 6804 } 6805 } 6806 6807 @Override 6808 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6809 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6810 "setProcessForeground()"); 6811 synchronized(this) { 6812 boolean changed = false; 6813 6814 synchronized (mPidsSelfLocked) { 6815 ProcessRecord pr = mPidsSelfLocked.get(pid); 6816 if (pr == null && isForeground) { 6817 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6818 return; 6819 } 6820 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6821 if (oldToken != null) { 6822 oldToken.token.unlinkToDeath(oldToken, 0); 6823 mForegroundProcesses.remove(pid); 6824 if (pr != null) { 6825 pr.forcingToForeground = null; 6826 } 6827 changed = true; 6828 } 6829 if (isForeground && token != null) { 6830 ForegroundToken newToken = new ForegroundToken() { 6831 @Override 6832 public void binderDied() { 6833 foregroundTokenDied(this); 6834 } 6835 }; 6836 newToken.pid = pid; 6837 newToken.token = token; 6838 try { 6839 token.linkToDeath(newToken, 0); 6840 mForegroundProcesses.put(pid, newToken); 6841 pr.forcingToForeground = token; 6842 changed = true; 6843 } catch (RemoteException e) { 6844 // If the process died while doing this, we will later 6845 // do the cleanup with the process death link. 6846 } 6847 } 6848 } 6849 6850 if (changed) { 6851 updateOomAdjLocked(); 6852 } 6853 } 6854 } 6855 6856 // ========================================================= 6857 // PERMISSIONS 6858 // ========================================================= 6859 6860 static class PermissionController extends IPermissionController.Stub { 6861 ActivityManagerService mActivityManagerService; 6862 PermissionController(ActivityManagerService activityManagerService) { 6863 mActivityManagerService = activityManagerService; 6864 } 6865 6866 @Override 6867 public boolean checkPermission(String permission, int pid, int uid) { 6868 return mActivityManagerService.checkPermission(permission, pid, 6869 uid) == PackageManager.PERMISSION_GRANTED; 6870 } 6871 } 6872 6873 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6874 @Override 6875 public int checkComponentPermission(String permission, int pid, int uid, 6876 int owningUid, boolean exported) { 6877 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6878 owningUid, exported); 6879 } 6880 6881 @Override 6882 public Object getAMSLock() { 6883 return ActivityManagerService.this; 6884 } 6885 } 6886 6887 /** 6888 * This can be called with or without the global lock held. 6889 */ 6890 int checkComponentPermission(String permission, int pid, int uid, 6891 int owningUid, boolean exported) { 6892 // We might be performing an operation on behalf of an indirect binder 6893 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6894 // client identity accordingly before proceeding. 6895 Identity tlsIdentity = sCallerIdentity.get(); 6896 if (tlsIdentity != null) { 6897 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6898 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6899 uid = tlsIdentity.uid; 6900 pid = tlsIdentity.pid; 6901 } 6902 6903 if (pid == MY_PID) { 6904 return PackageManager.PERMISSION_GRANTED; 6905 } 6906 6907 return ActivityManager.checkComponentPermission(permission, uid, 6908 owningUid, exported); 6909 } 6910 6911 /** 6912 * As the only public entry point for permissions checking, this method 6913 * can enforce the semantic that requesting a check on a null global 6914 * permission is automatically denied. (Internally a null permission 6915 * string is used when calling {@link #checkComponentPermission} in cases 6916 * when only uid-based security is needed.) 6917 * 6918 * This can be called with or without the global lock held. 6919 */ 6920 @Override 6921 public int checkPermission(String permission, int pid, int uid) { 6922 if (permission == null) { 6923 return PackageManager.PERMISSION_DENIED; 6924 } 6925 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6926 } 6927 6928 /** 6929 * Binder IPC calls go through the public entry point. 6930 * This can be called with or without the global lock held. 6931 */ 6932 int checkCallingPermission(String permission) { 6933 return checkPermission(permission, 6934 Binder.getCallingPid(), 6935 UserHandle.getAppId(Binder.getCallingUid())); 6936 } 6937 6938 /** 6939 * This can be called with or without the global lock held. 6940 */ 6941 void enforceCallingPermission(String permission, String func) { 6942 if (checkCallingPermission(permission) 6943 == PackageManager.PERMISSION_GRANTED) { 6944 return; 6945 } 6946 6947 String msg = "Permission Denial: " + func + " from pid=" 6948 + Binder.getCallingPid() 6949 + ", uid=" + Binder.getCallingUid() 6950 + " requires " + permission; 6951 Slog.w(TAG, msg); 6952 throw new SecurityException(msg); 6953 } 6954 6955 /** 6956 * Determine if UID is holding permissions required to access {@link Uri} in 6957 * the given {@link ProviderInfo}. Final permission checking is always done 6958 * in {@link ContentProvider}. 6959 */ 6960 private final boolean checkHoldingPermissionsLocked( 6961 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6962 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6963 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6964 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6965 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6966 != PERMISSION_GRANTED) { 6967 return false; 6968 } 6969 } 6970 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6971 } 6972 6973 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6974 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6975 if (pi.applicationInfo.uid == uid) { 6976 return true; 6977 } else if (!pi.exported) { 6978 return false; 6979 } 6980 6981 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6982 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6983 try { 6984 // check if target holds top-level <provider> permissions 6985 if (!readMet && pi.readPermission != null && considerUidPermissions 6986 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6987 readMet = true; 6988 } 6989 if (!writeMet && pi.writePermission != null && considerUidPermissions 6990 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6991 writeMet = true; 6992 } 6993 6994 // track if unprotected read/write is allowed; any denied 6995 // <path-permission> below removes this ability 6996 boolean allowDefaultRead = pi.readPermission == null; 6997 boolean allowDefaultWrite = pi.writePermission == null; 6998 6999 // check if target holds any <path-permission> that match uri 7000 final PathPermission[] pps = pi.pathPermissions; 7001 if (pps != null) { 7002 final String path = grantUri.uri.getPath(); 7003 int i = pps.length; 7004 while (i > 0 && (!readMet || !writeMet)) { 7005 i--; 7006 PathPermission pp = pps[i]; 7007 if (pp.match(path)) { 7008 if (!readMet) { 7009 final String pprperm = pp.getReadPermission(); 7010 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7011 + pprperm + " for " + pp.getPath() 7012 + ": match=" + pp.match(path) 7013 + " check=" + pm.checkUidPermission(pprperm, uid)); 7014 if (pprperm != null) { 7015 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7016 == PERMISSION_GRANTED) { 7017 readMet = true; 7018 } else { 7019 allowDefaultRead = false; 7020 } 7021 } 7022 } 7023 if (!writeMet) { 7024 final String ppwperm = pp.getWritePermission(); 7025 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7026 + ppwperm + " for " + pp.getPath() 7027 + ": match=" + pp.match(path) 7028 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7029 if (ppwperm != null) { 7030 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7031 == PERMISSION_GRANTED) { 7032 writeMet = true; 7033 } else { 7034 allowDefaultWrite = false; 7035 } 7036 } 7037 } 7038 } 7039 } 7040 } 7041 7042 // grant unprotected <provider> read/write, if not blocked by 7043 // <path-permission> above 7044 if (allowDefaultRead) readMet = true; 7045 if (allowDefaultWrite) writeMet = true; 7046 7047 } catch (RemoteException e) { 7048 return false; 7049 } 7050 7051 return readMet && writeMet; 7052 } 7053 7054 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7055 ProviderInfo pi = null; 7056 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7057 if (cpr != null) { 7058 pi = cpr.info; 7059 } else { 7060 try { 7061 pi = AppGlobals.getPackageManager().resolveContentProvider( 7062 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7063 } catch (RemoteException ex) { 7064 } 7065 } 7066 return pi; 7067 } 7068 7069 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7070 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7071 if (targetUris != null) { 7072 return targetUris.get(grantUri); 7073 } 7074 return null; 7075 } 7076 7077 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7078 String targetPkg, int targetUid, GrantUri grantUri) { 7079 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7080 if (targetUris == null) { 7081 targetUris = Maps.newArrayMap(); 7082 mGrantedUriPermissions.put(targetUid, targetUris); 7083 } 7084 7085 UriPermission perm = targetUris.get(grantUri); 7086 if (perm == null) { 7087 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7088 targetUris.put(grantUri, perm); 7089 } 7090 7091 return perm; 7092 } 7093 7094 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7095 final int modeFlags) { 7096 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7097 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7098 : UriPermission.STRENGTH_OWNED; 7099 7100 // Root gets to do everything. 7101 if (uid == 0) { 7102 return true; 7103 } 7104 7105 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7106 if (perms == null) return false; 7107 7108 // First look for exact match 7109 final UriPermission exactPerm = perms.get(grantUri); 7110 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7111 return true; 7112 } 7113 7114 // No exact match, look for prefixes 7115 final int N = perms.size(); 7116 for (int i = 0; i < N; i++) { 7117 final UriPermission perm = perms.valueAt(i); 7118 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7119 && perm.getStrength(modeFlags) >= minStrength) { 7120 return true; 7121 } 7122 } 7123 7124 return false; 7125 } 7126 7127 /** 7128 * @param uri This uri must NOT contain an embedded userId. 7129 * @param userId The userId in which the uri is to be resolved. 7130 */ 7131 @Override 7132 public int checkUriPermission(Uri uri, int pid, int uid, 7133 final int modeFlags, int userId) { 7134 enforceNotIsolatedCaller("checkUriPermission"); 7135 7136 // Another redirected-binder-call permissions check as in 7137 // {@link checkComponentPermission}. 7138 Identity tlsIdentity = sCallerIdentity.get(); 7139 if (tlsIdentity != null) { 7140 uid = tlsIdentity.uid; 7141 pid = tlsIdentity.pid; 7142 } 7143 7144 // Our own process gets to do everything. 7145 if (pid == MY_PID) { 7146 return PackageManager.PERMISSION_GRANTED; 7147 } 7148 synchronized (this) { 7149 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7150 ? PackageManager.PERMISSION_GRANTED 7151 : PackageManager.PERMISSION_DENIED; 7152 } 7153 } 7154 7155 /** 7156 * Check if the targetPkg can be granted permission to access uri by 7157 * the callingUid using the given modeFlags. Throws a security exception 7158 * if callingUid is not allowed to do this. Returns the uid of the target 7159 * if the URI permission grant should be performed; returns -1 if it is not 7160 * needed (for example targetPkg already has permission to access the URI). 7161 * If you already know the uid of the target, you can supply it in 7162 * lastTargetUid else set that to -1. 7163 */ 7164 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7165 final int modeFlags, int lastTargetUid) { 7166 if (!Intent.isAccessUriMode(modeFlags)) { 7167 return -1; 7168 } 7169 7170 if (targetPkg != null) { 7171 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7172 "Checking grant " + targetPkg + " permission to " + grantUri); 7173 } 7174 7175 final IPackageManager pm = AppGlobals.getPackageManager(); 7176 7177 // If this is not a content: uri, we can't do anything with it. 7178 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7179 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7180 "Can't grant URI permission for non-content URI: " + grantUri); 7181 return -1; 7182 } 7183 7184 final String authority = grantUri.uri.getAuthority(); 7185 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7186 if (pi == null) { 7187 Slog.w(TAG, "No content provider found for permission check: " + 7188 grantUri.uri.toSafeString()); 7189 return -1; 7190 } 7191 7192 int targetUid = lastTargetUid; 7193 if (targetUid < 0 && targetPkg != null) { 7194 try { 7195 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7196 if (targetUid < 0) { 7197 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7198 "Can't grant URI permission no uid for: " + targetPkg); 7199 return -1; 7200 } 7201 } catch (RemoteException ex) { 7202 return -1; 7203 } 7204 } 7205 7206 if (targetUid >= 0) { 7207 // First... does the target actually need this permission? 7208 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7209 // No need to grant the target this permission. 7210 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7211 "Target " + targetPkg + " already has full permission to " + grantUri); 7212 return -1; 7213 } 7214 } else { 7215 // First... there is no target package, so can anyone access it? 7216 boolean allowed = pi.exported; 7217 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7218 if (pi.readPermission != null) { 7219 allowed = false; 7220 } 7221 } 7222 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7223 if (pi.writePermission != null) { 7224 allowed = false; 7225 } 7226 } 7227 if (allowed) { 7228 return -1; 7229 } 7230 } 7231 7232 /* There is a special cross user grant if: 7233 * - The target is on another user. 7234 * - Apps on the current user can access the uri without any uid permissions. 7235 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7236 * grant uri permissions. 7237 */ 7238 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7239 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7240 modeFlags, false /*without considering the uid permissions*/); 7241 7242 // Second... is the provider allowing granting of URI permissions? 7243 if (!specialCrossUserGrant) { 7244 if (!pi.grantUriPermissions) { 7245 throw new SecurityException("Provider " + pi.packageName 7246 + "/" + pi.name 7247 + " does not allow granting of Uri permissions (uri " 7248 + grantUri + ")"); 7249 } 7250 if (pi.uriPermissionPatterns != null) { 7251 final int N = pi.uriPermissionPatterns.length; 7252 boolean allowed = false; 7253 for (int i=0; i<N; i++) { 7254 if (pi.uriPermissionPatterns[i] != null 7255 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7256 allowed = true; 7257 break; 7258 } 7259 } 7260 if (!allowed) { 7261 throw new SecurityException("Provider " + pi.packageName 7262 + "/" + pi.name 7263 + " does not allow granting of permission to path of Uri " 7264 + grantUri); 7265 } 7266 } 7267 } 7268 7269 // Third... does the caller itself have permission to access 7270 // this uri? 7271 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7272 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7273 // Require they hold a strong enough Uri permission 7274 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7275 throw new SecurityException("Uid " + callingUid 7276 + " does not have permission to uri " + grantUri); 7277 } 7278 } 7279 } 7280 return targetUid; 7281 } 7282 7283 /** 7284 * @param uri This uri must NOT contain an embedded userId. 7285 * @param userId The userId in which the uri is to be resolved. 7286 */ 7287 @Override 7288 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7289 final int modeFlags, int userId) { 7290 enforceNotIsolatedCaller("checkGrantUriPermission"); 7291 synchronized(this) { 7292 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7293 new GrantUri(userId, uri, false), modeFlags, -1); 7294 } 7295 } 7296 7297 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7298 final int modeFlags, UriPermissionOwner owner) { 7299 if (!Intent.isAccessUriMode(modeFlags)) { 7300 return; 7301 } 7302 7303 // So here we are: the caller has the assumed permission 7304 // to the uri, and the target doesn't. Let's now give this to 7305 // the target. 7306 7307 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7308 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7309 7310 final String authority = grantUri.uri.getAuthority(); 7311 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7312 if (pi == null) { 7313 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7314 return; 7315 } 7316 7317 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7318 grantUri.prefix = true; 7319 } 7320 final UriPermission perm = findOrCreateUriPermissionLocked( 7321 pi.packageName, targetPkg, targetUid, grantUri); 7322 perm.grantModes(modeFlags, owner); 7323 } 7324 7325 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7326 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7327 if (targetPkg == null) { 7328 throw new NullPointerException("targetPkg"); 7329 } 7330 int targetUid; 7331 final IPackageManager pm = AppGlobals.getPackageManager(); 7332 try { 7333 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7334 } catch (RemoteException ex) { 7335 return; 7336 } 7337 7338 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7339 targetUid); 7340 if (targetUid < 0) { 7341 return; 7342 } 7343 7344 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7345 owner); 7346 } 7347 7348 static class NeededUriGrants extends ArrayList<GrantUri> { 7349 final String targetPkg; 7350 final int targetUid; 7351 final int flags; 7352 7353 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7354 this.targetPkg = targetPkg; 7355 this.targetUid = targetUid; 7356 this.flags = flags; 7357 } 7358 } 7359 7360 /** 7361 * Like checkGrantUriPermissionLocked, but takes an Intent. 7362 */ 7363 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7364 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7365 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7366 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7367 + " clip=" + (intent != null ? intent.getClipData() : null) 7368 + " from " + intent + "; flags=0x" 7369 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7370 7371 if (targetPkg == null) { 7372 throw new NullPointerException("targetPkg"); 7373 } 7374 7375 if (intent == null) { 7376 return null; 7377 } 7378 Uri data = intent.getData(); 7379 ClipData clip = intent.getClipData(); 7380 if (data == null && clip == null) { 7381 return null; 7382 } 7383 // Default userId for uris in the intent (if they don't specify it themselves) 7384 int contentUserHint = intent.getContentUserHint(); 7385 if (contentUserHint == UserHandle.USER_CURRENT) { 7386 contentUserHint = UserHandle.getUserId(callingUid); 7387 } 7388 final IPackageManager pm = AppGlobals.getPackageManager(); 7389 int targetUid; 7390 if (needed != null) { 7391 targetUid = needed.targetUid; 7392 } else { 7393 try { 7394 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7395 } catch (RemoteException ex) { 7396 return null; 7397 } 7398 if (targetUid < 0) { 7399 if (DEBUG_URI_PERMISSION) { 7400 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7401 + " on user " + targetUserId); 7402 } 7403 return null; 7404 } 7405 } 7406 if (data != null) { 7407 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7408 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7409 targetUid); 7410 if (targetUid > 0) { 7411 if (needed == null) { 7412 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7413 } 7414 needed.add(grantUri); 7415 } 7416 } 7417 if (clip != null) { 7418 for (int i=0; i<clip.getItemCount(); i++) { 7419 Uri uri = clip.getItemAt(i).getUri(); 7420 if (uri != null) { 7421 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7422 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7423 targetUid); 7424 if (targetUid > 0) { 7425 if (needed == null) { 7426 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7427 } 7428 needed.add(grantUri); 7429 } 7430 } else { 7431 Intent clipIntent = clip.getItemAt(i).getIntent(); 7432 if (clipIntent != null) { 7433 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7434 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7435 if (newNeeded != null) { 7436 needed = newNeeded; 7437 } 7438 } 7439 } 7440 } 7441 } 7442 7443 return needed; 7444 } 7445 7446 /** 7447 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7448 */ 7449 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7450 UriPermissionOwner owner) { 7451 if (needed != null) { 7452 for (int i=0; i<needed.size(); i++) { 7453 GrantUri grantUri = needed.get(i); 7454 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7455 grantUri, needed.flags, owner); 7456 } 7457 } 7458 } 7459 7460 void grantUriPermissionFromIntentLocked(int callingUid, 7461 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7462 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7463 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7464 if (needed == null) { 7465 return; 7466 } 7467 7468 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7469 } 7470 7471 /** 7472 * @param uri This uri must NOT contain an embedded userId. 7473 * @param userId The userId in which the uri is to be resolved. 7474 */ 7475 @Override 7476 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7477 final int modeFlags, int userId) { 7478 enforceNotIsolatedCaller("grantUriPermission"); 7479 GrantUri grantUri = new GrantUri(userId, uri, false); 7480 synchronized(this) { 7481 final ProcessRecord r = getRecordForAppLocked(caller); 7482 if (r == null) { 7483 throw new SecurityException("Unable to find app for caller " 7484 + caller 7485 + " when granting permission to uri " + grantUri); 7486 } 7487 if (targetPkg == null) { 7488 throw new IllegalArgumentException("null target"); 7489 } 7490 if (grantUri == null) { 7491 throw new IllegalArgumentException("null uri"); 7492 } 7493 7494 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7495 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7496 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7497 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7498 7499 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7500 UserHandle.getUserId(r.uid)); 7501 } 7502 } 7503 7504 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7505 if (perm.modeFlags == 0) { 7506 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7507 perm.targetUid); 7508 if (perms != null) { 7509 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7510 "Removing " + perm.targetUid + " permission to " + perm.uri); 7511 7512 perms.remove(perm.uri); 7513 if (perms.isEmpty()) { 7514 mGrantedUriPermissions.remove(perm.targetUid); 7515 } 7516 } 7517 } 7518 } 7519 7520 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7521 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7522 7523 final IPackageManager pm = AppGlobals.getPackageManager(); 7524 final String authority = grantUri.uri.getAuthority(); 7525 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7526 if (pi == null) { 7527 Slog.w(TAG, "No content provider found for permission revoke: " 7528 + grantUri.toSafeString()); 7529 return; 7530 } 7531 7532 // Does the caller have this permission on the URI? 7533 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7534 // If they don't have direct access to the URI, then revoke any 7535 // ownerless URI permissions that have been granted to them. 7536 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7537 if (perms != null) { 7538 boolean persistChanged = false; 7539 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7540 final UriPermission perm = it.next(); 7541 if (perm.uri.sourceUserId == grantUri.sourceUserId 7542 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7543 if (DEBUG_URI_PERMISSION) 7544 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7545 " permission to " + perm.uri); 7546 persistChanged |= perm.revokeModes( 7547 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7548 if (perm.modeFlags == 0) { 7549 it.remove(); 7550 } 7551 } 7552 } 7553 if (perms.isEmpty()) { 7554 mGrantedUriPermissions.remove(callingUid); 7555 } 7556 if (persistChanged) { 7557 schedulePersistUriGrants(); 7558 } 7559 } 7560 return; 7561 } 7562 7563 boolean persistChanged = false; 7564 7565 // Go through all of the permissions and remove any that match. 7566 int N = mGrantedUriPermissions.size(); 7567 for (int i = 0; i < N; i++) { 7568 final int targetUid = mGrantedUriPermissions.keyAt(i); 7569 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7570 7571 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7572 final UriPermission perm = it.next(); 7573 if (perm.uri.sourceUserId == grantUri.sourceUserId 7574 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7575 if (DEBUG_URI_PERMISSION) 7576 Slog.v(TAG, 7577 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7578 persistChanged |= perm.revokeModes( 7579 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7580 if (perm.modeFlags == 0) { 7581 it.remove(); 7582 } 7583 } 7584 } 7585 7586 if (perms.isEmpty()) { 7587 mGrantedUriPermissions.remove(targetUid); 7588 N--; 7589 i--; 7590 } 7591 } 7592 7593 if (persistChanged) { 7594 schedulePersistUriGrants(); 7595 } 7596 } 7597 7598 /** 7599 * @param uri This uri must NOT contain an embedded userId. 7600 * @param userId The userId in which the uri is to be resolved. 7601 */ 7602 @Override 7603 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7604 int userId) { 7605 enforceNotIsolatedCaller("revokeUriPermission"); 7606 synchronized(this) { 7607 final ProcessRecord r = getRecordForAppLocked(caller); 7608 if (r == null) { 7609 throw new SecurityException("Unable to find app for caller " 7610 + caller 7611 + " when revoking permission to uri " + uri); 7612 } 7613 if (uri == null) { 7614 Slog.w(TAG, "revokeUriPermission: null uri"); 7615 return; 7616 } 7617 7618 if (!Intent.isAccessUriMode(modeFlags)) { 7619 return; 7620 } 7621 7622 final IPackageManager pm = AppGlobals.getPackageManager(); 7623 final String authority = uri.getAuthority(); 7624 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7625 if (pi == null) { 7626 Slog.w(TAG, "No content provider found for permission revoke: " 7627 + uri.toSafeString()); 7628 return; 7629 } 7630 7631 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7632 } 7633 } 7634 7635 /** 7636 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7637 * given package. 7638 * 7639 * @param packageName Package name to match, or {@code null} to apply to all 7640 * packages. 7641 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7642 * to all users. 7643 * @param persistable If persistable grants should be removed. 7644 */ 7645 private void removeUriPermissionsForPackageLocked( 7646 String packageName, int userHandle, boolean persistable) { 7647 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7648 throw new IllegalArgumentException("Must narrow by either package or user"); 7649 } 7650 7651 boolean persistChanged = false; 7652 7653 int N = mGrantedUriPermissions.size(); 7654 for (int i = 0; i < N; i++) { 7655 final int targetUid = mGrantedUriPermissions.keyAt(i); 7656 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7657 7658 // Only inspect grants matching user 7659 if (userHandle == UserHandle.USER_ALL 7660 || userHandle == UserHandle.getUserId(targetUid)) { 7661 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7662 final UriPermission perm = it.next(); 7663 7664 // Only inspect grants matching package 7665 if (packageName == null || perm.sourcePkg.equals(packageName) 7666 || perm.targetPkg.equals(packageName)) { 7667 persistChanged |= perm.revokeModes(persistable 7668 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7669 7670 // Only remove when no modes remain; any persisted grants 7671 // will keep this alive. 7672 if (perm.modeFlags == 0) { 7673 it.remove(); 7674 } 7675 } 7676 } 7677 7678 if (perms.isEmpty()) { 7679 mGrantedUriPermissions.remove(targetUid); 7680 N--; 7681 i--; 7682 } 7683 } 7684 } 7685 7686 if (persistChanged) { 7687 schedulePersistUriGrants(); 7688 } 7689 } 7690 7691 @Override 7692 public IBinder newUriPermissionOwner(String name) { 7693 enforceNotIsolatedCaller("newUriPermissionOwner"); 7694 synchronized(this) { 7695 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7696 return owner.getExternalTokenLocked(); 7697 } 7698 } 7699 7700 /** 7701 * @param uri This uri must NOT contain an embedded userId. 7702 * @param sourceUserId The userId in which the uri is to be resolved. 7703 * @param targetUserId The userId of the app that receives the grant. 7704 */ 7705 @Override 7706 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7707 final int modeFlags, int sourceUserId, int targetUserId) { 7708 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7709 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7710 synchronized(this) { 7711 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7712 if (owner == null) { 7713 throw new IllegalArgumentException("Unknown owner: " + token); 7714 } 7715 if (fromUid != Binder.getCallingUid()) { 7716 if (Binder.getCallingUid() != Process.myUid()) { 7717 // Only system code can grant URI permissions on behalf 7718 // of other users. 7719 throw new SecurityException("nice try"); 7720 } 7721 } 7722 if (targetPkg == null) { 7723 throw new IllegalArgumentException("null target"); 7724 } 7725 if (uri == null) { 7726 throw new IllegalArgumentException("null uri"); 7727 } 7728 7729 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7730 modeFlags, owner, targetUserId); 7731 } 7732 } 7733 7734 /** 7735 * @param uri This uri must NOT contain an embedded userId. 7736 * @param userId The userId in which the uri is to be resolved. 7737 */ 7738 @Override 7739 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7740 synchronized(this) { 7741 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7742 if (owner == null) { 7743 throw new IllegalArgumentException("Unknown owner: " + token); 7744 } 7745 7746 if (uri == null) { 7747 owner.removeUriPermissionsLocked(mode); 7748 } else { 7749 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7750 } 7751 } 7752 } 7753 7754 private void schedulePersistUriGrants() { 7755 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7756 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7757 10 * DateUtils.SECOND_IN_MILLIS); 7758 } 7759 } 7760 7761 private void writeGrantedUriPermissions() { 7762 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7763 7764 // Snapshot permissions so we can persist without lock 7765 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7766 synchronized (this) { 7767 final int size = mGrantedUriPermissions.size(); 7768 for (int i = 0; i < size; i++) { 7769 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7770 for (UriPermission perm : perms.values()) { 7771 if (perm.persistedModeFlags != 0) { 7772 persist.add(perm.snapshot()); 7773 } 7774 } 7775 } 7776 } 7777 7778 FileOutputStream fos = null; 7779 try { 7780 fos = mGrantFile.startWrite(); 7781 7782 XmlSerializer out = new FastXmlSerializer(); 7783 out.setOutput(fos, "utf-8"); 7784 out.startDocument(null, true); 7785 out.startTag(null, TAG_URI_GRANTS); 7786 for (UriPermission.Snapshot perm : persist) { 7787 out.startTag(null, TAG_URI_GRANT); 7788 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7789 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7790 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7791 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7792 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7793 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7794 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7795 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7796 out.endTag(null, TAG_URI_GRANT); 7797 } 7798 out.endTag(null, TAG_URI_GRANTS); 7799 out.endDocument(); 7800 7801 mGrantFile.finishWrite(fos); 7802 } catch (IOException e) { 7803 if (fos != null) { 7804 mGrantFile.failWrite(fos); 7805 } 7806 } 7807 } 7808 7809 private void readGrantedUriPermissionsLocked() { 7810 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7811 7812 final long now = System.currentTimeMillis(); 7813 7814 FileInputStream fis = null; 7815 try { 7816 fis = mGrantFile.openRead(); 7817 final XmlPullParser in = Xml.newPullParser(); 7818 in.setInput(fis, null); 7819 7820 int type; 7821 while ((type = in.next()) != END_DOCUMENT) { 7822 final String tag = in.getName(); 7823 if (type == START_TAG) { 7824 if (TAG_URI_GRANT.equals(tag)) { 7825 final int sourceUserId; 7826 final int targetUserId; 7827 final int userHandle = readIntAttribute(in, 7828 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7829 if (userHandle != UserHandle.USER_NULL) { 7830 // For backwards compatibility. 7831 sourceUserId = userHandle; 7832 targetUserId = userHandle; 7833 } else { 7834 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7835 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7836 } 7837 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7838 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7839 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7840 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7841 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7842 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7843 7844 // Sanity check that provider still belongs to source package 7845 final ProviderInfo pi = getProviderInfoLocked( 7846 uri.getAuthority(), sourceUserId); 7847 if (pi != null && sourcePkg.equals(pi.packageName)) { 7848 int targetUid = -1; 7849 try { 7850 targetUid = AppGlobals.getPackageManager() 7851 .getPackageUid(targetPkg, targetUserId); 7852 } catch (RemoteException e) { 7853 } 7854 if (targetUid != -1) { 7855 final UriPermission perm = findOrCreateUriPermissionLocked( 7856 sourcePkg, targetPkg, targetUid, 7857 new GrantUri(sourceUserId, uri, prefix)); 7858 perm.initPersistedModes(modeFlags, createdTime); 7859 } 7860 } else { 7861 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7862 + " but instead found " + pi); 7863 } 7864 } 7865 } 7866 } 7867 } catch (FileNotFoundException e) { 7868 // Missing grants is okay 7869 } catch (IOException e) { 7870 Log.wtf(TAG, "Failed reading Uri grants", e); 7871 } catch (XmlPullParserException e) { 7872 Log.wtf(TAG, "Failed reading Uri grants", e); 7873 } finally { 7874 IoUtils.closeQuietly(fis); 7875 } 7876 } 7877 7878 /** 7879 * @param uri This uri must NOT contain an embedded userId. 7880 * @param userId The userId in which the uri is to be resolved. 7881 */ 7882 @Override 7883 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7884 enforceNotIsolatedCaller("takePersistableUriPermission"); 7885 7886 Preconditions.checkFlagsArgument(modeFlags, 7887 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7888 7889 synchronized (this) { 7890 final int callingUid = Binder.getCallingUid(); 7891 boolean persistChanged = false; 7892 GrantUri grantUri = new GrantUri(userId, uri, false); 7893 7894 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7895 new GrantUri(userId, uri, false)); 7896 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7897 new GrantUri(userId, uri, true)); 7898 7899 final boolean exactValid = (exactPerm != null) 7900 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7901 final boolean prefixValid = (prefixPerm != null) 7902 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7903 7904 if (!(exactValid || prefixValid)) { 7905 throw new SecurityException("No persistable permission grants found for UID " 7906 + callingUid + " and Uri " + grantUri.toSafeString()); 7907 } 7908 7909 if (exactValid) { 7910 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7911 } 7912 if (prefixValid) { 7913 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7914 } 7915 7916 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7917 7918 if (persistChanged) { 7919 schedulePersistUriGrants(); 7920 } 7921 } 7922 } 7923 7924 /** 7925 * @param uri This uri must NOT contain an embedded userId. 7926 * @param userId The userId in which the uri is to be resolved. 7927 */ 7928 @Override 7929 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7930 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7931 7932 Preconditions.checkFlagsArgument(modeFlags, 7933 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7934 7935 synchronized (this) { 7936 final int callingUid = Binder.getCallingUid(); 7937 boolean persistChanged = false; 7938 7939 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7940 new GrantUri(userId, uri, false)); 7941 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7942 new GrantUri(userId, uri, true)); 7943 if (exactPerm == null && prefixPerm == null) { 7944 throw new SecurityException("No permission grants found for UID " + callingUid 7945 + " and Uri " + uri.toSafeString()); 7946 } 7947 7948 if (exactPerm != null) { 7949 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7950 removeUriPermissionIfNeededLocked(exactPerm); 7951 } 7952 if (prefixPerm != null) { 7953 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7954 removeUriPermissionIfNeededLocked(prefixPerm); 7955 } 7956 7957 if (persistChanged) { 7958 schedulePersistUriGrants(); 7959 } 7960 } 7961 } 7962 7963 /** 7964 * Prune any older {@link UriPermission} for the given UID until outstanding 7965 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7966 * 7967 * @return if any mutations occured that require persisting. 7968 */ 7969 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7970 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7971 if (perms == null) return false; 7972 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7973 7974 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7975 for (UriPermission perm : perms.values()) { 7976 if (perm.persistedModeFlags != 0) { 7977 persisted.add(perm); 7978 } 7979 } 7980 7981 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7982 if (trimCount <= 0) return false; 7983 7984 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7985 for (int i = 0; i < trimCount; i++) { 7986 final UriPermission perm = persisted.get(i); 7987 7988 if (DEBUG_URI_PERMISSION) { 7989 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7990 } 7991 7992 perm.releasePersistableModes(~0); 7993 removeUriPermissionIfNeededLocked(perm); 7994 } 7995 7996 return true; 7997 } 7998 7999 @Override 8000 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 8001 String packageName, boolean incoming) { 8002 enforceNotIsolatedCaller("getPersistedUriPermissions"); 8003 Preconditions.checkNotNull(packageName, "packageName"); 8004 8005 final int callingUid = Binder.getCallingUid(); 8006 final IPackageManager pm = AppGlobals.getPackageManager(); 8007 try { 8008 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8009 if (packageUid != callingUid) { 8010 throw new SecurityException( 8011 "Package " + packageName + " does not belong to calling UID " + callingUid); 8012 } 8013 } catch (RemoteException e) { 8014 throw new SecurityException("Failed to verify package name ownership"); 8015 } 8016 8017 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8018 synchronized (this) { 8019 if (incoming) { 8020 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8021 callingUid); 8022 if (perms == null) { 8023 Slog.w(TAG, "No permission grants found for " + packageName); 8024 } else { 8025 for (UriPermission perm : perms.values()) { 8026 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8027 result.add(perm.buildPersistedPublicApiObject()); 8028 } 8029 } 8030 } 8031 } else { 8032 final int size = mGrantedUriPermissions.size(); 8033 for (int i = 0; i < size; i++) { 8034 final ArrayMap<GrantUri, UriPermission> perms = 8035 mGrantedUriPermissions.valueAt(i); 8036 for (UriPermission perm : perms.values()) { 8037 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8038 result.add(perm.buildPersistedPublicApiObject()); 8039 } 8040 } 8041 } 8042 } 8043 } 8044 return new ParceledListSlice<android.content.UriPermission>(result); 8045 } 8046 8047 @Override 8048 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8049 synchronized (this) { 8050 ProcessRecord app = 8051 who != null ? getRecordForAppLocked(who) : null; 8052 if (app == null) return; 8053 8054 Message msg = Message.obtain(); 8055 msg.what = WAIT_FOR_DEBUGGER_MSG; 8056 msg.obj = app; 8057 msg.arg1 = waiting ? 1 : 0; 8058 mHandler.sendMessage(msg); 8059 } 8060 } 8061 8062 @Override 8063 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8064 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8065 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8066 outInfo.availMem = Process.getFreeMemory(); 8067 outInfo.totalMem = Process.getTotalMemory(); 8068 outInfo.threshold = homeAppMem; 8069 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8070 outInfo.hiddenAppThreshold = cachedAppMem; 8071 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8072 ProcessList.SERVICE_ADJ); 8073 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8074 ProcessList.VISIBLE_APP_ADJ); 8075 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8076 ProcessList.FOREGROUND_APP_ADJ); 8077 } 8078 8079 // ========================================================= 8080 // TASK MANAGEMENT 8081 // ========================================================= 8082 8083 @Override 8084 public List<IAppTask> getAppTasks(String callingPackage) { 8085 int callingUid = Binder.getCallingUid(); 8086 long ident = Binder.clearCallingIdentity(); 8087 8088 synchronized(this) { 8089 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8090 try { 8091 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8092 8093 final int N = mRecentTasks.size(); 8094 for (int i = 0; i < N; i++) { 8095 TaskRecord tr = mRecentTasks.get(i); 8096 // Skip tasks that do not match the caller. We don't need to verify 8097 // callingPackage, because we are also limiting to callingUid and know 8098 // that will limit to the correct security sandbox. 8099 if (tr.effectiveUid != callingUid) { 8100 continue; 8101 } 8102 Intent intent = tr.getBaseIntent(); 8103 if (intent == null || 8104 !callingPackage.equals(intent.getComponent().getPackageName())) { 8105 continue; 8106 } 8107 ActivityManager.RecentTaskInfo taskInfo = 8108 createRecentTaskInfoFromTaskRecord(tr); 8109 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8110 list.add(taskImpl); 8111 } 8112 } finally { 8113 Binder.restoreCallingIdentity(ident); 8114 } 8115 return list; 8116 } 8117 } 8118 8119 @Override 8120 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8121 final int callingUid = Binder.getCallingUid(); 8122 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8123 8124 synchronized(this) { 8125 if (localLOGV) Slog.v( 8126 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8127 8128 final boolean allowed = checkCallingPermission( 8129 android.Manifest.permission.GET_TASKS) 8130 == PackageManager.PERMISSION_GRANTED; 8131 if (!allowed) { 8132 Slog.w(TAG, "getTasks: caller " + callingUid 8133 + " does not hold GET_TASKS; limiting output"); 8134 } 8135 8136 // TODO: Improve with MRU list from all ActivityStacks. 8137 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8138 } 8139 8140 return list; 8141 } 8142 8143 TaskRecord getMostRecentTask() { 8144 return mRecentTasks.get(0); 8145 } 8146 8147 /** 8148 * Creates a new RecentTaskInfo from a TaskRecord. 8149 */ 8150 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8151 // Update the task description to reflect any changes in the task stack 8152 tr.updateTaskDescription(); 8153 8154 // Compose the recent task info 8155 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8156 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8157 rti.persistentId = tr.taskId; 8158 rti.baseIntent = new Intent(tr.getBaseIntent()); 8159 rti.origActivity = tr.origActivity; 8160 rti.description = tr.lastDescription; 8161 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8162 rti.userId = tr.userId; 8163 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8164 rti.firstActiveTime = tr.firstActiveTime; 8165 rti.lastActiveTime = tr.lastActiveTime; 8166 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8167 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8168 return rti; 8169 } 8170 8171 @Override 8172 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8173 final int callingUid = Binder.getCallingUid(); 8174 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8175 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8176 8177 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8178 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8179 synchronized (this) { 8180 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8181 == PackageManager.PERMISSION_GRANTED; 8182 if (!allowed) { 8183 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8184 + " does not hold GET_TASKS; limiting output"); 8185 } 8186 final boolean detailed = checkCallingPermission( 8187 android.Manifest.permission.GET_DETAILED_TASKS) 8188 == PackageManager.PERMISSION_GRANTED; 8189 8190 final int N = mRecentTasks.size(); 8191 ArrayList<ActivityManager.RecentTaskInfo> res 8192 = new ArrayList<ActivityManager.RecentTaskInfo>( 8193 maxNum < N ? maxNum : N); 8194 8195 final Set<Integer> includedUsers; 8196 if (includeProfiles) { 8197 includedUsers = getProfileIdsLocked(userId); 8198 } else { 8199 includedUsers = new HashSet<Integer>(); 8200 } 8201 includedUsers.add(Integer.valueOf(userId)); 8202 8203 for (int i=0; i<N && maxNum > 0; i++) { 8204 TaskRecord tr = mRecentTasks.get(i); 8205 // Only add calling user or related users recent tasks 8206 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8207 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8208 continue; 8209 } 8210 8211 // Return the entry if desired by the caller. We always return 8212 // the first entry, because callers always expect this to be the 8213 // foreground app. We may filter others if the caller has 8214 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8215 // we should exclude the entry. 8216 8217 if (i == 0 8218 || withExcluded 8219 || (tr.intent == null) 8220 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8221 == 0)) { 8222 if (!allowed) { 8223 // If the caller doesn't have the GET_TASKS permission, then only 8224 // allow them to see a small subset of tasks -- their own and home. 8225 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8226 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8227 continue; 8228 } 8229 } 8230 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8231 if (tr.stack != null && tr.stack.isHomeStack()) { 8232 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8233 continue; 8234 } 8235 } 8236 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8237 // Don't include auto remove tasks that are finished or finishing. 8238 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8239 + tr); 8240 continue; 8241 } 8242 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8243 && !tr.isAvailable) { 8244 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8245 continue; 8246 } 8247 8248 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8249 if (!detailed) { 8250 rti.baseIntent.replaceExtras((Bundle)null); 8251 } 8252 8253 res.add(rti); 8254 maxNum--; 8255 } 8256 } 8257 return res; 8258 } 8259 } 8260 8261 private TaskRecord recentTaskForIdLocked(int id) { 8262 final int N = mRecentTasks.size(); 8263 for (int i=0; i<N; i++) { 8264 TaskRecord tr = mRecentTasks.get(i); 8265 if (tr.taskId == id) { 8266 return tr; 8267 } 8268 } 8269 return null; 8270 } 8271 8272 @Override 8273 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8274 synchronized (this) { 8275 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8276 "getTaskThumbnail()"); 8277 TaskRecord tr = recentTaskForIdLocked(id); 8278 if (tr != null) { 8279 return tr.getTaskThumbnailLocked(); 8280 } 8281 } 8282 return null; 8283 } 8284 8285 @Override 8286 public int addAppTask(IBinder activityToken, Intent intent, 8287 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8288 final int callingUid = Binder.getCallingUid(); 8289 final long callingIdent = Binder.clearCallingIdentity(); 8290 8291 try { 8292 synchronized (this) { 8293 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8294 if (r == null) { 8295 throw new IllegalArgumentException("Activity does not exist; token=" 8296 + activityToken); 8297 } 8298 ComponentName comp = intent.getComponent(); 8299 if (comp == null) { 8300 throw new IllegalArgumentException("Intent " + intent 8301 + " must specify explicit component"); 8302 } 8303 if (thumbnail.getWidth() != mThumbnailWidth 8304 || thumbnail.getHeight() != mThumbnailHeight) { 8305 throw new IllegalArgumentException("Bad thumbnail size: got " 8306 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8307 + mThumbnailWidth + "x" + mThumbnailHeight); 8308 } 8309 if (intent.getSelector() != null) { 8310 intent.setSelector(null); 8311 } 8312 if (intent.getSourceBounds() != null) { 8313 intent.setSourceBounds(null); 8314 } 8315 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8316 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8317 // The caller has added this as an auto-remove task... that makes no 8318 // sense, so turn off auto-remove. 8319 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8320 } 8321 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8322 // Must be a new task. 8323 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8324 } 8325 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8326 mLastAddedTaskActivity = null; 8327 } 8328 ActivityInfo ainfo = mLastAddedTaskActivity; 8329 if (ainfo == null) { 8330 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8331 comp, 0, UserHandle.getUserId(callingUid)); 8332 if (ainfo.applicationInfo.uid != callingUid) { 8333 throw new SecurityException( 8334 "Can't add task for another application: target uid=" 8335 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8336 } 8337 } 8338 8339 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8340 intent, description); 8341 8342 int trimIdx = trimRecentsForTask(task, false); 8343 if (trimIdx >= 0) { 8344 // If this would have caused a trim, then we'll abort because that 8345 // means it would be added at the end of the list but then just removed. 8346 return -1; 8347 } 8348 8349 final int N = mRecentTasks.size(); 8350 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8351 final TaskRecord tr = mRecentTasks.remove(N - 1); 8352 tr.removedFromRecents(mTaskPersister); 8353 } 8354 8355 task.inRecents = true; 8356 mRecentTasks.add(task); 8357 r.task.stack.addTask(task, false, false); 8358 8359 task.setLastThumbnail(thumbnail); 8360 task.freeLastThumbnail(); 8361 8362 return task.taskId; 8363 } 8364 } finally { 8365 Binder.restoreCallingIdentity(callingIdent); 8366 } 8367 } 8368 8369 @Override 8370 public Point getAppTaskThumbnailSize() { 8371 synchronized (this) { 8372 return new Point(mThumbnailWidth, mThumbnailHeight); 8373 } 8374 } 8375 8376 @Override 8377 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8378 synchronized (this) { 8379 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8380 if (r != null) { 8381 r.setTaskDescription(td); 8382 r.task.updateTaskDescription(); 8383 } 8384 } 8385 } 8386 8387 @Override 8388 public Bitmap getTaskDescriptionIcon(String filename) { 8389 if (!FileUtils.isValidExtFilename(filename) 8390 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 8391 throw new IllegalArgumentException("Bad filename: " + filename); 8392 } 8393 return mTaskPersister.getTaskDescriptionIcon(filename); 8394 } 8395 8396 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8397 mRecentTasks.remove(tr); 8398 tr.removedFromRecents(mTaskPersister); 8399 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8400 Intent baseIntent = new Intent( 8401 tr.intent != null ? tr.intent : tr.affinityIntent); 8402 ComponentName component = baseIntent.getComponent(); 8403 if (component == null) { 8404 Slog.w(TAG, "Now component for base intent of task: " + tr); 8405 return; 8406 } 8407 8408 // Find any running services associated with this app. 8409 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8410 8411 if (killProcesses) { 8412 // Find any running processes associated with this app. 8413 final String pkg = component.getPackageName(); 8414 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8415 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8416 for (int i=0; i<pmap.size(); i++) { 8417 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8418 for (int j=0; j<uids.size(); j++) { 8419 ProcessRecord proc = uids.valueAt(j); 8420 if (proc.userId != tr.userId) { 8421 continue; 8422 } 8423 if (!proc.pkgList.containsKey(pkg)) { 8424 continue; 8425 } 8426 procs.add(proc); 8427 } 8428 } 8429 8430 // Kill the running processes. 8431 for (int i=0; i<procs.size(); i++) { 8432 ProcessRecord pr = procs.get(i); 8433 if (pr == mHomeProcess) { 8434 // Don't kill the home process along with tasks from the same package. 8435 continue; 8436 } 8437 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8438 pr.kill("remove task", true); 8439 } else { 8440 pr.waitingToKill = "remove task"; 8441 } 8442 } 8443 } 8444 } 8445 8446 /** 8447 * Removes the task with the specified task id. 8448 * 8449 * @param taskId Identifier of the task to be removed. 8450 * @param flags Additional operational flags. May be 0 or 8451 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8452 * @return Returns true if the given task was found and removed. 8453 */ 8454 private boolean removeTaskByIdLocked(int taskId, int flags) { 8455 TaskRecord tr = recentTaskForIdLocked(taskId); 8456 if (tr != null) { 8457 tr.removeTaskActivitiesLocked(); 8458 cleanUpRemovedTaskLocked(tr, flags); 8459 if (tr.isPersistable) { 8460 notifyTaskPersisterLocked(null, true); 8461 } 8462 return true; 8463 } 8464 return false; 8465 } 8466 8467 @Override 8468 public boolean removeTask(int taskId, int flags) { 8469 synchronized (this) { 8470 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8471 "removeTask()"); 8472 long ident = Binder.clearCallingIdentity(); 8473 try { 8474 return removeTaskByIdLocked(taskId, flags); 8475 } finally { 8476 Binder.restoreCallingIdentity(ident); 8477 } 8478 } 8479 } 8480 8481 /** 8482 * TODO: Add mController hook 8483 */ 8484 @Override 8485 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8486 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8487 "moveTaskToFront()"); 8488 8489 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8490 synchronized(this) { 8491 moveTaskToFrontLocked(taskId, flags, options); 8492 } 8493 } 8494 8495 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8496 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8497 Binder.getCallingUid(), -1, -1, "Task to front")) { 8498 ActivityOptions.abort(options); 8499 return; 8500 } 8501 final long origId = Binder.clearCallingIdentity(); 8502 try { 8503 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8504 if (task == null) { 8505 return; 8506 } 8507 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8508 mStackSupervisor.showLockTaskToast(); 8509 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8510 return; 8511 } 8512 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8513 if (prev != null && prev.isRecentsActivity()) { 8514 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8515 } 8516 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8517 } finally { 8518 Binder.restoreCallingIdentity(origId); 8519 } 8520 ActivityOptions.abort(options); 8521 } 8522 8523 @Override 8524 public void moveTaskToBack(int taskId) { 8525 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8526 "moveTaskToBack()"); 8527 8528 synchronized(this) { 8529 TaskRecord tr = recentTaskForIdLocked(taskId); 8530 if (tr != null) { 8531 if (tr == mStackSupervisor.mLockTaskModeTask) { 8532 mStackSupervisor.showLockTaskToast(); 8533 return; 8534 } 8535 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8536 ActivityStack stack = tr.stack; 8537 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8538 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8539 Binder.getCallingUid(), -1, -1, "Task to back")) { 8540 return; 8541 } 8542 } 8543 final long origId = Binder.clearCallingIdentity(); 8544 try { 8545 stack.moveTaskToBackLocked(taskId, null); 8546 } finally { 8547 Binder.restoreCallingIdentity(origId); 8548 } 8549 } 8550 } 8551 } 8552 8553 /** 8554 * Moves an activity, and all of the other activities within the same task, to the bottom 8555 * of the history stack. The activity's order within the task is unchanged. 8556 * 8557 * @param token A reference to the activity we wish to move 8558 * @param nonRoot If false then this only works if the activity is the root 8559 * of a task; if true it will work for any activity in a task. 8560 * @return Returns true if the move completed, false if not. 8561 */ 8562 @Override 8563 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8564 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8565 synchronized(this) { 8566 final long origId = Binder.clearCallingIdentity(); 8567 try { 8568 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8569 if (taskId >= 0) { 8570 if ((mStackSupervisor.mLockTaskModeTask != null) 8571 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8572 mStackSupervisor.showLockTaskToast(); 8573 return false; 8574 } 8575 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8576 } 8577 } finally { 8578 Binder.restoreCallingIdentity(origId); 8579 } 8580 } 8581 return false; 8582 } 8583 8584 @Override 8585 public void moveTaskBackwards(int task) { 8586 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8587 "moveTaskBackwards()"); 8588 8589 synchronized(this) { 8590 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8591 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8592 return; 8593 } 8594 final long origId = Binder.clearCallingIdentity(); 8595 moveTaskBackwardsLocked(task); 8596 Binder.restoreCallingIdentity(origId); 8597 } 8598 } 8599 8600 private final void moveTaskBackwardsLocked(int task) { 8601 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8602 } 8603 8604 @Override 8605 public IBinder getHomeActivityToken() throws RemoteException { 8606 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8607 "getHomeActivityToken()"); 8608 synchronized (this) { 8609 return mStackSupervisor.getHomeActivityToken(); 8610 } 8611 } 8612 8613 @Override 8614 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8615 IActivityContainerCallback callback) throws RemoteException { 8616 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8617 "createActivityContainer()"); 8618 synchronized (this) { 8619 if (parentActivityToken == null) { 8620 throw new IllegalArgumentException("parent token must not be null"); 8621 } 8622 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8623 if (r == null) { 8624 return null; 8625 } 8626 if (callback == null) { 8627 throw new IllegalArgumentException("callback must not be null"); 8628 } 8629 return mStackSupervisor.createActivityContainer(r, callback); 8630 } 8631 } 8632 8633 @Override 8634 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8635 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8636 "deleteActivityContainer()"); 8637 synchronized (this) { 8638 mStackSupervisor.deleteActivityContainer(container); 8639 } 8640 } 8641 8642 @Override 8643 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8644 throws RemoteException { 8645 synchronized (this) { 8646 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8647 if (stack != null) { 8648 return stack.mActivityContainer; 8649 } 8650 return null; 8651 } 8652 } 8653 8654 @Override 8655 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8656 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8657 "moveTaskToStack()"); 8658 if (stackId == HOME_STACK_ID) { 8659 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8660 new RuntimeException("here").fillInStackTrace()); 8661 } 8662 synchronized (this) { 8663 long ident = Binder.clearCallingIdentity(); 8664 try { 8665 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8666 + stackId + " toTop=" + toTop); 8667 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8668 } finally { 8669 Binder.restoreCallingIdentity(ident); 8670 } 8671 } 8672 } 8673 8674 @Override 8675 public void resizeStack(int stackBoxId, Rect bounds) { 8676 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8677 "resizeStackBox()"); 8678 long ident = Binder.clearCallingIdentity(); 8679 try { 8680 mWindowManager.resizeStack(stackBoxId, bounds); 8681 } finally { 8682 Binder.restoreCallingIdentity(ident); 8683 } 8684 } 8685 8686 @Override 8687 public List<StackInfo> getAllStackInfos() { 8688 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8689 "getAllStackInfos()"); 8690 long ident = Binder.clearCallingIdentity(); 8691 try { 8692 synchronized (this) { 8693 return mStackSupervisor.getAllStackInfosLocked(); 8694 } 8695 } finally { 8696 Binder.restoreCallingIdentity(ident); 8697 } 8698 } 8699 8700 @Override 8701 public StackInfo getStackInfo(int stackId) { 8702 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8703 "getStackInfo()"); 8704 long ident = Binder.clearCallingIdentity(); 8705 try { 8706 synchronized (this) { 8707 return mStackSupervisor.getStackInfoLocked(stackId); 8708 } 8709 } finally { 8710 Binder.restoreCallingIdentity(ident); 8711 } 8712 } 8713 8714 @Override 8715 public boolean isInHomeStack(int taskId) { 8716 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8717 "getStackInfo()"); 8718 long ident = Binder.clearCallingIdentity(); 8719 try { 8720 synchronized (this) { 8721 TaskRecord tr = recentTaskForIdLocked(taskId); 8722 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8723 } 8724 } finally { 8725 Binder.restoreCallingIdentity(ident); 8726 } 8727 } 8728 8729 @Override 8730 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8731 synchronized(this) { 8732 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8733 } 8734 } 8735 8736 private boolean isLockTaskAuthorized(String pkg) { 8737 final DevicePolicyManager dpm = (DevicePolicyManager) 8738 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8739 try { 8740 int uid = mContext.getPackageManager().getPackageUid(pkg, 8741 Binder.getCallingUserHandle().getIdentifier()); 8742 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8743 } catch (NameNotFoundException e) { 8744 return false; 8745 } 8746 } 8747 8748 void startLockTaskMode(TaskRecord task) { 8749 final String pkg; 8750 synchronized (this) { 8751 pkg = task.intent.getComponent().getPackageName(); 8752 } 8753 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8754 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8755 final TaskRecord taskRecord = task; 8756 mHandler.post(new Runnable() { 8757 @Override 8758 public void run() { 8759 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8760 } 8761 }); 8762 return; 8763 } 8764 long ident = Binder.clearCallingIdentity(); 8765 try { 8766 synchronized (this) { 8767 // Since we lost lock on task, make sure it is still there. 8768 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8769 if (task != null) { 8770 if (!isSystemInitiated 8771 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8772 throw new IllegalArgumentException("Invalid task, not in foreground"); 8773 } 8774 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8775 } 8776 } 8777 } finally { 8778 Binder.restoreCallingIdentity(ident); 8779 } 8780 } 8781 8782 @Override 8783 public void startLockTaskMode(int taskId) { 8784 final TaskRecord task; 8785 long ident = Binder.clearCallingIdentity(); 8786 try { 8787 synchronized (this) { 8788 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8789 } 8790 } finally { 8791 Binder.restoreCallingIdentity(ident); 8792 } 8793 if (task != null) { 8794 startLockTaskMode(task); 8795 } 8796 } 8797 8798 @Override 8799 public void startLockTaskMode(IBinder token) { 8800 final TaskRecord task; 8801 long ident = Binder.clearCallingIdentity(); 8802 try { 8803 synchronized (this) { 8804 final ActivityRecord r = ActivityRecord.forToken(token); 8805 if (r == null) { 8806 return; 8807 } 8808 task = r.task; 8809 } 8810 } finally { 8811 Binder.restoreCallingIdentity(ident); 8812 } 8813 if (task != null) { 8814 startLockTaskMode(task); 8815 } 8816 } 8817 8818 @Override 8819 public void startLockTaskModeOnCurrent() throws RemoteException { 8820 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8821 "startLockTaskModeOnCurrent"); 8822 ActivityRecord r = null; 8823 synchronized (this) { 8824 r = mStackSupervisor.topRunningActivityLocked(); 8825 } 8826 startLockTaskMode(r.task); 8827 } 8828 8829 @Override 8830 public void stopLockTaskMode() { 8831 // Verify that the user matches the package of the intent for the TaskRecord 8832 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8833 // and stopLockTaskMode. 8834 final int callingUid = Binder.getCallingUid(); 8835 if (callingUid != Process.SYSTEM_UID) { 8836 try { 8837 String pkg = 8838 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8839 int uid = mContext.getPackageManager().getPackageUid(pkg, 8840 Binder.getCallingUserHandle().getIdentifier()); 8841 if (uid != callingUid) { 8842 throw new SecurityException("Invalid uid, expected " + uid); 8843 } 8844 } catch (NameNotFoundException e) { 8845 Log.d(TAG, "stopLockTaskMode " + e); 8846 return; 8847 } 8848 } 8849 long ident = Binder.clearCallingIdentity(); 8850 try { 8851 Log.d(TAG, "stopLockTaskMode"); 8852 // Stop lock task 8853 synchronized (this) { 8854 mStackSupervisor.setLockTaskModeLocked(null, false); 8855 } 8856 } finally { 8857 Binder.restoreCallingIdentity(ident); 8858 } 8859 } 8860 8861 @Override 8862 public void stopLockTaskModeOnCurrent() throws RemoteException { 8863 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8864 "stopLockTaskModeOnCurrent"); 8865 long ident = Binder.clearCallingIdentity(); 8866 try { 8867 stopLockTaskMode(); 8868 } finally { 8869 Binder.restoreCallingIdentity(ident); 8870 } 8871 } 8872 8873 @Override 8874 public boolean isInLockTaskMode() { 8875 synchronized (this) { 8876 return mStackSupervisor.isInLockTaskMode(); 8877 } 8878 } 8879 8880 // ========================================================= 8881 // CONTENT PROVIDERS 8882 // ========================================================= 8883 8884 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8885 List<ProviderInfo> providers = null; 8886 try { 8887 providers = AppGlobals.getPackageManager(). 8888 queryContentProviders(app.processName, app.uid, 8889 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8890 } catch (RemoteException ex) { 8891 } 8892 if (DEBUG_MU) 8893 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8894 int userId = app.userId; 8895 if (providers != null) { 8896 int N = providers.size(); 8897 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8898 for (int i=0; i<N; i++) { 8899 ProviderInfo cpi = 8900 (ProviderInfo)providers.get(i); 8901 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8902 cpi.name, cpi.flags); 8903 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8904 // This is a singleton provider, but a user besides the 8905 // default user is asking to initialize a process it runs 8906 // in... well, no, it doesn't actually run in this process, 8907 // it runs in the process of the default user. Get rid of it. 8908 providers.remove(i); 8909 N--; 8910 i--; 8911 continue; 8912 } 8913 8914 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8915 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8916 if (cpr == null) { 8917 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8918 mProviderMap.putProviderByClass(comp, cpr); 8919 } 8920 if (DEBUG_MU) 8921 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8922 app.pubProviders.put(cpi.name, cpr); 8923 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8924 // Don't add this if it is a platform component that is marked 8925 // to run in multiple processes, because this is actually 8926 // part of the framework so doesn't make sense to track as a 8927 // separate apk in the process. 8928 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8929 mProcessStats); 8930 } 8931 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8932 } 8933 } 8934 return providers; 8935 } 8936 8937 /** 8938 * Check if {@link ProcessRecord} has a possible chance at accessing the 8939 * given {@link ProviderInfo}. Final permission checking is always done 8940 * in {@link ContentProvider}. 8941 */ 8942 private final String checkContentProviderPermissionLocked( 8943 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8944 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8945 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8946 boolean checkedGrants = false; 8947 if (checkUser) { 8948 // Looking for cross-user grants before enforcing the typical cross-users permissions 8949 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8950 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8951 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8952 return null; 8953 } 8954 checkedGrants = true; 8955 } 8956 userId = handleIncomingUser(callingPid, callingUid, userId, 8957 false, ALLOW_NON_FULL, 8958 "checkContentProviderPermissionLocked " + cpi.authority, null); 8959 if (userId != tmpTargetUserId) { 8960 // When we actually went to determine the final targer user ID, this ended 8961 // up different than our initial check for the authority. This is because 8962 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8963 // SELF. So we need to re-check the grants again. 8964 checkedGrants = false; 8965 } 8966 } 8967 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8968 cpi.applicationInfo.uid, cpi.exported) 8969 == PackageManager.PERMISSION_GRANTED) { 8970 return null; 8971 } 8972 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8973 cpi.applicationInfo.uid, cpi.exported) 8974 == PackageManager.PERMISSION_GRANTED) { 8975 return null; 8976 } 8977 8978 PathPermission[] pps = cpi.pathPermissions; 8979 if (pps != null) { 8980 int i = pps.length; 8981 while (i > 0) { 8982 i--; 8983 PathPermission pp = pps[i]; 8984 String pprperm = pp.getReadPermission(); 8985 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8986 cpi.applicationInfo.uid, cpi.exported) 8987 == PackageManager.PERMISSION_GRANTED) { 8988 return null; 8989 } 8990 String ppwperm = pp.getWritePermission(); 8991 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8992 cpi.applicationInfo.uid, cpi.exported) 8993 == PackageManager.PERMISSION_GRANTED) { 8994 return null; 8995 } 8996 } 8997 } 8998 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8999 return null; 9000 } 9001 9002 String msg; 9003 if (!cpi.exported) { 9004 msg = "Permission Denial: opening provider " + cpi.name 9005 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9006 + ", uid=" + callingUid + ") that is not exported from uid " 9007 + cpi.applicationInfo.uid; 9008 } else { 9009 msg = "Permission Denial: opening provider " + cpi.name 9010 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9011 + ", uid=" + callingUid + ") requires " 9012 + cpi.readPermission + " or " + cpi.writePermission; 9013 } 9014 Slog.w(TAG, msg); 9015 return msg; 9016 } 9017 9018 /** 9019 * Returns if the ContentProvider has granted a uri to callingUid 9020 */ 9021 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9022 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9023 if (perms != null) { 9024 for (int i=perms.size()-1; i>=0; i--) { 9025 GrantUri grantUri = perms.keyAt(i); 9026 if (grantUri.sourceUserId == userId || !checkUser) { 9027 if (matchesProvider(grantUri.uri, cpi)) { 9028 return true; 9029 } 9030 } 9031 } 9032 } 9033 return false; 9034 } 9035 9036 /** 9037 * Returns true if the uri authority is one of the authorities specified in the provider. 9038 */ 9039 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9040 String uriAuth = uri.getAuthority(); 9041 String cpiAuth = cpi.authority; 9042 if (cpiAuth.indexOf(';') == -1) { 9043 return cpiAuth.equals(uriAuth); 9044 } 9045 String[] cpiAuths = cpiAuth.split(";"); 9046 int length = cpiAuths.length; 9047 for (int i = 0; i < length; i++) { 9048 if (cpiAuths[i].equals(uriAuth)) return true; 9049 } 9050 return false; 9051 } 9052 9053 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9054 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9055 if (r != null) { 9056 for (int i=0; i<r.conProviders.size(); i++) { 9057 ContentProviderConnection conn = r.conProviders.get(i); 9058 if (conn.provider == cpr) { 9059 if (DEBUG_PROVIDER) Slog.v(TAG, 9060 "Adding provider requested by " 9061 + r.processName + " from process " 9062 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9063 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9064 if (stable) { 9065 conn.stableCount++; 9066 conn.numStableIncs++; 9067 } else { 9068 conn.unstableCount++; 9069 conn.numUnstableIncs++; 9070 } 9071 return conn; 9072 } 9073 } 9074 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9075 if (stable) { 9076 conn.stableCount = 1; 9077 conn.numStableIncs = 1; 9078 } else { 9079 conn.unstableCount = 1; 9080 conn.numUnstableIncs = 1; 9081 } 9082 cpr.connections.add(conn); 9083 r.conProviders.add(conn); 9084 return conn; 9085 } 9086 cpr.addExternalProcessHandleLocked(externalProcessToken); 9087 return null; 9088 } 9089 9090 boolean decProviderCountLocked(ContentProviderConnection conn, 9091 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9092 if (conn != null) { 9093 cpr = conn.provider; 9094 if (DEBUG_PROVIDER) Slog.v(TAG, 9095 "Removing provider requested by " 9096 + conn.client.processName + " from process " 9097 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9098 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9099 if (stable) { 9100 conn.stableCount--; 9101 } else { 9102 conn.unstableCount--; 9103 } 9104 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9105 cpr.connections.remove(conn); 9106 conn.client.conProviders.remove(conn); 9107 return true; 9108 } 9109 return false; 9110 } 9111 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9112 return false; 9113 } 9114 9115 private void checkTime(long startTime, String where) { 9116 long now = SystemClock.elapsedRealtime(); 9117 if ((now-startTime) > 1000) { 9118 // If we are taking more than a second, log about it. 9119 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9120 } 9121 } 9122 9123 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9124 String name, IBinder token, boolean stable, int userId) { 9125 ContentProviderRecord cpr; 9126 ContentProviderConnection conn = null; 9127 ProviderInfo cpi = null; 9128 9129 synchronized(this) { 9130 long startTime = SystemClock.elapsedRealtime(); 9131 9132 ProcessRecord r = null; 9133 if (caller != null) { 9134 r = getRecordForAppLocked(caller); 9135 if (r == null) { 9136 throw new SecurityException( 9137 "Unable to find app for caller " + caller 9138 + " (pid=" + Binder.getCallingPid() 9139 + ") when getting content provider " + name); 9140 } 9141 } 9142 9143 boolean checkCrossUser = true; 9144 9145 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9146 9147 // First check if this content provider has been published... 9148 cpr = mProviderMap.getProviderByName(name, userId); 9149 // If that didn't work, check if it exists for user 0 and then 9150 // verify that it's a singleton provider before using it. 9151 if (cpr == null && userId != UserHandle.USER_OWNER) { 9152 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9153 if (cpr != null) { 9154 cpi = cpr.info; 9155 if (isSingleton(cpi.processName, cpi.applicationInfo, 9156 cpi.name, cpi.flags) 9157 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9158 userId = UserHandle.USER_OWNER; 9159 checkCrossUser = false; 9160 } else { 9161 cpr = null; 9162 cpi = null; 9163 } 9164 } 9165 } 9166 9167 boolean providerRunning = cpr != null; 9168 if (providerRunning) { 9169 cpi = cpr.info; 9170 String msg; 9171 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9172 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9173 != null) { 9174 throw new SecurityException(msg); 9175 } 9176 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9177 9178 if (r != null && cpr.canRunHere(r)) { 9179 // This provider has been published or is in the process 9180 // of being published... but it is also allowed to run 9181 // in the caller's process, so don't make a connection 9182 // and just let the caller instantiate its own instance. 9183 ContentProviderHolder holder = cpr.newHolder(null); 9184 // don't give caller the provider object, it needs 9185 // to make its own. 9186 holder.provider = null; 9187 return holder; 9188 } 9189 9190 final long origId = Binder.clearCallingIdentity(); 9191 9192 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9193 9194 // In this case the provider instance already exists, so we can 9195 // return it right away. 9196 conn = incProviderCountLocked(r, cpr, token, stable); 9197 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9198 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9199 // If this is a perceptible app accessing the provider, 9200 // make sure to count it as being accessed and thus 9201 // back up on the LRU list. This is good because 9202 // content providers are often expensive to start. 9203 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9204 updateLruProcessLocked(cpr.proc, false, null); 9205 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9206 } 9207 } 9208 9209 if (cpr.proc != null) { 9210 if (false) { 9211 if (cpr.name.flattenToShortString().equals( 9212 "com.android.providers.calendar/.CalendarProvider2")) { 9213 Slog.v(TAG, "****************** KILLING " 9214 + cpr.name.flattenToShortString()); 9215 Process.killProcess(cpr.proc.pid); 9216 } 9217 } 9218 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9219 boolean success = updateOomAdjLocked(cpr.proc); 9220 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9221 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9222 // NOTE: there is still a race here where a signal could be 9223 // pending on the process even though we managed to update its 9224 // adj level. Not sure what to do about this, but at least 9225 // the race is now smaller. 9226 if (!success) { 9227 // Uh oh... it looks like the provider's process 9228 // has been killed on us. We need to wait for a new 9229 // process to be started, and make sure its death 9230 // doesn't kill our process. 9231 Slog.i(TAG, 9232 "Existing provider " + cpr.name.flattenToShortString() 9233 + " is crashing; detaching " + r); 9234 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9235 checkTime(startTime, "getContentProviderImpl: before appDied"); 9236 appDiedLocked(cpr.proc); 9237 checkTime(startTime, "getContentProviderImpl: after appDied"); 9238 if (!lastRef) { 9239 // This wasn't the last ref our process had on 9240 // the provider... we have now been killed, bail. 9241 return null; 9242 } 9243 providerRunning = false; 9244 conn = null; 9245 } 9246 } 9247 9248 Binder.restoreCallingIdentity(origId); 9249 } 9250 9251 boolean singleton; 9252 if (!providerRunning) { 9253 try { 9254 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9255 cpi = AppGlobals.getPackageManager(). 9256 resolveContentProvider(name, 9257 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9258 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9259 } catch (RemoteException ex) { 9260 } 9261 if (cpi == null) { 9262 return null; 9263 } 9264 // If the provider is a singleton AND 9265 // (it's a call within the same user || the provider is a 9266 // privileged app) 9267 // Then allow connecting to the singleton provider 9268 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9269 cpi.name, cpi.flags) 9270 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9271 if (singleton) { 9272 userId = UserHandle.USER_OWNER; 9273 } 9274 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9275 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9276 9277 String msg; 9278 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9279 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9280 != null) { 9281 throw new SecurityException(msg); 9282 } 9283 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9284 9285 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9286 && !cpi.processName.equals("system")) { 9287 // If this content provider does not run in the system 9288 // process, and the system is not yet ready to run other 9289 // processes, then fail fast instead of hanging. 9290 throw new IllegalArgumentException( 9291 "Attempt to launch content provider before system ready"); 9292 } 9293 9294 // Make sure that the user who owns this provider is started. If not, 9295 // we don't want to allow it to run. 9296 if (mStartedUsers.get(userId) == null) { 9297 Slog.w(TAG, "Unable to launch app " 9298 + cpi.applicationInfo.packageName + "/" 9299 + cpi.applicationInfo.uid + " for provider " 9300 + name + ": user " + userId + " is stopped"); 9301 return null; 9302 } 9303 9304 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9305 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9306 cpr = mProviderMap.getProviderByClass(comp, userId); 9307 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9308 final boolean firstClass = cpr == null; 9309 if (firstClass) { 9310 try { 9311 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9312 ApplicationInfo ai = 9313 AppGlobals.getPackageManager(). 9314 getApplicationInfo( 9315 cpi.applicationInfo.packageName, 9316 STOCK_PM_FLAGS, userId); 9317 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9318 if (ai == null) { 9319 Slog.w(TAG, "No package info for content provider " 9320 + cpi.name); 9321 return null; 9322 } 9323 ai = getAppInfoForUser(ai, userId); 9324 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9325 } catch (RemoteException ex) { 9326 // pm is in same process, this will never happen. 9327 } 9328 } 9329 9330 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9331 9332 if (r != null && cpr.canRunHere(r)) { 9333 // If this is a multiprocess provider, then just return its 9334 // info and allow the caller to instantiate it. Only do 9335 // this if the provider is the same user as the caller's 9336 // process, or can run as root (so can be in any process). 9337 return cpr.newHolder(null); 9338 } 9339 9340 if (DEBUG_PROVIDER) { 9341 RuntimeException e = new RuntimeException("here"); 9342 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9343 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9344 } 9345 9346 // This is single process, and our app is now connecting to it. 9347 // See if we are already in the process of launching this 9348 // provider. 9349 final int N = mLaunchingProviders.size(); 9350 int i; 9351 for (i=0; i<N; i++) { 9352 if (mLaunchingProviders.get(i) == cpr) { 9353 break; 9354 } 9355 } 9356 9357 // If the provider is not already being launched, then get it 9358 // started. 9359 if (i >= N) { 9360 final long origId = Binder.clearCallingIdentity(); 9361 9362 try { 9363 // Content provider is now in use, its package can't be stopped. 9364 try { 9365 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9366 AppGlobals.getPackageManager().setPackageStoppedState( 9367 cpr.appInfo.packageName, false, userId); 9368 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9369 } catch (RemoteException e) { 9370 } catch (IllegalArgumentException e) { 9371 Slog.w(TAG, "Failed trying to unstop package " 9372 + cpr.appInfo.packageName + ": " + e); 9373 } 9374 9375 // Use existing process if already started 9376 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9377 ProcessRecord proc = getProcessRecordLocked( 9378 cpi.processName, cpr.appInfo.uid, false); 9379 if (proc != null && proc.thread != null) { 9380 if (DEBUG_PROVIDER) { 9381 Slog.d(TAG, "Installing in existing process " + proc); 9382 } 9383 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9384 proc.pubProviders.put(cpi.name, cpr); 9385 try { 9386 proc.thread.scheduleInstallProvider(cpi); 9387 } catch (RemoteException e) { 9388 } 9389 } else { 9390 checkTime(startTime, "getContentProviderImpl: before start process"); 9391 proc = startProcessLocked(cpi.processName, 9392 cpr.appInfo, false, 0, "content provider", 9393 new ComponentName(cpi.applicationInfo.packageName, 9394 cpi.name), false, false, false); 9395 checkTime(startTime, "getContentProviderImpl: after start process"); 9396 if (proc == null) { 9397 Slog.w(TAG, "Unable to launch app " 9398 + cpi.applicationInfo.packageName + "/" 9399 + cpi.applicationInfo.uid + " for provider " 9400 + name + ": process is bad"); 9401 return null; 9402 } 9403 } 9404 cpr.launchingApp = proc; 9405 mLaunchingProviders.add(cpr); 9406 } finally { 9407 Binder.restoreCallingIdentity(origId); 9408 } 9409 } 9410 9411 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9412 9413 // Make sure the provider is published (the same provider class 9414 // may be published under multiple names). 9415 if (firstClass) { 9416 mProviderMap.putProviderByClass(comp, cpr); 9417 } 9418 9419 mProviderMap.putProviderByName(name, cpr); 9420 conn = incProviderCountLocked(r, cpr, token, stable); 9421 if (conn != null) { 9422 conn.waiting = true; 9423 } 9424 } 9425 checkTime(startTime, "getContentProviderImpl: done!"); 9426 } 9427 9428 // Wait for the provider to be published... 9429 synchronized (cpr) { 9430 while (cpr.provider == null) { 9431 if (cpr.launchingApp == null) { 9432 Slog.w(TAG, "Unable to launch app " 9433 + cpi.applicationInfo.packageName + "/" 9434 + cpi.applicationInfo.uid + " for provider " 9435 + name + ": launching app became null"); 9436 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9437 UserHandle.getUserId(cpi.applicationInfo.uid), 9438 cpi.applicationInfo.packageName, 9439 cpi.applicationInfo.uid, name); 9440 return null; 9441 } 9442 try { 9443 if (DEBUG_MU) { 9444 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9445 + cpr.launchingApp); 9446 } 9447 if (conn != null) { 9448 conn.waiting = true; 9449 } 9450 cpr.wait(); 9451 } catch (InterruptedException ex) { 9452 } finally { 9453 if (conn != null) { 9454 conn.waiting = false; 9455 } 9456 } 9457 } 9458 } 9459 return cpr != null ? cpr.newHolder(conn) : null; 9460 } 9461 9462 @Override 9463 public final ContentProviderHolder getContentProvider( 9464 IApplicationThread caller, String name, int userId, boolean stable) { 9465 enforceNotIsolatedCaller("getContentProvider"); 9466 if (caller == null) { 9467 String msg = "null IApplicationThread when getting content provider " 9468 + name; 9469 Slog.w(TAG, msg); 9470 throw new SecurityException(msg); 9471 } 9472 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9473 // with cross-user grant. 9474 return getContentProviderImpl(caller, name, null, stable, userId); 9475 } 9476 9477 public ContentProviderHolder getContentProviderExternal( 9478 String name, int userId, IBinder token) { 9479 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9480 "Do not have permission in call getContentProviderExternal()"); 9481 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9482 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9483 return getContentProviderExternalUnchecked(name, token, userId); 9484 } 9485 9486 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9487 IBinder token, int userId) { 9488 return getContentProviderImpl(null, name, token, true, userId); 9489 } 9490 9491 /** 9492 * Drop a content provider from a ProcessRecord's bookkeeping 9493 */ 9494 public void removeContentProvider(IBinder connection, boolean stable) { 9495 enforceNotIsolatedCaller("removeContentProvider"); 9496 long ident = Binder.clearCallingIdentity(); 9497 try { 9498 synchronized (this) { 9499 ContentProviderConnection conn; 9500 try { 9501 conn = (ContentProviderConnection)connection; 9502 } catch (ClassCastException e) { 9503 String msg ="removeContentProvider: " + connection 9504 + " not a ContentProviderConnection"; 9505 Slog.w(TAG, msg); 9506 throw new IllegalArgumentException(msg); 9507 } 9508 if (conn == null) { 9509 throw new NullPointerException("connection is null"); 9510 } 9511 if (decProviderCountLocked(conn, null, null, stable)) { 9512 updateOomAdjLocked(); 9513 } 9514 } 9515 } finally { 9516 Binder.restoreCallingIdentity(ident); 9517 } 9518 } 9519 9520 public void removeContentProviderExternal(String name, IBinder token) { 9521 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9522 "Do not have permission in call removeContentProviderExternal()"); 9523 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9524 } 9525 9526 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9527 synchronized (this) { 9528 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9529 if(cpr == null) { 9530 //remove from mProvidersByClass 9531 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9532 return; 9533 } 9534 9535 //update content provider record entry info 9536 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9537 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9538 if (localCpr.hasExternalProcessHandles()) { 9539 if (localCpr.removeExternalProcessHandleLocked(token)) { 9540 updateOomAdjLocked(); 9541 } else { 9542 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9543 + " with no external reference for token: " 9544 + token + "."); 9545 } 9546 } else { 9547 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9548 + " with no external references."); 9549 } 9550 } 9551 } 9552 9553 public final void publishContentProviders(IApplicationThread caller, 9554 List<ContentProviderHolder> providers) { 9555 if (providers == null) { 9556 return; 9557 } 9558 9559 enforceNotIsolatedCaller("publishContentProviders"); 9560 synchronized (this) { 9561 final ProcessRecord r = getRecordForAppLocked(caller); 9562 if (DEBUG_MU) 9563 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9564 if (r == null) { 9565 throw new SecurityException( 9566 "Unable to find app for caller " + caller 9567 + " (pid=" + Binder.getCallingPid() 9568 + ") when publishing content providers"); 9569 } 9570 9571 final long origId = Binder.clearCallingIdentity(); 9572 9573 final int N = providers.size(); 9574 for (int i=0; i<N; i++) { 9575 ContentProviderHolder src = providers.get(i); 9576 if (src == null || src.info == null || src.provider == null) { 9577 continue; 9578 } 9579 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9580 if (DEBUG_MU) 9581 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9582 if (dst != null) { 9583 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9584 mProviderMap.putProviderByClass(comp, dst); 9585 String names[] = dst.info.authority.split(";"); 9586 for (int j = 0; j < names.length; j++) { 9587 mProviderMap.putProviderByName(names[j], dst); 9588 } 9589 9590 int NL = mLaunchingProviders.size(); 9591 int j; 9592 for (j=0; j<NL; j++) { 9593 if (mLaunchingProviders.get(j) == dst) { 9594 mLaunchingProviders.remove(j); 9595 j--; 9596 NL--; 9597 } 9598 } 9599 synchronized (dst) { 9600 dst.provider = src.provider; 9601 dst.proc = r; 9602 dst.notifyAll(); 9603 } 9604 updateOomAdjLocked(r); 9605 } 9606 } 9607 9608 Binder.restoreCallingIdentity(origId); 9609 } 9610 } 9611 9612 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9613 ContentProviderConnection conn; 9614 try { 9615 conn = (ContentProviderConnection)connection; 9616 } catch (ClassCastException e) { 9617 String msg ="refContentProvider: " + connection 9618 + " not a ContentProviderConnection"; 9619 Slog.w(TAG, msg); 9620 throw new IllegalArgumentException(msg); 9621 } 9622 if (conn == null) { 9623 throw new NullPointerException("connection is null"); 9624 } 9625 9626 synchronized (this) { 9627 if (stable > 0) { 9628 conn.numStableIncs += stable; 9629 } 9630 stable = conn.stableCount + stable; 9631 if (stable < 0) { 9632 throw new IllegalStateException("stableCount < 0: " + stable); 9633 } 9634 9635 if (unstable > 0) { 9636 conn.numUnstableIncs += unstable; 9637 } 9638 unstable = conn.unstableCount + unstable; 9639 if (unstable < 0) { 9640 throw new IllegalStateException("unstableCount < 0: " + unstable); 9641 } 9642 9643 if ((stable+unstable) <= 0) { 9644 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9645 + stable + " unstable=" + unstable); 9646 } 9647 conn.stableCount = stable; 9648 conn.unstableCount = unstable; 9649 return !conn.dead; 9650 } 9651 } 9652 9653 public void unstableProviderDied(IBinder connection) { 9654 ContentProviderConnection conn; 9655 try { 9656 conn = (ContentProviderConnection)connection; 9657 } catch (ClassCastException e) { 9658 String msg ="refContentProvider: " + connection 9659 + " not a ContentProviderConnection"; 9660 Slog.w(TAG, msg); 9661 throw new IllegalArgumentException(msg); 9662 } 9663 if (conn == null) { 9664 throw new NullPointerException("connection is null"); 9665 } 9666 9667 // Safely retrieve the content provider associated with the connection. 9668 IContentProvider provider; 9669 synchronized (this) { 9670 provider = conn.provider.provider; 9671 } 9672 9673 if (provider == null) { 9674 // Um, yeah, we're way ahead of you. 9675 return; 9676 } 9677 9678 // Make sure the caller is being honest with us. 9679 if (provider.asBinder().pingBinder()) { 9680 // Er, no, still looks good to us. 9681 synchronized (this) { 9682 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9683 + " says " + conn + " died, but we don't agree"); 9684 return; 9685 } 9686 } 9687 9688 // Well look at that! It's dead! 9689 synchronized (this) { 9690 if (conn.provider.provider != provider) { 9691 // But something changed... good enough. 9692 return; 9693 } 9694 9695 ProcessRecord proc = conn.provider.proc; 9696 if (proc == null || proc.thread == null) { 9697 // Seems like the process is already cleaned up. 9698 return; 9699 } 9700 9701 // As far as we're concerned, this is just like receiving a 9702 // death notification... just a bit prematurely. 9703 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9704 + ") early provider death"); 9705 final long ident = Binder.clearCallingIdentity(); 9706 try { 9707 appDiedLocked(proc); 9708 } finally { 9709 Binder.restoreCallingIdentity(ident); 9710 } 9711 } 9712 } 9713 9714 @Override 9715 public void appNotRespondingViaProvider(IBinder connection) { 9716 enforceCallingPermission( 9717 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9718 9719 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9720 if (conn == null) { 9721 Slog.w(TAG, "ContentProviderConnection is null"); 9722 return; 9723 } 9724 9725 final ProcessRecord host = conn.provider.proc; 9726 if (host == null) { 9727 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9728 return; 9729 } 9730 9731 final long token = Binder.clearCallingIdentity(); 9732 try { 9733 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9734 } finally { 9735 Binder.restoreCallingIdentity(token); 9736 } 9737 } 9738 9739 public final void installSystemProviders() { 9740 List<ProviderInfo> providers; 9741 synchronized (this) { 9742 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9743 providers = generateApplicationProvidersLocked(app); 9744 if (providers != null) { 9745 for (int i=providers.size()-1; i>=0; i--) { 9746 ProviderInfo pi = (ProviderInfo)providers.get(i); 9747 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9748 Slog.w(TAG, "Not installing system proc provider " + pi.name 9749 + ": not system .apk"); 9750 providers.remove(i); 9751 } 9752 } 9753 } 9754 } 9755 if (providers != null) { 9756 mSystemThread.installSystemProviders(providers); 9757 } 9758 9759 mCoreSettingsObserver = new CoreSettingsObserver(this); 9760 9761 //mUsageStatsService.monitorPackages(); 9762 } 9763 9764 /** 9765 * Allows apps to retrieve the MIME type of a URI. 9766 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9767 * users, then it does not need permission to access the ContentProvider. 9768 * Either, it needs cross-user uri grants. 9769 * 9770 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9771 * 9772 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9773 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9774 */ 9775 public String getProviderMimeType(Uri uri, int userId) { 9776 enforceNotIsolatedCaller("getProviderMimeType"); 9777 final String name = uri.getAuthority(); 9778 int callingUid = Binder.getCallingUid(); 9779 int callingPid = Binder.getCallingPid(); 9780 long ident = 0; 9781 boolean clearedIdentity = false; 9782 userId = unsafeConvertIncomingUser(userId); 9783 if (canClearIdentity(callingPid, callingUid, userId)) { 9784 clearedIdentity = true; 9785 ident = Binder.clearCallingIdentity(); 9786 } 9787 ContentProviderHolder holder = null; 9788 try { 9789 holder = getContentProviderExternalUnchecked(name, null, userId); 9790 if (holder != null) { 9791 return holder.provider.getType(uri); 9792 } 9793 } catch (RemoteException e) { 9794 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9795 return null; 9796 } finally { 9797 // We need to clear the identity to call removeContentProviderExternalUnchecked 9798 if (!clearedIdentity) { 9799 ident = Binder.clearCallingIdentity(); 9800 } 9801 try { 9802 if (holder != null) { 9803 removeContentProviderExternalUnchecked(name, null, userId); 9804 } 9805 } finally { 9806 Binder.restoreCallingIdentity(ident); 9807 } 9808 } 9809 9810 return null; 9811 } 9812 9813 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9814 if (UserHandle.getUserId(callingUid) == userId) { 9815 return true; 9816 } 9817 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9818 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9819 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9820 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9821 return true; 9822 } 9823 return false; 9824 } 9825 9826 // ========================================================= 9827 // GLOBAL MANAGEMENT 9828 // ========================================================= 9829 9830 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9831 boolean isolated, int isolatedUid) { 9832 String proc = customProcess != null ? customProcess : info.processName; 9833 BatteryStatsImpl.Uid.Proc ps = null; 9834 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9835 int uid = info.uid; 9836 if (isolated) { 9837 if (isolatedUid == 0) { 9838 int userId = UserHandle.getUserId(uid); 9839 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9840 while (true) { 9841 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9842 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9843 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9844 } 9845 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9846 mNextIsolatedProcessUid++; 9847 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9848 // No process for this uid, use it. 9849 break; 9850 } 9851 stepsLeft--; 9852 if (stepsLeft <= 0) { 9853 return null; 9854 } 9855 } 9856 } else { 9857 // Special case for startIsolatedProcess (internal only), where 9858 // the uid of the isolated process is specified by the caller. 9859 uid = isolatedUid; 9860 } 9861 } 9862 return new ProcessRecord(stats, info, proc, uid); 9863 } 9864 9865 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9866 String abiOverride) { 9867 ProcessRecord app; 9868 if (!isolated) { 9869 app = getProcessRecordLocked(info.processName, info.uid, true); 9870 } else { 9871 app = null; 9872 } 9873 9874 if (app == null) { 9875 app = newProcessRecordLocked(info, null, isolated, 0); 9876 mProcessNames.put(info.processName, app.uid, app); 9877 if (isolated) { 9878 mIsolatedProcesses.put(app.uid, app); 9879 } 9880 updateLruProcessLocked(app, false, null); 9881 updateOomAdjLocked(); 9882 } 9883 9884 // This package really, really can not be stopped. 9885 try { 9886 AppGlobals.getPackageManager().setPackageStoppedState( 9887 info.packageName, false, UserHandle.getUserId(app.uid)); 9888 } catch (RemoteException e) { 9889 } catch (IllegalArgumentException e) { 9890 Slog.w(TAG, "Failed trying to unstop package " 9891 + info.packageName + ": " + e); 9892 } 9893 9894 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9895 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9896 app.persistent = true; 9897 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9898 } 9899 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9900 mPersistentStartingProcesses.add(app); 9901 startProcessLocked(app, "added application", app.processName, abiOverride, 9902 null /* entryPoint */, null /* entryPointArgs */); 9903 } 9904 9905 return app; 9906 } 9907 9908 public void unhandledBack() { 9909 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9910 "unhandledBack()"); 9911 9912 synchronized(this) { 9913 final long origId = Binder.clearCallingIdentity(); 9914 try { 9915 getFocusedStack().unhandledBackLocked(); 9916 } finally { 9917 Binder.restoreCallingIdentity(origId); 9918 } 9919 } 9920 } 9921 9922 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9923 enforceNotIsolatedCaller("openContentUri"); 9924 final int userId = UserHandle.getCallingUserId(); 9925 String name = uri.getAuthority(); 9926 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9927 ParcelFileDescriptor pfd = null; 9928 if (cph != null) { 9929 // We record the binder invoker's uid in thread-local storage before 9930 // going to the content provider to open the file. Later, in the code 9931 // that handles all permissions checks, we look for this uid and use 9932 // that rather than the Activity Manager's own uid. The effect is that 9933 // we do the check against the caller's permissions even though it looks 9934 // to the content provider like the Activity Manager itself is making 9935 // the request. 9936 sCallerIdentity.set(new Identity( 9937 Binder.getCallingPid(), Binder.getCallingUid())); 9938 try { 9939 pfd = cph.provider.openFile(null, uri, "r", null); 9940 } catch (FileNotFoundException e) { 9941 // do nothing; pfd will be returned null 9942 } finally { 9943 // Ensure that whatever happens, we clean up the identity state 9944 sCallerIdentity.remove(); 9945 } 9946 9947 // We've got the fd now, so we're done with the provider. 9948 removeContentProviderExternalUnchecked(name, null, userId); 9949 } else { 9950 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9951 } 9952 return pfd; 9953 } 9954 9955 // Actually is sleeping or shutting down or whatever else in the future 9956 // is an inactive state. 9957 public boolean isSleepingOrShuttingDown() { 9958 return isSleeping() || mShuttingDown; 9959 } 9960 9961 public boolean isSleeping() { 9962 return mSleeping; 9963 } 9964 9965 void goingToSleep() { 9966 synchronized(this) { 9967 mWentToSleep = true; 9968 goToSleepIfNeededLocked(); 9969 } 9970 } 9971 9972 void finishRunningVoiceLocked() { 9973 if (mRunningVoice) { 9974 mRunningVoice = false; 9975 goToSleepIfNeededLocked(); 9976 } 9977 } 9978 9979 void goToSleepIfNeededLocked() { 9980 if (mWentToSleep && !mRunningVoice) { 9981 if (!mSleeping) { 9982 mSleeping = true; 9983 mStackSupervisor.goingToSleepLocked(); 9984 9985 // Initialize the wake times of all processes. 9986 checkExcessivePowerUsageLocked(false); 9987 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9988 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9989 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9990 } 9991 } 9992 } 9993 9994 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9995 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9996 // Never persist the home stack. 9997 return; 9998 } 9999 mTaskPersister.wakeup(task, flush); 10000 } 10001 10002 @Override 10003 public boolean shutdown(int timeout) { 10004 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 10005 != PackageManager.PERMISSION_GRANTED) { 10006 throw new SecurityException("Requires permission " 10007 + android.Manifest.permission.SHUTDOWN); 10008 } 10009 10010 boolean timedout = false; 10011 10012 synchronized(this) { 10013 mShuttingDown = true; 10014 updateEventDispatchingLocked(); 10015 timedout = mStackSupervisor.shutdownLocked(timeout); 10016 } 10017 10018 mAppOpsService.shutdown(); 10019 if (mUsageStatsService != null) { 10020 mUsageStatsService.prepareShutdown(); 10021 } 10022 mBatteryStatsService.shutdown(); 10023 synchronized (this) { 10024 mProcessStats.shutdownLocked(); 10025 } 10026 notifyTaskPersisterLocked(null, true); 10027 10028 return timedout; 10029 } 10030 10031 public final void activitySlept(IBinder token) { 10032 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10033 10034 final long origId = Binder.clearCallingIdentity(); 10035 10036 synchronized (this) { 10037 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10038 if (r != null) { 10039 mStackSupervisor.activitySleptLocked(r); 10040 } 10041 } 10042 10043 Binder.restoreCallingIdentity(origId); 10044 } 10045 10046 void logLockScreen(String msg) { 10047 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10048 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10049 mWentToSleep + " mSleeping=" + mSleeping); 10050 } 10051 10052 private void comeOutOfSleepIfNeededLocked() { 10053 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10054 if (mSleeping) { 10055 mSleeping = false; 10056 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10057 } 10058 } 10059 } 10060 10061 void wakingUp() { 10062 synchronized(this) { 10063 mWentToSleep = false; 10064 comeOutOfSleepIfNeededLocked(); 10065 } 10066 } 10067 10068 void startRunningVoiceLocked() { 10069 if (!mRunningVoice) { 10070 mRunningVoice = true; 10071 comeOutOfSleepIfNeededLocked(); 10072 } 10073 } 10074 10075 private void updateEventDispatchingLocked() { 10076 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10077 } 10078 10079 public void setLockScreenShown(boolean shown) { 10080 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10081 != PackageManager.PERMISSION_GRANTED) { 10082 throw new SecurityException("Requires permission " 10083 + android.Manifest.permission.DEVICE_POWER); 10084 } 10085 10086 synchronized(this) { 10087 long ident = Binder.clearCallingIdentity(); 10088 try { 10089 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10090 mLockScreenShown = shown; 10091 comeOutOfSleepIfNeededLocked(); 10092 } finally { 10093 Binder.restoreCallingIdentity(ident); 10094 } 10095 } 10096 } 10097 10098 @Override 10099 public void stopAppSwitches() { 10100 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10101 != PackageManager.PERMISSION_GRANTED) { 10102 throw new SecurityException("Requires permission " 10103 + android.Manifest.permission.STOP_APP_SWITCHES); 10104 } 10105 10106 synchronized(this) { 10107 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10108 + APP_SWITCH_DELAY_TIME; 10109 mDidAppSwitch = false; 10110 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10111 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10112 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10113 } 10114 } 10115 10116 public void resumeAppSwitches() { 10117 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10118 != PackageManager.PERMISSION_GRANTED) { 10119 throw new SecurityException("Requires permission " 10120 + android.Manifest.permission.STOP_APP_SWITCHES); 10121 } 10122 10123 synchronized(this) { 10124 // Note that we don't execute any pending app switches... we will 10125 // let those wait until either the timeout, or the next start 10126 // activity request. 10127 mAppSwitchesAllowedTime = 0; 10128 } 10129 } 10130 10131 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10132 int callingPid, int callingUid, String name) { 10133 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10134 return true; 10135 } 10136 10137 int perm = checkComponentPermission( 10138 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10139 sourceUid, -1, true); 10140 if (perm == PackageManager.PERMISSION_GRANTED) { 10141 return true; 10142 } 10143 10144 // If the actual IPC caller is different from the logical source, then 10145 // also see if they are allowed to control app switches. 10146 if (callingUid != -1 && callingUid != sourceUid) { 10147 perm = checkComponentPermission( 10148 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10149 callingUid, -1, true); 10150 if (perm == PackageManager.PERMISSION_GRANTED) { 10151 return true; 10152 } 10153 } 10154 10155 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10156 return false; 10157 } 10158 10159 public void setDebugApp(String packageName, boolean waitForDebugger, 10160 boolean persistent) { 10161 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10162 "setDebugApp()"); 10163 10164 long ident = Binder.clearCallingIdentity(); 10165 try { 10166 // Note that this is not really thread safe if there are multiple 10167 // callers into it at the same time, but that's not a situation we 10168 // care about. 10169 if (persistent) { 10170 final ContentResolver resolver = mContext.getContentResolver(); 10171 Settings.Global.putString( 10172 resolver, Settings.Global.DEBUG_APP, 10173 packageName); 10174 Settings.Global.putInt( 10175 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10176 waitForDebugger ? 1 : 0); 10177 } 10178 10179 synchronized (this) { 10180 if (!persistent) { 10181 mOrigDebugApp = mDebugApp; 10182 mOrigWaitForDebugger = mWaitForDebugger; 10183 } 10184 mDebugApp = packageName; 10185 mWaitForDebugger = waitForDebugger; 10186 mDebugTransient = !persistent; 10187 if (packageName != null) { 10188 forceStopPackageLocked(packageName, -1, false, false, true, true, 10189 false, UserHandle.USER_ALL, "set debug app"); 10190 } 10191 } 10192 } finally { 10193 Binder.restoreCallingIdentity(ident); 10194 } 10195 } 10196 10197 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10198 synchronized (this) { 10199 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10200 if (!isDebuggable) { 10201 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10202 throw new SecurityException("Process not debuggable: " + app.packageName); 10203 } 10204 } 10205 10206 mOpenGlTraceApp = processName; 10207 } 10208 } 10209 10210 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10211 synchronized (this) { 10212 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10213 if (!isDebuggable) { 10214 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10215 throw new SecurityException("Process not debuggable: " + app.packageName); 10216 } 10217 } 10218 mProfileApp = processName; 10219 mProfileFile = profilerInfo.profileFile; 10220 if (mProfileFd != null) { 10221 try { 10222 mProfileFd.close(); 10223 } catch (IOException e) { 10224 } 10225 mProfileFd = null; 10226 } 10227 mProfileFd = profilerInfo.profileFd; 10228 mSamplingInterval = profilerInfo.samplingInterval; 10229 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10230 mProfileType = 0; 10231 } 10232 } 10233 10234 @Override 10235 public void setAlwaysFinish(boolean enabled) { 10236 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10237 "setAlwaysFinish()"); 10238 10239 Settings.Global.putInt( 10240 mContext.getContentResolver(), 10241 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10242 10243 synchronized (this) { 10244 mAlwaysFinishActivities = enabled; 10245 } 10246 } 10247 10248 @Override 10249 public void setActivityController(IActivityController controller) { 10250 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10251 "setActivityController()"); 10252 synchronized (this) { 10253 mController = controller; 10254 Watchdog.getInstance().setActivityController(controller); 10255 } 10256 } 10257 10258 @Override 10259 public void setUserIsMonkey(boolean userIsMonkey) { 10260 synchronized (this) { 10261 synchronized (mPidsSelfLocked) { 10262 final int callingPid = Binder.getCallingPid(); 10263 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10264 if (precessRecord == null) { 10265 throw new SecurityException("Unknown process: " + callingPid); 10266 } 10267 if (precessRecord.instrumentationUiAutomationConnection == null) { 10268 throw new SecurityException("Only an instrumentation process " 10269 + "with a UiAutomation can call setUserIsMonkey"); 10270 } 10271 } 10272 mUserIsMonkey = userIsMonkey; 10273 } 10274 } 10275 10276 @Override 10277 public boolean isUserAMonkey() { 10278 synchronized (this) { 10279 // If there is a controller also implies the user is a monkey. 10280 return (mUserIsMonkey || mController != null); 10281 } 10282 } 10283 10284 public void requestBugReport() { 10285 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10286 SystemProperties.set("ctl.start", "bugreport"); 10287 } 10288 10289 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10290 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10291 } 10292 10293 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10294 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10295 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10296 } 10297 return KEY_DISPATCHING_TIMEOUT; 10298 } 10299 10300 @Override 10301 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10302 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10303 != PackageManager.PERMISSION_GRANTED) { 10304 throw new SecurityException("Requires permission " 10305 + android.Manifest.permission.FILTER_EVENTS); 10306 } 10307 ProcessRecord proc; 10308 long timeout; 10309 synchronized (this) { 10310 synchronized (mPidsSelfLocked) { 10311 proc = mPidsSelfLocked.get(pid); 10312 } 10313 timeout = getInputDispatchingTimeoutLocked(proc); 10314 } 10315 10316 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10317 return -1; 10318 } 10319 10320 return timeout; 10321 } 10322 10323 /** 10324 * Handle input dispatching timeouts. 10325 * Returns whether input dispatching should be aborted or not. 10326 */ 10327 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10328 final ActivityRecord activity, final ActivityRecord parent, 10329 final boolean aboveSystem, String reason) { 10330 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10331 != PackageManager.PERMISSION_GRANTED) { 10332 throw new SecurityException("Requires permission " 10333 + android.Manifest.permission.FILTER_EVENTS); 10334 } 10335 10336 final String annotation; 10337 if (reason == null) { 10338 annotation = "Input dispatching timed out"; 10339 } else { 10340 annotation = "Input dispatching timed out (" + reason + ")"; 10341 } 10342 10343 if (proc != null) { 10344 synchronized (this) { 10345 if (proc.debugging) { 10346 return false; 10347 } 10348 10349 if (mDidDexOpt) { 10350 // Give more time since we were dexopting. 10351 mDidDexOpt = false; 10352 return false; 10353 } 10354 10355 if (proc.instrumentationClass != null) { 10356 Bundle info = new Bundle(); 10357 info.putString("shortMsg", "keyDispatchingTimedOut"); 10358 info.putString("longMsg", annotation); 10359 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10360 return true; 10361 } 10362 } 10363 mHandler.post(new Runnable() { 10364 @Override 10365 public void run() { 10366 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10367 } 10368 }); 10369 } 10370 10371 return true; 10372 } 10373 10374 public Bundle getAssistContextExtras(int requestType) { 10375 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10376 "getAssistContextExtras()"); 10377 PendingAssistExtras pae; 10378 Bundle extras = new Bundle(); 10379 synchronized (this) { 10380 ActivityRecord activity = getFocusedStack().mResumedActivity; 10381 if (activity == null) { 10382 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10383 return null; 10384 } 10385 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10386 if (activity.app == null || activity.app.thread == null) { 10387 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10388 return extras; 10389 } 10390 if (activity.app.pid == Binder.getCallingPid()) { 10391 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10392 return extras; 10393 } 10394 pae = new PendingAssistExtras(activity); 10395 try { 10396 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10397 requestType); 10398 mPendingAssistExtras.add(pae); 10399 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10400 } catch (RemoteException e) { 10401 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10402 return extras; 10403 } 10404 } 10405 synchronized (pae) { 10406 while (!pae.haveResult) { 10407 try { 10408 pae.wait(); 10409 } catch (InterruptedException e) { 10410 } 10411 } 10412 if (pae.result != null) { 10413 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10414 } 10415 } 10416 synchronized (this) { 10417 mPendingAssistExtras.remove(pae); 10418 mHandler.removeCallbacks(pae); 10419 } 10420 return extras; 10421 } 10422 10423 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10424 PendingAssistExtras pae = (PendingAssistExtras)token; 10425 synchronized (pae) { 10426 pae.result = extras; 10427 pae.haveResult = true; 10428 pae.notifyAll(); 10429 } 10430 } 10431 10432 public void registerProcessObserver(IProcessObserver observer) { 10433 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10434 "registerProcessObserver()"); 10435 synchronized (this) { 10436 mProcessObservers.register(observer); 10437 } 10438 } 10439 10440 @Override 10441 public void unregisterProcessObserver(IProcessObserver observer) { 10442 synchronized (this) { 10443 mProcessObservers.unregister(observer); 10444 } 10445 } 10446 10447 @Override 10448 public boolean convertFromTranslucent(IBinder token) { 10449 final long origId = Binder.clearCallingIdentity(); 10450 try { 10451 synchronized (this) { 10452 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10453 if (r == null) { 10454 return false; 10455 } 10456 final boolean translucentChanged = r.changeWindowTranslucency(true); 10457 if (translucentChanged) { 10458 r.task.stack.releaseBackgroundResources(); 10459 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10460 } 10461 mWindowManager.setAppFullscreen(token, true); 10462 return translucentChanged; 10463 } 10464 } finally { 10465 Binder.restoreCallingIdentity(origId); 10466 } 10467 } 10468 10469 @Override 10470 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10471 final long origId = Binder.clearCallingIdentity(); 10472 try { 10473 synchronized (this) { 10474 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10475 if (r == null) { 10476 return false; 10477 } 10478 int index = r.task.mActivities.lastIndexOf(r); 10479 if (index > 0) { 10480 ActivityRecord under = r.task.mActivities.get(index - 1); 10481 under.returningOptions = options; 10482 } 10483 final boolean translucentChanged = r.changeWindowTranslucency(false); 10484 if (translucentChanged) { 10485 r.task.stack.convertToTranslucent(r); 10486 } 10487 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10488 mWindowManager.setAppFullscreen(token, false); 10489 return translucentChanged; 10490 } 10491 } finally { 10492 Binder.restoreCallingIdentity(origId); 10493 } 10494 } 10495 10496 @Override 10497 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10498 final long origId = Binder.clearCallingIdentity(); 10499 try { 10500 synchronized (this) { 10501 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10502 if (r != null) { 10503 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10504 } 10505 } 10506 return false; 10507 } finally { 10508 Binder.restoreCallingIdentity(origId); 10509 } 10510 } 10511 10512 @Override 10513 public boolean isBackgroundVisibleBehind(IBinder token) { 10514 final long origId = Binder.clearCallingIdentity(); 10515 try { 10516 synchronized (this) { 10517 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10518 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10519 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10520 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10521 return visible; 10522 } 10523 } finally { 10524 Binder.restoreCallingIdentity(origId); 10525 } 10526 } 10527 10528 @Override 10529 public ActivityOptions getActivityOptions(IBinder token) { 10530 final long origId = Binder.clearCallingIdentity(); 10531 try { 10532 synchronized (this) { 10533 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10534 if (r != null) { 10535 final ActivityOptions activityOptions = r.pendingOptions; 10536 r.pendingOptions = null; 10537 return activityOptions; 10538 } 10539 return null; 10540 } 10541 } finally { 10542 Binder.restoreCallingIdentity(origId); 10543 } 10544 } 10545 10546 @Override 10547 public void setImmersive(IBinder token, boolean immersive) { 10548 synchronized(this) { 10549 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10550 if (r == null) { 10551 throw new IllegalArgumentException(); 10552 } 10553 r.immersive = immersive; 10554 10555 // update associated state if we're frontmost 10556 if (r == mFocusedActivity) { 10557 if (DEBUG_IMMERSIVE) { 10558 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10559 } 10560 applyUpdateLockStateLocked(r); 10561 } 10562 } 10563 } 10564 10565 @Override 10566 public boolean isImmersive(IBinder token) { 10567 synchronized (this) { 10568 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10569 if (r == null) { 10570 throw new IllegalArgumentException(); 10571 } 10572 return r.immersive; 10573 } 10574 } 10575 10576 public boolean isTopActivityImmersive() { 10577 enforceNotIsolatedCaller("startActivity"); 10578 synchronized (this) { 10579 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10580 return (r != null) ? r.immersive : false; 10581 } 10582 } 10583 10584 @Override 10585 public boolean isTopOfTask(IBinder token) { 10586 synchronized (this) { 10587 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10588 if (r == null) { 10589 throw new IllegalArgumentException(); 10590 } 10591 return r.task.getTopActivity() == r; 10592 } 10593 } 10594 10595 public final void enterSafeMode() { 10596 synchronized(this) { 10597 // It only makes sense to do this before the system is ready 10598 // and started launching other packages. 10599 if (!mSystemReady) { 10600 try { 10601 AppGlobals.getPackageManager().enterSafeMode(); 10602 } catch (RemoteException e) { 10603 } 10604 } 10605 10606 mSafeMode = true; 10607 } 10608 } 10609 10610 public final void showSafeModeOverlay() { 10611 View v = LayoutInflater.from(mContext).inflate( 10612 com.android.internal.R.layout.safe_mode, null); 10613 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10614 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10615 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10616 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10617 lp.gravity = Gravity.BOTTOM | Gravity.START; 10618 lp.format = v.getBackground().getOpacity(); 10619 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10620 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10621 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10622 ((WindowManager)mContext.getSystemService( 10623 Context.WINDOW_SERVICE)).addView(v, lp); 10624 } 10625 10626 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10627 if (!(sender instanceof PendingIntentRecord)) { 10628 return; 10629 } 10630 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10631 synchronized (stats) { 10632 if (mBatteryStatsService.isOnBattery()) { 10633 mBatteryStatsService.enforceCallingPermission(); 10634 PendingIntentRecord rec = (PendingIntentRecord)sender; 10635 int MY_UID = Binder.getCallingUid(); 10636 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10637 BatteryStatsImpl.Uid.Pkg pkg = 10638 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10639 sourcePkg != null ? sourcePkg : rec.key.packageName); 10640 pkg.incWakeupsLocked(); 10641 } 10642 } 10643 } 10644 10645 public boolean killPids(int[] pids, String pReason, boolean secure) { 10646 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10647 throw new SecurityException("killPids only available to the system"); 10648 } 10649 String reason = (pReason == null) ? "Unknown" : pReason; 10650 // XXX Note: don't acquire main activity lock here, because the window 10651 // manager calls in with its locks held. 10652 10653 boolean killed = false; 10654 synchronized (mPidsSelfLocked) { 10655 int[] types = new int[pids.length]; 10656 int worstType = 0; 10657 for (int i=0; i<pids.length; i++) { 10658 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10659 if (proc != null) { 10660 int type = proc.setAdj; 10661 types[i] = type; 10662 if (type > worstType) { 10663 worstType = type; 10664 } 10665 } 10666 } 10667 10668 // If the worst oom_adj is somewhere in the cached proc LRU range, 10669 // then constrain it so we will kill all cached procs. 10670 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10671 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10672 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10673 } 10674 10675 // If this is not a secure call, don't let it kill processes that 10676 // are important. 10677 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10678 worstType = ProcessList.SERVICE_ADJ; 10679 } 10680 10681 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10682 for (int i=0; i<pids.length; i++) { 10683 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10684 if (proc == null) { 10685 continue; 10686 } 10687 int adj = proc.setAdj; 10688 if (adj >= worstType && !proc.killedByAm) { 10689 proc.kill(reason, true); 10690 killed = true; 10691 } 10692 } 10693 } 10694 return killed; 10695 } 10696 10697 @Override 10698 public void killUid(int uid, String reason) { 10699 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10700 throw new SecurityException("killUid only available to the system"); 10701 } 10702 synchronized (this) { 10703 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10704 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10705 reason != null ? reason : "kill uid"); 10706 } 10707 } 10708 10709 @Override 10710 public boolean killProcessesBelowForeground(String reason) { 10711 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10712 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10713 } 10714 10715 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10716 } 10717 10718 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10719 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10720 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10721 } 10722 10723 boolean killed = false; 10724 synchronized (mPidsSelfLocked) { 10725 final int size = mPidsSelfLocked.size(); 10726 for (int i = 0; i < size; i++) { 10727 final int pid = mPidsSelfLocked.keyAt(i); 10728 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10729 if (proc == null) continue; 10730 10731 final int adj = proc.setAdj; 10732 if (adj > belowAdj && !proc.killedByAm) { 10733 proc.kill(reason, true); 10734 killed = true; 10735 } 10736 } 10737 } 10738 return killed; 10739 } 10740 10741 @Override 10742 public void hang(final IBinder who, boolean allowRestart) { 10743 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10744 != PackageManager.PERMISSION_GRANTED) { 10745 throw new SecurityException("Requires permission " 10746 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10747 } 10748 10749 final IBinder.DeathRecipient death = new DeathRecipient() { 10750 @Override 10751 public void binderDied() { 10752 synchronized (this) { 10753 notifyAll(); 10754 } 10755 } 10756 }; 10757 10758 try { 10759 who.linkToDeath(death, 0); 10760 } catch (RemoteException e) { 10761 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10762 return; 10763 } 10764 10765 synchronized (this) { 10766 Watchdog.getInstance().setAllowRestart(allowRestart); 10767 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10768 synchronized (death) { 10769 while (who.isBinderAlive()) { 10770 try { 10771 death.wait(); 10772 } catch (InterruptedException e) { 10773 } 10774 } 10775 } 10776 Watchdog.getInstance().setAllowRestart(true); 10777 } 10778 } 10779 10780 @Override 10781 public void restart() { 10782 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10783 != PackageManager.PERMISSION_GRANTED) { 10784 throw new SecurityException("Requires permission " 10785 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10786 } 10787 10788 Log.i(TAG, "Sending shutdown broadcast..."); 10789 10790 BroadcastReceiver br = new BroadcastReceiver() { 10791 @Override public void onReceive(Context context, Intent intent) { 10792 // Now the broadcast is done, finish up the low-level shutdown. 10793 Log.i(TAG, "Shutting down activity manager..."); 10794 shutdown(10000); 10795 Log.i(TAG, "Shutdown complete, restarting!"); 10796 Process.killProcess(Process.myPid()); 10797 System.exit(10); 10798 } 10799 }; 10800 10801 // First send the high-level shut down broadcast. 10802 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10803 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10804 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10805 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10806 mContext.sendOrderedBroadcastAsUser(intent, 10807 UserHandle.ALL, null, br, mHandler, 0, null, null); 10808 */ 10809 br.onReceive(mContext, intent); 10810 } 10811 10812 private long getLowRamTimeSinceIdle(long now) { 10813 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10814 } 10815 10816 @Override 10817 public void performIdleMaintenance() { 10818 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10819 != PackageManager.PERMISSION_GRANTED) { 10820 throw new SecurityException("Requires permission " 10821 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10822 } 10823 10824 synchronized (this) { 10825 final long now = SystemClock.uptimeMillis(); 10826 final long timeSinceLastIdle = now - mLastIdleTime; 10827 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10828 mLastIdleTime = now; 10829 mLowRamTimeSinceLastIdle = 0; 10830 if (mLowRamStartTime != 0) { 10831 mLowRamStartTime = now; 10832 } 10833 10834 StringBuilder sb = new StringBuilder(128); 10835 sb.append("Idle maintenance over "); 10836 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10837 sb.append(" low RAM for "); 10838 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10839 Slog.i(TAG, sb.toString()); 10840 10841 // If at least 1/3 of our time since the last idle period has been spent 10842 // with RAM low, then we want to kill processes. 10843 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10844 10845 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10846 ProcessRecord proc = mLruProcesses.get(i); 10847 if (proc.notCachedSinceIdle) { 10848 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10849 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10850 if (doKilling && proc.initialIdlePss != 0 10851 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10852 proc.kill("idle maint (pss " + proc.lastPss 10853 + " from " + proc.initialIdlePss + ")", true); 10854 } 10855 } 10856 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10857 proc.notCachedSinceIdle = true; 10858 proc.initialIdlePss = 0; 10859 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10860 isSleeping(), now); 10861 } 10862 } 10863 10864 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10865 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10866 } 10867 } 10868 10869 private void retrieveSettings() { 10870 final ContentResolver resolver = mContext.getContentResolver(); 10871 String debugApp = Settings.Global.getString( 10872 resolver, Settings.Global.DEBUG_APP); 10873 boolean waitForDebugger = Settings.Global.getInt( 10874 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10875 boolean alwaysFinishActivities = Settings.Global.getInt( 10876 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10877 boolean forceRtl = Settings.Global.getInt( 10878 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10879 // Transfer any global setting for forcing RTL layout, into a System Property 10880 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10881 10882 Configuration configuration = new Configuration(); 10883 Settings.System.getConfiguration(resolver, configuration); 10884 if (forceRtl) { 10885 // This will take care of setting the correct layout direction flags 10886 configuration.setLayoutDirection(configuration.locale); 10887 } 10888 10889 synchronized (this) { 10890 mDebugApp = mOrigDebugApp = debugApp; 10891 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10892 mAlwaysFinishActivities = alwaysFinishActivities; 10893 // This happens before any activities are started, so we can 10894 // change mConfiguration in-place. 10895 updateConfigurationLocked(configuration, null, false, true); 10896 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10897 } 10898 } 10899 10900 /** Loads resources after the current configuration has been set. */ 10901 private void loadResourcesOnSystemReady() { 10902 final Resources res = mContext.getResources(); 10903 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10904 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10905 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10906 } 10907 10908 public boolean testIsSystemReady() { 10909 // no need to synchronize(this) just to read & return the value 10910 return mSystemReady; 10911 } 10912 10913 private static File getCalledPreBootReceiversFile() { 10914 File dataDir = Environment.getDataDirectory(); 10915 File systemDir = new File(dataDir, "system"); 10916 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10917 return fname; 10918 } 10919 10920 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10921 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10922 File file = getCalledPreBootReceiversFile(); 10923 FileInputStream fis = null; 10924 try { 10925 fis = new FileInputStream(file); 10926 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10927 int fvers = dis.readInt(); 10928 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10929 String vers = dis.readUTF(); 10930 String codename = dis.readUTF(); 10931 String build = dis.readUTF(); 10932 if (android.os.Build.VERSION.RELEASE.equals(vers) 10933 && android.os.Build.VERSION.CODENAME.equals(codename) 10934 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10935 int num = dis.readInt(); 10936 while (num > 0) { 10937 num--; 10938 String pkg = dis.readUTF(); 10939 String cls = dis.readUTF(); 10940 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10941 } 10942 } 10943 } 10944 } catch (FileNotFoundException e) { 10945 } catch (IOException e) { 10946 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10947 } finally { 10948 if (fis != null) { 10949 try { 10950 fis.close(); 10951 } catch (IOException e) { 10952 } 10953 } 10954 } 10955 return lastDoneReceivers; 10956 } 10957 10958 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10959 File file = getCalledPreBootReceiversFile(); 10960 FileOutputStream fos = null; 10961 DataOutputStream dos = null; 10962 try { 10963 fos = new FileOutputStream(file); 10964 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10965 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10966 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10967 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10968 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10969 dos.writeInt(list.size()); 10970 for (int i=0; i<list.size(); i++) { 10971 dos.writeUTF(list.get(i).getPackageName()); 10972 dos.writeUTF(list.get(i).getClassName()); 10973 } 10974 } catch (IOException e) { 10975 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10976 file.delete(); 10977 } finally { 10978 FileUtils.sync(fos); 10979 if (dos != null) { 10980 try { 10981 dos.close(); 10982 } catch (IOException e) { 10983 // TODO Auto-generated catch block 10984 e.printStackTrace(); 10985 } 10986 } 10987 } 10988 } 10989 10990 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10991 ArrayList<ComponentName> doneReceivers, int userId) { 10992 boolean waitingUpdate = false; 10993 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10994 List<ResolveInfo> ris = null; 10995 try { 10996 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10997 intent, null, 0, userId); 10998 } catch (RemoteException e) { 10999 } 11000 if (ris != null) { 11001 for (int i=ris.size()-1; i>=0; i--) { 11002 if ((ris.get(i).activityInfo.applicationInfo.flags 11003 &ApplicationInfo.FLAG_SYSTEM) == 0) { 11004 ris.remove(i); 11005 } 11006 } 11007 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 11008 11009 // For User 0, load the version number. When delivering to a new user, deliver 11010 // to all receivers. 11011 if (userId == UserHandle.USER_OWNER) { 11012 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11013 for (int i=0; i<ris.size(); i++) { 11014 ActivityInfo ai = ris.get(i).activityInfo; 11015 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11016 if (lastDoneReceivers.contains(comp)) { 11017 // We already did the pre boot receiver for this app with the current 11018 // platform version, so don't do it again... 11019 ris.remove(i); 11020 i--; 11021 // ...however, do keep it as one that has been done, so we don't 11022 // forget about it when rewriting the file of last done receivers. 11023 doneReceivers.add(comp); 11024 } 11025 } 11026 } 11027 11028 // If primary user, send broadcast to all available users, else just to userId 11029 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11030 : new int[] { userId }; 11031 for (int i = 0; i < ris.size(); i++) { 11032 ActivityInfo ai = ris.get(i).activityInfo; 11033 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11034 doneReceivers.add(comp); 11035 intent.setComponent(comp); 11036 for (int j=0; j<users.length; j++) { 11037 IIntentReceiver finisher = null; 11038 // On last receiver and user, set up a completion callback 11039 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11040 finisher = new IIntentReceiver.Stub() { 11041 public void performReceive(Intent intent, int resultCode, 11042 String data, Bundle extras, boolean ordered, 11043 boolean sticky, int sendingUser) { 11044 // The raw IIntentReceiver interface is called 11045 // with the AM lock held, so redispatch to 11046 // execute our code without the lock. 11047 mHandler.post(onFinishCallback); 11048 } 11049 }; 11050 } 11051 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11052 + " for user " + users[j]); 11053 broadcastIntentLocked(null, null, intent, null, finisher, 11054 0, null, null, null, AppOpsManager.OP_NONE, 11055 true, false, MY_PID, Process.SYSTEM_UID, 11056 users[j]); 11057 if (finisher != null) { 11058 waitingUpdate = true; 11059 } 11060 } 11061 } 11062 } 11063 11064 return waitingUpdate; 11065 } 11066 11067 public void systemReady(final Runnable goingCallback) { 11068 synchronized(this) { 11069 if (mSystemReady) { 11070 // If we're done calling all the receivers, run the next "boot phase" passed in 11071 // by the SystemServer 11072 if (goingCallback != null) { 11073 goingCallback.run(); 11074 } 11075 return; 11076 } 11077 11078 // Make sure we have the current profile info, since it is needed for 11079 // security checks. 11080 updateCurrentProfileIdsLocked(); 11081 11082 if (mRecentTasks == null) { 11083 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11084 if (!mRecentTasks.isEmpty()) { 11085 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11086 } 11087 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11088 mTaskPersister.startPersisting(); 11089 } 11090 11091 // Check to see if there are any update receivers to run. 11092 if (!mDidUpdate) { 11093 if (mWaitingUpdate) { 11094 return; 11095 } 11096 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11097 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11098 public void run() { 11099 synchronized (ActivityManagerService.this) { 11100 mDidUpdate = true; 11101 } 11102 writeLastDonePreBootReceivers(doneReceivers); 11103 showBootMessage(mContext.getText( 11104 R.string.android_upgrading_complete), 11105 false); 11106 systemReady(goingCallback); 11107 } 11108 }, doneReceivers, UserHandle.USER_OWNER); 11109 11110 if (mWaitingUpdate) { 11111 return; 11112 } 11113 mDidUpdate = true; 11114 } 11115 11116 mAppOpsService.systemReady(); 11117 mSystemReady = true; 11118 } 11119 11120 ArrayList<ProcessRecord> procsToKill = null; 11121 synchronized(mPidsSelfLocked) { 11122 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11123 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11124 if (!isAllowedWhileBooting(proc.info)){ 11125 if (procsToKill == null) { 11126 procsToKill = new ArrayList<ProcessRecord>(); 11127 } 11128 procsToKill.add(proc); 11129 } 11130 } 11131 } 11132 11133 synchronized(this) { 11134 if (procsToKill != null) { 11135 for (int i=procsToKill.size()-1; i>=0; i--) { 11136 ProcessRecord proc = procsToKill.get(i); 11137 Slog.i(TAG, "Removing system update proc: " + proc); 11138 removeProcessLocked(proc, true, false, "system update done"); 11139 } 11140 } 11141 11142 // Now that we have cleaned up any update processes, we 11143 // are ready to start launching real processes and know that 11144 // we won't trample on them any more. 11145 mProcessesReady = true; 11146 } 11147 11148 Slog.i(TAG, "System now ready"); 11149 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11150 SystemClock.uptimeMillis()); 11151 11152 synchronized(this) { 11153 // Make sure we have no pre-ready processes sitting around. 11154 11155 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11156 ResolveInfo ri = mContext.getPackageManager() 11157 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11158 STOCK_PM_FLAGS); 11159 CharSequence errorMsg = null; 11160 if (ri != null) { 11161 ActivityInfo ai = ri.activityInfo; 11162 ApplicationInfo app = ai.applicationInfo; 11163 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11164 mTopAction = Intent.ACTION_FACTORY_TEST; 11165 mTopData = null; 11166 mTopComponent = new ComponentName(app.packageName, 11167 ai.name); 11168 } else { 11169 errorMsg = mContext.getResources().getText( 11170 com.android.internal.R.string.factorytest_not_system); 11171 } 11172 } else { 11173 errorMsg = mContext.getResources().getText( 11174 com.android.internal.R.string.factorytest_no_action); 11175 } 11176 if (errorMsg != null) { 11177 mTopAction = null; 11178 mTopData = null; 11179 mTopComponent = null; 11180 Message msg = Message.obtain(); 11181 msg.what = SHOW_FACTORY_ERROR_MSG; 11182 msg.getData().putCharSequence("msg", errorMsg); 11183 mHandler.sendMessage(msg); 11184 } 11185 } 11186 } 11187 11188 retrieveSettings(); 11189 loadResourcesOnSystemReady(); 11190 11191 synchronized (this) { 11192 readGrantedUriPermissionsLocked(); 11193 } 11194 11195 if (goingCallback != null) goingCallback.run(); 11196 11197 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11198 Integer.toString(mCurrentUserId), mCurrentUserId); 11199 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11200 Integer.toString(mCurrentUserId), mCurrentUserId); 11201 mSystemServiceManager.startUser(mCurrentUserId); 11202 11203 synchronized (this) { 11204 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11205 try { 11206 List apps = AppGlobals.getPackageManager(). 11207 getPersistentApplications(STOCK_PM_FLAGS); 11208 if (apps != null) { 11209 int N = apps.size(); 11210 int i; 11211 for (i=0; i<N; i++) { 11212 ApplicationInfo info 11213 = (ApplicationInfo)apps.get(i); 11214 if (info != null && 11215 !info.packageName.equals("android")) { 11216 addAppLocked(info, false, null /* ABI override */); 11217 } 11218 } 11219 } 11220 } catch (RemoteException ex) { 11221 // pm is in same process, this will never happen. 11222 } 11223 } 11224 11225 // Start up initial activity. 11226 mBooting = true; 11227 11228 try { 11229 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11230 Message msg = Message.obtain(); 11231 msg.what = SHOW_UID_ERROR_MSG; 11232 mHandler.sendMessage(msg); 11233 } 11234 } catch (RemoteException e) { 11235 } 11236 11237 long ident = Binder.clearCallingIdentity(); 11238 try { 11239 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11240 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11241 | Intent.FLAG_RECEIVER_FOREGROUND); 11242 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11243 broadcastIntentLocked(null, null, intent, 11244 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11245 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11246 intent = new Intent(Intent.ACTION_USER_STARTING); 11247 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11248 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11249 broadcastIntentLocked(null, null, intent, 11250 null, new IIntentReceiver.Stub() { 11251 @Override 11252 public void performReceive(Intent intent, int resultCode, String data, 11253 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11254 throws RemoteException { 11255 } 11256 }, 0, null, null, 11257 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11258 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11259 } catch (Throwable t) { 11260 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11261 } finally { 11262 Binder.restoreCallingIdentity(ident); 11263 } 11264 mStackSupervisor.resumeTopActivitiesLocked(); 11265 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11266 } 11267 } 11268 11269 private boolean makeAppCrashingLocked(ProcessRecord app, 11270 String shortMsg, String longMsg, String stackTrace) { 11271 app.crashing = true; 11272 app.crashingReport = generateProcessError(app, 11273 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11274 startAppProblemLocked(app); 11275 app.stopFreezingAllLocked(); 11276 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11277 } 11278 11279 private void makeAppNotRespondingLocked(ProcessRecord app, 11280 String activity, String shortMsg, String longMsg) { 11281 app.notResponding = true; 11282 app.notRespondingReport = generateProcessError(app, 11283 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11284 activity, shortMsg, longMsg, null); 11285 startAppProblemLocked(app); 11286 app.stopFreezingAllLocked(); 11287 } 11288 11289 /** 11290 * Generate a process error record, suitable for attachment to a ProcessRecord. 11291 * 11292 * @param app The ProcessRecord in which the error occurred. 11293 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11294 * ActivityManager.AppErrorStateInfo 11295 * @param activity The activity associated with the crash, if known. 11296 * @param shortMsg Short message describing the crash. 11297 * @param longMsg Long message describing the crash. 11298 * @param stackTrace Full crash stack trace, may be null. 11299 * 11300 * @return Returns a fully-formed AppErrorStateInfo record. 11301 */ 11302 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11303 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11304 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11305 11306 report.condition = condition; 11307 report.processName = app.processName; 11308 report.pid = app.pid; 11309 report.uid = app.info.uid; 11310 report.tag = activity; 11311 report.shortMsg = shortMsg; 11312 report.longMsg = longMsg; 11313 report.stackTrace = stackTrace; 11314 11315 return report; 11316 } 11317 11318 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11319 synchronized (this) { 11320 app.crashing = false; 11321 app.crashingReport = null; 11322 app.notResponding = false; 11323 app.notRespondingReport = null; 11324 if (app.anrDialog == fromDialog) { 11325 app.anrDialog = null; 11326 } 11327 if (app.waitDialog == fromDialog) { 11328 app.waitDialog = null; 11329 } 11330 if (app.pid > 0 && app.pid != MY_PID) { 11331 handleAppCrashLocked(app, null, null, null); 11332 app.kill("user request after error", true); 11333 } 11334 } 11335 } 11336 11337 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11338 String stackTrace) { 11339 long now = SystemClock.uptimeMillis(); 11340 11341 Long crashTime; 11342 if (!app.isolated) { 11343 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11344 } else { 11345 crashTime = null; 11346 } 11347 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11348 // This process loses! 11349 Slog.w(TAG, "Process " + app.info.processName 11350 + " has crashed too many times: killing!"); 11351 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11352 app.userId, app.info.processName, app.uid); 11353 mStackSupervisor.handleAppCrashLocked(app); 11354 if (!app.persistent) { 11355 // We don't want to start this process again until the user 11356 // explicitly does so... but for persistent process, we really 11357 // need to keep it running. If a persistent process is actually 11358 // repeatedly crashing, then badness for everyone. 11359 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11360 app.info.processName); 11361 if (!app.isolated) { 11362 // XXX We don't have a way to mark isolated processes 11363 // as bad, since they don't have a peristent identity. 11364 mBadProcesses.put(app.info.processName, app.uid, 11365 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11366 mProcessCrashTimes.remove(app.info.processName, app.uid); 11367 } 11368 app.bad = true; 11369 app.removed = true; 11370 // Don't let services in this process be restarted and potentially 11371 // annoy the user repeatedly. Unless it is persistent, since those 11372 // processes run critical code. 11373 removeProcessLocked(app, false, false, "crash"); 11374 mStackSupervisor.resumeTopActivitiesLocked(); 11375 return false; 11376 } 11377 mStackSupervisor.resumeTopActivitiesLocked(); 11378 } else { 11379 mStackSupervisor.finishTopRunningActivityLocked(app); 11380 } 11381 11382 // Bump up the crash count of any services currently running in the proc. 11383 for (int i=app.services.size()-1; i>=0; i--) { 11384 // Any services running in the application need to be placed 11385 // back in the pending list. 11386 ServiceRecord sr = app.services.valueAt(i); 11387 sr.crashCount++; 11388 } 11389 11390 // If the crashing process is what we consider to be the "home process" and it has been 11391 // replaced by a third-party app, clear the package preferred activities from packages 11392 // with a home activity running in the process to prevent a repeatedly crashing app 11393 // from blocking the user to manually clear the list. 11394 final ArrayList<ActivityRecord> activities = app.activities; 11395 if (app == mHomeProcess && activities.size() > 0 11396 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11397 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11398 final ActivityRecord r = activities.get(activityNdx); 11399 if (r.isHomeActivity()) { 11400 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11401 try { 11402 ActivityThread.getPackageManager() 11403 .clearPackagePreferredActivities(r.packageName); 11404 } catch (RemoteException c) { 11405 // pm is in same process, this will never happen. 11406 } 11407 } 11408 } 11409 } 11410 11411 if (!app.isolated) { 11412 // XXX Can't keep track of crash times for isolated processes, 11413 // because they don't have a perisistent identity. 11414 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11415 } 11416 11417 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11418 return true; 11419 } 11420 11421 void startAppProblemLocked(ProcessRecord app) { 11422 // If this app is not running under the current user, then we 11423 // can't give it a report button because that would require 11424 // launching the report UI under a different user. 11425 app.errorReportReceiver = null; 11426 11427 for (int userId : mCurrentProfileIds) { 11428 if (app.userId == userId) { 11429 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11430 mContext, app.info.packageName, app.info.flags); 11431 } 11432 } 11433 skipCurrentReceiverLocked(app); 11434 } 11435 11436 void skipCurrentReceiverLocked(ProcessRecord app) { 11437 for (BroadcastQueue queue : mBroadcastQueues) { 11438 queue.skipCurrentReceiverLocked(app); 11439 } 11440 } 11441 11442 /** 11443 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11444 * The application process will exit immediately after this call returns. 11445 * @param app object of the crashing app, null for the system server 11446 * @param crashInfo describing the exception 11447 */ 11448 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11449 ProcessRecord r = findAppProcess(app, "Crash"); 11450 final String processName = app == null ? "system_server" 11451 : (r == null ? "unknown" : r.processName); 11452 11453 handleApplicationCrashInner("crash", r, processName, crashInfo); 11454 } 11455 11456 /* Native crash reporting uses this inner version because it needs to be somewhat 11457 * decoupled from the AM-managed cleanup lifecycle 11458 */ 11459 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11460 ApplicationErrorReport.CrashInfo crashInfo) { 11461 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11462 UserHandle.getUserId(Binder.getCallingUid()), processName, 11463 r == null ? -1 : r.info.flags, 11464 crashInfo.exceptionClassName, 11465 crashInfo.exceptionMessage, 11466 crashInfo.throwFileName, 11467 crashInfo.throwLineNumber); 11468 11469 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11470 11471 crashApplication(r, crashInfo); 11472 } 11473 11474 public void handleApplicationStrictModeViolation( 11475 IBinder app, 11476 int violationMask, 11477 StrictMode.ViolationInfo info) { 11478 ProcessRecord r = findAppProcess(app, "StrictMode"); 11479 if (r == null) { 11480 return; 11481 } 11482 11483 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11484 Integer stackFingerprint = info.hashCode(); 11485 boolean logIt = true; 11486 synchronized (mAlreadyLoggedViolatedStacks) { 11487 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11488 logIt = false; 11489 // TODO: sub-sample into EventLog for these, with 11490 // the info.durationMillis? Then we'd get 11491 // the relative pain numbers, without logging all 11492 // the stack traces repeatedly. We'd want to do 11493 // likewise in the client code, which also does 11494 // dup suppression, before the Binder call. 11495 } else { 11496 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11497 mAlreadyLoggedViolatedStacks.clear(); 11498 } 11499 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11500 } 11501 } 11502 if (logIt) { 11503 logStrictModeViolationToDropBox(r, info); 11504 } 11505 } 11506 11507 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11508 AppErrorResult result = new AppErrorResult(); 11509 synchronized (this) { 11510 final long origId = Binder.clearCallingIdentity(); 11511 11512 Message msg = Message.obtain(); 11513 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11514 HashMap<String, Object> data = new HashMap<String, Object>(); 11515 data.put("result", result); 11516 data.put("app", r); 11517 data.put("violationMask", violationMask); 11518 data.put("info", info); 11519 msg.obj = data; 11520 mHandler.sendMessage(msg); 11521 11522 Binder.restoreCallingIdentity(origId); 11523 } 11524 int res = result.get(); 11525 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11526 } 11527 } 11528 11529 // Depending on the policy in effect, there could be a bunch of 11530 // these in quick succession so we try to batch these together to 11531 // minimize disk writes, number of dropbox entries, and maximize 11532 // compression, by having more fewer, larger records. 11533 private void logStrictModeViolationToDropBox( 11534 ProcessRecord process, 11535 StrictMode.ViolationInfo info) { 11536 if (info == null) { 11537 return; 11538 } 11539 final boolean isSystemApp = process == null || 11540 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11541 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11542 final String processName = process == null ? "unknown" : process.processName; 11543 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11544 final DropBoxManager dbox = (DropBoxManager) 11545 mContext.getSystemService(Context.DROPBOX_SERVICE); 11546 11547 // Exit early if the dropbox isn't configured to accept this report type. 11548 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11549 11550 boolean bufferWasEmpty; 11551 boolean needsFlush; 11552 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11553 synchronized (sb) { 11554 bufferWasEmpty = sb.length() == 0; 11555 appendDropBoxProcessHeaders(process, processName, sb); 11556 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11557 sb.append("System-App: ").append(isSystemApp).append("\n"); 11558 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11559 if (info.violationNumThisLoop != 0) { 11560 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11561 } 11562 if (info.numAnimationsRunning != 0) { 11563 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11564 } 11565 if (info.broadcastIntentAction != null) { 11566 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11567 } 11568 if (info.durationMillis != -1) { 11569 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11570 } 11571 if (info.numInstances != -1) { 11572 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11573 } 11574 if (info.tags != null) { 11575 for (String tag : info.tags) { 11576 sb.append("Span-Tag: ").append(tag).append("\n"); 11577 } 11578 } 11579 sb.append("\n"); 11580 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11581 sb.append(info.crashInfo.stackTrace); 11582 } 11583 sb.append("\n"); 11584 11585 // Only buffer up to ~64k. Various logging bits truncate 11586 // things at 128k. 11587 needsFlush = (sb.length() > 64 * 1024); 11588 } 11589 11590 // Flush immediately if the buffer's grown too large, or this 11591 // is a non-system app. Non-system apps are isolated with a 11592 // different tag & policy and not batched. 11593 // 11594 // Batching is useful during internal testing with 11595 // StrictMode settings turned up high. Without batching, 11596 // thousands of separate files could be created on boot. 11597 if (!isSystemApp || needsFlush) { 11598 new Thread("Error dump: " + dropboxTag) { 11599 @Override 11600 public void run() { 11601 String report; 11602 synchronized (sb) { 11603 report = sb.toString(); 11604 sb.delete(0, sb.length()); 11605 sb.trimToSize(); 11606 } 11607 if (report.length() != 0) { 11608 dbox.addText(dropboxTag, report); 11609 } 11610 } 11611 }.start(); 11612 return; 11613 } 11614 11615 // System app batching: 11616 if (!bufferWasEmpty) { 11617 // An existing dropbox-writing thread is outstanding, so 11618 // we don't need to start it up. The existing thread will 11619 // catch the buffer appends we just did. 11620 return; 11621 } 11622 11623 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11624 // (After this point, we shouldn't access AMS internal data structures.) 11625 new Thread("Error dump: " + dropboxTag) { 11626 @Override 11627 public void run() { 11628 // 5 second sleep to let stacks arrive and be batched together 11629 try { 11630 Thread.sleep(5000); // 5 seconds 11631 } catch (InterruptedException e) {} 11632 11633 String errorReport; 11634 synchronized (mStrictModeBuffer) { 11635 errorReport = mStrictModeBuffer.toString(); 11636 if (errorReport.length() == 0) { 11637 return; 11638 } 11639 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11640 mStrictModeBuffer.trimToSize(); 11641 } 11642 dbox.addText(dropboxTag, errorReport); 11643 } 11644 }.start(); 11645 } 11646 11647 /** 11648 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11649 * @param app object of the crashing app, null for the system server 11650 * @param tag reported by the caller 11651 * @param system whether this wtf is coming from the system 11652 * @param crashInfo describing the context of the error 11653 * @return true if the process should exit immediately (WTF is fatal) 11654 */ 11655 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11656 final ApplicationErrorReport.CrashInfo crashInfo) { 11657 final ProcessRecord r = findAppProcess(app, "WTF"); 11658 final String processName = app == null ? "system_server" 11659 : (r == null ? "unknown" : r.processName); 11660 11661 EventLog.writeEvent(EventLogTags.AM_WTF, 11662 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11663 processName, 11664 r == null ? -1 : r.info.flags, 11665 tag, crashInfo.exceptionMessage); 11666 11667 if (system) { 11668 // If this is coming from the system, we could very well have low-level 11669 // system locks held, so we want to do this all asynchronously. And we 11670 // never want this to become fatal, so there is that too. 11671 mHandler.post(new Runnable() { 11672 @Override public void run() { 11673 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11674 crashInfo); 11675 } 11676 }); 11677 return false; 11678 } 11679 11680 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11681 11682 if (r != null && r.pid != Process.myPid() && 11683 Settings.Global.getInt(mContext.getContentResolver(), 11684 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11685 crashApplication(r, crashInfo); 11686 return true; 11687 } else { 11688 return false; 11689 } 11690 } 11691 11692 /** 11693 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11694 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11695 */ 11696 private ProcessRecord findAppProcess(IBinder app, String reason) { 11697 if (app == null) { 11698 return null; 11699 } 11700 11701 synchronized (this) { 11702 final int NP = mProcessNames.getMap().size(); 11703 for (int ip=0; ip<NP; ip++) { 11704 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11705 final int NA = apps.size(); 11706 for (int ia=0; ia<NA; ia++) { 11707 ProcessRecord p = apps.valueAt(ia); 11708 if (p.thread != null && p.thread.asBinder() == app) { 11709 return p; 11710 } 11711 } 11712 } 11713 11714 Slog.w(TAG, "Can't find mystery application for " + reason 11715 + " from pid=" + Binder.getCallingPid() 11716 + " uid=" + Binder.getCallingUid() + ": " + app); 11717 return null; 11718 } 11719 } 11720 11721 /** 11722 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11723 * to append various headers to the dropbox log text. 11724 */ 11725 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11726 StringBuilder sb) { 11727 // Watchdog thread ends up invoking this function (with 11728 // a null ProcessRecord) to add the stack file to dropbox. 11729 // Do not acquire a lock on this (am) in such cases, as it 11730 // could cause a potential deadlock, if and when watchdog 11731 // is invoked due to unavailability of lock on am and it 11732 // would prevent watchdog from killing system_server. 11733 if (process == null) { 11734 sb.append("Process: ").append(processName).append("\n"); 11735 return; 11736 } 11737 // Note: ProcessRecord 'process' is guarded by the service 11738 // instance. (notably process.pkgList, which could otherwise change 11739 // concurrently during execution of this method) 11740 synchronized (this) { 11741 sb.append("Process: ").append(processName).append("\n"); 11742 int flags = process.info.flags; 11743 IPackageManager pm = AppGlobals.getPackageManager(); 11744 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11745 for (int ip=0; ip<process.pkgList.size(); ip++) { 11746 String pkg = process.pkgList.keyAt(ip); 11747 sb.append("Package: ").append(pkg); 11748 try { 11749 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11750 if (pi != null) { 11751 sb.append(" v").append(pi.versionCode); 11752 if (pi.versionName != null) { 11753 sb.append(" (").append(pi.versionName).append(")"); 11754 } 11755 } 11756 } catch (RemoteException e) { 11757 Slog.e(TAG, "Error getting package info: " + pkg, e); 11758 } 11759 sb.append("\n"); 11760 } 11761 } 11762 } 11763 11764 private static String processClass(ProcessRecord process) { 11765 if (process == null || process.pid == MY_PID) { 11766 return "system_server"; 11767 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11768 return "system_app"; 11769 } else { 11770 return "data_app"; 11771 } 11772 } 11773 11774 /** 11775 * Write a description of an error (crash, WTF, ANR) to the drop box. 11776 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11777 * @param process which caused the error, null means the system server 11778 * @param activity which triggered the error, null if unknown 11779 * @param parent activity related to the error, null if unknown 11780 * @param subject line related to the error, null if absent 11781 * @param report in long form describing the error, null if absent 11782 * @param logFile to include in the report, null if none 11783 * @param crashInfo giving an application stack trace, null if absent 11784 */ 11785 public void addErrorToDropBox(String eventType, 11786 ProcessRecord process, String processName, ActivityRecord activity, 11787 ActivityRecord parent, String subject, 11788 final String report, final File logFile, 11789 final ApplicationErrorReport.CrashInfo crashInfo) { 11790 // NOTE -- this must never acquire the ActivityManagerService lock, 11791 // otherwise the watchdog may be prevented from resetting the system. 11792 11793 final String dropboxTag = processClass(process) + "_" + eventType; 11794 final DropBoxManager dbox = (DropBoxManager) 11795 mContext.getSystemService(Context.DROPBOX_SERVICE); 11796 11797 // Exit early if the dropbox isn't configured to accept this report type. 11798 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11799 11800 final StringBuilder sb = new StringBuilder(1024); 11801 appendDropBoxProcessHeaders(process, processName, sb); 11802 if (activity != null) { 11803 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11804 } 11805 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11806 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11807 } 11808 if (parent != null && parent != activity) { 11809 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11810 } 11811 if (subject != null) { 11812 sb.append("Subject: ").append(subject).append("\n"); 11813 } 11814 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11815 if (Debug.isDebuggerConnected()) { 11816 sb.append("Debugger: Connected\n"); 11817 } 11818 sb.append("\n"); 11819 11820 // Do the rest in a worker thread to avoid blocking the caller on I/O 11821 // (After this point, we shouldn't access AMS internal data structures.) 11822 Thread worker = new Thread("Error dump: " + dropboxTag) { 11823 @Override 11824 public void run() { 11825 if (report != null) { 11826 sb.append(report); 11827 } 11828 if (logFile != null) { 11829 try { 11830 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11831 "\n\n[[TRUNCATED]]")); 11832 } catch (IOException e) { 11833 Slog.e(TAG, "Error reading " + logFile, e); 11834 } 11835 } 11836 if (crashInfo != null && crashInfo.stackTrace != null) { 11837 sb.append(crashInfo.stackTrace); 11838 } 11839 11840 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11841 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11842 if (lines > 0) { 11843 sb.append("\n"); 11844 11845 // Merge several logcat streams, and take the last N lines 11846 InputStreamReader input = null; 11847 try { 11848 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11849 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11850 "-b", "crash", 11851 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11852 11853 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11854 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11855 input = new InputStreamReader(logcat.getInputStream()); 11856 11857 int num; 11858 char[] buf = new char[8192]; 11859 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11860 } catch (IOException e) { 11861 Slog.e(TAG, "Error running logcat", e); 11862 } finally { 11863 if (input != null) try { input.close(); } catch (IOException e) {} 11864 } 11865 } 11866 11867 dbox.addText(dropboxTag, sb.toString()); 11868 } 11869 }; 11870 11871 if (process == null) { 11872 // If process is null, we are being called from some internal code 11873 // and may be about to die -- run this synchronously. 11874 worker.run(); 11875 } else { 11876 worker.start(); 11877 } 11878 } 11879 11880 /** 11881 * Bring up the "unexpected error" dialog box for a crashing app. 11882 * Deal with edge cases (intercepts from instrumented applications, 11883 * ActivityController, error intent receivers, that sort of thing). 11884 * @param r the application crashing 11885 * @param crashInfo describing the failure 11886 */ 11887 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11888 long timeMillis = System.currentTimeMillis(); 11889 String shortMsg = crashInfo.exceptionClassName; 11890 String longMsg = crashInfo.exceptionMessage; 11891 String stackTrace = crashInfo.stackTrace; 11892 if (shortMsg != null && longMsg != null) { 11893 longMsg = shortMsg + ": " + longMsg; 11894 } else if (shortMsg != null) { 11895 longMsg = shortMsg; 11896 } 11897 11898 AppErrorResult result = new AppErrorResult(); 11899 synchronized (this) { 11900 if (mController != null) { 11901 try { 11902 String name = r != null ? r.processName : null; 11903 int pid = r != null ? r.pid : Binder.getCallingPid(); 11904 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11905 if (!mController.appCrashed(name, pid, 11906 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11907 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11908 && "Native crash".equals(crashInfo.exceptionClassName)) { 11909 Slog.w(TAG, "Skip killing native crashed app " + name 11910 + "(" + pid + ") during testing"); 11911 } else { 11912 Slog.w(TAG, "Force-killing crashed app " + name 11913 + " at watcher's request"); 11914 if (r != null) { 11915 r.kill("crash", true); 11916 } else { 11917 // Huh. 11918 Process.killProcess(pid); 11919 Process.killProcessGroup(uid, pid); 11920 } 11921 } 11922 return; 11923 } 11924 } catch (RemoteException e) { 11925 mController = null; 11926 Watchdog.getInstance().setActivityController(null); 11927 } 11928 } 11929 11930 final long origId = Binder.clearCallingIdentity(); 11931 11932 // If this process is running instrumentation, finish it. 11933 if (r != null && r.instrumentationClass != null) { 11934 Slog.w(TAG, "Error in app " + r.processName 11935 + " running instrumentation " + r.instrumentationClass + ":"); 11936 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11937 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11938 Bundle info = new Bundle(); 11939 info.putString("shortMsg", shortMsg); 11940 info.putString("longMsg", longMsg); 11941 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11942 Binder.restoreCallingIdentity(origId); 11943 return; 11944 } 11945 11946 // If we can't identify the process or it's already exceeded its crash quota, 11947 // quit right away without showing a crash dialog. 11948 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11949 Binder.restoreCallingIdentity(origId); 11950 return; 11951 } 11952 11953 Message msg = Message.obtain(); 11954 msg.what = SHOW_ERROR_MSG; 11955 HashMap data = new HashMap(); 11956 data.put("result", result); 11957 data.put("app", r); 11958 msg.obj = data; 11959 mHandler.sendMessage(msg); 11960 11961 Binder.restoreCallingIdentity(origId); 11962 } 11963 11964 int res = result.get(); 11965 11966 Intent appErrorIntent = null; 11967 synchronized (this) { 11968 if (r != null && !r.isolated) { 11969 // XXX Can't keep track of crash time for isolated processes, 11970 // since they don't have a persistent identity. 11971 mProcessCrashTimes.put(r.info.processName, r.uid, 11972 SystemClock.uptimeMillis()); 11973 } 11974 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11975 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11976 } 11977 } 11978 11979 if (appErrorIntent != null) { 11980 try { 11981 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11982 } catch (ActivityNotFoundException e) { 11983 Slog.w(TAG, "bug report receiver dissappeared", e); 11984 } 11985 } 11986 } 11987 11988 Intent createAppErrorIntentLocked(ProcessRecord r, 11989 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11990 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11991 if (report == null) { 11992 return null; 11993 } 11994 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11995 result.setComponent(r.errorReportReceiver); 11996 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11997 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11998 return result; 11999 } 12000 12001 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 12002 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 12003 if (r.errorReportReceiver == null) { 12004 return null; 12005 } 12006 12007 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 12008 return null; 12009 } 12010 12011 ApplicationErrorReport report = new ApplicationErrorReport(); 12012 report.packageName = r.info.packageName; 12013 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12014 report.processName = r.processName; 12015 report.time = timeMillis; 12016 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12017 12018 if (r.crashing || r.forceCrashReport) { 12019 report.type = ApplicationErrorReport.TYPE_CRASH; 12020 report.crashInfo = crashInfo; 12021 } else if (r.notResponding) { 12022 report.type = ApplicationErrorReport.TYPE_ANR; 12023 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12024 12025 report.anrInfo.activity = r.notRespondingReport.tag; 12026 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12027 report.anrInfo.info = r.notRespondingReport.longMsg; 12028 } 12029 12030 return report; 12031 } 12032 12033 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12034 enforceNotIsolatedCaller("getProcessesInErrorState"); 12035 // assume our apps are happy - lazy create the list 12036 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12037 12038 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12039 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12040 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12041 12042 synchronized (this) { 12043 12044 // iterate across all processes 12045 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12046 ProcessRecord app = mLruProcesses.get(i); 12047 if (!allUsers && app.userId != userId) { 12048 continue; 12049 } 12050 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12051 // This one's in trouble, so we'll generate a report for it 12052 // crashes are higher priority (in case there's a crash *and* an anr) 12053 ActivityManager.ProcessErrorStateInfo report = null; 12054 if (app.crashing) { 12055 report = app.crashingReport; 12056 } else if (app.notResponding) { 12057 report = app.notRespondingReport; 12058 } 12059 12060 if (report != null) { 12061 if (errList == null) { 12062 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12063 } 12064 errList.add(report); 12065 } else { 12066 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12067 " crashing = " + app.crashing + 12068 " notResponding = " + app.notResponding); 12069 } 12070 } 12071 } 12072 } 12073 12074 return errList; 12075 } 12076 12077 static int procStateToImportance(int procState, int memAdj, 12078 ActivityManager.RunningAppProcessInfo currApp) { 12079 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12080 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12081 currApp.lru = memAdj; 12082 } else { 12083 currApp.lru = 0; 12084 } 12085 return imp; 12086 } 12087 12088 private void fillInProcMemInfo(ProcessRecord app, 12089 ActivityManager.RunningAppProcessInfo outInfo) { 12090 outInfo.pid = app.pid; 12091 outInfo.uid = app.info.uid; 12092 if (mHeavyWeightProcess == app) { 12093 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12094 } 12095 if (app.persistent) { 12096 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12097 } 12098 if (app.activities.size() > 0) { 12099 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12100 } 12101 outInfo.lastTrimLevel = app.trimMemoryLevel; 12102 int adj = app.curAdj; 12103 int procState = app.curProcState; 12104 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12105 outInfo.importanceReasonCode = app.adjTypeCode; 12106 outInfo.processState = app.curProcState; 12107 } 12108 12109 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12110 enforceNotIsolatedCaller("getRunningAppProcesses"); 12111 // Lazy instantiation of list 12112 List<ActivityManager.RunningAppProcessInfo> runList = null; 12113 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12114 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12115 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12116 synchronized (this) { 12117 // Iterate across all processes 12118 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12119 ProcessRecord app = mLruProcesses.get(i); 12120 if (!allUsers && app.userId != userId) { 12121 continue; 12122 } 12123 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12124 // Generate process state info for running application 12125 ActivityManager.RunningAppProcessInfo currApp = 12126 new ActivityManager.RunningAppProcessInfo(app.processName, 12127 app.pid, app.getPackageList()); 12128 fillInProcMemInfo(app, currApp); 12129 if (app.adjSource instanceof ProcessRecord) { 12130 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12131 currApp.importanceReasonImportance = 12132 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12133 app.adjSourceProcState); 12134 } else if (app.adjSource instanceof ActivityRecord) { 12135 ActivityRecord r = (ActivityRecord)app.adjSource; 12136 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12137 } 12138 if (app.adjTarget instanceof ComponentName) { 12139 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12140 } 12141 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12142 // + " lru=" + currApp.lru); 12143 if (runList == null) { 12144 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12145 } 12146 runList.add(currApp); 12147 } 12148 } 12149 } 12150 return runList; 12151 } 12152 12153 public List<ApplicationInfo> getRunningExternalApplications() { 12154 enforceNotIsolatedCaller("getRunningExternalApplications"); 12155 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12156 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12157 if (runningApps != null && runningApps.size() > 0) { 12158 Set<String> extList = new HashSet<String>(); 12159 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12160 if (app.pkgList != null) { 12161 for (String pkg : app.pkgList) { 12162 extList.add(pkg); 12163 } 12164 } 12165 } 12166 IPackageManager pm = AppGlobals.getPackageManager(); 12167 for (String pkg : extList) { 12168 try { 12169 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12170 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12171 retList.add(info); 12172 } 12173 } catch (RemoteException e) { 12174 } 12175 } 12176 } 12177 return retList; 12178 } 12179 12180 @Override 12181 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12182 enforceNotIsolatedCaller("getMyMemoryState"); 12183 synchronized (this) { 12184 ProcessRecord proc; 12185 synchronized (mPidsSelfLocked) { 12186 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12187 } 12188 fillInProcMemInfo(proc, outInfo); 12189 } 12190 } 12191 12192 @Override 12193 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12194 if (checkCallingPermission(android.Manifest.permission.DUMP) 12195 != PackageManager.PERMISSION_GRANTED) { 12196 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12197 + Binder.getCallingPid() 12198 + ", uid=" + Binder.getCallingUid() 12199 + " without permission " 12200 + android.Manifest.permission.DUMP); 12201 return; 12202 } 12203 12204 boolean dumpAll = false; 12205 boolean dumpClient = false; 12206 String dumpPackage = null; 12207 12208 int opti = 0; 12209 while (opti < args.length) { 12210 String opt = args[opti]; 12211 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12212 break; 12213 } 12214 opti++; 12215 if ("-a".equals(opt)) { 12216 dumpAll = true; 12217 } else if ("-c".equals(opt)) { 12218 dumpClient = true; 12219 } else if ("-h".equals(opt)) { 12220 pw.println("Activity manager dump options:"); 12221 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12222 pw.println(" cmd may be one of:"); 12223 pw.println(" a[ctivities]: activity stack state"); 12224 pw.println(" r[recents]: recent activities state"); 12225 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12226 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12227 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12228 pw.println(" o[om]: out of memory management"); 12229 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12230 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12231 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12232 pw.println(" service [COMP_SPEC]: service client-side state"); 12233 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12234 pw.println(" all: dump all activities"); 12235 pw.println(" top: dump the top activity"); 12236 pw.println(" write: write all pending state to storage"); 12237 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12238 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12239 pw.println(" a partial substring in a component name, a"); 12240 pw.println(" hex object identifier."); 12241 pw.println(" -a: include all available server state."); 12242 pw.println(" -c: include client state."); 12243 return; 12244 } else { 12245 pw.println("Unknown argument: " + opt + "; use -h for help"); 12246 } 12247 } 12248 12249 long origId = Binder.clearCallingIdentity(); 12250 boolean more = false; 12251 // Is the caller requesting to dump a particular piece of data? 12252 if (opti < args.length) { 12253 String cmd = args[opti]; 12254 opti++; 12255 if ("activities".equals(cmd) || "a".equals(cmd)) { 12256 synchronized (this) { 12257 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12258 } 12259 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12260 synchronized (this) { 12261 dumpRecentsLocked(fd, pw, args, opti, true, null); 12262 } 12263 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12264 String[] newArgs; 12265 String name; 12266 if (opti >= args.length) { 12267 name = null; 12268 newArgs = EMPTY_STRING_ARRAY; 12269 } else { 12270 name = args[opti]; 12271 opti++; 12272 newArgs = new String[args.length - opti]; 12273 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12274 args.length - opti); 12275 } 12276 synchronized (this) { 12277 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12278 } 12279 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12280 String[] newArgs; 12281 String name; 12282 if (opti >= args.length) { 12283 name = null; 12284 newArgs = EMPTY_STRING_ARRAY; 12285 } else { 12286 name = args[opti]; 12287 opti++; 12288 newArgs = new String[args.length - opti]; 12289 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12290 args.length - opti); 12291 } 12292 synchronized (this) { 12293 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12294 } 12295 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12296 String[] newArgs; 12297 String name; 12298 if (opti >= args.length) { 12299 name = null; 12300 newArgs = EMPTY_STRING_ARRAY; 12301 } else { 12302 name = args[opti]; 12303 opti++; 12304 newArgs = new String[args.length - opti]; 12305 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12306 args.length - opti); 12307 } 12308 synchronized (this) { 12309 dumpProcessesLocked(fd, pw, args, opti, true, name); 12310 } 12311 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12312 synchronized (this) { 12313 dumpOomLocked(fd, pw, args, opti, true); 12314 } 12315 } else if ("provider".equals(cmd)) { 12316 String[] newArgs; 12317 String name; 12318 if (opti >= args.length) { 12319 name = null; 12320 newArgs = EMPTY_STRING_ARRAY; 12321 } else { 12322 name = args[opti]; 12323 opti++; 12324 newArgs = new String[args.length - opti]; 12325 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12326 } 12327 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12328 pw.println("No providers match: " + name); 12329 pw.println("Use -h for help."); 12330 } 12331 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12332 synchronized (this) { 12333 dumpProvidersLocked(fd, pw, args, opti, true, null); 12334 } 12335 } else if ("service".equals(cmd)) { 12336 String[] newArgs; 12337 String name; 12338 if (opti >= args.length) { 12339 name = null; 12340 newArgs = EMPTY_STRING_ARRAY; 12341 } else { 12342 name = args[opti]; 12343 opti++; 12344 newArgs = new String[args.length - opti]; 12345 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12346 args.length - opti); 12347 } 12348 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12349 pw.println("No services match: " + name); 12350 pw.println("Use -h for help."); 12351 } 12352 } else if ("package".equals(cmd)) { 12353 String[] newArgs; 12354 if (opti >= args.length) { 12355 pw.println("package: no package name specified"); 12356 pw.println("Use -h for help."); 12357 } else { 12358 dumpPackage = args[opti]; 12359 opti++; 12360 newArgs = new String[args.length - opti]; 12361 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12362 args.length - opti); 12363 args = newArgs; 12364 opti = 0; 12365 more = true; 12366 } 12367 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12368 synchronized (this) { 12369 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12370 } 12371 } else if ("write".equals(cmd)) { 12372 mTaskPersister.flush(); 12373 pw.println("All tasks persisted."); 12374 return; 12375 } else { 12376 // Dumping a single activity? 12377 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12378 pw.println("Bad activity command, or no activities match: " + cmd); 12379 pw.println("Use -h for help."); 12380 } 12381 } 12382 if (!more) { 12383 Binder.restoreCallingIdentity(origId); 12384 return; 12385 } 12386 } 12387 12388 // No piece of data specified, dump everything. 12389 synchronized (this) { 12390 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12391 pw.println(); 12392 if (dumpAll) { 12393 pw.println("-------------------------------------------------------------------------------"); 12394 } 12395 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12396 pw.println(); 12397 if (dumpAll) { 12398 pw.println("-------------------------------------------------------------------------------"); 12399 } 12400 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12401 pw.println(); 12402 if (dumpAll) { 12403 pw.println("-------------------------------------------------------------------------------"); 12404 } 12405 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12406 pw.println(); 12407 if (dumpAll) { 12408 pw.println("-------------------------------------------------------------------------------"); 12409 } 12410 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12411 pw.println(); 12412 if (dumpAll) { 12413 pw.println("-------------------------------------------------------------------------------"); 12414 } 12415 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12416 pw.println(); 12417 if (dumpAll) { 12418 pw.println("-------------------------------------------------------------------------------"); 12419 } 12420 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12421 } 12422 Binder.restoreCallingIdentity(origId); 12423 } 12424 12425 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12426 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12427 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12428 12429 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12430 dumpPackage); 12431 boolean needSep = printedAnything; 12432 12433 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12434 dumpPackage, needSep, " mFocusedActivity: "); 12435 if (printed) { 12436 printedAnything = true; 12437 needSep = false; 12438 } 12439 12440 if (dumpPackage == null) { 12441 if (needSep) { 12442 pw.println(); 12443 } 12444 needSep = true; 12445 printedAnything = true; 12446 mStackSupervisor.dump(pw, " "); 12447 } 12448 12449 if (!printedAnything) { 12450 pw.println(" (nothing)"); 12451 } 12452 } 12453 12454 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12455 int opti, boolean dumpAll, String dumpPackage) { 12456 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12457 12458 boolean printedAnything = false; 12459 12460 if (mRecentTasks.size() > 0) { 12461 boolean printedHeader = false; 12462 12463 final int N = mRecentTasks.size(); 12464 for (int i=0; i<N; i++) { 12465 TaskRecord tr = mRecentTasks.get(i); 12466 if (dumpPackage != null) { 12467 if (tr.realActivity == null || 12468 !dumpPackage.equals(tr.realActivity)) { 12469 continue; 12470 } 12471 } 12472 if (!printedHeader) { 12473 pw.println(" Recent tasks:"); 12474 printedHeader = true; 12475 printedAnything = true; 12476 } 12477 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12478 pw.println(tr); 12479 if (dumpAll) { 12480 mRecentTasks.get(i).dump(pw, " "); 12481 } 12482 } 12483 } 12484 12485 if (!printedAnything) { 12486 pw.println(" (nothing)"); 12487 } 12488 } 12489 12490 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12491 int opti, boolean dumpAll, String dumpPackage) { 12492 boolean needSep = false; 12493 boolean printedAnything = false; 12494 int numPers = 0; 12495 12496 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12497 12498 if (dumpAll) { 12499 final int NP = mProcessNames.getMap().size(); 12500 for (int ip=0; ip<NP; ip++) { 12501 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12502 final int NA = procs.size(); 12503 for (int ia=0; ia<NA; ia++) { 12504 ProcessRecord r = procs.valueAt(ia); 12505 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12506 continue; 12507 } 12508 if (!needSep) { 12509 pw.println(" All known processes:"); 12510 needSep = true; 12511 printedAnything = true; 12512 } 12513 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12514 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12515 pw.print(" "); pw.println(r); 12516 r.dump(pw, " "); 12517 if (r.persistent) { 12518 numPers++; 12519 } 12520 } 12521 } 12522 } 12523 12524 if (mIsolatedProcesses.size() > 0) { 12525 boolean printed = false; 12526 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12527 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12528 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12529 continue; 12530 } 12531 if (!printed) { 12532 if (needSep) { 12533 pw.println(); 12534 } 12535 pw.println(" Isolated process list (sorted by uid):"); 12536 printedAnything = true; 12537 printed = true; 12538 needSep = true; 12539 } 12540 pw.println(String.format("%sIsolated #%2d: %s", 12541 " ", i, r.toString())); 12542 } 12543 } 12544 12545 if (mLruProcesses.size() > 0) { 12546 if (needSep) { 12547 pw.println(); 12548 } 12549 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12550 pw.print(" total, non-act at "); 12551 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12552 pw.print(", non-svc at "); 12553 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12554 pw.println("):"); 12555 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12556 needSep = true; 12557 printedAnything = true; 12558 } 12559 12560 if (dumpAll || dumpPackage != null) { 12561 synchronized (mPidsSelfLocked) { 12562 boolean printed = false; 12563 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12564 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12565 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12566 continue; 12567 } 12568 if (!printed) { 12569 if (needSep) pw.println(); 12570 needSep = true; 12571 pw.println(" PID mappings:"); 12572 printed = true; 12573 printedAnything = true; 12574 } 12575 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12576 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12577 } 12578 } 12579 } 12580 12581 if (mForegroundProcesses.size() > 0) { 12582 synchronized (mPidsSelfLocked) { 12583 boolean printed = false; 12584 for (int i=0; i<mForegroundProcesses.size(); i++) { 12585 ProcessRecord r = mPidsSelfLocked.get( 12586 mForegroundProcesses.valueAt(i).pid); 12587 if (dumpPackage != null && (r == null 12588 || !r.pkgList.containsKey(dumpPackage))) { 12589 continue; 12590 } 12591 if (!printed) { 12592 if (needSep) pw.println(); 12593 needSep = true; 12594 pw.println(" Foreground Processes:"); 12595 printed = true; 12596 printedAnything = true; 12597 } 12598 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12599 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12600 } 12601 } 12602 } 12603 12604 if (mPersistentStartingProcesses.size() > 0) { 12605 if (needSep) pw.println(); 12606 needSep = true; 12607 printedAnything = true; 12608 pw.println(" Persisent processes that are starting:"); 12609 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12610 "Starting Norm", "Restarting PERS", dumpPackage); 12611 } 12612 12613 if (mRemovedProcesses.size() > 0) { 12614 if (needSep) pw.println(); 12615 needSep = true; 12616 printedAnything = true; 12617 pw.println(" Processes that are being removed:"); 12618 dumpProcessList(pw, this, mRemovedProcesses, " ", 12619 "Removed Norm", "Removed PERS", dumpPackage); 12620 } 12621 12622 if (mProcessesOnHold.size() > 0) { 12623 if (needSep) pw.println(); 12624 needSep = true; 12625 printedAnything = true; 12626 pw.println(" Processes that are on old until the system is ready:"); 12627 dumpProcessList(pw, this, mProcessesOnHold, " ", 12628 "OnHold Norm", "OnHold PERS", dumpPackage); 12629 } 12630 12631 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12632 12633 if (mProcessCrashTimes.getMap().size() > 0) { 12634 boolean printed = false; 12635 long now = SystemClock.uptimeMillis(); 12636 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12637 final int NP = pmap.size(); 12638 for (int ip=0; ip<NP; ip++) { 12639 String pname = pmap.keyAt(ip); 12640 SparseArray<Long> uids = pmap.valueAt(ip); 12641 final int N = uids.size(); 12642 for (int i=0; i<N; i++) { 12643 int puid = uids.keyAt(i); 12644 ProcessRecord r = mProcessNames.get(pname, puid); 12645 if (dumpPackage != null && (r == null 12646 || !r.pkgList.containsKey(dumpPackage))) { 12647 continue; 12648 } 12649 if (!printed) { 12650 if (needSep) pw.println(); 12651 needSep = true; 12652 pw.println(" Time since processes crashed:"); 12653 printed = true; 12654 printedAnything = true; 12655 } 12656 pw.print(" Process "); pw.print(pname); 12657 pw.print(" uid "); pw.print(puid); 12658 pw.print(": last crashed "); 12659 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12660 pw.println(" ago"); 12661 } 12662 } 12663 } 12664 12665 if (mBadProcesses.getMap().size() > 0) { 12666 boolean printed = false; 12667 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12668 final int NP = pmap.size(); 12669 for (int ip=0; ip<NP; ip++) { 12670 String pname = pmap.keyAt(ip); 12671 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12672 final int N = uids.size(); 12673 for (int i=0; i<N; i++) { 12674 int puid = uids.keyAt(i); 12675 ProcessRecord r = mProcessNames.get(pname, puid); 12676 if (dumpPackage != null && (r == null 12677 || !r.pkgList.containsKey(dumpPackage))) { 12678 continue; 12679 } 12680 if (!printed) { 12681 if (needSep) pw.println(); 12682 needSep = true; 12683 pw.println(" Bad processes:"); 12684 printedAnything = true; 12685 } 12686 BadProcessInfo info = uids.valueAt(i); 12687 pw.print(" Bad process "); pw.print(pname); 12688 pw.print(" uid "); pw.print(puid); 12689 pw.print(": crashed at time "); pw.println(info.time); 12690 if (info.shortMsg != null) { 12691 pw.print(" Short msg: "); pw.println(info.shortMsg); 12692 } 12693 if (info.longMsg != null) { 12694 pw.print(" Long msg: "); pw.println(info.longMsg); 12695 } 12696 if (info.stack != null) { 12697 pw.println(" Stack:"); 12698 int lastPos = 0; 12699 for (int pos=0; pos<info.stack.length(); pos++) { 12700 if (info.stack.charAt(pos) == '\n') { 12701 pw.print(" "); 12702 pw.write(info.stack, lastPos, pos-lastPos); 12703 pw.println(); 12704 lastPos = pos+1; 12705 } 12706 } 12707 if (lastPos < info.stack.length()) { 12708 pw.print(" "); 12709 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12710 pw.println(); 12711 } 12712 } 12713 } 12714 } 12715 } 12716 12717 if (dumpPackage == null) { 12718 pw.println(); 12719 needSep = false; 12720 pw.println(" mStartedUsers:"); 12721 for (int i=0; i<mStartedUsers.size(); i++) { 12722 UserStartedState uss = mStartedUsers.valueAt(i); 12723 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12724 pw.print(": "); uss.dump("", pw); 12725 } 12726 pw.print(" mStartedUserArray: ["); 12727 for (int i=0; i<mStartedUserArray.length; i++) { 12728 if (i > 0) pw.print(", "); 12729 pw.print(mStartedUserArray[i]); 12730 } 12731 pw.println("]"); 12732 pw.print(" mUserLru: ["); 12733 for (int i=0; i<mUserLru.size(); i++) { 12734 if (i > 0) pw.print(", "); 12735 pw.print(mUserLru.get(i)); 12736 } 12737 pw.println("]"); 12738 if (dumpAll) { 12739 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12740 } 12741 synchronized (mUserProfileGroupIdsSelfLocked) { 12742 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12743 pw.println(" mUserProfileGroupIds:"); 12744 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12745 pw.print(" User #"); 12746 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12747 pw.print(" -> profile #"); 12748 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12749 } 12750 } 12751 } 12752 } 12753 if (mHomeProcess != null && (dumpPackage == null 12754 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12755 if (needSep) { 12756 pw.println(); 12757 needSep = false; 12758 } 12759 pw.println(" mHomeProcess: " + mHomeProcess); 12760 } 12761 if (mPreviousProcess != null && (dumpPackage == null 12762 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12763 if (needSep) { 12764 pw.println(); 12765 needSep = false; 12766 } 12767 pw.println(" mPreviousProcess: " + mPreviousProcess); 12768 } 12769 if (dumpAll) { 12770 StringBuilder sb = new StringBuilder(128); 12771 sb.append(" mPreviousProcessVisibleTime: "); 12772 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12773 pw.println(sb); 12774 } 12775 if (mHeavyWeightProcess != null && (dumpPackage == null 12776 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12777 if (needSep) { 12778 pw.println(); 12779 needSep = false; 12780 } 12781 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12782 } 12783 if (dumpPackage == null) { 12784 pw.println(" mConfiguration: " + mConfiguration); 12785 } 12786 if (dumpAll) { 12787 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12788 if (mCompatModePackages.getPackages().size() > 0) { 12789 boolean printed = false; 12790 for (Map.Entry<String, Integer> entry 12791 : mCompatModePackages.getPackages().entrySet()) { 12792 String pkg = entry.getKey(); 12793 int mode = entry.getValue(); 12794 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12795 continue; 12796 } 12797 if (!printed) { 12798 pw.println(" mScreenCompatPackages:"); 12799 printed = true; 12800 } 12801 pw.print(" "); pw.print(pkg); pw.print(": "); 12802 pw.print(mode); pw.println(); 12803 } 12804 } 12805 } 12806 if (dumpPackage == null) { 12807 if (mSleeping || mWentToSleep || mLockScreenShown) { 12808 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12809 + " mLockScreenShown " + mLockScreenShown); 12810 } 12811 if (mShuttingDown || mRunningVoice) { 12812 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12813 } 12814 } 12815 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12816 || mOrigWaitForDebugger) { 12817 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12818 || dumpPackage.equals(mOrigDebugApp)) { 12819 if (needSep) { 12820 pw.println(); 12821 needSep = false; 12822 } 12823 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12824 + " mDebugTransient=" + mDebugTransient 12825 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12826 } 12827 } 12828 if (mOpenGlTraceApp != null) { 12829 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12830 if (needSep) { 12831 pw.println(); 12832 needSep = false; 12833 } 12834 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12835 } 12836 } 12837 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12838 || mProfileFd != null) { 12839 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12840 if (needSep) { 12841 pw.println(); 12842 needSep = false; 12843 } 12844 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12845 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12846 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12847 + mAutoStopProfiler); 12848 pw.println(" mProfileType=" + mProfileType); 12849 } 12850 } 12851 if (dumpPackage == null) { 12852 if (mAlwaysFinishActivities || mController != null) { 12853 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12854 + " mController=" + mController); 12855 } 12856 if (dumpAll) { 12857 pw.println(" Total persistent processes: " + numPers); 12858 pw.println(" mProcessesReady=" + mProcessesReady 12859 + " mSystemReady=" + mSystemReady); 12860 pw.println(" mBooting=" + mBooting 12861 + " mBooted=" + mBooted 12862 + " mFactoryTest=" + mFactoryTest); 12863 pw.print(" mLastPowerCheckRealtime="); 12864 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12865 pw.println(""); 12866 pw.print(" mLastPowerCheckUptime="); 12867 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12868 pw.println(""); 12869 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12870 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12871 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12872 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12873 + " (" + mLruProcesses.size() + " total)" 12874 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12875 + " mNumServiceProcs=" + mNumServiceProcs 12876 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12877 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12878 + " mLastMemoryLevel" + mLastMemoryLevel 12879 + " mLastNumProcesses" + mLastNumProcesses); 12880 long now = SystemClock.uptimeMillis(); 12881 pw.print(" mLastIdleTime="); 12882 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12883 pw.print(" mLowRamSinceLastIdle="); 12884 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12885 pw.println(); 12886 } 12887 } 12888 12889 if (!printedAnything) { 12890 pw.println(" (nothing)"); 12891 } 12892 } 12893 12894 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12895 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12896 if (mProcessesToGc.size() > 0) { 12897 boolean printed = false; 12898 long now = SystemClock.uptimeMillis(); 12899 for (int i=0; i<mProcessesToGc.size(); i++) { 12900 ProcessRecord proc = mProcessesToGc.get(i); 12901 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12902 continue; 12903 } 12904 if (!printed) { 12905 if (needSep) pw.println(); 12906 needSep = true; 12907 pw.println(" Processes that are waiting to GC:"); 12908 printed = true; 12909 } 12910 pw.print(" Process "); pw.println(proc); 12911 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12912 pw.print(", last gced="); 12913 pw.print(now-proc.lastRequestedGc); 12914 pw.print(" ms ago, last lowMem="); 12915 pw.print(now-proc.lastLowMemory); 12916 pw.println(" ms ago"); 12917 12918 } 12919 } 12920 return needSep; 12921 } 12922 12923 void printOomLevel(PrintWriter pw, String name, int adj) { 12924 pw.print(" "); 12925 if (adj >= 0) { 12926 pw.print(' '); 12927 if (adj < 10) pw.print(' '); 12928 } else { 12929 if (adj > -10) pw.print(' '); 12930 } 12931 pw.print(adj); 12932 pw.print(": "); 12933 pw.print(name); 12934 pw.print(" ("); 12935 pw.print(mProcessList.getMemLevel(adj)/1024); 12936 pw.println(" kB)"); 12937 } 12938 12939 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12940 int opti, boolean dumpAll) { 12941 boolean needSep = false; 12942 12943 if (mLruProcesses.size() > 0) { 12944 if (needSep) pw.println(); 12945 needSep = true; 12946 pw.println(" OOM levels:"); 12947 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12948 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12949 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12950 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12951 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12952 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12953 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12954 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12955 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12956 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12957 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12958 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12959 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12960 12961 if (needSep) pw.println(); 12962 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12963 pw.print(" total, non-act at "); 12964 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12965 pw.print(", non-svc at "); 12966 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12967 pw.println("):"); 12968 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12969 needSep = true; 12970 } 12971 12972 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12973 12974 pw.println(); 12975 pw.println(" mHomeProcess: " + mHomeProcess); 12976 pw.println(" mPreviousProcess: " + mPreviousProcess); 12977 if (mHeavyWeightProcess != null) { 12978 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12979 } 12980 12981 return true; 12982 } 12983 12984 /** 12985 * There are three ways to call this: 12986 * - no provider specified: dump all the providers 12987 * - a flattened component name that matched an existing provider was specified as the 12988 * first arg: dump that one provider 12989 * - the first arg isn't the flattened component name of an existing provider: 12990 * dump all providers whose component contains the first arg as a substring 12991 */ 12992 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12993 int opti, boolean dumpAll) { 12994 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12995 } 12996 12997 static class ItemMatcher { 12998 ArrayList<ComponentName> components; 12999 ArrayList<String> strings; 13000 ArrayList<Integer> objects; 13001 boolean all; 13002 13003 ItemMatcher() { 13004 all = true; 13005 } 13006 13007 void build(String name) { 13008 ComponentName componentName = ComponentName.unflattenFromString(name); 13009 if (componentName != null) { 13010 if (components == null) { 13011 components = new ArrayList<ComponentName>(); 13012 } 13013 components.add(componentName); 13014 all = false; 13015 } else { 13016 int objectId = 0; 13017 // Not a '/' separated full component name; maybe an object ID? 13018 try { 13019 objectId = Integer.parseInt(name, 16); 13020 if (objects == null) { 13021 objects = new ArrayList<Integer>(); 13022 } 13023 objects.add(objectId); 13024 all = false; 13025 } catch (RuntimeException e) { 13026 // Not an integer; just do string match. 13027 if (strings == null) { 13028 strings = new ArrayList<String>(); 13029 } 13030 strings.add(name); 13031 all = false; 13032 } 13033 } 13034 } 13035 13036 int build(String[] args, int opti) { 13037 for (; opti<args.length; opti++) { 13038 String name = args[opti]; 13039 if ("--".equals(name)) { 13040 return opti+1; 13041 } 13042 build(name); 13043 } 13044 return opti; 13045 } 13046 13047 boolean match(Object object, ComponentName comp) { 13048 if (all) { 13049 return true; 13050 } 13051 if (components != null) { 13052 for (int i=0; i<components.size(); i++) { 13053 if (components.get(i).equals(comp)) { 13054 return true; 13055 } 13056 } 13057 } 13058 if (objects != null) { 13059 for (int i=0; i<objects.size(); i++) { 13060 if (System.identityHashCode(object) == objects.get(i)) { 13061 return true; 13062 } 13063 } 13064 } 13065 if (strings != null) { 13066 String flat = comp.flattenToString(); 13067 for (int i=0; i<strings.size(); i++) { 13068 if (flat.contains(strings.get(i))) { 13069 return true; 13070 } 13071 } 13072 } 13073 return false; 13074 } 13075 } 13076 13077 /** 13078 * There are three things that cmd can be: 13079 * - a flattened component name that matches an existing activity 13080 * - the cmd arg isn't the flattened component name of an existing activity: 13081 * dump all activity whose component contains the cmd as a substring 13082 * - A hex number of the ActivityRecord object instance. 13083 */ 13084 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13085 int opti, boolean dumpAll) { 13086 ArrayList<ActivityRecord> activities; 13087 13088 synchronized (this) { 13089 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13090 } 13091 13092 if (activities.size() <= 0) { 13093 return false; 13094 } 13095 13096 String[] newArgs = new String[args.length - opti]; 13097 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13098 13099 TaskRecord lastTask = null; 13100 boolean needSep = false; 13101 for (int i=activities.size()-1; i>=0; i--) { 13102 ActivityRecord r = activities.get(i); 13103 if (needSep) { 13104 pw.println(); 13105 } 13106 needSep = true; 13107 synchronized (this) { 13108 if (lastTask != r.task) { 13109 lastTask = r.task; 13110 pw.print("TASK "); pw.print(lastTask.affinity); 13111 pw.print(" id="); pw.println(lastTask.taskId); 13112 if (dumpAll) { 13113 lastTask.dump(pw, " "); 13114 } 13115 } 13116 } 13117 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13118 } 13119 return true; 13120 } 13121 13122 /** 13123 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13124 * there is a thread associated with the activity. 13125 */ 13126 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13127 final ActivityRecord r, String[] args, boolean dumpAll) { 13128 String innerPrefix = prefix + " "; 13129 synchronized (this) { 13130 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13131 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13132 pw.print(" pid="); 13133 if (r.app != null) pw.println(r.app.pid); 13134 else pw.println("(not running)"); 13135 if (dumpAll) { 13136 r.dump(pw, innerPrefix); 13137 } 13138 } 13139 if (r.app != null && r.app.thread != null) { 13140 // flush anything that is already in the PrintWriter since the thread is going 13141 // to write to the file descriptor directly 13142 pw.flush(); 13143 try { 13144 TransferPipe tp = new TransferPipe(); 13145 try { 13146 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13147 r.appToken, innerPrefix, args); 13148 tp.go(fd); 13149 } finally { 13150 tp.kill(); 13151 } 13152 } catch (IOException e) { 13153 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13154 } catch (RemoteException e) { 13155 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13156 } 13157 } 13158 } 13159 13160 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13161 int opti, boolean dumpAll, String dumpPackage) { 13162 boolean needSep = false; 13163 boolean onlyHistory = false; 13164 boolean printedAnything = false; 13165 13166 if ("history".equals(dumpPackage)) { 13167 if (opti < args.length && "-s".equals(args[opti])) { 13168 dumpAll = false; 13169 } 13170 onlyHistory = true; 13171 dumpPackage = null; 13172 } 13173 13174 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13175 if (!onlyHistory && dumpAll) { 13176 if (mRegisteredReceivers.size() > 0) { 13177 boolean printed = false; 13178 Iterator it = mRegisteredReceivers.values().iterator(); 13179 while (it.hasNext()) { 13180 ReceiverList r = (ReceiverList)it.next(); 13181 if (dumpPackage != null && (r.app == null || 13182 !dumpPackage.equals(r.app.info.packageName))) { 13183 continue; 13184 } 13185 if (!printed) { 13186 pw.println(" Registered Receivers:"); 13187 needSep = true; 13188 printed = true; 13189 printedAnything = true; 13190 } 13191 pw.print(" * "); pw.println(r); 13192 r.dump(pw, " "); 13193 } 13194 } 13195 13196 if (mReceiverResolver.dump(pw, needSep ? 13197 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13198 " ", dumpPackage, false)) { 13199 needSep = true; 13200 printedAnything = true; 13201 } 13202 } 13203 13204 for (BroadcastQueue q : mBroadcastQueues) { 13205 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13206 printedAnything |= needSep; 13207 } 13208 13209 needSep = true; 13210 13211 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13212 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13213 if (needSep) { 13214 pw.println(); 13215 } 13216 needSep = true; 13217 printedAnything = true; 13218 pw.print(" Sticky broadcasts for user "); 13219 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13220 StringBuilder sb = new StringBuilder(128); 13221 for (Map.Entry<String, ArrayList<Intent>> ent 13222 : mStickyBroadcasts.valueAt(user).entrySet()) { 13223 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13224 if (dumpAll) { 13225 pw.println(":"); 13226 ArrayList<Intent> intents = ent.getValue(); 13227 final int N = intents.size(); 13228 for (int i=0; i<N; i++) { 13229 sb.setLength(0); 13230 sb.append(" Intent: "); 13231 intents.get(i).toShortString(sb, false, true, false, false); 13232 pw.println(sb.toString()); 13233 Bundle bundle = intents.get(i).getExtras(); 13234 if (bundle != null) { 13235 pw.print(" "); 13236 pw.println(bundle.toString()); 13237 } 13238 } 13239 } else { 13240 pw.println(""); 13241 } 13242 } 13243 } 13244 } 13245 13246 if (!onlyHistory && dumpAll) { 13247 pw.println(); 13248 for (BroadcastQueue queue : mBroadcastQueues) { 13249 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13250 + queue.mBroadcastsScheduled); 13251 } 13252 pw.println(" mHandler:"); 13253 mHandler.dump(new PrintWriterPrinter(pw), " "); 13254 needSep = true; 13255 printedAnything = true; 13256 } 13257 13258 if (!printedAnything) { 13259 pw.println(" (nothing)"); 13260 } 13261 } 13262 13263 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13264 int opti, boolean dumpAll, String dumpPackage) { 13265 boolean needSep; 13266 boolean printedAnything = false; 13267 13268 ItemMatcher matcher = new ItemMatcher(); 13269 matcher.build(args, opti); 13270 13271 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13272 13273 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13274 printedAnything |= needSep; 13275 13276 if (mLaunchingProviders.size() > 0) { 13277 boolean printed = false; 13278 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13279 ContentProviderRecord r = mLaunchingProviders.get(i); 13280 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13281 continue; 13282 } 13283 if (!printed) { 13284 if (needSep) pw.println(); 13285 needSep = true; 13286 pw.println(" Launching content providers:"); 13287 printed = true; 13288 printedAnything = true; 13289 } 13290 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13291 pw.println(r); 13292 } 13293 } 13294 13295 if (mGrantedUriPermissions.size() > 0) { 13296 boolean printed = false; 13297 int dumpUid = -2; 13298 if (dumpPackage != null) { 13299 try { 13300 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13301 } catch (NameNotFoundException e) { 13302 dumpUid = -1; 13303 } 13304 } 13305 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13306 int uid = mGrantedUriPermissions.keyAt(i); 13307 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13308 continue; 13309 } 13310 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13311 if (!printed) { 13312 if (needSep) pw.println(); 13313 needSep = true; 13314 pw.println(" Granted Uri Permissions:"); 13315 printed = true; 13316 printedAnything = true; 13317 } 13318 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13319 for (UriPermission perm : perms.values()) { 13320 pw.print(" "); pw.println(perm); 13321 if (dumpAll) { 13322 perm.dump(pw, " "); 13323 } 13324 } 13325 } 13326 } 13327 13328 if (!printedAnything) { 13329 pw.println(" (nothing)"); 13330 } 13331 } 13332 13333 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13334 int opti, boolean dumpAll, String dumpPackage) { 13335 boolean printed = false; 13336 13337 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13338 13339 if (mIntentSenderRecords.size() > 0) { 13340 Iterator<WeakReference<PendingIntentRecord>> it 13341 = mIntentSenderRecords.values().iterator(); 13342 while (it.hasNext()) { 13343 WeakReference<PendingIntentRecord> ref = it.next(); 13344 PendingIntentRecord rec = ref != null ? ref.get(): null; 13345 if (dumpPackage != null && (rec == null 13346 || !dumpPackage.equals(rec.key.packageName))) { 13347 continue; 13348 } 13349 printed = true; 13350 if (rec != null) { 13351 pw.print(" * "); pw.println(rec); 13352 if (dumpAll) { 13353 rec.dump(pw, " "); 13354 } 13355 } else { 13356 pw.print(" * "); pw.println(ref); 13357 } 13358 } 13359 } 13360 13361 if (!printed) { 13362 pw.println(" (nothing)"); 13363 } 13364 } 13365 13366 private static final int dumpProcessList(PrintWriter pw, 13367 ActivityManagerService service, List list, 13368 String prefix, String normalLabel, String persistentLabel, 13369 String dumpPackage) { 13370 int numPers = 0; 13371 final int N = list.size()-1; 13372 for (int i=N; i>=0; i--) { 13373 ProcessRecord r = (ProcessRecord)list.get(i); 13374 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13375 continue; 13376 } 13377 pw.println(String.format("%s%s #%2d: %s", 13378 prefix, (r.persistent ? persistentLabel : normalLabel), 13379 i, r.toString())); 13380 if (r.persistent) { 13381 numPers++; 13382 } 13383 } 13384 return numPers; 13385 } 13386 13387 private static final boolean dumpProcessOomList(PrintWriter pw, 13388 ActivityManagerService service, List<ProcessRecord> origList, 13389 String prefix, String normalLabel, String persistentLabel, 13390 boolean inclDetails, String dumpPackage) { 13391 13392 ArrayList<Pair<ProcessRecord, Integer>> list 13393 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13394 for (int i=0; i<origList.size(); i++) { 13395 ProcessRecord r = origList.get(i); 13396 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13397 continue; 13398 } 13399 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13400 } 13401 13402 if (list.size() <= 0) { 13403 return false; 13404 } 13405 13406 Comparator<Pair<ProcessRecord, Integer>> comparator 13407 = new Comparator<Pair<ProcessRecord, Integer>>() { 13408 @Override 13409 public int compare(Pair<ProcessRecord, Integer> object1, 13410 Pair<ProcessRecord, Integer> object2) { 13411 if (object1.first.setAdj != object2.first.setAdj) { 13412 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13413 } 13414 if (object1.second.intValue() != object2.second.intValue()) { 13415 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13416 } 13417 return 0; 13418 } 13419 }; 13420 13421 Collections.sort(list, comparator); 13422 13423 final long curRealtime = SystemClock.elapsedRealtime(); 13424 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13425 final long curUptime = SystemClock.uptimeMillis(); 13426 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13427 13428 for (int i=list.size()-1; i>=0; i--) { 13429 ProcessRecord r = list.get(i).first; 13430 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13431 char schedGroup; 13432 switch (r.setSchedGroup) { 13433 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13434 schedGroup = 'B'; 13435 break; 13436 case Process.THREAD_GROUP_DEFAULT: 13437 schedGroup = 'F'; 13438 break; 13439 default: 13440 schedGroup = '?'; 13441 break; 13442 } 13443 char foreground; 13444 if (r.foregroundActivities) { 13445 foreground = 'A'; 13446 } else if (r.foregroundServices) { 13447 foreground = 'S'; 13448 } else { 13449 foreground = ' '; 13450 } 13451 String procState = ProcessList.makeProcStateString(r.curProcState); 13452 pw.print(prefix); 13453 pw.print(r.persistent ? persistentLabel : normalLabel); 13454 pw.print(" #"); 13455 int num = (origList.size()-1)-list.get(i).second; 13456 if (num < 10) pw.print(' '); 13457 pw.print(num); 13458 pw.print(": "); 13459 pw.print(oomAdj); 13460 pw.print(' '); 13461 pw.print(schedGroup); 13462 pw.print('/'); 13463 pw.print(foreground); 13464 pw.print('/'); 13465 pw.print(procState); 13466 pw.print(" trm:"); 13467 if (r.trimMemoryLevel < 10) pw.print(' '); 13468 pw.print(r.trimMemoryLevel); 13469 pw.print(' '); 13470 pw.print(r.toShortString()); 13471 pw.print(" ("); 13472 pw.print(r.adjType); 13473 pw.println(')'); 13474 if (r.adjSource != null || r.adjTarget != null) { 13475 pw.print(prefix); 13476 pw.print(" "); 13477 if (r.adjTarget instanceof ComponentName) { 13478 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13479 } else if (r.adjTarget != null) { 13480 pw.print(r.adjTarget.toString()); 13481 } else { 13482 pw.print("{null}"); 13483 } 13484 pw.print("<="); 13485 if (r.adjSource instanceof ProcessRecord) { 13486 pw.print("Proc{"); 13487 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13488 pw.println("}"); 13489 } else if (r.adjSource != null) { 13490 pw.println(r.adjSource.toString()); 13491 } else { 13492 pw.println("{null}"); 13493 } 13494 } 13495 if (inclDetails) { 13496 pw.print(prefix); 13497 pw.print(" "); 13498 pw.print("oom: max="); pw.print(r.maxAdj); 13499 pw.print(" curRaw="); pw.print(r.curRawAdj); 13500 pw.print(" setRaw="); pw.print(r.setRawAdj); 13501 pw.print(" cur="); pw.print(r.curAdj); 13502 pw.print(" set="); pw.println(r.setAdj); 13503 pw.print(prefix); 13504 pw.print(" "); 13505 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13506 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13507 pw.print(" lastPss="); pw.print(r.lastPss); 13508 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13509 pw.print(prefix); 13510 pw.print(" "); 13511 pw.print("cached="); pw.print(r.cached); 13512 pw.print(" empty="); pw.print(r.empty); 13513 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13514 13515 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13516 if (r.lastWakeTime != 0) { 13517 long wtime; 13518 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13519 synchronized (stats) { 13520 wtime = stats.getProcessWakeTime(r.info.uid, 13521 r.pid, curRealtime); 13522 } 13523 long timeUsed = wtime - r.lastWakeTime; 13524 pw.print(prefix); 13525 pw.print(" "); 13526 pw.print("keep awake over "); 13527 TimeUtils.formatDuration(realtimeSince, pw); 13528 pw.print(" used "); 13529 TimeUtils.formatDuration(timeUsed, pw); 13530 pw.print(" ("); 13531 pw.print((timeUsed*100)/realtimeSince); 13532 pw.println("%)"); 13533 } 13534 if (r.lastCpuTime != 0) { 13535 long timeUsed = r.curCpuTime - r.lastCpuTime; 13536 pw.print(prefix); 13537 pw.print(" "); 13538 pw.print("run cpu over "); 13539 TimeUtils.formatDuration(uptimeSince, pw); 13540 pw.print(" used "); 13541 TimeUtils.formatDuration(timeUsed, pw); 13542 pw.print(" ("); 13543 pw.print((timeUsed*100)/uptimeSince); 13544 pw.println("%)"); 13545 } 13546 } 13547 } 13548 } 13549 return true; 13550 } 13551 13552 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13553 ArrayList<ProcessRecord> procs; 13554 synchronized (this) { 13555 if (args != null && args.length > start 13556 && args[start].charAt(0) != '-') { 13557 procs = new ArrayList<ProcessRecord>(); 13558 int pid = -1; 13559 try { 13560 pid = Integer.parseInt(args[start]); 13561 } catch (NumberFormatException e) { 13562 } 13563 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13564 ProcessRecord proc = mLruProcesses.get(i); 13565 if (proc.pid == pid) { 13566 procs.add(proc); 13567 } else if (proc.processName.equals(args[start])) { 13568 procs.add(proc); 13569 } 13570 } 13571 if (procs.size() <= 0) { 13572 return null; 13573 } 13574 } else { 13575 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13576 } 13577 } 13578 return procs; 13579 } 13580 13581 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13582 PrintWriter pw, String[] args) { 13583 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13584 if (procs == null) { 13585 pw.println("No process found for: " + args[0]); 13586 return; 13587 } 13588 13589 long uptime = SystemClock.uptimeMillis(); 13590 long realtime = SystemClock.elapsedRealtime(); 13591 pw.println("Applications Graphics Acceleration Info:"); 13592 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13593 13594 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13595 ProcessRecord r = procs.get(i); 13596 if (r.thread != null) { 13597 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13598 pw.flush(); 13599 try { 13600 TransferPipe tp = new TransferPipe(); 13601 try { 13602 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13603 tp.go(fd); 13604 } finally { 13605 tp.kill(); 13606 } 13607 } catch (IOException e) { 13608 pw.println("Failure while dumping the app: " + r); 13609 pw.flush(); 13610 } catch (RemoteException e) { 13611 pw.println("Got a RemoteException while dumping the app " + r); 13612 pw.flush(); 13613 } 13614 } 13615 } 13616 } 13617 13618 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13619 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13620 if (procs == null) { 13621 pw.println("No process found for: " + args[0]); 13622 return; 13623 } 13624 13625 pw.println("Applications Database Info:"); 13626 13627 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13628 ProcessRecord r = procs.get(i); 13629 if (r.thread != null) { 13630 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13631 pw.flush(); 13632 try { 13633 TransferPipe tp = new TransferPipe(); 13634 try { 13635 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13636 tp.go(fd); 13637 } finally { 13638 tp.kill(); 13639 } 13640 } catch (IOException e) { 13641 pw.println("Failure while dumping the app: " + r); 13642 pw.flush(); 13643 } catch (RemoteException e) { 13644 pw.println("Got a RemoteException while dumping the app " + r); 13645 pw.flush(); 13646 } 13647 } 13648 } 13649 } 13650 13651 final static class MemItem { 13652 final boolean isProc; 13653 final String label; 13654 final String shortLabel; 13655 final long pss; 13656 final int id; 13657 final boolean hasActivities; 13658 ArrayList<MemItem> subitems; 13659 13660 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13661 boolean _hasActivities) { 13662 isProc = true; 13663 label = _label; 13664 shortLabel = _shortLabel; 13665 pss = _pss; 13666 id = _id; 13667 hasActivities = _hasActivities; 13668 } 13669 13670 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13671 isProc = false; 13672 label = _label; 13673 shortLabel = _shortLabel; 13674 pss = _pss; 13675 id = _id; 13676 hasActivities = false; 13677 } 13678 } 13679 13680 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13681 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13682 if (sort && !isCompact) { 13683 Collections.sort(items, new Comparator<MemItem>() { 13684 @Override 13685 public int compare(MemItem lhs, MemItem rhs) { 13686 if (lhs.pss < rhs.pss) { 13687 return 1; 13688 } else if (lhs.pss > rhs.pss) { 13689 return -1; 13690 } 13691 return 0; 13692 } 13693 }); 13694 } 13695 13696 for (int i=0; i<items.size(); i++) { 13697 MemItem mi = items.get(i); 13698 if (!isCompact) { 13699 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13700 } else if (mi.isProc) { 13701 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13702 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13703 pw.println(mi.hasActivities ? ",a" : ",e"); 13704 } else { 13705 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13706 pw.println(mi.pss); 13707 } 13708 if (mi.subitems != null) { 13709 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13710 true, isCompact); 13711 } 13712 } 13713 } 13714 13715 // These are in KB. 13716 static final long[] DUMP_MEM_BUCKETS = new long[] { 13717 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13718 120*1024, 160*1024, 200*1024, 13719 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13720 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13721 }; 13722 13723 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13724 boolean stackLike) { 13725 int start = label.lastIndexOf('.'); 13726 if (start >= 0) start++; 13727 else start = 0; 13728 int end = label.length(); 13729 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13730 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13731 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13732 out.append(bucket); 13733 out.append(stackLike ? "MB." : "MB "); 13734 out.append(label, start, end); 13735 return; 13736 } 13737 } 13738 out.append(memKB/1024); 13739 out.append(stackLike ? "MB." : "MB "); 13740 out.append(label, start, end); 13741 } 13742 13743 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13744 ProcessList.NATIVE_ADJ, 13745 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13746 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13747 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13748 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13749 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13750 }; 13751 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13752 "Native", 13753 "System", "Persistent", "Foreground", 13754 "Visible", "Perceptible", 13755 "Heavy Weight", "Backup", 13756 "A Services", "Home", 13757 "Previous", "B Services", "Cached" 13758 }; 13759 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13760 "native", 13761 "sys", "pers", "fore", 13762 "vis", "percept", 13763 "heavy", "backup", 13764 "servicea", "home", 13765 "prev", "serviceb", "cached" 13766 }; 13767 13768 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13769 long realtime, boolean isCheckinRequest, boolean isCompact) { 13770 if (isCheckinRequest || isCompact) { 13771 // short checkin version 13772 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13773 } else { 13774 pw.println("Applications Memory Usage (kB):"); 13775 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13776 } 13777 } 13778 13779 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13780 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13781 boolean dumpDetails = false; 13782 boolean dumpFullDetails = false; 13783 boolean dumpDalvik = false; 13784 boolean oomOnly = false; 13785 boolean isCompact = false; 13786 boolean localOnly = false; 13787 13788 int opti = 0; 13789 while (opti < args.length) { 13790 String opt = args[opti]; 13791 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13792 break; 13793 } 13794 opti++; 13795 if ("-a".equals(opt)) { 13796 dumpDetails = true; 13797 dumpFullDetails = true; 13798 dumpDalvik = true; 13799 } else if ("-d".equals(opt)) { 13800 dumpDalvik = true; 13801 } else if ("-c".equals(opt)) { 13802 isCompact = true; 13803 } else if ("--oom".equals(opt)) { 13804 oomOnly = true; 13805 } else if ("--local".equals(opt)) { 13806 localOnly = true; 13807 } else if ("-h".equals(opt)) { 13808 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13809 pw.println(" -a: include all available information for each process."); 13810 pw.println(" -d: include dalvik details when dumping process details."); 13811 pw.println(" -c: dump in a compact machine-parseable representation."); 13812 pw.println(" --oom: only show processes organized by oom adj."); 13813 pw.println(" --local: only collect details locally, don't call process."); 13814 pw.println("If [process] is specified it can be the name or "); 13815 pw.println("pid of a specific process to dump."); 13816 return; 13817 } else { 13818 pw.println("Unknown argument: " + opt + "; use -h for help"); 13819 } 13820 } 13821 13822 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13823 long uptime = SystemClock.uptimeMillis(); 13824 long realtime = SystemClock.elapsedRealtime(); 13825 final long[] tmpLong = new long[1]; 13826 13827 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13828 if (procs == null) { 13829 // No Java processes. Maybe they want to print a native process. 13830 if (args != null && args.length > opti 13831 && args[opti].charAt(0) != '-') { 13832 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13833 = new ArrayList<ProcessCpuTracker.Stats>(); 13834 updateCpuStatsNow(); 13835 int findPid = -1; 13836 try { 13837 findPid = Integer.parseInt(args[opti]); 13838 } catch (NumberFormatException e) { 13839 } 13840 synchronized (mProcessCpuTracker) { 13841 final int N = mProcessCpuTracker.countStats(); 13842 for (int i=0; i<N; i++) { 13843 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13844 if (st.pid == findPid || (st.baseName != null 13845 && st.baseName.equals(args[opti]))) { 13846 nativeProcs.add(st); 13847 } 13848 } 13849 } 13850 if (nativeProcs.size() > 0) { 13851 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13852 isCompact); 13853 Debug.MemoryInfo mi = null; 13854 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13855 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13856 final int pid = r.pid; 13857 if (!isCheckinRequest && dumpDetails) { 13858 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13859 } 13860 if (mi == null) { 13861 mi = new Debug.MemoryInfo(); 13862 } 13863 if (dumpDetails || (!brief && !oomOnly)) { 13864 Debug.getMemoryInfo(pid, mi); 13865 } else { 13866 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13867 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13868 } 13869 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13870 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13871 if (isCheckinRequest) { 13872 pw.println(); 13873 } 13874 } 13875 return; 13876 } 13877 } 13878 pw.println("No process found for: " + args[opti]); 13879 return; 13880 } 13881 13882 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13883 dumpDetails = true; 13884 } 13885 13886 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13887 13888 String[] innerArgs = new String[args.length-opti]; 13889 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13890 13891 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13892 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13893 long nativePss=0, dalvikPss=0, otherPss=0; 13894 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13895 13896 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13897 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13898 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13899 13900 long totalPss = 0; 13901 long cachedPss = 0; 13902 13903 Debug.MemoryInfo mi = null; 13904 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13905 final ProcessRecord r = procs.get(i); 13906 final IApplicationThread thread; 13907 final int pid; 13908 final int oomAdj; 13909 final boolean hasActivities; 13910 synchronized (this) { 13911 thread = r.thread; 13912 pid = r.pid; 13913 oomAdj = r.getSetAdjWithServices(); 13914 hasActivities = r.activities.size() > 0; 13915 } 13916 if (thread != null) { 13917 if (!isCheckinRequest && dumpDetails) { 13918 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13919 } 13920 if (mi == null) { 13921 mi = new Debug.MemoryInfo(); 13922 } 13923 if (dumpDetails || (!brief && !oomOnly)) { 13924 Debug.getMemoryInfo(pid, mi); 13925 } else { 13926 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13927 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13928 } 13929 if (dumpDetails) { 13930 if (localOnly) { 13931 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13932 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13933 if (isCheckinRequest) { 13934 pw.println(); 13935 } 13936 } else { 13937 try { 13938 pw.flush(); 13939 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13940 dumpDalvik, innerArgs); 13941 } catch (RemoteException e) { 13942 if (!isCheckinRequest) { 13943 pw.println("Got RemoteException!"); 13944 pw.flush(); 13945 } 13946 } 13947 } 13948 } 13949 13950 final long myTotalPss = mi.getTotalPss(); 13951 final long myTotalUss = mi.getTotalUss(); 13952 13953 synchronized (this) { 13954 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13955 // Record this for posterity if the process has been stable. 13956 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13957 } 13958 } 13959 13960 if (!isCheckinRequest && mi != null) { 13961 totalPss += myTotalPss; 13962 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13963 (hasActivities ? " / activities)" : ")"), 13964 r.processName, myTotalPss, pid, hasActivities); 13965 procMems.add(pssItem); 13966 procMemsMap.put(pid, pssItem); 13967 13968 nativePss += mi.nativePss; 13969 dalvikPss += mi.dalvikPss; 13970 otherPss += mi.otherPss; 13971 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13972 long mem = mi.getOtherPss(j); 13973 miscPss[j] += mem; 13974 otherPss -= mem; 13975 } 13976 13977 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13978 cachedPss += myTotalPss; 13979 } 13980 13981 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13982 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13983 || oomIndex == (oomPss.length-1)) { 13984 oomPss[oomIndex] += myTotalPss; 13985 if (oomProcs[oomIndex] == null) { 13986 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13987 } 13988 oomProcs[oomIndex].add(pssItem); 13989 break; 13990 } 13991 } 13992 } 13993 } 13994 } 13995 13996 long nativeProcTotalPss = 0; 13997 13998 if (!isCheckinRequest && procs.size() > 1) { 13999 // If we are showing aggregations, also look for native processes to 14000 // include so that our aggregations are more accurate. 14001 updateCpuStatsNow(); 14002 synchronized (mProcessCpuTracker) { 14003 final int N = mProcessCpuTracker.countStats(); 14004 for (int i=0; i<N; i++) { 14005 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 14006 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 14007 if (mi == null) { 14008 mi = new Debug.MemoryInfo(); 14009 } 14010 if (!brief && !oomOnly) { 14011 Debug.getMemoryInfo(st.pid, mi); 14012 } else { 14013 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14014 mi.nativePrivateDirty = (int)tmpLong[0]; 14015 } 14016 14017 final long myTotalPss = mi.getTotalPss(); 14018 totalPss += myTotalPss; 14019 nativeProcTotalPss += myTotalPss; 14020 14021 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14022 st.name, myTotalPss, st.pid, false); 14023 procMems.add(pssItem); 14024 14025 nativePss += mi.nativePss; 14026 dalvikPss += mi.dalvikPss; 14027 otherPss += mi.otherPss; 14028 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14029 long mem = mi.getOtherPss(j); 14030 miscPss[j] += mem; 14031 otherPss -= mem; 14032 } 14033 oomPss[0] += myTotalPss; 14034 if (oomProcs[0] == null) { 14035 oomProcs[0] = new ArrayList<MemItem>(); 14036 } 14037 oomProcs[0].add(pssItem); 14038 } 14039 } 14040 } 14041 14042 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14043 14044 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14045 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14046 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14047 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14048 String label = Debug.MemoryInfo.getOtherLabel(j); 14049 catMems.add(new MemItem(label, label, miscPss[j], j)); 14050 } 14051 14052 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14053 for (int j=0; j<oomPss.length; j++) { 14054 if (oomPss[j] != 0) { 14055 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14056 : DUMP_MEM_OOM_LABEL[j]; 14057 MemItem item = new MemItem(label, label, oomPss[j], 14058 DUMP_MEM_OOM_ADJ[j]); 14059 item.subitems = oomProcs[j]; 14060 oomMems.add(item); 14061 } 14062 } 14063 14064 if (!brief && !oomOnly && !isCompact) { 14065 pw.println(); 14066 pw.println("Total PSS by process:"); 14067 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14068 pw.println(); 14069 } 14070 if (!isCompact) { 14071 pw.println("Total PSS by OOM adjustment:"); 14072 } 14073 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14074 if (!brief && !oomOnly) { 14075 PrintWriter out = categoryPw != null ? categoryPw : pw; 14076 if (!isCompact) { 14077 out.println(); 14078 out.println("Total PSS by category:"); 14079 } 14080 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14081 } 14082 if (!isCompact) { 14083 pw.println(); 14084 } 14085 MemInfoReader memInfo = new MemInfoReader(); 14086 memInfo.readMemInfo(); 14087 if (nativeProcTotalPss > 0) { 14088 synchronized (this) { 14089 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14090 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14091 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14092 nativeProcTotalPss); 14093 } 14094 } 14095 if (!brief) { 14096 if (!isCompact) { 14097 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14098 pw.print(" kB (status "); 14099 switch (mLastMemoryLevel) { 14100 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14101 pw.println("normal)"); 14102 break; 14103 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14104 pw.println("moderate)"); 14105 break; 14106 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14107 pw.println("low)"); 14108 break; 14109 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14110 pw.println("critical)"); 14111 break; 14112 default: 14113 pw.print(mLastMemoryLevel); 14114 pw.println(")"); 14115 break; 14116 } 14117 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14118 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14119 pw.print(cachedPss); pw.print(" cached pss + "); 14120 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14121 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14122 } else { 14123 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14124 pw.print(cachedPss + memInfo.getCachedSizeKb() 14125 + memInfo.getFreeSizeKb()); pw.print(","); 14126 pw.println(totalPss - cachedPss); 14127 } 14128 } 14129 if (!isCompact) { 14130 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14131 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14132 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14133 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14134 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14135 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14136 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14137 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14138 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14139 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14140 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14141 } 14142 if (!brief) { 14143 if (memInfo.getZramTotalSizeKb() != 0) { 14144 if (!isCompact) { 14145 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14146 pw.print(" kB physical used for "); 14147 pw.print(memInfo.getSwapTotalSizeKb() 14148 - memInfo.getSwapFreeSizeKb()); 14149 pw.print(" kB in swap ("); 14150 pw.print(memInfo.getSwapTotalSizeKb()); 14151 pw.println(" kB total swap)"); 14152 } else { 14153 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14154 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14155 pw.println(memInfo.getSwapFreeSizeKb()); 14156 } 14157 } 14158 final int[] SINGLE_LONG_FORMAT = new int[] { 14159 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14160 }; 14161 long[] longOut = new long[1]; 14162 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14163 SINGLE_LONG_FORMAT, null, longOut, null); 14164 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14165 longOut[0] = 0; 14166 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14167 SINGLE_LONG_FORMAT, null, longOut, null); 14168 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14169 longOut[0] = 0; 14170 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14171 SINGLE_LONG_FORMAT, null, longOut, null); 14172 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14173 longOut[0] = 0; 14174 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14175 SINGLE_LONG_FORMAT, null, longOut, null); 14176 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14177 if (!isCompact) { 14178 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14179 pw.print(" KSM: "); pw.print(sharing); 14180 pw.print(" kB saved from shared "); 14181 pw.print(shared); pw.println(" kB"); 14182 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14183 pw.print(voltile); pw.println(" kB volatile"); 14184 } 14185 pw.print(" Tuning: "); 14186 pw.print(ActivityManager.staticGetMemoryClass()); 14187 pw.print(" (large "); 14188 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14189 pw.print("), oom "); 14190 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14191 pw.print(" kB"); 14192 pw.print(", restore limit "); 14193 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14194 pw.print(" kB"); 14195 if (ActivityManager.isLowRamDeviceStatic()) { 14196 pw.print(" (low-ram)"); 14197 } 14198 if (ActivityManager.isHighEndGfx()) { 14199 pw.print(" (high-end-gfx)"); 14200 } 14201 pw.println(); 14202 } else { 14203 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14204 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14205 pw.println(voltile); 14206 pw.print("tuning,"); 14207 pw.print(ActivityManager.staticGetMemoryClass()); 14208 pw.print(','); 14209 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14210 pw.print(','); 14211 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14212 if (ActivityManager.isLowRamDeviceStatic()) { 14213 pw.print(",low-ram"); 14214 } 14215 if (ActivityManager.isHighEndGfx()) { 14216 pw.print(",high-end-gfx"); 14217 } 14218 pw.println(); 14219 } 14220 } 14221 } 14222 } 14223 14224 /** 14225 * Searches array of arguments for the specified string 14226 * @param args array of argument strings 14227 * @param value value to search for 14228 * @return true if the value is contained in the array 14229 */ 14230 private static boolean scanArgs(String[] args, String value) { 14231 if (args != null) { 14232 for (String arg : args) { 14233 if (value.equals(arg)) { 14234 return true; 14235 } 14236 } 14237 } 14238 return false; 14239 } 14240 14241 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14242 ContentProviderRecord cpr, boolean always) { 14243 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14244 14245 if (!inLaunching || always) { 14246 synchronized (cpr) { 14247 cpr.launchingApp = null; 14248 cpr.notifyAll(); 14249 } 14250 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14251 String names[] = cpr.info.authority.split(";"); 14252 for (int j = 0; j < names.length; j++) { 14253 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14254 } 14255 } 14256 14257 for (int i=0; i<cpr.connections.size(); i++) { 14258 ContentProviderConnection conn = cpr.connections.get(i); 14259 if (conn.waiting) { 14260 // If this connection is waiting for the provider, then we don't 14261 // need to mess with its process unless we are always removing 14262 // or for some reason the provider is not currently launching. 14263 if (inLaunching && !always) { 14264 continue; 14265 } 14266 } 14267 ProcessRecord capp = conn.client; 14268 conn.dead = true; 14269 if (conn.stableCount > 0) { 14270 if (!capp.persistent && capp.thread != null 14271 && capp.pid != 0 14272 && capp.pid != MY_PID) { 14273 capp.kill("depends on provider " 14274 + cpr.name.flattenToShortString() 14275 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14276 } 14277 } else if (capp.thread != null && conn.provider.provider != null) { 14278 try { 14279 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14280 } catch (RemoteException e) { 14281 } 14282 // In the protocol here, we don't expect the client to correctly 14283 // clean up this connection, we'll just remove it. 14284 cpr.connections.remove(i); 14285 conn.client.conProviders.remove(conn); 14286 } 14287 } 14288 14289 if (inLaunching && always) { 14290 mLaunchingProviders.remove(cpr); 14291 } 14292 return inLaunching; 14293 } 14294 14295 /** 14296 * Main code for cleaning up a process when it has gone away. This is 14297 * called both as a result of the process dying, or directly when stopping 14298 * a process when running in single process mode. 14299 */ 14300 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14301 boolean restarting, boolean allowRestart, int index) { 14302 if (index >= 0) { 14303 removeLruProcessLocked(app); 14304 ProcessList.remove(app.pid); 14305 } 14306 14307 mProcessesToGc.remove(app); 14308 mPendingPssProcesses.remove(app); 14309 14310 // Dismiss any open dialogs. 14311 if (app.crashDialog != null && !app.forceCrashReport) { 14312 app.crashDialog.dismiss(); 14313 app.crashDialog = null; 14314 } 14315 if (app.anrDialog != null) { 14316 app.anrDialog.dismiss(); 14317 app.anrDialog = null; 14318 } 14319 if (app.waitDialog != null) { 14320 app.waitDialog.dismiss(); 14321 app.waitDialog = null; 14322 } 14323 14324 app.crashing = false; 14325 app.notResponding = false; 14326 14327 app.resetPackageList(mProcessStats); 14328 app.unlinkDeathRecipient(); 14329 app.makeInactive(mProcessStats); 14330 app.waitingToKill = null; 14331 app.forcingToForeground = null; 14332 updateProcessForegroundLocked(app, false, false); 14333 app.foregroundActivities = false; 14334 app.hasShownUi = false; 14335 app.treatLikeActivity = false; 14336 app.hasAboveClient = false; 14337 app.hasClientActivities = false; 14338 14339 mServices.killServicesLocked(app, allowRestart); 14340 14341 boolean restart = false; 14342 14343 // Remove published content providers. 14344 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14345 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14346 final boolean always = app.bad || !allowRestart; 14347 if (removeDyingProviderLocked(app, cpr, always) || always) { 14348 // We left the provider in the launching list, need to 14349 // restart it. 14350 restart = true; 14351 } 14352 14353 cpr.provider = null; 14354 cpr.proc = null; 14355 } 14356 app.pubProviders.clear(); 14357 14358 // Take care of any launching providers waiting for this process. 14359 if (checkAppInLaunchingProvidersLocked(app, false)) { 14360 restart = true; 14361 } 14362 14363 // Unregister from connected content providers. 14364 if (!app.conProviders.isEmpty()) { 14365 for (int i=0; i<app.conProviders.size(); i++) { 14366 ContentProviderConnection conn = app.conProviders.get(i); 14367 conn.provider.connections.remove(conn); 14368 } 14369 app.conProviders.clear(); 14370 } 14371 14372 // At this point there may be remaining entries in mLaunchingProviders 14373 // where we were the only one waiting, so they are no longer of use. 14374 // Look for these and clean up if found. 14375 // XXX Commented out for now. Trying to figure out a way to reproduce 14376 // the actual situation to identify what is actually going on. 14377 if (false) { 14378 for (int i=0; i<mLaunchingProviders.size(); i++) { 14379 ContentProviderRecord cpr = (ContentProviderRecord) 14380 mLaunchingProviders.get(i); 14381 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14382 synchronized (cpr) { 14383 cpr.launchingApp = null; 14384 cpr.notifyAll(); 14385 } 14386 } 14387 } 14388 } 14389 14390 skipCurrentReceiverLocked(app); 14391 14392 // Unregister any receivers. 14393 for (int i=app.receivers.size()-1; i>=0; i--) { 14394 removeReceiverLocked(app.receivers.valueAt(i)); 14395 } 14396 app.receivers.clear(); 14397 14398 // If the app is undergoing backup, tell the backup manager about it 14399 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14400 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14401 + mBackupTarget.appInfo + " died during backup"); 14402 try { 14403 IBackupManager bm = IBackupManager.Stub.asInterface( 14404 ServiceManager.getService(Context.BACKUP_SERVICE)); 14405 bm.agentDisconnected(app.info.packageName); 14406 } catch (RemoteException e) { 14407 // can't happen; backup manager is local 14408 } 14409 } 14410 14411 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14412 ProcessChangeItem item = mPendingProcessChanges.get(i); 14413 if (item.pid == app.pid) { 14414 mPendingProcessChanges.remove(i); 14415 mAvailProcessChanges.add(item); 14416 } 14417 } 14418 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14419 14420 // If the caller is restarting this app, then leave it in its 14421 // current lists and let the caller take care of it. 14422 if (restarting) { 14423 return; 14424 } 14425 14426 if (!app.persistent || app.isolated) { 14427 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14428 "Removing non-persistent process during cleanup: " + app); 14429 mProcessNames.remove(app.processName, app.uid); 14430 mIsolatedProcesses.remove(app.uid); 14431 if (mHeavyWeightProcess == app) { 14432 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14433 mHeavyWeightProcess.userId, 0)); 14434 mHeavyWeightProcess = null; 14435 } 14436 } else if (!app.removed) { 14437 // This app is persistent, so we need to keep its record around. 14438 // If it is not already on the pending app list, add it there 14439 // and start a new process for it. 14440 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14441 mPersistentStartingProcesses.add(app); 14442 restart = true; 14443 } 14444 } 14445 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14446 "Clean-up removing on hold: " + app); 14447 mProcessesOnHold.remove(app); 14448 14449 if (app == mHomeProcess) { 14450 mHomeProcess = null; 14451 } 14452 if (app == mPreviousProcess) { 14453 mPreviousProcess = null; 14454 } 14455 14456 if (restart && !app.isolated) { 14457 // We have components that still need to be running in the 14458 // process, so re-launch it. 14459 mProcessNames.put(app.processName, app.uid, app); 14460 startProcessLocked(app, "restart", app.processName); 14461 } else if (app.pid > 0 && app.pid != MY_PID) { 14462 // Goodbye! 14463 boolean removed; 14464 synchronized (mPidsSelfLocked) { 14465 mPidsSelfLocked.remove(app.pid); 14466 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14467 } 14468 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14469 if (app.isolated) { 14470 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14471 } 14472 app.setPid(0); 14473 } 14474 } 14475 14476 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14477 // Look through the content providers we are waiting to have launched, 14478 // and if any run in this process then either schedule a restart of 14479 // the process or kill the client waiting for it if this process has 14480 // gone bad. 14481 int NL = mLaunchingProviders.size(); 14482 boolean restart = false; 14483 for (int i=0; i<NL; i++) { 14484 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14485 if (cpr.launchingApp == app) { 14486 if (!alwaysBad && !app.bad) { 14487 restart = true; 14488 } else { 14489 removeDyingProviderLocked(app, cpr, true); 14490 // cpr should have been removed from mLaunchingProviders 14491 NL = mLaunchingProviders.size(); 14492 i--; 14493 } 14494 } 14495 } 14496 return restart; 14497 } 14498 14499 // ========================================================= 14500 // SERVICES 14501 // ========================================================= 14502 14503 @Override 14504 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14505 int flags) { 14506 enforceNotIsolatedCaller("getServices"); 14507 synchronized (this) { 14508 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14509 } 14510 } 14511 14512 @Override 14513 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14514 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14515 synchronized (this) { 14516 return mServices.getRunningServiceControlPanelLocked(name); 14517 } 14518 } 14519 14520 @Override 14521 public ComponentName startService(IApplicationThread caller, Intent service, 14522 String resolvedType, int userId) { 14523 enforceNotIsolatedCaller("startService"); 14524 // Refuse possible leaked file descriptors 14525 if (service != null && service.hasFileDescriptors() == true) { 14526 throw new IllegalArgumentException("File descriptors passed in Intent"); 14527 } 14528 14529 if (DEBUG_SERVICE) 14530 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14531 synchronized(this) { 14532 final int callingPid = Binder.getCallingPid(); 14533 final int callingUid = Binder.getCallingUid(); 14534 final long origId = Binder.clearCallingIdentity(); 14535 ComponentName res = mServices.startServiceLocked(caller, service, 14536 resolvedType, callingPid, callingUid, userId); 14537 Binder.restoreCallingIdentity(origId); 14538 return res; 14539 } 14540 } 14541 14542 ComponentName startServiceInPackage(int uid, 14543 Intent service, String resolvedType, int userId) { 14544 synchronized(this) { 14545 if (DEBUG_SERVICE) 14546 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14547 final long origId = Binder.clearCallingIdentity(); 14548 ComponentName res = mServices.startServiceLocked(null, service, 14549 resolvedType, -1, uid, userId); 14550 Binder.restoreCallingIdentity(origId); 14551 return res; 14552 } 14553 } 14554 14555 @Override 14556 public int stopService(IApplicationThread caller, Intent service, 14557 String resolvedType, int userId) { 14558 enforceNotIsolatedCaller("stopService"); 14559 // Refuse possible leaked file descriptors 14560 if (service != null && service.hasFileDescriptors() == true) { 14561 throw new IllegalArgumentException("File descriptors passed in Intent"); 14562 } 14563 14564 synchronized(this) { 14565 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14566 } 14567 } 14568 14569 @Override 14570 public IBinder peekService(Intent service, String resolvedType) { 14571 enforceNotIsolatedCaller("peekService"); 14572 // Refuse possible leaked file descriptors 14573 if (service != null && service.hasFileDescriptors() == true) { 14574 throw new IllegalArgumentException("File descriptors passed in Intent"); 14575 } 14576 synchronized(this) { 14577 return mServices.peekServiceLocked(service, resolvedType); 14578 } 14579 } 14580 14581 @Override 14582 public boolean stopServiceToken(ComponentName className, IBinder token, 14583 int startId) { 14584 synchronized(this) { 14585 return mServices.stopServiceTokenLocked(className, token, startId); 14586 } 14587 } 14588 14589 @Override 14590 public void setServiceForeground(ComponentName className, IBinder token, 14591 int id, Notification notification, boolean removeNotification) { 14592 synchronized(this) { 14593 mServices.setServiceForegroundLocked(className, token, id, notification, 14594 removeNotification); 14595 } 14596 } 14597 14598 @Override 14599 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14600 boolean requireFull, String name, String callerPackage) { 14601 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14602 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14603 } 14604 14605 int unsafeConvertIncomingUser(int userId) { 14606 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14607 ? mCurrentUserId : userId; 14608 } 14609 14610 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14611 int allowMode, String name, String callerPackage) { 14612 final int callingUserId = UserHandle.getUserId(callingUid); 14613 if (callingUserId == userId) { 14614 return userId; 14615 } 14616 14617 // Note that we may be accessing mCurrentUserId outside of a lock... 14618 // shouldn't be a big deal, if this is being called outside 14619 // of a locked context there is intrinsically a race with 14620 // the value the caller will receive and someone else changing it. 14621 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14622 // we will switch to the calling user if access to the current user fails. 14623 int targetUserId = unsafeConvertIncomingUser(userId); 14624 14625 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14626 final boolean allow; 14627 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14628 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14629 // If the caller has this permission, they always pass go. And collect $200. 14630 allow = true; 14631 } else if (allowMode == ALLOW_FULL_ONLY) { 14632 // We require full access, sucks to be you. 14633 allow = false; 14634 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14635 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14636 // If the caller does not have either permission, they are always doomed. 14637 allow = false; 14638 } else if (allowMode == ALLOW_NON_FULL) { 14639 // We are blanket allowing non-full access, you lucky caller! 14640 allow = true; 14641 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14642 // We may or may not allow this depending on whether the two users are 14643 // in the same profile. 14644 synchronized (mUserProfileGroupIdsSelfLocked) { 14645 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14646 UserInfo.NO_PROFILE_GROUP_ID); 14647 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14648 UserInfo.NO_PROFILE_GROUP_ID); 14649 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14650 && callingProfile == targetProfile; 14651 } 14652 } else { 14653 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14654 } 14655 if (!allow) { 14656 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14657 // In this case, they would like to just execute as their 14658 // owner user instead of failing. 14659 targetUserId = callingUserId; 14660 } else { 14661 StringBuilder builder = new StringBuilder(128); 14662 builder.append("Permission Denial: "); 14663 builder.append(name); 14664 if (callerPackage != null) { 14665 builder.append(" from "); 14666 builder.append(callerPackage); 14667 } 14668 builder.append(" asks to run as user "); 14669 builder.append(userId); 14670 builder.append(" but is calling from user "); 14671 builder.append(UserHandle.getUserId(callingUid)); 14672 builder.append("; this requires "); 14673 builder.append(INTERACT_ACROSS_USERS_FULL); 14674 if (allowMode != ALLOW_FULL_ONLY) { 14675 builder.append(" or "); 14676 builder.append(INTERACT_ACROSS_USERS); 14677 } 14678 String msg = builder.toString(); 14679 Slog.w(TAG, msg); 14680 throw new SecurityException(msg); 14681 } 14682 } 14683 } 14684 if (!allowAll && targetUserId < 0) { 14685 throw new IllegalArgumentException( 14686 "Call does not support special user #" + targetUserId); 14687 } 14688 // Check shell permission 14689 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14690 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14691 targetUserId)) { 14692 throw new SecurityException("Shell does not have permission to access user " 14693 + targetUserId + "\n " + Debug.getCallers(3)); 14694 } 14695 } 14696 return targetUserId; 14697 } 14698 14699 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14700 String className, int flags) { 14701 boolean result = false; 14702 // For apps that don't have pre-defined UIDs, check for permission 14703 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14704 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14705 if (ActivityManager.checkUidPermission( 14706 INTERACT_ACROSS_USERS, 14707 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14708 ComponentName comp = new ComponentName(aInfo.packageName, className); 14709 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14710 + " requests FLAG_SINGLE_USER, but app does not hold " 14711 + INTERACT_ACROSS_USERS; 14712 Slog.w(TAG, msg); 14713 throw new SecurityException(msg); 14714 } 14715 // Permission passed 14716 result = true; 14717 } 14718 } else if ("system".equals(componentProcessName)) { 14719 result = true; 14720 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14721 // Phone app and persistent apps are allowed to export singleuser providers. 14722 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14723 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14724 } 14725 if (DEBUG_MU) { 14726 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14727 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14728 } 14729 return result; 14730 } 14731 14732 /** 14733 * Checks to see if the caller is in the same app as the singleton 14734 * component, or the component is in a special app. It allows special apps 14735 * to export singleton components but prevents exporting singleton 14736 * components for regular apps. 14737 */ 14738 boolean isValidSingletonCall(int callingUid, int componentUid) { 14739 int componentAppId = UserHandle.getAppId(componentUid); 14740 return UserHandle.isSameApp(callingUid, componentUid) 14741 || componentAppId == Process.SYSTEM_UID 14742 || componentAppId == Process.PHONE_UID 14743 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14744 == PackageManager.PERMISSION_GRANTED; 14745 } 14746 14747 public int bindService(IApplicationThread caller, IBinder token, 14748 Intent service, String resolvedType, 14749 IServiceConnection connection, int flags, int userId) { 14750 enforceNotIsolatedCaller("bindService"); 14751 14752 // Refuse possible leaked file descriptors 14753 if (service != null && service.hasFileDescriptors() == true) { 14754 throw new IllegalArgumentException("File descriptors passed in Intent"); 14755 } 14756 14757 synchronized(this) { 14758 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14759 connection, flags, userId); 14760 } 14761 } 14762 14763 public boolean unbindService(IServiceConnection connection) { 14764 synchronized (this) { 14765 return mServices.unbindServiceLocked(connection); 14766 } 14767 } 14768 14769 public void publishService(IBinder token, Intent intent, IBinder service) { 14770 // Refuse possible leaked file descriptors 14771 if (intent != null && intent.hasFileDescriptors() == true) { 14772 throw new IllegalArgumentException("File descriptors passed in Intent"); 14773 } 14774 14775 synchronized(this) { 14776 if (!(token instanceof ServiceRecord)) { 14777 throw new IllegalArgumentException("Invalid service token"); 14778 } 14779 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14780 } 14781 } 14782 14783 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14784 // Refuse possible leaked file descriptors 14785 if (intent != null && intent.hasFileDescriptors() == true) { 14786 throw new IllegalArgumentException("File descriptors passed in Intent"); 14787 } 14788 14789 synchronized(this) { 14790 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14791 } 14792 } 14793 14794 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14795 synchronized(this) { 14796 if (!(token instanceof ServiceRecord)) { 14797 throw new IllegalArgumentException("Invalid service token"); 14798 } 14799 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14800 } 14801 } 14802 14803 // ========================================================= 14804 // BACKUP AND RESTORE 14805 // ========================================================= 14806 14807 // Cause the target app to be launched if necessary and its backup agent 14808 // instantiated. The backup agent will invoke backupAgentCreated() on the 14809 // activity manager to announce its creation. 14810 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14811 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14812 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14813 14814 synchronized(this) { 14815 // !!! TODO: currently no check here that we're already bound 14816 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14817 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14818 synchronized (stats) { 14819 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14820 } 14821 14822 // Backup agent is now in use, its package can't be stopped. 14823 try { 14824 AppGlobals.getPackageManager().setPackageStoppedState( 14825 app.packageName, false, UserHandle.getUserId(app.uid)); 14826 } catch (RemoteException e) { 14827 } catch (IllegalArgumentException e) { 14828 Slog.w(TAG, "Failed trying to unstop package " 14829 + app.packageName + ": " + e); 14830 } 14831 14832 BackupRecord r = new BackupRecord(ss, app, backupMode); 14833 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14834 ? new ComponentName(app.packageName, app.backupAgentName) 14835 : new ComponentName("android", "FullBackupAgent"); 14836 // startProcessLocked() returns existing proc's record if it's already running 14837 ProcessRecord proc = startProcessLocked(app.processName, app, 14838 false, 0, "backup", hostingName, false, false, false); 14839 if (proc == null) { 14840 Slog.e(TAG, "Unable to start backup agent process " + r); 14841 return false; 14842 } 14843 14844 r.app = proc; 14845 mBackupTarget = r; 14846 mBackupAppName = app.packageName; 14847 14848 // Try not to kill the process during backup 14849 updateOomAdjLocked(proc); 14850 14851 // If the process is already attached, schedule the creation of the backup agent now. 14852 // If it is not yet live, this will be done when it attaches to the framework. 14853 if (proc.thread != null) { 14854 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14855 try { 14856 proc.thread.scheduleCreateBackupAgent(app, 14857 compatibilityInfoForPackageLocked(app), backupMode); 14858 } catch (RemoteException e) { 14859 // Will time out on the backup manager side 14860 } 14861 } else { 14862 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14863 } 14864 // Invariants: at this point, the target app process exists and the application 14865 // is either already running or in the process of coming up. mBackupTarget and 14866 // mBackupAppName describe the app, so that when it binds back to the AM we 14867 // know that it's scheduled for a backup-agent operation. 14868 } 14869 14870 return true; 14871 } 14872 14873 @Override 14874 public void clearPendingBackup() { 14875 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14876 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14877 14878 synchronized (this) { 14879 mBackupTarget = null; 14880 mBackupAppName = null; 14881 } 14882 } 14883 14884 // A backup agent has just come up 14885 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14886 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14887 + " = " + agent); 14888 14889 synchronized(this) { 14890 if (!agentPackageName.equals(mBackupAppName)) { 14891 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14892 return; 14893 } 14894 } 14895 14896 long oldIdent = Binder.clearCallingIdentity(); 14897 try { 14898 IBackupManager bm = IBackupManager.Stub.asInterface( 14899 ServiceManager.getService(Context.BACKUP_SERVICE)); 14900 bm.agentConnected(agentPackageName, agent); 14901 } catch (RemoteException e) { 14902 // can't happen; the backup manager service is local 14903 } catch (Exception e) { 14904 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14905 e.printStackTrace(); 14906 } finally { 14907 Binder.restoreCallingIdentity(oldIdent); 14908 } 14909 } 14910 14911 // done with this agent 14912 public void unbindBackupAgent(ApplicationInfo appInfo) { 14913 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14914 if (appInfo == null) { 14915 Slog.w(TAG, "unbind backup agent for null app"); 14916 return; 14917 } 14918 14919 synchronized(this) { 14920 try { 14921 if (mBackupAppName == null) { 14922 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14923 return; 14924 } 14925 14926 if (!mBackupAppName.equals(appInfo.packageName)) { 14927 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14928 return; 14929 } 14930 14931 // Not backing this app up any more; reset its OOM adjustment 14932 final ProcessRecord proc = mBackupTarget.app; 14933 updateOomAdjLocked(proc); 14934 14935 // If the app crashed during backup, 'thread' will be null here 14936 if (proc.thread != null) { 14937 try { 14938 proc.thread.scheduleDestroyBackupAgent(appInfo, 14939 compatibilityInfoForPackageLocked(appInfo)); 14940 } catch (Exception e) { 14941 Slog.e(TAG, "Exception when unbinding backup agent:"); 14942 e.printStackTrace(); 14943 } 14944 } 14945 } finally { 14946 mBackupTarget = null; 14947 mBackupAppName = null; 14948 } 14949 } 14950 } 14951 // ========================================================= 14952 // BROADCASTS 14953 // ========================================================= 14954 14955 private final List getStickiesLocked(String action, IntentFilter filter, 14956 List cur, int userId) { 14957 final ContentResolver resolver = mContext.getContentResolver(); 14958 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14959 if (stickies == null) { 14960 return cur; 14961 } 14962 final ArrayList<Intent> list = stickies.get(action); 14963 if (list == null) { 14964 return cur; 14965 } 14966 int N = list.size(); 14967 for (int i=0; i<N; i++) { 14968 Intent intent = list.get(i); 14969 if (filter.match(resolver, intent, true, TAG) >= 0) { 14970 if (cur == null) { 14971 cur = new ArrayList<Intent>(); 14972 } 14973 cur.add(intent); 14974 } 14975 } 14976 return cur; 14977 } 14978 14979 boolean isPendingBroadcastProcessLocked(int pid) { 14980 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14981 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14982 } 14983 14984 void skipPendingBroadcastLocked(int pid) { 14985 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14986 for (BroadcastQueue queue : mBroadcastQueues) { 14987 queue.skipPendingBroadcastLocked(pid); 14988 } 14989 } 14990 14991 // The app just attached; send any pending broadcasts that it should receive 14992 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14993 boolean didSomething = false; 14994 for (BroadcastQueue queue : mBroadcastQueues) { 14995 didSomething |= queue.sendPendingBroadcastsLocked(app); 14996 } 14997 return didSomething; 14998 } 14999 15000 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 15001 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 15002 enforceNotIsolatedCaller("registerReceiver"); 15003 int callingUid; 15004 int callingPid; 15005 synchronized(this) { 15006 ProcessRecord callerApp = null; 15007 if (caller != null) { 15008 callerApp = getRecordForAppLocked(caller); 15009 if (callerApp == null) { 15010 throw new SecurityException( 15011 "Unable to find app for caller " + caller 15012 + " (pid=" + Binder.getCallingPid() 15013 + ") when registering receiver " + receiver); 15014 } 15015 if (callerApp.info.uid != Process.SYSTEM_UID && 15016 !callerApp.pkgList.containsKey(callerPackage) && 15017 !"android".equals(callerPackage)) { 15018 throw new SecurityException("Given caller package " + callerPackage 15019 + " is not running in process " + callerApp); 15020 } 15021 callingUid = callerApp.info.uid; 15022 callingPid = callerApp.pid; 15023 } else { 15024 callerPackage = null; 15025 callingUid = Binder.getCallingUid(); 15026 callingPid = Binder.getCallingPid(); 15027 } 15028 15029 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15030 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15031 15032 List allSticky = null; 15033 15034 // Look for any matching sticky broadcasts... 15035 Iterator actions = filter.actionsIterator(); 15036 if (actions != null) { 15037 while (actions.hasNext()) { 15038 String action = (String)actions.next(); 15039 allSticky = getStickiesLocked(action, filter, allSticky, 15040 UserHandle.USER_ALL); 15041 allSticky = getStickiesLocked(action, filter, allSticky, 15042 UserHandle.getUserId(callingUid)); 15043 } 15044 } else { 15045 allSticky = getStickiesLocked(null, filter, allSticky, 15046 UserHandle.USER_ALL); 15047 allSticky = getStickiesLocked(null, filter, allSticky, 15048 UserHandle.getUserId(callingUid)); 15049 } 15050 15051 // The first sticky in the list is returned directly back to 15052 // the client. 15053 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15054 15055 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15056 + ": " + sticky); 15057 15058 if (receiver == null) { 15059 return sticky; 15060 } 15061 15062 ReceiverList rl 15063 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15064 if (rl == null) { 15065 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15066 userId, receiver); 15067 if (rl.app != null) { 15068 rl.app.receivers.add(rl); 15069 } else { 15070 try { 15071 receiver.asBinder().linkToDeath(rl, 0); 15072 } catch (RemoteException e) { 15073 return sticky; 15074 } 15075 rl.linkedToDeath = true; 15076 } 15077 mRegisteredReceivers.put(receiver.asBinder(), rl); 15078 } else if (rl.uid != callingUid) { 15079 throw new IllegalArgumentException( 15080 "Receiver requested to register for uid " + callingUid 15081 + " was previously registered for uid " + rl.uid); 15082 } else if (rl.pid != callingPid) { 15083 throw new IllegalArgumentException( 15084 "Receiver requested to register for pid " + callingPid 15085 + " was previously registered for pid " + rl.pid); 15086 } else if (rl.userId != userId) { 15087 throw new IllegalArgumentException( 15088 "Receiver requested to register for user " + userId 15089 + " was previously registered for user " + rl.userId); 15090 } 15091 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15092 permission, callingUid, userId); 15093 rl.add(bf); 15094 if (!bf.debugCheck()) { 15095 Slog.w(TAG, "==> For Dynamic broadast"); 15096 } 15097 mReceiverResolver.addFilter(bf); 15098 15099 // Enqueue broadcasts for all existing stickies that match 15100 // this filter. 15101 if (allSticky != null) { 15102 ArrayList receivers = new ArrayList(); 15103 receivers.add(bf); 15104 15105 int N = allSticky.size(); 15106 for (int i=0; i<N; i++) { 15107 Intent intent = (Intent)allSticky.get(i); 15108 BroadcastQueue queue = broadcastQueueForIntent(intent); 15109 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15110 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15111 null, null, false, true, true, -1); 15112 queue.enqueueParallelBroadcastLocked(r); 15113 queue.scheduleBroadcastsLocked(); 15114 } 15115 } 15116 15117 return sticky; 15118 } 15119 } 15120 15121 public void unregisterReceiver(IIntentReceiver receiver) { 15122 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15123 15124 final long origId = Binder.clearCallingIdentity(); 15125 try { 15126 boolean doTrim = false; 15127 15128 synchronized(this) { 15129 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15130 if (rl != null) { 15131 if (rl.curBroadcast != null) { 15132 BroadcastRecord r = rl.curBroadcast; 15133 final boolean doNext = finishReceiverLocked( 15134 receiver.asBinder(), r.resultCode, r.resultData, 15135 r.resultExtras, r.resultAbort); 15136 if (doNext) { 15137 doTrim = true; 15138 r.queue.processNextBroadcast(false); 15139 } 15140 } 15141 15142 if (rl.app != null) { 15143 rl.app.receivers.remove(rl); 15144 } 15145 removeReceiverLocked(rl); 15146 if (rl.linkedToDeath) { 15147 rl.linkedToDeath = false; 15148 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15149 } 15150 } 15151 } 15152 15153 // If we actually concluded any broadcasts, we might now be able 15154 // to trim the recipients' apps from our working set 15155 if (doTrim) { 15156 trimApplications(); 15157 return; 15158 } 15159 15160 } finally { 15161 Binder.restoreCallingIdentity(origId); 15162 } 15163 } 15164 15165 void removeReceiverLocked(ReceiverList rl) { 15166 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15167 int N = rl.size(); 15168 for (int i=0; i<N; i++) { 15169 mReceiverResolver.removeFilter(rl.get(i)); 15170 } 15171 } 15172 15173 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15174 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15175 ProcessRecord r = mLruProcesses.get(i); 15176 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15177 try { 15178 r.thread.dispatchPackageBroadcast(cmd, packages); 15179 } catch (RemoteException ex) { 15180 } 15181 } 15182 } 15183 } 15184 15185 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15186 int callingUid, int[] users) { 15187 List<ResolveInfo> receivers = null; 15188 try { 15189 HashSet<ComponentName> singleUserReceivers = null; 15190 boolean scannedFirstReceivers = false; 15191 for (int user : users) { 15192 // Skip users that have Shell restrictions 15193 if (callingUid == Process.SHELL_UID 15194 && getUserManagerLocked().hasUserRestriction( 15195 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15196 continue; 15197 } 15198 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15199 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15200 if (user != 0 && newReceivers != null) { 15201 // If this is not the primary user, we need to check for 15202 // any receivers that should be filtered out. 15203 for (int i=0; i<newReceivers.size(); i++) { 15204 ResolveInfo ri = newReceivers.get(i); 15205 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15206 newReceivers.remove(i); 15207 i--; 15208 } 15209 } 15210 } 15211 if (newReceivers != null && newReceivers.size() == 0) { 15212 newReceivers = null; 15213 } 15214 if (receivers == null) { 15215 receivers = newReceivers; 15216 } else if (newReceivers != null) { 15217 // We need to concatenate the additional receivers 15218 // found with what we have do far. This would be easy, 15219 // but we also need to de-dup any receivers that are 15220 // singleUser. 15221 if (!scannedFirstReceivers) { 15222 // Collect any single user receivers we had already retrieved. 15223 scannedFirstReceivers = true; 15224 for (int i=0; i<receivers.size(); i++) { 15225 ResolveInfo ri = receivers.get(i); 15226 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15227 ComponentName cn = new ComponentName( 15228 ri.activityInfo.packageName, ri.activityInfo.name); 15229 if (singleUserReceivers == null) { 15230 singleUserReceivers = new HashSet<ComponentName>(); 15231 } 15232 singleUserReceivers.add(cn); 15233 } 15234 } 15235 } 15236 // Add the new results to the existing results, tracking 15237 // and de-dupping single user receivers. 15238 for (int i=0; i<newReceivers.size(); i++) { 15239 ResolveInfo ri = newReceivers.get(i); 15240 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15241 ComponentName cn = new ComponentName( 15242 ri.activityInfo.packageName, ri.activityInfo.name); 15243 if (singleUserReceivers == null) { 15244 singleUserReceivers = new HashSet<ComponentName>(); 15245 } 15246 if (!singleUserReceivers.contains(cn)) { 15247 singleUserReceivers.add(cn); 15248 receivers.add(ri); 15249 } 15250 } else { 15251 receivers.add(ri); 15252 } 15253 } 15254 } 15255 } 15256 } catch (RemoteException ex) { 15257 // pm is in same process, this will never happen. 15258 } 15259 return receivers; 15260 } 15261 15262 private final int broadcastIntentLocked(ProcessRecord callerApp, 15263 String callerPackage, Intent intent, String resolvedType, 15264 IIntentReceiver resultTo, int resultCode, String resultData, 15265 Bundle map, String requiredPermission, int appOp, 15266 boolean ordered, boolean sticky, int callingPid, int callingUid, 15267 int userId) { 15268 intent = new Intent(intent); 15269 15270 // By default broadcasts do not go to stopped apps. 15271 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15272 15273 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15274 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15275 + " ordered=" + ordered + " userid=" + userId); 15276 if ((resultTo != null) && !ordered) { 15277 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15278 } 15279 15280 userId = handleIncomingUser(callingPid, callingUid, userId, 15281 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15282 15283 // Make sure that the user who is receiving this broadcast is started. 15284 // If not, we will just skip it. 15285 15286 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15287 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15288 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15289 Slog.w(TAG, "Skipping broadcast of " + intent 15290 + ": user " + userId + " is stopped"); 15291 return ActivityManager.BROADCAST_SUCCESS; 15292 } 15293 } 15294 15295 /* 15296 * Prevent non-system code (defined here to be non-persistent 15297 * processes) from sending protected broadcasts. 15298 */ 15299 int callingAppId = UserHandle.getAppId(callingUid); 15300 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15301 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15302 || callingAppId == Process.NFC_UID || callingUid == 0) { 15303 // Always okay. 15304 } else if (callerApp == null || !callerApp.persistent) { 15305 try { 15306 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15307 intent.getAction())) { 15308 String msg = "Permission Denial: not allowed to send broadcast " 15309 + intent.getAction() + " from pid=" 15310 + callingPid + ", uid=" + callingUid; 15311 Slog.w(TAG, msg); 15312 throw new SecurityException(msg); 15313 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15314 // Special case for compatibility: we don't want apps to send this, 15315 // but historically it has not been protected and apps may be using it 15316 // to poke their own app widget. So, instead of making it protected, 15317 // just limit it to the caller. 15318 if (callerApp == null) { 15319 String msg = "Permission Denial: not allowed to send broadcast " 15320 + intent.getAction() + " from unknown caller."; 15321 Slog.w(TAG, msg); 15322 throw new SecurityException(msg); 15323 } else if (intent.getComponent() != null) { 15324 // They are good enough to send to an explicit component... verify 15325 // it is being sent to the calling app. 15326 if (!intent.getComponent().getPackageName().equals( 15327 callerApp.info.packageName)) { 15328 String msg = "Permission Denial: not allowed to send broadcast " 15329 + intent.getAction() + " to " 15330 + intent.getComponent().getPackageName() + " from " 15331 + callerApp.info.packageName; 15332 Slog.w(TAG, msg); 15333 throw new SecurityException(msg); 15334 } 15335 } else { 15336 // Limit broadcast to their own package. 15337 intent.setPackage(callerApp.info.packageName); 15338 } 15339 } 15340 } catch (RemoteException e) { 15341 Slog.w(TAG, "Remote exception", e); 15342 return ActivityManager.BROADCAST_SUCCESS; 15343 } 15344 } 15345 15346 // Handle special intents: if this broadcast is from the package 15347 // manager about a package being removed, we need to remove all of 15348 // its activities from the history stack. 15349 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15350 intent.getAction()); 15351 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15352 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15353 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15354 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15355 || uidRemoved) { 15356 if (checkComponentPermission( 15357 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15358 callingPid, callingUid, -1, true) 15359 == PackageManager.PERMISSION_GRANTED) { 15360 if (uidRemoved) { 15361 final Bundle intentExtras = intent.getExtras(); 15362 final int uid = intentExtras != null 15363 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15364 if (uid >= 0) { 15365 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15366 synchronized (bs) { 15367 bs.removeUidStatsLocked(uid); 15368 } 15369 mAppOpsService.uidRemoved(uid); 15370 } 15371 } else { 15372 // If resources are unavailable just force stop all 15373 // those packages and flush the attribute cache as well. 15374 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15375 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15376 if (list != null && (list.length > 0)) { 15377 for (String pkg : list) { 15378 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15379 "storage unmount"); 15380 } 15381 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15382 sendPackageBroadcastLocked( 15383 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15384 } 15385 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15386 intent.getAction())) { 15387 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15388 } else { 15389 Uri data = intent.getData(); 15390 String ssp; 15391 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15392 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15393 intent.getAction()); 15394 boolean fullUninstall = removed && 15395 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15396 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15397 forceStopPackageLocked(ssp, UserHandle.getAppId( 15398 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15399 false, fullUninstall, userId, 15400 removed ? "pkg removed" : "pkg changed"); 15401 } 15402 if (removed) { 15403 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15404 new String[] {ssp}, userId); 15405 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15406 mAppOpsService.packageRemoved( 15407 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15408 15409 // Remove all permissions granted from/to this package 15410 removeUriPermissionsForPackageLocked(ssp, userId, true); 15411 } 15412 } 15413 } 15414 } 15415 } 15416 } else { 15417 String msg = "Permission Denial: " + intent.getAction() 15418 + " broadcast from " + callerPackage + " (pid=" + callingPid 15419 + ", uid=" + callingUid + ")" 15420 + " requires " 15421 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15422 Slog.w(TAG, msg); 15423 throw new SecurityException(msg); 15424 } 15425 15426 // Special case for adding a package: by default turn on compatibility 15427 // mode. 15428 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15429 Uri data = intent.getData(); 15430 String ssp; 15431 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15432 mCompatModePackages.handlePackageAddedLocked(ssp, 15433 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15434 } 15435 } 15436 15437 /* 15438 * If this is the time zone changed action, queue up a message that will reset the timezone 15439 * of all currently running processes. This message will get queued up before the broadcast 15440 * happens. 15441 */ 15442 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15443 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15444 } 15445 15446 /* 15447 * If the user set the time, let all running processes know. 15448 */ 15449 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15450 final int is24Hour = intent.getBooleanExtra( 15451 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15452 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15453 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15454 synchronized (stats) { 15455 stats.noteCurrentTimeChangedLocked(); 15456 } 15457 } 15458 15459 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15460 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15461 } 15462 15463 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15464 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15465 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15466 } 15467 15468 // Add to the sticky list if requested. 15469 if (sticky) { 15470 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15471 callingPid, callingUid) 15472 != PackageManager.PERMISSION_GRANTED) { 15473 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15474 + callingPid + ", uid=" + callingUid 15475 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15476 Slog.w(TAG, msg); 15477 throw new SecurityException(msg); 15478 } 15479 if (requiredPermission != null) { 15480 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15481 + " and enforce permission " + requiredPermission); 15482 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15483 } 15484 if (intent.getComponent() != null) { 15485 throw new SecurityException( 15486 "Sticky broadcasts can't target a specific component"); 15487 } 15488 // We use userId directly here, since the "all" target is maintained 15489 // as a separate set of sticky broadcasts. 15490 if (userId != UserHandle.USER_ALL) { 15491 // But first, if this is not a broadcast to all users, then 15492 // make sure it doesn't conflict with an existing broadcast to 15493 // all users. 15494 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15495 UserHandle.USER_ALL); 15496 if (stickies != null) { 15497 ArrayList<Intent> list = stickies.get(intent.getAction()); 15498 if (list != null) { 15499 int N = list.size(); 15500 int i; 15501 for (i=0; i<N; i++) { 15502 if (intent.filterEquals(list.get(i))) { 15503 throw new IllegalArgumentException( 15504 "Sticky broadcast " + intent + " for user " 15505 + userId + " conflicts with existing global broadcast"); 15506 } 15507 } 15508 } 15509 } 15510 } 15511 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15512 if (stickies == null) { 15513 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15514 mStickyBroadcasts.put(userId, stickies); 15515 } 15516 ArrayList<Intent> list = stickies.get(intent.getAction()); 15517 if (list == null) { 15518 list = new ArrayList<Intent>(); 15519 stickies.put(intent.getAction(), list); 15520 } 15521 int N = list.size(); 15522 int i; 15523 for (i=0; i<N; i++) { 15524 if (intent.filterEquals(list.get(i))) { 15525 // This sticky already exists, replace it. 15526 list.set(i, new Intent(intent)); 15527 break; 15528 } 15529 } 15530 if (i >= N) { 15531 list.add(new Intent(intent)); 15532 } 15533 } 15534 15535 int[] users; 15536 if (userId == UserHandle.USER_ALL) { 15537 // Caller wants broadcast to go to all started users. 15538 users = mStartedUserArray; 15539 } else { 15540 // Caller wants broadcast to go to one specific user. 15541 users = new int[] {userId}; 15542 } 15543 15544 // Figure out who all will receive this broadcast. 15545 List receivers = null; 15546 List<BroadcastFilter> registeredReceivers = null; 15547 // Need to resolve the intent to interested receivers... 15548 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15549 == 0) { 15550 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15551 } 15552 if (intent.getComponent() == null) { 15553 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15554 // Query one target user at a time, excluding shell-restricted users 15555 UserManagerService ums = getUserManagerLocked(); 15556 for (int i = 0; i < users.length; i++) { 15557 if (ums.hasUserRestriction( 15558 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15559 continue; 15560 } 15561 List<BroadcastFilter> registeredReceiversForUser = 15562 mReceiverResolver.queryIntent(intent, 15563 resolvedType, false, users[i]); 15564 if (registeredReceivers == null) { 15565 registeredReceivers = registeredReceiversForUser; 15566 } else if (registeredReceiversForUser != null) { 15567 registeredReceivers.addAll(registeredReceiversForUser); 15568 } 15569 } 15570 } else { 15571 registeredReceivers = mReceiverResolver.queryIntent(intent, 15572 resolvedType, false, userId); 15573 } 15574 } 15575 15576 final boolean replacePending = 15577 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15578 15579 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15580 + " replacePending=" + replacePending); 15581 15582 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15583 if (!ordered && NR > 0) { 15584 // If we are not serializing this broadcast, then send the 15585 // registered receivers separately so they don't wait for the 15586 // components to be launched. 15587 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15588 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15589 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15590 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15591 ordered, sticky, false, userId); 15592 if (DEBUG_BROADCAST) Slog.v( 15593 TAG, "Enqueueing parallel broadcast " + r); 15594 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15595 if (!replaced) { 15596 queue.enqueueParallelBroadcastLocked(r); 15597 queue.scheduleBroadcastsLocked(); 15598 } 15599 registeredReceivers = null; 15600 NR = 0; 15601 } 15602 15603 // Merge into one list. 15604 int ir = 0; 15605 if (receivers != null) { 15606 // A special case for PACKAGE_ADDED: do not allow the package 15607 // being added to see this broadcast. This prevents them from 15608 // using this as a back door to get run as soon as they are 15609 // installed. Maybe in the future we want to have a special install 15610 // broadcast or such for apps, but we'd like to deliberately make 15611 // this decision. 15612 String skipPackages[] = null; 15613 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15614 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15615 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15616 Uri data = intent.getData(); 15617 if (data != null) { 15618 String pkgName = data.getSchemeSpecificPart(); 15619 if (pkgName != null) { 15620 skipPackages = new String[] { pkgName }; 15621 } 15622 } 15623 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15624 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15625 } 15626 if (skipPackages != null && (skipPackages.length > 0)) { 15627 for (String skipPackage : skipPackages) { 15628 if (skipPackage != null) { 15629 int NT = receivers.size(); 15630 for (int it=0; it<NT; it++) { 15631 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15632 if (curt.activityInfo.packageName.equals(skipPackage)) { 15633 receivers.remove(it); 15634 it--; 15635 NT--; 15636 } 15637 } 15638 } 15639 } 15640 } 15641 15642 int NT = receivers != null ? receivers.size() : 0; 15643 int it = 0; 15644 ResolveInfo curt = null; 15645 BroadcastFilter curr = null; 15646 while (it < NT && ir < NR) { 15647 if (curt == null) { 15648 curt = (ResolveInfo)receivers.get(it); 15649 } 15650 if (curr == null) { 15651 curr = registeredReceivers.get(ir); 15652 } 15653 if (curr.getPriority() >= curt.priority) { 15654 // Insert this broadcast record into the final list. 15655 receivers.add(it, curr); 15656 ir++; 15657 curr = null; 15658 it++; 15659 NT++; 15660 } else { 15661 // Skip to the next ResolveInfo in the final list. 15662 it++; 15663 curt = null; 15664 } 15665 } 15666 } 15667 while (ir < NR) { 15668 if (receivers == null) { 15669 receivers = new ArrayList(); 15670 } 15671 receivers.add(registeredReceivers.get(ir)); 15672 ir++; 15673 } 15674 15675 if ((receivers != null && receivers.size() > 0) 15676 || resultTo != null) { 15677 BroadcastQueue queue = broadcastQueueForIntent(intent); 15678 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15679 callerPackage, callingPid, callingUid, resolvedType, 15680 requiredPermission, appOp, receivers, resultTo, resultCode, 15681 resultData, map, ordered, sticky, false, userId); 15682 if (DEBUG_BROADCAST) Slog.v( 15683 TAG, "Enqueueing ordered broadcast " + r 15684 + ": prev had " + queue.mOrderedBroadcasts.size()); 15685 if (DEBUG_BROADCAST) { 15686 int seq = r.intent.getIntExtra("seq", -1); 15687 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15688 } 15689 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15690 if (!replaced) { 15691 queue.enqueueOrderedBroadcastLocked(r); 15692 queue.scheduleBroadcastsLocked(); 15693 } 15694 } 15695 15696 return ActivityManager.BROADCAST_SUCCESS; 15697 } 15698 15699 final Intent verifyBroadcastLocked(Intent intent) { 15700 // Refuse possible leaked file descriptors 15701 if (intent != null && intent.hasFileDescriptors() == true) { 15702 throw new IllegalArgumentException("File descriptors passed in Intent"); 15703 } 15704 15705 int flags = intent.getFlags(); 15706 15707 if (!mProcessesReady) { 15708 // if the caller really truly claims to know what they're doing, go 15709 // ahead and allow the broadcast without launching any receivers 15710 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15711 intent = new Intent(intent); 15712 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15713 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15714 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15715 + " before boot completion"); 15716 throw new IllegalStateException("Cannot broadcast before boot completed"); 15717 } 15718 } 15719 15720 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15721 throw new IllegalArgumentException( 15722 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15723 } 15724 15725 return intent; 15726 } 15727 15728 public final int broadcastIntent(IApplicationThread caller, 15729 Intent intent, String resolvedType, IIntentReceiver resultTo, 15730 int resultCode, String resultData, Bundle map, 15731 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15732 enforceNotIsolatedCaller("broadcastIntent"); 15733 synchronized(this) { 15734 intent = verifyBroadcastLocked(intent); 15735 15736 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15737 final int callingPid = Binder.getCallingPid(); 15738 final int callingUid = Binder.getCallingUid(); 15739 final long origId = Binder.clearCallingIdentity(); 15740 int res = broadcastIntentLocked(callerApp, 15741 callerApp != null ? callerApp.info.packageName : null, 15742 intent, resolvedType, resultTo, 15743 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15744 callingPid, callingUid, userId); 15745 Binder.restoreCallingIdentity(origId); 15746 return res; 15747 } 15748 } 15749 15750 int broadcastIntentInPackage(String packageName, int uid, 15751 Intent intent, String resolvedType, IIntentReceiver resultTo, 15752 int resultCode, String resultData, Bundle map, 15753 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15754 synchronized(this) { 15755 intent = verifyBroadcastLocked(intent); 15756 15757 final long origId = Binder.clearCallingIdentity(); 15758 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15759 resultTo, resultCode, resultData, map, requiredPermission, 15760 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15761 Binder.restoreCallingIdentity(origId); 15762 return res; 15763 } 15764 } 15765 15766 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15767 // Refuse possible leaked file descriptors 15768 if (intent != null && intent.hasFileDescriptors() == true) { 15769 throw new IllegalArgumentException("File descriptors passed in Intent"); 15770 } 15771 15772 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15773 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15774 15775 synchronized(this) { 15776 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15777 != PackageManager.PERMISSION_GRANTED) { 15778 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15779 + Binder.getCallingPid() 15780 + ", uid=" + Binder.getCallingUid() 15781 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15782 Slog.w(TAG, msg); 15783 throw new SecurityException(msg); 15784 } 15785 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15786 if (stickies != null) { 15787 ArrayList<Intent> list = stickies.get(intent.getAction()); 15788 if (list != null) { 15789 int N = list.size(); 15790 int i; 15791 for (i=0; i<N; i++) { 15792 if (intent.filterEquals(list.get(i))) { 15793 list.remove(i); 15794 break; 15795 } 15796 } 15797 if (list.size() <= 0) { 15798 stickies.remove(intent.getAction()); 15799 } 15800 } 15801 if (stickies.size() <= 0) { 15802 mStickyBroadcasts.remove(userId); 15803 } 15804 } 15805 } 15806 } 15807 15808 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15809 String resultData, Bundle resultExtras, boolean resultAbort) { 15810 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15811 if (r == null) { 15812 Slog.w(TAG, "finishReceiver called but not found on queue"); 15813 return false; 15814 } 15815 15816 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15817 } 15818 15819 void backgroundServicesFinishedLocked(int userId) { 15820 for (BroadcastQueue queue : mBroadcastQueues) { 15821 queue.backgroundServicesFinishedLocked(userId); 15822 } 15823 } 15824 15825 public void finishReceiver(IBinder who, int resultCode, String resultData, 15826 Bundle resultExtras, boolean resultAbort) { 15827 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15828 15829 // Refuse possible leaked file descriptors 15830 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15831 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15832 } 15833 15834 final long origId = Binder.clearCallingIdentity(); 15835 try { 15836 boolean doNext = false; 15837 BroadcastRecord r; 15838 15839 synchronized(this) { 15840 r = broadcastRecordForReceiverLocked(who); 15841 if (r != null) { 15842 doNext = r.queue.finishReceiverLocked(r, resultCode, 15843 resultData, resultExtras, resultAbort, true); 15844 } 15845 } 15846 15847 if (doNext) { 15848 r.queue.processNextBroadcast(false); 15849 } 15850 trimApplications(); 15851 } finally { 15852 Binder.restoreCallingIdentity(origId); 15853 } 15854 } 15855 15856 // ========================================================= 15857 // INSTRUMENTATION 15858 // ========================================================= 15859 15860 public boolean startInstrumentation(ComponentName className, 15861 String profileFile, int flags, Bundle arguments, 15862 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15863 int userId, String abiOverride) { 15864 enforceNotIsolatedCaller("startInstrumentation"); 15865 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15866 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15867 // Refuse possible leaked file descriptors 15868 if (arguments != null && arguments.hasFileDescriptors()) { 15869 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15870 } 15871 15872 synchronized(this) { 15873 InstrumentationInfo ii = null; 15874 ApplicationInfo ai = null; 15875 try { 15876 ii = mContext.getPackageManager().getInstrumentationInfo( 15877 className, STOCK_PM_FLAGS); 15878 ai = AppGlobals.getPackageManager().getApplicationInfo( 15879 ii.targetPackage, STOCK_PM_FLAGS, userId); 15880 } catch (PackageManager.NameNotFoundException e) { 15881 } catch (RemoteException e) { 15882 } 15883 if (ii == null) { 15884 reportStartInstrumentationFailure(watcher, className, 15885 "Unable to find instrumentation info for: " + className); 15886 return false; 15887 } 15888 if (ai == null) { 15889 reportStartInstrumentationFailure(watcher, className, 15890 "Unable to find instrumentation target package: " + ii.targetPackage); 15891 return false; 15892 } 15893 15894 int match = mContext.getPackageManager().checkSignatures( 15895 ii.targetPackage, ii.packageName); 15896 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15897 String msg = "Permission Denial: starting instrumentation " 15898 + className + " from pid=" 15899 + Binder.getCallingPid() 15900 + ", uid=" + Binder.getCallingPid() 15901 + " not allowed because package " + ii.packageName 15902 + " does not have a signature matching the target " 15903 + ii.targetPackage; 15904 reportStartInstrumentationFailure(watcher, className, msg); 15905 throw new SecurityException(msg); 15906 } 15907 15908 final long origId = Binder.clearCallingIdentity(); 15909 // Instrumentation can kill and relaunch even persistent processes 15910 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15911 "start instr"); 15912 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15913 app.instrumentationClass = className; 15914 app.instrumentationInfo = ai; 15915 app.instrumentationProfileFile = profileFile; 15916 app.instrumentationArguments = arguments; 15917 app.instrumentationWatcher = watcher; 15918 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15919 app.instrumentationResultClass = className; 15920 Binder.restoreCallingIdentity(origId); 15921 } 15922 15923 return true; 15924 } 15925 15926 /** 15927 * Report errors that occur while attempting to start Instrumentation. Always writes the 15928 * error to the logs, but if somebody is watching, send the report there too. This enables 15929 * the "am" command to report errors with more information. 15930 * 15931 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15932 * @param cn The component name of the instrumentation. 15933 * @param report The error report. 15934 */ 15935 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15936 ComponentName cn, String report) { 15937 Slog.w(TAG, report); 15938 try { 15939 if (watcher != null) { 15940 Bundle results = new Bundle(); 15941 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15942 results.putString("Error", report); 15943 watcher.instrumentationStatus(cn, -1, results); 15944 } 15945 } catch (RemoteException e) { 15946 Slog.w(TAG, e); 15947 } 15948 } 15949 15950 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15951 if (app.instrumentationWatcher != null) { 15952 try { 15953 // NOTE: IInstrumentationWatcher *must* be oneway here 15954 app.instrumentationWatcher.instrumentationFinished( 15955 app.instrumentationClass, 15956 resultCode, 15957 results); 15958 } catch (RemoteException e) { 15959 } 15960 } 15961 if (app.instrumentationUiAutomationConnection != null) { 15962 try { 15963 app.instrumentationUiAutomationConnection.shutdown(); 15964 } catch (RemoteException re) { 15965 /* ignore */ 15966 } 15967 // Only a UiAutomation can set this flag and now that 15968 // it is finished we make sure it is reset to its default. 15969 mUserIsMonkey = false; 15970 } 15971 app.instrumentationWatcher = null; 15972 app.instrumentationUiAutomationConnection = null; 15973 app.instrumentationClass = null; 15974 app.instrumentationInfo = null; 15975 app.instrumentationProfileFile = null; 15976 app.instrumentationArguments = null; 15977 15978 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15979 "finished inst"); 15980 } 15981 15982 public void finishInstrumentation(IApplicationThread target, 15983 int resultCode, Bundle results) { 15984 int userId = UserHandle.getCallingUserId(); 15985 // Refuse possible leaked file descriptors 15986 if (results != null && results.hasFileDescriptors()) { 15987 throw new IllegalArgumentException("File descriptors passed in Intent"); 15988 } 15989 15990 synchronized(this) { 15991 ProcessRecord app = getRecordForAppLocked(target); 15992 if (app == null) { 15993 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15994 return; 15995 } 15996 final long origId = Binder.clearCallingIdentity(); 15997 finishInstrumentationLocked(app, resultCode, results); 15998 Binder.restoreCallingIdentity(origId); 15999 } 16000 } 16001 16002 // ========================================================= 16003 // CONFIGURATION 16004 // ========================================================= 16005 16006 public ConfigurationInfo getDeviceConfigurationInfo() { 16007 ConfigurationInfo config = new ConfigurationInfo(); 16008 synchronized (this) { 16009 config.reqTouchScreen = mConfiguration.touchscreen; 16010 config.reqKeyboardType = mConfiguration.keyboard; 16011 config.reqNavigation = mConfiguration.navigation; 16012 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16013 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16014 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16015 } 16016 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16017 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16018 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16019 } 16020 config.reqGlEsVersion = GL_ES_VERSION; 16021 } 16022 return config; 16023 } 16024 16025 ActivityStack getFocusedStack() { 16026 return mStackSupervisor.getFocusedStack(); 16027 } 16028 16029 public Configuration getConfiguration() { 16030 Configuration ci; 16031 synchronized(this) { 16032 ci = new Configuration(mConfiguration); 16033 } 16034 return ci; 16035 } 16036 16037 public void updatePersistentConfiguration(Configuration values) { 16038 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16039 "updateConfiguration()"); 16040 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16041 "updateConfiguration()"); 16042 if (values == null) { 16043 throw new NullPointerException("Configuration must not be null"); 16044 } 16045 16046 synchronized(this) { 16047 final long origId = Binder.clearCallingIdentity(); 16048 updateConfigurationLocked(values, null, true, false); 16049 Binder.restoreCallingIdentity(origId); 16050 } 16051 } 16052 16053 public void updateConfiguration(Configuration values) { 16054 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16055 "updateConfiguration()"); 16056 16057 synchronized(this) { 16058 if (values == null && mWindowManager != null) { 16059 // sentinel: fetch the current configuration from the window manager 16060 values = mWindowManager.computeNewConfiguration(); 16061 } 16062 16063 if (mWindowManager != null) { 16064 mProcessList.applyDisplaySize(mWindowManager); 16065 } 16066 16067 final long origId = Binder.clearCallingIdentity(); 16068 if (values != null) { 16069 Settings.System.clearConfiguration(values); 16070 } 16071 updateConfigurationLocked(values, null, false, false); 16072 Binder.restoreCallingIdentity(origId); 16073 } 16074 } 16075 16076 /** 16077 * Do either or both things: (1) change the current configuration, and (2) 16078 * make sure the given activity is running with the (now) current 16079 * configuration. Returns true if the activity has been left running, or 16080 * false if <var>starting</var> is being destroyed to match the new 16081 * configuration. 16082 * @param persistent TODO 16083 */ 16084 boolean updateConfigurationLocked(Configuration values, 16085 ActivityRecord starting, boolean persistent, boolean initLocale) { 16086 int changes = 0; 16087 16088 if (values != null) { 16089 Configuration newConfig = new Configuration(mConfiguration); 16090 changes = newConfig.updateFrom(values); 16091 if (changes != 0) { 16092 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16093 Slog.i(TAG, "Updating configuration to: " + values); 16094 } 16095 16096 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16097 16098 if (values.locale != null && !initLocale) { 16099 saveLocaleLocked(values.locale, 16100 !values.locale.equals(mConfiguration.locale), 16101 values.userSetLocale); 16102 } 16103 16104 mConfigurationSeq++; 16105 if (mConfigurationSeq <= 0) { 16106 mConfigurationSeq = 1; 16107 } 16108 newConfig.seq = mConfigurationSeq; 16109 mConfiguration = newConfig; 16110 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16111 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16112 //mUsageStatsService.noteStartConfig(newConfig); 16113 16114 final Configuration configCopy = new Configuration(mConfiguration); 16115 16116 // TODO: If our config changes, should we auto dismiss any currently 16117 // showing dialogs? 16118 mShowDialogs = shouldShowDialogs(newConfig); 16119 16120 AttributeCache ac = AttributeCache.instance(); 16121 if (ac != null) { 16122 ac.updateConfiguration(configCopy); 16123 } 16124 16125 // Make sure all resources in our process are updated 16126 // right now, so that anyone who is going to retrieve 16127 // resource values after we return will be sure to get 16128 // the new ones. This is especially important during 16129 // boot, where the first config change needs to guarantee 16130 // all resources have that config before following boot 16131 // code is executed. 16132 mSystemThread.applyConfigurationToResources(configCopy); 16133 16134 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16135 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16136 msg.obj = new Configuration(configCopy); 16137 mHandler.sendMessage(msg); 16138 } 16139 16140 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16141 ProcessRecord app = mLruProcesses.get(i); 16142 try { 16143 if (app.thread != null) { 16144 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16145 + app.processName + " new config " + mConfiguration); 16146 app.thread.scheduleConfigurationChanged(configCopy); 16147 } 16148 } catch (Exception e) { 16149 } 16150 } 16151 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16152 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16153 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16154 | Intent.FLAG_RECEIVER_FOREGROUND); 16155 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16156 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16157 Process.SYSTEM_UID, UserHandle.USER_ALL); 16158 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16159 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16160 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16161 broadcastIntentLocked(null, null, intent, 16162 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16163 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16164 } 16165 } 16166 } 16167 16168 boolean kept = true; 16169 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16170 // mainStack is null during startup. 16171 if (mainStack != null) { 16172 if (changes != 0 && starting == null) { 16173 // If the configuration changed, and the caller is not already 16174 // in the process of starting an activity, then find the top 16175 // activity to check if its configuration needs to change. 16176 starting = mainStack.topRunningActivityLocked(null); 16177 } 16178 16179 if (starting != null) { 16180 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16181 // And we need to make sure at this point that all other activities 16182 // are made visible with the correct configuration. 16183 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16184 } 16185 } 16186 16187 if (values != null && mWindowManager != null) { 16188 mWindowManager.setNewConfiguration(mConfiguration); 16189 } 16190 16191 return kept; 16192 } 16193 16194 /** 16195 * Decide based on the configuration whether we should shouw the ANR, 16196 * crash, etc dialogs. The idea is that if there is no affordnace to 16197 * press the on-screen buttons, we shouldn't show the dialog. 16198 * 16199 * A thought: SystemUI might also want to get told about this, the Power 16200 * dialog / global actions also might want different behaviors. 16201 */ 16202 private static final boolean shouldShowDialogs(Configuration config) { 16203 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16204 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16205 } 16206 16207 /** 16208 * Save the locale. You must be inside a synchronized (this) block. 16209 */ 16210 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16211 if(isDiff) { 16212 SystemProperties.set("user.language", l.getLanguage()); 16213 SystemProperties.set("user.region", l.getCountry()); 16214 } 16215 16216 if(isPersist) { 16217 SystemProperties.set("persist.sys.language", l.getLanguage()); 16218 SystemProperties.set("persist.sys.country", l.getCountry()); 16219 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16220 } 16221 } 16222 16223 @Override 16224 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16225 synchronized (this) { 16226 ActivityRecord srec = ActivityRecord.forToken(token); 16227 if (srec.task != null && srec.task.stack != null) { 16228 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16229 } 16230 } 16231 return false; 16232 } 16233 16234 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16235 Intent resultData) { 16236 16237 synchronized (this) { 16238 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16239 if (stack != null) { 16240 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16241 } 16242 return false; 16243 } 16244 } 16245 16246 public int getLaunchedFromUid(IBinder activityToken) { 16247 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16248 if (srec == null) { 16249 return -1; 16250 } 16251 return srec.launchedFromUid; 16252 } 16253 16254 public String getLaunchedFromPackage(IBinder activityToken) { 16255 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16256 if (srec == null) { 16257 return null; 16258 } 16259 return srec.launchedFromPackage; 16260 } 16261 16262 // ========================================================= 16263 // LIFETIME MANAGEMENT 16264 // ========================================================= 16265 16266 // Returns which broadcast queue the app is the current [or imminent] receiver 16267 // on, or 'null' if the app is not an active broadcast recipient. 16268 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16269 BroadcastRecord r = app.curReceiver; 16270 if (r != null) { 16271 return r.queue; 16272 } 16273 16274 // It's not the current receiver, but it might be starting up to become one 16275 synchronized (this) { 16276 for (BroadcastQueue queue : mBroadcastQueues) { 16277 r = queue.mPendingBroadcast; 16278 if (r != null && r.curApp == app) { 16279 // found it; report which queue it's in 16280 return queue; 16281 } 16282 } 16283 } 16284 16285 return null; 16286 } 16287 16288 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16289 boolean doingAll, long now) { 16290 if (mAdjSeq == app.adjSeq) { 16291 // This adjustment has already been computed. 16292 return app.curRawAdj; 16293 } 16294 16295 if (app.thread == null) { 16296 app.adjSeq = mAdjSeq; 16297 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16298 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16299 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16300 } 16301 16302 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16303 app.adjSource = null; 16304 app.adjTarget = null; 16305 app.empty = false; 16306 app.cached = false; 16307 16308 final int activitiesSize = app.activities.size(); 16309 16310 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16311 // The max adjustment doesn't allow this app to be anything 16312 // below foreground, so it is not worth doing work for it. 16313 app.adjType = "fixed"; 16314 app.adjSeq = mAdjSeq; 16315 app.curRawAdj = app.maxAdj; 16316 app.foregroundActivities = false; 16317 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16318 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16319 // System processes can do UI, and when they do we want to have 16320 // them trim their memory after the user leaves the UI. To 16321 // facilitate this, here we need to determine whether or not it 16322 // is currently showing UI. 16323 app.systemNoUi = true; 16324 if (app == TOP_APP) { 16325 app.systemNoUi = false; 16326 } else if (activitiesSize > 0) { 16327 for (int j = 0; j < activitiesSize; j++) { 16328 final ActivityRecord r = app.activities.get(j); 16329 if (r.visible) { 16330 app.systemNoUi = false; 16331 } 16332 } 16333 } 16334 if (!app.systemNoUi) { 16335 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16336 } 16337 return (app.curAdj=app.maxAdj); 16338 } 16339 16340 app.systemNoUi = false; 16341 16342 // Determine the importance of the process, starting with most 16343 // important to least, and assign an appropriate OOM adjustment. 16344 int adj; 16345 int schedGroup; 16346 int procState; 16347 boolean foregroundActivities = false; 16348 BroadcastQueue queue; 16349 if (app == TOP_APP) { 16350 // The last app on the list is the foreground app. 16351 adj = ProcessList.FOREGROUND_APP_ADJ; 16352 schedGroup = Process.THREAD_GROUP_DEFAULT; 16353 app.adjType = "top-activity"; 16354 foregroundActivities = true; 16355 procState = ActivityManager.PROCESS_STATE_TOP; 16356 } else if (app.instrumentationClass != null) { 16357 // Don't want to kill running instrumentation. 16358 adj = ProcessList.FOREGROUND_APP_ADJ; 16359 schedGroup = Process.THREAD_GROUP_DEFAULT; 16360 app.adjType = "instrumentation"; 16361 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16362 } else if ((queue = isReceivingBroadcast(app)) != null) { 16363 // An app that is currently receiving a broadcast also 16364 // counts as being in the foreground for OOM killer purposes. 16365 // It's placed in a sched group based on the nature of the 16366 // broadcast as reflected by which queue it's active in. 16367 adj = ProcessList.FOREGROUND_APP_ADJ; 16368 schedGroup = (queue == mFgBroadcastQueue) 16369 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16370 app.adjType = "broadcast"; 16371 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16372 } else if (app.executingServices.size() > 0) { 16373 // An app that is currently executing a service callback also 16374 // counts as being in the foreground. 16375 adj = ProcessList.FOREGROUND_APP_ADJ; 16376 schedGroup = app.execServicesFg ? 16377 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16378 app.adjType = "exec-service"; 16379 procState = ActivityManager.PROCESS_STATE_SERVICE; 16380 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16381 } else { 16382 // As far as we know the process is empty. We may change our mind later. 16383 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16384 // At this point we don't actually know the adjustment. Use the cached adj 16385 // value that the caller wants us to. 16386 adj = cachedAdj; 16387 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16388 app.cached = true; 16389 app.empty = true; 16390 app.adjType = "cch-empty"; 16391 } 16392 16393 // Examine all activities if not already foreground. 16394 if (!foregroundActivities && activitiesSize > 0) { 16395 for (int j = 0; j < activitiesSize; j++) { 16396 final ActivityRecord r = app.activities.get(j); 16397 if (r.app != app) { 16398 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16399 + app + "?!?"); 16400 continue; 16401 } 16402 if (r.visible) { 16403 // App has a visible activity; only upgrade adjustment. 16404 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16405 adj = ProcessList.VISIBLE_APP_ADJ; 16406 app.adjType = "visible"; 16407 } 16408 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16409 procState = ActivityManager.PROCESS_STATE_TOP; 16410 } 16411 schedGroup = Process.THREAD_GROUP_DEFAULT; 16412 app.cached = false; 16413 app.empty = false; 16414 foregroundActivities = true; 16415 break; 16416 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16417 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16418 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16419 app.adjType = "pausing"; 16420 } 16421 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16422 procState = ActivityManager.PROCESS_STATE_TOP; 16423 } 16424 schedGroup = Process.THREAD_GROUP_DEFAULT; 16425 app.cached = false; 16426 app.empty = false; 16427 foregroundActivities = true; 16428 } else if (r.state == ActivityState.STOPPING) { 16429 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16430 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16431 app.adjType = "stopping"; 16432 } 16433 // For the process state, we will at this point consider the 16434 // process to be cached. It will be cached either as an activity 16435 // or empty depending on whether the activity is finishing. We do 16436 // this so that we can treat the process as cached for purposes of 16437 // memory trimming (determing current memory level, trim command to 16438 // send to process) since there can be an arbitrary number of stopping 16439 // processes and they should soon all go into the cached state. 16440 if (!r.finishing) { 16441 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16442 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16443 } 16444 } 16445 app.cached = false; 16446 app.empty = false; 16447 foregroundActivities = true; 16448 } else { 16449 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16450 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16451 app.adjType = "cch-act"; 16452 } 16453 } 16454 } 16455 } 16456 16457 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16458 if (app.foregroundServices) { 16459 // The user is aware of this app, so make it visible. 16460 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16461 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16462 app.cached = false; 16463 app.adjType = "fg-service"; 16464 schedGroup = Process.THREAD_GROUP_DEFAULT; 16465 } else if (app.forcingToForeground != null) { 16466 // The user is aware of this app, so make it visible. 16467 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16468 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16469 app.cached = false; 16470 app.adjType = "force-fg"; 16471 app.adjSource = app.forcingToForeground; 16472 schedGroup = Process.THREAD_GROUP_DEFAULT; 16473 } 16474 } 16475 16476 if (app == mHeavyWeightProcess) { 16477 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16478 // We don't want to kill the current heavy-weight process. 16479 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16480 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16481 app.cached = false; 16482 app.adjType = "heavy"; 16483 } 16484 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16485 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16486 } 16487 } 16488 16489 if (app == mHomeProcess) { 16490 if (adj > ProcessList.HOME_APP_ADJ) { 16491 // This process is hosting what we currently consider to be the 16492 // home app, so we don't want to let it go into the background. 16493 adj = ProcessList.HOME_APP_ADJ; 16494 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16495 app.cached = false; 16496 app.adjType = "home"; 16497 } 16498 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16499 procState = ActivityManager.PROCESS_STATE_HOME; 16500 } 16501 } 16502 16503 if (app == mPreviousProcess && app.activities.size() > 0) { 16504 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16505 // This was the previous process that showed UI to the user. 16506 // We want to try to keep it around more aggressively, to give 16507 // a good experience around switching between two apps. 16508 adj = ProcessList.PREVIOUS_APP_ADJ; 16509 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16510 app.cached = false; 16511 app.adjType = "previous"; 16512 } 16513 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16514 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16515 } 16516 } 16517 16518 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16519 + " reason=" + app.adjType); 16520 16521 // By default, we use the computed adjustment. It may be changed if 16522 // there are applications dependent on our services or providers, but 16523 // this gives us a baseline and makes sure we don't get into an 16524 // infinite recursion. 16525 app.adjSeq = mAdjSeq; 16526 app.curRawAdj = adj; 16527 app.hasStartedServices = false; 16528 16529 if (mBackupTarget != null && app == mBackupTarget.app) { 16530 // If possible we want to avoid killing apps while they're being backed up 16531 if (adj > ProcessList.BACKUP_APP_ADJ) { 16532 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16533 adj = ProcessList.BACKUP_APP_ADJ; 16534 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16535 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16536 } 16537 app.adjType = "backup"; 16538 app.cached = false; 16539 } 16540 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16541 procState = ActivityManager.PROCESS_STATE_BACKUP; 16542 } 16543 } 16544 16545 boolean mayBeTop = false; 16546 16547 for (int is = app.services.size()-1; 16548 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16549 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16550 || procState > ActivityManager.PROCESS_STATE_TOP); 16551 is--) { 16552 ServiceRecord s = app.services.valueAt(is); 16553 if (s.startRequested) { 16554 app.hasStartedServices = true; 16555 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16556 procState = ActivityManager.PROCESS_STATE_SERVICE; 16557 } 16558 if (app.hasShownUi && app != mHomeProcess) { 16559 // If this process has shown some UI, let it immediately 16560 // go to the LRU list because it may be pretty heavy with 16561 // UI stuff. We'll tag it with a label just to help 16562 // debug and understand what is going on. 16563 if (adj > ProcessList.SERVICE_ADJ) { 16564 app.adjType = "cch-started-ui-services"; 16565 } 16566 } else { 16567 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16568 // This service has seen some activity within 16569 // recent memory, so we will keep its process ahead 16570 // of the background processes. 16571 if (adj > ProcessList.SERVICE_ADJ) { 16572 adj = ProcessList.SERVICE_ADJ; 16573 app.adjType = "started-services"; 16574 app.cached = false; 16575 } 16576 } 16577 // If we have let the service slide into the background 16578 // state, still have some text describing what it is doing 16579 // even though the service no longer has an impact. 16580 if (adj > ProcessList.SERVICE_ADJ) { 16581 app.adjType = "cch-started-services"; 16582 } 16583 } 16584 } 16585 for (int conni = s.connections.size()-1; 16586 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16587 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16588 || procState > ActivityManager.PROCESS_STATE_TOP); 16589 conni--) { 16590 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16591 for (int i = 0; 16592 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16593 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16594 || procState > ActivityManager.PROCESS_STATE_TOP); 16595 i++) { 16596 // XXX should compute this based on the max of 16597 // all connected clients. 16598 ConnectionRecord cr = clist.get(i); 16599 if (cr.binding.client == app) { 16600 // Binding to ourself is not interesting. 16601 continue; 16602 } 16603 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16604 ProcessRecord client = cr.binding.client; 16605 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16606 TOP_APP, doingAll, now); 16607 int clientProcState = client.curProcState; 16608 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16609 // If the other app is cached for any reason, for purposes here 16610 // we are going to consider it empty. The specific cached state 16611 // doesn't propagate except under certain conditions. 16612 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16613 } 16614 String adjType = null; 16615 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16616 // Not doing bind OOM management, so treat 16617 // this guy more like a started service. 16618 if (app.hasShownUi && app != mHomeProcess) { 16619 // If this process has shown some UI, let it immediately 16620 // go to the LRU list because it may be pretty heavy with 16621 // UI stuff. We'll tag it with a label just to help 16622 // debug and understand what is going on. 16623 if (adj > clientAdj) { 16624 adjType = "cch-bound-ui-services"; 16625 } 16626 app.cached = false; 16627 clientAdj = adj; 16628 clientProcState = procState; 16629 } else { 16630 if (now >= (s.lastActivity 16631 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16632 // This service has not seen activity within 16633 // recent memory, so allow it to drop to the 16634 // LRU list if there is no other reason to keep 16635 // it around. We'll also tag it with a label just 16636 // to help debug and undertand what is going on. 16637 if (adj > clientAdj) { 16638 adjType = "cch-bound-services"; 16639 } 16640 clientAdj = adj; 16641 } 16642 } 16643 } 16644 if (adj > clientAdj) { 16645 // If this process has recently shown UI, and 16646 // the process that is binding to it is less 16647 // important than being visible, then we don't 16648 // care about the binding as much as we care 16649 // about letting this process get into the LRU 16650 // list to be killed and restarted if needed for 16651 // memory. 16652 if (app.hasShownUi && app != mHomeProcess 16653 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16654 adjType = "cch-bound-ui-services"; 16655 } else { 16656 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16657 |Context.BIND_IMPORTANT)) != 0) { 16658 adj = clientAdj; 16659 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16660 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16661 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16662 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16663 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16664 adj = clientAdj; 16665 } else { 16666 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16667 adj = ProcessList.VISIBLE_APP_ADJ; 16668 } 16669 } 16670 if (!client.cached) { 16671 app.cached = false; 16672 } 16673 adjType = "service"; 16674 } 16675 } 16676 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16677 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16678 schedGroup = Process.THREAD_GROUP_DEFAULT; 16679 } 16680 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16681 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16682 // Special handling of clients who are in the top state. 16683 // We *may* want to consider this process to be in the 16684 // top state as well, but only if there is not another 16685 // reason for it to be running. Being on the top is a 16686 // special state, meaning you are specifically running 16687 // for the current top app. If the process is already 16688 // running in the background for some other reason, it 16689 // is more important to continue considering it to be 16690 // in the background state. 16691 mayBeTop = true; 16692 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16693 } else { 16694 // Special handling for above-top states (persistent 16695 // processes). These should not bring the current process 16696 // into the top state, since they are not on top. Instead 16697 // give them the best state after that. 16698 clientProcState = 16699 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16700 } 16701 } 16702 } else { 16703 if (clientProcState < 16704 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16705 clientProcState = 16706 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16707 } 16708 } 16709 if (procState > clientProcState) { 16710 procState = clientProcState; 16711 } 16712 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16713 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16714 app.pendingUiClean = true; 16715 } 16716 if (adjType != null) { 16717 app.adjType = adjType; 16718 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16719 .REASON_SERVICE_IN_USE; 16720 app.adjSource = cr.binding.client; 16721 app.adjSourceProcState = clientProcState; 16722 app.adjTarget = s.name; 16723 } 16724 } 16725 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16726 app.treatLikeActivity = true; 16727 } 16728 final ActivityRecord a = cr.activity; 16729 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16730 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16731 (a.visible || a.state == ActivityState.RESUMED 16732 || a.state == ActivityState.PAUSING)) { 16733 adj = ProcessList.FOREGROUND_APP_ADJ; 16734 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16735 schedGroup = Process.THREAD_GROUP_DEFAULT; 16736 } 16737 app.cached = false; 16738 app.adjType = "service"; 16739 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16740 .REASON_SERVICE_IN_USE; 16741 app.adjSource = a; 16742 app.adjSourceProcState = procState; 16743 app.adjTarget = s.name; 16744 } 16745 } 16746 } 16747 } 16748 } 16749 16750 for (int provi = app.pubProviders.size()-1; 16751 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16752 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16753 || procState > ActivityManager.PROCESS_STATE_TOP); 16754 provi--) { 16755 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16756 for (int i = cpr.connections.size()-1; 16757 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16758 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16759 || procState > ActivityManager.PROCESS_STATE_TOP); 16760 i--) { 16761 ContentProviderConnection conn = cpr.connections.get(i); 16762 ProcessRecord client = conn.client; 16763 if (client == app) { 16764 // Being our own client is not interesting. 16765 continue; 16766 } 16767 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16768 int clientProcState = client.curProcState; 16769 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16770 // If the other app is cached for any reason, for purposes here 16771 // we are going to consider it empty. 16772 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16773 } 16774 if (adj > clientAdj) { 16775 if (app.hasShownUi && app != mHomeProcess 16776 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16777 app.adjType = "cch-ui-provider"; 16778 } else { 16779 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16780 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16781 app.adjType = "provider"; 16782 } 16783 app.cached &= client.cached; 16784 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16785 .REASON_PROVIDER_IN_USE; 16786 app.adjSource = client; 16787 app.adjSourceProcState = clientProcState; 16788 app.adjTarget = cpr.name; 16789 } 16790 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16791 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16792 // Special handling of clients who are in the top state. 16793 // We *may* want to consider this process to be in the 16794 // top state as well, but only if there is not another 16795 // reason for it to be running. Being on the top is a 16796 // special state, meaning you are specifically running 16797 // for the current top app. If the process is already 16798 // running in the background for some other reason, it 16799 // is more important to continue considering it to be 16800 // in the background state. 16801 mayBeTop = true; 16802 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16803 } else { 16804 // Special handling for above-top states (persistent 16805 // processes). These should not bring the current process 16806 // into the top state, since they are not on top. Instead 16807 // give them the best state after that. 16808 clientProcState = 16809 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16810 } 16811 } 16812 if (procState > clientProcState) { 16813 procState = clientProcState; 16814 } 16815 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16816 schedGroup = Process.THREAD_GROUP_DEFAULT; 16817 } 16818 } 16819 // If the provider has external (non-framework) process 16820 // dependencies, ensure that its adjustment is at least 16821 // FOREGROUND_APP_ADJ. 16822 if (cpr.hasExternalProcessHandles()) { 16823 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16824 adj = ProcessList.FOREGROUND_APP_ADJ; 16825 schedGroup = Process.THREAD_GROUP_DEFAULT; 16826 app.cached = false; 16827 app.adjType = "provider"; 16828 app.adjTarget = cpr.name; 16829 } 16830 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16831 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16832 } 16833 } 16834 } 16835 16836 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16837 // A client of one of our services or providers is in the top state. We 16838 // *may* want to be in the top state, but not if we are already running in 16839 // the background for some other reason. For the decision here, we are going 16840 // to pick out a few specific states that we want to remain in when a client 16841 // is top (states that tend to be longer-term) and otherwise allow it to go 16842 // to the top state. 16843 switch (procState) { 16844 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16845 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16846 case ActivityManager.PROCESS_STATE_SERVICE: 16847 // These all are longer-term states, so pull them up to the top 16848 // of the background states, but not all the way to the top state. 16849 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16850 break; 16851 default: 16852 // Otherwise, top is a better choice, so take it. 16853 procState = ActivityManager.PROCESS_STATE_TOP; 16854 break; 16855 } 16856 } 16857 16858 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16859 if (app.hasClientActivities) { 16860 // This is a cached process, but with client activities. Mark it so. 16861 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16862 app.adjType = "cch-client-act"; 16863 } else if (app.treatLikeActivity) { 16864 // This is a cached process, but somebody wants us to treat it like it has 16865 // an activity, okay! 16866 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16867 app.adjType = "cch-as-act"; 16868 } 16869 } 16870 16871 if (adj == ProcessList.SERVICE_ADJ) { 16872 if (doingAll) { 16873 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16874 mNewNumServiceProcs++; 16875 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16876 if (!app.serviceb) { 16877 // This service isn't far enough down on the LRU list to 16878 // normally be a B service, but if we are low on RAM and it 16879 // is large we want to force it down since we would prefer to 16880 // keep launcher over it. 16881 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16882 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16883 app.serviceHighRam = true; 16884 app.serviceb = true; 16885 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16886 } else { 16887 mNewNumAServiceProcs++; 16888 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16889 } 16890 } else { 16891 app.serviceHighRam = false; 16892 } 16893 } 16894 if (app.serviceb) { 16895 adj = ProcessList.SERVICE_B_ADJ; 16896 } 16897 } 16898 16899 app.curRawAdj = adj; 16900 16901 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16902 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16903 if (adj > app.maxAdj) { 16904 adj = app.maxAdj; 16905 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16906 schedGroup = Process.THREAD_GROUP_DEFAULT; 16907 } 16908 } 16909 16910 // Do final modification to adj. Everything we do between here and applying 16911 // the final setAdj must be done in this function, because we will also use 16912 // it when computing the final cached adj later. Note that we don't need to 16913 // worry about this for max adj above, since max adj will always be used to 16914 // keep it out of the cached vaues. 16915 app.curAdj = app.modifyRawOomAdj(adj); 16916 app.curSchedGroup = schedGroup; 16917 app.curProcState = procState; 16918 app.foregroundActivities = foregroundActivities; 16919 16920 return app.curRawAdj; 16921 } 16922 16923 /** 16924 * Schedule PSS collection of a process. 16925 */ 16926 void requestPssLocked(ProcessRecord proc, int procState) { 16927 if (mPendingPssProcesses.contains(proc)) { 16928 return; 16929 } 16930 if (mPendingPssProcesses.size() == 0) { 16931 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16932 } 16933 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16934 proc.pssProcState = procState; 16935 mPendingPssProcesses.add(proc); 16936 } 16937 16938 /** 16939 * Schedule PSS collection of all processes. 16940 */ 16941 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16942 if (!always) { 16943 if (now < (mLastFullPssTime + 16944 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16945 return; 16946 } 16947 } 16948 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16949 mLastFullPssTime = now; 16950 mFullPssPending = true; 16951 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16952 mPendingPssProcesses.clear(); 16953 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16954 ProcessRecord app = mLruProcesses.get(i); 16955 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16956 app.pssProcState = app.setProcState; 16957 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16958 isSleeping(), now); 16959 mPendingPssProcesses.add(app); 16960 } 16961 } 16962 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16963 } 16964 16965 /** 16966 * Ask a given process to GC right now. 16967 */ 16968 final void performAppGcLocked(ProcessRecord app) { 16969 try { 16970 app.lastRequestedGc = SystemClock.uptimeMillis(); 16971 if (app.thread != null) { 16972 if (app.reportLowMemory) { 16973 app.reportLowMemory = false; 16974 app.thread.scheduleLowMemory(); 16975 } else { 16976 app.thread.processInBackground(); 16977 } 16978 } 16979 } catch (Exception e) { 16980 // whatever. 16981 } 16982 } 16983 16984 /** 16985 * Returns true if things are idle enough to perform GCs. 16986 */ 16987 private final boolean canGcNowLocked() { 16988 boolean processingBroadcasts = false; 16989 for (BroadcastQueue q : mBroadcastQueues) { 16990 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16991 processingBroadcasts = true; 16992 } 16993 } 16994 return !processingBroadcasts 16995 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16996 } 16997 16998 /** 16999 * Perform GCs on all processes that are waiting for it, but only 17000 * if things are idle. 17001 */ 17002 final void performAppGcsLocked() { 17003 final int N = mProcessesToGc.size(); 17004 if (N <= 0) { 17005 return; 17006 } 17007 if (canGcNowLocked()) { 17008 while (mProcessesToGc.size() > 0) { 17009 ProcessRecord proc = mProcessesToGc.remove(0); 17010 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17011 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17012 <= SystemClock.uptimeMillis()) { 17013 // To avoid spamming the system, we will GC processes one 17014 // at a time, waiting a few seconds between each. 17015 performAppGcLocked(proc); 17016 scheduleAppGcsLocked(); 17017 return; 17018 } else { 17019 // It hasn't been long enough since we last GCed this 17020 // process... put it in the list to wait for its time. 17021 addProcessToGcListLocked(proc); 17022 break; 17023 } 17024 } 17025 } 17026 17027 scheduleAppGcsLocked(); 17028 } 17029 } 17030 17031 /** 17032 * If all looks good, perform GCs on all processes waiting for them. 17033 */ 17034 final void performAppGcsIfAppropriateLocked() { 17035 if (canGcNowLocked()) { 17036 performAppGcsLocked(); 17037 return; 17038 } 17039 // Still not idle, wait some more. 17040 scheduleAppGcsLocked(); 17041 } 17042 17043 /** 17044 * Schedule the execution of all pending app GCs. 17045 */ 17046 final void scheduleAppGcsLocked() { 17047 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17048 17049 if (mProcessesToGc.size() > 0) { 17050 // Schedule a GC for the time to the next process. 17051 ProcessRecord proc = mProcessesToGc.get(0); 17052 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17053 17054 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17055 long now = SystemClock.uptimeMillis(); 17056 if (when < (now+GC_TIMEOUT)) { 17057 when = now + GC_TIMEOUT; 17058 } 17059 mHandler.sendMessageAtTime(msg, when); 17060 } 17061 } 17062 17063 /** 17064 * Add a process to the array of processes waiting to be GCed. Keeps the 17065 * list in sorted order by the last GC time. The process can't already be 17066 * on the list. 17067 */ 17068 final void addProcessToGcListLocked(ProcessRecord proc) { 17069 boolean added = false; 17070 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17071 if (mProcessesToGc.get(i).lastRequestedGc < 17072 proc.lastRequestedGc) { 17073 added = true; 17074 mProcessesToGc.add(i+1, proc); 17075 break; 17076 } 17077 } 17078 if (!added) { 17079 mProcessesToGc.add(0, proc); 17080 } 17081 } 17082 17083 /** 17084 * Set up to ask a process to GC itself. This will either do it 17085 * immediately, or put it on the list of processes to gc the next 17086 * time things are idle. 17087 */ 17088 final void scheduleAppGcLocked(ProcessRecord app) { 17089 long now = SystemClock.uptimeMillis(); 17090 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17091 return; 17092 } 17093 if (!mProcessesToGc.contains(app)) { 17094 addProcessToGcListLocked(app); 17095 scheduleAppGcsLocked(); 17096 } 17097 } 17098 17099 final void checkExcessivePowerUsageLocked(boolean doKills) { 17100 updateCpuStatsNow(); 17101 17102 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17103 boolean doWakeKills = doKills; 17104 boolean doCpuKills = doKills; 17105 if (mLastPowerCheckRealtime == 0) { 17106 doWakeKills = false; 17107 } 17108 if (mLastPowerCheckUptime == 0) { 17109 doCpuKills = false; 17110 } 17111 if (stats.isScreenOn()) { 17112 doWakeKills = false; 17113 } 17114 final long curRealtime = SystemClock.elapsedRealtime(); 17115 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17116 final long curUptime = SystemClock.uptimeMillis(); 17117 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17118 mLastPowerCheckRealtime = curRealtime; 17119 mLastPowerCheckUptime = curUptime; 17120 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17121 doWakeKills = false; 17122 } 17123 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17124 doCpuKills = false; 17125 } 17126 int i = mLruProcesses.size(); 17127 while (i > 0) { 17128 i--; 17129 ProcessRecord app = mLruProcesses.get(i); 17130 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17131 long wtime; 17132 synchronized (stats) { 17133 wtime = stats.getProcessWakeTime(app.info.uid, 17134 app.pid, curRealtime); 17135 } 17136 long wtimeUsed = wtime - app.lastWakeTime; 17137 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17138 if (DEBUG_POWER) { 17139 StringBuilder sb = new StringBuilder(128); 17140 sb.append("Wake for "); 17141 app.toShortString(sb); 17142 sb.append(": over "); 17143 TimeUtils.formatDuration(realtimeSince, sb); 17144 sb.append(" used "); 17145 TimeUtils.formatDuration(wtimeUsed, sb); 17146 sb.append(" ("); 17147 sb.append((wtimeUsed*100)/realtimeSince); 17148 sb.append("%)"); 17149 Slog.i(TAG, sb.toString()); 17150 sb.setLength(0); 17151 sb.append("CPU for "); 17152 app.toShortString(sb); 17153 sb.append(": over "); 17154 TimeUtils.formatDuration(uptimeSince, sb); 17155 sb.append(" used "); 17156 TimeUtils.formatDuration(cputimeUsed, sb); 17157 sb.append(" ("); 17158 sb.append((cputimeUsed*100)/uptimeSince); 17159 sb.append("%)"); 17160 Slog.i(TAG, sb.toString()); 17161 } 17162 // If a process has held a wake lock for more 17163 // than 50% of the time during this period, 17164 // that sounds bad. Kill! 17165 if (doWakeKills && realtimeSince > 0 17166 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17167 synchronized (stats) { 17168 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17169 realtimeSince, wtimeUsed); 17170 } 17171 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17172 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17173 } else if (doCpuKills && uptimeSince > 0 17174 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17175 synchronized (stats) { 17176 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17177 uptimeSince, cputimeUsed); 17178 } 17179 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17180 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17181 } else { 17182 app.lastWakeTime = wtime; 17183 app.lastCpuTime = app.curCpuTime; 17184 } 17185 } 17186 } 17187 } 17188 17189 private final boolean applyOomAdjLocked(ProcessRecord app, 17190 ProcessRecord TOP_APP, boolean doingAll, long now) { 17191 boolean success = true; 17192 17193 if (app.curRawAdj != app.setRawAdj) { 17194 app.setRawAdj = app.curRawAdj; 17195 } 17196 17197 int changes = 0; 17198 17199 if (app.curAdj != app.setAdj) { 17200 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17201 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17202 TAG, "Set " + app.pid + " " + app.processName + 17203 " adj " + app.curAdj + ": " + app.adjType); 17204 app.setAdj = app.curAdj; 17205 } 17206 17207 if (app.setSchedGroup != app.curSchedGroup) { 17208 app.setSchedGroup = app.curSchedGroup; 17209 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17210 "Setting process group of " + app.processName 17211 + " to " + app.curSchedGroup); 17212 if (app.waitingToKill != null && 17213 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17214 app.kill(app.waitingToKill, true); 17215 success = false; 17216 } else { 17217 if (true) { 17218 long oldId = Binder.clearCallingIdentity(); 17219 try { 17220 Process.setProcessGroup(app.pid, app.curSchedGroup); 17221 } catch (Exception e) { 17222 Slog.w(TAG, "Failed setting process group of " + app.pid 17223 + " to " + app.curSchedGroup); 17224 e.printStackTrace(); 17225 } finally { 17226 Binder.restoreCallingIdentity(oldId); 17227 } 17228 } else { 17229 if (app.thread != null) { 17230 try { 17231 app.thread.setSchedulingGroup(app.curSchedGroup); 17232 } catch (RemoteException e) { 17233 } 17234 } 17235 } 17236 Process.setSwappiness(app.pid, 17237 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17238 } 17239 } 17240 if (app.repForegroundActivities != app.foregroundActivities) { 17241 app.repForegroundActivities = app.foregroundActivities; 17242 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17243 } 17244 if (app.repProcState != app.curProcState) { 17245 app.repProcState = app.curProcState; 17246 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17247 if (app.thread != null) { 17248 try { 17249 if (false) { 17250 //RuntimeException h = new RuntimeException("here"); 17251 Slog.i(TAG, "Sending new process state " + app.repProcState 17252 + " to " + app /*, h*/); 17253 } 17254 app.thread.setProcessState(app.repProcState); 17255 } catch (RemoteException e) { 17256 } 17257 } 17258 } 17259 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17260 app.setProcState)) { 17261 app.lastStateTime = now; 17262 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17263 isSleeping(), now); 17264 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17265 + ProcessList.makeProcStateString(app.setProcState) + " to " 17266 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17267 + (app.nextPssTime-now) + ": " + app); 17268 } else { 17269 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17270 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17271 requestPssLocked(app, app.setProcState); 17272 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17273 isSleeping(), now); 17274 } else if (false && DEBUG_PSS) { 17275 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17276 } 17277 } 17278 if (app.setProcState != app.curProcState) { 17279 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17280 "Proc state change of " + app.processName 17281 + " to " + app.curProcState); 17282 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17283 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17284 if (setImportant && !curImportant) { 17285 // This app is no longer something we consider important enough to allow to 17286 // use arbitrary amounts of battery power. Note 17287 // its current wake lock time to later know to kill it if 17288 // it is not behaving well. 17289 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17290 synchronized (stats) { 17291 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17292 app.pid, SystemClock.elapsedRealtime()); 17293 } 17294 app.lastCpuTime = app.curCpuTime; 17295 17296 } 17297 app.setProcState = app.curProcState; 17298 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17299 app.notCachedSinceIdle = false; 17300 } 17301 if (!doingAll) { 17302 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17303 } else { 17304 app.procStateChanged = true; 17305 } 17306 } 17307 17308 if (changes != 0) { 17309 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17310 int i = mPendingProcessChanges.size()-1; 17311 ProcessChangeItem item = null; 17312 while (i >= 0) { 17313 item = mPendingProcessChanges.get(i); 17314 if (item.pid == app.pid) { 17315 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17316 break; 17317 } 17318 i--; 17319 } 17320 if (i < 0) { 17321 // No existing item in pending changes; need a new one. 17322 final int NA = mAvailProcessChanges.size(); 17323 if (NA > 0) { 17324 item = mAvailProcessChanges.remove(NA-1); 17325 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17326 } else { 17327 item = new ProcessChangeItem(); 17328 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17329 } 17330 item.changes = 0; 17331 item.pid = app.pid; 17332 item.uid = app.info.uid; 17333 if (mPendingProcessChanges.size() == 0) { 17334 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17335 "*** Enqueueing dispatch processes changed!"); 17336 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17337 } 17338 mPendingProcessChanges.add(item); 17339 } 17340 item.changes |= changes; 17341 item.processState = app.repProcState; 17342 item.foregroundActivities = app.repForegroundActivities; 17343 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17344 + Integer.toHexString(System.identityHashCode(item)) 17345 + " " + app.toShortString() + ": changes=" + item.changes 17346 + " procState=" + item.processState 17347 + " foreground=" + item.foregroundActivities 17348 + " type=" + app.adjType + " source=" + app.adjSource 17349 + " target=" + app.adjTarget); 17350 } 17351 17352 return success; 17353 } 17354 17355 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17356 if (proc.thread != null) { 17357 if (proc.baseProcessTracker != null) { 17358 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17359 } 17360 if (proc.repProcState >= 0) { 17361 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17362 proc.repProcState); 17363 } 17364 } 17365 } 17366 17367 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17368 ProcessRecord TOP_APP, boolean doingAll, long now) { 17369 if (app.thread == null) { 17370 return false; 17371 } 17372 17373 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17374 17375 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17376 } 17377 17378 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17379 boolean oomAdj) { 17380 if (isForeground != proc.foregroundServices) { 17381 proc.foregroundServices = isForeground; 17382 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17383 proc.info.uid); 17384 if (isForeground) { 17385 if (curProcs == null) { 17386 curProcs = new ArrayList<ProcessRecord>(); 17387 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17388 } 17389 if (!curProcs.contains(proc)) { 17390 curProcs.add(proc); 17391 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17392 proc.info.packageName, proc.info.uid); 17393 } 17394 } else { 17395 if (curProcs != null) { 17396 if (curProcs.remove(proc)) { 17397 mBatteryStatsService.noteEvent( 17398 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17399 proc.info.packageName, proc.info.uid); 17400 if (curProcs.size() <= 0) { 17401 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17402 } 17403 } 17404 } 17405 } 17406 if (oomAdj) { 17407 updateOomAdjLocked(); 17408 } 17409 } 17410 } 17411 17412 private final ActivityRecord resumedAppLocked() { 17413 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17414 String pkg; 17415 int uid; 17416 if (act != null) { 17417 pkg = act.packageName; 17418 uid = act.info.applicationInfo.uid; 17419 } else { 17420 pkg = null; 17421 uid = -1; 17422 } 17423 // Has the UID or resumed package name changed? 17424 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17425 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17426 if (mCurResumedPackage != null) { 17427 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17428 mCurResumedPackage, mCurResumedUid); 17429 } 17430 mCurResumedPackage = pkg; 17431 mCurResumedUid = uid; 17432 if (mCurResumedPackage != null) { 17433 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17434 mCurResumedPackage, mCurResumedUid); 17435 } 17436 } 17437 return act; 17438 } 17439 17440 final boolean updateOomAdjLocked(ProcessRecord app) { 17441 final ActivityRecord TOP_ACT = resumedAppLocked(); 17442 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17443 final boolean wasCached = app.cached; 17444 17445 mAdjSeq++; 17446 17447 // This is the desired cached adjusment we want to tell it to use. 17448 // If our app is currently cached, we know it, and that is it. Otherwise, 17449 // we don't know it yet, and it needs to now be cached we will then 17450 // need to do a complete oom adj. 17451 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17452 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17453 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17454 SystemClock.uptimeMillis()); 17455 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17456 // Changed to/from cached state, so apps after it in the LRU 17457 // list may also be changed. 17458 updateOomAdjLocked(); 17459 } 17460 return success; 17461 } 17462 17463 final void updateOomAdjLocked() { 17464 final ActivityRecord TOP_ACT = resumedAppLocked(); 17465 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17466 final long now = SystemClock.uptimeMillis(); 17467 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17468 final int N = mLruProcesses.size(); 17469 17470 if (false) { 17471 RuntimeException e = new RuntimeException(); 17472 e.fillInStackTrace(); 17473 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17474 } 17475 17476 mAdjSeq++; 17477 mNewNumServiceProcs = 0; 17478 mNewNumAServiceProcs = 0; 17479 17480 final int emptyProcessLimit; 17481 final int cachedProcessLimit; 17482 if (mProcessLimit <= 0) { 17483 emptyProcessLimit = cachedProcessLimit = 0; 17484 } else if (mProcessLimit == 1) { 17485 emptyProcessLimit = 1; 17486 cachedProcessLimit = 0; 17487 } else { 17488 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17489 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17490 } 17491 17492 // Let's determine how many processes we have running vs. 17493 // how many slots we have for background processes; we may want 17494 // to put multiple processes in a slot of there are enough of 17495 // them. 17496 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17497 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17498 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17499 if (numEmptyProcs > cachedProcessLimit) { 17500 // If there are more empty processes than our limit on cached 17501 // processes, then use the cached process limit for the factor. 17502 // This ensures that the really old empty processes get pushed 17503 // down to the bottom, so if we are running low on memory we will 17504 // have a better chance at keeping around more cached processes 17505 // instead of a gazillion empty processes. 17506 numEmptyProcs = cachedProcessLimit; 17507 } 17508 int emptyFactor = numEmptyProcs/numSlots; 17509 if (emptyFactor < 1) emptyFactor = 1; 17510 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17511 if (cachedFactor < 1) cachedFactor = 1; 17512 int stepCached = 0; 17513 int stepEmpty = 0; 17514 int numCached = 0; 17515 int numEmpty = 0; 17516 int numTrimming = 0; 17517 17518 mNumNonCachedProcs = 0; 17519 mNumCachedHiddenProcs = 0; 17520 17521 // First update the OOM adjustment for each of the 17522 // application processes based on their current state. 17523 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17524 int nextCachedAdj = curCachedAdj+1; 17525 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17526 int nextEmptyAdj = curEmptyAdj+2; 17527 for (int i=N-1; i>=0; i--) { 17528 ProcessRecord app = mLruProcesses.get(i); 17529 if (!app.killedByAm && app.thread != null) { 17530 app.procStateChanged = false; 17531 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17532 17533 // If we haven't yet assigned the final cached adj 17534 // to the process, do that now. 17535 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17536 switch (app.curProcState) { 17537 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17538 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17539 // This process is a cached process holding activities... 17540 // assign it the next cached value for that type, and then 17541 // step that cached level. 17542 app.curRawAdj = curCachedAdj; 17543 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17544 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17545 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17546 + ")"); 17547 if (curCachedAdj != nextCachedAdj) { 17548 stepCached++; 17549 if (stepCached >= cachedFactor) { 17550 stepCached = 0; 17551 curCachedAdj = nextCachedAdj; 17552 nextCachedAdj += 2; 17553 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17554 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17555 } 17556 } 17557 } 17558 break; 17559 default: 17560 // For everything else, assign next empty cached process 17561 // level and bump that up. Note that this means that 17562 // long-running services that have dropped down to the 17563 // cached level will be treated as empty (since their process 17564 // state is still as a service), which is what we want. 17565 app.curRawAdj = curEmptyAdj; 17566 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17567 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17568 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17569 + ")"); 17570 if (curEmptyAdj != nextEmptyAdj) { 17571 stepEmpty++; 17572 if (stepEmpty >= emptyFactor) { 17573 stepEmpty = 0; 17574 curEmptyAdj = nextEmptyAdj; 17575 nextEmptyAdj += 2; 17576 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17577 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17578 } 17579 } 17580 } 17581 break; 17582 } 17583 } 17584 17585 applyOomAdjLocked(app, TOP_APP, true, now); 17586 17587 // Count the number of process types. 17588 switch (app.curProcState) { 17589 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17590 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17591 mNumCachedHiddenProcs++; 17592 numCached++; 17593 if (numCached > cachedProcessLimit) { 17594 app.kill("cached #" + numCached, true); 17595 } 17596 break; 17597 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17598 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17599 && app.lastActivityTime < oldTime) { 17600 app.kill("empty for " 17601 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17602 / 1000) + "s", true); 17603 } else { 17604 numEmpty++; 17605 if (numEmpty > emptyProcessLimit) { 17606 app.kill("empty #" + numEmpty, true); 17607 } 17608 } 17609 break; 17610 default: 17611 mNumNonCachedProcs++; 17612 break; 17613 } 17614 17615 if (app.isolated && app.services.size() <= 0) { 17616 // If this is an isolated process, and there are no 17617 // services running in it, then the process is no longer 17618 // needed. We agressively kill these because we can by 17619 // definition not re-use the same process again, and it is 17620 // good to avoid having whatever code was running in them 17621 // left sitting around after no longer needed. 17622 app.kill("isolated not needed", true); 17623 } 17624 17625 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17626 && !app.killedByAm) { 17627 numTrimming++; 17628 } 17629 } 17630 } 17631 17632 mNumServiceProcs = mNewNumServiceProcs; 17633 17634 // Now determine the memory trimming level of background processes. 17635 // Unfortunately we need to start at the back of the list to do this 17636 // properly. We only do this if the number of background apps we 17637 // are managing to keep around is less than half the maximum we desire; 17638 // if we are keeping a good number around, we'll let them use whatever 17639 // memory they want. 17640 final int numCachedAndEmpty = numCached + numEmpty; 17641 int memFactor; 17642 if (numCached <= ProcessList.TRIM_CACHED_APPS 17643 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17644 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17645 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17646 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17647 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17648 } else { 17649 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17650 } 17651 } else { 17652 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17653 } 17654 // We always allow the memory level to go up (better). We only allow it to go 17655 // down if we are in a state where that is allowed, *and* the total number of processes 17656 // has gone down since last time. 17657 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17658 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17659 + " last=" + mLastNumProcesses); 17660 if (memFactor > mLastMemoryLevel) { 17661 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17662 memFactor = mLastMemoryLevel; 17663 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17664 } 17665 } 17666 mLastMemoryLevel = memFactor; 17667 mLastNumProcesses = mLruProcesses.size(); 17668 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17669 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17670 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17671 if (mLowRamStartTime == 0) { 17672 mLowRamStartTime = now; 17673 } 17674 int step = 0; 17675 int fgTrimLevel; 17676 switch (memFactor) { 17677 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17678 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17679 break; 17680 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17681 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17682 break; 17683 default: 17684 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17685 break; 17686 } 17687 int factor = numTrimming/3; 17688 int minFactor = 2; 17689 if (mHomeProcess != null) minFactor++; 17690 if (mPreviousProcess != null) minFactor++; 17691 if (factor < minFactor) factor = minFactor; 17692 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17693 for (int i=N-1; i>=0; i--) { 17694 ProcessRecord app = mLruProcesses.get(i); 17695 if (allChanged || app.procStateChanged) { 17696 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17697 app.procStateChanged = false; 17698 } 17699 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17700 && !app.killedByAm) { 17701 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17702 try { 17703 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17704 "Trimming memory of " + app.processName 17705 + " to " + curLevel); 17706 app.thread.scheduleTrimMemory(curLevel); 17707 } catch (RemoteException e) { 17708 } 17709 if (false) { 17710 // For now we won't do this; our memory trimming seems 17711 // to be good enough at this point that destroying 17712 // activities causes more harm than good. 17713 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17714 && app != mHomeProcess && app != mPreviousProcess) { 17715 // Need to do this on its own message because the stack may not 17716 // be in a consistent state at this point. 17717 // For these apps we will also finish their activities 17718 // to help them free memory. 17719 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17720 } 17721 } 17722 } 17723 app.trimMemoryLevel = curLevel; 17724 step++; 17725 if (step >= factor) { 17726 step = 0; 17727 switch (curLevel) { 17728 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17729 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17730 break; 17731 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17732 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17733 break; 17734 } 17735 } 17736 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17737 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17738 && app.thread != null) { 17739 try { 17740 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17741 "Trimming memory of heavy-weight " + app.processName 17742 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17743 app.thread.scheduleTrimMemory( 17744 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17745 } catch (RemoteException e) { 17746 } 17747 } 17748 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17749 } else { 17750 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17751 || app.systemNoUi) && app.pendingUiClean) { 17752 // If this application is now in the background and it 17753 // had done UI, then give it the special trim level to 17754 // have it free UI resources. 17755 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17756 if (app.trimMemoryLevel < level && app.thread != null) { 17757 try { 17758 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17759 "Trimming memory of bg-ui " + app.processName 17760 + " to " + level); 17761 app.thread.scheduleTrimMemory(level); 17762 } catch (RemoteException e) { 17763 } 17764 } 17765 app.pendingUiClean = false; 17766 } 17767 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17768 try { 17769 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17770 "Trimming memory of fg " + app.processName 17771 + " to " + fgTrimLevel); 17772 app.thread.scheduleTrimMemory(fgTrimLevel); 17773 } catch (RemoteException e) { 17774 } 17775 } 17776 app.trimMemoryLevel = fgTrimLevel; 17777 } 17778 } 17779 } else { 17780 if (mLowRamStartTime != 0) { 17781 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17782 mLowRamStartTime = 0; 17783 } 17784 for (int i=N-1; i>=0; i--) { 17785 ProcessRecord app = mLruProcesses.get(i); 17786 if (allChanged || app.procStateChanged) { 17787 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17788 app.procStateChanged = false; 17789 } 17790 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17791 || app.systemNoUi) && app.pendingUiClean) { 17792 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17793 && app.thread != null) { 17794 try { 17795 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17796 "Trimming memory of ui hidden " + app.processName 17797 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17798 app.thread.scheduleTrimMemory( 17799 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17800 } catch (RemoteException e) { 17801 } 17802 } 17803 app.pendingUiClean = false; 17804 } 17805 app.trimMemoryLevel = 0; 17806 } 17807 } 17808 17809 if (mAlwaysFinishActivities) { 17810 // Need to do this on its own message because the stack may not 17811 // be in a consistent state at this point. 17812 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17813 } 17814 17815 if (allChanged) { 17816 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17817 } 17818 17819 if (mProcessStats.shouldWriteNowLocked(now)) { 17820 mHandler.post(new Runnable() { 17821 @Override public void run() { 17822 synchronized (ActivityManagerService.this) { 17823 mProcessStats.writeStateAsyncLocked(); 17824 } 17825 } 17826 }); 17827 } 17828 17829 if (DEBUG_OOM_ADJ) { 17830 if (false) { 17831 RuntimeException here = new RuntimeException("here"); 17832 here.fillInStackTrace(); 17833 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17834 } else { 17835 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17836 } 17837 } 17838 } 17839 17840 final void trimApplications() { 17841 synchronized (this) { 17842 int i; 17843 17844 // First remove any unused application processes whose package 17845 // has been removed. 17846 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17847 final ProcessRecord app = mRemovedProcesses.get(i); 17848 if (app.activities.size() == 0 17849 && app.curReceiver == null && app.services.size() == 0) { 17850 Slog.i( 17851 TAG, "Exiting empty application process " 17852 + app.processName + " (" 17853 + (app.thread != null ? app.thread.asBinder() : null) 17854 + ")\n"); 17855 if (app.pid > 0 && app.pid != MY_PID) { 17856 app.kill("empty", false); 17857 } else { 17858 try { 17859 app.thread.scheduleExit(); 17860 } catch (Exception e) { 17861 // Ignore exceptions. 17862 } 17863 } 17864 cleanUpApplicationRecordLocked(app, false, true, -1); 17865 mRemovedProcesses.remove(i); 17866 17867 if (app.persistent) { 17868 addAppLocked(app.info, false, null /* ABI override */); 17869 } 17870 } 17871 } 17872 17873 // Now update the oom adj for all processes. 17874 updateOomAdjLocked(); 17875 } 17876 } 17877 17878 /** This method sends the specified signal to each of the persistent apps */ 17879 public void signalPersistentProcesses(int sig) throws RemoteException { 17880 if (sig != Process.SIGNAL_USR1) { 17881 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17882 } 17883 17884 synchronized (this) { 17885 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17886 != PackageManager.PERMISSION_GRANTED) { 17887 throw new SecurityException("Requires permission " 17888 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17889 } 17890 17891 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17892 ProcessRecord r = mLruProcesses.get(i); 17893 if (r.thread != null && r.persistent) { 17894 Process.sendSignal(r.pid, sig); 17895 } 17896 } 17897 } 17898 } 17899 17900 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17901 if (proc == null || proc == mProfileProc) { 17902 proc = mProfileProc; 17903 profileType = mProfileType; 17904 clearProfilerLocked(); 17905 } 17906 if (proc == null) { 17907 return; 17908 } 17909 try { 17910 proc.thread.profilerControl(false, null, profileType); 17911 } catch (RemoteException e) { 17912 throw new IllegalStateException("Process disappeared"); 17913 } 17914 } 17915 17916 private void clearProfilerLocked() { 17917 if (mProfileFd != null) { 17918 try { 17919 mProfileFd.close(); 17920 } catch (IOException e) { 17921 } 17922 } 17923 mProfileApp = null; 17924 mProfileProc = null; 17925 mProfileFile = null; 17926 mProfileType = 0; 17927 mAutoStopProfiler = false; 17928 mSamplingInterval = 0; 17929 } 17930 17931 public boolean profileControl(String process, int userId, boolean start, 17932 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17933 17934 try { 17935 synchronized (this) { 17936 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17937 // its own permission. 17938 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17939 != PackageManager.PERMISSION_GRANTED) { 17940 throw new SecurityException("Requires permission " 17941 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17942 } 17943 17944 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17945 throw new IllegalArgumentException("null profile info or fd"); 17946 } 17947 17948 ProcessRecord proc = null; 17949 if (process != null) { 17950 proc = findProcessLocked(process, userId, "profileControl"); 17951 } 17952 17953 if (start && (proc == null || proc.thread == null)) { 17954 throw new IllegalArgumentException("Unknown process: " + process); 17955 } 17956 17957 if (start) { 17958 stopProfilerLocked(null, 0); 17959 setProfileApp(proc.info, proc.processName, profilerInfo); 17960 mProfileProc = proc; 17961 mProfileType = profileType; 17962 ParcelFileDescriptor fd = profilerInfo.profileFd; 17963 try { 17964 fd = fd.dup(); 17965 } catch (IOException e) { 17966 fd = null; 17967 } 17968 profilerInfo.profileFd = fd; 17969 proc.thread.profilerControl(start, profilerInfo, profileType); 17970 fd = null; 17971 mProfileFd = null; 17972 } else { 17973 stopProfilerLocked(proc, profileType); 17974 if (profilerInfo != null && profilerInfo.profileFd != null) { 17975 try { 17976 profilerInfo.profileFd.close(); 17977 } catch (IOException e) { 17978 } 17979 } 17980 } 17981 17982 return true; 17983 } 17984 } catch (RemoteException e) { 17985 throw new IllegalStateException("Process disappeared"); 17986 } finally { 17987 if (profilerInfo != null && profilerInfo.profileFd != null) { 17988 try { 17989 profilerInfo.profileFd.close(); 17990 } catch (IOException e) { 17991 } 17992 } 17993 } 17994 } 17995 17996 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17997 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17998 userId, true, ALLOW_FULL_ONLY, callName, null); 17999 ProcessRecord proc = null; 18000 try { 18001 int pid = Integer.parseInt(process); 18002 synchronized (mPidsSelfLocked) { 18003 proc = mPidsSelfLocked.get(pid); 18004 } 18005 } catch (NumberFormatException e) { 18006 } 18007 18008 if (proc == null) { 18009 ArrayMap<String, SparseArray<ProcessRecord>> all 18010 = mProcessNames.getMap(); 18011 SparseArray<ProcessRecord> procs = all.get(process); 18012 if (procs != null && procs.size() > 0) { 18013 proc = procs.valueAt(0); 18014 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18015 for (int i=1; i<procs.size(); i++) { 18016 ProcessRecord thisProc = procs.valueAt(i); 18017 if (thisProc.userId == userId) { 18018 proc = thisProc; 18019 break; 18020 } 18021 } 18022 } 18023 } 18024 } 18025 18026 return proc; 18027 } 18028 18029 public boolean dumpHeap(String process, int userId, boolean managed, 18030 String path, ParcelFileDescriptor fd) throws RemoteException { 18031 18032 try { 18033 synchronized (this) { 18034 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18035 // its own permission (same as profileControl). 18036 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18037 != PackageManager.PERMISSION_GRANTED) { 18038 throw new SecurityException("Requires permission " 18039 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18040 } 18041 18042 if (fd == null) { 18043 throw new IllegalArgumentException("null fd"); 18044 } 18045 18046 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18047 if (proc == null || proc.thread == null) { 18048 throw new IllegalArgumentException("Unknown process: " + process); 18049 } 18050 18051 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18052 if (!isDebuggable) { 18053 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18054 throw new SecurityException("Process not debuggable: " + proc); 18055 } 18056 } 18057 18058 proc.thread.dumpHeap(managed, path, fd); 18059 fd = null; 18060 return true; 18061 } 18062 } catch (RemoteException e) { 18063 throw new IllegalStateException("Process disappeared"); 18064 } finally { 18065 if (fd != null) { 18066 try { 18067 fd.close(); 18068 } catch (IOException e) { 18069 } 18070 } 18071 } 18072 } 18073 18074 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18075 public void monitor() { 18076 synchronized (this) { } 18077 } 18078 18079 void onCoreSettingsChange(Bundle settings) { 18080 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18081 ProcessRecord processRecord = mLruProcesses.get(i); 18082 try { 18083 if (processRecord.thread != null) { 18084 processRecord.thread.setCoreSettings(settings); 18085 } 18086 } catch (RemoteException re) { 18087 /* ignore */ 18088 } 18089 } 18090 } 18091 18092 // Multi-user methods 18093 18094 /** 18095 * Start user, if its not already running, but don't bring it to foreground. 18096 */ 18097 @Override 18098 public boolean startUserInBackground(final int userId) { 18099 return startUser(userId, /* foreground */ false); 18100 } 18101 18102 /** 18103 * Start user, if its not already running, and bring it to foreground. 18104 */ 18105 boolean startUserInForeground(final int userId, Dialog dlg) { 18106 boolean result = startUser(userId, /* foreground */ true); 18107 dlg.dismiss(); 18108 return result; 18109 } 18110 18111 /** 18112 * Refreshes the list of users related to the current user when either a 18113 * user switch happens or when a new related user is started in the 18114 * background. 18115 */ 18116 private void updateCurrentProfileIdsLocked() { 18117 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18118 mCurrentUserId, false /* enabledOnly */); 18119 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18120 for (int i = 0; i < currentProfileIds.length; i++) { 18121 currentProfileIds[i] = profiles.get(i).id; 18122 } 18123 mCurrentProfileIds = currentProfileIds; 18124 18125 synchronized (mUserProfileGroupIdsSelfLocked) { 18126 mUserProfileGroupIdsSelfLocked.clear(); 18127 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18128 for (int i = 0; i < users.size(); i++) { 18129 UserInfo user = users.get(i); 18130 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18131 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18132 } 18133 } 18134 } 18135 } 18136 18137 private Set getProfileIdsLocked(int userId) { 18138 Set userIds = new HashSet<Integer>(); 18139 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18140 userId, false /* enabledOnly */); 18141 for (UserInfo user : profiles) { 18142 userIds.add(Integer.valueOf(user.id)); 18143 } 18144 return userIds; 18145 } 18146 18147 @Override 18148 public boolean switchUser(final int userId) { 18149 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18150 String userName; 18151 synchronized (this) { 18152 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18153 if (userInfo == null) { 18154 Slog.w(TAG, "No user info for user #" + userId); 18155 return false; 18156 } 18157 if (userInfo.isManagedProfile()) { 18158 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18159 return false; 18160 } 18161 userName = userInfo.name; 18162 mTargetUserId = userId; 18163 } 18164 mHandler.removeMessages(START_USER_SWITCH_MSG); 18165 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18166 return true; 18167 } 18168 18169 private void showUserSwitchDialog(int userId, String userName) { 18170 // The dialog will show and then initiate the user switch by calling startUserInForeground 18171 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18172 true /* above system */); 18173 d.show(); 18174 } 18175 18176 private boolean startUser(final int userId, final boolean foreground) { 18177 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18178 != PackageManager.PERMISSION_GRANTED) { 18179 String msg = "Permission Denial: switchUser() from pid=" 18180 + Binder.getCallingPid() 18181 + ", uid=" + Binder.getCallingUid() 18182 + " requires " + INTERACT_ACROSS_USERS_FULL; 18183 Slog.w(TAG, msg); 18184 throw new SecurityException(msg); 18185 } 18186 18187 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18188 18189 final long ident = Binder.clearCallingIdentity(); 18190 try { 18191 synchronized (this) { 18192 final int oldUserId = mCurrentUserId; 18193 if (oldUserId == userId) { 18194 return true; 18195 } 18196 18197 mStackSupervisor.setLockTaskModeLocked(null, false); 18198 18199 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18200 if (userInfo == null) { 18201 Slog.w(TAG, "No user info for user #" + userId); 18202 return false; 18203 } 18204 if (foreground && userInfo.isManagedProfile()) { 18205 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18206 return false; 18207 } 18208 18209 if (foreground) { 18210 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18211 R.anim.screen_user_enter); 18212 } 18213 18214 boolean needStart = false; 18215 18216 // If the user we are switching to is not currently started, then 18217 // we need to start it now. 18218 if (mStartedUsers.get(userId) == null) { 18219 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18220 updateStartedUserArrayLocked(); 18221 needStart = true; 18222 } 18223 18224 final Integer userIdInt = Integer.valueOf(userId); 18225 mUserLru.remove(userIdInt); 18226 mUserLru.add(userIdInt); 18227 18228 if (foreground) { 18229 mCurrentUserId = userId; 18230 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18231 updateCurrentProfileIdsLocked(); 18232 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18233 // Once the internal notion of the active user has switched, we lock the device 18234 // with the option to show the user switcher on the keyguard. 18235 mWindowManager.lockNow(null); 18236 } else { 18237 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18238 updateCurrentProfileIdsLocked(); 18239 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18240 mUserLru.remove(currentUserIdInt); 18241 mUserLru.add(currentUserIdInt); 18242 } 18243 18244 final UserStartedState uss = mStartedUsers.get(userId); 18245 18246 // Make sure user is in the started state. If it is currently 18247 // stopping, we need to knock that off. 18248 if (uss.mState == UserStartedState.STATE_STOPPING) { 18249 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18250 // so we can just fairly silently bring the user back from 18251 // the almost-dead. 18252 uss.mState = UserStartedState.STATE_RUNNING; 18253 updateStartedUserArrayLocked(); 18254 needStart = true; 18255 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18256 // This means ACTION_SHUTDOWN has been sent, so we will 18257 // need to treat this as a new boot of the user. 18258 uss.mState = UserStartedState.STATE_BOOTING; 18259 updateStartedUserArrayLocked(); 18260 needStart = true; 18261 } 18262 18263 if (uss.mState == UserStartedState.STATE_BOOTING) { 18264 // Booting up a new user, need to tell system services about it. 18265 // Note that this is on the same handler as scheduling of broadcasts, 18266 // which is important because it needs to go first. 18267 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18268 } 18269 18270 if (foreground) { 18271 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18272 oldUserId)); 18273 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18274 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18275 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18276 oldUserId, userId, uss)); 18277 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18278 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18279 } 18280 18281 if (needStart) { 18282 // Send USER_STARTED broadcast 18283 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18284 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18285 | Intent.FLAG_RECEIVER_FOREGROUND); 18286 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18287 broadcastIntentLocked(null, null, intent, 18288 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18289 false, false, MY_PID, Process.SYSTEM_UID, userId); 18290 } 18291 18292 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18293 if (userId != UserHandle.USER_OWNER) { 18294 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18295 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18296 broadcastIntentLocked(null, null, intent, null, 18297 new IIntentReceiver.Stub() { 18298 public void performReceive(Intent intent, int resultCode, 18299 String data, Bundle extras, boolean ordered, 18300 boolean sticky, int sendingUser) { 18301 onUserInitialized(uss, foreground, oldUserId, userId); 18302 } 18303 }, 0, null, null, null, AppOpsManager.OP_NONE, 18304 true, false, MY_PID, Process.SYSTEM_UID, 18305 userId); 18306 uss.initializing = true; 18307 } else { 18308 getUserManagerLocked().makeInitialized(userInfo.id); 18309 } 18310 } 18311 18312 if (foreground) { 18313 if (!uss.initializing) { 18314 moveUserToForeground(uss, oldUserId, userId); 18315 } 18316 } else { 18317 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18318 } 18319 18320 if (needStart) { 18321 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18322 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18323 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18324 broadcastIntentLocked(null, null, intent, 18325 null, new IIntentReceiver.Stub() { 18326 @Override 18327 public void performReceive(Intent intent, int resultCode, String data, 18328 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18329 throws RemoteException { 18330 } 18331 }, 0, null, null, 18332 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18333 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18334 } 18335 } 18336 } finally { 18337 Binder.restoreCallingIdentity(ident); 18338 } 18339 18340 return true; 18341 } 18342 18343 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18344 long ident = Binder.clearCallingIdentity(); 18345 try { 18346 Intent intent; 18347 if (oldUserId >= 0) { 18348 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18349 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18350 int count = profiles.size(); 18351 for (int i = 0; i < count; i++) { 18352 int profileUserId = profiles.get(i).id; 18353 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18354 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18355 | Intent.FLAG_RECEIVER_FOREGROUND); 18356 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18357 broadcastIntentLocked(null, null, intent, 18358 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18359 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18360 } 18361 } 18362 if (newUserId >= 0) { 18363 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18364 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18365 int count = profiles.size(); 18366 for (int i = 0; i < count; i++) { 18367 int profileUserId = profiles.get(i).id; 18368 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18369 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18370 | Intent.FLAG_RECEIVER_FOREGROUND); 18371 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18372 broadcastIntentLocked(null, null, intent, 18373 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18374 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18375 } 18376 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18377 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18378 | Intent.FLAG_RECEIVER_FOREGROUND); 18379 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18380 broadcastIntentLocked(null, null, intent, 18381 null, null, 0, null, null, 18382 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18383 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18384 } 18385 } finally { 18386 Binder.restoreCallingIdentity(ident); 18387 } 18388 } 18389 18390 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18391 final int newUserId) { 18392 final int N = mUserSwitchObservers.beginBroadcast(); 18393 if (N > 0) { 18394 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18395 int mCount = 0; 18396 @Override 18397 public void sendResult(Bundle data) throws RemoteException { 18398 synchronized (ActivityManagerService.this) { 18399 if (mCurUserSwitchCallback == this) { 18400 mCount++; 18401 if (mCount == N) { 18402 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18403 } 18404 } 18405 } 18406 } 18407 }; 18408 synchronized (this) { 18409 uss.switching = true; 18410 mCurUserSwitchCallback = callback; 18411 } 18412 for (int i=0; i<N; i++) { 18413 try { 18414 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18415 newUserId, callback); 18416 } catch (RemoteException e) { 18417 } 18418 } 18419 } else { 18420 synchronized (this) { 18421 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18422 } 18423 } 18424 mUserSwitchObservers.finishBroadcast(); 18425 } 18426 18427 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18428 synchronized (this) { 18429 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18430 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18431 } 18432 } 18433 18434 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18435 mCurUserSwitchCallback = null; 18436 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18437 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18438 oldUserId, newUserId, uss)); 18439 } 18440 18441 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18442 synchronized (this) { 18443 if (foreground) { 18444 moveUserToForeground(uss, oldUserId, newUserId); 18445 } 18446 } 18447 18448 completeSwitchAndInitalize(uss, newUserId, true, false); 18449 } 18450 18451 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18452 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18453 if (homeInFront) { 18454 startHomeActivityLocked(newUserId); 18455 } else { 18456 mStackSupervisor.resumeTopActivitiesLocked(); 18457 } 18458 EventLogTags.writeAmSwitchUser(newUserId); 18459 getUserManagerLocked().userForeground(newUserId); 18460 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18461 } 18462 18463 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18464 completeSwitchAndInitalize(uss, newUserId, false, true); 18465 } 18466 18467 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18468 boolean clearInitializing, boolean clearSwitching) { 18469 boolean unfrozen = false; 18470 synchronized (this) { 18471 if (clearInitializing) { 18472 uss.initializing = false; 18473 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18474 } 18475 if (clearSwitching) { 18476 uss.switching = false; 18477 } 18478 if (!uss.switching && !uss.initializing) { 18479 mWindowManager.stopFreezingScreen(); 18480 unfrozen = true; 18481 } 18482 } 18483 if (unfrozen) { 18484 final int N = mUserSwitchObservers.beginBroadcast(); 18485 for (int i=0; i<N; i++) { 18486 try { 18487 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18488 } catch (RemoteException e) { 18489 } 18490 } 18491 mUserSwitchObservers.finishBroadcast(); 18492 } 18493 } 18494 18495 void scheduleStartProfilesLocked() { 18496 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18497 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18498 DateUtils.SECOND_IN_MILLIS); 18499 } 18500 } 18501 18502 void startProfilesLocked() { 18503 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18504 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18505 mCurrentUserId, false /* enabledOnly */); 18506 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18507 for (UserInfo user : profiles) { 18508 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18509 && user.id != mCurrentUserId) { 18510 toStart.add(user); 18511 } 18512 } 18513 final int n = toStart.size(); 18514 int i = 0; 18515 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18516 startUserInBackground(toStart.get(i).id); 18517 } 18518 if (i < n) { 18519 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18520 } 18521 } 18522 18523 void finishUserBoot(UserStartedState uss) { 18524 synchronized (this) { 18525 if (uss.mState == UserStartedState.STATE_BOOTING 18526 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18527 uss.mState = UserStartedState.STATE_RUNNING; 18528 final int userId = uss.mHandle.getIdentifier(); 18529 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18530 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18531 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18532 broadcastIntentLocked(null, null, intent, 18533 null, null, 0, null, null, 18534 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18535 true, false, MY_PID, Process.SYSTEM_UID, userId); 18536 } 18537 } 18538 } 18539 18540 void finishUserSwitch(UserStartedState uss) { 18541 synchronized (this) { 18542 finishUserBoot(uss); 18543 18544 startProfilesLocked(); 18545 18546 int num = mUserLru.size(); 18547 int i = 0; 18548 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18549 Integer oldUserId = mUserLru.get(i); 18550 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18551 if (oldUss == null) { 18552 // Shouldn't happen, but be sane if it does. 18553 mUserLru.remove(i); 18554 num--; 18555 continue; 18556 } 18557 if (oldUss.mState == UserStartedState.STATE_STOPPING 18558 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18559 // This user is already stopping, doesn't count. 18560 num--; 18561 i++; 18562 continue; 18563 } 18564 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18565 // Owner and current can't be stopped, but count as running. 18566 i++; 18567 continue; 18568 } 18569 // This is a user to be stopped. 18570 stopUserLocked(oldUserId, null); 18571 num--; 18572 i++; 18573 } 18574 } 18575 } 18576 18577 @Override 18578 public int stopUser(final int userId, final IStopUserCallback callback) { 18579 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18580 != PackageManager.PERMISSION_GRANTED) { 18581 String msg = "Permission Denial: switchUser() from pid=" 18582 + Binder.getCallingPid() 18583 + ", uid=" + Binder.getCallingUid() 18584 + " requires " + INTERACT_ACROSS_USERS_FULL; 18585 Slog.w(TAG, msg); 18586 throw new SecurityException(msg); 18587 } 18588 if (userId <= 0) { 18589 throw new IllegalArgumentException("Can't stop primary user " + userId); 18590 } 18591 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18592 synchronized (this) { 18593 return stopUserLocked(userId, callback); 18594 } 18595 } 18596 18597 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18598 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18599 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18600 return ActivityManager.USER_OP_IS_CURRENT; 18601 } 18602 18603 final UserStartedState uss = mStartedUsers.get(userId); 18604 if (uss == null) { 18605 // User is not started, nothing to do... but we do need to 18606 // callback if requested. 18607 if (callback != null) { 18608 mHandler.post(new Runnable() { 18609 @Override 18610 public void run() { 18611 try { 18612 callback.userStopped(userId); 18613 } catch (RemoteException e) { 18614 } 18615 } 18616 }); 18617 } 18618 return ActivityManager.USER_OP_SUCCESS; 18619 } 18620 18621 if (callback != null) { 18622 uss.mStopCallbacks.add(callback); 18623 } 18624 18625 if (uss.mState != UserStartedState.STATE_STOPPING 18626 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18627 uss.mState = UserStartedState.STATE_STOPPING; 18628 updateStartedUserArrayLocked(); 18629 18630 long ident = Binder.clearCallingIdentity(); 18631 try { 18632 // We are going to broadcast ACTION_USER_STOPPING and then 18633 // once that is done send a final ACTION_SHUTDOWN and then 18634 // stop the user. 18635 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18636 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18637 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18638 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18639 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18640 // This is the result receiver for the final shutdown broadcast. 18641 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18642 @Override 18643 public void performReceive(Intent intent, int resultCode, String data, 18644 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18645 finishUserStop(uss); 18646 } 18647 }; 18648 // This is the result receiver for the initial stopping broadcast. 18649 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18650 @Override 18651 public void performReceive(Intent intent, int resultCode, String data, 18652 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18653 // On to the next. 18654 synchronized (ActivityManagerService.this) { 18655 if (uss.mState != UserStartedState.STATE_STOPPING) { 18656 // Whoops, we are being started back up. Abort, abort! 18657 return; 18658 } 18659 uss.mState = UserStartedState.STATE_SHUTDOWN; 18660 } 18661 mBatteryStatsService.noteEvent( 18662 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18663 Integer.toString(userId), userId); 18664 mSystemServiceManager.stopUser(userId); 18665 broadcastIntentLocked(null, null, shutdownIntent, 18666 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18667 true, false, MY_PID, Process.SYSTEM_UID, userId); 18668 } 18669 }; 18670 // Kick things off. 18671 broadcastIntentLocked(null, null, stoppingIntent, 18672 null, stoppingReceiver, 0, null, null, 18673 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18674 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18675 } finally { 18676 Binder.restoreCallingIdentity(ident); 18677 } 18678 } 18679 18680 return ActivityManager.USER_OP_SUCCESS; 18681 } 18682 18683 void finishUserStop(UserStartedState uss) { 18684 final int userId = uss.mHandle.getIdentifier(); 18685 boolean stopped; 18686 ArrayList<IStopUserCallback> callbacks; 18687 synchronized (this) { 18688 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18689 if (mStartedUsers.get(userId) != uss) { 18690 stopped = false; 18691 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18692 stopped = false; 18693 } else { 18694 stopped = true; 18695 // User can no longer run. 18696 mStartedUsers.remove(userId); 18697 mUserLru.remove(Integer.valueOf(userId)); 18698 updateStartedUserArrayLocked(); 18699 18700 // Clean up all state and processes associated with the user. 18701 // Kill all the processes for the user. 18702 forceStopUserLocked(userId, "finish user"); 18703 } 18704 18705 // Explicitly remove the old information in mRecentTasks. 18706 removeRecentTasksForUserLocked(userId); 18707 } 18708 18709 for (int i=0; i<callbacks.size(); i++) { 18710 try { 18711 if (stopped) callbacks.get(i).userStopped(userId); 18712 else callbacks.get(i).userStopAborted(userId); 18713 } catch (RemoteException e) { 18714 } 18715 } 18716 18717 if (stopped) { 18718 mSystemServiceManager.cleanupUser(userId); 18719 synchronized (this) { 18720 mStackSupervisor.removeUserLocked(userId); 18721 } 18722 } 18723 } 18724 18725 @Override 18726 public UserInfo getCurrentUser() { 18727 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18728 != PackageManager.PERMISSION_GRANTED) && ( 18729 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18730 != PackageManager.PERMISSION_GRANTED)) { 18731 String msg = "Permission Denial: getCurrentUser() from pid=" 18732 + Binder.getCallingPid() 18733 + ", uid=" + Binder.getCallingUid() 18734 + " requires " + INTERACT_ACROSS_USERS; 18735 Slog.w(TAG, msg); 18736 throw new SecurityException(msg); 18737 } 18738 synchronized (this) { 18739 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18740 return getUserManagerLocked().getUserInfo(userId); 18741 } 18742 } 18743 18744 int getCurrentUserIdLocked() { 18745 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18746 } 18747 18748 @Override 18749 public boolean isUserRunning(int userId, boolean orStopped) { 18750 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18751 != PackageManager.PERMISSION_GRANTED) { 18752 String msg = "Permission Denial: isUserRunning() from pid=" 18753 + Binder.getCallingPid() 18754 + ", uid=" + Binder.getCallingUid() 18755 + " requires " + INTERACT_ACROSS_USERS; 18756 Slog.w(TAG, msg); 18757 throw new SecurityException(msg); 18758 } 18759 synchronized (this) { 18760 return isUserRunningLocked(userId, orStopped); 18761 } 18762 } 18763 18764 boolean isUserRunningLocked(int userId, boolean orStopped) { 18765 UserStartedState state = mStartedUsers.get(userId); 18766 if (state == null) { 18767 return false; 18768 } 18769 if (orStopped) { 18770 return true; 18771 } 18772 return state.mState != UserStartedState.STATE_STOPPING 18773 && state.mState != UserStartedState.STATE_SHUTDOWN; 18774 } 18775 18776 @Override 18777 public int[] getRunningUserIds() { 18778 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18779 != PackageManager.PERMISSION_GRANTED) { 18780 String msg = "Permission Denial: isUserRunning() from pid=" 18781 + Binder.getCallingPid() 18782 + ", uid=" + Binder.getCallingUid() 18783 + " requires " + INTERACT_ACROSS_USERS; 18784 Slog.w(TAG, msg); 18785 throw new SecurityException(msg); 18786 } 18787 synchronized (this) { 18788 return mStartedUserArray; 18789 } 18790 } 18791 18792 private void updateStartedUserArrayLocked() { 18793 int num = 0; 18794 for (int i=0; i<mStartedUsers.size(); i++) { 18795 UserStartedState uss = mStartedUsers.valueAt(i); 18796 // This list does not include stopping users. 18797 if (uss.mState != UserStartedState.STATE_STOPPING 18798 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18799 num++; 18800 } 18801 } 18802 mStartedUserArray = new int[num]; 18803 num = 0; 18804 for (int i=0; i<mStartedUsers.size(); i++) { 18805 UserStartedState uss = mStartedUsers.valueAt(i); 18806 if (uss.mState != UserStartedState.STATE_STOPPING 18807 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18808 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18809 num++; 18810 } 18811 } 18812 } 18813 18814 @Override 18815 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18816 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18817 != PackageManager.PERMISSION_GRANTED) { 18818 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18819 + Binder.getCallingPid() 18820 + ", uid=" + Binder.getCallingUid() 18821 + " requires " + INTERACT_ACROSS_USERS_FULL; 18822 Slog.w(TAG, msg); 18823 throw new SecurityException(msg); 18824 } 18825 18826 mUserSwitchObservers.register(observer); 18827 } 18828 18829 @Override 18830 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18831 mUserSwitchObservers.unregister(observer); 18832 } 18833 18834 private boolean userExists(int userId) { 18835 if (userId == 0) { 18836 return true; 18837 } 18838 UserManagerService ums = getUserManagerLocked(); 18839 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18840 } 18841 18842 int[] getUsersLocked() { 18843 UserManagerService ums = getUserManagerLocked(); 18844 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18845 } 18846 18847 UserManagerService getUserManagerLocked() { 18848 if (mUserManager == null) { 18849 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18850 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18851 } 18852 return mUserManager; 18853 } 18854 18855 private int applyUserId(int uid, int userId) { 18856 return UserHandle.getUid(userId, uid); 18857 } 18858 18859 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18860 if (info == null) return null; 18861 ApplicationInfo newInfo = new ApplicationInfo(info); 18862 newInfo.uid = applyUserId(info.uid, userId); 18863 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18864 + info.packageName; 18865 return newInfo; 18866 } 18867 18868 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18869 if (aInfo == null 18870 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18871 return aInfo; 18872 } 18873 18874 ActivityInfo info = new ActivityInfo(aInfo); 18875 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18876 return info; 18877 } 18878 18879 private final class LocalService extends ActivityManagerInternal { 18880 @Override 18881 public void goingToSleep() { 18882 ActivityManagerService.this.goingToSleep(); 18883 } 18884 18885 @Override 18886 public void wakingUp() { 18887 ActivityManagerService.this.wakingUp(); 18888 } 18889 18890 @Override 18891 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18892 String processName, String abiOverride, int uid, Runnable crashHandler) { 18893 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18894 processName, abiOverride, uid, crashHandler); 18895 } 18896 } 18897 18898 /** 18899 * An implementation of IAppTask, that allows an app to manage its own tasks via 18900 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18901 * only the process that calls getAppTasks() can call the AppTask methods. 18902 */ 18903 class AppTaskImpl extends IAppTask.Stub { 18904 private int mTaskId; 18905 private int mCallingUid; 18906 18907 public AppTaskImpl(int taskId, int callingUid) { 18908 mTaskId = taskId; 18909 mCallingUid = callingUid; 18910 } 18911 18912 private void checkCaller() { 18913 if (mCallingUid != Binder.getCallingUid()) { 18914 throw new SecurityException("Caller " + mCallingUid 18915 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18916 } 18917 } 18918 18919 @Override 18920 public void finishAndRemoveTask() { 18921 checkCaller(); 18922 18923 synchronized (ActivityManagerService.this) { 18924 long origId = Binder.clearCallingIdentity(); 18925 try { 18926 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18927 if (tr == null) { 18928 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18929 } 18930 // Only kill the process if we are not a new document 18931 int flags = tr.getBaseIntent().getFlags(); 18932 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18933 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18934 removeTaskByIdLocked(mTaskId, 18935 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18936 } finally { 18937 Binder.restoreCallingIdentity(origId); 18938 } 18939 } 18940 } 18941 18942 @Override 18943 public ActivityManager.RecentTaskInfo getTaskInfo() { 18944 checkCaller(); 18945 18946 synchronized (ActivityManagerService.this) { 18947 long origId = Binder.clearCallingIdentity(); 18948 try { 18949 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18950 if (tr == null) { 18951 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18952 } 18953 return createRecentTaskInfoFromTaskRecord(tr); 18954 } finally { 18955 Binder.restoreCallingIdentity(origId); 18956 } 18957 } 18958 } 18959 18960 @Override 18961 public void moveToFront() { 18962 checkCaller(); 18963 18964 final TaskRecord tr; 18965 synchronized (ActivityManagerService.this) { 18966 tr = recentTaskForIdLocked(mTaskId); 18967 if (tr == null) { 18968 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18969 } 18970 if (tr.getRootActivity() != null) { 18971 moveTaskToFrontLocked(tr.taskId, 0, null); 18972 return; 18973 } 18974 } 18975 18976 startActivityFromRecentsInner(tr.taskId, null); 18977 } 18978 18979 @Override 18980 public int startActivity(IBinder whoThread, String callingPackage, 18981 Intent intent, String resolvedType, Bundle options) { 18982 checkCaller(); 18983 18984 int callingUser = UserHandle.getCallingUserId(); 18985 TaskRecord tr; 18986 IApplicationThread appThread; 18987 synchronized (ActivityManagerService.this) { 18988 tr = recentTaskForIdLocked(mTaskId); 18989 if (tr == null) { 18990 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18991 } 18992 appThread = ApplicationThreadNative.asInterface(whoThread); 18993 if (appThread == null) { 18994 throw new IllegalArgumentException("Bad app thread " + appThread); 18995 } 18996 } 18997 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18998 resolvedType, null, null, null, null, 0, 0, null, null, 18999 null, options, callingUser, null, tr); 19000 } 19001 19002 @Override 19003 public void setExcludeFromRecents(boolean exclude) { 19004 checkCaller(); 19005 19006 synchronized (ActivityManagerService.this) { 19007 long origId = Binder.clearCallingIdentity(); 19008 try { 19009 TaskRecord tr = recentTaskForIdLocked(mTaskId); 19010 if (tr == null) { 19011 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19012 } 19013 Intent intent = tr.getBaseIntent(); 19014 if (exclude) { 19015 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19016 } else { 19017 intent.setFlags(intent.getFlags() 19018 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19019 } 19020 } finally { 19021 Binder.restoreCallingIdentity(origId); 19022 } 19023 } 19024 } 19025 } 19026} 19027