ActivityManagerService.java revision 246a8bcadde961f6bc8172811a052af3568a6f4d
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.os.UserManager; 184import android.provider.Settings; 185import android.text.format.DateUtils; 186import android.text.format.Time; 187import android.util.AtomicFile; 188import android.util.EventLog; 189import android.util.Log; 190import android.util.Pair; 191import android.util.PrintWriterPrinter; 192import android.util.Slog; 193import android.util.SparseArray; 194import android.util.TimeUtils; 195import android.util.Xml; 196import android.view.Gravity; 197import android.view.LayoutInflater; 198import android.view.View; 199import android.view.WindowManager; 200import dalvik.system.VMRuntime; 201 202import java.io.BufferedInputStream; 203import java.io.BufferedOutputStream; 204import java.io.DataInputStream; 205import java.io.DataOutputStream; 206import java.io.File; 207import java.io.FileDescriptor; 208import java.io.FileInputStream; 209import java.io.FileNotFoundException; 210import java.io.FileOutputStream; 211import java.io.IOException; 212import java.io.InputStreamReader; 213import java.io.PrintWriter; 214import java.io.StringWriter; 215import java.lang.ref.WeakReference; 216import java.util.ArrayList; 217import java.util.Arrays; 218import java.util.Collections; 219import java.util.Comparator; 220import java.util.HashMap; 221import java.util.HashSet; 222import java.util.Iterator; 223import java.util.List; 224import java.util.Locale; 225import java.util.Map; 226import java.util.Set; 227import java.util.concurrent.atomic.AtomicBoolean; 228import java.util.concurrent.atomic.AtomicLong; 229 230public final class ActivityManagerService extends ActivityManagerNative 231 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 232 233 private static final String USER_DATA_DIR = "/data/user/"; 234 // File that stores last updated system version and called preboot receivers 235 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 236 237 static final String TAG = "ActivityManager"; 238 static final String TAG_MU = "ActivityManagerServiceMU"; 239 static final boolean DEBUG = false; 240 static final boolean localLOGV = DEBUG; 241 static final boolean DEBUG_BACKUP = localLOGV || false; 242 static final boolean DEBUG_BROADCAST = localLOGV || false; 243 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 245 static final boolean DEBUG_CLEANUP = localLOGV || false; 246 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 247 static final boolean DEBUG_FOCUS = false; 248 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 249 static final boolean DEBUG_MU = localLOGV || false; 250 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 251 static final boolean DEBUG_LRU = localLOGV || false; 252 static final boolean DEBUG_PAUSE = localLOGV || false; 253 static final boolean DEBUG_POWER = localLOGV || false; 254 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 255 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 256 static final boolean DEBUG_PROCESSES = localLOGV || false; 257 static final boolean DEBUG_PROVIDER = localLOGV || false; 258 static final boolean DEBUG_RESULTS = localLOGV || false; 259 static final boolean DEBUG_SERVICE = localLOGV || false; 260 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 261 static final boolean DEBUG_STACK = localLOGV || false; 262 static final boolean DEBUG_SWITCH = localLOGV || false; 263 static final boolean DEBUG_TASKS = localLOGV || false; 264 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 265 static final boolean DEBUG_TRANSITION = localLOGV || false; 266 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 267 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 268 static final boolean DEBUG_VISBILITY = localLOGV || false; 269 static final boolean DEBUG_PSS = localLOGV || false; 270 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 271 static final boolean DEBUG_RECENTS = localLOGV || false; 272 static final boolean VALIDATE_TOKENS = false; 273 static final boolean SHOW_ACTIVITY_START_TIME = true; 274 275 // Control over CPU and battery monitoring. 276 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 277 static final boolean MONITOR_CPU_USAGE = true; 278 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 279 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 280 static final boolean MONITOR_THREAD_CPU_USAGE = false; 281 282 // The flags that are set for all calls we make to the package manager. 283 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 284 285 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 286 287 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 288 289 // Maximum number recent bitmaps to keep in memory. 290 static final int MAX_RECENT_BITMAPS = 5; 291 292 // Amount of time after a call to stopAppSwitches() during which we will 293 // prevent further untrusted switches from happening. 294 static final long APP_SWITCH_DELAY_TIME = 5*1000; 295 296 // How long we wait for a launched process to attach to the activity manager 297 // before we decide it's never going to come up for real. 298 static final int PROC_START_TIMEOUT = 10*1000; 299 300 // How long we wait for a launched process to attach to the activity manager 301 // before we decide it's never going to come up for real, when the process was 302 // started with a wrapper for instrumentation (such as Valgrind) because it 303 // could take much longer than usual. 304 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 305 306 // How long to wait after going idle before forcing apps to GC. 307 static final int GC_TIMEOUT = 5*1000; 308 309 // The minimum amount of time between successive GC requests for a process. 310 static final int GC_MIN_INTERVAL = 60*1000; 311 312 // The minimum amount of time between successive PSS requests for a process. 313 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 314 315 // The minimum amount of time between successive PSS requests for a process 316 // when the request is due to the memory state being lowered. 317 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 318 319 // The rate at which we check for apps using excessive power -- 15 mins. 320 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 321 322 // The minimum sample duration we will allow before deciding we have 323 // enough data on wake locks to start killing things. 324 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 325 326 // The minimum sample duration we will allow before deciding we have 327 // enough data on CPU usage to start killing things. 328 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 329 330 // How long we allow a receiver to run before giving up on it. 331 static final int BROADCAST_FG_TIMEOUT = 10*1000; 332 static final int BROADCAST_BG_TIMEOUT = 60*1000; 333 334 // How long we wait until we timeout on key dispatching. 335 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 336 337 // How long we wait until we timeout on key dispatching during instrumentation. 338 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 339 340 // Amount of time we wait for observers to handle a user switch before 341 // giving up on them and unfreezing the screen. 342 static final int USER_SWITCH_TIMEOUT = 2*1000; 343 344 // Maximum number of users we allow to be running at a time. 345 static final int MAX_RUNNING_USERS = 3; 346 347 // How long to wait in getAssistContextExtras for the activity and foreground services 348 // to respond with the result. 349 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 350 351 // Maximum number of persisted Uri grants a package is allowed 352 static final int MAX_PERSISTED_URI_GRANTS = 128; 353 354 static final int MY_PID = Process.myPid(); 355 356 static final String[] EMPTY_STRING_ARRAY = new String[0]; 357 358 // How many bytes to write into the dropbox log before truncating 359 static final int DROPBOX_MAX_SIZE = 256 * 1024; 360 361 // Access modes for handleIncomingUser. 362 static final int ALLOW_NON_FULL = 0; 363 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 364 static final int ALLOW_FULL_ONLY = 2; 365 366 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 367 368 /** All system services */ 369 SystemServiceManager mSystemServiceManager; 370 371 /** Run all ActivityStacks through this */ 372 ActivityStackSupervisor mStackSupervisor; 373 374 public IntentFirewall mIntentFirewall; 375 376 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 377 // default actuion automatically. Important for devices without direct input 378 // devices. 379 private boolean mShowDialogs = true; 380 381 BroadcastQueue mFgBroadcastQueue; 382 BroadcastQueue mBgBroadcastQueue; 383 // Convenient for easy iteration over the queues. Foreground is first 384 // so that dispatch of foreground broadcasts gets precedence. 385 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 386 387 BroadcastQueue broadcastQueueForIntent(Intent intent) { 388 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 389 if (DEBUG_BACKGROUND_BROADCAST) { 390 Slog.i(TAG, "Broadcast intent " + intent + " on " 391 + (isFg ? "foreground" : "background") 392 + " queue"); 393 } 394 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 395 } 396 397 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 398 for (BroadcastQueue queue : mBroadcastQueues) { 399 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 400 if (r != null) { 401 return r; 402 } 403 } 404 return null; 405 } 406 407 /** 408 * Activity we have told the window manager to have key focus. 409 */ 410 ActivityRecord mFocusedActivity = null; 411 412 /** 413 * List of intents that were used to start the most recent tasks. 414 */ 415 ArrayList<TaskRecord> mRecentTasks; 416 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 417 418 /** 419 * For addAppTask: cached of the last activity component that was added. 420 */ 421 ComponentName mLastAddedTaskComponent; 422 423 /** 424 * For addAppTask: cached of the last activity uid that was added. 425 */ 426 int mLastAddedTaskUid; 427 428 /** 429 * For addAppTask: cached of the last ActivityInfo that was added. 430 */ 431 ActivityInfo mLastAddedTaskActivity; 432 433 public class PendingAssistExtras extends Binder implements Runnable { 434 public final ActivityRecord activity; 435 public boolean haveResult = false; 436 public Bundle result = null; 437 public PendingAssistExtras(ActivityRecord _activity) { 438 activity = _activity; 439 } 440 @Override 441 public void run() { 442 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 443 synchronized (this) { 444 haveResult = true; 445 notifyAll(); 446 } 447 } 448 } 449 450 final ArrayList<PendingAssistExtras> mPendingAssistExtras 451 = new ArrayList<PendingAssistExtras>(); 452 453 /** 454 * Process management. 455 */ 456 final ProcessList mProcessList = new ProcessList(); 457 458 /** 459 * All of the applications we currently have running organized by name. 460 * The keys are strings of the application package name (as 461 * returned by the package manager), and the keys are ApplicationRecord 462 * objects. 463 */ 464 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 465 466 /** 467 * Tracking long-term execution of processes to look for abuse and other 468 * bad app behavior. 469 */ 470 final ProcessStatsService mProcessStats; 471 472 /** 473 * The currently running isolated processes. 474 */ 475 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 476 477 /** 478 * Counter for assigning isolated process uids, to avoid frequently reusing the 479 * same ones. 480 */ 481 int mNextIsolatedProcessUid = 0; 482 483 /** 484 * The currently running heavy-weight process, if any. 485 */ 486 ProcessRecord mHeavyWeightProcess = null; 487 488 /** 489 * The last time that various processes have crashed. 490 */ 491 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 492 493 /** 494 * Information about a process that is currently marked as bad. 495 */ 496 static final class BadProcessInfo { 497 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 498 this.time = time; 499 this.shortMsg = shortMsg; 500 this.longMsg = longMsg; 501 this.stack = stack; 502 } 503 504 final long time; 505 final String shortMsg; 506 final String longMsg; 507 final String stack; 508 } 509 510 /** 511 * Set of applications that we consider to be bad, and will reject 512 * incoming broadcasts from (which the user has no control over). 513 * Processes are added to this set when they have crashed twice within 514 * a minimum amount of time; they are removed from it when they are 515 * later restarted (hopefully due to some user action). The value is the 516 * time it was added to the list. 517 */ 518 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 519 520 /** 521 * All of the processes we currently have running organized by pid. 522 * The keys are the pid running the application. 523 * 524 * <p>NOTE: This object is protected by its own lock, NOT the global 525 * activity manager lock! 526 */ 527 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 528 529 /** 530 * All of the processes that have been forced to be foreground. The key 531 * is the pid of the caller who requested it (we hold a death 532 * link on it). 533 */ 534 abstract class ForegroundToken implements IBinder.DeathRecipient { 535 int pid; 536 IBinder token; 537 } 538 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 539 540 /** 541 * List of records for processes that someone had tried to start before the 542 * system was ready. We don't start them at that point, but ensure they 543 * are started by the time booting is complete. 544 */ 545 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 546 547 /** 548 * List of persistent applications that are in the process 549 * of being started. 550 */ 551 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Processes that are being forcibly torn down. 555 */ 556 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 557 558 /** 559 * List of running applications, sorted by recent usage. 560 * The first entry in the list is the least recently used. 561 */ 562 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Where in mLruProcesses that the processes hosting activities start. 566 */ 567 int mLruProcessActivityStart = 0; 568 569 /** 570 * Where in mLruProcesses that the processes hosting services start. 571 * This is after (lower index) than mLruProcessesActivityStart. 572 */ 573 int mLruProcessServiceStart = 0; 574 575 /** 576 * List of processes that should gc as soon as things are idle. 577 */ 578 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 579 580 /** 581 * Processes we want to collect PSS data from. 582 */ 583 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 584 585 /** 586 * Last time we requested PSS data of all processes. 587 */ 588 long mLastFullPssTime = SystemClock.uptimeMillis(); 589 590 /** 591 * If set, the next time we collect PSS data we should do a full collection 592 * with data from native processes and the kernel. 593 */ 594 boolean mFullPssPending = false; 595 596 /** 597 * This is the process holding what we currently consider to be 598 * the "home" activity. 599 */ 600 ProcessRecord mHomeProcess; 601 602 /** 603 * This is the process holding the activity the user last visited that 604 * is in a different process from the one they are currently in. 605 */ 606 ProcessRecord mPreviousProcess; 607 608 /** 609 * The time at which the previous process was last visible. 610 */ 611 long mPreviousProcessVisibleTime; 612 613 /** 614 * Which uses have been started, so are allowed to run code. 615 */ 616 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 617 618 /** 619 * LRU list of history of current users. Most recently current is at the end. 620 */ 621 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 622 623 /** 624 * Constant array of the users that are currently started. 625 */ 626 int[] mStartedUserArray = new int[] { 0 }; 627 628 /** 629 * Registered observers of the user switching mechanics. 630 */ 631 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 632 = new RemoteCallbackList<IUserSwitchObserver>(); 633 634 /** 635 * Currently active user switch. 636 */ 637 Object mCurUserSwitchCallback; 638 639 /** 640 * Packages that the user has asked to have run in screen size 641 * compatibility mode instead of filling the screen. 642 */ 643 final CompatModePackages mCompatModePackages; 644 645 /** 646 * Set of IntentSenderRecord objects that are currently active. 647 */ 648 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 649 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 650 651 /** 652 * Fingerprints (hashCode()) of stack traces that we've 653 * already logged DropBox entries for. Guarded by itself. If 654 * something (rogue user app) forces this over 655 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 656 */ 657 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 658 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 659 660 /** 661 * Strict Mode background batched logging state. 662 * 663 * The string buffer is guarded by itself, and its lock is also 664 * used to determine if another batched write is already 665 * in-flight. 666 */ 667 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 668 669 /** 670 * Keeps track of all IIntentReceivers that have been registered for 671 * broadcasts. Hash keys are the receiver IBinder, hash value is 672 * a ReceiverList. 673 */ 674 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 675 new HashMap<IBinder, ReceiverList>(); 676 677 /** 678 * Resolver for broadcast intents to registered receivers. 679 * Holds BroadcastFilter (subclass of IntentFilter). 680 */ 681 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 682 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 683 @Override 684 protected boolean allowFilterResult( 685 BroadcastFilter filter, List<BroadcastFilter> dest) { 686 IBinder target = filter.receiverList.receiver.asBinder(); 687 for (int i=dest.size()-1; i>=0; i--) { 688 if (dest.get(i).receiverList.receiver.asBinder() == target) { 689 return false; 690 } 691 } 692 return true; 693 } 694 695 @Override 696 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 697 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 698 || userId == filter.owningUserId) { 699 return super.newResult(filter, match, userId); 700 } 701 return null; 702 } 703 704 @Override 705 protected BroadcastFilter[] newArray(int size) { 706 return new BroadcastFilter[size]; 707 } 708 709 @Override 710 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 711 return packageName.equals(filter.packageName); 712 } 713 }; 714 715 /** 716 * State of all active sticky broadcasts per user. Keys are the action of the 717 * sticky Intent, values are an ArrayList of all broadcasted intents with 718 * that action (which should usually be one). The SparseArray is keyed 719 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 720 * for stickies that are sent to all users. 721 */ 722 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 723 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 724 725 final ActiveServices mServices; 726 727 /** 728 * Backup/restore process management 729 */ 730 String mBackupAppName = null; 731 BackupRecord mBackupTarget = null; 732 733 final ProviderMap mProviderMap; 734 735 /** 736 * List of content providers who have clients waiting for them. The 737 * application is currently being launched and the provider will be 738 * removed from this list once it is published. 739 */ 740 final ArrayList<ContentProviderRecord> mLaunchingProviders 741 = new ArrayList<ContentProviderRecord>(); 742 743 /** 744 * File storing persisted {@link #mGrantedUriPermissions}. 745 */ 746 private final AtomicFile mGrantFile; 747 748 /** XML constants used in {@link #mGrantFile} */ 749 private static final String TAG_URI_GRANTS = "uri-grants"; 750 private static final String TAG_URI_GRANT = "uri-grant"; 751 private static final String ATTR_USER_HANDLE = "userHandle"; 752 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 753 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 754 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 755 private static final String ATTR_TARGET_PKG = "targetPkg"; 756 private static final String ATTR_URI = "uri"; 757 private static final String ATTR_MODE_FLAGS = "modeFlags"; 758 private static final String ATTR_CREATED_TIME = "createdTime"; 759 private static final String ATTR_PREFIX = "prefix"; 760 761 /** 762 * Global set of specific {@link Uri} permissions that have been granted. 763 * This optimized lookup structure maps from {@link UriPermission#targetUid} 764 * to {@link UriPermission#uri} to {@link UriPermission}. 765 */ 766 @GuardedBy("this") 767 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 768 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 769 770 public static class GrantUri { 771 public final int sourceUserId; 772 public final Uri uri; 773 public boolean prefix; 774 775 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 776 this.sourceUserId = sourceUserId; 777 this.uri = uri; 778 this.prefix = prefix; 779 } 780 781 @Override 782 public int hashCode() { 783 return toString().hashCode(); 784 } 785 786 @Override 787 public boolean equals(Object o) { 788 if (o instanceof GrantUri) { 789 GrantUri other = (GrantUri) o; 790 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 791 && prefix == other.prefix; 792 } 793 return false; 794 } 795 796 @Override 797 public String toString() { 798 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 799 if (prefix) result += " [prefix]"; 800 return result; 801 } 802 803 public String toSafeString() { 804 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 805 if (prefix) result += " [prefix]"; 806 return result; 807 } 808 809 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 810 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 811 ContentProvider.getUriWithoutUserId(uri), false); 812 } 813 } 814 815 CoreSettingsObserver mCoreSettingsObserver; 816 817 /** 818 * Thread-local storage used to carry caller permissions over through 819 * indirect content-provider access. 820 */ 821 private class Identity { 822 public int pid; 823 public int uid; 824 825 Identity(int _pid, int _uid) { 826 pid = _pid; 827 uid = _uid; 828 } 829 } 830 831 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 832 833 /** 834 * All information we have collected about the runtime performance of 835 * any user id that can impact battery performance. 836 */ 837 final BatteryStatsService mBatteryStatsService; 838 839 /** 840 * Information about component usage 841 */ 842 UsageStatsManagerInternal mUsageStatsService; 843 844 /** 845 * Information about and control over application operations 846 */ 847 final AppOpsService mAppOpsService; 848 849 /** 850 * Save recent tasks information across reboots. 851 */ 852 final TaskPersister mTaskPersister; 853 854 /** 855 * Current configuration information. HistoryRecord objects are given 856 * a reference to this object to indicate which configuration they are 857 * currently running in, so this object must be kept immutable. 858 */ 859 Configuration mConfiguration = new Configuration(); 860 861 /** 862 * Current sequencing integer of the configuration, for skipping old 863 * configurations. 864 */ 865 int mConfigurationSeq = 0; 866 867 /** 868 * Hardware-reported OpenGLES version. 869 */ 870 final int GL_ES_VERSION; 871 872 /** 873 * List of initialization arguments to pass to all processes when binding applications to them. 874 * For example, references to the commonly used services. 875 */ 876 HashMap<String, IBinder> mAppBindArgs; 877 878 /** 879 * Temporary to avoid allocations. Protected by main lock. 880 */ 881 final StringBuilder mStringBuilder = new StringBuilder(256); 882 883 /** 884 * Used to control how we initialize the service. 885 */ 886 ComponentName mTopComponent; 887 String mTopAction = Intent.ACTION_MAIN; 888 String mTopData; 889 boolean mProcessesReady = false; 890 boolean mSystemReady = false; 891 boolean mBooting = false; 892 boolean mCallFinishBooting = false; 893 boolean mBootAnimationComplete = false; 894 boolean mWaitingUpdate = false; 895 boolean mDidUpdate = false; 896 boolean mOnBattery = false; 897 boolean mLaunchWarningShown = false; 898 899 Context mContext; 900 901 int mFactoryTest; 902 903 boolean mCheckedForSetup; 904 905 /** 906 * The time at which we will allow normal application switches again, 907 * after a call to {@link #stopAppSwitches()}. 908 */ 909 long mAppSwitchesAllowedTime; 910 911 /** 912 * This is set to true after the first switch after mAppSwitchesAllowedTime 913 * is set; any switches after that will clear the time. 914 */ 915 boolean mDidAppSwitch; 916 917 /** 918 * Last time (in realtime) at which we checked for power usage. 919 */ 920 long mLastPowerCheckRealtime; 921 922 /** 923 * Last time (in uptime) at which we checked for power usage. 924 */ 925 long mLastPowerCheckUptime; 926 927 /** 928 * Set while we are wanting to sleep, to prevent any 929 * activities from being started/resumed. 930 */ 931 private boolean mSleeping = false; 932 933 /** 934 * Set while we are running a voice interaction. This overrides 935 * sleeping while it is active. 936 */ 937 private boolean mRunningVoice = false; 938 939 /** 940 * State of external calls telling us if the device is asleep. 941 */ 942 private boolean mWentToSleep = false; 943 944 /** 945 * State of external call telling us if the lock screen is shown. 946 */ 947 private boolean mLockScreenShown = false; 948 949 /** 950 * Set if we are shutting down the system, similar to sleeping. 951 */ 952 boolean mShuttingDown = false; 953 954 /** 955 * Current sequence id for oom_adj computation traversal. 956 */ 957 int mAdjSeq = 0; 958 959 /** 960 * Current sequence id for process LRU updating. 961 */ 962 int mLruSeq = 0; 963 964 /** 965 * Keep track of the non-cached/empty process we last found, to help 966 * determine how to distribute cached/empty processes next time. 967 */ 968 int mNumNonCachedProcs = 0; 969 970 /** 971 * Keep track of the number of cached hidden procs, to balance oom adj 972 * distribution between those and empty procs. 973 */ 974 int mNumCachedHiddenProcs = 0; 975 976 /** 977 * Keep track of the number of service processes we last found, to 978 * determine on the next iteration which should be B services. 979 */ 980 int mNumServiceProcs = 0; 981 int mNewNumAServiceProcs = 0; 982 int mNewNumServiceProcs = 0; 983 984 /** 985 * Allow the current computed overall memory level of the system to go down? 986 * This is set to false when we are killing processes for reasons other than 987 * memory management, so that the now smaller process list will not be taken as 988 * an indication that memory is tighter. 989 */ 990 boolean mAllowLowerMemLevel = false; 991 992 /** 993 * The last computed memory level, for holding when we are in a state that 994 * processes are going away for other reasons. 995 */ 996 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 997 998 /** 999 * The last total number of process we have, to determine if changes actually look 1000 * like a shrinking number of process due to lower RAM. 1001 */ 1002 int mLastNumProcesses; 1003 1004 /** 1005 * The uptime of the last time we performed idle maintenance. 1006 */ 1007 long mLastIdleTime = SystemClock.uptimeMillis(); 1008 1009 /** 1010 * Total time spent with RAM that has been added in the past since the last idle time. 1011 */ 1012 long mLowRamTimeSinceLastIdle = 0; 1013 1014 /** 1015 * If RAM is currently low, when that horrible situation started. 1016 */ 1017 long mLowRamStartTime = 0; 1018 1019 /** 1020 * For reporting to battery stats the current top application. 1021 */ 1022 private String mCurResumedPackage = null; 1023 private int mCurResumedUid = -1; 1024 1025 /** 1026 * For reporting to battery stats the apps currently running foreground 1027 * service. The ProcessMap is package/uid tuples; each of these contain 1028 * an array of the currently foreground processes. 1029 */ 1030 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1031 = new ProcessMap<ArrayList<ProcessRecord>>(); 1032 1033 /** 1034 * This is set if we had to do a delayed dexopt of an app before launching 1035 * it, to increase the ANR timeouts in that case. 1036 */ 1037 boolean mDidDexOpt; 1038 1039 /** 1040 * Set if the systemServer made a call to enterSafeMode. 1041 */ 1042 boolean mSafeMode; 1043 1044 String mDebugApp = null; 1045 boolean mWaitForDebugger = false; 1046 boolean mDebugTransient = false; 1047 String mOrigDebugApp = null; 1048 boolean mOrigWaitForDebugger = false; 1049 boolean mAlwaysFinishActivities = false; 1050 IActivityController mController = null; 1051 String mProfileApp = null; 1052 ProcessRecord mProfileProc = null; 1053 String mProfileFile; 1054 ParcelFileDescriptor mProfileFd; 1055 int mSamplingInterval = 0; 1056 boolean mAutoStopProfiler = false; 1057 int mProfileType = 0; 1058 String mOpenGlTraceApp = null; 1059 1060 static class ProcessChangeItem { 1061 static final int CHANGE_ACTIVITIES = 1<<0; 1062 static final int CHANGE_PROCESS_STATE = 1<<1; 1063 int changes; 1064 int uid; 1065 int pid; 1066 int processState; 1067 boolean foregroundActivities; 1068 } 1069 1070 final RemoteCallbackList<IProcessObserver> mProcessObservers 1071 = new RemoteCallbackList<IProcessObserver>(); 1072 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1073 1074 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1075 = new ArrayList<ProcessChangeItem>(); 1076 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1077 = new ArrayList<ProcessChangeItem>(); 1078 1079 /** 1080 * Runtime CPU use collection thread. This object's lock is used to 1081 * perform synchronization with the thread (notifying it to run). 1082 */ 1083 final Thread mProcessCpuThread; 1084 1085 /** 1086 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1087 * Must acquire this object's lock when accessing it. 1088 * NOTE: this lock will be held while doing long operations (trawling 1089 * through all processes in /proc), so it should never be acquired by 1090 * any critical paths such as when holding the main activity manager lock. 1091 */ 1092 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1093 MONITOR_THREAD_CPU_USAGE); 1094 final AtomicLong mLastCpuTime = new AtomicLong(0); 1095 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1096 1097 long mLastWriteTime = 0; 1098 1099 /** 1100 * Used to retain an update lock when the foreground activity is in 1101 * immersive mode. 1102 */ 1103 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1104 1105 /** 1106 * Set to true after the system has finished booting. 1107 */ 1108 boolean mBooted = false; 1109 1110 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1111 int mProcessLimitOverride = -1; 1112 1113 WindowManagerService mWindowManager; 1114 1115 final ActivityThread mSystemThread; 1116 1117 // Holds the current foreground user's id 1118 int mCurrentUserId = 0; 1119 // Holds the target user's id during a user switch 1120 int mTargetUserId = UserHandle.USER_NULL; 1121 // If there are multiple profiles for the current user, their ids are here 1122 // Currently only the primary user can have managed profiles 1123 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1124 1125 /** 1126 * Mapping from each known user ID to the profile group ID it is associated with. 1127 */ 1128 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1129 1130 private UserManagerService mUserManager; 1131 1132 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1133 final ProcessRecord mApp; 1134 final int mPid; 1135 final IApplicationThread mAppThread; 1136 1137 AppDeathRecipient(ProcessRecord app, int pid, 1138 IApplicationThread thread) { 1139 if (localLOGV) Slog.v( 1140 TAG, "New death recipient " + this 1141 + " for thread " + thread.asBinder()); 1142 mApp = app; 1143 mPid = pid; 1144 mAppThread = thread; 1145 } 1146 1147 @Override 1148 public void binderDied() { 1149 if (localLOGV) Slog.v( 1150 TAG, "Death received in " + this 1151 + " for thread " + mAppThread.asBinder()); 1152 synchronized(ActivityManagerService.this) { 1153 appDiedLocked(mApp, mPid, mAppThread); 1154 } 1155 } 1156 } 1157 1158 static final int SHOW_ERROR_MSG = 1; 1159 static final int SHOW_NOT_RESPONDING_MSG = 2; 1160 static final int SHOW_FACTORY_ERROR_MSG = 3; 1161 static final int UPDATE_CONFIGURATION_MSG = 4; 1162 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1163 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1164 static final int SERVICE_TIMEOUT_MSG = 12; 1165 static final int UPDATE_TIME_ZONE = 13; 1166 static final int SHOW_UID_ERROR_MSG = 14; 1167 static final int IM_FEELING_LUCKY_MSG = 15; 1168 static final int PROC_START_TIMEOUT_MSG = 20; 1169 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1170 static final int KILL_APPLICATION_MSG = 22; 1171 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1172 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1173 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1174 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1175 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1176 static final int CLEAR_DNS_CACHE_MSG = 28; 1177 static final int UPDATE_HTTP_PROXY_MSG = 29; 1178 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1179 static final int DISPATCH_PROCESSES_CHANGED = 31; 1180 static final int DISPATCH_PROCESS_DIED = 32; 1181 static final int REPORT_MEM_USAGE_MSG = 33; 1182 static final int REPORT_USER_SWITCH_MSG = 34; 1183 static final int CONTINUE_USER_SWITCH_MSG = 35; 1184 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1185 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1186 static final int PERSIST_URI_GRANTS_MSG = 38; 1187 static final int REQUEST_ALL_PSS_MSG = 39; 1188 static final int START_PROFILES_MSG = 40; 1189 static final int UPDATE_TIME = 41; 1190 static final int SYSTEM_USER_START_MSG = 42; 1191 static final int SYSTEM_USER_CURRENT_MSG = 43; 1192 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1193 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1194 static final int START_USER_SWITCH_MSG = 46; 1195 1196 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1197 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1198 static final int FIRST_COMPAT_MODE_MSG = 300; 1199 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1200 1201 AlertDialog mUidAlert; 1202 CompatModeDialog mCompatModeDialog; 1203 long mLastMemUsageReportTime = 0; 1204 1205 private LockToAppRequestDialog mLockToAppRequest; 1206 1207 /** 1208 * Flag whether the current user is a "monkey", i.e. whether 1209 * the UI is driven by a UI automation tool. 1210 */ 1211 private boolean mUserIsMonkey; 1212 1213 /** Flag whether the device has a Recents UI */ 1214 boolean mHasRecents; 1215 1216 /** The dimensions of the thumbnails in the Recents UI. */ 1217 int mThumbnailWidth; 1218 int mThumbnailHeight; 1219 1220 final ServiceThread mHandlerThread; 1221 final MainHandler mHandler; 1222 1223 final class MainHandler extends Handler { 1224 public MainHandler(Looper looper) { 1225 super(looper, null, true); 1226 } 1227 1228 @Override 1229 public void handleMessage(Message msg) { 1230 switch (msg.what) { 1231 case SHOW_ERROR_MSG: { 1232 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1233 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1234 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1235 synchronized (ActivityManagerService.this) { 1236 ProcessRecord proc = (ProcessRecord)data.get("app"); 1237 AppErrorResult res = (AppErrorResult) data.get("result"); 1238 if (proc != null && proc.crashDialog != null) { 1239 Slog.e(TAG, "App already has crash dialog: " + proc); 1240 if (res != null) { 1241 res.set(0); 1242 } 1243 return; 1244 } 1245 boolean isBackground = (UserHandle.getAppId(proc.uid) 1246 >= Process.FIRST_APPLICATION_UID 1247 && proc.pid != MY_PID); 1248 for (int userId : mCurrentProfileIds) { 1249 isBackground &= (proc.userId != userId); 1250 } 1251 if (isBackground && !showBackground) { 1252 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1253 if (res != null) { 1254 res.set(0); 1255 } 1256 return; 1257 } 1258 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1259 Dialog d = new AppErrorDialog(mContext, 1260 ActivityManagerService.this, res, proc); 1261 d.show(); 1262 proc.crashDialog = d; 1263 } else { 1264 // The device is asleep, so just pretend that the user 1265 // saw a crash dialog and hit "force quit". 1266 if (res != null) { 1267 res.set(0); 1268 } 1269 } 1270 } 1271 1272 ensureBootCompleted(); 1273 } break; 1274 case SHOW_NOT_RESPONDING_MSG: { 1275 synchronized (ActivityManagerService.this) { 1276 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1277 ProcessRecord proc = (ProcessRecord)data.get("app"); 1278 if (proc != null && proc.anrDialog != null) { 1279 Slog.e(TAG, "App already has anr dialog: " + proc); 1280 return; 1281 } 1282 1283 Intent intent = new Intent("android.intent.action.ANR"); 1284 if (!mProcessesReady) { 1285 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1286 | Intent.FLAG_RECEIVER_FOREGROUND); 1287 } 1288 broadcastIntentLocked(null, null, intent, 1289 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1290 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1291 1292 if (mShowDialogs) { 1293 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1294 mContext, proc, (ActivityRecord)data.get("activity"), 1295 msg.arg1 != 0); 1296 d.show(); 1297 proc.anrDialog = d; 1298 } else { 1299 // Just kill the app if there is no dialog to be shown. 1300 killAppAtUsersRequest(proc, null); 1301 } 1302 } 1303 1304 ensureBootCompleted(); 1305 } break; 1306 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1307 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1308 synchronized (ActivityManagerService.this) { 1309 ProcessRecord proc = (ProcessRecord) data.get("app"); 1310 if (proc == null) { 1311 Slog.e(TAG, "App not found when showing strict mode dialog."); 1312 break; 1313 } 1314 if (proc.crashDialog != null) { 1315 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1316 return; 1317 } 1318 AppErrorResult res = (AppErrorResult) data.get("result"); 1319 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1320 Dialog d = new StrictModeViolationDialog(mContext, 1321 ActivityManagerService.this, res, proc); 1322 d.show(); 1323 proc.crashDialog = d; 1324 } else { 1325 // The device is asleep, so just pretend that the user 1326 // saw a crash dialog and hit "force quit". 1327 res.set(0); 1328 } 1329 } 1330 ensureBootCompleted(); 1331 } break; 1332 case SHOW_FACTORY_ERROR_MSG: { 1333 Dialog d = new FactoryErrorDialog( 1334 mContext, msg.getData().getCharSequence("msg")); 1335 d.show(); 1336 ensureBootCompleted(); 1337 } break; 1338 case UPDATE_CONFIGURATION_MSG: { 1339 final ContentResolver resolver = mContext.getContentResolver(); 1340 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1341 } break; 1342 case GC_BACKGROUND_PROCESSES_MSG: { 1343 synchronized (ActivityManagerService.this) { 1344 performAppGcsIfAppropriateLocked(); 1345 } 1346 } break; 1347 case WAIT_FOR_DEBUGGER_MSG: { 1348 synchronized (ActivityManagerService.this) { 1349 ProcessRecord app = (ProcessRecord)msg.obj; 1350 if (msg.arg1 != 0) { 1351 if (!app.waitedForDebugger) { 1352 Dialog d = new AppWaitingForDebuggerDialog( 1353 ActivityManagerService.this, 1354 mContext, app); 1355 app.waitDialog = d; 1356 app.waitedForDebugger = true; 1357 d.show(); 1358 } 1359 } else { 1360 if (app.waitDialog != null) { 1361 app.waitDialog.dismiss(); 1362 app.waitDialog = null; 1363 } 1364 } 1365 } 1366 } break; 1367 case SERVICE_TIMEOUT_MSG: { 1368 if (mDidDexOpt) { 1369 mDidDexOpt = false; 1370 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1371 nmsg.obj = msg.obj; 1372 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1373 return; 1374 } 1375 mServices.serviceTimeout((ProcessRecord)msg.obj); 1376 } break; 1377 case UPDATE_TIME_ZONE: { 1378 synchronized (ActivityManagerService.this) { 1379 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1380 ProcessRecord r = mLruProcesses.get(i); 1381 if (r.thread != null) { 1382 try { 1383 r.thread.updateTimeZone(); 1384 } catch (RemoteException ex) { 1385 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1386 } 1387 } 1388 } 1389 } 1390 } break; 1391 case CLEAR_DNS_CACHE_MSG: { 1392 synchronized (ActivityManagerService.this) { 1393 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1394 ProcessRecord r = mLruProcesses.get(i); 1395 if (r.thread != null) { 1396 try { 1397 r.thread.clearDnsCache(); 1398 } catch (RemoteException ex) { 1399 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1400 } 1401 } 1402 } 1403 } 1404 } break; 1405 case UPDATE_HTTP_PROXY_MSG: { 1406 ProxyInfo proxy = (ProxyInfo)msg.obj; 1407 String host = ""; 1408 String port = ""; 1409 String exclList = ""; 1410 Uri pacFileUrl = Uri.EMPTY; 1411 if (proxy != null) { 1412 host = proxy.getHost(); 1413 port = Integer.toString(proxy.getPort()); 1414 exclList = proxy.getExclusionListAsString(); 1415 pacFileUrl = proxy.getPacFileUrl(); 1416 } 1417 synchronized (ActivityManagerService.this) { 1418 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1419 ProcessRecord r = mLruProcesses.get(i); 1420 if (r.thread != null) { 1421 try { 1422 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1423 } catch (RemoteException ex) { 1424 Slog.w(TAG, "Failed to update http proxy for: " + 1425 r.info.processName); 1426 } 1427 } 1428 } 1429 } 1430 } break; 1431 case SHOW_UID_ERROR_MSG: { 1432 String title = "System UIDs Inconsistent"; 1433 String text = "UIDs on the system are inconsistent, you need to wipe your" 1434 + " data partition or your device will be unstable."; 1435 Log.e(TAG, title + ": " + text); 1436 if (mShowDialogs) { 1437 // XXX This is a temporary dialog, no need to localize. 1438 AlertDialog d = new BaseErrorDialog(mContext); 1439 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1440 d.setCancelable(false); 1441 d.setTitle(title); 1442 d.setMessage(text); 1443 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1444 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1445 mUidAlert = d; 1446 d.show(); 1447 } 1448 } break; 1449 case IM_FEELING_LUCKY_MSG: { 1450 if (mUidAlert != null) { 1451 mUidAlert.dismiss(); 1452 mUidAlert = null; 1453 } 1454 } break; 1455 case PROC_START_TIMEOUT_MSG: { 1456 if (mDidDexOpt) { 1457 mDidDexOpt = false; 1458 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1459 nmsg.obj = msg.obj; 1460 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1461 return; 1462 } 1463 ProcessRecord app = (ProcessRecord)msg.obj; 1464 synchronized (ActivityManagerService.this) { 1465 processStartTimedOutLocked(app); 1466 } 1467 } break; 1468 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1469 synchronized (ActivityManagerService.this) { 1470 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1471 } 1472 } break; 1473 case KILL_APPLICATION_MSG: { 1474 synchronized (ActivityManagerService.this) { 1475 int appid = msg.arg1; 1476 boolean restart = (msg.arg2 == 1); 1477 Bundle bundle = (Bundle)msg.obj; 1478 String pkg = bundle.getString("pkg"); 1479 String reason = bundle.getString("reason"); 1480 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1481 false, UserHandle.USER_ALL, reason); 1482 } 1483 } break; 1484 case FINALIZE_PENDING_INTENT_MSG: { 1485 ((PendingIntentRecord)msg.obj).completeFinalize(); 1486 } break; 1487 case POST_HEAVY_NOTIFICATION_MSG: { 1488 INotificationManager inm = NotificationManager.getService(); 1489 if (inm == null) { 1490 return; 1491 } 1492 1493 ActivityRecord root = (ActivityRecord)msg.obj; 1494 ProcessRecord process = root.app; 1495 if (process == null) { 1496 return; 1497 } 1498 1499 try { 1500 Context context = mContext.createPackageContext(process.info.packageName, 0); 1501 String text = mContext.getString(R.string.heavy_weight_notification, 1502 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1503 Notification notification = new Notification(); 1504 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1505 notification.when = 0; 1506 notification.flags = Notification.FLAG_ONGOING_EVENT; 1507 notification.tickerText = text; 1508 notification.defaults = 0; // please be quiet 1509 notification.sound = null; 1510 notification.vibrate = null; 1511 notification.color = mContext.getResources().getColor( 1512 com.android.internal.R.color.system_notification_accent_color); 1513 notification.setLatestEventInfo(context, text, 1514 mContext.getText(R.string.heavy_weight_notification_detail), 1515 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1516 PendingIntent.FLAG_CANCEL_CURRENT, null, 1517 new UserHandle(root.userId))); 1518 1519 try { 1520 int[] outId = new int[1]; 1521 inm.enqueueNotificationWithTag("android", "android", null, 1522 R.string.heavy_weight_notification, 1523 notification, outId, root.userId); 1524 } catch (RuntimeException e) { 1525 Slog.w(ActivityManagerService.TAG, 1526 "Error showing notification for heavy-weight app", e); 1527 } catch (RemoteException e) { 1528 } 1529 } catch (NameNotFoundException e) { 1530 Slog.w(TAG, "Unable to create context for heavy notification", e); 1531 } 1532 } break; 1533 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1534 INotificationManager inm = NotificationManager.getService(); 1535 if (inm == null) { 1536 return; 1537 } 1538 try { 1539 inm.cancelNotificationWithTag("android", null, 1540 R.string.heavy_weight_notification, msg.arg1); 1541 } catch (RuntimeException e) { 1542 Slog.w(ActivityManagerService.TAG, 1543 "Error canceling notification for service", e); 1544 } catch (RemoteException e) { 1545 } 1546 } break; 1547 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1548 synchronized (ActivityManagerService.this) { 1549 checkExcessivePowerUsageLocked(true); 1550 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1551 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1552 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1553 } 1554 } break; 1555 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1556 synchronized (ActivityManagerService.this) { 1557 ActivityRecord ar = (ActivityRecord)msg.obj; 1558 if (mCompatModeDialog != null) { 1559 if (mCompatModeDialog.mAppInfo.packageName.equals( 1560 ar.info.applicationInfo.packageName)) { 1561 return; 1562 } 1563 mCompatModeDialog.dismiss(); 1564 mCompatModeDialog = null; 1565 } 1566 if (ar != null && false) { 1567 if (mCompatModePackages.getPackageAskCompatModeLocked( 1568 ar.packageName)) { 1569 int mode = mCompatModePackages.computeCompatModeLocked( 1570 ar.info.applicationInfo); 1571 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1572 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1573 mCompatModeDialog = new CompatModeDialog( 1574 ActivityManagerService.this, mContext, 1575 ar.info.applicationInfo); 1576 mCompatModeDialog.show(); 1577 } 1578 } 1579 } 1580 } 1581 break; 1582 } 1583 case DISPATCH_PROCESSES_CHANGED: { 1584 dispatchProcessesChanged(); 1585 break; 1586 } 1587 case DISPATCH_PROCESS_DIED: { 1588 final int pid = msg.arg1; 1589 final int uid = msg.arg2; 1590 dispatchProcessDied(pid, uid); 1591 break; 1592 } 1593 case REPORT_MEM_USAGE_MSG: { 1594 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1595 Thread thread = new Thread() { 1596 @Override public void run() { 1597 final SparseArray<ProcessMemInfo> infoMap 1598 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1599 for (int i=0, N=memInfos.size(); i<N; i++) { 1600 ProcessMemInfo mi = memInfos.get(i); 1601 infoMap.put(mi.pid, mi); 1602 } 1603 updateCpuStatsNow(); 1604 synchronized (mProcessCpuTracker) { 1605 final int N = mProcessCpuTracker.countStats(); 1606 for (int i=0; i<N; i++) { 1607 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1608 if (st.vsize > 0) { 1609 long pss = Debug.getPss(st.pid, null); 1610 if (pss > 0) { 1611 if (infoMap.indexOfKey(st.pid) < 0) { 1612 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1613 ProcessList.NATIVE_ADJ, -1, "native", null); 1614 mi.pss = pss; 1615 memInfos.add(mi); 1616 } 1617 } 1618 } 1619 } 1620 } 1621 1622 long totalPss = 0; 1623 for (int i=0, N=memInfos.size(); i<N; i++) { 1624 ProcessMemInfo mi = memInfos.get(i); 1625 if (mi.pss == 0) { 1626 mi.pss = Debug.getPss(mi.pid, null); 1627 } 1628 totalPss += mi.pss; 1629 } 1630 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1631 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1632 if (lhs.oomAdj != rhs.oomAdj) { 1633 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1634 } 1635 if (lhs.pss != rhs.pss) { 1636 return lhs.pss < rhs.pss ? 1 : -1; 1637 } 1638 return 0; 1639 } 1640 }); 1641 1642 StringBuilder tag = new StringBuilder(128); 1643 StringBuilder stack = new StringBuilder(128); 1644 tag.append("Low on memory -- "); 1645 appendMemBucket(tag, totalPss, "total", false); 1646 appendMemBucket(stack, totalPss, "total", true); 1647 1648 StringBuilder logBuilder = new StringBuilder(1024); 1649 logBuilder.append("Low on memory:\n"); 1650 1651 boolean firstLine = true; 1652 int lastOomAdj = Integer.MIN_VALUE; 1653 for (int i=0, N=memInfos.size(); i<N; i++) { 1654 ProcessMemInfo mi = memInfos.get(i); 1655 1656 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1657 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1658 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1659 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1660 if (lastOomAdj != mi.oomAdj) { 1661 lastOomAdj = mi.oomAdj; 1662 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1663 tag.append(" / "); 1664 } 1665 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1666 if (firstLine) { 1667 stack.append(":"); 1668 firstLine = false; 1669 } 1670 stack.append("\n\t at "); 1671 } else { 1672 stack.append("$"); 1673 } 1674 } else { 1675 tag.append(" "); 1676 stack.append("$"); 1677 } 1678 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1679 appendMemBucket(tag, mi.pss, mi.name, false); 1680 } 1681 appendMemBucket(stack, mi.pss, mi.name, true); 1682 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1683 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1684 stack.append("("); 1685 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1686 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1687 stack.append(DUMP_MEM_OOM_LABEL[k]); 1688 stack.append(":"); 1689 stack.append(DUMP_MEM_OOM_ADJ[k]); 1690 } 1691 } 1692 stack.append(")"); 1693 } 1694 } 1695 1696 logBuilder.append(" "); 1697 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1698 logBuilder.append(' '); 1699 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1700 logBuilder.append(' '); 1701 ProcessList.appendRamKb(logBuilder, mi.pss); 1702 logBuilder.append(" kB: "); 1703 logBuilder.append(mi.name); 1704 logBuilder.append(" ("); 1705 logBuilder.append(mi.pid); 1706 logBuilder.append(") "); 1707 logBuilder.append(mi.adjType); 1708 logBuilder.append('\n'); 1709 if (mi.adjReason != null) { 1710 logBuilder.append(" "); 1711 logBuilder.append(mi.adjReason); 1712 logBuilder.append('\n'); 1713 } 1714 } 1715 1716 logBuilder.append(" "); 1717 ProcessList.appendRamKb(logBuilder, totalPss); 1718 logBuilder.append(" kB: TOTAL\n"); 1719 1720 long[] infos = new long[Debug.MEMINFO_COUNT]; 1721 Debug.getMemInfo(infos); 1722 logBuilder.append(" MemInfo: "); 1723 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1724 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1725 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1726 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1727 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1728 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1729 logBuilder.append(" ZRAM: "); 1730 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1731 logBuilder.append(" kB RAM, "); 1732 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1733 logBuilder.append(" kB swap total, "); 1734 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1735 logBuilder.append(" kB swap free\n"); 1736 } 1737 Slog.i(TAG, logBuilder.toString()); 1738 1739 StringBuilder dropBuilder = new StringBuilder(1024); 1740 /* 1741 StringWriter oomSw = new StringWriter(); 1742 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1743 StringWriter catSw = new StringWriter(); 1744 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1745 String[] emptyArgs = new String[] { }; 1746 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1747 oomPw.flush(); 1748 String oomString = oomSw.toString(); 1749 */ 1750 dropBuilder.append(stack); 1751 dropBuilder.append('\n'); 1752 dropBuilder.append('\n'); 1753 dropBuilder.append(logBuilder); 1754 dropBuilder.append('\n'); 1755 /* 1756 dropBuilder.append(oomString); 1757 dropBuilder.append('\n'); 1758 */ 1759 StringWriter catSw = new StringWriter(); 1760 synchronized (ActivityManagerService.this) { 1761 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1762 String[] emptyArgs = new String[] { }; 1763 catPw.println(); 1764 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1765 catPw.println(); 1766 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1767 false, false, null); 1768 catPw.println(); 1769 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1770 catPw.flush(); 1771 } 1772 dropBuilder.append(catSw.toString()); 1773 addErrorToDropBox("lowmem", null, "system_server", null, 1774 null, tag.toString(), dropBuilder.toString(), null, null); 1775 //Slog.i(TAG, "Sent to dropbox:"); 1776 //Slog.i(TAG, dropBuilder.toString()); 1777 synchronized (ActivityManagerService.this) { 1778 long now = SystemClock.uptimeMillis(); 1779 if (mLastMemUsageReportTime < now) { 1780 mLastMemUsageReportTime = now; 1781 } 1782 } 1783 } 1784 }; 1785 thread.start(); 1786 break; 1787 } 1788 case START_USER_SWITCH_MSG: { 1789 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1790 break; 1791 } 1792 case REPORT_USER_SWITCH_MSG: { 1793 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1794 break; 1795 } 1796 case CONTINUE_USER_SWITCH_MSG: { 1797 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1798 break; 1799 } 1800 case USER_SWITCH_TIMEOUT_MSG: { 1801 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1802 break; 1803 } 1804 case IMMERSIVE_MODE_LOCK_MSG: { 1805 final boolean nextState = (msg.arg1 != 0); 1806 if (mUpdateLock.isHeld() != nextState) { 1807 if (DEBUG_IMMERSIVE) { 1808 final ActivityRecord r = (ActivityRecord) msg.obj; 1809 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1810 } 1811 if (nextState) { 1812 mUpdateLock.acquire(); 1813 } else { 1814 mUpdateLock.release(); 1815 } 1816 } 1817 break; 1818 } 1819 case PERSIST_URI_GRANTS_MSG: { 1820 writeGrantedUriPermissions(); 1821 break; 1822 } 1823 case REQUEST_ALL_PSS_MSG: { 1824 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1825 break; 1826 } 1827 case START_PROFILES_MSG: { 1828 synchronized (ActivityManagerService.this) { 1829 startProfilesLocked(); 1830 } 1831 break; 1832 } 1833 case UPDATE_TIME: { 1834 synchronized (ActivityManagerService.this) { 1835 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1836 ProcessRecord r = mLruProcesses.get(i); 1837 if (r.thread != null) { 1838 try { 1839 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1840 } catch (RemoteException ex) { 1841 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1842 } 1843 } 1844 } 1845 } 1846 break; 1847 } 1848 case SYSTEM_USER_START_MSG: { 1849 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1850 Integer.toString(msg.arg1), msg.arg1); 1851 mSystemServiceManager.startUser(msg.arg1); 1852 break; 1853 } 1854 case SYSTEM_USER_CURRENT_MSG: { 1855 mBatteryStatsService.noteEvent( 1856 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1857 Integer.toString(msg.arg2), msg.arg2); 1858 mBatteryStatsService.noteEvent( 1859 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1860 Integer.toString(msg.arg1), msg.arg1); 1861 mSystemServiceManager.switchUser(msg.arg1); 1862 mLockToAppRequest.clearPrompt(); 1863 break; 1864 } 1865 case ENTER_ANIMATION_COMPLETE_MSG: { 1866 synchronized (ActivityManagerService.this) { 1867 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1868 if (r != null && r.app != null && r.app.thread != null) { 1869 try { 1870 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1871 } catch (RemoteException e) { 1872 } 1873 } 1874 } 1875 break; 1876 } 1877 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1878 enableScreenAfterBoot(); 1879 break; 1880 } 1881 } 1882 } 1883 }; 1884 1885 static final int COLLECT_PSS_BG_MSG = 1; 1886 1887 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1888 @Override 1889 public void handleMessage(Message msg) { 1890 switch (msg.what) { 1891 case COLLECT_PSS_BG_MSG: { 1892 long start = SystemClock.uptimeMillis(); 1893 MemInfoReader memInfo = null; 1894 synchronized (ActivityManagerService.this) { 1895 if (mFullPssPending) { 1896 mFullPssPending = false; 1897 memInfo = new MemInfoReader(); 1898 } 1899 } 1900 if (memInfo != null) { 1901 updateCpuStatsNow(); 1902 long nativeTotalPss = 0; 1903 synchronized (mProcessCpuTracker) { 1904 final int N = mProcessCpuTracker.countStats(); 1905 for (int j=0; j<N; j++) { 1906 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1907 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1908 // This is definitely an application process; skip it. 1909 continue; 1910 } 1911 synchronized (mPidsSelfLocked) { 1912 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1913 // This is one of our own processes; skip it. 1914 continue; 1915 } 1916 } 1917 nativeTotalPss += Debug.getPss(st.pid, null); 1918 } 1919 } 1920 memInfo.readMemInfo(); 1921 synchronized (ActivityManagerService.this) { 1922 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1923 + (SystemClock.uptimeMillis()-start) + "ms"); 1924 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1925 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1926 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1927 +memInfo.getSlabSizeKb(), 1928 nativeTotalPss); 1929 } 1930 } 1931 1932 int i=0, num=0; 1933 long[] tmp = new long[1]; 1934 do { 1935 ProcessRecord proc; 1936 int procState; 1937 int pid; 1938 synchronized (ActivityManagerService.this) { 1939 if (i >= mPendingPssProcesses.size()) { 1940 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1941 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1942 mPendingPssProcesses.clear(); 1943 return; 1944 } 1945 proc = mPendingPssProcesses.get(i); 1946 procState = proc.pssProcState; 1947 if (proc.thread != null && procState == proc.setProcState) { 1948 pid = proc.pid; 1949 } else { 1950 proc = null; 1951 pid = 0; 1952 } 1953 i++; 1954 } 1955 if (proc != null) { 1956 long pss = Debug.getPss(pid, tmp); 1957 synchronized (ActivityManagerService.this) { 1958 if (proc.thread != null && proc.setProcState == procState 1959 && proc.pid == pid) { 1960 num++; 1961 proc.lastPssTime = SystemClock.uptimeMillis(); 1962 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1963 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1964 + ": " + pss + " lastPss=" + proc.lastPss 1965 + " state=" + ProcessList.makeProcStateString(procState)); 1966 if (proc.initialIdlePss == 0) { 1967 proc.initialIdlePss = pss; 1968 } 1969 proc.lastPss = pss; 1970 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1971 proc.lastCachedPss = pss; 1972 } 1973 } 1974 } 1975 } 1976 } while (true); 1977 } 1978 } 1979 } 1980 }; 1981 1982 /** 1983 * Monitor for package changes and update our internal state. 1984 */ 1985 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1986 @Override 1987 public void onPackageRemoved(String packageName, int uid) { 1988 // Remove all tasks with activities in the specified package from the list of recent tasks 1989 synchronized (ActivityManagerService.this) { 1990 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1991 TaskRecord tr = mRecentTasks.get(i); 1992 ComponentName cn = tr.intent.getComponent(); 1993 if (cn != null && cn.getPackageName().equals(packageName)) { 1994 // If the package name matches, remove the task and kill the process 1995 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1996 } 1997 } 1998 } 1999 } 2000 2001 @Override 2002 public boolean onPackageChanged(String packageName, int uid, String[] components) { 2003 onPackageModified(packageName); 2004 return true; 2005 } 2006 2007 @Override 2008 public void onPackageModified(String packageName) { 2009 final PackageManager pm = mContext.getPackageManager(); 2010 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2011 new ArrayList<Pair<Intent, Integer>>(); 2012 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2013 // Copy the list of recent tasks so that we don't hold onto the lock on 2014 // ActivityManagerService for long periods while checking if components exist. 2015 synchronized (ActivityManagerService.this) { 2016 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2017 TaskRecord tr = mRecentTasks.get(i); 2018 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2019 } 2020 } 2021 // Check the recent tasks and filter out all tasks with components that no longer exist. 2022 Intent tmpI = new Intent(); 2023 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2024 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2025 ComponentName cn = p.first.getComponent(); 2026 if (cn != null && cn.getPackageName().equals(packageName)) { 2027 try { 2028 // Add the task to the list to remove if the component no longer exists 2029 tmpI.setComponent(cn); 2030 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2031 tasksToRemove.add(p.second); 2032 } 2033 } catch (Exception e) {} 2034 } 2035 } 2036 // Prune all the tasks with removed components from the list of recent tasks 2037 synchronized (ActivityManagerService.this) { 2038 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2039 // Remove the task but don't kill the process (since other components in that 2040 // package may still be running and in the background) 2041 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2042 } 2043 } 2044 } 2045 2046 @Override 2047 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2048 // Force stop the specified packages 2049 if (packages != null) { 2050 for (String pkg : packages) { 2051 synchronized (ActivityManagerService.this) { 2052 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2053 "finished booting")) { 2054 return true; 2055 } 2056 } 2057 } 2058 } 2059 return false; 2060 } 2061 }; 2062 2063 public void setSystemProcess() { 2064 try { 2065 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2066 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2067 ServiceManager.addService("meminfo", new MemBinder(this)); 2068 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2069 ServiceManager.addService("dbinfo", new DbBinder(this)); 2070 if (MONITOR_CPU_USAGE) { 2071 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2072 } 2073 ServiceManager.addService("permission", new PermissionController(this)); 2074 2075 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2076 "android", STOCK_PM_FLAGS); 2077 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2078 2079 synchronized (this) { 2080 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2081 app.persistent = true; 2082 app.pid = MY_PID; 2083 app.maxAdj = ProcessList.SYSTEM_ADJ; 2084 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2085 mProcessNames.put(app.processName, app.uid, app); 2086 synchronized (mPidsSelfLocked) { 2087 mPidsSelfLocked.put(app.pid, app); 2088 } 2089 updateLruProcessLocked(app, false, null); 2090 updateOomAdjLocked(); 2091 } 2092 } catch (PackageManager.NameNotFoundException e) { 2093 throw new RuntimeException( 2094 "Unable to find android system package", e); 2095 } 2096 } 2097 2098 public void setWindowManager(WindowManagerService wm) { 2099 mWindowManager = wm; 2100 mStackSupervisor.setWindowManager(wm); 2101 } 2102 2103 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2104 mUsageStatsService = usageStatsManager; 2105 } 2106 2107 public void startObservingNativeCrashes() { 2108 final NativeCrashListener ncl = new NativeCrashListener(this); 2109 ncl.start(); 2110 } 2111 2112 public IAppOpsService getAppOpsService() { 2113 return mAppOpsService; 2114 } 2115 2116 static class MemBinder extends Binder { 2117 ActivityManagerService mActivityManagerService; 2118 MemBinder(ActivityManagerService activityManagerService) { 2119 mActivityManagerService = activityManagerService; 2120 } 2121 2122 @Override 2123 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2124 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2125 != PackageManager.PERMISSION_GRANTED) { 2126 pw.println("Permission Denial: can't dump meminfo from from pid=" 2127 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2128 + " without permission " + android.Manifest.permission.DUMP); 2129 return; 2130 } 2131 2132 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2133 } 2134 } 2135 2136 static class GraphicsBinder extends Binder { 2137 ActivityManagerService mActivityManagerService; 2138 GraphicsBinder(ActivityManagerService activityManagerService) { 2139 mActivityManagerService = activityManagerService; 2140 } 2141 2142 @Override 2143 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2144 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2145 != PackageManager.PERMISSION_GRANTED) { 2146 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2147 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2148 + " without permission " + android.Manifest.permission.DUMP); 2149 return; 2150 } 2151 2152 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2153 } 2154 } 2155 2156 static class DbBinder extends Binder { 2157 ActivityManagerService mActivityManagerService; 2158 DbBinder(ActivityManagerService activityManagerService) { 2159 mActivityManagerService = activityManagerService; 2160 } 2161 2162 @Override 2163 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2164 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2165 != PackageManager.PERMISSION_GRANTED) { 2166 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2167 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2168 + " without permission " + android.Manifest.permission.DUMP); 2169 return; 2170 } 2171 2172 mActivityManagerService.dumpDbInfo(fd, pw, args); 2173 } 2174 } 2175 2176 static class CpuBinder extends Binder { 2177 ActivityManagerService mActivityManagerService; 2178 CpuBinder(ActivityManagerService activityManagerService) { 2179 mActivityManagerService = activityManagerService; 2180 } 2181 2182 @Override 2183 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2184 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2185 != PackageManager.PERMISSION_GRANTED) { 2186 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2187 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2188 + " without permission " + android.Manifest.permission.DUMP); 2189 return; 2190 } 2191 2192 synchronized (mActivityManagerService.mProcessCpuTracker) { 2193 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2194 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2195 SystemClock.uptimeMillis())); 2196 } 2197 } 2198 } 2199 2200 public static final class Lifecycle extends SystemService { 2201 private final ActivityManagerService mService; 2202 2203 public Lifecycle(Context context) { 2204 super(context); 2205 mService = new ActivityManagerService(context); 2206 } 2207 2208 @Override 2209 public void onStart() { 2210 mService.start(); 2211 } 2212 2213 public ActivityManagerService getService() { 2214 return mService; 2215 } 2216 } 2217 2218 // Note: This method is invoked on the main thread but may need to attach various 2219 // handlers to other threads. So take care to be explicit about the looper. 2220 public ActivityManagerService(Context systemContext) { 2221 mContext = systemContext; 2222 mFactoryTest = FactoryTest.getMode(); 2223 mSystemThread = ActivityThread.currentActivityThread(); 2224 2225 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2226 2227 mHandlerThread = new ServiceThread(TAG, 2228 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2229 mHandlerThread.start(); 2230 mHandler = new MainHandler(mHandlerThread.getLooper()); 2231 2232 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2233 "foreground", BROADCAST_FG_TIMEOUT, false); 2234 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2235 "background", BROADCAST_BG_TIMEOUT, true); 2236 mBroadcastQueues[0] = mFgBroadcastQueue; 2237 mBroadcastQueues[1] = mBgBroadcastQueue; 2238 2239 mServices = new ActiveServices(this); 2240 mProviderMap = new ProviderMap(this); 2241 2242 // TODO: Move creation of battery stats service outside of activity manager service. 2243 File dataDir = Environment.getDataDirectory(); 2244 File systemDir = new File(dataDir, "system"); 2245 systemDir.mkdirs(); 2246 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2247 mBatteryStatsService.getActiveStatistics().readLocked(); 2248 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2249 mOnBattery = DEBUG_POWER ? true 2250 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2251 mBatteryStatsService.getActiveStatistics().setCallback(this); 2252 2253 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2254 2255 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2256 2257 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2258 2259 // User 0 is the first and only user that runs at boot. 2260 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2261 mUserLru.add(Integer.valueOf(0)); 2262 updateStartedUserArrayLocked(); 2263 2264 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2265 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2266 2267 mConfiguration.setToDefaults(); 2268 mConfiguration.setLocale(Locale.getDefault()); 2269 2270 mConfigurationSeq = mConfiguration.seq = 1; 2271 mProcessCpuTracker.init(); 2272 2273 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2274 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2275 mStackSupervisor = new ActivityStackSupervisor(this); 2276 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2277 2278 mProcessCpuThread = new Thread("CpuTracker") { 2279 @Override 2280 public void run() { 2281 while (true) { 2282 try { 2283 try { 2284 synchronized(this) { 2285 final long now = SystemClock.uptimeMillis(); 2286 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2287 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2288 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2289 // + ", write delay=" + nextWriteDelay); 2290 if (nextWriteDelay < nextCpuDelay) { 2291 nextCpuDelay = nextWriteDelay; 2292 } 2293 if (nextCpuDelay > 0) { 2294 mProcessCpuMutexFree.set(true); 2295 this.wait(nextCpuDelay); 2296 } 2297 } 2298 } catch (InterruptedException e) { 2299 } 2300 updateCpuStatsNow(); 2301 } catch (Exception e) { 2302 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2303 } 2304 } 2305 } 2306 }; 2307 2308 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2309 2310 Watchdog.getInstance().addMonitor(this); 2311 Watchdog.getInstance().addThread(mHandler); 2312 } 2313 2314 public void setSystemServiceManager(SystemServiceManager mgr) { 2315 mSystemServiceManager = mgr; 2316 } 2317 2318 private void start() { 2319 Process.removeAllProcessGroups(); 2320 mProcessCpuThread.start(); 2321 2322 mBatteryStatsService.publish(mContext); 2323 mAppOpsService.publish(mContext); 2324 Slog.d("AppOps", "AppOpsService published"); 2325 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2326 } 2327 2328 public void initPowerManagement() { 2329 mStackSupervisor.initPowerManagement(); 2330 mBatteryStatsService.initPowerManagement(); 2331 } 2332 2333 @Override 2334 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2335 throws RemoteException { 2336 if (code == SYSPROPS_TRANSACTION) { 2337 // We need to tell all apps about the system property change. 2338 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2339 synchronized(this) { 2340 final int NP = mProcessNames.getMap().size(); 2341 for (int ip=0; ip<NP; ip++) { 2342 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2343 final int NA = apps.size(); 2344 for (int ia=0; ia<NA; ia++) { 2345 ProcessRecord app = apps.valueAt(ia); 2346 if (app.thread != null) { 2347 procs.add(app.thread.asBinder()); 2348 } 2349 } 2350 } 2351 } 2352 2353 int N = procs.size(); 2354 for (int i=0; i<N; i++) { 2355 Parcel data2 = Parcel.obtain(); 2356 try { 2357 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2358 } catch (RemoteException e) { 2359 } 2360 data2.recycle(); 2361 } 2362 } 2363 try { 2364 return super.onTransact(code, data, reply, flags); 2365 } catch (RuntimeException e) { 2366 // The activity manager only throws security exceptions, so let's 2367 // log all others. 2368 if (!(e instanceof SecurityException)) { 2369 Slog.wtf(TAG, "Activity Manager Crash", e); 2370 } 2371 throw e; 2372 } 2373 } 2374 2375 void updateCpuStats() { 2376 final long now = SystemClock.uptimeMillis(); 2377 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2378 return; 2379 } 2380 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2381 synchronized (mProcessCpuThread) { 2382 mProcessCpuThread.notify(); 2383 } 2384 } 2385 } 2386 2387 void updateCpuStatsNow() { 2388 synchronized (mProcessCpuTracker) { 2389 mProcessCpuMutexFree.set(false); 2390 final long now = SystemClock.uptimeMillis(); 2391 boolean haveNewCpuStats = false; 2392 2393 if (MONITOR_CPU_USAGE && 2394 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2395 mLastCpuTime.set(now); 2396 haveNewCpuStats = true; 2397 mProcessCpuTracker.update(); 2398 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2399 //Slog.i(TAG, "Total CPU usage: " 2400 // + mProcessCpu.getTotalCpuPercent() + "%"); 2401 2402 // Slog the cpu usage if the property is set. 2403 if ("true".equals(SystemProperties.get("events.cpu"))) { 2404 int user = mProcessCpuTracker.getLastUserTime(); 2405 int system = mProcessCpuTracker.getLastSystemTime(); 2406 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2407 int irq = mProcessCpuTracker.getLastIrqTime(); 2408 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2409 int idle = mProcessCpuTracker.getLastIdleTime(); 2410 2411 int total = user + system + iowait + irq + softIrq + idle; 2412 if (total == 0) total = 1; 2413 2414 EventLog.writeEvent(EventLogTags.CPU, 2415 ((user+system+iowait+irq+softIrq) * 100) / total, 2416 (user * 100) / total, 2417 (system * 100) / total, 2418 (iowait * 100) / total, 2419 (irq * 100) / total, 2420 (softIrq * 100) / total); 2421 } 2422 } 2423 2424 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2425 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2426 synchronized(bstats) { 2427 synchronized(mPidsSelfLocked) { 2428 if (haveNewCpuStats) { 2429 if (mOnBattery) { 2430 int perc = bstats.startAddingCpuLocked(); 2431 int totalUTime = 0; 2432 int totalSTime = 0; 2433 final int N = mProcessCpuTracker.countStats(); 2434 for (int i=0; i<N; i++) { 2435 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2436 if (!st.working) { 2437 continue; 2438 } 2439 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2440 int otherUTime = (st.rel_utime*perc)/100; 2441 int otherSTime = (st.rel_stime*perc)/100; 2442 totalUTime += otherUTime; 2443 totalSTime += otherSTime; 2444 if (pr != null) { 2445 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2446 if (ps == null || !ps.isActive()) { 2447 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2448 pr.info.uid, pr.processName); 2449 } 2450 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2451 st.rel_stime-otherSTime); 2452 ps.addSpeedStepTimes(cpuSpeedTimes); 2453 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2454 } else { 2455 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2456 if (ps == null || !ps.isActive()) { 2457 st.batteryStats = ps = bstats.getProcessStatsLocked( 2458 bstats.mapUid(st.uid), st.name); 2459 } 2460 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2461 st.rel_stime-otherSTime); 2462 ps.addSpeedStepTimes(cpuSpeedTimes); 2463 } 2464 } 2465 bstats.finishAddingCpuLocked(perc, totalUTime, 2466 totalSTime, cpuSpeedTimes); 2467 } 2468 } 2469 } 2470 2471 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2472 mLastWriteTime = now; 2473 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2474 } 2475 } 2476 } 2477 } 2478 2479 @Override 2480 public void batteryNeedsCpuUpdate() { 2481 updateCpuStatsNow(); 2482 } 2483 2484 @Override 2485 public void batteryPowerChanged(boolean onBattery) { 2486 // When plugging in, update the CPU stats first before changing 2487 // the plug state. 2488 updateCpuStatsNow(); 2489 synchronized (this) { 2490 synchronized(mPidsSelfLocked) { 2491 mOnBattery = DEBUG_POWER ? true : onBattery; 2492 } 2493 } 2494 } 2495 2496 /** 2497 * Initialize the application bind args. These are passed to each 2498 * process when the bindApplication() IPC is sent to the process. They're 2499 * lazily setup to make sure the services are running when they're asked for. 2500 */ 2501 private HashMap<String, IBinder> getCommonServicesLocked() { 2502 if (mAppBindArgs == null) { 2503 mAppBindArgs = new HashMap<String, IBinder>(); 2504 2505 // Setup the application init args 2506 mAppBindArgs.put("package", ServiceManager.getService("package")); 2507 mAppBindArgs.put("window", ServiceManager.getService("window")); 2508 mAppBindArgs.put(Context.ALARM_SERVICE, 2509 ServiceManager.getService(Context.ALARM_SERVICE)); 2510 } 2511 return mAppBindArgs; 2512 } 2513 2514 final void setFocusedActivityLocked(ActivityRecord r) { 2515 if (mFocusedActivity != r) { 2516 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2517 mFocusedActivity = r; 2518 if (r.task != null && r.task.voiceInteractor != null) { 2519 startRunningVoiceLocked(); 2520 } else { 2521 finishRunningVoiceLocked(); 2522 } 2523 mStackSupervisor.setFocusedStack(r); 2524 if (r != null) { 2525 mWindowManager.setFocusedApp(r.appToken, true); 2526 } 2527 applyUpdateLockStateLocked(r); 2528 } 2529 } 2530 2531 final void clearFocusedActivity(ActivityRecord r) { 2532 if (mFocusedActivity == r) { 2533 mFocusedActivity = null; 2534 } 2535 } 2536 2537 @Override 2538 public void setFocusedStack(int stackId) { 2539 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2540 synchronized (ActivityManagerService.this) { 2541 ActivityStack stack = mStackSupervisor.getStack(stackId); 2542 if (stack != null) { 2543 ActivityRecord r = stack.topRunningActivityLocked(null); 2544 if (r != null) { 2545 setFocusedActivityLocked(r); 2546 } 2547 } 2548 } 2549 } 2550 2551 @Override 2552 public void notifyActivityDrawn(IBinder token) { 2553 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2554 synchronized (this) { 2555 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2556 if (r != null) { 2557 r.task.stack.notifyActivityDrawnLocked(r); 2558 } 2559 } 2560 } 2561 2562 final void applyUpdateLockStateLocked(ActivityRecord r) { 2563 // Modifications to the UpdateLock state are done on our handler, outside 2564 // the activity manager's locks. The new state is determined based on the 2565 // state *now* of the relevant activity record. The object is passed to 2566 // the handler solely for logging detail, not to be consulted/modified. 2567 final boolean nextState = r != null && r.immersive; 2568 mHandler.sendMessage( 2569 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2570 } 2571 2572 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2573 Message msg = Message.obtain(); 2574 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2575 msg.obj = r.task.askedCompatMode ? null : r; 2576 mHandler.sendMessage(msg); 2577 } 2578 2579 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2580 String what, Object obj, ProcessRecord srcApp) { 2581 app.lastActivityTime = now; 2582 2583 if (app.activities.size() > 0) { 2584 // Don't want to touch dependent processes that are hosting activities. 2585 return index; 2586 } 2587 2588 int lrui = mLruProcesses.lastIndexOf(app); 2589 if (lrui < 0) { 2590 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2591 + what + " " + obj + " from " + srcApp); 2592 return index; 2593 } 2594 2595 if (lrui >= index) { 2596 // Don't want to cause this to move dependent processes *back* in the 2597 // list as if they were less frequently used. 2598 return index; 2599 } 2600 2601 if (lrui >= mLruProcessActivityStart) { 2602 // Don't want to touch dependent processes that are hosting activities. 2603 return index; 2604 } 2605 2606 mLruProcesses.remove(lrui); 2607 if (index > 0) { 2608 index--; 2609 } 2610 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2611 + " in LRU list: " + app); 2612 mLruProcesses.add(index, app); 2613 return index; 2614 } 2615 2616 final void removeLruProcessLocked(ProcessRecord app) { 2617 int lrui = mLruProcesses.lastIndexOf(app); 2618 if (lrui >= 0) { 2619 if (lrui <= mLruProcessActivityStart) { 2620 mLruProcessActivityStart--; 2621 } 2622 if (lrui <= mLruProcessServiceStart) { 2623 mLruProcessServiceStart--; 2624 } 2625 mLruProcesses.remove(lrui); 2626 } 2627 } 2628 2629 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2630 ProcessRecord client) { 2631 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2632 || app.treatLikeActivity; 2633 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2634 if (!activityChange && hasActivity) { 2635 // The process has activities, so we are only allowing activity-based adjustments 2636 // to move it. It should be kept in the front of the list with other 2637 // processes that have activities, and we don't want those to change their 2638 // order except due to activity operations. 2639 return; 2640 } 2641 2642 mLruSeq++; 2643 final long now = SystemClock.uptimeMillis(); 2644 app.lastActivityTime = now; 2645 2646 // First a quick reject: if the app is already at the position we will 2647 // put it, then there is nothing to do. 2648 if (hasActivity) { 2649 final int N = mLruProcesses.size(); 2650 if (N > 0 && mLruProcesses.get(N-1) == app) { 2651 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2652 return; 2653 } 2654 } else { 2655 if (mLruProcessServiceStart > 0 2656 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2657 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2658 return; 2659 } 2660 } 2661 2662 int lrui = mLruProcesses.lastIndexOf(app); 2663 2664 if (app.persistent && lrui >= 0) { 2665 // We don't care about the position of persistent processes, as long as 2666 // they are in the list. 2667 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2668 return; 2669 } 2670 2671 /* In progress: compute new position first, so we can avoid doing work 2672 if the process is not actually going to move. Not yet working. 2673 int addIndex; 2674 int nextIndex; 2675 boolean inActivity = false, inService = false; 2676 if (hasActivity) { 2677 // Process has activities, put it at the very tipsy-top. 2678 addIndex = mLruProcesses.size(); 2679 nextIndex = mLruProcessServiceStart; 2680 inActivity = true; 2681 } else if (hasService) { 2682 // Process has services, put it at the top of the service list. 2683 addIndex = mLruProcessActivityStart; 2684 nextIndex = mLruProcessServiceStart; 2685 inActivity = true; 2686 inService = true; 2687 } else { 2688 // Process not otherwise of interest, it goes to the top of the non-service area. 2689 addIndex = mLruProcessServiceStart; 2690 if (client != null) { 2691 int clientIndex = mLruProcesses.lastIndexOf(client); 2692 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2693 + app); 2694 if (clientIndex >= 0 && addIndex > clientIndex) { 2695 addIndex = clientIndex; 2696 } 2697 } 2698 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2699 } 2700 2701 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2702 + mLruProcessActivityStart + "): " + app); 2703 */ 2704 2705 if (lrui >= 0) { 2706 if (lrui < mLruProcessActivityStart) { 2707 mLruProcessActivityStart--; 2708 } 2709 if (lrui < mLruProcessServiceStart) { 2710 mLruProcessServiceStart--; 2711 } 2712 /* 2713 if (addIndex > lrui) { 2714 addIndex--; 2715 } 2716 if (nextIndex > lrui) { 2717 nextIndex--; 2718 } 2719 */ 2720 mLruProcesses.remove(lrui); 2721 } 2722 2723 /* 2724 mLruProcesses.add(addIndex, app); 2725 if (inActivity) { 2726 mLruProcessActivityStart++; 2727 } 2728 if (inService) { 2729 mLruProcessActivityStart++; 2730 } 2731 */ 2732 2733 int nextIndex; 2734 if (hasActivity) { 2735 final int N = mLruProcesses.size(); 2736 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2737 // Process doesn't have activities, but has clients with 2738 // activities... move it up, but one below the top (the top 2739 // should always have a real activity). 2740 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2741 mLruProcesses.add(N-1, app); 2742 // To keep it from spamming the LRU list (by making a bunch of clients), 2743 // we will push down any other entries owned by the app. 2744 final int uid = app.info.uid; 2745 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2746 ProcessRecord subProc = mLruProcesses.get(i); 2747 if (subProc.info.uid == uid) { 2748 // We want to push this one down the list. If the process after 2749 // it is for the same uid, however, don't do so, because we don't 2750 // want them internally to be re-ordered. 2751 if (mLruProcesses.get(i-1).info.uid != uid) { 2752 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2753 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2754 ProcessRecord tmp = mLruProcesses.get(i); 2755 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2756 mLruProcesses.set(i-1, tmp); 2757 i--; 2758 } 2759 } else { 2760 // A gap, we can stop here. 2761 break; 2762 } 2763 } 2764 } else { 2765 // Process has activities, put it at the very tipsy-top. 2766 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2767 mLruProcesses.add(app); 2768 } 2769 nextIndex = mLruProcessServiceStart; 2770 } else if (hasService) { 2771 // Process has services, put it at the top of the service list. 2772 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2773 mLruProcesses.add(mLruProcessActivityStart, app); 2774 nextIndex = mLruProcessServiceStart; 2775 mLruProcessActivityStart++; 2776 } else { 2777 // Process not otherwise of interest, it goes to the top of the non-service area. 2778 int index = mLruProcessServiceStart; 2779 if (client != null) { 2780 // If there is a client, don't allow the process to be moved up higher 2781 // in the list than that client. 2782 int clientIndex = mLruProcesses.lastIndexOf(client); 2783 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2784 + " when updating " + app); 2785 if (clientIndex <= lrui) { 2786 // Don't allow the client index restriction to push it down farther in the 2787 // list than it already is. 2788 clientIndex = lrui; 2789 } 2790 if (clientIndex >= 0 && index > clientIndex) { 2791 index = clientIndex; 2792 } 2793 } 2794 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2795 mLruProcesses.add(index, app); 2796 nextIndex = index-1; 2797 mLruProcessActivityStart++; 2798 mLruProcessServiceStart++; 2799 } 2800 2801 // If the app is currently using a content provider or service, 2802 // bump those processes as well. 2803 for (int j=app.connections.size()-1; j>=0; j--) { 2804 ConnectionRecord cr = app.connections.valueAt(j); 2805 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2806 && cr.binding.service.app != null 2807 && cr.binding.service.app.lruSeq != mLruSeq 2808 && !cr.binding.service.app.persistent) { 2809 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2810 "service connection", cr, app); 2811 } 2812 } 2813 for (int j=app.conProviders.size()-1; j>=0; j--) { 2814 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2815 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2816 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2817 "provider reference", cpr, app); 2818 } 2819 } 2820 } 2821 2822 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2823 if (uid == Process.SYSTEM_UID) { 2824 // The system gets to run in any process. If there are multiple 2825 // processes with the same uid, just pick the first (this 2826 // should never happen). 2827 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2828 if (procs == null) return null; 2829 final int N = procs.size(); 2830 for (int i = 0; i < N; i++) { 2831 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2832 } 2833 } 2834 ProcessRecord proc = mProcessNames.get(processName, uid); 2835 if (false && proc != null && !keepIfLarge 2836 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2837 && proc.lastCachedPss >= 4000) { 2838 // Turn this condition on to cause killing to happen regularly, for testing. 2839 if (proc.baseProcessTracker != null) { 2840 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2841 } 2842 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2843 } else if (proc != null && !keepIfLarge 2844 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2845 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2846 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2847 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2848 if (proc.baseProcessTracker != null) { 2849 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2850 } 2851 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2852 } 2853 } 2854 return proc; 2855 } 2856 2857 void ensurePackageDexOpt(String packageName) { 2858 IPackageManager pm = AppGlobals.getPackageManager(); 2859 try { 2860 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2861 mDidDexOpt = true; 2862 } 2863 } catch (RemoteException e) { 2864 } 2865 } 2866 2867 boolean isNextTransitionForward() { 2868 int transit = mWindowManager.getPendingAppTransition(); 2869 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2870 || transit == AppTransition.TRANSIT_TASK_OPEN 2871 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2872 } 2873 2874 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2875 String processName, String abiOverride, int uid, Runnable crashHandler) { 2876 synchronized(this) { 2877 ApplicationInfo info = new ApplicationInfo(); 2878 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2879 // For isolated processes, the former contains the parent's uid and the latter the 2880 // actual uid of the isolated process. 2881 // In the special case introduced by this method (which is, starting an isolated 2882 // process directly from the SystemServer without an actual parent app process) the 2883 // closest thing to a parent's uid is SYSTEM_UID. 2884 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2885 // the |isolated| logic in the ProcessRecord constructor. 2886 info.uid = Process.SYSTEM_UID; 2887 info.processName = processName; 2888 info.className = entryPoint; 2889 info.packageName = "android"; 2890 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2891 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2892 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2893 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2894 crashHandler); 2895 return proc != null ? proc.pid : 0; 2896 } 2897 } 2898 2899 final ProcessRecord startProcessLocked(String processName, 2900 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2901 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2902 boolean isolated, boolean keepIfLarge) { 2903 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2904 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2905 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2906 null /* crashHandler */); 2907 } 2908 2909 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2910 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2911 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2912 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2913 long startTime = SystemClock.elapsedRealtime(); 2914 ProcessRecord app; 2915 if (!isolated) { 2916 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2917 checkTime(startTime, "startProcess: after getProcessRecord"); 2918 } else { 2919 // If this is an isolated process, it can't re-use an existing process. 2920 app = null; 2921 } 2922 // We don't have to do anything more if: 2923 // (1) There is an existing application record; and 2924 // (2) The caller doesn't think it is dead, OR there is no thread 2925 // object attached to it so we know it couldn't have crashed; and 2926 // (3) There is a pid assigned to it, so it is either starting or 2927 // already running. 2928 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2929 + " app=" + app + " knownToBeDead=" + knownToBeDead 2930 + " thread=" + (app != null ? app.thread : null) 2931 + " pid=" + (app != null ? app.pid : -1)); 2932 if (app != null && app.pid > 0) { 2933 if (!knownToBeDead || app.thread == null) { 2934 // We already have the app running, or are waiting for it to 2935 // come up (we have a pid but not yet its thread), so keep it. 2936 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2937 // If this is a new package in the process, add the package to the list 2938 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2939 checkTime(startTime, "startProcess: done, added package to proc"); 2940 return app; 2941 } 2942 2943 // An application record is attached to a previous process, 2944 // clean it up now. 2945 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2946 checkTime(startTime, "startProcess: bad proc running, killing"); 2947 Process.killProcessGroup(app.info.uid, app.pid); 2948 handleAppDiedLocked(app, true, true); 2949 checkTime(startTime, "startProcess: done killing old proc"); 2950 } 2951 2952 String hostingNameStr = hostingName != null 2953 ? hostingName.flattenToShortString() : null; 2954 2955 if (!isolated) { 2956 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2957 // If we are in the background, then check to see if this process 2958 // is bad. If so, we will just silently fail. 2959 if (mBadProcesses.get(info.processName, info.uid) != null) { 2960 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2961 + "/" + info.processName); 2962 return null; 2963 } 2964 } else { 2965 // When the user is explicitly starting a process, then clear its 2966 // crash count so that we won't make it bad until they see at 2967 // least one crash dialog again, and make the process good again 2968 // if it had been bad. 2969 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2970 + "/" + info.processName); 2971 mProcessCrashTimes.remove(info.processName, info.uid); 2972 if (mBadProcesses.get(info.processName, info.uid) != null) { 2973 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2974 UserHandle.getUserId(info.uid), info.uid, 2975 info.processName); 2976 mBadProcesses.remove(info.processName, info.uid); 2977 if (app != null) { 2978 app.bad = false; 2979 } 2980 } 2981 } 2982 } 2983 2984 if (app == null) { 2985 checkTime(startTime, "startProcess: creating new process record"); 2986 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2987 app.crashHandler = crashHandler; 2988 if (app == null) { 2989 Slog.w(TAG, "Failed making new process record for " 2990 + processName + "/" + info.uid + " isolated=" + isolated); 2991 return null; 2992 } 2993 mProcessNames.put(processName, app.uid, app); 2994 if (isolated) { 2995 mIsolatedProcesses.put(app.uid, app); 2996 } 2997 checkTime(startTime, "startProcess: done creating new process record"); 2998 } else { 2999 // If this is a new package in the process, add the package to the list 3000 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3001 checkTime(startTime, "startProcess: added package to existing proc"); 3002 } 3003 3004 // If the system is not ready yet, then hold off on starting this 3005 // process until it is. 3006 if (!mProcessesReady 3007 && !isAllowedWhileBooting(info) 3008 && !allowWhileBooting) { 3009 if (!mProcessesOnHold.contains(app)) { 3010 mProcessesOnHold.add(app); 3011 } 3012 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3013 checkTime(startTime, "startProcess: returning with proc on hold"); 3014 return app; 3015 } 3016 3017 checkTime(startTime, "startProcess: stepping in to startProcess"); 3018 startProcessLocked( 3019 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3020 checkTime(startTime, "startProcess: done starting proc!"); 3021 return (app.pid != 0) ? app : null; 3022 } 3023 3024 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3025 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3026 } 3027 3028 private final void startProcessLocked(ProcessRecord app, 3029 String hostingType, String hostingNameStr) { 3030 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3031 null /* entryPoint */, null /* entryPointArgs */); 3032 } 3033 3034 private final void startProcessLocked(ProcessRecord app, String hostingType, 3035 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3036 long startTime = SystemClock.elapsedRealtime(); 3037 if (app.pid > 0 && app.pid != MY_PID) { 3038 checkTime(startTime, "startProcess: removing from pids map"); 3039 synchronized (mPidsSelfLocked) { 3040 mPidsSelfLocked.remove(app.pid); 3041 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3042 } 3043 checkTime(startTime, "startProcess: done removing from pids map"); 3044 app.setPid(0); 3045 } 3046 3047 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3048 "startProcessLocked removing on hold: " + app); 3049 mProcessesOnHold.remove(app); 3050 3051 checkTime(startTime, "startProcess: starting to update cpu stats"); 3052 updateCpuStats(); 3053 checkTime(startTime, "startProcess: done updating cpu stats"); 3054 3055 try { 3056 int uid = app.uid; 3057 3058 int[] gids = null; 3059 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3060 if (!app.isolated) { 3061 int[] permGids = null; 3062 try { 3063 checkTime(startTime, "startProcess: getting gids from package manager"); 3064 final PackageManager pm = mContext.getPackageManager(); 3065 permGids = pm.getPackageGids(app.info.packageName); 3066 3067 if (Environment.isExternalStorageEmulated()) { 3068 checkTime(startTime, "startProcess: checking external storage perm"); 3069 if (pm.checkPermission( 3070 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3071 app.info.packageName) == PERMISSION_GRANTED) { 3072 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3073 } else { 3074 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3075 } 3076 } 3077 } catch (PackageManager.NameNotFoundException e) { 3078 Slog.w(TAG, "Unable to retrieve gids", e); 3079 } 3080 3081 /* 3082 * Add shared application and profile GIDs so applications can share some 3083 * resources like shared libraries and access user-wide resources 3084 */ 3085 if (permGids == null) { 3086 gids = new int[2]; 3087 } else { 3088 gids = new int[permGids.length + 2]; 3089 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3090 } 3091 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3092 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3093 } 3094 checkTime(startTime, "startProcess: building args"); 3095 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3096 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3097 && mTopComponent != null 3098 && app.processName.equals(mTopComponent.getPackageName())) { 3099 uid = 0; 3100 } 3101 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3102 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3103 uid = 0; 3104 } 3105 } 3106 int debugFlags = 0; 3107 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3108 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3109 // Also turn on CheckJNI for debuggable apps. It's quite 3110 // awkward to turn on otherwise. 3111 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3112 } 3113 // Run the app in safe mode if its manifest requests so or the 3114 // system is booted in safe mode. 3115 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3116 mSafeMode == true) { 3117 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3118 } 3119 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3120 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3121 } 3122 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3123 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3124 } 3125 if ("1".equals(SystemProperties.get("debug.assert"))) { 3126 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3127 } 3128 3129 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3130 if (requiredAbi == null) { 3131 requiredAbi = Build.SUPPORTED_ABIS[0]; 3132 } 3133 3134 String instructionSet = null; 3135 if (app.info.primaryCpuAbi != null) { 3136 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3137 } 3138 3139 // Start the process. It will either succeed and return a result containing 3140 // the PID of the new process, or else throw a RuntimeException. 3141 boolean isActivityProcess = (entryPoint == null); 3142 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3143 checkTime(startTime, "startProcess: asking zygote to start proc"); 3144 Process.ProcessStartResult startResult = Process.start(entryPoint, 3145 app.processName, uid, uid, gids, debugFlags, mountExternal, 3146 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3147 entryPointArgs); 3148 checkTime(startTime, "startProcess: returned from zygote!"); 3149 3150 if (app.isolated) { 3151 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3152 } 3153 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3154 checkTime(startTime, "startProcess: done updating battery stats"); 3155 3156 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3157 UserHandle.getUserId(uid), startResult.pid, uid, 3158 app.processName, hostingType, 3159 hostingNameStr != null ? hostingNameStr : ""); 3160 3161 if (app.persistent) { 3162 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3163 } 3164 3165 checkTime(startTime, "startProcess: building log message"); 3166 StringBuilder buf = mStringBuilder; 3167 buf.setLength(0); 3168 buf.append("Start proc "); 3169 buf.append(app.processName); 3170 if (!isActivityProcess) { 3171 buf.append(" ["); 3172 buf.append(entryPoint); 3173 buf.append("]"); 3174 } 3175 buf.append(" for "); 3176 buf.append(hostingType); 3177 if (hostingNameStr != null) { 3178 buf.append(" "); 3179 buf.append(hostingNameStr); 3180 } 3181 buf.append(": pid="); 3182 buf.append(startResult.pid); 3183 buf.append(" uid="); 3184 buf.append(uid); 3185 buf.append(" gids={"); 3186 if (gids != null) { 3187 for (int gi=0; gi<gids.length; gi++) { 3188 if (gi != 0) buf.append(", "); 3189 buf.append(gids[gi]); 3190 3191 } 3192 } 3193 buf.append("}"); 3194 if (requiredAbi != null) { 3195 buf.append(" abi="); 3196 buf.append(requiredAbi); 3197 } 3198 Slog.i(TAG, buf.toString()); 3199 app.setPid(startResult.pid); 3200 app.usingWrapper = startResult.usingWrapper; 3201 app.removed = false; 3202 app.killedByAm = false; 3203 checkTime(startTime, "startProcess: starting to update pids map"); 3204 synchronized (mPidsSelfLocked) { 3205 this.mPidsSelfLocked.put(startResult.pid, app); 3206 if (isActivityProcess) { 3207 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3208 msg.obj = app; 3209 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3210 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3211 } 3212 } 3213 checkTime(startTime, "startProcess: done updating pids map"); 3214 } catch (RuntimeException e) { 3215 // XXX do better error recovery. 3216 app.setPid(0); 3217 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3218 if (app.isolated) { 3219 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3220 } 3221 Slog.e(TAG, "Failure starting process " + app.processName, e); 3222 } 3223 } 3224 3225 void updateUsageStats(ActivityRecord component, boolean resumed) { 3226 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3227 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3228 if (resumed) { 3229 if (mUsageStatsService != null) { 3230 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3231 UsageEvents.Event.MOVE_TO_FOREGROUND); 3232 } 3233 synchronized (stats) { 3234 stats.noteActivityResumedLocked(component.app.uid); 3235 } 3236 } else { 3237 if (mUsageStatsService != null) { 3238 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3239 UsageEvents.Event.MOVE_TO_BACKGROUND); 3240 } 3241 synchronized (stats) { 3242 stats.noteActivityPausedLocked(component.app.uid); 3243 } 3244 } 3245 } 3246 3247 Intent getHomeIntent() { 3248 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3249 intent.setComponent(mTopComponent); 3250 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3251 intent.addCategory(Intent.CATEGORY_HOME); 3252 } 3253 return intent; 3254 } 3255 3256 boolean startHomeActivityLocked(int userId) { 3257 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3258 && mTopAction == null) { 3259 // We are running in factory test mode, but unable to find 3260 // the factory test app, so just sit around displaying the 3261 // error message and don't try to start anything. 3262 return false; 3263 } 3264 Intent intent = getHomeIntent(); 3265 ActivityInfo aInfo = 3266 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3267 if (aInfo != null) { 3268 intent.setComponent(new ComponentName( 3269 aInfo.applicationInfo.packageName, aInfo.name)); 3270 // Don't do this if the home app is currently being 3271 // instrumented. 3272 aInfo = new ActivityInfo(aInfo); 3273 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3274 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3275 aInfo.applicationInfo.uid, true); 3276 if (app == null || app.instrumentationClass == null) { 3277 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3278 mStackSupervisor.startHomeActivity(intent, aInfo); 3279 } 3280 } 3281 3282 return true; 3283 } 3284 3285 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3286 ActivityInfo ai = null; 3287 ComponentName comp = intent.getComponent(); 3288 try { 3289 if (comp != null) { 3290 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3291 } else { 3292 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3293 intent, 3294 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3295 flags, userId); 3296 3297 if (info != null) { 3298 ai = info.activityInfo; 3299 } 3300 } 3301 } catch (RemoteException e) { 3302 // ignore 3303 } 3304 3305 return ai; 3306 } 3307 3308 /** 3309 * Starts the "new version setup screen" if appropriate. 3310 */ 3311 void startSetupActivityLocked() { 3312 // Only do this once per boot. 3313 if (mCheckedForSetup) { 3314 return; 3315 } 3316 3317 // We will show this screen if the current one is a different 3318 // version than the last one shown, and we are not running in 3319 // low-level factory test mode. 3320 final ContentResolver resolver = mContext.getContentResolver(); 3321 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3322 Settings.Global.getInt(resolver, 3323 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3324 mCheckedForSetup = true; 3325 3326 // See if we should be showing the platform update setup UI. 3327 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3328 List<ResolveInfo> ris = mContext.getPackageManager() 3329 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3330 3331 // We don't allow third party apps to replace this. 3332 ResolveInfo ri = null; 3333 for (int i=0; ris != null && i<ris.size(); i++) { 3334 if ((ris.get(i).activityInfo.applicationInfo.flags 3335 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3336 ri = ris.get(i); 3337 break; 3338 } 3339 } 3340 3341 if (ri != null) { 3342 String vers = ri.activityInfo.metaData != null 3343 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3344 : null; 3345 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3346 vers = ri.activityInfo.applicationInfo.metaData.getString( 3347 Intent.METADATA_SETUP_VERSION); 3348 } 3349 String lastVers = Settings.Secure.getString( 3350 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3351 if (vers != null && !vers.equals(lastVers)) { 3352 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3353 intent.setComponent(new ComponentName( 3354 ri.activityInfo.packageName, ri.activityInfo.name)); 3355 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3356 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null, 3357 null); 3358 } 3359 } 3360 } 3361 } 3362 3363 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3364 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3365 } 3366 3367 void enforceNotIsolatedCaller(String caller) { 3368 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3369 throw new SecurityException("Isolated process not allowed to call " + caller); 3370 } 3371 } 3372 3373 void enforceShellRestriction(String restriction, int userHandle) { 3374 if (Binder.getCallingUid() == Process.SHELL_UID) { 3375 if (userHandle < 0 3376 || mUserManager.hasUserRestriction(restriction, userHandle)) { 3377 throw new SecurityException("Shell does not have permission to access user " 3378 + userHandle); 3379 } 3380 } 3381 } 3382 3383 @Override 3384 public int getFrontActivityScreenCompatMode() { 3385 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3386 synchronized (this) { 3387 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3388 } 3389 } 3390 3391 @Override 3392 public void setFrontActivityScreenCompatMode(int mode) { 3393 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3394 "setFrontActivityScreenCompatMode"); 3395 synchronized (this) { 3396 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3397 } 3398 } 3399 3400 @Override 3401 public int getPackageScreenCompatMode(String packageName) { 3402 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3403 synchronized (this) { 3404 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3405 } 3406 } 3407 3408 @Override 3409 public void setPackageScreenCompatMode(String packageName, int mode) { 3410 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3411 "setPackageScreenCompatMode"); 3412 synchronized (this) { 3413 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3414 } 3415 } 3416 3417 @Override 3418 public boolean getPackageAskScreenCompat(String packageName) { 3419 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3420 synchronized (this) { 3421 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3422 } 3423 } 3424 3425 @Override 3426 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3427 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3428 "setPackageAskScreenCompat"); 3429 synchronized (this) { 3430 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3431 } 3432 } 3433 3434 private void dispatchProcessesChanged() { 3435 int N; 3436 synchronized (this) { 3437 N = mPendingProcessChanges.size(); 3438 if (mActiveProcessChanges.length < N) { 3439 mActiveProcessChanges = new ProcessChangeItem[N]; 3440 } 3441 mPendingProcessChanges.toArray(mActiveProcessChanges); 3442 mAvailProcessChanges.addAll(mPendingProcessChanges); 3443 mPendingProcessChanges.clear(); 3444 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3445 } 3446 3447 int i = mProcessObservers.beginBroadcast(); 3448 while (i > 0) { 3449 i--; 3450 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3451 if (observer != null) { 3452 try { 3453 for (int j=0; j<N; j++) { 3454 ProcessChangeItem item = mActiveProcessChanges[j]; 3455 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3456 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3457 + item.pid + " uid=" + item.uid + ": " 3458 + item.foregroundActivities); 3459 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3460 item.foregroundActivities); 3461 } 3462 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3463 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3464 + item.pid + " uid=" + item.uid + ": " + item.processState); 3465 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3466 } 3467 } 3468 } catch (RemoteException e) { 3469 } 3470 } 3471 } 3472 mProcessObservers.finishBroadcast(); 3473 } 3474 3475 private void dispatchProcessDied(int pid, int uid) { 3476 int i = mProcessObservers.beginBroadcast(); 3477 while (i > 0) { 3478 i--; 3479 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3480 if (observer != null) { 3481 try { 3482 observer.onProcessDied(pid, uid); 3483 } catch (RemoteException e) { 3484 } 3485 } 3486 } 3487 mProcessObservers.finishBroadcast(); 3488 } 3489 3490 @Override 3491 public final int startActivity(IApplicationThread caller, String callingPackage, 3492 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3493 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3494 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3495 resultWho, requestCode, startFlags, profilerInfo, options, 3496 UserHandle.getCallingUserId()); 3497 } 3498 3499 @Override 3500 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3501 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3502 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3503 enforceNotIsolatedCaller("startActivity"); 3504 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3505 false, ALLOW_FULL_ONLY, "startActivity", null); 3506 // TODO: Switch to user app stacks here. 3507 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3508 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3509 profilerInfo, null, null, options, userId, null, null); 3510 } 3511 3512 @Override 3513 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3514 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3515 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3516 3517 // This is very dangerous -- it allows you to perform a start activity (including 3518 // permission grants) as any app that may launch one of your own activities. So 3519 // we will only allow this to be done from activities that are part of the core framework, 3520 // and then only when they are running as the system. 3521 final ActivityRecord sourceRecord; 3522 final int targetUid; 3523 final String targetPackage; 3524 synchronized (this) { 3525 if (resultTo == null) { 3526 throw new SecurityException("Must be called from an activity"); 3527 } 3528 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3529 if (sourceRecord == null) { 3530 throw new SecurityException("Called with bad activity token: " + resultTo); 3531 } 3532 if (!sourceRecord.info.packageName.equals("android")) { 3533 throw new SecurityException( 3534 "Must be called from an activity that is declared in the android package"); 3535 } 3536 if (sourceRecord.app == null) { 3537 throw new SecurityException("Called without a process attached to activity"); 3538 } 3539 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3540 // This is still okay, as long as this activity is running under the 3541 // uid of the original calling activity. 3542 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3543 throw new SecurityException( 3544 "Calling activity in uid " + sourceRecord.app.uid 3545 + " must be system uid or original calling uid " 3546 + sourceRecord.launchedFromUid); 3547 } 3548 } 3549 targetUid = sourceRecord.launchedFromUid; 3550 targetPackage = sourceRecord.launchedFromPackage; 3551 } 3552 3553 // TODO: Switch to user app stacks here. 3554 try { 3555 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3556 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3557 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3558 return ret; 3559 } catch (SecurityException e) { 3560 // XXX need to figure out how to propagate to original app. 3561 // A SecurityException here is generally actually a fault of the original 3562 // calling activity (such as a fairly granting permissions), so propagate it 3563 // back to them. 3564 /* 3565 StringBuilder msg = new StringBuilder(); 3566 msg.append("While launching"); 3567 msg.append(intent.toString()); 3568 msg.append(": "); 3569 msg.append(e.getMessage()); 3570 */ 3571 throw e; 3572 } 3573 } 3574 3575 @Override 3576 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3577 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3578 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3579 enforceNotIsolatedCaller("startActivityAndWait"); 3580 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3581 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3582 WaitResult res = new WaitResult(); 3583 // TODO: Switch to user app stacks here. 3584 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3585 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3586 options, userId, null, null); 3587 return res; 3588 } 3589 3590 @Override 3591 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3592 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3593 int startFlags, Configuration config, Bundle options, int userId) { 3594 enforceNotIsolatedCaller("startActivityWithConfig"); 3595 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3596 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3597 // TODO: Switch to user app stacks here. 3598 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3599 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3600 null, null, config, options, userId, null, null); 3601 return ret; 3602 } 3603 3604 @Override 3605 public int startActivityIntentSender(IApplicationThread caller, 3606 IntentSender intent, Intent fillInIntent, String resolvedType, 3607 IBinder resultTo, String resultWho, int requestCode, 3608 int flagsMask, int flagsValues, Bundle options) { 3609 enforceNotIsolatedCaller("startActivityIntentSender"); 3610 // Refuse possible leaked file descriptors 3611 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3612 throw new IllegalArgumentException("File descriptors passed in Intent"); 3613 } 3614 3615 IIntentSender sender = intent.getTarget(); 3616 if (!(sender instanceof PendingIntentRecord)) { 3617 throw new IllegalArgumentException("Bad PendingIntent object"); 3618 } 3619 3620 PendingIntentRecord pir = (PendingIntentRecord)sender; 3621 3622 synchronized (this) { 3623 // If this is coming from the currently resumed activity, it is 3624 // effectively saying that app switches are allowed at this point. 3625 final ActivityStack stack = getFocusedStack(); 3626 if (stack.mResumedActivity != null && 3627 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3628 mAppSwitchesAllowedTime = 0; 3629 } 3630 } 3631 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3632 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3633 return ret; 3634 } 3635 3636 @Override 3637 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3638 Intent intent, String resolvedType, IVoiceInteractionSession session, 3639 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3640 Bundle options, int userId) { 3641 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3642 != PackageManager.PERMISSION_GRANTED) { 3643 String msg = "Permission Denial: startVoiceActivity() from pid=" 3644 + Binder.getCallingPid() 3645 + ", uid=" + Binder.getCallingUid() 3646 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3647 Slog.w(TAG, msg); 3648 throw new SecurityException(msg); 3649 } 3650 if (session == null || interactor == null) { 3651 throw new NullPointerException("null session or interactor"); 3652 } 3653 userId = handleIncomingUser(callingPid, callingUid, userId, 3654 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3655 // TODO: Switch to user app stacks here. 3656 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3657 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3658 null, options, userId, null, null); 3659 } 3660 3661 @Override 3662 public boolean startNextMatchingActivity(IBinder callingActivity, 3663 Intent intent, Bundle options) { 3664 // Refuse possible leaked file descriptors 3665 if (intent != null && intent.hasFileDescriptors() == true) { 3666 throw new IllegalArgumentException("File descriptors passed in Intent"); 3667 } 3668 3669 synchronized (this) { 3670 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3671 if (r == null) { 3672 ActivityOptions.abort(options); 3673 return false; 3674 } 3675 if (r.app == null || r.app.thread == null) { 3676 // The caller is not running... d'oh! 3677 ActivityOptions.abort(options); 3678 return false; 3679 } 3680 intent = new Intent(intent); 3681 // The caller is not allowed to change the data. 3682 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3683 // And we are resetting to find the next component... 3684 intent.setComponent(null); 3685 3686 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3687 3688 ActivityInfo aInfo = null; 3689 try { 3690 List<ResolveInfo> resolves = 3691 AppGlobals.getPackageManager().queryIntentActivities( 3692 intent, r.resolvedType, 3693 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3694 UserHandle.getCallingUserId()); 3695 3696 // Look for the original activity in the list... 3697 final int N = resolves != null ? resolves.size() : 0; 3698 for (int i=0; i<N; i++) { 3699 ResolveInfo rInfo = resolves.get(i); 3700 if (rInfo.activityInfo.packageName.equals(r.packageName) 3701 && rInfo.activityInfo.name.equals(r.info.name)) { 3702 // We found the current one... the next matching is 3703 // after it. 3704 i++; 3705 if (i<N) { 3706 aInfo = resolves.get(i).activityInfo; 3707 } 3708 if (debug) { 3709 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3710 + "/" + r.info.name); 3711 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3712 + "/" + aInfo.name); 3713 } 3714 break; 3715 } 3716 } 3717 } catch (RemoteException e) { 3718 } 3719 3720 if (aInfo == null) { 3721 // Nobody who is next! 3722 ActivityOptions.abort(options); 3723 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3724 return false; 3725 } 3726 3727 intent.setComponent(new ComponentName( 3728 aInfo.applicationInfo.packageName, aInfo.name)); 3729 intent.setFlags(intent.getFlags()&~( 3730 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3731 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3732 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3733 Intent.FLAG_ACTIVITY_NEW_TASK)); 3734 3735 // Okay now we need to start the new activity, replacing the 3736 // currently running activity. This is a little tricky because 3737 // we want to start the new one as if the current one is finished, 3738 // but not finish the current one first so that there is no flicker. 3739 // And thus... 3740 final boolean wasFinishing = r.finishing; 3741 r.finishing = true; 3742 3743 // Propagate reply information over to the new activity. 3744 final ActivityRecord resultTo = r.resultTo; 3745 final String resultWho = r.resultWho; 3746 final int requestCode = r.requestCode; 3747 r.resultTo = null; 3748 if (resultTo != null) { 3749 resultTo.removeResultsLocked(r, resultWho, requestCode); 3750 } 3751 3752 final long origId = Binder.clearCallingIdentity(); 3753 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3754 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3755 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 3756 -1, r.launchedFromUid, 0, options, false, null, null, null); 3757 Binder.restoreCallingIdentity(origId); 3758 3759 r.finishing = wasFinishing; 3760 if (res != ActivityManager.START_SUCCESS) { 3761 return false; 3762 } 3763 return true; 3764 } 3765 } 3766 3767 @Override 3768 public final int startActivityFromRecents(int taskId, Bundle options) { 3769 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3770 String msg = "Permission Denial: startActivityFromRecents called without " + 3771 START_TASKS_FROM_RECENTS; 3772 Slog.w(TAG, msg); 3773 throw new SecurityException(msg); 3774 } 3775 return startActivityFromRecentsInner(taskId, options); 3776 } 3777 3778 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3779 final TaskRecord task; 3780 final int callingUid; 3781 final String callingPackage; 3782 final Intent intent; 3783 final int userId; 3784 synchronized (this) { 3785 task = recentTaskForIdLocked(taskId); 3786 if (task == null) { 3787 throw new IllegalArgumentException("Task " + taskId + " not found."); 3788 } 3789 callingUid = task.mCallingUid; 3790 callingPackage = task.mCallingPackage; 3791 intent = task.intent; 3792 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3793 userId = task.userId; 3794 } 3795 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3796 options, userId, null, task); 3797 } 3798 3799 final int startActivityInPackage(int uid, String callingPackage, 3800 Intent intent, String resolvedType, IBinder resultTo, 3801 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3802 IActivityContainer container, TaskRecord inTask) { 3803 3804 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3805 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3806 3807 // TODO: Switch to user app stacks here. 3808 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3809 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3810 null, null, null, options, userId, container, inTask); 3811 return ret; 3812 } 3813 3814 @Override 3815 public final int startActivities(IApplicationThread caller, String callingPackage, 3816 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3817 int userId) { 3818 enforceNotIsolatedCaller("startActivities"); 3819 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3820 false, ALLOW_FULL_ONLY, "startActivity", null); 3821 // TODO: Switch to user app stacks here. 3822 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3823 resolvedTypes, resultTo, options, userId); 3824 return ret; 3825 } 3826 3827 final int startActivitiesInPackage(int uid, String callingPackage, 3828 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3829 Bundle options, int userId) { 3830 3831 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3832 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3833 // TODO: Switch to user app stacks here. 3834 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3835 resultTo, options, userId); 3836 return ret; 3837 } 3838 3839 //explicitly remove thd old information in mRecentTasks when removing existing user. 3840 private void removeRecentTasksForUserLocked(int userId) { 3841 if(userId <= 0) { 3842 Slog.i(TAG, "Can't remove recent task on user " + userId); 3843 return; 3844 } 3845 3846 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3847 TaskRecord tr = mRecentTasks.get(i); 3848 if (tr.userId == userId) { 3849 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3850 + " when finishing user" + userId); 3851 mRecentTasks.remove(i); 3852 tr.removedFromRecents(mTaskPersister); 3853 } 3854 } 3855 3856 // Remove tasks from persistent storage. 3857 mTaskPersister.wakeup(null, true); 3858 } 3859 3860 // Sort by taskId 3861 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3862 @Override 3863 public int compare(TaskRecord lhs, TaskRecord rhs) { 3864 return rhs.taskId - lhs.taskId; 3865 } 3866 }; 3867 3868 // Extract the affiliates of the chain containing mRecentTasks[start]. 3869 private int processNextAffiliateChain(int start) { 3870 final TaskRecord startTask = mRecentTasks.get(start); 3871 final int affiliateId = startTask.mAffiliatedTaskId; 3872 3873 // Quick identification of isolated tasks. I.e. those not launched behind. 3874 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3875 startTask.mNextAffiliate == null) { 3876 // There is still a slim chance that there are other tasks that point to this task 3877 // and that the chain is so messed up that this task no longer points to them but 3878 // the gain of this optimization outweighs the risk. 3879 startTask.inRecents = true; 3880 return start + 1; 3881 } 3882 3883 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3884 mTmpRecents.clear(); 3885 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3886 final TaskRecord task = mRecentTasks.get(i); 3887 if (task.mAffiliatedTaskId == affiliateId) { 3888 mRecentTasks.remove(i); 3889 mTmpRecents.add(task); 3890 } 3891 } 3892 3893 // Sort them all by taskId. That is the order they were create in and that order will 3894 // always be correct. 3895 Collections.sort(mTmpRecents, mTaskRecordComparator); 3896 3897 // Go through and fix up the linked list. 3898 // The first one is the end of the chain and has no next. 3899 final TaskRecord first = mTmpRecents.get(0); 3900 first.inRecents = true; 3901 if (first.mNextAffiliate != null) { 3902 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3903 first.setNextAffiliate(null); 3904 mTaskPersister.wakeup(first, false); 3905 } 3906 // Everything in the middle is doubly linked from next to prev. 3907 final int tmpSize = mTmpRecents.size(); 3908 for (int i = 0; i < tmpSize - 1; ++i) { 3909 final TaskRecord next = mTmpRecents.get(i); 3910 final TaskRecord prev = mTmpRecents.get(i + 1); 3911 if (next.mPrevAffiliate != prev) { 3912 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3913 " setting prev=" + prev); 3914 next.setPrevAffiliate(prev); 3915 mTaskPersister.wakeup(next, false); 3916 } 3917 if (prev.mNextAffiliate != next) { 3918 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3919 " setting next=" + next); 3920 prev.setNextAffiliate(next); 3921 mTaskPersister.wakeup(prev, false); 3922 } 3923 prev.inRecents = true; 3924 } 3925 // The last one is the beginning of the list and has no prev. 3926 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3927 if (last.mPrevAffiliate != null) { 3928 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3929 last.setPrevAffiliate(null); 3930 mTaskPersister.wakeup(last, false); 3931 } 3932 3933 // Insert the group back into mRecentTasks at start. 3934 mRecentTasks.addAll(start, mTmpRecents); 3935 3936 // Let the caller know where we left off. 3937 return start + tmpSize; 3938 } 3939 3940 /** 3941 * Update the recent tasks lists: make sure tasks should still be here (their 3942 * applications / activities still exist), update their availability, fixup ordering 3943 * of affiliations. 3944 */ 3945 void cleanupRecentTasksLocked(int userId) { 3946 if (mRecentTasks == null) { 3947 // Happens when called from the packagemanager broadcast before boot. 3948 return; 3949 } 3950 3951 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3952 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3953 final IPackageManager pm = AppGlobals.getPackageManager(); 3954 final ActivityInfo dummyAct = new ActivityInfo(); 3955 final ApplicationInfo dummyApp = new ApplicationInfo(); 3956 3957 int N = mRecentTasks.size(); 3958 3959 int[] users = userId == UserHandle.USER_ALL 3960 ? getUsersLocked() : new int[] { userId }; 3961 for (int user : users) { 3962 for (int i = 0; i < N; i++) { 3963 TaskRecord task = mRecentTasks.get(i); 3964 if (task.userId != user) { 3965 // Only look at tasks for the user ID of interest. 3966 continue; 3967 } 3968 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3969 // This situation is broken, and we should just get rid of it now. 3970 mRecentTasks.remove(i); 3971 task.removedFromRecents(mTaskPersister); 3972 i--; 3973 N--; 3974 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3975 continue; 3976 } 3977 // Check whether this activity is currently available. 3978 if (task.realActivity != null) { 3979 ActivityInfo ai = availActCache.get(task.realActivity); 3980 if (ai == null) { 3981 try { 3982 ai = pm.getActivityInfo(task.realActivity, 3983 PackageManager.GET_UNINSTALLED_PACKAGES 3984 | PackageManager.GET_DISABLED_COMPONENTS, user); 3985 } catch (RemoteException e) { 3986 // Will never happen. 3987 continue; 3988 } 3989 if (ai == null) { 3990 ai = dummyAct; 3991 } 3992 availActCache.put(task.realActivity, ai); 3993 } 3994 if (ai == dummyAct) { 3995 // This could be either because the activity no longer exists, or the 3996 // app is temporarily gone. For the former we want to remove the recents 3997 // entry; for the latter we want to mark it as unavailable. 3998 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3999 if (app == null) { 4000 try { 4001 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 4002 PackageManager.GET_UNINSTALLED_PACKAGES 4003 | PackageManager.GET_DISABLED_COMPONENTS, user); 4004 } catch (RemoteException e) { 4005 // Will never happen. 4006 continue; 4007 } 4008 if (app == null) { 4009 app = dummyApp; 4010 } 4011 availAppCache.put(task.realActivity.getPackageName(), app); 4012 } 4013 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4014 // Doesn't exist any more! Good-bye. 4015 mRecentTasks.remove(i); 4016 task.removedFromRecents(mTaskPersister); 4017 i--; 4018 N--; 4019 Slog.w(TAG, "Removing no longer valid recent: " + task); 4020 continue; 4021 } else { 4022 // Otherwise just not available for now. 4023 if (task.isAvailable) { 4024 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4025 + task); 4026 } 4027 task.isAvailable = false; 4028 } 4029 } else { 4030 if (!ai.enabled || !ai.applicationInfo.enabled 4031 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4032 if (task.isAvailable) { 4033 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4034 + task + " (enabled=" + ai.enabled + "/" 4035 + ai.applicationInfo.enabled + " flags=" 4036 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4037 } 4038 task.isAvailable = false; 4039 } else { 4040 if (!task.isAvailable) { 4041 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4042 + task); 4043 } 4044 task.isAvailable = true; 4045 } 4046 } 4047 } 4048 } 4049 } 4050 4051 // Verify the affiliate chain for each task. 4052 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4053 } 4054 4055 mTmpRecents.clear(); 4056 // mRecentTasks is now in sorted, affiliated order. 4057 } 4058 4059 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4060 int N = mRecentTasks.size(); 4061 TaskRecord top = task; 4062 int topIndex = taskIndex; 4063 while (top.mNextAffiliate != null && topIndex > 0) { 4064 top = top.mNextAffiliate; 4065 topIndex--; 4066 } 4067 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4068 + topIndex + " from intial " + taskIndex); 4069 // Find the end of the chain, doing a sanity check along the way. 4070 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4071 int endIndex = topIndex; 4072 TaskRecord prev = top; 4073 while (endIndex < N) { 4074 TaskRecord cur = mRecentTasks.get(endIndex); 4075 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4076 + endIndex + " " + cur); 4077 if (cur == top) { 4078 // Verify start of the chain. 4079 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4080 Slog.wtf(TAG, "Bad chain @" + endIndex 4081 + ": first task has next affiliate: " + prev); 4082 sane = false; 4083 break; 4084 } 4085 } else { 4086 // Verify middle of the chain's next points back to the one before. 4087 if (cur.mNextAffiliate != prev 4088 || cur.mNextAffiliateTaskId != prev.taskId) { 4089 Slog.wtf(TAG, "Bad chain @" + endIndex 4090 + ": middle task " + cur + " @" + endIndex 4091 + " has bad next affiliate " 4092 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4093 + ", expected " + prev); 4094 sane = false; 4095 break; 4096 } 4097 } 4098 if (cur.mPrevAffiliateTaskId == -1) { 4099 // Chain ends here. 4100 if (cur.mPrevAffiliate != null) { 4101 Slog.wtf(TAG, "Bad chain @" + endIndex 4102 + ": last task " + cur + " has previous affiliate " 4103 + cur.mPrevAffiliate); 4104 sane = false; 4105 } 4106 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4107 break; 4108 } else { 4109 // Verify middle of the chain's prev points to a valid item. 4110 if (cur.mPrevAffiliate == null) { 4111 Slog.wtf(TAG, "Bad chain @" + endIndex 4112 + ": task " + cur + " has previous affiliate " 4113 + cur.mPrevAffiliate + " but should be id " 4114 + cur.mPrevAffiliate); 4115 sane = false; 4116 break; 4117 } 4118 } 4119 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4120 Slog.wtf(TAG, "Bad chain @" + endIndex 4121 + ": task " + cur + " has affiliated id " 4122 + cur.mAffiliatedTaskId + " but should be " 4123 + task.mAffiliatedTaskId); 4124 sane = false; 4125 break; 4126 } 4127 prev = cur; 4128 endIndex++; 4129 if (endIndex >= N) { 4130 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4131 + ": last task " + prev); 4132 sane = false; 4133 break; 4134 } 4135 } 4136 if (sane) { 4137 if (endIndex < taskIndex) { 4138 Slog.wtf(TAG, "Bad chain @" + endIndex 4139 + ": did not extend to task " + task + " @" + taskIndex); 4140 sane = false; 4141 } 4142 } 4143 if (sane) { 4144 // All looks good, we can just move all of the affiliated tasks 4145 // to the top. 4146 for (int i=topIndex; i<=endIndex; i++) { 4147 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4148 + " from " + i + " to " + (i-topIndex)); 4149 TaskRecord cur = mRecentTasks.remove(i); 4150 mRecentTasks.add(i-topIndex, cur); 4151 } 4152 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4153 + " to " + endIndex); 4154 return true; 4155 } 4156 4157 // Whoops, couldn't do it. 4158 return false; 4159 } 4160 4161 final void addRecentTaskLocked(TaskRecord task) { 4162 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4163 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4164 4165 int N = mRecentTasks.size(); 4166 // Quick case: check if the top-most recent task is the same. 4167 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4168 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4169 return; 4170 } 4171 // Another quick case: check if this is part of a set of affiliated 4172 // tasks that are at the top. 4173 if (isAffiliated && N > 0 && task.inRecents 4174 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4175 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4176 + " at top when adding " + task); 4177 return; 4178 } 4179 // Another quick case: never add voice sessions. 4180 if (task.voiceSession != null) { 4181 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4182 return; 4183 } 4184 4185 boolean needAffiliationFix = false; 4186 4187 // Slightly less quick case: the task is already in recents, so all we need 4188 // to do is move it. 4189 if (task.inRecents) { 4190 int taskIndex = mRecentTasks.indexOf(task); 4191 if (taskIndex >= 0) { 4192 if (!isAffiliated) { 4193 // Simple case: this is not an affiliated task, so we just move it to the front. 4194 mRecentTasks.remove(taskIndex); 4195 mRecentTasks.add(0, task); 4196 notifyTaskPersisterLocked(task, false); 4197 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4198 + " from " + taskIndex); 4199 return; 4200 } else { 4201 // More complicated: need to keep all affiliated tasks together. 4202 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4203 // All went well. 4204 return; 4205 } 4206 4207 // Uh oh... something bad in the affiliation chain, try to rebuild 4208 // everything and then go through our general path of adding a new task. 4209 needAffiliationFix = true; 4210 } 4211 } else { 4212 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4213 needAffiliationFix = true; 4214 } 4215 } 4216 4217 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4218 trimRecentsForTask(task, true); 4219 4220 N = mRecentTasks.size(); 4221 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4222 final TaskRecord tr = mRecentTasks.remove(N - 1); 4223 tr.removedFromRecents(mTaskPersister); 4224 N--; 4225 } 4226 task.inRecents = true; 4227 if (!isAffiliated || needAffiliationFix) { 4228 // If this is a simple non-affiliated task, or we had some failure trying to 4229 // handle it as part of an affilated task, then just place it at the top. 4230 mRecentTasks.add(0, task); 4231 } else if (isAffiliated) { 4232 // If this is a new affiliated task, then move all of the affiliated tasks 4233 // to the front and insert this new one. 4234 TaskRecord other = task.mNextAffiliate; 4235 if (other == null) { 4236 other = task.mPrevAffiliate; 4237 } 4238 if (other != null) { 4239 int otherIndex = mRecentTasks.indexOf(other); 4240 if (otherIndex >= 0) { 4241 // Insert new task at appropriate location. 4242 int taskIndex; 4243 if (other == task.mNextAffiliate) { 4244 // We found the index of our next affiliation, which is who is 4245 // before us in the list, so add after that point. 4246 taskIndex = otherIndex+1; 4247 } else { 4248 // We found the index of our previous affiliation, which is who is 4249 // after us in the list, so add at their position. 4250 taskIndex = otherIndex; 4251 } 4252 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4253 + taskIndex + ": " + task); 4254 mRecentTasks.add(taskIndex, task); 4255 4256 // Now move everything to the front. 4257 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4258 // All went well. 4259 return; 4260 } 4261 4262 // Uh oh... something bad in the affiliation chain, try to rebuild 4263 // everything and then go through our general path of adding a new task. 4264 needAffiliationFix = true; 4265 } else { 4266 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4267 + other); 4268 needAffiliationFix = true; 4269 } 4270 } else { 4271 if (DEBUG_RECENTS) Slog.d(TAG, 4272 "addRecent: adding affiliated task without next/prev:" + task); 4273 needAffiliationFix = true; 4274 } 4275 } 4276 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4277 4278 if (needAffiliationFix) { 4279 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4280 cleanupRecentTasksLocked(task.userId); 4281 } 4282 } 4283 4284 /** 4285 * If needed, remove oldest existing entries in recents that are for the same kind 4286 * of task as the given one. 4287 */ 4288 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4289 int N = mRecentTasks.size(); 4290 final Intent intent = task.intent; 4291 final boolean document = intent != null && intent.isDocument(); 4292 4293 int maxRecents = task.maxRecents - 1; 4294 for (int i=0; i<N; i++) { 4295 final TaskRecord tr = mRecentTasks.get(i); 4296 if (task != tr) { 4297 if (task.userId != tr.userId) { 4298 continue; 4299 } 4300 if (i > MAX_RECENT_BITMAPS) { 4301 tr.freeLastThumbnail(); 4302 } 4303 final Intent trIntent = tr.intent; 4304 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4305 (intent == null || !intent.filterEquals(trIntent))) { 4306 continue; 4307 } 4308 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4309 if (document && trIsDocument) { 4310 // These are the same document activity (not necessarily the same doc). 4311 if (maxRecents > 0) { 4312 --maxRecents; 4313 continue; 4314 } 4315 // Hit the maximum number of documents for this task. Fall through 4316 // and remove this document from recents. 4317 } else if (document || trIsDocument) { 4318 // Only one of these is a document. Not the droid we're looking for. 4319 continue; 4320 } 4321 } 4322 4323 if (!doTrim) { 4324 // If the caller is not actually asking for a trim, just tell them we reached 4325 // a point where the trim would happen. 4326 return i; 4327 } 4328 4329 // Either task and tr are the same or, their affinities match or their intents match 4330 // and neither of them is a document, or they are documents using the same activity 4331 // and their maxRecents has been reached. 4332 tr.disposeThumbnail(); 4333 mRecentTasks.remove(i); 4334 if (task != tr) { 4335 tr.removedFromRecents(mTaskPersister); 4336 } 4337 i--; 4338 N--; 4339 if (task.intent == null) { 4340 // If the new recent task we are adding is not fully 4341 // specified, then replace it with the existing recent task. 4342 task = tr; 4343 } 4344 notifyTaskPersisterLocked(tr, false); 4345 } 4346 4347 return -1; 4348 } 4349 4350 @Override 4351 public void reportActivityFullyDrawn(IBinder token) { 4352 synchronized (this) { 4353 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4354 if (r == null) { 4355 return; 4356 } 4357 r.reportFullyDrawnLocked(); 4358 } 4359 } 4360 4361 @Override 4362 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4363 synchronized (this) { 4364 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4365 if (r == null) { 4366 return; 4367 } 4368 final long origId = Binder.clearCallingIdentity(); 4369 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4370 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4371 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4372 if (config != null) { 4373 r.frozenBeforeDestroy = true; 4374 if (!updateConfigurationLocked(config, r, false, false)) { 4375 mStackSupervisor.resumeTopActivitiesLocked(); 4376 } 4377 } 4378 Binder.restoreCallingIdentity(origId); 4379 } 4380 } 4381 4382 @Override 4383 public int getRequestedOrientation(IBinder token) { 4384 synchronized (this) { 4385 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4386 if (r == null) { 4387 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4388 } 4389 return mWindowManager.getAppOrientation(r.appToken); 4390 } 4391 } 4392 4393 /** 4394 * This is the internal entry point for handling Activity.finish(). 4395 * 4396 * @param token The Binder token referencing the Activity we want to finish. 4397 * @param resultCode Result code, if any, from this Activity. 4398 * @param resultData Result data (Intent), if any, from this Activity. 4399 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4400 * the root Activity in the task. 4401 * 4402 * @return Returns true if the activity successfully finished, or false if it is still running. 4403 */ 4404 @Override 4405 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4406 boolean finishTask) { 4407 // Refuse possible leaked file descriptors 4408 if (resultData != null && resultData.hasFileDescriptors() == true) { 4409 throw new IllegalArgumentException("File descriptors passed in Intent"); 4410 } 4411 4412 synchronized(this) { 4413 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4414 if (r == null) { 4415 return true; 4416 } 4417 // Keep track of the root activity of the task before we finish it 4418 TaskRecord tr = r.task; 4419 ActivityRecord rootR = tr.getRootActivity(); 4420 // Do not allow task to finish in Lock Task mode. 4421 if (tr == mStackSupervisor.mLockTaskModeTask) { 4422 if (rootR == r) { 4423 mStackSupervisor.showLockTaskToast(); 4424 return false; 4425 } 4426 } 4427 if (mController != null) { 4428 // Find the first activity that is not finishing. 4429 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4430 if (next != null) { 4431 // ask watcher if this is allowed 4432 boolean resumeOK = true; 4433 try { 4434 resumeOK = mController.activityResuming(next.packageName); 4435 } catch (RemoteException e) { 4436 mController = null; 4437 Watchdog.getInstance().setActivityController(null); 4438 } 4439 4440 if (!resumeOK) { 4441 return false; 4442 } 4443 } 4444 } 4445 final long origId = Binder.clearCallingIdentity(); 4446 try { 4447 boolean res; 4448 if (finishTask && r == rootR) { 4449 // If requested, remove the task that is associated to this activity only if it 4450 // was the root activity in the task. The result code and data is ignored because 4451 // we don't support returning them across task boundaries. 4452 res = removeTaskByIdLocked(tr.taskId, 0); 4453 } else { 4454 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4455 resultData, "app-request", true); 4456 } 4457 return res; 4458 } finally { 4459 Binder.restoreCallingIdentity(origId); 4460 } 4461 } 4462 } 4463 4464 @Override 4465 public final void finishHeavyWeightApp() { 4466 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4467 != PackageManager.PERMISSION_GRANTED) { 4468 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4469 + Binder.getCallingPid() 4470 + ", uid=" + Binder.getCallingUid() 4471 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4472 Slog.w(TAG, msg); 4473 throw new SecurityException(msg); 4474 } 4475 4476 synchronized(this) { 4477 if (mHeavyWeightProcess == null) { 4478 return; 4479 } 4480 4481 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4482 mHeavyWeightProcess.activities); 4483 for (int i=0; i<activities.size(); i++) { 4484 ActivityRecord r = activities.get(i); 4485 if (!r.finishing) { 4486 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4487 null, "finish-heavy", true); 4488 } 4489 } 4490 4491 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4492 mHeavyWeightProcess.userId, 0)); 4493 mHeavyWeightProcess = null; 4494 } 4495 } 4496 4497 @Override 4498 public void crashApplication(int uid, int initialPid, String packageName, 4499 String message) { 4500 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4501 != PackageManager.PERMISSION_GRANTED) { 4502 String msg = "Permission Denial: crashApplication() from pid=" 4503 + Binder.getCallingPid() 4504 + ", uid=" + Binder.getCallingUid() 4505 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4506 Slog.w(TAG, msg); 4507 throw new SecurityException(msg); 4508 } 4509 4510 synchronized(this) { 4511 ProcessRecord proc = null; 4512 4513 // Figure out which process to kill. We don't trust that initialPid 4514 // still has any relation to current pids, so must scan through the 4515 // list. 4516 synchronized (mPidsSelfLocked) { 4517 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4518 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4519 if (p.uid != uid) { 4520 continue; 4521 } 4522 if (p.pid == initialPid) { 4523 proc = p; 4524 break; 4525 } 4526 if (p.pkgList.containsKey(packageName)) { 4527 proc = p; 4528 } 4529 } 4530 } 4531 4532 if (proc == null) { 4533 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4534 + " initialPid=" + initialPid 4535 + " packageName=" + packageName); 4536 return; 4537 } 4538 4539 if (proc.thread != null) { 4540 if (proc.pid == Process.myPid()) { 4541 Log.w(TAG, "crashApplication: trying to crash self!"); 4542 return; 4543 } 4544 long ident = Binder.clearCallingIdentity(); 4545 try { 4546 proc.thread.scheduleCrash(message); 4547 } catch (RemoteException e) { 4548 } 4549 Binder.restoreCallingIdentity(ident); 4550 } 4551 } 4552 } 4553 4554 @Override 4555 public final void finishSubActivity(IBinder token, String resultWho, 4556 int requestCode) { 4557 synchronized(this) { 4558 final long origId = Binder.clearCallingIdentity(); 4559 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4560 if (r != null) { 4561 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4562 } 4563 Binder.restoreCallingIdentity(origId); 4564 } 4565 } 4566 4567 @Override 4568 public boolean finishActivityAffinity(IBinder token) { 4569 synchronized(this) { 4570 final long origId = Binder.clearCallingIdentity(); 4571 try { 4572 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4573 4574 ActivityRecord rootR = r.task.getRootActivity(); 4575 // Do not allow task to finish in Lock Task mode. 4576 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4577 if (rootR == r) { 4578 mStackSupervisor.showLockTaskToast(); 4579 return false; 4580 } 4581 } 4582 boolean res = false; 4583 if (r != null) { 4584 res = r.task.stack.finishActivityAffinityLocked(r); 4585 } 4586 return res; 4587 } finally { 4588 Binder.restoreCallingIdentity(origId); 4589 } 4590 } 4591 } 4592 4593 @Override 4594 public void finishVoiceTask(IVoiceInteractionSession session) { 4595 synchronized(this) { 4596 final long origId = Binder.clearCallingIdentity(); 4597 try { 4598 mStackSupervisor.finishVoiceTask(session); 4599 } finally { 4600 Binder.restoreCallingIdentity(origId); 4601 } 4602 } 4603 4604 } 4605 4606 @Override 4607 public boolean releaseActivityInstance(IBinder token) { 4608 synchronized(this) { 4609 final long origId = Binder.clearCallingIdentity(); 4610 try { 4611 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4612 if (r.task == null || r.task.stack == null) { 4613 return false; 4614 } 4615 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4616 } finally { 4617 Binder.restoreCallingIdentity(origId); 4618 } 4619 } 4620 } 4621 4622 @Override 4623 public void releaseSomeActivities(IApplicationThread appInt) { 4624 synchronized(this) { 4625 final long origId = Binder.clearCallingIdentity(); 4626 try { 4627 ProcessRecord app = getRecordForAppLocked(appInt); 4628 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4629 } finally { 4630 Binder.restoreCallingIdentity(origId); 4631 } 4632 } 4633 } 4634 4635 @Override 4636 public boolean willActivityBeVisible(IBinder token) { 4637 synchronized(this) { 4638 ActivityStack stack = ActivityRecord.getStackLocked(token); 4639 if (stack != null) { 4640 return stack.willActivityBeVisibleLocked(token); 4641 } 4642 return false; 4643 } 4644 } 4645 4646 @Override 4647 public void overridePendingTransition(IBinder token, String packageName, 4648 int enterAnim, int exitAnim) { 4649 synchronized(this) { 4650 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4651 if (self == null) { 4652 return; 4653 } 4654 4655 final long origId = Binder.clearCallingIdentity(); 4656 4657 if (self.state == ActivityState.RESUMED 4658 || self.state == ActivityState.PAUSING) { 4659 mWindowManager.overridePendingAppTransition(packageName, 4660 enterAnim, exitAnim, null); 4661 } 4662 4663 Binder.restoreCallingIdentity(origId); 4664 } 4665 } 4666 4667 /** 4668 * Main function for removing an existing process from the activity manager 4669 * as a result of that process going away. Clears out all connections 4670 * to the process. 4671 */ 4672 private final void handleAppDiedLocked(ProcessRecord app, 4673 boolean restarting, boolean allowRestart) { 4674 int pid = app.pid; 4675 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4676 if (!restarting) { 4677 removeLruProcessLocked(app); 4678 if (pid > 0) { 4679 ProcessList.remove(pid); 4680 } 4681 } 4682 4683 if (mProfileProc == app) { 4684 clearProfilerLocked(); 4685 } 4686 4687 // Remove this application's activities from active lists. 4688 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4689 4690 app.activities.clear(); 4691 4692 if (app.instrumentationClass != null) { 4693 Slog.w(TAG, "Crash of app " + app.processName 4694 + " running instrumentation " + app.instrumentationClass); 4695 Bundle info = new Bundle(); 4696 info.putString("shortMsg", "Process crashed."); 4697 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4698 } 4699 4700 if (!restarting) { 4701 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4702 // If there was nothing to resume, and we are not already 4703 // restarting this process, but there is a visible activity that 4704 // is hosted by the process... then make sure all visible 4705 // activities are running, taking care of restarting this 4706 // process. 4707 if (hasVisibleActivities) { 4708 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4709 } 4710 } 4711 } 4712 } 4713 4714 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4715 IBinder threadBinder = thread.asBinder(); 4716 // Find the application record. 4717 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4718 ProcessRecord rec = mLruProcesses.get(i); 4719 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4720 return i; 4721 } 4722 } 4723 return -1; 4724 } 4725 4726 final ProcessRecord getRecordForAppLocked( 4727 IApplicationThread thread) { 4728 if (thread == null) { 4729 return null; 4730 } 4731 4732 int appIndex = getLRURecordIndexForAppLocked(thread); 4733 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4734 } 4735 4736 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4737 // If there are no longer any background processes running, 4738 // and the app that died was not running instrumentation, 4739 // then tell everyone we are now low on memory. 4740 boolean haveBg = false; 4741 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4742 ProcessRecord rec = mLruProcesses.get(i); 4743 if (rec.thread != null 4744 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4745 haveBg = true; 4746 break; 4747 } 4748 } 4749 4750 if (!haveBg) { 4751 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4752 if (doReport) { 4753 long now = SystemClock.uptimeMillis(); 4754 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4755 doReport = false; 4756 } else { 4757 mLastMemUsageReportTime = now; 4758 } 4759 } 4760 final ArrayList<ProcessMemInfo> memInfos 4761 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4762 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4763 long now = SystemClock.uptimeMillis(); 4764 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4765 ProcessRecord rec = mLruProcesses.get(i); 4766 if (rec == dyingProc || rec.thread == null) { 4767 continue; 4768 } 4769 if (doReport) { 4770 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4771 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4772 } 4773 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4774 // The low memory report is overriding any current 4775 // state for a GC request. Make sure to do 4776 // heavy/important/visible/foreground processes first. 4777 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4778 rec.lastRequestedGc = 0; 4779 } else { 4780 rec.lastRequestedGc = rec.lastLowMemory; 4781 } 4782 rec.reportLowMemory = true; 4783 rec.lastLowMemory = now; 4784 mProcessesToGc.remove(rec); 4785 addProcessToGcListLocked(rec); 4786 } 4787 } 4788 if (doReport) { 4789 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4790 mHandler.sendMessage(msg); 4791 } 4792 scheduleAppGcsLocked(); 4793 } 4794 } 4795 4796 final void appDiedLocked(ProcessRecord app) { 4797 appDiedLocked(app, app.pid, app.thread); 4798 } 4799 4800 final void appDiedLocked(ProcessRecord app, int pid, 4801 IApplicationThread thread) { 4802 4803 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4804 synchronized (stats) { 4805 stats.noteProcessDiedLocked(app.info.uid, pid); 4806 } 4807 4808 Process.killProcessGroup(app.info.uid, pid); 4809 4810 // Clean up already done if the process has been re-started. 4811 if (app.pid == pid && app.thread != null && 4812 app.thread.asBinder() == thread.asBinder()) { 4813 boolean doLowMem = app.instrumentationClass == null; 4814 boolean doOomAdj = doLowMem; 4815 if (!app.killedByAm) { 4816 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4817 + ") has died."); 4818 mAllowLowerMemLevel = true; 4819 } else { 4820 // Note that we always want to do oom adj to update our state with the 4821 // new number of procs. 4822 mAllowLowerMemLevel = false; 4823 doLowMem = false; 4824 } 4825 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4826 if (DEBUG_CLEANUP) Slog.v( 4827 TAG, "Dying app: " + app + ", pid: " + pid 4828 + ", thread: " + thread.asBinder()); 4829 handleAppDiedLocked(app, false, true); 4830 4831 if (doOomAdj) { 4832 updateOomAdjLocked(); 4833 } 4834 if (doLowMem) { 4835 doLowMemReportIfNeededLocked(app); 4836 } 4837 } else if (app.pid != pid) { 4838 // A new process has already been started. 4839 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4840 + ") has died and restarted (pid " + app.pid + ")."); 4841 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4842 } else if (DEBUG_PROCESSES) { 4843 Slog.d(TAG, "Received spurious death notification for thread " 4844 + thread.asBinder()); 4845 } 4846 } 4847 4848 /** 4849 * If a stack trace dump file is configured, dump process stack traces. 4850 * @param clearTraces causes the dump file to be erased prior to the new 4851 * traces being written, if true; when false, the new traces will be 4852 * appended to any existing file content. 4853 * @param firstPids of dalvik VM processes to dump stack traces for first 4854 * @param lastPids of dalvik VM processes to dump stack traces for last 4855 * @param nativeProcs optional list of native process names to dump stack crawls 4856 * @return file containing stack traces, or null if no dump file is configured 4857 */ 4858 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4859 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4860 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4861 if (tracesPath == null || tracesPath.length() == 0) { 4862 return null; 4863 } 4864 4865 File tracesFile = new File(tracesPath); 4866 try { 4867 File tracesDir = tracesFile.getParentFile(); 4868 if (!tracesDir.exists()) { 4869 tracesDir.mkdirs(); 4870 if (!SELinux.restorecon(tracesDir)) { 4871 return null; 4872 } 4873 } 4874 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4875 4876 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4877 tracesFile.createNewFile(); 4878 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4879 } catch (IOException e) { 4880 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4881 return null; 4882 } 4883 4884 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4885 return tracesFile; 4886 } 4887 4888 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4889 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4890 // Use a FileObserver to detect when traces finish writing. 4891 // The order of traces is considered important to maintain for legibility. 4892 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4893 @Override 4894 public synchronized void onEvent(int event, String path) { notify(); } 4895 }; 4896 4897 try { 4898 observer.startWatching(); 4899 4900 // First collect all of the stacks of the most important pids. 4901 if (firstPids != null) { 4902 try { 4903 int num = firstPids.size(); 4904 for (int i = 0; i < num; i++) { 4905 synchronized (observer) { 4906 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4907 observer.wait(200); // Wait for write-close, give up after 200msec 4908 } 4909 } 4910 } catch (InterruptedException e) { 4911 Log.wtf(TAG, e); 4912 } 4913 } 4914 4915 // Next collect the stacks of the native pids 4916 if (nativeProcs != null) { 4917 int[] pids = Process.getPidsForCommands(nativeProcs); 4918 if (pids != null) { 4919 for (int pid : pids) { 4920 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4921 } 4922 } 4923 } 4924 4925 // Lastly, measure CPU usage. 4926 if (processCpuTracker != null) { 4927 processCpuTracker.init(); 4928 System.gc(); 4929 processCpuTracker.update(); 4930 try { 4931 synchronized (processCpuTracker) { 4932 processCpuTracker.wait(500); // measure over 1/2 second. 4933 } 4934 } catch (InterruptedException e) { 4935 } 4936 processCpuTracker.update(); 4937 4938 // We'll take the stack crawls of just the top apps using CPU. 4939 final int N = processCpuTracker.countWorkingStats(); 4940 int numProcs = 0; 4941 for (int i=0; i<N && numProcs<5; i++) { 4942 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4943 if (lastPids.indexOfKey(stats.pid) >= 0) { 4944 numProcs++; 4945 try { 4946 synchronized (observer) { 4947 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4948 observer.wait(200); // Wait for write-close, give up after 200msec 4949 } 4950 } catch (InterruptedException e) { 4951 Log.wtf(TAG, e); 4952 } 4953 4954 } 4955 } 4956 } 4957 } finally { 4958 observer.stopWatching(); 4959 } 4960 } 4961 4962 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4963 if (true || IS_USER_BUILD) { 4964 return; 4965 } 4966 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4967 if (tracesPath == null || tracesPath.length() == 0) { 4968 return; 4969 } 4970 4971 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4972 StrictMode.allowThreadDiskWrites(); 4973 try { 4974 final File tracesFile = new File(tracesPath); 4975 final File tracesDir = tracesFile.getParentFile(); 4976 final File tracesTmp = new File(tracesDir, "__tmp__"); 4977 try { 4978 if (!tracesDir.exists()) { 4979 tracesDir.mkdirs(); 4980 if (!SELinux.restorecon(tracesDir.getPath())) { 4981 return; 4982 } 4983 } 4984 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4985 4986 if (tracesFile.exists()) { 4987 tracesTmp.delete(); 4988 tracesFile.renameTo(tracesTmp); 4989 } 4990 StringBuilder sb = new StringBuilder(); 4991 Time tobj = new Time(); 4992 tobj.set(System.currentTimeMillis()); 4993 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4994 sb.append(": "); 4995 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4996 sb.append(" since "); 4997 sb.append(msg); 4998 FileOutputStream fos = new FileOutputStream(tracesFile); 4999 fos.write(sb.toString().getBytes()); 5000 if (app == null) { 5001 fos.write("\n*** No application process!".getBytes()); 5002 } 5003 fos.close(); 5004 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5005 } catch (IOException e) { 5006 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5007 return; 5008 } 5009 5010 if (app != null) { 5011 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5012 firstPids.add(app.pid); 5013 dumpStackTraces(tracesPath, firstPids, null, null, null); 5014 } 5015 5016 File lastTracesFile = null; 5017 File curTracesFile = null; 5018 for (int i=9; i>=0; i--) { 5019 String name = String.format(Locale.US, "slow%02d.txt", i); 5020 curTracesFile = new File(tracesDir, name); 5021 if (curTracesFile.exists()) { 5022 if (lastTracesFile != null) { 5023 curTracesFile.renameTo(lastTracesFile); 5024 } else { 5025 curTracesFile.delete(); 5026 } 5027 } 5028 lastTracesFile = curTracesFile; 5029 } 5030 tracesFile.renameTo(curTracesFile); 5031 if (tracesTmp.exists()) { 5032 tracesTmp.renameTo(tracesFile); 5033 } 5034 } finally { 5035 StrictMode.setThreadPolicy(oldPolicy); 5036 } 5037 } 5038 5039 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5040 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5041 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5042 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5043 5044 if (mController != null) { 5045 try { 5046 // 0 == continue, -1 = kill process immediately 5047 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5048 if (res < 0 && app.pid != MY_PID) { 5049 app.kill("anr", true); 5050 } 5051 } catch (RemoteException e) { 5052 mController = null; 5053 Watchdog.getInstance().setActivityController(null); 5054 } 5055 } 5056 5057 long anrTime = SystemClock.uptimeMillis(); 5058 if (MONITOR_CPU_USAGE) { 5059 updateCpuStatsNow(); 5060 } 5061 5062 synchronized (this) { 5063 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5064 if (mShuttingDown) { 5065 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5066 return; 5067 } else if (app.notResponding) { 5068 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5069 return; 5070 } else if (app.crashing) { 5071 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5072 return; 5073 } 5074 5075 // In case we come through here for the same app before completing 5076 // this one, mark as anring now so we will bail out. 5077 app.notResponding = true; 5078 5079 // Log the ANR to the event log. 5080 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5081 app.processName, app.info.flags, annotation); 5082 5083 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5084 firstPids.add(app.pid); 5085 5086 int parentPid = app.pid; 5087 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5088 if (parentPid != app.pid) firstPids.add(parentPid); 5089 5090 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5091 5092 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5093 ProcessRecord r = mLruProcesses.get(i); 5094 if (r != null && r.thread != null) { 5095 int pid = r.pid; 5096 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5097 if (r.persistent) { 5098 firstPids.add(pid); 5099 } else { 5100 lastPids.put(pid, Boolean.TRUE); 5101 } 5102 } 5103 } 5104 } 5105 } 5106 5107 // Log the ANR to the main log. 5108 StringBuilder info = new StringBuilder(); 5109 info.setLength(0); 5110 info.append("ANR in ").append(app.processName); 5111 if (activity != null && activity.shortComponentName != null) { 5112 info.append(" (").append(activity.shortComponentName).append(")"); 5113 } 5114 info.append("\n"); 5115 info.append("PID: ").append(app.pid).append("\n"); 5116 if (annotation != null) { 5117 info.append("Reason: ").append(annotation).append("\n"); 5118 } 5119 if (parent != null && parent != activity) { 5120 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5121 } 5122 5123 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5124 5125 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5126 NATIVE_STACKS_OF_INTEREST); 5127 5128 String cpuInfo = null; 5129 if (MONITOR_CPU_USAGE) { 5130 updateCpuStatsNow(); 5131 synchronized (mProcessCpuTracker) { 5132 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5133 } 5134 info.append(processCpuTracker.printCurrentLoad()); 5135 info.append(cpuInfo); 5136 } 5137 5138 info.append(processCpuTracker.printCurrentState(anrTime)); 5139 5140 Slog.e(TAG, info.toString()); 5141 if (tracesFile == null) { 5142 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5143 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5144 } 5145 5146 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5147 cpuInfo, tracesFile, null); 5148 5149 if (mController != null) { 5150 try { 5151 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5152 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5153 if (res != 0) { 5154 if (res < 0 && app.pid != MY_PID) { 5155 app.kill("anr", true); 5156 } else { 5157 synchronized (this) { 5158 mServices.scheduleServiceTimeoutLocked(app); 5159 } 5160 } 5161 return; 5162 } 5163 } catch (RemoteException e) { 5164 mController = null; 5165 Watchdog.getInstance().setActivityController(null); 5166 } 5167 } 5168 5169 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5170 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5171 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5172 5173 synchronized (this) { 5174 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5175 app.kill("bg anr", true); 5176 return; 5177 } 5178 5179 // Set the app's notResponding state, and look up the errorReportReceiver 5180 makeAppNotRespondingLocked(app, 5181 activity != null ? activity.shortComponentName : null, 5182 annotation != null ? "ANR " + annotation : "ANR", 5183 info.toString()); 5184 5185 // Bring up the infamous App Not Responding dialog 5186 Message msg = Message.obtain(); 5187 HashMap<String, Object> map = new HashMap<String, Object>(); 5188 msg.what = SHOW_NOT_RESPONDING_MSG; 5189 msg.obj = map; 5190 msg.arg1 = aboveSystem ? 1 : 0; 5191 map.put("app", app); 5192 if (activity != null) { 5193 map.put("activity", activity); 5194 } 5195 5196 mHandler.sendMessage(msg); 5197 } 5198 } 5199 5200 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5201 if (!mLaunchWarningShown) { 5202 mLaunchWarningShown = true; 5203 mHandler.post(new Runnable() { 5204 @Override 5205 public void run() { 5206 synchronized (ActivityManagerService.this) { 5207 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5208 d.show(); 5209 mHandler.postDelayed(new Runnable() { 5210 @Override 5211 public void run() { 5212 synchronized (ActivityManagerService.this) { 5213 d.dismiss(); 5214 mLaunchWarningShown = false; 5215 } 5216 } 5217 }, 4000); 5218 } 5219 } 5220 }); 5221 } 5222 } 5223 5224 @Override 5225 public boolean clearApplicationUserData(final String packageName, 5226 final IPackageDataObserver observer, int userId) { 5227 enforceNotIsolatedCaller("clearApplicationUserData"); 5228 int uid = Binder.getCallingUid(); 5229 int pid = Binder.getCallingPid(); 5230 userId = handleIncomingUser(pid, uid, 5231 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5232 long callingId = Binder.clearCallingIdentity(); 5233 try { 5234 IPackageManager pm = AppGlobals.getPackageManager(); 5235 int pkgUid = -1; 5236 synchronized(this) { 5237 try { 5238 pkgUid = pm.getPackageUid(packageName, userId); 5239 } catch (RemoteException e) { 5240 } 5241 if (pkgUid == -1) { 5242 Slog.w(TAG, "Invalid packageName: " + packageName); 5243 if (observer != null) { 5244 try { 5245 observer.onRemoveCompleted(packageName, false); 5246 } catch (RemoteException e) { 5247 Slog.i(TAG, "Observer no longer exists."); 5248 } 5249 } 5250 return false; 5251 } 5252 if (uid == pkgUid || checkComponentPermission( 5253 android.Manifest.permission.CLEAR_APP_USER_DATA, 5254 pid, uid, -1, true) 5255 == PackageManager.PERMISSION_GRANTED) { 5256 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5257 } else { 5258 throw new SecurityException("PID " + pid + " does not have permission " 5259 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5260 + " of package " + packageName); 5261 } 5262 5263 // Remove all tasks match the cleared application package and user 5264 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5265 final TaskRecord tr = mRecentTasks.get(i); 5266 final String taskPackageName = 5267 tr.getBaseIntent().getComponent().getPackageName(); 5268 if (tr.userId != userId) continue; 5269 if (!taskPackageName.equals(packageName)) continue; 5270 removeTaskByIdLocked(tr.taskId, 0); 5271 } 5272 } 5273 5274 try { 5275 // Clear application user data 5276 pm.clearApplicationUserData(packageName, observer, userId); 5277 5278 synchronized(this) { 5279 // Remove all permissions granted from/to this package 5280 removeUriPermissionsForPackageLocked(packageName, userId, true); 5281 } 5282 5283 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5284 Uri.fromParts("package", packageName, null)); 5285 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5286 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5287 null, null, 0, null, null, null, false, false, userId); 5288 } catch (RemoteException e) { 5289 } 5290 } finally { 5291 Binder.restoreCallingIdentity(callingId); 5292 } 5293 return true; 5294 } 5295 5296 @Override 5297 public void killBackgroundProcesses(final String packageName, int userId) { 5298 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5299 != PackageManager.PERMISSION_GRANTED && 5300 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5301 != PackageManager.PERMISSION_GRANTED) { 5302 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5303 + Binder.getCallingPid() 5304 + ", uid=" + Binder.getCallingUid() 5305 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5306 Slog.w(TAG, msg); 5307 throw new SecurityException(msg); 5308 } 5309 5310 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5311 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5312 long callingId = Binder.clearCallingIdentity(); 5313 try { 5314 IPackageManager pm = AppGlobals.getPackageManager(); 5315 synchronized(this) { 5316 int appId = -1; 5317 try { 5318 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5319 } catch (RemoteException e) { 5320 } 5321 if (appId == -1) { 5322 Slog.w(TAG, "Invalid packageName: " + packageName); 5323 return; 5324 } 5325 killPackageProcessesLocked(packageName, appId, userId, 5326 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5327 } 5328 } finally { 5329 Binder.restoreCallingIdentity(callingId); 5330 } 5331 } 5332 5333 @Override 5334 public void killAllBackgroundProcesses() { 5335 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5336 != PackageManager.PERMISSION_GRANTED) { 5337 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5338 + Binder.getCallingPid() 5339 + ", uid=" + Binder.getCallingUid() 5340 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5341 Slog.w(TAG, msg); 5342 throw new SecurityException(msg); 5343 } 5344 5345 long callingId = Binder.clearCallingIdentity(); 5346 try { 5347 synchronized(this) { 5348 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5349 final int NP = mProcessNames.getMap().size(); 5350 for (int ip=0; ip<NP; ip++) { 5351 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5352 final int NA = apps.size(); 5353 for (int ia=0; ia<NA; ia++) { 5354 ProcessRecord app = apps.valueAt(ia); 5355 if (app.persistent) { 5356 // we don't kill persistent processes 5357 continue; 5358 } 5359 if (app.removed) { 5360 procs.add(app); 5361 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5362 app.removed = true; 5363 procs.add(app); 5364 } 5365 } 5366 } 5367 5368 int N = procs.size(); 5369 for (int i=0; i<N; i++) { 5370 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5371 } 5372 mAllowLowerMemLevel = true; 5373 updateOomAdjLocked(); 5374 doLowMemReportIfNeededLocked(null); 5375 } 5376 } finally { 5377 Binder.restoreCallingIdentity(callingId); 5378 } 5379 } 5380 5381 @Override 5382 public void forceStopPackage(final String packageName, int userId) { 5383 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5384 != PackageManager.PERMISSION_GRANTED) { 5385 String msg = "Permission Denial: forceStopPackage() from pid=" 5386 + Binder.getCallingPid() 5387 + ", uid=" + Binder.getCallingUid() 5388 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5389 Slog.w(TAG, msg); 5390 throw new SecurityException(msg); 5391 } 5392 final int callingPid = Binder.getCallingPid(); 5393 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5394 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5395 long callingId = Binder.clearCallingIdentity(); 5396 try { 5397 IPackageManager pm = AppGlobals.getPackageManager(); 5398 synchronized(this) { 5399 int[] users = userId == UserHandle.USER_ALL 5400 ? getUsersLocked() : new int[] { userId }; 5401 for (int user : users) { 5402 int pkgUid = -1; 5403 try { 5404 pkgUid = pm.getPackageUid(packageName, user); 5405 } catch (RemoteException e) { 5406 } 5407 if (pkgUid == -1) { 5408 Slog.w(TAG, "Invalid packageName: " + packageName); 5409 continue; 5410 } 5411 try { 5412 pm.setPackageStoppedState(packageName, true, user); 5413 } catch (RemoteException e) { 5414 } catch (IllegalArgumentException e) { 5415 Slog.w(TAG, "Failed trying to unstop package " 5416 + packageName + ": " + e); 5417 } 5418 if (isUserRunningLocked(user, false)) { 5419 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5420 } 5421 } 5422 } 5423 } finally { 5424 Binder.restoreCallingIdentity(callingId); 5425 } 5426 } 5427 5428 @Override 5429 public void addPackageDependency(String packageName) { 5430 synchronized (this) { 5431 int callingPid = Binder.getCallingPid(); 5432 if (callingPid == Process.myPid()) { 5433 // Yeah, um, no. 5434 Slog.w(TAG, "Can't addPackageDependency on system process"); 5435 return; 5436 } 5437 ProcessRecord proc; 5438 synchronized (mPidsSelfLocked) { 5439 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5440 } 5441 if (proc != null) { 5442 if (proc.pkgDeps == null) { 5443 proc.pkgDeps = new ArraySet<String>(1); 5444 } 5445 proc.pkgDeps.add(packageName); 5446 } 5447 } 5448 } 5449 5450 /* 5451 * The pkg name and app id have to be specified. 5452 */ 5453 @Override 5454 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5455 if (pkg == null) { 5456 return; 5457 } 5458 // Make sure the uid is valid. 5459 if (appid < 0) { 5460 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5461 return; 5462 } 5463 int callerUid = Binder.getCallingUid(); 5464 // Only the system server can kill an application 5465 if (callerUid == Process.SYSTEM_UID) { 5466 // Post an aysnc message to kill the application 5467 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5468 msg.arg1 = appid; 5469 msg.arg2 = 0; 5470 Bundle bundle = new Bundle(); 5471 bundle.putString("pkg", pkg); 5472 bundle.putString("reason", reason); 5473 msg.obj = bundle; 5474 mHandler.sendMessage(msg); 5475 } else { 5476 throw new SecurityException(callerUid + " cannot kill pkg: " + 5477 pkg); 5478 } 5479 } 5480 5481 @Override 5482 public void closeSystemDialogs(String reason) { 5483 enforceNotIsolatedCaller("closeSystemDialogs"); 5484 5485 final int pid = Binder.getCallingPid(); 5486 final int uid = Binder.getCallingUid(); 5487 final long origId = Binder.clearCallingIdentity(); 5488 try { 5489 synchronized (this) { 5490 // Only allow this from foreground processes, so that background 5491 // applications can't abuse it to prevent system UI from being shown. 5492 if (uid >= Process.FIRST_APPLICATION_UID) { 5493 ProcessRecord proc; 5494 synchronized (mPidsSelfLocked) { 5495 proc = mPidsSelfLocked.get(pid); 5496 } 5497 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5498 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5499 + " from background process " + proc); 5500 return; 5501 } 5502 } 5503 closeSystemDialogsLocked(reason); 5504 } 5505 } finally { 5506 Binder.restoreCallingIdentity(origId); 5507 } 5508 } 5509 5510 void closeSystemDialogsLocked(String reason) { 5511 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5512 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5513 | Intent.FLAG_RECEIVER_FOREGROUND); 5514 if (reason != null) { 5515 intent.putExtra("reason", reason); 5516 } 5517 mWindowManager.closeSystemDialogs(reason); 5518 5519 mStackSupervisor.closeSystemDialogsLocked(); 5520 5521 broadcastIntentLocked(null, null, intent, null, 5522 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5523 Process.SYSTEM_UID, UserHandle.USER_ALL); 5524 } 5525 5526 @Override 5527 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5528 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5529 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5530 for (int i=pids.length-1; i>=0; i--) { 5531 ProcessRecord proc; 5532 int oomAdj; 5533 synchronized (this) { 5534 synchronized (mPidsSelfLocked) { 5535 proc = mPidsSelfLocked.get(pids[i]); 5536 oomAdj = proc != null ? proc.setAdj : 0; 5537 } 5538 } 5539 infos[i] = new Debug.MemoryInfo(); 5540 Debug.getMemoryInfo(pids[i], infos[i]); 5541 if (proc != null) { 5542 synchronized (this) { 5543 if (proc.thread != null && proc.setAdj == oomAdj) { 5544 // Record this for posterity if the process has been stable. 5545 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5546 infos[i].getTotalUss(), false, proc.pkgList); 5547 } 5548 } 5549 } 5550 } 5551 return infos; 5552 } 5553 5554 @Override 5555 public long[] getProcessPss(int[] pids) { 5556 enforceNotIsolatedCaller("getProcessPss"); 5557 long[] pss = new long[pids.length]; 5558 for (int i=pids.length-1; i>=0; i--) { 5559 ProcessRecord proc; 5560 int oomAdj; 5561 synchronized (this) { 5562 synchronized (mPidsSelfLocked) { 5563 proc = mPidsSelfLocked.get(pids[i]); 5564 oomAdj = proc != null ? proc.setAdj : 0; 5565 } 5566 } 5567 long[] tmpUss = new long[1]; 5568 pss[i] = Debug.getPss(pids[i], tmpUss); 5569 if (proc != null) { 5570 synchronized (this) { 5571 if (proc.thread != null && proc.setAdj == oomAdj) { 5572 // Record this for posterity if the process has been stable. 5573 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5574 } 5575 } 5576 } 5577 } 5578 return pss; 5579 } 5580 5581 @Override 5582 public void killApplicationProcess(String processName, int uid) { 5583 if (processName == null) { 5584 return; 5585 } 5586 5587 int callerUid = Binder.getCallingUid(); 5588 // Only the system server can kill an application 5589 if (callerUid == Process.SYSTEM_UID) { 5590 synchronized (this) { 5591 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5592 if (app != null && app.thread != null) { 5593 try { 5594 app.thread.scheduleSuicide(); 5595 } catch (RemoteException e) { 5596 // If the other end already died, then our work here is done. 5597 } 5598 } else { 5599 Slog.w(TAG, "Process/uid not found attempting kill of " 5600 + processName + " / " + uid); 5601 } 5602 } 5603 } else { 5604 throw new SecurityException(callerUid + " cannot kill app process: " + 5605 processName); 5606 } 5607 } 5608 5609 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5610 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5611 false, true, false, false, UserHandle.getUserId(uid), reason); 5612 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5613 Uri.fromParts("package", packageName, null)); 5614 if (!mProcessesReady) { 5615 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5616 | Intent.FLAG_RECEIVER_FOREGROUND); 5617 } 5618 intent.putExtra(Intent.EXTRA_UID, uid); 5619 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5620 broadcastIntentLocked(null, null, intent, 5621 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5622 false, false, 5623 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5624 } 5625 5626 private void forceStopUserLocked(int userId, String reason) { 5627 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5628 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5630 | Intent.FLAG_RECEIVER_FOREGROUND); 5631 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5632 broadcastIntentLocked(null, null, intent, 5633 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5634 false, false, 5635 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5636 } 5637 5638 private final boolean killPackageProcessesLocked(String packageName, int appId, 5639 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5640 boolean doit, boolean evenPersistent, String reason) { 5641 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5642 5643 // Remove all processes this package may have touched: all with the 5644 // same UID (except for the system or root user), and all whose name 5645 // matches the package name. 5646 final int NP = mProcessNames.getMap().size(); 5647 for (int ip=0; ip<NP; ip++) { 5648 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5649 final int NA = apps.size(); 5650 for (int ia=0; ia<NA; ia++) { 5651 ProcessRecord app = apps.valueAt(ia); 5652 if (app.persistent && !evenPersistent) { 5653 // we don't kill persistent processes 5654 continue; 5655 } 5656 if (app.removed) { 5657 if (doit) { 5658 procs.add(app); 5659 } 5660 continue; 5661 } 5662 5663 // Skip process if it doesn't meet our oom adj requirement. 5664 if (app.setAdj < minOomAdj) { 5665 continue; 5666 } 5667 5668 // If no package is specified, we call all processes under the 5669 // give user id. 5670 if (packageName == null) { 5671 if (app.userId != userId) { 5672 continue; 5673 } 5674 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5675 continue; 5676 } 5677 // Package has been specified, we want to hit all processes 5678 // that match it. We need to qualify this by the processes 5679 // that are running under the specified app and user ID. 5680 } else { 5681 final boolean isDep = app.pkgDeps != null 5682 && app.pkgDeps.contains(packageName); 5683 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5684 continue; 5685 } 5686 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5687 continue; 5688 } 5689 if (!app.pkgList.containsKey(packageName) && !isDep) { 5690 continue; 5691 } 5692 } 5693 5694 // Process has passed all conditions, kill it! 5695 if (!doit) { 5696 return true; 5697 } 5698 app.removed = true; 5699 procs.add(app); 5700 } 5701 } 5702 5703 int N = procs.size(); 5704 for (int i=0; i<N; i++) { 5705 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5706 } 5707 updateOomAdjLocked(); 5708 return N > 0; 5709 } 5710 5711 private final boolean forceStopPackageLocked(String name, int appId, 5712 boolean callerWillRestart, boolean purgeCache, boolean doit, 5713 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5714 int i; 5715 int N; 5716 5717 if (userId == UserHandle.USER_ALL && name == null) { 5718 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5719 } 5720 5721 if (appId < 0 && name != null) { 5722 try { 5723 appId = UserHandle.getAppId( 5724 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5725 } catch (RemoteException e) { 5726 } 5727 } 5728 5729 if (doit) { 5730 if (name != null) { 5731 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5732 + " user=" + userId + ": " + reason); 5733 } else { 5734 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5735 } 5736 5737 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5738 for (int ip=pmap.size()-1; ip>=0; ip--) { 5739 SparseArray<Long> ba = pmap.valueAt(ip); 5740 for (i=ba.size()-1; i>=0; i--) { 5741 boolean remove = false; 5742 final int entUid = ba.keyAt(i); 5743 if (name != null) { 5744 if (userId == UserHandle.USER_ALL) { 5745 if (UserHandle.getAppId(entUid) == appId) { 5746 remove = true; 5747 } 5748 } else { 5749 if (entUid == UserHandle.getUid(userId, appId)) { 5750 remove = true; 5751 } 5752 } 5753 } else if (UserHandle.getUserId(entUid) == userId) { 5754 remove = true; 5755 } 5756 if (remove) { 5757 ba.removeAt(i); 5758 } 5759 } 5760 if (ba.size() == 0) { 5761 pmap.removeAt(ip); 5762 } 5763 } 5764 } 5765 5766 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5767 -100, callerWillRestart, true, doit, evenPersistent, 5768 name == null ? ("stop user " + userId) : ("stop " + name)); 5769 5770 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5771 if (!doit) { 5772 return true; 5773 } 5774 didSomething = true; 5775 } 5776 5777 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5778 if (!doit) { 5779 return true; 5780 } 5781 didSomething = true; 5782 } 5783 5784 if (name == null) { 5785 // Remove all sticky broadcasts from this user. 5786 mStickyBroadcasts.remove(userId); 5787 } 5788 5789 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5790 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5791 userId, providers)) { 5792 if (!doit) { 5793 return true; 5794 } 5795 didSomething = true; 5796 } 5797 N = providers.size(); 5798 for (i=0; i<N; i++) { 5799 removeDyingProviderLocked(null, providers.get(i), true); 5800 } 5801 5802 // Remove transient permissions granted from/to this package/user 5803 removeUriPermissionsForPackageLocked(name, userId, false); 5804 5805 if (name == null || uninstalling) { 5806 // Remove pending intents. For now we only do this when force 5807 // stopping users, because we have some problems when doing this 5808 // for packages -- app widgets are not currently cleaned up for 5809 // such packages, so they can be left with bad pending intents. 5810 if (mIntentSenderRecords.size() > 0) { 5811 Iterator<WeakReference<PendingIntentRecord>> it 5812 = mIntentSenderRecords.values().iterator(); 5813 while (it.hasNext()) { 5814 WeakReference<PendingIntentRecord> wpir = it.next(); 5815 if (wpir == null) { 5816 it.remove(); 5817 continue; 5818 } 5819 PendingIntentRecord pir = wpir.get(); 5820 if (pir == null) { 5821 it.remove(); 5822 continue; 5823 } 5824 if (name == null) { 5825 // Stopping user, remove all objects for the user. 5826 if (pir.key.userId != userId) { 5827 // Not the same user, skip it. 5828 continue; 5829 } 5830 } else { 5831 if (UserHandle.getAppId(pir.uid) != appId) { 5832 // Different app id, skip it. 5833 continue; 5834 } 5835 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5836 // Different user, skip it. 5837 continue; 5838 } 5839 if (!pir.key.packageName.equals(name)) { 5840 // Different package, skip it. 5841 continue; 5842 } 5843 } 5844 if (!doit) { 5845 return true; 5846 } 5847 didSomething = true; 5848 it.remove(); 5849 pir.canceled = true; 5850 if (pir.key.activity != null) { 5851 pir.key.activity.pendingResults.remove(pir.ref); 5852 } 5853 } 5854 } 5855 } 5856 5857 if (doit) { 5858 if (purgeCache && name != null) { 5859 AttributeCache ac = AttributeCache.instance(); 5860 if (ac != null) { 5861 ac.removePackage(name); 5862 } 5863 } 5864 if (mBooted) { 5865 mStackSupervisor.resumeTopActivitiesLocked(); 5866 mStackSupervisor.scheduleIdleLocked(); 5867 } 5868 } 5869 5870 return didSomething; 5871 } 5872 5873 private final boolean removeProcessLocked(ProcessRecord app, 5874 boolean callerWillRestart, boolean allowRestart, String reason) { 5875 final String name = app.processName; 5876 final int uid = app.uid; 5877 if (DEBUG_PROCESSES) Slog.d( 5878 TAG, "Force removing proc " + app.toShortString() + " (" + name 5879 + "/" + uid + ")"); 5880 5881 mProcessNames.remove(name, uid); 5882 mIsolatedProcesses.remove(app.uid); 5883 if (mHeavyWeightProcess == app) { 5884 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5885 mHeavyWeightProcess.userId, 0)); 5886 mHeavyWeightProcess = null; 5887 } 5888 boolean needRestart = false; 5889 if (app.pid > 0 && app.pid != MY_PID) { 5890 int pid = app.pid; 5891 synchronized (mPidsSelfLocked) { 5892 mPidsSelfLocked.remove(pid); 5893 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5894 } 5895 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5896 if (app.isolated) { 5897 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5898 } 5899 app.kill(reason, true); 5900 handleAppDiedLocked(app, true, allowRestart); 5901 removeLruProcessLocked(app); 5902 5903 if (app.persistent && !app.isolated) { 5904 if (!callerWillRestart) { 5905 addAppLocked(app.info, false, null /* ABI override */); 5906 } else { 5907 needRestart = true; 5908 } 5909 } 5910 } else { 5911 mRemovedProcesses.add(app); 5912 } 5913 5914 return needRestart; 5915 } 5916 5917 private final void processStartTimedOutLocked(ProcessRecord app) { 5918 final int pid = app.pid; 5919 boolean gone = false; 5920 synchronized (mPidsSelfLocked) { 5921 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5922 if (knownApp != null && knownApp.thread == null) { 5923 mPidsSelfLocked.remove(pid); 5924 gone = true; 5925 } 5926 } 5927 5928 if (gone) { 5929 Slog.w(TAG, "Process " + app + " failed to attach"); 5930 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5931 pid, app.uid, app.processName); 5932 mProcessNames.remove(app.processName, app.uid); 5933 mIsolatedProcesses.remove(app.uid); 5934 if (mHeavyWeightProcess == app) { 5935 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5936 mHeavyWeightProcess.userId, 0)); 5937 mHeavyWeightProcess = null; 5938 } 5939 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5940 if (app.isolated) { 5941 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5942 } 5943 // Take care of any launching providers waiting for this process. 5944 checkAppInLaunchingProvidersLocked(app, true); 5945 // Take care of any services that are waiting for the process. 5946 mServices.processStartTimedOutLocked(app); 5947 app.kill("start timeout", true); 5948 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5949 Slog.w(TAG, "Unattached app died before backup, skipping"); 5950 try { 5951 IBackupManager bm = IBackupManager.Stub.asInterface( 5952 ServiceManager.getService(Context.BACKUP_SERVICE)); 5953 bm.agentDisconnected(app.info.packageName); 5954 } catch (RemoteException e) { 5955 // Can't happen; the backup manager is local 5956 } 5957 } 5958 if (isPendingBroadcastProcessLocked(pid)) { 5959 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5960 skipPendingBroadcastLocked(pid); 5961 } 5962 } else { 5963 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5964 } 5965 } 5966 5967 private final boolean attachApplicationLocked(IApplicationThread thread, 5968 int pid) { 5969 5970 // Find the application record that is being attached... either via 5971 // the pid if we are running in multiple processes, or just pull the 5972 // next app record if we are emulating process with anonymous threads. 5973 ProcessRecord app; 5974 if (pid != MY_PID && pid >= 0) { 5975 synchronized (mPidsSelfLocked) { 5976 app = mPidsSelfLocked.get(pid); 5977 } 5978 } else { 5979 app = null; 5980 } 5981 5982 if (app == null) { 5983 Slog.w(TAG, "No pending application record for pid " + pid 5984 + " (IApplicationThread " + thread + "); dropping process"); 5985 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5986 if (pid > 0 && pid != MY_PID) { 5987 Process.killProcessQuiet(pid); 5988 //TODO: Process.killProcessGroup(app.info.uid, pid); 5989 } else { 5990 try { 5991 thread.scheduleExit(); 5992 } catch (Exception e) { 5993 // Ignore exceptions. 5994 } 5995 } 5996 return false; 5997 } 5998 5999 // If this application record is still attached to a previous 6000 // process, clean it up now. 6001 if (app.thread != null) { 6002 handleAppDiedLocked(app, true, true); 6003 } 6004 6005 // Tell the process all about itself. 6006 6007 if (localLOGV) Slog.v( 6008 TAG, "Binding process pid " + pid + " to record " + app); 6009 6010 final String processName = app.processName; 6011 try { 6012 AppDeathRecipient adr = new AppDeathRecipient( 6013 app, pid, thread); 6014 thread.asBinder().linkToDeath(adr, 0); 6015 app.deathRecipient = adr; 6016 } catch (RemoteException e) { 6017 app.resetPackageList(mProcessStats); 6018 startProcessLocked(app, "link fail", processName); 6019 return false; 6020 } 6021 6022 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6023 6024 app.makeActive(thread, mProcessStats); 6025 app.curAdj = app.setAdj = -100; 6026 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6027 app.forcingToForeground = null; 6028 updateProcessForegroundLocked(app, false, false); 6029 app.hasShownUi = false; 6030 app.debugging = false; 6031 app.cached = false; 6032 6033 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6034 6035 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6036 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6037 6038 if (!normalMode) { 6039 Slog.i(TAG, "Launching preboot mode app: " + app); 6040 } 6041 6042 if (localLOGV) Slog.v( 6043 TAG, "New app record " + app 6044 + " thread=" + thread.asBinder() + " pid=" + pid); 6045 try { 6046 int testMode = IApplicationThread.DEBUG_OFF; 6047 if (mDebugApp != null && mDebugApp.equals(processName)) { 6048 testMode = mWaitForDebugger 6049 ? IApplicationThread.DEBUG_WAIT 6050 : IApplicationThread.DEBUG_ON; 6051 app.debugging = true; 6052 if (mDebugTransient) { 6053 mDebugApp = mOrigDebugApp; 6054 mWaitForDebugger = mOrigWaitForDebugger; 6055 } 6056 } 6057 String profileFile = app.instrumentationProfileFile; 6058 ParcelFileDescriptor profileFd = null; 6059 int samplingInterval = 0; 6060 boolean profileAutoStop = false; 6061 if (mProfileApp != null && mProfileApp.equals(processName)) { 6062 mProfileProc = app; 6063 profileFile = mProfileFile; 6064 profileFd = mProfileFd; 6065 samplingInterval = mSamplingInterval; 6066 profileAutoStop = mAutoStopProfiler; 6067 } 6068 boolean enableOpenGlTrace = false; 6069 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6070 enableOpenGlTrace = true; 6071 mOpenGlTraceApp = null; 6072 } 6073 6074 // If the app is being launched for restore or full backup, set it up specially 6075 boolean isRestrictedBackupMode = false; 6076 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6077 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6078 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6079 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6080 } 6081 6082 ensurePackageDexOpt(app.instrumentationInfo != null 6083 ? app.instrumentationInfo.packageName 6084 : app.info.packageName); 6085 if (app.instrumentationClass != null) { 6086 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6087 } 6088 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6089 + processName + " with config " + mConfiguration); 6090 ApplicationInfo appInfo = app.instrumentationInfo != null 6091 ? app.instrumentationInfo : app.info; 6092 app.compat = compatibilityInfoForPackageLocked(appInfo); 6093 if (profileFd != null) { 6094 profileFd = profileFd.dup(); 6095 } 6096 ProfilerInfo profilerInfo = profileFile == null ? null 6097 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6098 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6099 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6100 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6101 isRestrictedBackupMode || !normalMode, app.persistent, 6102 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6103 mCoreSettingsObserver.getCoreSettingsLocked()); 6104 updateLruProcessLocked(app, false, null); 6105 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6106 } catch (Exception e) { 6107 // todo: Yikes! What should we do? For now we will try to 6108 // start another process, but that could easily get us in 6109 // an infinite loop of restarting processes... 6110 Slog.w(TAG, "Exception thrown during bind!", e); 6111 6112 app.resetPackageList(mProcessStats); 6113 app.unlinkDeathRecipient(); 6114 startProcessLocked(app, "bind fail", processName); 6115 return false; 6116 } 6117 6118 // Remove this record from the list of starting applications. 6119 mPersistentStartingProcesses.remove(app); 6120 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6121 "Attach application locked removing on hold: " + app); 6122 mProcessesOnHold.remove(app); 6123 6124 boolean badApp = false; 6125 boolean didSomething = false; 6126 6127 // See if the top visible activity is waiting to run in this process... 6128 if (normalMode) { 6129 try { 6130 if (mStackSupervisor.attachApplicationLocked(app)) { 6131 didSomething = true; 6132 } 6133 } catch (Exception e) { 6134 badApp = true; 6135 } 6136 } 6137 6138 // Find any services that should be running in this process... 6139 if (!badApp) { 6140 try { 6141 didSomething |= mServices.attachApplicationLocked(app, processName); 6142 } catch (Exception e) { 6143 badApp = true; 6144 } 6145 } 6146 6147 // Check if a next-broadcast receiver is in this process... 6148 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6149 try { 6150 didSomething |= sendPendingBroadcastsLocked(app); 6151 } catch (Exception e) { 6152 // If the app died trying to launch the receiver we declare it 'bad' 6153 badApp = true; 6154 } 6155 } 6156 6157 // Check whether the next backup agent is in this process... 6158 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6159 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6160 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6161 try { 6162 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6163 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6164 mBackupTarget.backupMode); 6165 } catch (Exception e) { 6166 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6167 e.printStackTrace(); 6168 } 6169 } 6170 6171 if (badApp) { 6172 // todo: Also need to kill application to deal with all 6173 // kinds of exceptions. 6174 handleAppDiedLocked(app, false, true); 6175 return false; 6176 } 6177 6178 if (!didSomething) { 6179 updateOomAdjLocked(); 6180 } 6181 6182 return true; 6183 } 6184 6185 @Override 6186 public final void attachApplication(IApplicationThread thread) { 6187 synchronized (this) { 6188 int callingPid = Binder.getCallingPid(); 6189 final long origId = Binder.clearCallingIdentity(); 6190 attachApplicationLocked(thread, callingPid); 6191 Binder.restoreCallingIdentity(origId); 6192 } 6193 } 6194 6195 @Override 6196 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6197 final long origId = Binder.clearCallingIdentity(); 6198 synchronized (this) { 6199 ActivityStack stack = ActivityRecord.getStackLocked(token); 6200 if (stack != null) { 6201 ActivityRecord r = 6202 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6203 if (stopProfiling) { 6204 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6205 try { 6206 mProfileFd.close(); 6207 } catch (IOException e) { 6208 } 6209 clearProfilerLocked(); 6210 } 6211 } 6212 } 6213 } 6214 Binder.restoreCallingIdentity(origId); 6215 } 6216 6217 void postEnableScreenAfterBootLocked() { 6218 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6219 } 6220 6221 void enableScreenAfterBoot() { 6222 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6223 SystemClock.uptimeMillis()); 6224 mWindowManager.enableScreenAfterBoot(); 6225 6226 synchronized (this) { 6227 updateEventDispatchingLocked(); 6228 } 6229 } 6230 6231 @Override 6232 public void showBootMessage(final CharSequence msg, final boolean always) { 6233 enforceNotIsolatedCaller("showBootMessage"); 6234 mWindowManager.showBootMessage(msg, always); 6235 } 6236 6237 @Override 6238 public void keyguardWaitingForActivityDrawn() { 6239 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6240 final long token = Binder.clearCallingIdentity(); 6241 try { 6242 synchronized (this) { 6243 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6244 mWindowManager.keyguardWaitingForActivityDrawn(); 6245 if (mLockScreenShown) { 6246 mLockScreenShown = false; 6247 comeOutOfSleepIfNeededLocked(); 6248 } 6249 } 6250 } finally { 6251 Binder.restoreCallingIdentity(token); 6252 } 6253 } 6254 6255 final void finishBooting() { 6256 synchronized (this) { 6257 if (!mBootAnimationComplete) { 6258 mCallFinishBooting = true; 6259 return; 6260 } 6261 mCallFinishBooting = false; 6262 } 6263 6264 // Register receivers to handle package update events 6265 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6266 6267 // Let system services know. 6268 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6269 6270 synchronized (this) { 6271 // Ensure that any processes we had put on hold are now started 6272 // up. 6273 final int NP = mProcessesOnHold.size(); 6274 if (NP > 0) { 6275 ArrayList<ProcessRecord> procs = 6276 new ArrayList<ProcessRecord>(mProcessesOnHold); 6277 for (int ip=0; ip<NP; ip++) { 6278 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6279 + procs.get(ip)); 6280 startProcessLocked(procs.get(ip), "on-hold", null); 6281 } 6282 } 6283 6284 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6285 // Start looking for apps that are abusing wake locks. 6286 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6287 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6288 // Tell anyone interested that we are done booting! 6289 SystemProperties.set("sys.boot_completed", "1"); 6290 SystemProperties.set("dev.bootcomplete", "1"); 6291 for (int i=0; i<mStartedUsers.size(); i++) { 6292 UserStartedState uss = mStartedUsers.valueAt(i); 6293 if (uss.mState == UserStartedState.STATE_BOOTING) { 6294 uss.mState = UserStartedState.STATE_RUNNING; 6295 final int userId = mStartedUsers.keyAt(i); 6296 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6297 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6298 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6299 broadcastIntentLocked(null, null, intent, null, 6300 new IIntentReceiver.Stub() { 6301 @Override 6302 public void performReceive(Intent intent, int resultCode, 6303 String data, Bundle extras, boolean ordered, 6304 boolean sticky, int sendingUser) { 6305 synchronized (ActivityManagerService.this) { 6306 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6307 true, false); 6308 } 6309 } 6310 }, 6311 0, null, null, 6312 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6313 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6314 userId); 6315 } 6316 } 6317 scheduleStartProfilesLocked(); 6318 } 6319 } 6320 } 6321 6322 @Override 6323 public void bootAnimationComplete() { 6324 final boolean callFinishBooting; 6325 synchronized (this) { 6326 callFinishBooting = mCallFinishBooting; 6327 mBootAnimationComplete = true; 6328 } 6329 if (callFinishBooting) { 6330 finishBooting(); 6331 } 6332 } 6333 6334 final void ensureBootCompleted() { 6335 boolean booting; 6336 boolean enableScreen; 6337 synchronized (this) { 6338 booting = mBooting; 6339 mBooting = false; 6340 enableScreen = !mBooted; 6341 mBooted = true; 6342 } 6343 6344 if (booting) { 6345 finishBooting(); 6346 } 6347 6348 if (enableScreen) { 6349 enableScreenAfterBoot(); 6350 } 6351 } 6352 6353 @Override 6354 public final void activityResumed(IBinder token) { 6355 final long origId = Binder.clearCallingIdentity(); 6356 synchronized(this) { 6357 ActivityStack stack = ActivityRecord.getStackLocked(token); 6358 if (stack != null) { 6359 ActivityRecord.activityResumedLocked(token); 6360 } 6361 } 6362 Binder.restoreCallingIdentity(origId); 6363 } 6364 6365 @Override 6366 public final void activityPaused(IBinder token) { 6367 final long origId = Binder.clearCallingIdentity(); 6368 synchronized(this) { 6369 ActivityStack stack = ActivityRecord.getStackLocked(token); 6370 if (stack != null) { 6371 stack.activityPausedLocked(token, false); 6372 } 6373 } 6374 Binder.restoreCallingIdentity(origId); 6375 } 6376 6377 @Override 6378 public final void activityStopped(IBinder token, Bundle icicle, 6379 PersistableBundle persistentState, CharSequence description) { 6380 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6381 6382 // Refuse possible leaked file descriptors 6383 if (icicle != null && icicle.hasFileDescriptors()) { 6384 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6385 } 6386 6387 final long origId = Binder.clearCallingIdentity(); 6388 6389 synchronized (this) { 6390 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6391 if (r != null) { 6392 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6393 } 6394 } 6395 6396 trimApplications(); 6397 6398 Binder.restoreCallingIdentity(origId); 6399 } 6400 6401 @Override 6402 public final void activityDestroyed(IBinder token) { 6403 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6404 synchronized (this) { 6405 ActivityStack stack = ActivityRecord.getStackLocked(token); 6406 if (stack != null) { 6407 stack.activityDestroyedLocked(token); 6408 } 6409 } 6410 } 6411 6412 @Override 6413 public final void backgroundResourcesReleased(IBinder token) { 6414 final long origId = Binder.clearCallingIdentity(); 6415 try { 6416 synchronized (this) { 6417 ActivityStack stack = ActivityRecord.getStackLocked(token); 6418 if (stack != null) { 6419 stack.backgroundResourcesReleased(token); 6420 } 6421 } 6422 } finally { 6423 Binder.restoreCallingIdentity(origId); 6424 } 6425 } 6426 6427 @Override 6428 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6429 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6430 } 6431 6432 @Override 6433 public final void notifyEnterAnimationComplete(IBinder token) { 6434 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6435 } 6436 6437 @Override 6438 public String getCallingPackage(IBinder token) { 6439 synchronized (this) { 6440 ActivityRecord r = getCallingRecordLocked(token); 6441 return r != null ? r.info.packageName : null; 6442 } 6443 } 6444 6445 @Override 6446 public ComponentName getCallingActivity(IBinder token) { 6447 synchronized (this) { 6448 ActivityRecord r = getCallingRecordLocked(token); 6449 return r != null ? r.intent.getComponent() : null; 6450 } 6451 } 6452 6453 private ActivityRecord getCallingRecordLocked(IBinder token) { 6454 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6455 if (r == null) { 6456 return null; 6457 } 6458 return r.resultTo; 6459 } 6460 6461 @Override 6462 public ComponentName getActivityClassForToken(IBinder token) { 6463 synchronized(this) { 6464 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6465 if (r == null) { 6466 return null; 6467 } 6468 return r.intent.getComponent(); 6469 } 6470 } 6471 6472 @Override 6473 public String getPackageForToken(IBinder token) { 6474 synchronized(this) { 6475 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6476 if (r == null) { 6477 return null; 6478 } 6479 return r.packageName; 6480 } 6481 } 6482 6483 @Override 6484 public IIntentSender getIntentSender(int type, 6485 String packageName, IBinder token, String resultWho, 6486 int requestCode, Intent[] intents, String[] resolvedTypes, 6487 int flags, Bundle options, int userId) { 6488 enforceNotIsolatedCaller("getIntentSender"); 6489 // Refuse possible leaked file descriptors 6490 if (intents != null) { 6491 if (intents.length < 1) { 6492 throw new IllegalArgumentException("Intents array length must be >= 1"); 6493 } 6494 for (int i=0; i<intents.length; i++) { 6495 Intent intent = intents[i]; 6496 if (intent != null) { 6497 if (intent.hasFileDescriptors()) { 6498 throw new IllegalArgumentException("File descriptors passed in Intent"); 6499 } 6500 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6501 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6502 throw new IllegalArgumentException( 6503 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6504 } 6505 intents[i] = new Intent(intent); 6506 } 6507 } 6508 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6509 throw new IllegalArgumentException( 6510 "Intent array length does not match resolvedTypes length"); 6511 } 6512 } 6513 if (options != null) { 6514 if (options.hasFileDescriptors()) { 6515 throw new IllegalArgumentException("File descriptors passed in options"); 6516 } 6517 } 6518 6519 synchronized(this) { 6520 int callingUid = Binder.getCallingUid(); 6521 int origUserId = userId; 6522 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6523 type == ActivityManager.INTENT_SENDER_BROADCAST, 6524 ALLOW_NON_FULL, "getIntentSender", null); 6525 if (origUserId == UserHandle.USER_CURRENT) { 6526 // We don't want to evaluate this until the pending intent is 6527 // actually executed. However, we do want to always do the 6528 // security checking for it above. 6529 userId = UserHandle.USER_CURRENT; 6530 } 6531 try { 6532 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6533 int uid = AppGlobals.getPackageManager() 6534 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6535 if (!UserHandle.isSameApp(callingUid, uid)) { 6536 String msg = "Permission Denial: getIntentSender() from pid=" 6537 + Binder.getCallingPid() 6538 + ", uid=" + Binder.getCallingUid() 6539 + ", (need uid=" + uid + ")" 6540 + " is not allowed to send as package " + packageName; 6541 Slog.w(TAG, msg); 6542 throw new SecurityException(msg); 6543 } 6544 } 6545 6546 return getIntentSenderLocked(type, packageName, callingUid, userId, 6547 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6548 6549 } catch (RemoteException e) { 6550 throw new SecurityException(e); 6551 } 6552 } 6553 } 6554 6555 IIntentSender getIntentSenderLocked(int type, String packageName, 6556 int callingUid, int userId, IBinder token, String resultWho, 6557 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6558 Bundle options) { 6559 if (DEBUG_MU) 6560 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6561 ActivityRecord activity = null; 6562 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6563 activity = ActivityRecord.isInStackLocked(token); 6564 if (activity == null) { 6565 return null; 6566 } 6567 if (activity.finishing) { 6568 return null; 6569 } 6570 } 6571 6572 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6573 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6574 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6575 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6576 |PendingIntent.FLAG_UPDATE_CURRENT); 6577 6578 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6579 type, packageName, activity, resultWho, 6580 requestCode, intents, resolvedTypes, flags, options, userId); 6581 WeakReference<PendingIntentRecord> ref; 6582 ref = mIntentSenderRecords.get(key); 6583 PendingIntentRecord rec = ref != null ? ref.get() : null; 6584 if (rec != null) { 6585 if (!cancelCurrent) { 6586 if (updateCurrent) { 6587 if (rec.key.requestIntent != null) { 6588 rec.key.requestIntent.replaceExtras(intents != null ? 6589 intents[intents.length - 1] : null); 6590 } 6591 if (intents != null) { 6592 intents[intents.length-1] = rec.key.requestIntent; 6593 rec.key.allIntents = intents; 6594 rec.key.allResolvedTypes = resolvedTypes; 6595 } else { 6596 rec.key.allIntents = null; 6597 rec.key.allResolvedTypes = null; 6598 } 6599 } 6600 return rec; 6601 } 6602 rec.canceled = true; 6603 mIntentSenderRecords.remove(key); 6604 } 6605 if (noCreate) { 6606 return rec; 6607 } 6608 rec = new PendingIntentRecord(this, key, callingUid); 6609 mIntentSenderRecords.put(key, rec.ref); 6610 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6611 if (activity.pendingResults == null) { 6612 activity.pendingResults 6613 = new HashSet<WeakReference<PendingIntentRecord>>(); 6614 } 6615 activity.pendingResults.add(rec.ref); 6616 } 6617 return rec; 6618 } 6619 6620 @Override 6621 public void cancelIntentSender(IIntentSender sender) { 6622 if (!(sender instanceof PendingIntentRecord)) { 6623 return; 6624 } 6625 synchronized(this) { 6626 PendingIntentRecord rec = (PendingIntentRecord)sender; 6627 try { 6628 int uid = AppGlobals.getPackageManager() 6629 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6630 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6631 String msg = "Permission Denial: cancelIntentSender() from pid=" 6632 + Binder.getCallingPid() 6633 + ", uid=" + Binder.getCallingUid() 6634 + " is not allowed to cancel packges " 6635 + rec.key.packageName; 6636 Slog.w(TAG, msg); 6637 throw new SecurityException(msg); 6638 } 6639 } catch (RemoteException e) { 6640 throw new SecurityException(e); 6641 } 6642 cancelIntentSenderLocked(rec, true); 6643 } 6644 } 6645 6646 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6647 rec.canceled = true; 6648 mIntentSenderRecords.remove(rec.key); 6649 if (cleanActivity && rec.key.activity != null) { 6650 rec.key.activity.pendingResults.remove(rec.ref); 6651 } 6652 } 6653 6654 @Override 6655 public String getPackageForIntentSender(IIntentSender pendingResult) { 6656 if (!(pendingResult instanceof PendingIntentRecord)) { 6657 return null; 6658 } 6659 try { 6660 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6661 return res.key.packageName; 6662 } catch (ClassCastException e) { 6663 } 6664 return null; 6665 } 6666 6667 @Override 6668 public int getUidForIntentSender(IIntentSender sender) { 6669 if (sender instanceof PendingIntentRecord) { 6670 try { 6671 PendingIntentRecord res = (PendingIntentRecord)sender; 6672 return res.uid; 6673 } catch (ClassCastException e) { 6674 } 6675 } 6676 return -1; 6677 } 6678 6679 @Override 6680 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6681 if (!(pendingResult instanceof PendingIntentRecord)) { 6682 return false; 6683 } 6684 try { 6685 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6686 if (res.key.allIntents == null) { 6687 return false; 6688 } 6689 for (int i=0; i<res.key.allIntents.length; i++) { 6690 Intent intent = res.key.allIntents[i]; 6691 if (intent.getPackage() != null && intent.getComponent() != null) { 6692 return false; 6693 } 6694 } 6695 return true; 6696 } catch (ClassCastException e) { 6697 } 6698 return false; 6699 } 6700 6701 @Override 6702 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6703 if (!(pendingResult instanceof PendingIntentRecord)) { 6704 return false; 6705 } 6706 try { 6707 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6708 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6709 return true; 6710 } 6711 return false; 6712 } catch (ClassCastException e) { 6713 } 6714 return false; 6715 } 6716 6717 @Override 6718 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6719 if (!(pendingResult instanceof PendingIntentRecord)) { 6720 return null; 6721 } 6722 try { 6723 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6724 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6725 } catch (ClassCastException e) { 6726 } 6727 return null; 6728 } 6729 6730 @Override 6731 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6732 if (!(pendingResult instanceof PendingIntentRecord)) { 6733 return null; 6734 } 6735 try { 6736 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6737 Intent intent = res.key.requestIntent; 6738 if (intent != null) { 6739 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6740 || res.lastTagPrefix.equals(prefix))) { 6741 return res.lastTag; 6742 } 6743 res.lastTagPrefix = prefix; 6744 StringBuilder sb = new StringBuilder(128); 6745 if (prefix != null) { 6746 sb.append(prefix); 6747 } 6748 if (intent.getAction() != null) { 6749 sb.append(intent.getAction()); 6750 } else if (intent.getComponent() != null) { 6751 intent.getComponent().appendShortString(sb); 6752 } else { 6753 sb.append("?"); 6754 } 6755 return res.lastTag = sb.toString(); 6756 } 6757 } catch (ClassCastException e) { 6758 } 6759 return null; 6760 } 6761 6762 @Override 6763 public void setProcessLimit(int max) { 6764 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6765 "setProcessLimit()"); 6766 synchronized (this) { 6767 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6768 mProcessLimitOverride = max; 6769 } 6770 trimApplications(); 6771 } 6772 6773 @Override 6774 public int getProcessLimit() { 6775 synchronized (this) { 6776 return mProcessLimitOverride; 6777 } 6778 } 6779 6780 void foregroundTokenDied(ForegroundToken token) { 6781 synchronized (ActivityManagerService.this) { 6782 synchronized (mPidsSelfLocked) { 6783 ForegroundToken cur 6784 = mForegroundProcesses.get(token.pid); 6785 if (cur != token) { 6786 return; 6787 } 6788 mForegroundProcesses.remove(token.pid); 6789 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6790 if (pr == null) { 6791 return; 6792 } 6793 pr.forcingToForeground = null; 6794 updateProcessForegroundLocked(pr, false, false); 6795 } 6796 updateOomAdjLocked(); 6797 } 6798 } 6799 6800 @Override 6801 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6802 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6803 "setProcessForeground()"); 6804 synchronized(this) { 6805 boolean changed = false; 6806 6807 synchronized (mPidsSelfLocked) { 6808 ProcessRecord pr = mPidsSelfLocked.get(pid); 6809 if (pr == null && isForeground) { 6810 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6811 return; 6812 } 6813 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6814 if (oldToken != null) { 6815 oldToken.token.unlinkToDeath(oldToken, 0); 6816 mForegroundProcesses.remove(pid); 6817 if (pr != null) { 6818 pr.forcingToForeground = null; 6819 } 6820 changed = true; 6821 } 6822 if (isForeground && token != null) { 6823 ForegroundToken newToken = new ForegroundToken() { 6824 @Override 6825 public void binderDied() { 6826 foregroundTokenDied(this); 6827 } 6828 }; 6829 newToken.pid = pid; 6830 newToken.token = token; 6831 try { 6832 token.linkToDeath(newToken, 0); 6833 mForegroundProcesses.put(pid, newToken); 6834 pr.forcingToForeground = token; 6835 changed = true; 6836 } catch (RemoteException e) { 6837 // If the process died while doing this, we will later 6838 // do the cleanup with the process death link. 6839 } 6840 } 6841 } 6842 6843 if (changed) { 6844 updateOomAdjLocked(); 6845 } 6846 } 6847 } 6848 6849 // ========================================================= 6850 // PERMISSIONS 6851 // ========================================================= 6852 6853 static class PermissionController extends IPermissionController.Stub { 6854 ActivityManagerService mActivityManagerService; 6855 PermissionController(ActivityManagerService activityManagerService) { 6856 mActivityManagerService = activityManagerService; 6857 } 6858 6859 @Override 6860 public boolean checkPermission(String permission, int pid, int uid) { 6861 return mActivityManagerService.checkPermission(permission, pid, 6862 uid) == PackageManager.PERMISSION_GRANTED; 6863 } 6864 } 6865 6866 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6867 @Override 6868 public int checkComponentPermission(String permission, int pid, int uid, 6869 int owningUid, boolean exported) { 6870 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6871 owningUid, exported); 6872 } 6873 6874 @Override 6875 public Object getAMSLock() { 6876 return ActivityManagerService.this; 6877 } 6878 } 6879 6880 /** 6881 * This can be called with or without the global lock held. 6882 */ 6883 int checkComponentPermission(String permission, int pid, int uid, 6884 int owningUid, boolean exported) { 6885 // We might be performing an operation on behalf of an indirect binder 6886 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6887 // client identity accordingly before proceeding. 6888 Identity tlsIdentity = sCallerIdentity.get(); 6889 if (tlsIdentity != null) { 6890 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6891 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6892 uid = tlsIdentity.uid; 6893 pid = tlsIdentity.pid; 6894 } 6895 6896 if (pid == MY_PID) { 6897 return PackageManager.PERMISSION_GRANTED; 6898 } 6899 6900 return ActivityManager.checkComponentPermission(permission, uid, 6901 owningUid, exported); 6902 } 6903 6904 /** 6905 * As the only public entry point for permissions checking, this method 6906 * can enforce the semantic that requesting a check on a null global 6907 * permission is automatically denied. (Internally a null permission 6908 * string is used when calling {@link #checkComponentPermission} in cases 6909 * when only uid-based security is needed.) 6910 * 6911 * This can be called with or without the global lock held. 6912 */ 6913 @Override 6914 public int checkPermission(String permission, int pid, int uid) { 6915 if (permission == null) { 6916 return PackageManager.PERMISSION_DENIED; 6917 } 6918 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6919 } 6920 6921 /** 6922 * Binder IPC calls go through the public entry point. 6923 * This can be called with or without the global lock held. 6924 */ 6925 int checkCallingPermission(String permission) { 6926 return checkPermission(permission, 6927 Binder.getCallingPid(), 6928 UserHandle.getAppId(Binder.getCallingUid())); 6929 } 6930 6931 /** 6932 * This can be called with or without the global lock held. 6933 */ 6934 void enforceCallingPermission(String permission, String func) { 6935 if (checkCallingPermission(permission) 6936 == PackageManager.PERMISSION_GRANTED) { 6937 return; 6938 } 6939 6940 String msg = "Permission Denial: " + func + " from pid=" 6941 + Binder.getCallingPid() 6942 + ", uid=" + Binder.getCallingUid() 6943 + " requires " + permission; 6944 Slog.w(TAG, msg); 6945 throw new SecurityException(msg); 6946 } 6947 6948 /** 6949 * Determine if UID is holding permissions required to access {@link Uri} in 6950 * the given {@link ProviderInfo}. Final permission checking is always done 6951 * in {@link ContentProvider}. 6952 */ 6953 private final boolean checkHoldingPermissionsLocked( 6954 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6955 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6956 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6957 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6958 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6959 != PERMISSION_GRANTED) { 6960 return false; 6961 } 6962 } 6963 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6964 } 6965 6966 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6967 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6968 if (pi.applicationInfo.uid == uid) { 6969 return true; 6970 } else if (!pi.exported) { 6971 return false; 6972 } 6973 6974 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6975 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6976 try { 6977 // check if target holds top-level <provider> permissions 6978 if (!readMet && pi.readPermission != null && considerUidPermissions 6979 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6980 readMet = true; 6981 } 6982 if (!writeMet && pi.writePermission != null && considerUidPermissions 6983 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6984 writeMet = true; 6985 } 6986 6987 // track if unprotected read/write is allowed; any denied 6988 // <path-permission> below removes this ability 6989 boolean allowDefaultRead = pi.readPermission == null; 6990 boolean allowDefaultWrite = pi.writePermission == null; 6991 6992 // check if target holds any <path-permission> that match uri 6993 final PathPermission[] pps = pi.pathPermissions; 6994 if (pps != null) { 6995 final String path = grantUri.uri.getPath(); 6996 int i = pps.length; 6997 while (i > 0 && (!readMet || !writeMet)) { 6998 i--; 6999 PathPermission pp = pps[i]; 7000 if (pp.match(path)) { 7001 if (!readMet) { 7002 final String pprperm = pp.getReadPermission(); 7003 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 7004 + pprperm + " for " + pp.getPath() 7005 + ": match=" + pp.match(path) 7006 + " check=" + pm.checkUidPermission(pprperm, uid)); 7007 if (pprperm != null) { 7008 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 7009 == PERMISSION_GRANTED) { 7010 readMet = true; 7011 } else { 7012 allowDefaultRead = false; 7013 } 7014 } 7015 } 7016 if (!writeMet) { 7017 final String ppwperm = pp.getWritePermission(); 7018 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 7019 + ppwperm + " for " + pp.getPath() 7020 + ": match=" + pp.match(path) 7021 + " check=" + pm.checkUidPermission(ppwperm, uid)); 7022 if (ppwperm != null) { 7023 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 7024 == PERMISSION_GRANTED) { 7025 writeMet = true; 7026 } else { 7027 allowDefaultWrite = false; 7028 } 7029 } 7030 } 7031 } 7032 } 7033 } 7034 7035 // grant unprotected <provider> read/write, if not blocked by 7036 // <path-permission> above 7037 if (allowDefaultRead) readMet = true; 7038 if (allowDefaultWrite) writeMet = true; 7039 7040 } catch (RemoteException e) { 7041 return false; 7042 } 7043 7044 return readMet && writeMet; 7045 } 7046 7047 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7048 ProviderInfo pi = null; 7049 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7050 if (cpr != null) { 7051 pi = cpr.info; 7052 } else { 7053 try { 7054 pi = AppGlobals.getPackageManager().resolveContentProvider( 7055 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7056 } catch (RemoteException ex) { 7057 } 7058 } 7059 return pi; 7060 } 7061 7062 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7063 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7064 if (targetUris != null) { 7065 return targetUris.get(grantUri); 7066 } 7067 return null; 7068 } 7069 7070 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7071 String targetPkg, int targetUid, GrantUri grantUri) { 7072 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7073 if (targetUris == null) { 7074 targetUris = Maps.newArrayMap(); 7075 mGrantedUriPermissions.put(targetUid, targetUris); 7076 } 7077 7078 UriPermission perm = targetUris.get(grantUri); 7079 if (perm == null) { 7080 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7081 targetUris.put(grantUri, perm); 7082 } 7083 7084 return perm; 7085 } 7086 7087 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7088 final int modeFlags) { 7089 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7090 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7091 : UriPermission.STRENGTH_OWNED; 7092 7093 // Root gets to do everything. 7094 if (uid == 0) { 7095 return true; 7096 } 7097 7098 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7099 if (perms == null) return false; 7100 7101 // First look for exact match 7102 final UriPermission exactPerm = perms.get(grantUri); 7103 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7104 return true; 7105 } 7106 7107 // No exact match, look for prefixes 7108 final int N = perms.size(); 7109 for (int i = 0; i < N; i++) { 7110 final UriPermission perm = perms.valueAt(i); 7111 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7112 && perm.getStrength(modeFlags) >= minStrength) { 7113 return true; 7114 } 7115 } 7116 7117 return false; 7118 } 7119 7120 /** 7121 * @param uri This uri must NOT contain an embedded userId. 7122 * @param userId The userId in which the uri is to be resolved. 7123 */ 7124 @Override 7125 public int checkUriPermission(Uri uri, int pid, int uid, 7126 final int modeFlags, int userId) { 7127 enforceNotIsolatedCaller("checkUriPermission"); 7128 7129 // Another redirected-binder-call permissions check as in 7130 // {@link checkComponentPermission}. 7131 Identity tlsIdentity = sCallerIdentity.get(); 7132 if (tlsIdentity != null) { 7133 uid = tlsIdentity.uid; 7134 pid = tlsIdentity.pid; 7135 } 7136 7137 // Our own process gets to do everything. 7138 if (pid == MY_PID) { 7139 return PackageManager.PERMISSION_GRANTED; 7140 } 7141 synchronized (this) { 7142 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7143 ? PackageManager.PERMISSION_GRANTED 7144 : PackageManager.PERMISSION_DENIED; 7145 } 7146 } 7147 7148 /** 7149 * Check if the targetPkg can be granted permission to access uri by 7150 * the callingUid using the given modeFlags. Throws a security exception 7151 * if callingUid is not allowed to do this. Returns the uid of the target 7152 * if the URI permission grant should be performed; returns -1 if it is not 7153 * needed (for example targetPkg already has permission to access the URI). 7154 * If you already know the uid of the target, you can supply it in 7155 * lastTargetUid else set that to -1. 7156 */ 7157 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7158 final int modeFlags, int lastTargetUid) { 7159 if (!Intent.isAccessUriMode(modeFlags)) { 7160 return -1; 7161 } 7162 7163 if (targetPkg != null) { 7164 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7165 "Checking grant " + targetPkg + " permission to " + grantUri); 7166 } 7167 7168 final IPackageManager pm = AppGlobals.getPackageManager(); 7169 7170 // If this is not a content: uri, we can't do anything with it. 7171 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7172 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7173 "Can't grant URI permission for non-content URI: " + grantUri); 7174 return -1; 7175 } 7176 7177 final String authority = grantUri.uri.getAuthority(); 7178 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7179 if (pi == null) { 7180 Slog.w(TAG, "No content provider found for permission check: " + 7181 grantUri.uri.toSafeString()); 7182 return -1; 7183 } 7184 7185 int targetUid = lastTargetUid; 7186 if (targetUid < 0 && targetPkg != null) { 7187 try { 7188 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7189 if (targetUid < 0) { 7190 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7191 "Can't grant URI permission no uid for: " + targetPkg); 7192 return -1; 7193 } 7194 } catch (RemoteException ex) { 7195 return -1; 7196 } 7197 } 7198 7199 if (targetUid >= 0) { 7200 // First... does the target actually need this permission? 7201 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7202 // No need to grant the target this permission. 7203 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7204 "Target " + targetPkg + " already has full permission to " + grantUri); 7205 return -1; 7206 } 7207 } else { 7208 // First... there is no target package, so can anyone access it? 7209 boolean allowed = pi.exported; 7210 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7211 if (pi.readPermission != null) { 7212 allowed = false; 7213 } 7214 } 7215 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7216 if (pi.writePermission != null) { 7217 allowed = false; 7218 } 7219 } 7220 if (allowed) { 7221 return -1; 7222 } 7223 } 7224 7225 /* There is a special cross user grant if: 7226 * - The target is on another user. 7227 * - Apps on the current user can access the uri without any uid permissions. 7228 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7229 * grant uri permissions. 7230 */ 7231 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7232 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7233 modeFlags, false /*without considering the uid permissions*/); 7234 7235 // Second... is the provider allowing granting of URI permissions? 7236 if (!specialCrossUserGrant) { 7237 if (!pi.grantUriPermissions) { 7238 throw new SecurityException("Provider " + pi.packageName 7239 + "/" + pi.name 7240 + " does not allow granting of Uri permissions (uri " 7241 + grantUri + ")"); 7242 } 7243 if (pi.uriPermissionPatterns != null) { 7244 final int N = pi.uriPermissionPatterns.length; 7245 boolean allowed = false; 7246 for (int i=0; i<N; i++) { 7247 if (pi.uriPermissionPatterns[i] != null 7248 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7249 allowed = true; 7250 break; 7251 } 7252 } 7253 if (!allowed) { 7254 throw new SecurityException("Provider " + pi.packageName 7255 + "/" + pi.name 7256 + " does not allow granting of permission to path of Uri " 7257 + grantUri); 7258 } 7259 } 7260 } 7261 7262 // Third... does the caller itself have permission to access 7263 // this uri? 7264 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7265 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7266 // Require they hold a strong enough Uri permission 7267 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7268 throw new SecurityException("Uid " + callingUid 7269 + " does not have permission to uri " + grantUri); 7270 } 7271 } 7272 } 7273 return targetUid; 7274 } 7275 7276 /** 7277 * @param uri This uri must NOT contain an embedded userId. 7278 * @param userId The userId in which the uri is to be resolved. 7279 */ 7280 @Override 7281 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7282 final int modeFlags, int userId) { 7283 enforceNotIsolatedCaller("checkGrantUriPermission"); 7284 synchronized(this) { 7285 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7286 new GrantUri(userId, uri, false), modeFlags, -1); 7287 } 7288 } 7289 7290 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7291 final int modeFlags, UriPermissionOwner owner) { 7292 if (!Intent.isAccessUriMode(modeFlags)) { 7293 return; 7294 } 7295 7296 // So here we are: the caller has the assumed permission 7297 // to the uri, and the target doesn't. Let's now give this to 7298 // the target. 7299 7300 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7301 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7302 7303 final String authority = grantUri.uri.getAuthority(); 7304 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7305 if (pi == null) { 7306 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7307 return; 7308 } 7309 7310 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7311 grantUri.prefix = true; 7312 } 7313 final UriPermission perm = findOrCreateUriPermissionLocked( 7314 pi.packageName, targetPkg, targetUid, grantUri); 7315 perm.grantModes(modeFlags, owner); 7316 } 7317 7318 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7319 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7320 if (targetPkg == null) { 7321 throw new NullPointerException("targetPkg"); 7322 } 7323 int targetUid; 7324 final IPackageManager pm = AppGlobals.getPackageManager(); 7325 try { 7326 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7327 } catch (RemoteException ex) { 7328 return; 7329 } 7330 7331 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7332 targetUid); 7333 if (targetUid < 0) { 7334 return; 7335 } 7336 7337 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7338 owner); 7339 } 7340 7341 static class NeededUriGrants extends ArrayList<GrantUri> { 7342 final String targetPkg; 7343 final int targetUid; 7344 final int flags; 7345 7346 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7347 this.targetPkg = targetPkg; 7348 this.targetUid = targetUid; 7349 this.flags = flags; 7350 } 7351 } 7352 7353 /** 7354 * Like checkGrantUriPermissionLocked, but takes an Intent. 7355 */ 7356 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7357 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7358 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7359 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7360 + " clip=" + (intent != null ? intent.getClipData() : null) 7361 + " from " + intent + "; flags=0x" 7362 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7363 7364 if (targetPkg == null) { 7365 throw new NullPointerException("targetPkg"); 7366 } 7367 7368 if (intent == null) { 7369 return null; 7370 } 7371 Uri data = intent.getData(); 7372 ClipData clip = intent.getClipData(); 7373 if (data == null && clip == null) { 7374 return null; 7375 } 7376 // Default userId for uris in the intent (if they don't specify it themselves) 7377 int contentUserHint = intent.getContentUserHint(); 7378 if (contentUserHint == UserHandle.USER_CURRENT) { 7379 contentUserHint = UserHandle.getUserId(callingUid); 7380 } 7381 final IPackageManager pm = AppGlobals.getPackageManager(); 7382 int targetUid; 7383 if (needed != null) { 7384 targetUid = needed.targetUid; 7385 } else { 7386 try { 7387 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7388 } catch (RemoteException ex) { 7389 return null; 7390 } 7391 if (targetUid < 0) { 7392 if (DEBUG_URI_PERMISSION) { 7393 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7394 + " on user " + targetUserId); 7395 } 7396 return null; 7397 } 7398 } 7399 if (data != null) { 7400 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7401 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7402 targetUid); 7403 if (targetUid > 0) { 7404 if (needed == null) { 7405 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7406 } 7407 needed.add(grantUri); 7408 } 7409 } 7410 if (clip != null) { 7411 for (int i=0; i<clip.getItemCount(); i++) { 7412 Uri uri = clip.getItemAt(i).getUri(); 7413 if (uri != null) { 7414 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7415 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7416 targetUid); 7417 if (targetUid > 0) { 7418 if (needed == null) { 7419 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7420 } 7421 needed.add(grantUri); 7422 } 7423 } else { 7424 Intent clipIntent = clip.getItemAt(i).getIntent(); 7425 if (clipIntent != null) { 7426 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7427 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7428 if (newNeeded != null) { 7429 needed = newNeeded; 7430 } 7431 } 7432 } 7433 } 7434 } 7435 7436 return needed; 7437 } 7438 7439 /** 7440 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7441 */ 7442 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7443 UriPermissionOwner owner) { 7444 if (needed != null) { 7445 for (int i=0; i<needed.size(); i++) { 7446 GrantUri grantUri = needed.get(i); 7447 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7448 grantUri, needed.flags, owner); 7449 } 7450 } 7451 } 7452 7453 void grantUriPermissionFromIntentLocked(int callingUid, 7454 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7455 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7456 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7457 if (needed == null) { 7458 return; 7459 } 7460 7461 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7462 } 7463 7464 /** 7465 * @param uri This uri must NOT contain an embedded userId. 7466 * @param userId The userId in which the uri is to be resolved. 7467 */ 7468 @Override 7469 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7470 final int modeFlags, int userId) { 7471 enforceNotIsolatedCaller("grantUriPermission"); 7472 GrantUri grantUri = new GrantUri(userId, uri, false); 7473 synchronized(this) { 7474 final ProcessRecord r = getRecordForAppLocked(caller); 7475 if (r == null) { 7476 throw new SecurityException("Unable to find app for caller " 7477 + caller 7478 + " when granting permission to uri " + grantUri); 7479 } 7480 if (targetPkg == null) { 7481 throw new IllegalArgumentException("null target"); 7482 } 7483 if (grantUri == null) { 7484 throw new IllegalArgumentException("null uri"); 7485 } 7486 7487 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7488 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7489 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7490 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7491 7492 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7493 UserHandle.getUserId(r.uid)); 7494 } 7495 } 7496 7497 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7498 if (perm.modeFlags == 0) { 7499 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7500 perm.targetUid); 7501 if (perms != null) { 7502 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7503 "Removing " + perm.targetUid + " permission to " + perm.uri); 7504 7505 perms.remove(perm.uri); 7506 if (perms.isEmpty()) { 7507 mGrantedUriPermissions.remove(perm.targetUid); 7508 } 7509 } 7510 } 7511 } 7512 7513 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7514 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7515 7516 final IPackageManager pm = AppGlobals.getPackageManager(); 7517 final String authority = grantUri.uri.getAuthority(); 7518 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7519 if (pi == null) { 7520 Slog.w(TAG, "No content provider found for permission revoke: " 7521 + grantUri.toSafeString()); 7522 return; 7523 } 7524 7525 // Does the caller have this permission on the URI? 7526 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7527 // If they don't have direct access to the URI, then revoke any 7528 // ownerless URI permissions that have been granted to them. 7529 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7530 if (perms != null) { 7531 boolean persistChanged = false; 7532 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7533 final UriPermission perm = it.next(); 7534 if (perm.uri.sourceUserId == grantUri.sourceUserId 7535 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7536 if (DEBUG_URI_PERMISSION) 7537 Slog.v(TAG, "Revoking non-owned " + perm.targetUid + 7538 " permission to " + perm.uri); 7539 persistChanged |= perm.revokeModes( 7540 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 7541 if (perm.modeFlags == 0) { 7542 it.remove(); 7543 } 7544 } 7545 } 7546 if (perms.isEmpty()) { 7547 mGrantedUriPermissions.remove(callingUid); 7548 } 7549 if (persistChanged) { 7550 schedulePersistUriGrants(); 7551 } 7552 } 7553 return; 7554 } 7555 7556 boolean persistChanged = false; 7557 7558 // Go through all of the permissions and remove any that match. 7559 int N = mGrantedUriPermissions.size(); 7560 for (int i = 0; i < N; i++) { 7561 final int targetUid = mGrantedUriPermissions.keyAt(i); 7562 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7563 7564 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7565 final UriPermission perm = it.next(); 7566 if (perm.uri.sourceUserId == grantUri.sourceUserId 7567 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7568 if (DEBUG_URI_PERMISSION) 7569 Slog.v(TAG, 7570 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7571 persistChanged |= perm.revokeModes( 7572 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7573 if (perm.modeFlags == 0) { 7574 it.remove(); 7575 } 7576 } 7577 } 7578 7579 if (perms.isEmpty()) { 7580 mGrantedUriPermissions.remove(targetUid); 7581 N--; 7582 i--; 7583 } 7584 } 7585 7586 if (persistChanged) { 7587 schedulePersistUriGrants(); 7588 } 7589 } 7590 7591 /** 7592 * @param uri This uri must NOT contain an embedded userId. 7593 * @param userId The userId in which the uri is to be resolved. 7594 */ 7595 @Override 7596 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7597 int userId) { 7598 enforceNotIsolatedCaller("revokeUriPermission"); 7599 synchronized(this) { 7600 final ProcessRecord r = getRecordForAppLocked(caller); 7601 if (r == null) { 7602 throw new SecurityException("Unable to find app for caller " 7603 + caller 7604 + " when revoking permission to uri " + uri); 7605 } 7606 if (uri == null) { 7607 Slog.w(TAG, "revokeUriPermission: null uri"); 7608 return; 7609 } 7610 7611 if (!Intent.isAccessUriMode(modeFlags)) { 7612 return; 7613 } 7614 7615 final IPackageManager pm = AppGlobals.getPackageManager(); 7616 final String authority = uri.getAuthority(); 7617 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7618 if (pi == null) { 7619 Slog.w(TAG, "No content provider found for permission revoke: " 7620 + uri.toSafeString()); 7621 return; 7622 } 7623 7624 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7625 } 7626 } 7627 7628 /** 7629 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7630 * given package. 7631 * 7632 * @param packageName Package name to match, or {@code null} to apply to all 7633 * packages. 7634 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7635 * to all users. 7636 * @param persistable If persistable grants should be removed. 7637 */ 7638 private void removeUriPermissionsForPackageLocked( 7639 String packageName, int userHandle, boolean persistable) { 7640 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7641 throw new IllegalArgumentException("Must narrow by either package or user"); 7642 } 7643 7644 boolean persistChanged = false; 7645 7646 int N = mGrantedUriPermissions.size(); 7647 for (int i = 0; i < N; i++) { 7648 final int targetUid = mGrantedUriPermissions.keyAt(i); 7649 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7650 7651 // Only inspect grants matching user 7652 if (userHandle == UserHandle.USER_ALL 7653 || userHandle == UserHandle.getUserId(targetUid)) { 7654 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7655 final UriPermission perm = it.next(); 7656 7657 // Only inspect grants matching package 7658 if (packageName == null || perm.sourcePkg.equals(packageName) 7659 || perm.targetPkg.equals(packageName)) { 7660 persistChanged |= perm.revokeModes(persistable 7661 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 7662 7663 // Only remove when no modes remain; any persisted grants 7664 // will keep this alive. 7665 if (perm.modeFlags == 0) { 7666 it.remove(); 7667 } 7668 } 7669 } 7670 7671 if (perms.isEmpty()) { 7672 mGrantedUriPermissions.remove(targetUid); 7673 N--; 7674 i--; 7675 } 7676 } 7677 } 7678 7679 if (persistChanged) { 7680 schedulePersistUriGrants(); 7681 } 7682 } 7683 7684 @Override 7685 public IBinder newUriPermissionOwner(String name) { 7686 enforceNotIsolatedCaller("newUriPermissionOwner"); 7687 synchronized(this) { 7688 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7689 return owner.getExternalTokenLocked(); 7690 } 7691 } 7692 7693 /** 7694 * @param uri This uri must NOT contain an embedded userId. 7695 * @param sourceUserId The userId in which the uri is to be resolved. 7696 * @param targetUserId The userId of the app that receives the grant. 7697 */ 7698 @Override 7699 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7700 final int modeFlags, int sourceUserId, int targetUserId) { 7701 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7702 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7703 synchronized(this) { 7704 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7705 if (owner == null) { 7706 throw new IllegalArgumentException("Unknown owner: " + token); 7707 } 7708 if (fromUid != Binder.getCallingUid()) { 7709 if (Binder.getCallingUid() != Process.myUid()) { 7710 // Only system code can grant URI permissions on behalf 7711 // of other users. 7712 throw new SecurityException("nice try"); 7713 } 7714 } 7715 if (targetPkg == null) { 7716 throw new IllegalArgumentException("null target"); 7717 } 7718 if (uri == null) { 7719 throw new IllegalArgumentException("null uri"); 7720 } 7721 7722 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7723 modeFlags, owner, targetUserId); 7724 } 7725 } 7726 7727 /** 7728 * @param uri This uri must NOT contain an embedded userId. 7729 * @param userId The userId in which the uri is to be resolved. 7730 */ 7731 @Override 7732 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7733 synchronized(this) { 7734 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7735 if (owner == null) { 7736 throw new IllegalArgumentException("Unknown owner: " + token); 7737 } 7738 7739 if (uri == null) { 7740 owner.removeUriPermissionsLocked(mode); 7741 } else { 7742 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7743 } 7744 } 7745 } 7746 7747 private void schedulePersistUriGrants() { 7748 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7749 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7750 10 * DateUtils.SECOND_IN_MILLIS); 7751 } 7752 } 7753 7754 private void writeGrantedUriPermissions() { 7755 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7756 7757 // Snapshot permissions so we can persist without lock 7758 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7759 synchronized (this) { 7760 final int size = mGrantedUriPermissions.size(); 7761 for (int i = 0; i < size; i++) { 7762 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7763 for (UriPermission perm : perms.values()) { 7764 if (perm.persistedModeFlags != 0) { 7765 persist.add(perm.snapshot()); 7766 } 7767 } 7768 } 7769 } 7770 7771 FileOutputStream fos = null; 7772 try { 7773 fos = mGrantFile.startWrite(); 7774 7775 XmlSerializer out = new FastXmlSerializer(); 7776 out.setOutput(fos, "utf-8"); 7777 out.startDocument(null, true); 7778 out.startTag(null, TAG_URI_GRANTS); 7779 for (UriPermission.Snapshot perm : persist) { 7780 out.startTag(null, TAG_URI_GRANT); 7781 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7782 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7783 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7784 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7785 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7786 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7787 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7788 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7789 out.endTag(null, TAG_URI_GRANT); 7790 } 7791 out.endTag(null, TAG_URI_GRANTS); 7792 out.endDocument(); 7793 7794 mGrantFile.finishWrite(fos); 7795 } catch (IOException e) { 7796 if (fos != null) { 7797 mGrantFile.failWrite(fos); 7798 } 7799 } 7800 } 7801 7802 private void readGrantedUriPermissionsLocked() { 7803 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7804 7805 final long now = System.currentTimeMillis(); 7806 7807 FileInputStream fis = null; 7808 try { 7809 fis = mGrantFile.openRead(); 7810 final XmlPullParser in = Xml.newPullParser(); 7811 in.setInput(fis, null); 7812 7813 int type; 7814 while ((type = in.next()) != END_DOCUMENT) { 7815 final String tag = in.getName(); 7816 if (type == START_TAG) { 7817 if (TAG_URI_GRANT.equals(tag)) { 7818 final int sourceUserId; 7819 final int targetUserId; 7820 final int userHandle = readIntAttribute(in, 7821 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7822 if (userHandle != UserHandle.USER_NULL) { 7823 // For backwards compatibility. 7824 sourceUserId = userHandle; 7825 targetUserId = userHandle; 7826 } else { 7827 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7828 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7829 } 7830 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7831 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7832 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7833 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7834 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7835 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7836 7837 // Sanity check that provider still belongs to source package 7838 final ProviderInfo pi = getProviderInfoLocked( 7839 uri.getAuthority(), sourceUserId); 7840 if (pi != null && sourcePkg.equals(pi.packageName)) { 7841 int targetUid = -1; 7842 try { 7843 targetUid = AppGlobals.getPackageManager() 7844 .getPackageUid(targetPkg, targetUserId); 7845 } catch (RemoteException e) { 7846 } 7847 if (targetUid != -1) { 7848 final UriPermission perm = findOrCreateUriPermissionLocked( 7849 sourcePkg, targetPkg, targetUid, 7850 new GrantUri(sourceUserId, uri, prefix)); 7851 perm.initPersistedModes(modeFlags, createdTime); 7852 } 7853 } else { 7854 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7855 + " but instead found " + pi); 7856 } 7857 } 7858 } 7859 } 7860 } catch (FileNotFoundException e) { 7861 // Missing grants is okay 7862 } catch (IOException e) { 7863 Log.wtf(TAG, "Failed reading Uri grants", e); 7864 } catch (XmlPullParserException e) { 7865 Log.wtf(TAG, "Failed reading Uri grants", e); 7866 } finally { 7867 IoUtils.closeQuietly(fis); 7868 } 7869 } 7870 7871 /** 7872 * @param uri This uri must NOT contain an embedded userId. 7873 * @param userId The userId in which the uri is to be resolved. 7874 */ 7875 @Override 7876 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7877 enforceNotIsolatedCaller("takePersistableUriPermission"); 7878 7879 Preconditions.checkFlagsArgument(modeFlags, 7880 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7881 7882 synchronized (this) { 7883 final int callingUid = Binder.getCallingUid(); 7884 boolean persistChanged = false; 7885 GrantUri grantUri = new GrantUri(userId, uri, false); 7886 7887 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7888 new GrantUri(userId, uri, false)); 7889 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7890 new GrantUri(userId, uri, true)); 7891 7892 final boolean exactValid = (exactPerm != null) 7893 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7894 final boolean prefixValid = (prefixPerm != null) 7895 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7896 7897 if (!(exactValid || prefixValid)) { 7898 throw new SecurityException("No persistable permission grants found for UID " 7899 + callingUid + " and Uri " + grantUri.toSafeString()); 7900 } 7901 7902 if (exactValid) { 7903 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7904 } 7905 if (prefixValid) { 7906 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7907 } 7908 7909 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7910 7911 if (persistChanged) { 7912 schedulePersistUriGrants(); 7913 } 7914 } 7915 } 7916 7917 /** 7918 * @param uri This uri must NOT contain an embedded userId. 7919 * @param userId The userId in which the uri is to be resolved. 7920 */ 7921 @Override 7922 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7923 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7924 7925 Preconditions.checkFlagsArgument(modeFlags, 7926 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7927 7928 synchronized (this) { 7929 final int callingUid = Binder.getCallingUid(); 7930 boolean persistChanged = false; 7931 7932 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7933 new GrantUri(userId, uri, false)); 7934 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7935 new GrantUri(userId, uri, true)); 7936 if (exactPerm == null && prefixPerm == null) { 7937 throw new SecurityException("No permission grants found for UID " + callingUid 7938 + " and Uri " + uri.toSafeString()); 7939 } 7940 7941 if (exactPerm != null) { 7942 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7943 removeUriPermissionIfNeededLocked(exactPerm); 7944 } 7945 if (prefixPerm != null) { 7946 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7947 removeUriPermissionIfNeededLocked(prefixPerm); 7948 } 7949 7950 if (persistChanged) { 7951 schedulePersistUriGrants(); 7952 } 7953 } 7954 } 7955 7956 /** 7957 * Prune any older {@link UriPermission} for the given UID until outstanding 7958 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7959 * 7960 * @return if any mutations occured that require persisting. 7961 */ 7962 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7963 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7964 if (perms == null) return false; 7965 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7966 7967 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7968 for (UriPermission perm : perms.values()) { 7969 if (perm.persistedModeFlags != 0) { 7970 persisted.add(perm); 7971 } 7972 } 7973 7974 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7975 if (trimCount <= 0) return false; 7976 7977 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7978 for (int i = 0; i < trimCount; i++) { 7979 final UriPermission perm = persisted.get(i); 7980 7981 if (DEBUG_URI_PERMISSION) { 7982 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7983 } 7984 7985 perm.releasePersistableModes(~0); 7986 removeUriPermissionIfNeededLocked(perm); 7987 } 7988 7989 return true; 7990 } 7991 7992 @Override 7993 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7994 String packageName, boolean incoming) { 7995 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7996 Preconditions.checkNotNull(packageName, "packageName"); 7997 7998 final int callingUid = Binder.getCallingUid(); 7999 final IPackageManager pm = AppGlobals.getPackageManager(); 8000 try { 8001 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 8002 if (packageUid != callingUid) { 8003 throw new SecurityException( 8004 "Package " + packageName + " does not belong to calling UID " + callingUid); 8005 } 8006 } catch (RemoteException e) { 8007 throw new SecurityException("Failed to verify package name ownership"); 8008 } 8009 8010 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 8011 synchronized (this) { 8012 if (incoming) { 8013 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8014 callingUid); 8015 if (perms == null) { 8016 Slog.w(TAG, "No permission grants found for " + packageName); 8017 } else { 8018 for (UriPermission perm : perms.values()) { 8019 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 8020 result.add(perm.buildPersistedPublicApiObject()); 8021 } 8022 } 8023 } 8024 } else { 8025 final int size = mGrantedUriPermissions.size(); 8026 for (int i = 0; i < size; i++) { 8027 final ArrayMap<GrantUri, UriPermission> perms = 8028 mGrantedUriPermissions.valueAt(i); 8029 for (UriPermission perm : perms.values()) { 8030 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 8031 result.add(perm.buildPersistedPublicApiObject()); 8032 } 8033 } 8034 } 8035 } 8036 } 8037 return new ParceledListSlice<android.content.UriPermission>(result); 8038 } 8039 8040 @Override 8041 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 8042 synchronized (this) { 8043 ProcessRecord app = 8044 who != null ? getRecordForAppLocked(who) : null; 8045 if (app == null) return; 8046 8047 Message msg = Message.obtain(); 8048 msg.what = WAIT_FOR_DEBUGGER_MSG; 8049 msg.obj = app; 8050 msg.arg1 = waiting ? 1 : 0; 8051 mHandler.sendMessage(msg); 8052 } 8053 } 8054 8055 @Override 8056 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 8057 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 8058 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 8059 outInfo.availMem = Process.getFreeMemory(); 8060 outInfo.totalMem = Process.getTotalMemory(); 8061 outInfo.threshold = homeAppMem; 8062 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8063 outInfo.hiddenAppThreshold = cachedAppMem; 8064 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8065 ProcessList.SERVICE_ADJ); 8066 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8067 ProcessList.VISIBLE_APP_ADJ); 8068 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8069 ProcessList.FOREGROUND_APP_ADJ); 8070 } 8071 8072 // ========================================================= 8073 // TASK MANAGEMENT 8074 // ========================================================= 8075 8076 @Override 8077 public List<IAppTask> getAppTasks(String callingPackage) { 8078 int callingUid = Binder.getCallingUid(); 8079 long ident = Binder.clearCallingIdentity(); 8080 8081 synchronized(this) { 8082 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8083 try { 8084 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8085 8086 final int N = mRecentTasks.size(); 8087 for (int i = 0; i < N; i++) { 8088 TaskRecord tr = mRecentTasks.get(i); 8089 // Skip tasks that do not match the caller. We don't need to verify 8090 // callingPackage, because we are also limiting to callingUid and know 8091 // that will limit to the correct security sandbox. 8092 if (tr.effectiveUid != callingUid) { 8093 continue; 8094 } 8095 Intent intent = tr.getBaseIntent(); 8096 if (intent == null || 8097 !callingPackage.equals(intent.getComponent().getPackageName())) { 8098 continue; 8099 } 8100 ActivityManager.RecentTaskInfo taskInfo = 8101 createRecentTaskInfoFromTaskRecord(tr); 8102 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8103 list.add(taskImpl); 8104 } 8105 } finally { 8106 Binder.restoreCallingIdentity(ident); 8107 } 8108 return list; 8109 } 8110 } 8111 8112 @Override 8113 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8114 final int callingUid = Binder.getCallingUid(); 8115 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8116 8117 synchronized(this) { 8118 if (localLOGV) Slog.v( 8119 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8120 8121 final boolean allowed = checkCallingPermission( 8122 android.Manifest.permission.GET_TASKS) 8123 == PackageManager.PERMISSION_GRANTED; 8124 if (!allowed) { 8125 Slog.w(TAG, "getTasks: caller " + callingUid 8126 + " does not hold GET_TASKS; limiting output"); 8127 } 8128 8129 // TODO: Improve with MRU list from all ActivityStacks. 8130 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8131 } 8132 8133 return list; 8134 } 8135 8136 TaskRecord getMostRecentTask() { 8137 return mRecentTasks.get(0); 8138 } 8139 8140 /** 8141 * Creates a new RecentTaskInfo from a TaskRecord. 8142 */ 8143 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8144 // Update the task description to reflect any changes in the task stack 8145 tr.updateTaskDescription(); 8146 8147 // Compose the recent task info 8148 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8149 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8150 rti.persistentId = tr.taskId; 8151 rti.baseIntent = new Intent(tr.getBaseIntent()); 8152 rti.origActivity = tr.origActivity; 8153 rti.description = tr.lastDescription; 8154 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8155 rti.userId = tr.userId; 8156 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8157 rti.firstActiveTime = tr.firstActiveTime; 8158 rti.lastActiveTime = tr.lastActiveTime; 8159 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8160 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8161 return rti; 8162 } 8163 8164 @Override 8165 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8166 final int callingUid = Binder.getCallingUid(); 8167 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8168 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8169 8170 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8171 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8172 synchronized (this) { 8173 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8174 == PackageManager.PERMISSION_GRANTED; 8175 if (!allowed) { 8176 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8177 + " does not hold GET_TASKS; limiting output"); 8178 } 8179 final boolean detailed = checkCallingPermission( 8180 android.Manifest.permission.GET_DETAILED_TASKS) 8181 == PackageManager.PERMISSION_GRANTED; 8182 8183 final int N = mRecentTasks.size(); 8184 ArrayList<ActivityManager.RecentTaskInfo> res 8185 = new ArrayList<ActivityManager.RecentTaskInfo>( 8186 maxNum < N ? maxNum : N); 8187 8188 final Set<Integer> includedUsers; 8189 if (includeProfiles) { 8190 includedUsers = getProfileIdsLocked(userId); 8191 } else { 8192 includedUsers = new HashSet<Integer>(); 8193 } 8194 includedUsers.add(Integer.valueOf(userId)); 8195 8196 for (int i=0; i<N && maxNum > 0; i++) { 8197 TaskRecord tr = mRecentTasks.get(i); 8198 // Only add calling user or related users recent tasks 8199 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8200 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8201 continue; 8202 } 8203 8204 // Return the entry if desired by the caller. We always return 8205 // the first entry, because callers always expect this to be the 8206 // foreground app. We may filter others if the caller has 8207 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8208 // we should exclude the entry. 8209 8210 if (i == 0 8211 || withExcluded 8212 || (tr.intent == null) 8213 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8214 == 0)) { 8215 if (!allowed) { 8216 // If the caller doesn't have the GET_TASKS permission, then only 8217 // allow them to see a small subset of tasks -- their own and home. 8218 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8219 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8220 continue; 8221 } 8222 } 8223 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8224 if (tr.stack != null && tr.stack.isHomeStack()) { 8225 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8226 continue; 8227 } 8228 } 8229 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8230 // Don't include auto remove tasks that are finished or finishing. 8231 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8232 + tr); 8233 continue; 8234 } 8235 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8236 && !tr.isAvailable) { 8237 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8238 continue; 8239 } 8240 8241 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8242 if (!detailed) { 8243 rti.baseIntent.replaceExtras((Bundle)null); 8244 } 8245 8246 res.add(rti); 8247 maxNum--; 8248 } 8249 } 8250 return res; 8251 } 8252 } 8253 8254 private TaskRecord recentTaskForIdLocked(int id) { 8255 final int N = mRecentTasks.size(); 8256 for (int i=0; i<N; i++) { 8257 TaskRecord tr = mRecentTasks.get(i); 8258 if (tr.taskId == id) { 8259 return tr; 8260 } 8261 } 8262 return null; 8263 } 8264 8265 @Override 8266 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8267 synchronized (this) { 8268 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8269 "getTaskThumbnail()"); 8270 TaskRecord tr = recentTaskForIdLocked(id); 8271 if (tr != null) { 8272 return tr.getTaskThumbnailLocked(); 8273 } 8274 } 8275 return null; 8276 } 8277 8278 @Override 8279 public int addAppTask(IBinder activityToken, Intent intent, 8280 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8281 final int callingUid = Binder.getCallingUid(); 8282 final long callingIdent = Binder.clearCallingIdentity(); 8283 8284 try { 8285 synchronized (this) { 8286 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8287 if (r == null) { 8288 throw new IllegalArgumentException("Activity does not exist; token=" 8289 + activityToken); 8290 } 8291 ComponentName comp = intent.getComponent(); 8292 if (comp == null) { 8293 throw new IllegalArgumentException("Intent " + intent 8294 + " must specify explicit component"); 8295 } 8296 if (thumbnail.getWidth() != mThumbnailWidth 8297 || thumbnail.getHeight() != mThumbnailHeight) { 8298 throw new IllegalArgumentException("Bad thumbnail size: got " 8299 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8300 + mThumbnailWidth + "x" + mThumbnailHeight); 8301 } 8302 if (intent.getSelector() != null) { 8303 intent.setSelector(null); 8304 } 8305 if (intent.getSourceBounds() != null) { 8306 intent.setSourceBounds(null); 8307 } 8308 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8309 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8310 // The caller has added this as an auto-remove task... that makes no 8311 // sense, so turn off auto-remove. 8312 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8313 } 8314 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8315 // Must be a new task. 8316 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8317 } 8318 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8319 mLastAddedTaskActivity = null; 8320 } 8321 ActivityInfo ainfo = mLastAddedTaskActivity; 8322 if (ainfo == null) { 8323 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8324 comp, 0, UserHandle.getUserId(callingUid)); 8325 if (ainfo.applicationInfo.uid != callingUid) { 8326 throw new SecurityException( 8327 "Can't add task for another application: target uid=" 8328 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8329 } 8330 } 8331 8332 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8333 intent, description); 8334 8335 int trimIdx = trimRecentsForTask(task, false); 8336 if (trimIdx >= 0) { 8337 // If this would have caused a trim, then we'll abort because that 8338 // means it would be added at the end of the list but then just removed. 8339 return -1; 8340 } 8341 8342 final int N = mRecentTasks.size(); 8343 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8344 final TaskRecord tr = mRecentTasks.remove(N - 1); 8345 tr.removedFromRecents(mTaskPersister); 8346 } 8347 8348 task.inRecents = true; 8349 mRecentTasks.add(task); 8350 r.task.stack.addTask(task, false, false); 8351 8352 task.setLastThumbnail(thumbnail); 8353 task.freeLastThumbnail(); 8354 8355 return task.taskId; 8356 } 8357 } finally { 8358 Binder.restoreCallingIdentity(callingIdent); 8359 } 8360 } 8361 8362 @Override 8363 public Point getAppTaskThumbnailSize() { 8364 synchronized (this) { 8365 return new Point(mThumbnailWidth, mThumbnailHeight); 8366 } 8367 } 8368 8369 @Override 8370 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8371 synchronized (this) { 8372 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8373 if (r != null) { 8374 r.setTaskDescription(td); 8375 r.task.updateTaskDescription(); 8376 } 8377 } 8378 } 8379 8380 @Override 8381 public Bitmap getTaskDescriptionIcon(String filename) { 8382 return mTaskPersister.getTaskDescriptionIcon(filename); 8383 } 8384 8385 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8386 mRecentTasks.remove(tr); 8387 tr.removedFromRecents(mTaskPersister); 8388 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8389 Intent baseIntent = new Intent( 8390 tr.intent != null ? tr.intent : tr.affinityIntent); 8391 ComponentName component = baseIntent.getComponent(); 8392 if (component == null) { 8393 Slog.w(TAG, "Now component for base intent of task: " + tr); 8394 return; 8395 } 8396 8397 // Find any running services associated with this app. 8398 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8399 8400 if (killProcesses) { 8401 // Find any running processes associated with this app. 8402 final String pkg = component.getPackageName(); 8403 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8404 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8405 for (int i=0; i<pmap.size(); i++) { 8406 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8407 for (int j=0; j<uids.size(); j++) { 8408 ProcessRecord proc = uids.valueAt(j); 8409 if (proc.userId != tr.userId) { 8410 continue; 8411 } 8412 if (!proc.pkgList.containsKey(pkg)) { 8413 continue; 8414 } 8415 procs.add(proc); 8416 } 8417 } 8418 8419 // Kill the running processes. 8420 for (int i=0; i<procs.size(); i++) { 8421 ProcessRecord pr = procs.get(i); 8422 if (pr == mHomeProcess) { 8423 // Don't kill the home process along with tasks from the same package. 8424 continue; 8425 } 8426 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8427 pr.kill("remove task", true); 8428 } else { 8429 pr.waitingToKill = "remove task"; 8430 } 8431 } 8432 } 8433 } 8434 8435 /** 8436 * Removes the task with the specified task id. 8437 * 8438 * @param taskId Identifier of the task to be removed. 8439 * @param flags Additional operational flags. May be 0 or 8440 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8441 * @return Returns true if the given task was found and removed. 8442 */ 8443 private boolean removeTaskByIdLocked(int taskId, int flags) { 8444 TaskRecord tr = recentTaskForIdLocked(taskId); 8445 if (tr != null) { 8446 tr.removeTaskActivitiesLocked(); 8447 cleanUpRemovedTaskLocked(tr, flags); 8448 if (tr.isPersistable) { 8449 notifyTaskPersisterLocked(null, true); 8450 } 8451 return true; 8452 } 8453 return false; 8454 } 8455 8456 @Override 8457 public boolean removeTask(int taskId, int flags) { 8458 synchronized (this) { 8459 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8460 "removeTask()"); 8461 long ident = Binder.clearCallingIdentity(); 8462 try { 8463 return removeTaskByIdLocked(taskId, flags); 8464 } finally { 8465 Binder.restoreCallingIdentity(ident); 8466 } 8467 } 8468 } 8469 8470 /** 8471 * TODO: Add mController hook 8472 */ 8473 @Override 8474 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8475 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8476 "moveTaskToFront()"); 8477 8478 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8479 synchronized(this) { 8480 moveTaskToFrontLocked(taskId, flags, options); 8481 } 8482 } 8483 8484 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8485 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8486 Binder.getCallingUid(), -1, -1, "Task to front")) { 8487 ActivityOptions.abort(options); 8488 return; 8489 } 8490 final long origId = Binder.clearCallingIdentity(); 8491 try { 8492 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8493 if (task == null) { 8494 return; 8495 } 8496 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8497 mStackSupervisor.showLockTaskToast(); 8498 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8499 return; 8500 } 8501 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8502 if (prev != null && prev.isRecentsActivity()) { 8503 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8504 } 8505 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8506 } finally { 8507 Binder.restoreCallingIdentity(origId); 8508 } 8509 ActivityOptions.abort(options); 8510 } 8511 8512 @Override 8513 public void moveTaskToBack(int taskId) { 8514 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8515 "moveTaskToBack()"); 8516 8517 synchronized(this) { 8518 TaskRecord tr = recentTaskForIdLocked(taskId); 8519 if (tr != null) { 8520 if (tr == mStackSupervisor.mLockTaskModeTask) { 8521 mStackSupervisor.showLockTaskToast(); 8522 return; 8523 } 8524 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8525 ActivityStack stack = tr.stack; 8526 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8527 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8528 Binder.getCallingUid(), -1, -1, "Task to back")) { 8529 return; 8530 } 8531 } 8532 final long origId = Binder.clearCallingIdentity(); 8533 try { 8534 stack.moveTaskToBackLocked(taskId, null); 8535 } finally { 8536 Binder.restoreCallingIdentity(origId); 8537 } 8538 } 8539 } 8540 } 8541 8542 /** 8543 * Moves an activity, and all of the other activities within the same task, to the bottom 8544 * of the history stack. The activity's order within the task is unchanged. 8545 * 8546 * @param token A reference to the activity we wish to move 8547 * @param nonRoot If false then this only works if the activity is the root 8548 * of a task; if true it will work for any activity in a task. 8549 * @return Returns true if the move completed, false if not. 8550 */ 8551 @Override 8552 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8553 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8554 synchronized(this) { 8555 final long origId = Binder.clearCallingIdentity(); 8556 try { 8557 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8558 if (taskId >= 0) { 8559 if ((mStackSupervisor.mLockTaskModeTask != null) 8560 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8561 mStackSupervisor.showLockTaskToast(); 8562 return false; 8563 } 8564 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8565 } 8566 } finally { 8567 Binder.restoreCallingIdentity(origId); 8568 } 8569 } 8570 return false; 8571 } 8572 8573 @Override 8574 public void moveTaskBackwards(int task) { 8575 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8576 "moveTaskBackwards()"); 8577 8578 synchronized(this) { 8579 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8580 Binder.getCallingUid(), -1, -1, "Task backwards")) { 8581 return; 8582 } 8583 final long origId = Binder.clearCallingIdentity(); 8584 moveTaskBackwardsLocked(task); 8585 Binder.restoreCallingIdentity(origId); 8586 } 8587 } 8588 8589 private final void moveTaskBackwardsLocked(int task) { 8590 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8591 } 8592 8593 @Override 8594 public IBinder getHomeActivityToken() throws RemoteException { 8595 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8596 "getHomeActivityToken()"); 8597 synchronized (this) { 8598 return mStackSupervisor.getHomeActivityToken(); 8599 } 8600 } 8601 8602 @Override 8603 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8604 IActivityContainerCallback callback) throws RemoteException { 8605 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8606 "createActivityContainer()"); 8607 synchronized (this) { 8608 if (parentActivityToken == null) { 8609 throw new IllegalArgumentException("parent token must not be null"); 8610 } 8611 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8612 if (r == null) { 8613 return null; 8614 } 8615 if (callback == null) { 8616 throw new IllegalArgumentException("callback must not be null"); 8617 } 8618 return mStackSupervisor.createActivityContainer(r, callback); 8619 } 8620 } 8621 8622 @Override 8623 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8624 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8625 "deleteActivityContainer()"); 8626 synchronized (this) { 8627 mStackSupervisor.deleteActivityContainer(container); 8628 } 8629 } 8630 8631 @Override 8632 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8633 throws RemoteException { 8634 synchronized (this) { 8635 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8636 if (stack != null) { 8637 return stack.mActivityContainer; 8638 } 8639 return null; 8640 } 8641 } 8642 8643 @Override 8644 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8645 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8646 "moveTaskToStack()"); 8647 if (stackId == HOME_STACK_ID) { 8648 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8649 new RuntimeException("here").fillInStackTrace()); 8650 } 8651 synchronized (this) { 8652 long ident = Binder.clearCallingIdentity(); 8653 try { 8654 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8655 + stackId + " toTop=" + toTop); 8656 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8657 } finally { 8658 Binder.restoreCallingIdentity(ident); 8659 } 8660 } 8661 } 8662 8663 @Override 8664 public void resizeStack(int stackBoxId, Rect bounds) { 8665 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8666 "resizeStackBox()"); 8667 long ident = Binder.clearCallingIdentity(); 8668 try { 8669 mWindowManager.resizeStack(stackBoxId, bounds); 8670 } finally { 8671 Binder.restoreCallingIdentity(ident); 8672 } 8673 } 8674 8675 @Override 8676 public List<StackInfo> getAllStackInfos() { 8677 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8678 "getAllStackInfos()"); 8679 long ident = Binder.clearCallingIdentity(); 8680 try { 8681 synchronized (this) { 8682 return mStackSupervisor.getAllStackInfosLocked(); 8683 } 8684 } finally { 8685 Binder.restoreCallingIdentity(ident); 8686 } 8687 } 8688 8689 @Override 8690 public StackInfo getStackInfo(int stackId) { 8691 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8692 "getStackInfo()"); 8693 long ident = Binder.clearCallingIdentity(); 8694 try { 8695 synchronized (this) { 8696 return mStackSupervisor.getStackInfoLocked(stackId); 8697 } 8698 } finally { 8699 Binder.restoreCallingIdentity(ident); 8700 } 8701 } 8702 8703 @Override 8704 public boolean isInHomeStack(int taskId) { 8705 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8706 "getStackInfo()"); 8707 long ident = Binder.clearCallingIdentity(); 8708 try { 8709 synchronized (this) { 8710 TaskRecord tr = recentTaskForIdLocked(taskId); 8711 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8712 } 8713 } finally { 8714 Binder.restoreCallingIdentity(ident); 8715 } 8716 } 8717 8718 @Override 8719 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8720 synchronized(this) { 8721 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8722 } 8723 } 8724 8725 private boolean isLockTaskAuthorized(String pkg) { 8726 final DevicePolicyManager dpm = (DevicePolicyManager) 8727 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8728 try { 8729 int uid = mContext.getPackageManager().getPackageUid(pkg, 8730 Binder.getCallingUserHandle().getIdentifier()); 8731 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8732 } catch (NameNotFoundException e) { 8733 return false; 8734 } 8735 } 8736 8737 void startLockTaskMode(TaskRecord task) { 8738 final String pkg; 8739 synchronized (this) { 8740 pkg = task.intent.getComponent().getPackageName(); 8741 } 8742 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8743 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8744 final TaskRecord taskRecord = task; 8745 mHandler.post(new Runnable() { 8746 @Override 8747 public void run() { 8748 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8749 } 8750 }); 8751 return; 8752 } 8753 long ident = Binder.clearCallingIdentity(); 8754 try { 8755 synchronized (this) { 8756 // Since we lost lock on task, make sure it is still there. 8757 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8758 if (task != null) { 8759 if (!isSystemInitiated 8760 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8761 throw new IllegalArgumentException("Invalid task, not in foreground"); 8762 } 8763 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8764 } 8765 } 8766 } finally { 8767 Binder.restoreCallingIdentity(ident); 8768 } 8769 } 8770 8771 @Override 8772 public void startLockTaskMode(int taskId) { 8773 final TaskRecord task; 8774 long ident = Binder.clearCallingIdentity(); 8775 try { 8776 synchronized (this) { 8777 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8778 } 8779 } finally { 8780 Binder.restoreCallingIdentity(ident); 8781 } 8782 if (task != null) { 8783 startLockTaskMode(task); 8784 } 8785 } 8786 8787 @Override 8788 public void startLockTaskMode(IBinder token) { 8789 final TaskRecord task; 8790 long ident = Binder.clearCallingIdentity(); 8791 try { 8792 synchronized (this) { 8793 final ActivityRecord r = ActivityRecord.forToken(token); 8794 if (r == null) { 8795 return; 8796 } 8797 task = r.task; 8798 } 8799 } finally { 8800 Binder.restoreCallingIdentity(ident); 8801 } 8802 if (task != null) { 8803 startLockTaskMode(task); 8804 } 8805 } 8806 8807 @Override 8808 public void startLockTaskModeOnCurrent() throws RemoteException { 8809 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8810 "startLockTaskModeOnCurrent"); 8811 ActivityRecord r = null; 8812 synchronized (this) { 8813 r = mStackSupervisor.topRunningActivityLocked(); 8814 } 8815 startLockTaskMode(r.task); 8816 } 8817 8818 @Override 8819 public void stopLockTaskMode() { 8820 // Verify that the user matches the package of the intent for the TaskRecord 8821 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8822 // and stopLockTaskMode. 8823 final int callingUid = Binder.getCallingUid(); 8824 if (callingUid != Process.SYSTEM_UID) { 8825 try { 8826 String pkg = 8827 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8828 int uid = mContext.getPackageManager().getPackageUid(pkg, 8829 Binder.getCallingUserHandle().getIdentifier()); 8830 if (uid != callingUid) { 8831 throw new SecurityException("Invalid uid, expected " + uid); 8832 } 8833 } catch (NameNotFoundException e) { 8834 Log.d(TAG, "stopLockTaskMode " + e); 8835 return; 8836 } 8837 } 8838 long ident = Binder.clearCallingIdentity(); 8839 try { 8840 Log.d(TAG, "stopLockTaskMode"); 8841 // Stop lock task 8842 synchronized (this) { 8843 mStackSupervisor.setLockTaskModeLocked(null, false); 8844 } 8845 } finally { 8846 Binder.restoreCallingIdentity(ident); 8847 } 8848 } 8849 8850 @Override 8851 public void stopLockTaskModeOnCurrent() throws RemoteException { 8852 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8853 "stopLockTaskModeOnCurrent"); 8854 long ident = Binder.clearCallingIdentity(); 8855 try { 8856 stopLockTaskMode(); 8857 } finally { 8858 Binder.restoreCallingIdentity(ident); 8859 } 8860 } 8861 8862 @Override 8863 public boolean isInLockTaskMode() { 8864 synchronized (this) { 8865 return mStackSupervisor.isInLockTaskMode(); 8866 } 8867 } 8868 8869 // ========================================================= 8870 // CONTENT PROVIDERS 8871 // ========================================================= 8872 8873 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8874 List<ProviderInfo> providers = null; 8875 try { 8876 providers = AppGlobals.getPackageManager(). 8877 queryContentProviders(app.processName, app.uid, 8878 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8879 } catch (RemoteException ex) { 8880 } 8881 if (DEBUG_MU) 8882 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8883 int userId = app.userId; 8884 if (providers != null) { 8885 int N = providers.size(); 8886 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8887 for (int i=0; i<N; i++) { 8888 ProviderInfo cpi = 8889 (ProviderInfo)providers.get(i); 8890 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8891 cpi.name, cpi.flags); 8892 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8893 // This is a singleton provider, but a user besides the 8894 // default user is asking to initialize a process it runs 8895 // in... well, no, it doesn't actually run in this process, 8896 // it runs in the process of the default user. Get rid of it. 8897 providers.remove(i); 8898 N--; 8899 i--; 8900 continue; 8901 } 8902 8903 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8904 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8905 if (cpr == null) { 8906 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8907 mProviderMap.putProviderByClass(comp, cpr); 8908 } 8909 if (DEBUG_MU) 8910 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8911 app.pubProviders.put(cpi.name, cpr); 8912 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8913 // Don't add this if it is a platform component that is marked 8914 // to run in multiple processes, because this is actually 8915 // part of the framework so doesn't make sense to track as a 8916 // separate apk in the process. 8917 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8918 mProcessStats); 8919 } 8920 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8921 } 8922 } 8923 return providers; 8924 } 8925 8926 /** 8927 * Check if {@link ProcessRecord} has a possible chance at accessing the 8928 * given {@link ProviderInfo}. Final permission checking is always done 8929 * in {@link ContentProvider}. 8930 */ 8931 private final String checkContentProviderPermissionLocked( 8932 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8933 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8934 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8935 boolean checkedGrants = false; 8936 if (checkUser) { 8937 // Looking for cross-user grants before enforcing the typical cross-users permissions 8938 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8939 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8940 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8941 return null; 8942 } 8943 checkedGrants = true; 8944 } 8945 userId = handleIncomingUser(callingPid, callingUid, userId, 8946 false, ALLOW_NON_FULL, 8947 "checkContentProviderPermissionLocked " + cpi.authority, null); 8948 if (userId != tmpTargetUserId) { 8949 // When we actually went to determine the final targer user ID, this ended 8950 // up different than our initial check for the authority. This is because 8951 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8952 // SELF. So we need to re-check the grants again. 8953 checkedGrants = false; 8954 } 8955 } 8956 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8957 cpi.applicationInfo.uid, cpi.exported) 8958 == PackageManager.PERMISSION_GRANTED) { 8959 return null; 8960 } 8961 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8962 cpi.applicationInfo.uid, cpi.exported) 8963 == PackageManager.PERMISSION_GRANTED) { 8964 return null; 8965 } 8966 8967 PathPermission[] pps = cpi.pathPermissions; 8968 if (pps != null) { 8969 int i = pps.length; 8970 while (i > 0) { 8971 i--; 8972 PathPermission pp = pps[i]; 8973 String pprperm = pp.getReadPermission(); 8974 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8975 cpi.applicationInfo.uid, cpi.exported) 8976 == PackageManager.PERMISSION_GRANTED) { 8977 return null; 8978 } 8979 String ppwperm = pp.getWritePermission(); 8980 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8981 cpi.applicationInfo.uid, cpi.exported) 8982 == PackageManager.PERMISSION_GRANTED) { 8983 return null; 8984 } 8985 } 8986 } 8987 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8988 return null; 8989 } 8990 8991 String msg; 8992 if (!cpi.exported) { 8993 msg = "Permission Denial: opening provider " + cpi.name 8994 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8995 + ", uid=" + callingUid + ") that is not exported from uid " 8996 + cpi.applicationInfo.uid; 8997 } else { 8998 msg = "Permission Denial: opening provider " + cpi.name 8999 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 9000 + ", uid=" + callingUid + ") requires " 9001 + cpi.readPermission + " or " + cpi.writePermission; 9002 } 9003 Slog.w(TAG, msg); 9004 return msg; 9005 } 9006 9007 /** 9008 * Returns if the ContentProvider has granted a uri to callingUid 9009 */ 9010 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 9011 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 9012 if (perms != null) { 9013 for (int i=perms.size()-1; i>=0; i--) { 9014 GrantUri grantUri = perms.keyAt(i); 9015 if (grantUri.sourceUserId == userId || !checkUser) { 9016 if (matchesProvider(grantUri.uri, cpi)) { 9017 return true; 9018 } 9019 } 9020 } 9021 } 9022 return false; 9023 } 9024 9025 /** 9026 * Returns true if the uri authority is one of the authorities specified in the provider. 9027 */ 9028 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 9029 String uriAuth = uri.getAuthority(); 9030 String cpiAuth = cpi.authority; 9031 if (cpiAuth.indexOf(';') == -1) { 9032 return cpiAuth.equals(uriAuth); 9033 } 9034 String[] cpiAuths = cpiAuth.split(";"); 9035 int length = cpiAuths.length; 9036 for (int i = 0; i < length; i++) { 9037 if (cpiAuths[i].equals(uriAuth)) return true; 9038 } 9039 return false; 9040 } 9041 9042 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 9043 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9044 if (r != null) { 9045 for (int i=0; i<r.conProviders.size(); i++) { 9046 ContentProviderConnection conn = r.conProviders.get(i); 9047 if (conn.provider == cpr) { 9048 if (DEBUG_PROVIDER) Slog.v(TAG, 9049 "Adding provider requested by " 9050 + r.processName + " from process " 9051 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9052 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9053 if (stable) { 9054 conn.stableCount++; 9055 conn.numStableIncs++; 9056 } else { 9057 conn.unstableCount++; 9058 conn.numUnstableIncs++; 9059 } 9060 return conn; 9061 } 9062 } 9063 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 9064 if (stable) { 9065 conn.stableCount = 1; 9066 conn.numStableIncs = 1; 9067 } else { 9068 conn.unstableCount = 1; 9069 conn.numUnstableIncs = 1; 9070 } 9071 cpr.connections.add(conn); 9072 r.conProviders.add(conn); 9073 return conn; 9074 } 9075 cpr.addExternalProcessHandleLocked(externalProcessToken); 9076 return null; 9077 } 9078 9079 boolean decProviderCountLocked(ContentProviderConnection conn, 9080 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9081 if (conn != null) { 9082 cpr = conn.provider; 9083 if (DEBUG_PROVIDER) Slog.v(TAG, 9084 "Removing provider requested by " 9085 + conn.client.processName + " from process " 9086 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9087 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9088 if (stable) { 9089 conn.stableCount--; 9090 } else { 9091 conn.unstableCount--; 9092 } 9093 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9094 cpr.connections.remove(conn); 9095 conn.client.conProviders.remove(conn); 9096 return true; 9097 } 9098 return false; 9099 } 9100 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9101 return false; 9102 } 9103 9104 private void checkTime(long startTime, String where) { 9105 long now = SystemClock.elapsedRealtime(); 9106 if ((now-startTime) > 1000) { 9107 // If we are taking more than a second, log about it. 9108 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9109 } 9110 } 9111 9112 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9113 String name, IBinder token, boolean stable, int userId) { 9114 ContentProviderRecord cpr; 9115 ContentProviderConnection conn = null; 9116 ProviderInfo cpi = null; 9117 9118 synchronized(this) { 9119 long startTime = SystemClock.elapsedRealtime(); 9120 9121 ProcessRecord r = null; 9122 if (caller != null) { 9123 r = getRecordForAppLocked(caller); 9124 if (r == null) { 9125 throw new SecurityException( 9126 "Unable to find app for caller " + caller 9127 + " (pid=" + Binder.getCallingPid() 9128 + ") when getting content provider " + name); 9129 } 9130 } 9131 9132 boolean checkCrossUser = true; 9133 9134 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9135 9136 // First check if this content provider has been published... 9137 cpr = mProviderMap.getProviderByName(name, userId); 9138 // If that didn't work, check if it exists for user 0 and then 9139 // verify that it's a singleton provider before using it. 9140 if (cpr == null && userId != UserHandle.USER_OWNER) { 9141 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9142 if (cpr != null) { 9143 cpi = cpr.info; 9144 if (isSingleton(cpi.processName, cpi.applicationInfo, 9145 cpi.name, cpi.flags) 9146 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9147 userId = UserHandle.USER_OWNER; 9148 checkCrossUser = false; 9149 } else { 9150 cpr = null; 9151 cpi = null; 9152 } 9153 } 9154 } 9155 9156 boolean providerRunning = cpr != null; 9157 if (providerRunning) { 9158 cpi = cpr.info; 9159 String msg; 9160 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9161 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9162 != null) { 9163 throw new SecurityException(msg); 9164 } 9165 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9166 9167 if (r != null && cpr.canRunHere(r)) { 9168 // This provider has been published or is in the process 9169 // of being published... but it is also allowed to run 9170 // in the caller's process, so don't make a connection 9171 // and just let the caller instantiate its own instance. 9172 ContentProviderHolder holder = cpr.newHolder(null); 9173 // don't give caller the provider object, it needs 9174 // to make its own. 9175 holder.provider = null; 9176 return holder; 9177 } 9178 9179 final long origId = Binder.clearCallingIdentity(); 9180 9181 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9182 9183 // In this case the provider instance already exists, so we can 9184 // return it right away. 9185 conn = incProviderCountLocked(r, cpr, token, stable); 9186 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9187 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9188 // If this is a perceptible app accessing the provider, 9189 // make sure to count it as being accessed and thus 9190 // back up on the LRU list. This is good because 9191 // content providers are often expensive to start. 9192 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9193 updateLruProcessLocked(cpr.proc, false, null); 9194 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9195 } 9196 } 9197 9198 if (cpr.proc != null) { 9199 if (false) { 9200 if (cpr.name.flattenToShortString().equals( 9201 "com.android.providers.calendar/.CalendarProvider2")) { 9202 Slog.v(TAG, "****************** KILLING " 9203 + cpr.name.flattenToShortString()); 9204 Process.killProcess(cpr.proc.pid); 9205 } 9206 } 9207 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9208 boolean success = updateOomAdjLocked(cpr.proc); 9209 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9210 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9211 // NOTE: there is still a race here where a signal could be 9212 // pending on the process even though we managed to update its 9213 // adj level. Not sure what to do about this, but at least 9214 // the race is now smaller. 9215 if (!success) { 9216 // Uh oh... it looks like the provider's process 9217 // has been killed on us. We need to wait for a new 9218 // process to be started, and make sure its death 9219 // doesn't kill our process. 9220 Slog.i(TAG, 9221 "Existing provider " + cpr.name.flattenToShortString() 9222 + " is crashing; detaching " + r); 9223 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9224 checkTime(startTime, "getContentProviderImpl: before appDied"); 9225 appDiedLocked(cpr.proc); 9226 checkTime(startTime, "getContentProviderImpl: after appDied"); 9227 if (!lastRef) { 9228 // This wasn't the last ref our process had on 9229 // the provider... we have now been killed, bail. 9230 return null; 9231 } 9232 providerRunning = false; 9233 conn = null; 9234 } 9235 } 9236 9237 Binder.restoreCallingIdentity(origId); 9238 } 9239 9240 boolean singleton; 9241 if (!providerRunning) { 9242 try { 9243 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9244 cpi = AppGlobals.getPackageManager(). 9245 resolveContentProvider(name, 9246 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9247 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9248 } catch (RemoteException ex) { 9249 } 9250 if (cpi == null) { 9251 return null; 9252 } 9253 // If the provider is a singleton AND 9254 // (it's a call within the same user || the provider is a 9255 // privileged app) 9256 // Then allow connecting to the singleton provider 9257 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9258 cpi.name, cpi.flags) 9259 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9260 if (singleton) { 9261 userId = UserHandle.USER_OWNER; 9262 } 9263 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9264 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9265 9266 String msg; 9267 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9268 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9269 != null) { 9270 throw new SecurityException(msg); 9271 } 9272 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9273 9274 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9275 && !cpi.processName.equals("system")) { 9276 // If this content provider does not run in the system 9277 // process, and the system is not yet ready to run other 9278 // processes, then fail fast instead of hanging. 9279 throw new IllegalArgumentException( 9280 "Attempt to launch content provider before system ready"); 9281 } 9282 9283 // Make sure that the user who owns this provider is started. If not, 9284 // we don't want to allow it to run. 9285 if (mStartedUsers.get(userId) == null) { 9286 Slog.w(TAG, "Unable to launch app " 9287 + cpi.applicationInfo.packageName + "/" 9288 + cpi.applicationInfo.uid + " for provider " 9289 + name + ": user " + userId + " is stopped"); 9290 return null; 9291 } 9292 9293 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9294 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9295 cpr = mProviderMap.getProviderByClass(comp, userId); 9296 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9297 final boolean firstClass = cpr == null; 9298 if (firstClass) { 9299 try { 9300 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9301 ApplicationInfo ai = 9302 AppGlobals.getPackageManager(). 9303 getApplicationInfo( 9304 cpi.applicationInfo.packageName, 9305 STOCK_PM_FLAGS, userId); 9306 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9307 if (ai == null) { 9308 Slog.w(TAG, "No package info for content provider " 9309 + cpi.name); 9310 return null; 9311 } 9312 ai = getAppInfoForUser(ai, userId); 9313 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9314 } catch (RemoteException ex) { 9315 // pm is in same process, this will never happen. 9316 } 9317 } 9318 9319 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9320 9321 if (r != null && cpr.canRunHere(r)) { 9322 // If this is a multiprocess provider, then just return its 9323 // info and allow the caller to instantiate it. Only do 9324 // this if the provider is the same user as the caller's 9325 // process, or can run as root (so can be in any process). 9326 return cpr.newHolder(null); 9327 } 9328 9329 if (DEBUG_PROVIDER) { 9330 RuntimeException e = new RuntimeException("here"); 9331 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9332 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9333 } 9334 9335 // This is single process, and our app is now connecting to it. 9336 // See if we are already in the process of launching this 9337 // provider. 9338 final int N = mLaunchingProviders.size(); 9339 int i; 9340 for (i=0; i<N; i++) { 9341 if (mLaunchingProviders.get(i) == cpr) { 9342 break; 9343 } 9344 } 9345 9346 // If the provider is not already being launched, then get it 9347 // started. 9348 if (i >= N) { 9349 final long origId = Binder.clearCallingIdentity(); 9350 9351 try { 9352 // Content provider is now in use, its package can't be stopped. 9353 try { 9354 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9355 AppGlobals.getPackageManager().setPackageStoppedState( 9356 cpr.appInfo.packageName, false, userId); 9357 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9358 } catch (RemoteException e) { 9359 } catch (IllegalArgumentException e) { 9360 Slog.w(TAG, "Failed trying to unstop package " 9361 + cpr.appInfo.packageName + ": " + e); 9362 } 9363 9364 // Use existing process if already started 9365 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9366 ProcessRecord proc = getProcessRecordLocked( 9367 cpi.processName, cpr.appInfo.uid, false); 9368 if (proc != null && proc.thread != null) { 9369 if (DEBUG_PROVIDER) { 9370 Slog.d(TAG, "Installing in existing process " + proc); 9371 } 9372 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9373 proc.pubProviders.put(cpi.name, cpr); 9374 try { 9375 proc.thread.scheduleInstallProvider(cpi); 9376 } catch (RemoteException e) { 9377 } 9378 } else { 9379 checkTime(startTime, "getContentProviderImpl: before start process"); 9380 proc = startProcessLocked(cpi.processName, 9381 cpr.appInfo, false, 0, "content provider", 9382 new ComponentName(cpi.applicationInfo.packageName, 9383 cpi.name), false, false, false); 9384 checkTime(startTime, "getContentProviderImpl: after start process"); 9385 if (proc == null) { 9386 Slog.w(TAG, "Unable to launch app " 9387 + cpi.applicationInfo.packageName + "/" 9388 + cpi.applicationInfo.uid + " for provider " 9389 + name + ": process is bad"); 9390 return null; 9391 } 9392 } 9393 cpr.launchingApp = proc; 9394 mLaunchingProviders.add(cpr); 9395 } finally { 9396 Binder.restoreCallingIdentity(origId); 9397 } 9398 } 9399 9400 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9401 9402 // Make sure the provider is published (the same provider class 9403 // may be published under multiple names). 9404 if (firstClass) { 9405 mProviderMap.putProviderByClass(comp, cpr); 9406 } 9407 9408 mProviderMap.putProviderByName(name, cpr); 9409 conn = incProviderCountLocked(r, cpr, token, stable); 9410 if (conn != null) { 9411 conn.waiting = true; 9412 } 9413 } 9414 checkTime(startTime, "getContentProviderImpl: done!"); 9415 } 9416 9417 // Wait for the provider to be published... 9418 synchronized (cpr) { 9419 while (cpr.provider == null) { 9420 if (cpr.launchingApp == null) { 9421 Slog.w(TAG, "Unable to launch app " 9422 + cpi.applicationInfo.packageName + "/" 9423 + cpi.applicationInfo.uid + " for provider " 9424 + name + ": launching app became null"); 9425 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9426 UserHandle.getUserId(cpi.applicationInfo.uid), 9427 cpi.applicationInfo.packageName, 9428 cpi.applicationInfo.uid, name); 9429 return null; 9430 } 9431 try { 9432 if (DEBUG_MU) { 9433 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9434 + cpr.launchingApp); 9435 } 9436 if (conn != null) { 9437 conn.waiting = true; 9438 } 9439 cpr.wait(); 9440 } catch (InterruptedException ex) { 9441 } finally { 9442 if (conn != null) { 9443 conn.waiting = false; 9444 } 9445 } 9446 } 9447 } 9448 return cpr != null ? cpr.newHolder(conn) : null; 9449 } 9450 9451 @Override 9452 public final ContentProviderHolder getContentProvider( 9453 IApplicationThread caller, String name, int userId, boolean stable) { 9454 enforceNotIsolatedCaller("getContentProvider"); 9455 if (caller == null) { 9456 String msg = "null IApplicationThread when getting content provider " 9457 + name; 9458 Slog.w(TAG, msg); 9459 throw new SecurityException(msg); 9460 } 9461 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9462 // with cross-user grant. 9463 return getContentProviderImpl(caller, name, null, stable, userId); 9464 } 9465 9466 public ContentProviderHolder getContentProviderExternal( 9467 String name, int userId, IBinder token) { 9468 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9469 "Do not have permission in call getContentProviderExternal()"); 9470 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9471 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9472 return getContentProviderExternalUnchecked(name, token, userId); 9473 } 9474 9475 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9476 IBinder token, int userId) { 9477 return getContentProviderImpl(null, name, token, true, userId); 9478 } 9479 9480 /** 9481 * Drop a content provider from a ProcessRecord's bookkeeping 9482 */ 9483 public void removeContentProvider(IBinder connection, boolean stable) { 9484 enforceNotIsolatedCaller("removeContentProvider"); 9485 long ident = Binder.clearCallingIdentity(); 9486 try { 9487 synchronized (this) { 9488 ContentProviderConnection conn; 9489 try { 9490 conn = (ContentProviderConnection)connection; 9491 } catch (ClassCastException e) { 9492 String msg ="removeContentProvider: " + connection 9493 + " not a ContentProviderConnection"; 9494 Slog.w(TAG, msg); 9495 throw new IllegalArgumentException(msg); 9496 } 9497 if (conn == null) { 9498 throw new NullPointerException("connection is null"); 9499 } 9500 if (decProviderCountLocked(conn, null, null, stable)) { 9501 updateOomAdjLocked(); 9502 } 9503 } 9504 } finally { 9505 Binder.restoreCallingIdentity(ident); 9506 } 9507 } 9508 9509 public void removeContentProviderExternal(String name, IBinder token) { 9510 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9511 "Do not have permission in call removeContentProviderExternal()"); 9512 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9513 } 9514 9515 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9516 synchronized (this) { 9517 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9518 if(cpr == null) { 9519 //remove from mProvidersByClass 9520 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9521 return; 9522 } 9523 9524 //update content provider record entry info 9525 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9526 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9527 if (localCpr.hasExternalProcessHandles()) { 9528 if (localCpr.removeExternalProcessHandleLocked(token)) { 9529 updateOomAdjLocked(); 9530 } else { 9531 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9532 + " with no external reference for token: " 9533 + token + "."); 9534 } 9535 } else { 9536 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9537 + " with no external references."); 9538 } 9539 } 9540 } 9541 9542 public final void publishContentProviders(IApplicationThread caller, 9543 List<ContentProviderHolder> providers) { 9544 if (providers == null) { 9545 return; 9546 } 9547 9548 enforceNotIsolatedCaller("publishContentProviders"); 9549 synchronized (this) { 9550 final ProcessRecord r = getRecordForAppLocked(caller); 9551 if (DEBUG_MU) 9552 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9553 if (r == null) { 9554 throw new SecurityException( 9555 "Unable to find app for caller " + caller 9556 + " (pid=" + Binder.getCallingPid() 9557 + ") when publishing content providers"); 9558 } 9559 9560 final long origId = Binder.clearCallingIdentity(); 9561 9562 final int N = providers.size(); 9563 for (int i=0; i<N; i++) { 9564 ContentProviderHolder src = providers.get(i); 9565 if (src == null || src.info == null || src.provider == null) { 9566 continue; 9567 } 9568 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9569 if (DEBUG_MU) 9570 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9571 if (dst != null) { 9572 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9573 mProviderMap.putProviderByClass(comp, dst); 9574 String names[] = dst.info.authority.split(";"); 9575 for (int j = 0; j < names.length; j++) { 9576 mProviderMap.putProviderByName(names[j], dst); 9577 } 9578 9579 int NL = mLaunchingProviders.size(); 9580 int j; 9581 for (j=0; j<NL; j++) { 9582 if (mLaunchingProviders.get(j) == dst) { 9583 mLaunchingProviders.remove(j); 9584 j--; 9585 NL--; 9586 } 9587 } 9588 synchronized (dst) { 9589 dst.provider = src.provider; 9590 dst.proc = r; 9591 dst.notifyAll(); 9592 } 9593 updateOomAdjLocked(r); 9594 } 9595 } 9596 9597 Binder.restoreCallingIdentity(origId); 9598 } 9599 } 9600 9601 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9602 ContentProviderConnection conn; 9603 try { 9604 conn = (ContentProviderConnection)connection; 9605 } catch (ClassCastException e) { 9606 String msg ="refContentProvider: " + connection 9607 + " not a ContentProviderConnection"; 9608 Slog.w(TAG, msg); 9609 throw new IllegalArgumentException(msg); 9610 } 9611 if (conn == null) { 9612 throw new NullPointerException("connection is null"); 9613 } 9614 9615 synchronized (this) { 9616 if (stable > 0) { 9617 conn.numStableIncs += stable; 9618 } 9619 stable = conn.stableCount + stable; 9620 if (stable < 0) { 9621 throw new IllegalStateException("stableCount < 0: " + stable); 9622 } 9623 9624 if (unstable > 0) { 9625 conn.numUnstableIncs += unstable; 9626 } 9627 unstable = conn.unstableCount + unstable; 9628 if (unstable < 0) { 9629 throw new IllegalStateException("unstableCount < 0: " + unstable); 9630 } 9631 9632 if ((stable+unstable) <= 0) { 9633 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9634 + stable + " unstable=" + unstable); 9635 } 9636 conn.stableCount = stable; 9637 conn.unstableCount = unstable; 9638 return !conn.dead; 9639 } 9640 } 9641 9642 public void unstableProviderDied(IBinder connection) { 9643 ContentProviderConnection conn; 9644 try { 9645 conn = (ContentProviderConnection)connection; 9646 } catch (ClassCastException e) { 9647 String msg ="refContentProvider: " + connection 9648 + " not a ContentProviderConnection"; 9649 Slog.w(TAG, msg); 9650 throw new IllegalArgumentException(msg); 9651 } 9652 if (conn == null) { 9653 throw new NullPointerException("connection is null"); 9654 } 9655 9656 // Safely retrieve the content provider associated with the connection. 9657 IContentProvider provider; 9658 synchronized (this) { 9659 provider = conn.provider.provider; 9660 } 9661 9662 if (provider == null) { 9663 // Um, yeah, we're way ahead of you. 9664 return; 9665 } 9666 9667 // Make sure the caller is being honest with us. 9668 if (provider.asBinder().pingBinder()) { 9669 // Er, no, still looks good to us. 9670 synchronized (this) { 9671 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9672 + " says " + conn + " died, but we don't agree"); 9673 return; 9674 } 9675 } 9676 9677 // Well look at that! It's dead! 9678 synchronized (this) { 9679 if (conn.provider.provider != provider) { 9680 // But something changed... good enough. 9681 return; 9682 } 9683 9684 ProcessRecord proc = conn.provider.proc; 9685 if (proc == null || proc.thread == null) { 9686 // Seems like the process is already cleaned up. 9687 return; 9688 } 9689 9690 // As far as we're concerned, this is just like receiving a 9691 // death notification... just a bit prematurely. 9692 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9693 + ") early provider death"); 9694 final long ident = Binder.clearCallingIdentity(); 9695 try { 9696 appDiedLocked(proc); 9697 } finally { 9698 Binder.restoreCallingIdentity(ident); 9699 } 9700 } 9701 } 9702 9703 @Override 9704 public void appNotRespondingViaProvider(IBinder connection) { 9705 enforceCallingPermission( 9706 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9707 9708 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9709 if (conn == null) { 9710 Slog.w(TAG, "ContentProviderConnection is null"); 9711 return; 9712 } 9713 9714 final ProcessRecord host = conn.provider.proc; 9715 if (host == null) { 9716 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9717 return; 9718 } 9719 9720 final long token = Binder.clearCallingIdentity(); 9721 try { 9722 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9723 } finally { 9724 Binder.restoreCallingIdentity(token); 9725 } 9726 } 9727 9728 public final void installSystemProviders() { 9729 List<ProviderInfo> providers; 9730 synchronized (this) { 9731 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9732 providers = generateApplicationProvidersLocked(app); 9733 if (providers != null) { 9734 for (int i=providers.size()-1; i>=0; i--) { 9735 ProviderInfo pi = (ProviderInfo)providers.get(i); 9736 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9737 Slog.w(TAG, "Not installing system proc provider " + pi.name 9738 + ": not system .apk"); 9739 providers.remove(i); 9740 } 9741 } 9742 } 9743 } 9744 if (providers != null) { 9745 mSystemThread.installSystemProviders(providers); 9746 } 9747 9748 mCoreSettingsObserver = new CoreSettingsObserver(this); 9749 9750 //mUsageStatsService.monitorPackages(); 9751 } 9752 9753 /** 9754 * Allows apps to retrieve the MIME type of a URI. 9755 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9756 * users, then it does not need permission to access the ContentProvider. 9757 * Either, it needs cross-user uri grants. 9758 * 9759 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9760 * 9761 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9762 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9763 */ 9764 public String getProviderMimeType(Uri uri, int userId) { 9765 enforceNotIsolatedCaller("getProviderMimeType"); 9766 final String name = uri.getAuthority(); 9767 int callingUid = Binder.getCallingUid(); 9768 int callingPid = Binder.getCallingPid(); 9769 long ident = 0; 9770 boolean clearedIdentity = false; 9771 userId = unsafeConvertIncomingUser(userId); 9772 if (canClearIdentity(callingPid, callingUid, userId)) { 9773 clearedIdentity = true; 9774 ident = Binder.clearCallingIdentity(); 9775 } 9776 ContentProviderHolder holder = null; 9777 try { 9778 holder = getContentProviderExternalUnchecked(name, null, userId); 9779 if (holder != null) { 9780 return holder.provider.getType(uri); 9781 } 9782 } catch (RemoteException e) { 9783 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9784 return null; 9785 } finally { 9786 // We need to clear the identity to call removeContentProviderExternalUnchecked 9787 if (!clearedIdentity) { 9788 ident = Binder.clearCallingIdentity(); 9789 } 9790 try { 9791 if (holder != null) { 9792 removeContentProviderExternalUnchecked(name, null, userId); 9793 } 9794 } finally { 9795 Binder.restoreCallingIdentity(ident); 9796 } 9797 } 9798 9799 return null; 9800 } 9801 9802 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 9803 if (UserHandle.getUserId(callingUid) == userId) { 9804 return true; 9805 } 9806 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9807 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9808 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9809 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9810 return true; 9811 } 9812 return false; 9813 } 9814 9815 // ========================================================= 9816 // GLOBAL MANAGEMENT 9817 // ========================================================= 9818 9819 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9820 boolean isolated, int isolatedUid) { 9821 String proc = customProcess != null ? customProcess : info.processName; 9822 BatteryStatsImpl.Uid.Proc ps = null; 9823 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9824 int uid = info.uid; 9825 if (isolated) { 9826 if (isolatedUid == 0) { 9827 int userId = UserHandle.getUserId(uid); 9828 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9829 while (true) { 9830 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9831 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9832 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9833 } 9834 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9835 mNextIsolatedProcessUid++; 9836 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9837 // No process for this uid, use it. 9838 break; 9839 } 9840 stepsLeft--; 9841 if (stepsLeft <= 0) { 9842 return null; 9843 } 9844 } 9845 } else { 9846 // Special case for startIsolatedProcess (internal only), where 9847 // the uid of the isolated process is specified by the caller. 9848 uid = isolatedUid; 9849 } 9850 } 9851 return new ProcessRecord(stats, info, proc, uid); 9852 } 9853 9854 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9855 String abiOverride) { 9856 ProcessRecord app; 9857 if (!isolated) { 9858 app = getProcessRecordLocked(info.processName, info.uid, true); 9859 } else { 9860 app = null; 9861 } 9862 9863 if (app == null) { 9864 app = newProcessRecordLocked(info, null, isolated, 0); 9865 mProcessNames.put(info.processName, app.uid, app); 9866 if (isolated) { 9867 mIsolatedProcesses.put(app.uid, app); 9868 } 9869 updateLruProcessLocked(app, false, null); 9870 updateOomAdjLocked(); 9871 } 9872 9873 // This package really, really can not be stopped. 9874 try { 9875 AppGlobals.getPackageManager().setPackageStoppedState( 9876 info.packageName, false, UserHandle.getUserId(app.uid)); 9877 } catch (RemoteException e) { 9878 } catch (IllegalArgumentException e) { 9879 Slog.w(TAG, "Failed trying to unstop package " 9880 + info.packageName + ": " + e); 9881 } 9882 9883 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9884 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9885 app.persistent = true; 9886 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9887 } 9888 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9889 mPersistentStartingProcesses.add(app); 9890 startProcessLocked(app, "added application", app.processName, abiOverride, 9891 null /* entryPoint */, null /* entryPointArgs */); 9892 } 9893 9894 return app; 9895 } 9896 9897 public void unhandledBack() { 9898 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9899 "unhandledBack()"); 9900 9901 synchronized(this) { 9902 final long origId = Binder.clearCallingIdentity(); 9903 try { 9904 getFocusedStack().unhandledBackLocked(); 9905 } finally { 9906 Binder.restoreCallingIdentity(origId); 9907 } 9908 } 9909 } 9910 9911 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9912 enforceNotIsolatedCaller("openContentUri"); 9913 final int userId = UserHandle.getCallingUserId(); 9914 String name = uri.getAuthority(); 9915 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9916 ParcelFileDescriptor pfd = null; 9917 if (cph != null) { 9918 // We record the binder invoker's uid in thread-local storage before 9919 // going to the content provider to open the file. Later, in the code 9920 // that handles all permissions checks, we look for this uid and use 9921 // that rather than the Activity Manager's own uid. The effect is that 9922 // we do the check against the caller's permissions even though it looks 9923 // to the content provider like the Activity Manager itself is making 9924 // the request. 9925 sCallerIdentity.set(new Identity( 9926 Binder.getCallingPid(), Binder.getCallingUid())); 9927 try { 9928 pfd = cph.provider.openFile(null, uri, "r", null); 9929 } catch (FileNotFoundException e) { 9930 // do nothing; pfd will be returned null 9931 } finally { 9932 // Ensure that whatever happens, we clean up the identity state 9933 sCallerIdentity.remove(); 9934 } 9935 9936 // We've got the fd now, so we're done with the provider. 9937 removeContentProviderExternalUnchecked(name, null, userId); 9938 } else { 9939 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9940 } 9941 return pfd; 9942 } 9943 9944 // Actually is sleeping or shutting down or whatever else in the future 9945 // is an inactive state. 9946 public boolean isSleepingOrShuttingDown() { 9947 return isSleeping() || mShuttingDown; 9948 } 9949 9950 public boolean isSleeping() { 9951 return mSleeping; 9952 } 9953 9954 void goingToSleep() { 9955 synchronized(this) { 9956 mWentToSleep = true; 9957 goToSleepIfNeededLocked(); 9958 } 9959 } 9960 9961 void finishRunningVoiceLocked() { 9962 if (mRunningVoice) { 9963 mRunningVoice = false; 9964 goToSleepIfNeededLocked(); 9965 } 9966 } 9967 9968 void goToSleepIfNeededLocked() { 9969 if (mWentToSleep && !mRunningVoice) { 9970 if (!mSleeping) { 9971 mSleeping = true; 9972 mStackSupervisor.goingToSleepLocked(); 9973 9974 // Initialize the wake times of all processes. 9975 checkExcessivePowerUsageLocked(false); 9976 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9977 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9978 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9979 } 9980 } 9981 } 9982 9983 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9984 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9985 // Never persist the home stack. 9986 return; 9987 } 9988 mTaskPersister.wakeup(task, flush); 9989 } 9990 9991 @Override 9992 public boolean shutdown(int timeout) { 9993 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9994 != PackageManager.PERMISSION_GRANTED) { 9995 throw new SecurityException("Requires permission " 9996 + android.Manifest.permission.SHUTDOWN); 9997 } 9998 9999 boolean timedout = false; 10000 10001 synchronized(this) { 10002 mShuttingDown = true; 10003 updateEventDispatchingLocked(); 10004 timedout = mStackSupervisor.shutdownLocked(timeout); 10005 } 10006 10007 mAppOpsService.shutdown(); 10008 if (mUsageStatsService != null) { 10009 mUsageStatsService.prepareShutdown(); 10010 } 10011 mBatteryStatsService.shutdown(); 10012 synchronized (this) { 10013 mProcessStats.shutdownLocked(); 10014 } 10015 notifyTaskPersisterLocked(null, true); 10016 10017 return timedout; 10018 } 10019 10020 public final void activitySlept(IBinder token) { 10021 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 10022 10023 final long origId = Binder.clearCallingIdentity(); 10024 10025 synchronized (this) { 10026 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10027 if (r != null) { 10028 mStackSupervisor.activitySleptLocked(r); 10029 } 10030 } 10031 10032 Binder.restoreCallingIdentity(origId); 10033 } 10034 10035 void logLockScreen(String msg) { 10036 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 10037 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 10038 mWentToSleep + " mSleeping=" + mSleeping); 10039 } 10040 10041 private void comeOutOfSleepIfNeededLocked() { 10042 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 10043 if (mSleeping) { 10044 mSleeping = false; 10045 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 10046 } 10047 } 10048 } 10049 10050 void wakingUp() { 10051 synchronized(this) { 10052 mWentToSleep = false; 10053 comeOutOfSleepIfNeededLocked(); 10054 } 10055 } 10056 10057 void startRunningVoiceLocked() { 10058 if (!mRunningVoice) { 10059 mRunningVoice = true; 10060 comeOutOfSleepIfNeededLocked(); 10061 } 10062 } 10063 10064 private void updateEventDispatchingLocked() { 10065 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 10066 } 10067 10068 public void setLockScreenShown(boolean shown) { 10069 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 10070 != PackageManager.PERMISSION_GRANTED) { 10071 throw new SecurityException("Requires permission " 10072 + android.Manifest.permission.DEVICE_POWER); 10073 } 10074 10075 synchronized(this) { 10076 long ident = Binder.clearCallingIdentity(); 10077 try { 10078 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10079 mLockScreenShown = shown; 10080 comeOutOfSleepIfNeededLocked(); 10081 } finally { 10082 Binder.restoreCallingIdentity(ident); 10083 } 10084 } 10085 } 10086 10087 @Override 10088 public void stopAppSwitches() { 10089 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10090 != PackageManager.PERMISSION_GRANTED) { 10091 throw new SecurityException("Requires permission " 10092 + android.Manifest.permission.STOP_APP_SWITCHES); 10093 } 10094 10095 synchronized(this) { 10096 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10097 + APP_SWITCH_DELAY_TIME; 10098 mDidAppSwitch = false; 10099 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10100 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10101 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10102 } 10103 } 10104 10105 public void resumeAppSwitches() { 10106 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10107 != PackageManager.PERMISSION_GRANTED) { 10108 throw new SecurityException("Requires permission " 10109 + android.Manifest.permission.STOP_APP_SWITCHES); 10110 } 10111 10112 synchronized(this) { 10113 // Note that we don't execute any pending app switches... we will 10114 // let those wait until either the timeout, or the next start 10115 // activity request. 10116 mAppSwitchesAllowedTime = 0; 10117 } 10118 } 10119 10120 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 10121 int callingPid, int callingUid, String name) { 10122 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10123 return true; 10124 } 10125 10126 int perm = checkComponentPermission( 10127 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 10128 sourceUid, -1, true); 10129 if (perm == PackageManager.PERMISSION_GRANTED) { 10130 return true; 10131 } 10132 10133 // If the actual IPC caller is different from the logical source, then 10134 // also see if they are allowed to control app switches. 10135 if (callingUid != -1 && callingUid != sourceUid) { 10136 perm = checkComponentPermission( 10137 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10138 callingUid, -1, true); 10139 if (perm == PackageManager.PERMISSION_GRANTED) { 10140 return true; 10141 } 10142 } 10143 10144 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 10145 return false; 10146 } 10147 10148 public void setDebugApp(String packageName, boolean waitForDebugger, 10149 boolean persistent) { 10150 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10151 "setDebugApp()"); 10152 10153 long ident = Binder.clearCallingIdentity(); 10154 try { 10155 // Note that this is not really thread safe if there are multiple 10156 // callers into it at the same time, but that's not a situation we 10157 // care about. 10158 if (persistent) { 10159 final ContentResolver resolver = mContext.getContentResolver(); 10160 Settings.Global.putString( 10161 resolver, Settings.Global.DEBUG_APP, 10162 packageName); 10163 Settings.Global.putInt( 10164 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10165 waitForDebugger ? 1 : 0); 10166 } 10167 10168 synchronized (this) { 10169 if (!persistent) { 10170 mOrigDebugApp = mDebugApp; 10171 mOrigWaitForDebugger = mWaitForDebugger; 10172 } 10173 mDebugApp = packageName; 10174 mWaitForDebugger = waitForDebugger; 10175 mDebugTransient = !persistent; 10176 if (packageName != null) { 10177 forceStopPackageLocked(packageName, -1, false, false, true, true, 10178 false, UserHandle.USER_ALL, "set debug app"); 10179 } 10180 } 10181 } finally { 10182 Binder.restoreCallingIdentity(ident); 10183 } 10184 } 10185 10186 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10187 synchronized (this) { 10188 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10189 if (!isDebuggable) { 10190 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10191 throw new SecurityException("Process not debuggable: " + app.packageName); 10192 } 10193 } 10194 10195 mOpenGlTraceApp = processName; 10196 } 10197 } 10198 10199 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10200 synchronized (this) { 10201 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10202 if (!isDebuggable) { 10203 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10204 throw new SecurityException("Process not debuggable: " + app.packageName); 10205 } 10206 } 10207 mProfileApp = processName; 10208 mProfileFile = profilerInfo.profileFile; 10209 if (mProfileFd != null) { 10210 try { 10211 mProfileFd.close(); 10212 } catch (IOException e) { 10213 } 10214 mProfileFd = null; 10215 } 10216 mProfileFd = profilerInfo.profileFd; 10217 mSamplingInterval = profilerInfo.samplingInterval; 10218 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10219 mProfileType = 0; 10220 } 10221 } 10222 10223 @Override 10224 public void setAlwaysFinish(boolean enabled) { 10225 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10226 "setAlwaysFinish()"); 10227 10228 Settings.Global.putInt( 10229 mContext.getContentResolver(), 10230 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10231 10232 synchronized (this) { 10233 mAlwaysFinishActivities = enabled; 10234 } 10235 } 10236 10237 @Override 10238 public void setActivityController(IActivityController controller) { 10239 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10240 "setActivityController()"); 10241 synchronized (this) { 10242 mController = controller; 10243 Watchdog.getInstance().setActivityController(controller); 10244 } 10245 } 10246 10247 @Override 10248 public void setUserIsMonkey(boolean userIsMonkey) { 10249 synchronized (this) { 10250 synchronized (mPidsSelfLocked) { 10251 final int callingPid = Binder.getCallingPid(); 10252 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10253 if (precessRecord == null) { 10254 throw new SecurityException("Unknown process: " + callingPid); 10255 } 10256 if (precessRecord.instrumentationUiAutomationConnection == null) { 10257 throw new SecurityException("Only an instrumentation process " 10258 + "with a UiAutomation can call setUserIsMonkey"); 10259 } 10260 } 10261 mUserIsMonkey = userIsMonkey; 10262 } 10263 } 10264 10265 @Override 10266 public boolean isUserAMonkey() { 10267 synchronized (this) { 10268 // If there is a controller also implies the user is a monkey. 10269 return (mUserIsMonkey || mController != null); 10270 } 10271 } 10272 10273 public void requestBugReport() { 10274 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10275 SystemProperties.set("ctl.start", "bugreport"); 10276 } 10277 10278 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10279 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10280 } 10281 10282 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10283 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10284 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10285 } 10286 return KEY_DISPATCHING_TIMEOUT; 10287 } 10288 10289 @Override 10290 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10291 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10292 != PackageManager.PERMISSION_GRANTED) { 10293 throw new SecurityException("Requires permission " 10294 + android.Manifest.permission.FILTER_EVENTS); 10295 } 10296 ProcessRecord proc; 10297 long timeout; 10298 synchronized (this) { 10299 synchronized (mPidsSelfLocked) { 10300 proc = mPidsSelfLocked.get(pid); 10301 } 10302 timeout = getInputDispatchingTimeoutLocked(proc); 10303 } 10304 10305 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10306 return -1; 10307 } 10308 10309 return timeout; 10310 } 10311 10312 /** 10313 * Handle input dispatching timeouts. 10314 * Returns whether input dispatching should be aborted or not. 10315 */ 10316 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10317 final ActivityRecord activity, final ActivityRecord parent, 10318 final boolean aboveSystem, String reason) { 10319 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10320 != PackageManager.PERMISSION_GRANTED) { 10321 throw new SecurityException("Requires permission " 10322 + android.Manifest.permission.FILTER_EVENTS); 10323 } 10324 10325 final String annotation; 10326 if (reason == null) { 10327 annotation = "Input dispatching timed out"; 10328 } else { 10329 annotation = "Input dispatching timed out (" + reason + ")"; 10330 } 10331 10332 if (proc != null) { 10333 synchronized (this) { 10334 if (proc.debugging) { 10335 return false; 10336 } 10337 10338 if (mDidDexOpt) { 10339 // Give more time since we were dexopting. 10340 mDidDexOpt = false; 10341 return false; 10342 } 10343 10344 if (proc.instrumentationClass != null) { 10345 Bundle info = new Bundle(); 10346 info.putString("shortMsg", "keyDispatchingTimedOut"); 10347 info.putString("longMsg", annotation); 10348 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10349 return true; 10350 } 10351 } 10352 mHandler.post(new Runnable() { 10353 @Override 10354 public void run() { 10355 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10356 } 10357 }); 10358 } 10359 10360 return true; 10361 } 10362 10363 public Bundle getAssistContextExtras(int requestType) { 10364 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10365 "getAssistContextExtras()"); 10366 PendingAssistExtras pae; 10367 Bundle extras = new Bundle(); 10368 synchronized (this) { 10369 ActivityRecord activity = getFocusedStack().mResumedActivity; 10370 if (activity == null) { 10371 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10372 return null; 10373 } 10374 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10375 if (activity.app == null || activity.app.thread == null) { 10376 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10377 return extras; 10378 } 10379 if (activity.app.pid == Binder.getCallingPid()) { 10380 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10381 return extras; 10382 } 10383 pae = new PendingAssistExtras(activity); 10384 try { 10385 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10386 requestType); 10387 mPendingAssistExtras.add(pae); 10388 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10389 } catch (RemoteException e) { 10390 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10391 return extras; 10392 } 10393 } 10394 synchronized (pae) { 10395 while (!pae.haveResult) { 10396 try { 10397 pae.wait(); 10398 } catch (InterruptedException e) { 10399 } 10400 } 10401 if (pae.result != null) { 10402 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10403 } 10404 } 10405 synchronized (this) { 10406 mPendingAssistExtras.remove(pae); 10407 mHandler.removeCallbacks(pae); 10408 } 10409 return extras; 10410 } 10411 10412 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10413 PendingAssistExtras pae = (PendingAssistExtras)token; 10414 synchronized (pae) { 10415 pae.result = extras; 10416 pae.haveResult = true; 10417 pae.notifyAll(); 10418 } 10419 } 10420 10421 public void registerProcessObserver(IProcessObserver observer) { 10422 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10423 "registerProcessObserver()"); 10424 synchronized (this) { 10425 mProcessObservers.register(observer); 10426 } 10427 } 10428 10429 @Override 10430 public void unregisterProcessObserver(IProcessObserver observer) { 10431 synchronized (this) { 10432 mProcessObservers.unregister(observer); 10433 } 10434 } 10435 10436 @Override 10437 public boolean convertFromTranslucent(IBinder token) { 10438 final long origId = Binder.clearCallingIdentity(); 10439 try { 10440 synchronized (this) { 10441 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10442 if (r == null) { 10443 return false; 10444 } 10445 final boolean translucentChanged = r.changeWindowTranslucency(true); 10446 if (translucentChanged) { 10447 r.task.stack.releaseBackgroundResources(); 10448 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10449 } 10450 mWindowManager.setAppFullscreen(token, true); 10451 return translucentChanged; 10452 } 10453 } finally { 10454 Binder.restoreCallingIdentity(origId); 10455 } 10456 } 10457 10458 @Override 10459 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10460 final long origId = Binder.clearCallingIdentity(); 10461 try { 10462 synchronized (this) { 10463 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10464 if (r == null) { 10465 return false; 10466 } 10467 int index = r.task.mActivities.lastIndexOf(r); 10468 if (index > 0) { 10469 ActivityRecord under = r.task.mActivities.get(index - 1); 10470 under.returningOptions = options; 10471 } 10472 final boolean translucentChanged = r.changeWindowTranslucency(false); 10473 if (translucentChanged) { 10474 r.task.stack.convertToTranslucent(r); 10475 } 10476 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10477 mWindowManager.setAppFullscreen(token, false); 10478 return translucentChanged; 10479 } 10480 } finally { 10481 Binder.restoreCallingIdentity(origId); 10482 } 10483 } 10484 10485 @Override 10486 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10487 final long origId = Binder.clearCallingIdentity(); 10488 try { 10489 synchronized (this) { 10490 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10491 if (r != null) { 10492 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10493 } 10494 } 10495 return false; 10496 } finally { 10497 Binder.restoreCallingIdentity(origId); 10498 } 10499 } 10500 10501 @Override 10502 public boolean isBackgroundVisibleBehind(IBinder token) { 10503 final long origId = Binder.clearCallingIdentity(); 10504 try { 10505 synchronized (this) { 10506 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10507 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10508 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10509 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10510 return visible; 10511 } 10512 } finally { 10513 Binder.restoreCallingIdentity(origId); 10514 } 10515 } 10516 10517 @Override 10518 public ActivityOptions getActivityOptions(IBinder token) { 10519 final long origId = Binder.clearCallingIdentity(); 10520 try { 10521 synchronized (this) { 10522 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10523 if (r != null) { 10524 final ActivityOptions activityOptions = r.pendingOptions; 10525 r.pendingOptions = null; 10526 return activityOptions; 10527 } 10528 return null; 10529 } 10530 } finally { 10531 Binder.restoreCallingIdentity(origId); 10532 } 10533 } 10534 10535 @Override 10536 public void setImmersive(IBinder token, boolean immersive) { 10537 synchronized(this) { 10538 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10539 if (r == null) { 10540 throw new IllegalArgumentException(); 10541 } 10542 r.immersive = immersive; 10543 10544 // update associated state if we're frontmost 10545 if (r == mFocusedActivity) { 10546 if (DEBUG_IMMERSIVE) { 10547 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10548 } 10549 applyUpdateLockStateLocked(r); 10550 } 10551 } 10552 } 10553 10554 @Override 10555 public boolean isImmersive(IBinder token) { 10556 synchronized (this) { 10557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10558 if (r == null) { 10559 throw new IllegalArgumentException(); 10560 } 10561 return r.immersive; 10562 } 10563 } 10564 10565 public boolean isTopActivityImmersive() { 10566 enforceNotIsolatedCaller("startActivity"); 10567 synchronized (this) { 10568 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10569 return (r != null) ? r.immersive : false; 10570 } 10571 } 10572 10573 @Override 10574 public boolean isTopOfTask(IBinder token) { 10575 synchronized (this) { 10576 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10577 if (r == null) { 10578 throw new IllegalArgumentException(); 10579 } 10580 return r.task.getTopActivity() == r; 10581 } 10582 } 10583 10584 public final void enterSafeMode() { 10585 synchronized(this) { 10586 // It only makes sense to do this before the system is ready 10587 // and started launching other packages. 10588 if (!mSystemReady) { 10589 try { 10590 AppGlobals.getPackageManager().enterSafeMode(); 10591 } catch (RemoteException e) { 10592 } 10593 } 10594 10595 mSafeMode = true; 10596 } 10597 } 10598 10599 public final void showSafeModeOverlay() { 10600 View v = LayoutInflater.from(mContext).inflate( 10601 com.android.internal.R.layout.safe_mode, null); 10602 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10603 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10604 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10605 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10606 lp.gravity = Gravity.BOTTOM | Gravity.START; 10607 lp.format = v.getBackground().getOpacity(); 10608 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10609 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10610 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10611 ((WindowManager)mContext.getSystemService( 10612 Context.WINDOW_SERVICE)).addView(v, lp); 10613 } 10614 10615 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10616 if (!(sender instanceof PendingIntentRecord)) { 10617 return; 10618 } 10619 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10620 synchronized (stats) { 10621 if (mBatteryStatsService.isOnBattery()) { 10622 mBatteryStatsService.enforceCallingPermission(); 10623 PendingIntentRecord rec = (PendingIntentRecord)sender; 10624 int MY_UID = Binder.getCallingUid(); 10625 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10626 BatteryStatsImpl.Uid.Pkg pkg = 10627 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10628 sourcePkg != null ? sourcePkg : rec.key.packageName); 10629 pkg.incWakeupsLocked(); 10630 } 10631 } 10632 } 10633 10634 public boolean killPids(int[] pids, String pReason, boolean secure) { 10635 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10636 throw new SecurityException("killPids only available to the system"); 10637 } 10638 String reason = (pReason == null) ? "Unknown" : pReason; 10639 // XXX Note: don't acquire main activity lock here, because the window 10640 // manager calls in with its locks held. 10641 10642 boolean killed = false; 10643 synchronized (mPidsSelfLocked) { 10644 int[] types = new int[pids.length]; 10645 int worstType = 0; 10646 for (int i=0; i<pids.length; i++) { 10647 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10648 if (proc != null) { 10649 int type = proc.setAdj; 10650 types[i] = type; 10651 if (type > worstType) { 10652 worstType = type; 10653 } 10654 } 10655 } 10656 10657 // If the worst oom_adj is somewhere in the cached proc LRU range, 10658 // then constrain it so we will kill all cached procs. 10659 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10660 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10661 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10662 } 10663 10664 // If this is not a secure call, don't let it kill processes that 10665 // are important. 10666 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10667 worstType = ProcessList.SERVICE_ADJ; 10668 } 10669 10670 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10671 for (int i=0; i<pids.length; i++) { 10672 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10673 if (proc == null) { 10674 continue; 10675 } 10676 int adj = proc.setAdj; 10677 if (adj >= worstType && !proc.killedByAm) { 10678 proc.kill(reason, true); 10679 killed = true; 10680 } 10681 } 10682 } 10683 return killed; 10684 } 10685 10686 @Override 10687 public void killUid(int uid, String reason) { 10688 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10689 throw new SecurityException("killUid only available to the system"); 10690 } 10691 synchronized (this) { 10692 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10693 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10694 reason != null ? reason : "kill uid"); 10695 } 10696 } 10697 10698 @Override 10699 public boolean killProcessesBelowForeground(String reason) { 10700 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10701 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10702 } 10703 10704 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10705 } 10706 10707 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10708 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10709 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10710 } 10711 10712 boolean killed = false; 10713 synchronized (mPidsSelfLocked) { 10714 final int size = mPidsSelfLocked.size(); 10715 for (int i = 0; i < size; i++) { 10716 final int pid = mPidsSelfLocked.keyAt(i); 10717 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10718 if (proc == null) continue; 10719 10720 final int adj = proc.setAdj; 10721 if (adj > belowAdj && !proc.killedByAm) { 10722 proc.kill(reason, true); 10723 killed = true; 10724 } 10725 } 10726 } 10727 return killed; 10728 } 10729 10730 @Override 10731 public void hang(final IBinder who, boolean allowRestart) { 10732 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10733 != PackageManager.PERMISSION_GRANTED) { 10734 throw new SecurityException("Requires permission " 10735 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10736 } 10737 10738 final IBinder.DeathRecipient death = new DeathRecipient() { 10739 @Override 10740 public void binderDied() { 10741 synchronized (this) { 10742 notifyAll(); 10743 } 10744 } 10745 }; 10746 10747 try { 10748 who.linkToDeath(death, 0); 10749 } catch (RemoteException e) { 10750 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10751 return; 10752 } 10753 10754 synchronized (this) { 10755 Watchdog.getInstance().setAllowRestart(allowRestart); 10756 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10757 synchronized (death) { 10758 while (who.isBinderAlive()) { 10759 try { 10760 death.wait(); 10761 } catch (InterruptedException e) { 10762 } 10763 } 10764 } 10765 Watchdog.getInstance().setAllowRestart(true); 10766 } 10767 } 10768 10769 @Override 10770 public void restart() { 10771 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10772 != PackageManager.PERMISSION_GRANTED) { 10773 throw new SecurityException("Requires permission " 10774 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10775 } 10776 10777 Log.i(TAG, "Sending shutdown broadcast..."); 10778 10779 BroadcastReceiver br = new BroadcastReceiver() { 10780 @Override public void onReceive(Context context, Intent intent) { 10781 // Now the broadcast is done, finish up the low-level shutdown. 10782 Log.i(TAG, "Shutting down activity manager..."); 10783 shutdown(10000); 10784 Log.i(TAG, "Shutdown complete, restarting!"); 10785 Process.killProcess(Process.myPid()); 10786 System.exit(10); 10787 } 10788 }; 10789 10790 // First send the high-level shut down broadcast. 10791 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10792 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10793 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10794 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10795 mContext.sendOrderedBroadcastAsUser(intent, 10796 UserHandle.ALL, null, br, mHandler, 0, null, null); 10797 */ 10798 br.onReceive(mContext, intent); 10799 } 10800 10801 private long getLowRamTimeSinceIdle(long now) { 10802 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10803 } 10804 10805 @Override 10806 public void performIdleMaintenance() { 10807 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10808 != PackageManager.PERMISSION_GRANTED) { 10809 throw new SecurityException("Requires permission " 10810 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10811 } 10812 10813 synchronized (this) { 10814 final long now = SystemClock.uptimeMillis(); 10815 final long timeSinceLastIdle = now - mLastIdleTime; 10816 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10817 mLastIdleTime = now; 10818 mLowRamTimeSinceLastIdle = 0; 10819 if (mLowRamStartTime != 0) { 10820 mLowRamStartTime = now; 10821 } 10822 10823 StringBuilder sb = new StringBuilder(128); 10824 sb.append("Idle maintenance over "); 10825 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10826 sb.append(" low RAM for "); 10827 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10828 Slog.i(TAG, sb.toString()); 10829 10830 // If at least 1/3 of our time since the last idle period has been spent 10831 // with RAM low, then we want to kill processes. 10832 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10833 10834 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10835 ProcessRecord proc = mLruProcesses.get(i); 10836 if (proc.notCachedSinceIdle) { 10837 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10838 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10839 if (doKilling && proc.initialIdlePss != 0 10840 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10841 proc.kill("idle maint (pss " + proc.lastPss 10842 + " from " + proc.initialIdlePss + ")", true); 10843 } 10844 } 10845 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10846 proc.notCachedSinceIdle = true; 10847 proc.initialIdlePss = 0; 10848 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10849 isSleeping(), now); 10850 } 10851 } 10852 10853 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10854 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10855 } 10856 } 10857 10858 private void retrieveSettings() { 10859 final ContentResolver resolver = mContext.getContentResolver(); 10860 String debugApp = Settings.Global.getString( 10861 resolver, Settings.Global.DEBUG_APP); 10862 boolean waitForDebugger = Settings.Global.getInt( 10863 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10864 boolean alwaysFinishActivities = Settings.Global.getInt( 10865 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10866 boolean forceRtl = Settings.Global.getInt( 10867 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10868 // Transfer any global setting for forcing RTL layout, into a System Property 10869 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10870 10871 Configuration configuration = new Configuration(); 10872 Settings.System.getConfiguration(resolver, configuration); 10873 if (forceRtl) { 10874 // This will take care of setting the correct layout direction flags 10875 configuration.setLayoutDirection(configuration.locale); 10876 } 10877 10878 synchronized (this) { 10879 mDebugApp = mOrigDebugApp = debugApp; 10880 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10881 mAlwaysFinishActivities = alwaysFinishActivities; 10882 // This happens before any activities are started, so we can 10883 // change mConfiguration in-place. 10884 updateConfigurationLocked(configuration, null, false, true); 10885 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10886 } 10887 } 10888 10889 /** Loads resources after the current configuration has been set. */ 10890 private void loadResourcesOnSystemReady() { 10891 final Resources res = mContext.getResources(); 10892 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10893 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10894 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10895 } 10896 10897 public boolean testIsSystemReady() { 10898 // no need to synchronize(this) just to read & return the value 10899 return mSystemReady; 10900 } 10901 10902 private static File getCalledPreBootReceiversFile() { 10903 File dataDir = Environment.getDataDirectory(); 10904 File systemDir = new File(dataDir, "system"); 10905 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10906 return fname; 10907 } 10908 10909 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10910 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10911 File file = getCalledPreBootReceiversFile(); 10912 FileInputStream fis = null; 10913 try { 10914 fis = new FileInputStream(file); 10915 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10916 int fvers = dis.readInt(); 10917 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10918 String vers = dis.readUTF(); 10919 String codename = dis.readUTF(); 10920 String build = dis.readUTF(); 10921 if (android.os.Build.VERSION.RELEASE.equals(vers) 10922 && android.os.Build.VERSION.CODENAME.equals(codename) 10923 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10924 int num = dis.readInt(); 10925 while (num > 0) { 10926 num--; 10927 String pkg = dis.readUTF(); 10928 String cls = dis.readUTF(); 10929 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10930 } 10931 } 10932 } 10933 } catch (FileNotFoundException e) { 10934 } catch (IOException e) { 10935 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10936 } finally { 10937 if (fis != null) { 10938 try { 10939 fis.close(); 10940 } catch (IOException e) { 10941 } 10942 } 10943 } 10944 return lastDoneReceivers; 10945 } 10946 10947 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10948 File file = getCalledPreBootReceiversFile(); 10949 FileOutputStream fos = null; 10950 DataOutputStream dos = null; 10951 try { 10952 fos = new FileOutputStream(file); 10953 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10954 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10955 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10956 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10957 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10958 dos.writeInt(list.size()); 10959 for (int i=0; i<list.size(); i++) { 10960 dos.writeUTF(list.get(i).getPackageName()); 10961 dos.writeUTF(list.get(i).getClassName()); 10962 } 10963 } catch (IOException e) { 10964 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10965 file.delete(); 10966 } finally { 10967 FileUtils.sync(fos); 10968 if (dos != null) { 10969 try { 10970 dos.close(); 10971 } catch (IOException e) { 10972 // TODO Auto-generated catch block 10973 e.printStackTrace(); 10974 } 10975 } 10976 } 10977 } 10978 10979 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10980 ArrayList<ComponentName> doneReceivers, int userId) { 10981 boolean waitingUpdate = false; 10982 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10983 List<ResolveInfo> ris = null; 10984 try { 10985 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10986 intent, null, 0, userId); 10987 } catch (RemoteException e) { 10988 } 10989 if (ris != null) { 10990 for (int i=ris.size()-1; i>=0; i--) { 10991 if ((ris.get(i).activityInfo.applicationInfo.flags 10992 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10993 ris.remove(i); 10994 } 10995 } 10996 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10997 10998 // For User 0, load the version number. When delivering to a new user, deliver 10999 // to all receivers. 11000 if (userId == UserHandle.USER_OWNER) { 11001 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 11002 for (int i=0; i<ris.size(); i++) { 11003 ActivityInfo ai = ris.get(i).activityInfo; 11004 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11005 if (lastDoneReceivers.contains(comp)) { 11006 // We already did the pre boot receiver for this app with the current 11007 // platform version, so don't do it again... 11008 ris.remove(i); 11009 i--; 11010 // ...however, do keep it as one that has been done, so we don't 11011 // forget about it when rewriting the file of last done receivers. 11012 doneReceivers.add(comp); 11013 } 11014 } 11015 } 11016 11017 // If primary user, send broadcast to all available users, else just to userId 11018 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 11019 : new int[] { userId }; 11020 for (int i = 0; i < ris.size(); i++) { 11021 ActivityInfo ai = ris.get(i).activityInfo; 11022 ComponentName comp = new ComponentName(ai.packageName, ai.name); 11023 doneReceivers.add(comp); 11024 intent.setComponent(comp); 11025 for (int j=0; j<users.length; j++) { 11026 IIntentReceiver finisher = null; 11027 // On last receiver and user, set up a completion callback 11028 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 11029 finisher = new IIntentReceiver.Stub() { 11030 public void performReceive(Intent intent, int resultCode, 11031 String data, Bundle extras, boolean ordered, 11032 boolean sticky, int sendingUser) { 11033 // The raw IIntentReceiver interface is called 11034 // with the AM lock held, so redispatch to 11035 // execute our code without the lock. 11036 mHandler.post(onFinishCallback); 11037 } 11038 }; 11039 } 11040 Slog.i(TAG, "Sending system update to " + intent.getComponent() 11041 + " for user " + users[j]); 11042 broadcastIntentLocked(null, null, intent, null, finisher, 11043 0, null, null, null, AppOpsManager.OP_NONE, 11044 true, false, MY_PID, Process.SYSTEM_UID, 11045 users[j]); 11046 if (finisher != null) { 11047 waitingUpdate = true; 11048 } 11049 } 11050 } 11051 } 11052 11053 return waitingUpdate; 11054 } 11055 11056 public void systemReady(final Runnable goingCallback) { 11057 synchronized(this) { 11058 if (mSystemReady) { 11059 // If we're done calling all the receivers, run the next "boot phase" passed in 11060 // by the SystemServer 11061 if (goingCallback != null) { 11062 goingCallback.run(); 11063 } 11064 return; 11065 } 11066 11067 // Make sure we have the current profile info, since it is needed for 11068 // security checks. 11069 updateCurrentProfileIdsLocked(); 11070 11071 if (mRecentTasks == null) { 11072 mRecentTasks = mTaskPersister.restoreTasksLocked(); 11073 if (!mRecentTasks.isEmpty()) { 11074 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 11075 } 11076 cleanupRecentTasksLocked(UserHandle.USER_ALL); 11077 mTaskPersister.startPersisting(); 11078 } 11079 11080 // Check to see if there are any update receivers to run. 11081 if (!mDidUpdate) { 11082 if (mWaitingUpdate) { 11083 return; 11084 } 11085 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11086 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11087 public void run() { 11088 synchronized (ActivityManagerService.this) { 11089 mDidUpdate = true; 11090 } 11091 writeLastDonePreBootReceivers(doneReceivers); 11092 showBootMessage(mContext.getText( 11093 R.string.android_upgrading_complete), 11094 false); 11095 systemReady(goingCallback); 11096 } 11097 }, doneReceivers, UserHandle.USER_OWNER); 11098 11099 if (mWaitingUpdate) { 11100 return; 11101 } 11102 mDidUpdate = true; 11103 } 11104 11105 mAppOpsService.systemReady(); 11106 mSystemReady = true; 11107 } 11108 11109 ArrayList<ProcessRecord> procsToKill = null; 11110 synchronized(mPidsSelfLocked) { 11111 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11112 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11113 if (!isAllowedWhileBooting(proc.info)){ 11114 if (procsToKill == null) { 11115 procsToKill = new ArrayList<ProcessRecord>(); 11116 } 11117 procsToKill.add(proc); 11118 } 11119 } 11120 } 11121 11122 synchronized(this) { 11123 if (procsToKill != null) { 11124 for (int i=procsToKill.size()-1; i>=0; i--) { 11125 ProcessRecord proc = procsToKill.get(i); 11126 Slog.i(TAG, "Removing system update proc: " + proc); 11127 removeProcessLocked(proc, true, false, "system update done"); 11128 } 11129 } 11130 11131 // Now that we have cleaned up any update processes, we 11132 // are ready to start launching real processes and know that 11133 // we won't trample on them any more. 11134 mProcessesReady = true; 11135 } 11136 11137 Slog.i(TAG, "System now ready"); 11138 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11139 SystemClock.uptimeMillis()); 11140 11141 synchronized(this) { 11142 // Make sure we have no pre-ready processes sitting around. 11143 11144 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11145 ResolveInfo ri = mContext.getPackageManager() 11146 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11147 STOCK_PM_FLAGS); 11148 CharSequence errorMsg = null; 11149 if (ri != null) { 11150 ActivityInfo ai = ri.activityInfo; 11151 ApplicationInfo app = ai.applicationInfo; 11152 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11153 mTopAction = Intent.ACTION_FACTORY_TEST; 11154 mTopData = null; 11155 mTopComponent = new ComponentName(app.packageName, 11156 ai.name); 11157 } else { 11158 errorMsg = mContext.getResources().getText( 11159 com.android.internal.R.string.factorytest_not_system); 11160 } 11161 } else { 11162 errorMsg = mContext.getResources().getText( 11163 com.android.internal.R.string.factorytest_no_action); 11164 } 11165 if (errorMsg != null) { 11166 mTopAction = null; 11167 mTopData = null; 11168 mTopComponent = null; 11169 Message msg = Message.obtain(); 11170 msg.what = SHOW_FACTORY_ERROR_MSG; 11171 msg.getData().putCharSequence("msg", errorMsg); 11172 mHandler.sendMessage(msg); 11173 } 11174 } 11175 } 11176 11177 retrieveSettings(); 11178 loadResourcesOnSystemReady(); 11179 11180 synchronized (this) { 11181 readGrantedUriPermissionsLocked(); 11182 } 11183 11184 if (goingCallback != null) goingCallback.run(); 11185 11186 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11187 Integer.toString(mCurrentUserId), mCurrentUserId); 11188 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11189 Integer.toString(mCurrentUserId), mCurrentUserId); 11190 mSystemServiceManager.startUser(mCurrentUserId); 11191 11192 synchronized (this) { 11193 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11194 try { 11195 List apps = AppGlobals.getPackageManager(). 11196 getPersistentApplications(STOCK_PM_FLAGS); 11197 if (apps != null) { 11198 int N = apps.size(); 11199 int i; 11200 for (i=0; i<N; i++) { 11201 ApplicationInfo info 11202 = (ApplicationInfo)apps.get(i); 11203 if (info != null && 11204 !info.packageName.equals("android")) { 11205 addAppLocked(info, false, null /* ABI override */); 11206 } 11207 } 11208 } 11209 } catch (RemoteException ex) { 11210 // pm is in same process, this will never happen. 11211 } 11212 } 11213 11214 // Start up initial activity. 11215 mBooting = true; 11216 11217 try { 11218 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11219 Message msg = Message.obtain(); 11220 msg.what = SHOW_UID_ERROR_MSG; 11221 mHandler.sendMessage(msg); 11222 } 11223 } catch (RemoteException e) { 11224 } 11225 11226 long ident = Binder.clearCallingIdentity(); 11227 try { 11228 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11229 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11230 | Intent.FLAG_RECEIVER_FOREGROUND); 11231 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11232 broadcastIntentLocked(null, null, intent, 11233 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11234 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11235 intent = new Intent(Intent.ACTION_USER_STARTING); 11236 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11237 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11238 broadcastIntentLocked(null, null, intent, 11239 null, new IIntentReceiver.Stub() { 11240 @Override 11241 public void performReceive(Intent intent, int resultCode, String data, 11242 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11243 throws RemoteException { 11244 } 11245 }, 0, null, null, 11246 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11247 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11248 } catch (Throwable t) { 11249 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11250 } finally { 11251 Binder.restoreCallingIdentity(ident); 11252 } 11253 mStackSupervisor.resumeTopActivitiesLocked(); 11254 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11255 } 11256 } 11257 11258 private boolean makeAppCrashingLocked(ProcessRecord app, 11259 String shortMsg, String longMsg, String stackTrace) { 11260 app.crashing = true; 11261 app.crashingReport = generateProcessError(app, 11262 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11263 startAppProblemLocked(app); 11264 app.stopFreezingAllLocked(); 11265 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11266 } 11267 11268 private void makeAppNotRespondingLocked(ProcessRecord app, 11269 String activity, String shortMsg, String longMsg) { 11270 app.notResponding = true; 11271 app.notRespondingReport = generateProcessError(app, 11272 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11273 activity, shortMsg, longMsg, null); 11274 startAppProblemLocked(app); 11275 app.stopFreezingAllLocked(); 11276 } 11277 11278 /** 11279 * Generate a process error record, suitable for attachment to a ProcessRecord. 11280 * 11281 * @param app The ProcessRecord in which the error occurred. 11282 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11283 * ActivityManager.AppErrorStateInfo 11284 * @param activity The activity associated with the crash, if known. 11285 * @param shortMsg Short message describing the crash. 11286 * @param longMsg Long message describing the crash. 11287 * @param stackTrace Full crash stack trace, may be null. 11288 * 11289 * @return Returns a fully-formed AppErrorStateInfo record. 11290 */ 11291 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11292 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11293 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11294 11295 report.condition = condition; 11296 report.processName = app.processName; 11297 report.pid = app.pid; 11298 report.uid = app.info.uid; 11299 report.tag = activity; 11300 report.shortMsg = shortMsg; 11301 report.longMsg = longMsg; 11302 report.stackTrace = stackTrace; 11303 11304 return report; 11305 } 11306 11307 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11308 synchronized (this) { 11309 app.crashing = false; 11310 app.crashingReport = null; 11311 app.notResponding = false; 11312 app.notRespondingReport = null; 11313 if (app.anrDialog == fromDialog) { 11314 app.anrDialog = null; 11315 } 11316 if (app.waitDialog == fromDialog) { 11317 app.waitDialog = null; 11318 } 11319 if (app.pid > 0 && app.pid != MY_PID) { 11320 handleAppCrashLocked(app, null, null, null); 11321 app.kill("user request after error", true); 11322 } 11323 } 11324 } 11325 11326 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11327 String stackTrace) { 11328 long now = SystemClock.uptimeMillis(); 11329 11330 Long crashTime; 11331 if (!app.isolated) { 11332 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11333 } else { 11334 crashTime = null; 11335 } 11336 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11337 // This process loses! 11338 Slog.w(TAG, "Process " + app.info.processName 11339 + " has crashed too many times: killing!"); 11340 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11341 app.userId, app.info.processName, app.uid); 11342 mStackSupervisor.handleAppCrashLocked(app); 11343 if (!app.persistent) { 11344 // We don't want to start this process again until the user 11345 // explicitly does so... but for persistent process, we really 11346 // need to keep it running. If a persistent process is actually 11347 // repeatedly crashing, then badness for everyone. 11348 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11349 app.info.processName); 11350 if (!app.isolated) { 11351 // XXX We don't have a way to mark isolated processes 11352 // as bad, since they don't have a peristent identity. 11353 mBadProcesses.put(app.info.processName, app.uid, 11354 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11355 mProcessCrashTimes.remove(app.info.processName, app.uid); 11356 } 11357 app.bad = true; 11358 app.removed = true; 11359 // Don't let services in this process be restarted and potentially 11360 // annoy the user repeatedly. Unless it is persistent, since those 11361 // processes run critical code. 11362 removeProcessLocked(app, false, false, "crash"); 11363 mStackSupervisor.resumeTopActivitiesLocked(); 11364 return false; 11365 } 11366 mStackSupervisor.resumeTopActivitiesLocked(); 11367 } else { 11368 mStackSupervisor.finishTopRunningActivityLocked(app); 11369 } 11370 11371 // Bump up the crash count of any services currently running in the proc. 11372 for (int i=app.services.size()-1; i>=0; i--) { 11373 // Any services running in the application need to be placed 11374 // back in the pending list. 11375 ServiceRecord sr = app.services.valueAt(i); 11376 sr.crashCount++; 11377 } 11378 11379 // If the crashing process is what we consider to be the "home process" and it has been 11380 // replaced by a third-party app, clear the package preferred activities from packages 11381 // with a home activity running in the process to prevent a repeatedly crashing app 11382 // from blocking the user to manually clear the list. 11383 final ArrayList<ActivityRecord> activities = app.activities; 11384 if (app == mHomeProcess && activities.size() > 0 11385 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11386 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11387 final ActivityRecord r = activities.get(activityNdx); 11388 if (r.isHomeActivity()) { 11389 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11390 try { 11391 ActivityThread.getPackageManager() 11392 .clearPackagePreferredActivities(r.packageName); 11393 } catch (RemoteException c) { 11394 // pm is in same process, this will never happen. 11395 } 11396 } 11397 } 11398 } 11399 11400 if (!app.isolated) { 11401 // XXX Can't keep track of crash times for isolated processes, 11402 // because they don't have a perisistent identity. 11403 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11404 } 11405 11406 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11407 return true; 11408 } 11409 11410 void startAppProblemLocked(ProcessRecord app) { 11411 // If this app is not running under the current user, then we 11412 // can't give it a report button because that would require 11413 // launching the report UI under a different user. 11414 app.errorReportReceiver = null; 11415 11416 for (int userId : mCurrentProfileIds) { 11417 if (app.userId == userId) { 11418 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11419 mContext, app.info.packageName, app.info.flags); 11420 } 11421 } 11422 skipCurrentReceiverLocked(app); 11423 } 11424 11425 void skipCurrentReceiverLocked(ProcessRecord app) { 11426 for (BroadcastQueue queue : mBroadcastQueues) { 11427 queue.skipCurrentReceiverLocked(app); 11428 } 11429 } 11430 11431 /** 11432 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11433 * The application process will exit immediately after this call returns. 11434 * @param app object of the crashing app, null for the system server 11435 * @param crashInfo describing the exception 11436 */ 11437 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11438 ProcessRecord r = findAppProcess(app, "Crash"); 11439 final String processName = app == null ? "system_server" 11440 : (r == null ? "unknown" : r.processName); 11441 11442 handleApplicationCrashInner("crash", r, processName, crashInfo); 11443 } 11444 11445 /* Native crash reporting uses this inner version because it needs to be somewhat 11446 * decoupled from the AM-managed cleanup lifecycle 11447 */ 11448 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11449 ApplicationErrorReport.CrashInfo crashInfo) { 11450 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11451 UserHandle.getUserId(Binder.getCallingUid()), processName, 11452 r == null ? -1 : r.info.flags, 11453 crashInfo.exceptionClassName, 11454 crashInfo.exceptionMessage, 11455 crashInfo.throwFileName, 11456 crashInfo.throwLineNumber); 11457 11458 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11459 11460 crashApplication(r, crashInfo); 11461 } 11462 11463 public void handleApplicationStrictModeViolation( 11464 IBinder app, 11465 int violationMask, 11466 StrictMode.ViolationInfo info) { 11467 ProcessRecord r = findAppProcess(app, "StrictMode"); 11468 if (r == null) { 11469 return; 11470 } 11471 11472 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11473 Integer stackFingerprint = info.hashCode(); 11474 boolean logIt = true; 11475 synchronized (mAlreadyLoggedViolatedStacks) { 11476 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11477 logIt = false; 11478 // TODO: sub-sample into EventLog for these, with 11479 // the info.durationMillis? Then we'd get 11480 // the relative pain numbers, without logging all 11481 // the stack traces repeatedly. We'd want to do 11482 // likewise in the client code, which also does 11483 // dup suppression, before the Binder call. 11484 } else { 11485 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11486 mAlreadyLoggedViolatedStacks.clear(); 11487 } 11488 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11489 } 11490 } 11491 if (logIt) { 11492 logStrictModeViolationToDropBox(r, info); 11493 } 11494 } 11495 11496 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11497 AppErrorResult result = new AppErrorResult(); 11498 synchronized (this) { 11499 final long origId = Binder.clearCallingIdentity(); 11500 11501 Message msg = Message.obtain(); 11502 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11503 HashMap<String, Object> data = new HashMap<String, Object>(); 11504 data.put("result", result); 11505 data.put("app", r); 11506 data.put("violationMask", violationMask); 11507 data.put("info", info); 11508 msg.obj = data; 11509 mHandler.sendMessage(msg); 11510 11511 Binder.restoreCallingIdentity(origId); 11512 } 11513 int res = result.get(); 11514 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11515 } 11516 } 11517 11518 // Depending on the policy in effect, there could be a bunch of 11519 // these in quick succession so we try to batch these together to 11520 // minimize disk writes, number of dropbox entries, and maximize 11521 // compression, by having more fewer, larger records. 11522 private void logStrictModeViolationToDropBox( 11523 ProcessRecord process, 11524 StrictMode.ViolationInfo info) { 11525 if (info == null) { 11526 return; 11527 } 11528 final boolean isSystemApp = process == null || 11529 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11530 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11531 final String processName = process == null ? "unknown" : process.processName; 11532 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11533 final DropBoxManager dbox = (DropBoxManager) 11534 mContext.getSystemService(Context.DROPBOX_SERVICE); 11535 11536 // Exit early if the dropbox isn't configured to accept this report type. 11537 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11538 11539 boolean bufferWasEmpty; 11540 boolean needsFlush; 11541 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11542 synchronized (sb) { 11543 bufferWasEmpty = sb.length() == 0; 11544 appendDropBoxProcessHeaders(process, processName, sb); 11545 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11546 sb.append("System-App: ").append(isSystemApp).append("\n"); 11547 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11548 if (info.violationNumThisLoop != 0) { 11549 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11550 } 11551 if (info.numAnimationsRunning != 0) { 11552 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11553 } 11554 if (info.broadcastIntentAction != null) { 11555 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11556 } 11557 if (info.durationMillis != -1) { 11558 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11559 } 11560 if (info.numInstances != -1) { 11561 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11562 } 11563 if (info.tags != null) { 11564 for (String tag : info.tags) { 11565 sb.append("Span-Tag: ").append(tag).append("\n"); 11566 } 11567 } 11568 sb.append("\n"); 11569 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11570 sb.append(info.crashInfo.stackTrace); 11571 } 11572 sb.append("\n"); 11573 11574 // Only buffer up to ~64k. Various logging bits truncate 11575 // things at 128k. 11576 needsFlush = (sb.length() > 64 * 1024); 11577 } 11578 11579 // Flush immediately if the buffer's grown too large, or this 11580 // is a non-system app. Non-system apps are isolated with a 11581 // different tag & policy and not batched. 11582 // 11583 // Batching is useful during internal testing with 11584 // StrictMode settings turned up high. Without batching, 11585 // thousands of separate files could be created on boot. 11586 if (!isSystemApp || needsFlush) { 11587 new Thread("Error dump: " + dropboxTag) { 11588 @Override 11589 public void run() { 11590 String report; 11591 synchronized (sb) { 11592 report = sb.toString(); 11593 sb.delete(0, sb.length()); 11594 sb.trimToSize(); 11595 } 11596 if (report.length() != 0) { 11597 dbox.addText(dropboxTag, report); 11598 } 11599 } 11600 }.start(); 11601 return; 11602 } 11603 11604 // System app batching: 11605 if (!bufferWasEmpty) { 11606 // An existing dropbox-writing thread is outstanding, so 11607 // we don't need to start it up. The existing thread will 11608 // catch the buffer appends we just did. 11609 return; 11610 } 11611 11612 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11613 // (After this point, we shouldn't access AMS internal data structures.) 11614 new Thread("Error dump: " + dropboxTag) { 11615 @Override 11616 public void run() { 11617 // 5 second sleep to let stacks arrive and be batched together 11618 try { 11619 Thread.sleep(5000); // 5 seconds 11620 } catch (InterruptedException e) {} 11621 11622 String errorReport; 11623 synchronized (mStrictModeBuffer) { 11624 errorReport = mStrictModeBuffer.toString(); 11625 if (errorReport.length() == 0) { 11626 return; 11627 } 11628 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11629 mStrictModeBuffer.trimToSize(); 11630 } 11631 dbox.addText(dropboxTag, errorReport); 11632 } 11633 }.start(); 11634 } 11635 11636 /** 11637 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11638 * @param app object of the crashing app, null for the system server 11639 * @param tag reported by the caller 11640 * @param system whether this wtf is coming from the system 11641 * @param crashInfo describing the context of the error 11642 * @return true if the process should exit immediately (WTF is fatal) 11643 */ 11644 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11645 final ApplicationErrorReport.CrashInfo crashInfo) { 11646 final ProcessRecord r = findAppProcess(app, "WTF"); 11647 final String processName = app == null ? "system_server" 11648 : (r == null ? "unknown" : r.processName); 11649 11650 EventLog.writeEvent(EventLogTags.AM_WTF, 11651 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11652 processName, 11653 r == null ? -1 : r.info.flags, 11654 tag, crashInfo.exceptionMessage); 11655 11656 if (system) { 11657 // If this is coming from the system, we could very well have low-level 11658 // system locks held, so we want to do this all asynchronously. And we 11659 // never want this to become fatal, so there is that too. 11660 mHandler.post(new Runnable() { 11661 @Override public void run() { 11662 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11663 crashInfo); 11664 } 11665 }); 11666 return false; 11667 } 11668 11669 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11670 11671 if (r != null && r.pid != Process.myPid() && 11672 Settings.Global.getInt(mContext.getContentResolver(), 11673 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11674 crashApplication(r, crashInfo); 11675 return true; 11676 } else { 11677 return false; 11678 } 11679 } 11680 11681 /** 11682 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11683 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11684 */ 11685 private ProcessRecord findAppProcess(IBinder app, String reason) { 11686 if (app == null) { 11687 return null; 11688 } 11689 11690 synchronized (this) { 11691 final int NP = mProcessNames.getMap().size(); 11692 for (int ip=0; ip<NP; ip++) { 11693 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11694 final int NA = apps.size(); 11695 for (int ia=0; ia<NA; ia++) { 11696 ProcessRecord p = apps.valueAt(ia); 11697 if (p.thread != null && p.thread.asBinder() == app) { 11698 return p; 11699 } 11700 } 11701 } 11702 11703 Slog.w(TAG, "Can't find mystery application for " + reason 11704 + " from pid=" + Binder.getCallingPid() 11705 + " uid=" + Binder.getCallingUid() + ": " + app); 11706 return null; 11707 } 11708 } 11709 11710 /** 11711 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11712 * to append various headers to the dropbox log text. 11713 */ 11714 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11715 StringBuilder sb) { 11716 // Watchdog thread ends up invoking this function (with 11717 // a null ProcessRecord) to add the stack file to dropbox. 11718 // Do not acquire a lock on this (am) in such cases, as it 11719 // could cause a potential deadlock, if and when watchdog 11720 // is invoked due to unavailability of lock on am and it 11721 // would prevent watchdog from killing system_server. 11722 if (process == null) { 11723 sb.append("Process: ").append(processName).append("\n"); 11724 return; 11725 } 11726 // Note: ProcessRecord 'process' is guarded by the service 11727 // instance. (notably process.pkgList, which could otherwise change 11728 // concurrently during execution of this method) 11729 synchronized (this) { 11730 sb.append("Process: ").append(processName).append("\n"); 11731 int flags = process.info.flags; 11732 IPackageManager pm = AppGlobals.getPackageManager(); 11733 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11734 for (int ip=0; ip<process.pkgList.size(); ip++) { 11735 String pkg = process.pkgList.keyAt(ip); 11736 sb.append("Package: ").append(pkg); 11737 try { 11738 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11739 if (pi != null) { 11740 sb.append(" v").append(pi.versionCode); 11741 if (pi.versionName != null) { 11742 sb.append(" (").append(pi.versionName).append(")"); 11743 } 11744 } 11745 } catch (RemoteException e) { 11746 Slog.e(TAG, "Error getting package info: " + pkg, e); 11747 } 11748 sb.append("\n"); 11749 } 11750 } 11751 } 11752 11753 private static String processClass(ProcessRecord process) { 11754 if (process == null || process.pid == MY_PID) { 11755 return "system_server"; 11756 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11757 return "system_app"; 11758 } else { 11759 return "data_app"; 11760 } 11761 } 11762 11763 /** 11764 * Write a description of an error (crash, WTF, ANR) to the drop box. 11765 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11766 * @param process which caused the error, null means the system server 11767 * @param activity which triggered the error, null if unknown 11768 * @param parent activity related to the error, null if unknown 11769 * @param subject line related to the error, null if absent 11770 * @param report in long form describing the error, null if absent 11771 * @param logFile to include in the report, null if none 11772 * @param crashInfo giving an application stack trace, null if absent 11773 */ 11774 public void addErrorToDropBox(String eventType, 11775 ProcessRecord process, String processName, ActivityRecord activity, 11776 ActivityRecord parent, String subject, 11777 final String report, final File logFile, 11778 final ApplicationErrorReport.CrashInfo crashInfo) { 11779 // NOTE -- this must never acquire the ActivityManagerService lock, 11780 // otherwise the watchdog may be prevented from resetting the system. 11781 11782 final String dropboxTag = processClass(process) + "_" + eventType; 11783 final DropBoxManager dbox = (DropBoxManager) 11784 mContext.getSystemService(Context.DROPBOX_SERVICE); 11785 11786 // Exit early if the dropbox isn't configured to accept this report type. 11787 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11788 11789 final StringBuilder sb = new StringBuilder(1024); 11790 appendDropBoxProcessHeaders(process, processName, sb); 11791 if (activity != null) { 11792 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11793 } 11794 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11795 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11796 } 11797 if (parent != null && parent != activity) { 11798 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11799 } 11800 if (subject != null) { 11801 sb.append("Subject: ").append(subject).append("\n"); 11802 } 11803 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11804 if (Debug.isDebuggerConnected()) { 11805 sb.append("Debugger: Connected\n"); 11806 } 11807 sb.append("\n"); 11808 11809 // Do the rest in a worker thread to avoid blocking the caller on I/O 11810 // (After this point, we shouldn't access AMS internal data structures.) 11811 Thread worker = new Thread("Error dump: " + dropboxTag) { 11812 @Override 11813 public void run() { 11814 if (report != null) { 11815 sb.append(report); 11816 } 11817 if (logFile != null) { 11818 try { 11819 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11820 "\n\n[[TRUNCATED]]")); 11821 } catch (IOException e) { 11822 Slog.e(TAG, "Error reading " + logFile, e); 11823 } 11824 } 11825 if (crashInfo != null && crashInfo.stackTrace != null) { 11826 sb.append(crashInfo.stackTrace); 11827 } 11828 11829 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11830 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11831 if (lines > 0) { 11832 sb.append("\n"); 11833 11834 // Merge several logcat streams, and take the last N lines 11835 InputStreamReader input = null; 11836 try { 11837 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11838 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11839 "-b", "crash", 11840 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11841 11842 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11843 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11844 input = new InputStreamReader(logcat.getInputStream()); 11845 11846 int num; 11847 char[] buf = new char[8192]; 11848 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11849 } catch (IOException e) { 11850 Slog.e(TAG, "Error running logcat", e); 11851 } finally { 11852 if (input != null) try { input.close(); } catch (IOException e) {} 11853 } 11854 } 11855 11856 dbox.addText(dropboxTag, sb.toString()); 11857 } 11858 }; 11859 11860 if (process == null) { 11861 // If process is null, we are being called from some internal code 11862 // and may be about to die -- run this synchronously. 11863 worker.run(); 11864 } else { 11865 worker.start(); 11866 } 11867 } 11868 11869 /** 11870 * Bring up the "unexpected error" dialog box for a crashing app. 11871 * Deal with edge cases (intercepts from instrumented applications, 11872 * ActivityController, error intent receivers, that sort of thing). 11873 * @param r the application crashing 11874 * @param crashInfo describing the failure 11875 */ 11876 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11877 long timeMillis = System.currentTimeMillis(); 11878 String shortMsg = crashInfo.exceptionClassName; 11879 String longMsg = crashInfo.exceptionMessage; 11880 String stackTrace = crashInfo.stackTrace; 11881 if (shortMsg != null && longMsg != null) { 11882 longMsg = shortMsg + ": " + longMsg; 11883 } else if (shortMsg != null) { 11884 longMsg = shortMsg; 11885 } 11886 11887 AppErrorResult result = new AppErrorResult(); 11888 synchronized (this) { 11889 if (mController != null) { 11890 try { 11891 String name = r != null ? r.processName : null; 11892 int pid = r != null ? r.pid : Binder.getCallingPid(); 11893 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11894 if (!mController.appCrashed(name, pid, 11895 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11896 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11897 && "Native crash".equals(crashInfo.exceptionClassName)) { 11898 Slog.w(TAG, "Skip killing native crashed app " + name 11899 + "(" + pid + ") during testing"); 11900 } else { 11901 Slog.w(TAG, "Force-killing crashed app " + name 11902 + " at watcher's request"); 11903 if (r != null) { 11904 r.kill("crash", true); 11905 } else { 11906 // Huh. 11907 Process.killProcess(pid); 11908 Process.killProcessGroup(uid, pid); 11909 } 11910 } 11911 return; 11912 } 11913 } catch (RemoteException e) { 11914 mController = null; 11915 Watchdog.getInstance().setActivityController(null); 11916 } 11917 } 11918 11919 final long origId = Binder.clearCallingIdentity(); 11920 11921 // If this process is running instrumentation, finish it. 11922 if (r != null && r.instrumentationClass != null) { 11923 Slog.w(TAG, "Error in app " + r.processName 11924 + " running instrumentation " + r.instrumentationClass + ":"); 11925 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11926 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11927 Bundle info = new Bundle(); 11928 info.putString("shortMsg", shortMsg); 11929 info.putString("longMsg", longMsg); 11930 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11931 Binder.restoreCallingIdentity(origId); 11932 return; 11933 } 11934 11935 // If we can't identify the process or it's already exceeded its crash quota, 11936 // quit right away without showing a crash dialog. 11937 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11938 Binder.restoreCallingIdentity(origId); 11939 return; 11940 } 11941 11942 Message msg = Message.obtain(); 11943 msg.what = SHOW_ERROR_MSG; 11944 HashMap data = new HashMap(); 11945 data.put("result", result); 11946 data.put("app", r); 11947 msg.obj = data; 11948 mHandler.sendMessage(msg); 11949 11950 Binder.restoreCallingIdentity(origId); 11951 } 11952 11953 int res = result.get(); 11954 11955 Intent appErrorIntent = null; 11956 synchronized (this) { 11957 if (r != null && !r.isolated) { 11958 // XXX Can't keep track of crash time for isolated processes, 11959 // since they don't have a persistent identity. 11960 mProcessCrashTimes.put(r.info.processName, r.uid, 11961 SystemClock.uptimeMillis()); 11962 } 11963 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11964 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11965 } 11966 } 11967 11968 if (appErrorIntent != null) { 11969 try { 11970 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11971 } catch (ActivityNotFoundException e) { 11972 Slog.w(TAG, "bug report receiver dissappeared", e); 11973 } 11974 } 11975 } 11976 11977 Intent createAppErrorIntentLocked(ProcessRecord r, 11978 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11979 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11980 if (report == null) { 11981 return null; 11982 } 11983 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11984 result.setComponent(r.errorReportReceiver); 11985 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11986 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11987 return result; 11988 } 11989 11990 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11991 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11992 if (r.errorReportReceiver == null) { 11993 return null; 11994 } 11995 11996 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11997 return null; 11998 } 11999 12000 ApplicationErrorReport report = new ApplicationErrorReport(); 12001 report.packageName = r.info.packageName; 12002 report.installerPackageName = r.errorReportReceiver.getPackageName(); 12003 report.processName = r.processName; 12004 report.time = timeMillis; 12005 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 12006 12007 if (r.crashing || r.forceCrashReport) { 12008 report.type = ApplicationErrorReport.TYPE_CRASH; 12009 report.crashInfo = crashInfo; 12010 } else if (r.notResponding) { 12011 report.type = ApplicationErrorReport.TYPE_ANR; 12012 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 12013 12014 report.anrInfo.activity = r.notRespondingReport.tag; 12015 report.anrInfo.cause = r.notRespondingReport.shortMsg; 12016 report.anrInfo.info = r.notRespondingReport.longMsg; 12017 } 12018 12019 return report; 12020 } 12021 12022 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 12023 enforceNotIsolatedCaller("getProcessesInErrorState"); 12024 // assume our apps are happy - lazy create the list 12025 List<ActivityManager.ProcessErrorStateInfo> errList = null; 12026 12027 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12028 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12029 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12030 12031 synchronized (this) { 12032 12033 // iterate across all processes 12034 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12035 ProcessRecord app = mLruProcesses.get(i); 12036 if (!allUsers && app.userId != userId) { 12037 continue; 12038 } 12039 if ((app.thread != null) && (app.crashing || app.notResponding)) { 12040 // This one's in trouble, so we'll generate a report for it 12041 // crashes are higher priority (in case there's a crash *and* an anr) 12042 ActivityManager.ProcessErrorStateInfo report = null; 12043 if (app.crashing) { 12044 report = app.crashingReport; 12045 } else if (app.notResponding) { 12046 report = app.notRespondingReport; 12047 } 12048 12049 if (report != null) { 12050 if (errList == null) { 12051 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 12052 } 12053 errList.add(report); 12054 } else { 12055 Slog.w(TAG, "Missing app error report, app = " + app.processName + 12056 " crashing = " + app.crashing + 12057 " notResponding = " + app.notResponding); 12058 } 12059 } 12060 } 12061 } 12062 12063 return errList; 12064 } 12065 12066 static int procStateToImportance(int procState, int memAdj, 12067 ActivityManager.RunningAppProcessInfo currApp) { 12068 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 12069 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 12070 currApp.lru = memAdj; 12071 } else { 12072 currApp.lru = 0; 12073 } 12074 return imp; 12075 } 12076 12077 private void fillInProcMemInfo(ProcessRecord app, 12078 ActivityManager.RunningAppProcessInfo outInfo) { 12079 outInfo.pid = app.pid; 12080 outInfo.uid = app.info.uid; 12081 if (mHeavyWeightProcess == app) { 12082 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12083 } 12084 if (app.persistent) { 12085 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12086 } 12087 if (app.activities.size() > 0) { 12088 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12089 } 12090 outInfo.lastTrimLevel = app.trimMemoryLevel; 12091 int adj = app.curAdj; 12092 int procState = app.curProcState; 12093 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12094 outInfo.importanceReasonCode = app.adjTypeCode; 12095 outInfo.processState = app.curProcState; 12096 } 12097 12098 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12099 enforceNotIsolatedCaller("getRunningAppProcesses"); 12100 // Lazy instantiation of list 12101 List<ActivityManager.RunningAppProcessInfo> runList = null; 12102 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12103 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12104 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12105 synchronized (this) { 12106 // Iterate across all processes 12107 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12108 ProcessRecord app = mLruProcesses.get(i); 12109 if (!allUsers && app.userId != userId) { 12110 continue; 12111 } 12112 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12113 // Generate process state info for running application 12114 ActivityManager.RunningAppProcessInfo currApp = 12115 new ActivityManager.RunningAppProcessInfo(app.processName, 12116 app.pid, app.getPackageList()); 12117 fillInProcMemInfo(app, currApp); 12118 if (app.adjSource instanceof ProcessRecord) { 12119 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12120 currApp.importanceReasonImportance = 12121 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12122 app.adjSourceProcState); 12123 } else if (app.adjSource instanceof ActivityRecord) { 12124 ActivityRecord r = (ActivityRecord)app.adjSource; 12125 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12126 } 12127 if (app.adjTarget instanceof ComponentName) { 12128 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12129 } 12130 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12131 // + " lru=" + currApp.lru); 12132 if (runList == null) { 12133 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12134 } 12135 runList.add(currApp); 12136 } 12137 } 12138 } 12139 return runList; 12140 } 12141 12142 public List<ApplicationInfo> getRunningExternalApplications() { 12143 enforceNotIsolatedCaller("getRunningExternalApplications"); 12144 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12145 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12146 if (runningApps != null && runningApps.size() > 0) { 12147 Set<String> extList = new HashSet<String>(); 12148 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12149 if (app.pkgList != null) { 12150 for (String pkg : app.pkgList) { 12151 extList.add(pkg); 12152 } 12153 } 12154 } 12155 IPackageManager pm = AppGlobals.getPackageManager(); 12156 for (String pkg : extList) { 12157 try { 12158 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12159 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12160 retList.add(info); 12161 } 12162 } catch (RemoteException e) { 12163 } 12164 } 12165 } 12166 return retList; 12167 } 12168 12169 @Override 12170 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12171 enforceNotIsolatedCaller("getMyMemoryState"); 12172 synchronized (this) { 12173 ProcessRecord proc; 12174 synchronized (mPidsSelfLocked) { 12175 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12176 } 12177 fillInProcMemInfo(proc, outInfo); 12178 } 12179 } 12180 12181 @Override 12182 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12183 if (checkCallingPermission(android.Manifest.permission.DUMP) 12184 != PackageManager.PERMISSION_GRANTED) { 12185 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12186 + Binder.getCallingPid() 12187 + ", uid=" + Binder.getCallingUid() 12188 + " without permission " 12189 + android.Manifest.permission.DUMP); 12190 return; 12191 } 12192 12193 boolean dumpAll = false; 12194 boolean dumpClient = false; 12195 String dumpPackage = null; 12196 12197 int opti = 0; 12198 while (opti < args.length) { 12199 String opt = args[opti]; 12200 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12201 break; 12202 } 12203 opti++; 12204 if ("-a".equals(opt)) { 12205 dumpAll = true; 12206 } else if ("-c".equals(opt)) { 12207 dumpClient = true; 12208 } else if ("-h".equals(opt)) { 12209 pw.println("Activity manager dump options:"); 12210 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12211 pw.println(" cmd may be one of:"); 12212 pw.println(" a[ctivities]: activity stack state"); 12213 pw.println(" r[recents]: recent activities state"); 12214 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12215 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12216 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12217 pw.println(" o[om]: out of memory management"); 12218 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12219 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12220 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12221 pw.println(" service [COMP_SPEC]: service client-side state"); 12222 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12223 pw.println(" all: dump all activities"); 12224 pw.println(" top: dump the top activity"); 12225 pw.println(" write: write all pending state to storage"); 12226 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12227 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12228 pw.println(" a partial substring in a component name, a"); 12229 pw.println(" hex object identifier."); 12230 pw.println(" -a: include all available server state."); 12231 pw.println(" -c: include client state."); 12232 return; 12233 } else { 12234 pw.println("Unknown argument: " + opt + "; use -h for help"); 12235 } 12236 } 12237 12238 long origId = Binder.clearCallingIdentity(); 12239 boolean more = false; 12240 // Is the caller requesting to dump a particular piece of data? 12241 if (opti < args.length) { 12242 String cmd = args[opti]; 12243 opti++; 12244 if ("activities".equals(cmd) || "a".equals(cmd)) { 12245 synchronized (this) { 12246 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12247 } 12248 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12249 synchronized (this) { 12250 dumpRecentsLocked(fd, pw, args, opti, true, null); 12251 } 12252 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12253 String[] newArgs; 12254 String name; 12255 if (opti >= args.length) { 12256 name = null; 12257 newArgs = EMPTY_STRING_ARRAY; 12258 } else { 12259 name = args[opti]; 12260 opti++; 12261 newArgs = new String[args.length - opti]; 12262 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12263 args.length - opti); 12264 } 12265 synchronized (this) { 12266 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12267 } 12268 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12269 String[] newArgs; 12270 String name; 12271 if (opti >= args.length) { 12272 name = null; 12273 newArgs = EMPTY_STRING_ARRAY; 12274 } else { 12275 name = args[opti]; 12276 opti++; 12277 newArgs = new String[args.length - opti]; 12278 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12279 args.length - opti); 12280 } 12281 synchronized (this) { 12282 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12283 } 12284 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12285 String[] newArgs; 12286 String name; 12287 if (opti >= args.length) { 12288 name = null; 12289 newArgs = EMPTY_STRING_ARRAY; 12290 } else { 12291 name = args[opti]; 12292 opti++; 12293 newArgs = new String[args.length - opti]; 12294 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12295 args.length - opti); 12296 } 12297 synchronized (this) { 12298 dumpProcessesLocked(fd, pw, args, opti, true, name); 12299 } 12300 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12301 synchronized (this) { 12302 dumpOomLocked(fd, pw, args, opti, true); 12303 } 12304 } else if ("provider".equals(cmd)) { 12305 String[] newArgs; 12306 String name; 12307 if (opti >= args.length) { 12308 name = null; 12309 newArgs = EMPTY_STRING_ARRAY; 12310 } else { 12311 name = args[opti]; 12312 opti++; 12313 newArgs = new String[args.length - opti]; 12314 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12315 } 12316 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12317 pw.println("No providers match: " + name); 12318 pw.println("Use -h for help."); 12319 } 12320 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12321 synchronized (this) { 12322 dumpProvidersLocked(fd, pw, args, opti, true, null); 12323 } 12324 } else if ("service".equals(cmd)) { 12325 String[] newArgs; 12326 String name; 12327 if (opti >= args.length) { 12328 name = null; 12329 newArgs = EMPTY_STRING_ARRAY; 12330 } else { 12331 name = args[opti]; 12332 opti++; 12333 newArgs = new String[args.length - opti]; 12334 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12335 args.length - opti); 12336 } 12337 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12338 pw.println("No services match: " + name); 12339 pw.println("Use -h for help."); 12340 } 12341 } else if ("package".equals(cmd)) { 12342 String[] newArgs; 12343 if (opti >= args.length) { 12344 pw.println("package: no package name specified"); 12345 pw.println("Use -h for help."); 12346 } else { 12347 dumpPackage = args[opti]; 12348 opti++; 12349 newArgs = new String[args.length - opti]; 12350 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12351 args.length - opti); 12352 args = newArgs; 12353 opti = 0; 12354 more = true; 12355 } 12356 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12357 synchronized (this) { 12358 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12359 } 12360 } else if ("write".equals(cmd)) { 12361 mTaskPersister.flush(); 12362 pw.println("All tasks persisted."); 12363 return; 12364 } else { 12365 // Dumping a single activity? 12366 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12367 pw.println("Bad activity command, or no activities match: " + cmd); 12368 pw.println("Use -h for help."); 12369 } 12370 } 12371 if (!more) { 12372 Binder.restoreCallingIdentity(origId); 12373 return; 12374 } 12375 } 12376 12377 // No piece of data specified, dump everything. 12378 synchronized (this) { 12379 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12380 pw.println(); 12381 if (dumpAll) { 12382 pw.println("-------------------------------------------------------------------------------"); 12383 } 12384 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12385 pw.println(); 12386 if (dumpAll) { 12387 pw.println("-------------------------------------------------------------------------------"); 12388 } 12389 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12390 pw.println(); 12391 if (dumpAll) { 12392 pw.println("-------------------------------------------------------------------------------"); 12393 } 12394 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12395 pw.println(); 12396 if (dumpAll) { 12397 pw.println("-------------------------------------------------------------------------------"); 12398 } 12399 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12400 pw.println(); 12401 if (dumpAll) { 12402 pw.println("-------------------------------------------------------------------------------"); 12403 } 12404 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12405 pw.println(); 12406 if (dumpAll) { 12407 pw.println("-------------------------------------------------------------------------------"); 12408 } 12409 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12410 } 12411 Binder.restoreCallingIdentity(origId); 12412 } 12413 12414 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12415 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12416 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12417 12418 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12419 dumpPackage); 12420 boolean needSep = printedAnything; 12421 12422 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12423 dumpPackage, needSep, " mFocusedActivity: "); 12424 if (printed) { 12425 printedAnything = true; 12426 needSep = false; 12427 } 12428 12429 if (dumpPackage == null) { 12430 if (needSep) { 12431 pw.println(); 12432 } 12433 needSep = true; 12434 printedAnything = true; 12435 mStackSupervisor.dump(pw, " "); 12436 } 12437 12438 if (!printedAnything) { 12439 pw.println(" (nothing)"); 12440 } 12441 } 12442 12443 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12444 int opti, boolean dumpAll, String dumpPackage) { 12445 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12446 12447 boolean printedAnything = false; 12448 12449 if (mRecentTasks.size() > 0) { 12450 boolean printedHeader = false; 12451 12452 final int N = mRecentTasks.size(); 12453 for (int i=0; i<N; i++) { 12454 TaskRecord tr = mRecentTasks.get(i); 12455 if (dumpPackage != null) { 12456 if (tr.realActivity == null || 12457 !dumpPackage.equals(tr.realActivity)) { 12458 continue; 12459 } 12460 } 12461 if (!printedHeader) { 12462 pw.println(" Recent tasks:"); 12463 printedHeader = true; 12464 printedAnything = true; 12465 } 12466 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12467 pw.println(tr); 12468 if (dumpAll) { 12469 mRecentTasks.get(i).dump(pw, " "); 12470 } 12471 } 12472 } 12473 12474 if (!printedAnything) { 12475 pw.println(" (nothing)"); 12476 } 12477 } 12478 12479 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12480 int opti, boolean dumpAll, String dumpPackage) { 12481 boolean needSep = false; 12482 boolean printedAnything = false; 12483 int numPers = 0; 12484 12485 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12486 12487 if (dumpAll) { 12488 final int NP = mProcessNames.getMap().size(); 12489 for (int ip=0; ip<NP; ip++) { 12490 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12491 final int NA = procs.size(); 12492 for (int ia=0; ia<NA; ia++) { 12493 ProcessRecord r = procs.valueAt(ia); 12494 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12495 continue; 12496 } 12497 if (!needSep) { 12498 pw.println(" All known processes:"); 12499 needSep = true; 12500 printedAnything = true; 12501 } 12502 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12503 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12504 pw.print(" "); pw.println(r); 12505 r.dump(pw, " "); 12506 if (r.persistent) { 12507 numPers++; 12508 } 12509 } 12510 } 12511 } 12512 12513 if (mIsolatedProcesses.size() > 0) { 12514 boolean printed = false; 12515 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12516 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12517 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12518 continue; 12519 } 12520 if (!printed) { 12521 if (needSep) { 12522 pw.println(); 12523 } 12524 pw.println(" Isolated process list (sorted by uid):"); 12525 printedAnything = true; 12526 printed = true; 12527 needSep = true; 12528 } 12529 pw.println(String.format("%sIsolated #%2d: %s", 12530 " ", i, r.toString())); 12531 } 12532 } 12533 12534 if (mLruProcesses.size() > 0) { 12535 if (needSep) { 12536 pw.println(); 12537 } 12538 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12539 pw.print(" total, non-act at "); 12540 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12541 pw.print(", non-svc at "); 12542 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12543 pw.println("):"); 12544 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12545 needSep = true; 12546 printedAnything = true; 12547 } 12548 12549 if (dumpAll || dumpPackage != null) { 12550 synchronized (mPidsSelfLocked) { 12551 boolean printed = false; 12552 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12553 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12554 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12555 continue; 12556 } 12557 if (!printed) { 12558 if (needSep) pw.println(); 12559 needSep = true; 12560 pw.println(" PID mappings:"); 12561 printed = true; 12562 printedAnything = true; 12563 } 12564 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12565 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12566 } 12567 } 12568 } 12569 12570 if (mForegroundProcesses.size() > 0) { 12571 synchronized (mPidsSelfLocked) { 12572 boolean printed = false; 12573 for (int i=0; i<mForegroundProcesses.size(); i++) { 12574 ProcessRecord r = mPidsSelfLocked.get( 12575 mForegroundProcesses.valueAt(i).pid); 12576 if (dumpPackage != null && (r == null 12577 || !r.pkgList.containsKey(dumpPackage))) { 12578 continue; 12579 } 12580 if (!printed) { 12581 if (needSep) pw.println(); 12582 needSep = true; 12583 pw.println(" Foreground Processes:"); 12584 printed = true; 12585 printedAnything = true; 12586 } 12587 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12588 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12589 } 12590 } 12591 } 12592 12593 if (mPersistentStartingProcesses.size() > 0) { 12594 if (needSep) pw.println(); 12595 needSep = true; 12596 printedAnything = true; 12597 pw.println(" Persisent processes that are starting:"); 12598 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12599 "Starting Norm", "Restarting PERS", dumpPackage); 12600 } 12601 12602 if (mRemovedProcesses.size() > 0) { 12603 if (needSep) pw.println(); 12604 needSep = true; 12605 printedAnything = true; 12606 pw.println(" Processes that are being removed:"); 12607 dumpProcessList(pw, this, mRemovedProcesses, " ", 12608 "Removed Norm", "Removed PERS", dumpPackage); 12609 } 12610 12611 if (mProcessesOnHold.size() > 0) { 12612 if (needSep) pw.println(); 12613 needSep = true; 12614 printedAnything = true; 12615 pw.println(" Processes that are on old until the system is ready:"); 12616 dumpProcessList(pw, this, mProcessesOnHold, " ", 12617 "OnHold Norm", "OnHold PERS", dumpPackage); 12618 } 12619 12620 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12621 12622 if (mProcessCrashTimes.getMap().size() > 0) { 12623 boolean printed = false; 12624 long now = SystemClock.uptimeMillis(); 12625 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12626 final int NP = pmap.size(); 12627 for (int ip=0; ip<NP; ip++) { 12628 String pname = pmap.keyAt(ip); 12629 SparseArray<Long> uids = pmap.valueAt(ip); 12630 final int N = uids.size(); 12631 for (int i=0; i<N; i++) { 12632 int puid = uids.keyAt(i); 12633 ProcessRecord r = mProcessNames.get(pname, puid); 12634 if (dumpPackage != null && (r == null 12635 || !r.pkgList.containsKey(dumpPackage))) { 12636 continue; 12637 } 12638 if (!printed) { 12639 if (needSep) pw.println(); 12640 needSep = true; 12641 pw.println(" Time since processes crashed:"); 12642 printed = true; 12643 printedAnything = true; 12644 } 12645 pw.print(" Process "); pw.print(pname); 12646 pw.print(" uid "); pw.print(puid); 12647 pw.print(": last crashed "); 12648 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12649 pw.println(" ago"); 12650 } 12651 } 12652 } 12653 12654 if (mBadProcesses.getMap().size() > 0) { 12655 boolean printed = false; 12656 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12657 final int NP = pmap.size(); 12658 for (int ip=0; ip<NP; ip++) { 12659 String pname = pmap.keyAt(ip); 12660 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12661 final int N = uids.size(); 12662 for (int i=0; i<N; i++) { 12663 int puid = uids.keyAt(i); 12664 ProcessRecord r = mProcessNames.get(pname, puid); 12665 if (dumpPackage != null && (r == null 12666 || !r.pkgList.containsKey(dumpPackage))) { 12667 continue; 12668 } 12669 if (!printed) { 12670 if (needSep) pw.println(); 12671 needSep = true; 12672 pw.println(" Bad processes:"); 12673 printedAnything = true; 12674 } 12675 BadProcessInfo info = uids.valueAt(i); 12676 pw.print(" Bad process "); pw.print(pname); 12677 pw.print(" uid "); pw.print(puid); 12678 pw.print(": crashed at time "); pw.println(info.time); 12679 if (info.shortMsg != null) { 12680 pw.print(" Short msg: "); pw.println(info.shortMsg); 12681 } 12682 if (info.longMsg != null) { 12683 pw.print(" Long msg: "); pw.println(info.longMsg); 12684 } 12685 if (info.stack != null) { 12686 pw.println(" Stack:"); 12687 int lastPos = 0; 12688 for (int pos=0; pos<info.stack.length(); pos++) { 12689 if (info.stack.charAt(pos) == '\n') { 12690 pw.print(" "); 12691 pw.write(info.stack, lastPos, pos-lastPos); 12692 pw.println(); 12693 lastPos = pos+1; 12694 } 12695 } 12696 if (lastPos < info.stack.length()) { 12697 pw.print(" "); 12698 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12699 pw.println(); 12700 } 12701 } 12702 } 12703 } 12704 } 12705 12706 if (dumpPackage == null) { 12707 pw.println(); 12708 needSep = false; 12709 pw.println(" mStartedUsers:"); 12710 for (int i=0; i<mStartedUsers.size(); i++) { 12711 UserStartedState uss = mStartedUsers.valueAt(i); 12712 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12713 pw.print(": "); uss.dump("", pw); 12714 } 12715 pw.print(" mStartedUserArray: ["); 12716 for (int i=0; i<mStartedUserArray.length; i++) { 12717 if (i > 0) pw.print(", "); 12718 pw.print(mStartedUserArray[i]); 12719 } 12720 pw.println("]"); 12721 pw.print(" mUserLru: ["); 12722 for (int i=0; i<mUserLru.size(); i++) { 12723 if (i > 0) pw.print(", "); 12724 pw.print(mUserLru.get(i)); 12725 } 12726 pw.println("]"); 12727 if (dumpAll) { 12728 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12729 } 12730 synchronized (mUserProfileGroupIdsSelfLocked) { 12731 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12732 pw.println(" mUserProfileGroupIds:"); 12733 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12734 pw.print(" User #"); 12735 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12736 pw.print(" -> profile #"); 12737 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12738 } 12739 } 12740 } 12741 } 12742 if (mHomeProcess != null && (dumpPackage == null 12743 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12744 if (needSep) { 12745 pw.println(); 12746 needSep = false; 12747 } 12748 pw.println(" mHomeProcess: " + mHomeProcess); 12749 } 12750 if (mPreviousProcess != null && (dumpPackage == null 12751 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12752 if (needSep) { 12753 pw.println(); 12754 needSep = false; 12755 } 12756 pw.println(" mPreviousProcess: " + mPreviousProcess); 12757 } 12758 if (dumpAll) { 12759 StringBuilder sb = new StringBuilder(128); 12760 sb.append(" mPreviousProcessVisibleTime: "); 12761 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12762 pw.println(sb); 12763 } 12764 if (mHeavyWeightProcess != null && (dumpPackage == null 12765 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12766 if (needSep) { 12767 pw.println(); 12768 needSep = false; 12769 } 12770 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12771 } 12772 if (dumpPackage == null) { 12773 pw.println(" mConfiguration: " + mConfiguration); 12774 } 12775 if (dumpAll) { 12776 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12777 if (mCompatModePackages.getPackages().size() > 0) { 12778 boolean printed = false; 12779 for (Map.Entry<String, Integer> entry 12780 : mCompatModePackages.getPackages().entrySet()) { 12781 String pkg = entry.getKey(); 12782 int mode = entry.getValue(); 12783 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12784 continue; 12785 } 12786 if (!printed) { 12787 pw.println(" mScreenCompatPackages:"); 12788 printed = true; 12789 } 12790 pw.print(" "); pw.print(pkg); pw.print(": "); 12791 pw.print(mode); pw.println(); 12792 } 12793 } 12794 } 12795 if (dumpPackage == null) { 12796 if (mSleeping || mWentToSleep || mLockScreenShown) { 12797 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12798 + " mLockScreenShown " + mLockScreenShown); 12799 } 12800 if (mShuttingDown || mRunningVoice) { 12801 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12802 } 12803 } 12804 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12805 || mOrigWaitForDebugger) { 12806 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12807 || dumpPackage.equals(mOrigDebugApp)) { 12808 if (needSep) { 12809 pw.println(); 12810 needSep = false; 12811 } 12812 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12813 + " mDebugTransient=" + mDebugTransient 12814 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12815 } 12816 } 12817 if (mOpenGlTraceApp != null) { 12818 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12819 if (needSep) { 12820 pw.println(); 12821 needSep = false; 12822 } 12823 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12824 } 12825 } 12826 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12827 || mProfileFd != null) { 12828 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12829 if (needSep) { 12830 pw.println(); 12831 needSep = false; 12832 } 12833 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12834 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12835 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12836 + mAutoStopProfiler); 12837 pw.println(" mProfileType=" + mProfileType); 12838 } 12839 } 12840 if (dumpPackage == null) { 12841 if (mAlwaysFinishActivities || mController != null) { 12842 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12843 + " mController=" + mController); 12844 } 12845 if (dumpAll) { 12846 pw.println(" Total persistent processes: " + numPers); 12847 pw.println(" mProcessesReady=" + mProcessesReady 12848 + " mSystemReady=" + mSystemReady); 12849 pw.println(" mBooting=" + mBooting 12850 + " mBooted=" + mBooted 12851 + " mFactoryTest=" + mFactoryTest); 12852 pw.print(" mLastPowerCheckRealtime="); 12853 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12854 pw.println(""); 12855 pw.print(" mLastPowerCheckUptime="); 12856 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12857 pw.println(""); 12858 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12859 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12860 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12861 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12862 + " (" + mLruProcesses.size() + " total)" 12863 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12864 + " mNumServiceProcs=" + mNumServiceProcs 12865 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12866 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12867 + " mLastMemoryLevel" + mLastMemoryLevel 12868 + " mLastNumProcesses" + mLastNumProcesses); 12869 long now = SystemClock.uptimeMillis(); 12870 pw.print(" mLastIdleTime="); 12871 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12872 pw.print(" mLowRamSinceLastIdle="); 12873 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12874 pw.println(); 12875 } 12876 } 12877 12878 if (!printedAnything) { 12879 pw.println(" (nothing)"); 12880 } 12881 } 12882 12883 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12884 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12885 if (mProcessesToGc.size() > 0) { 12886 boolean printed = false; 12887 long now = SystemClock.uptimeMillis(); 12888 for (int i=0; i<mProcessesToGc.size(); i++) { 12889 ProcessRecord proc = mProcessesToGc.get(i); 12890 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12891 continue; 12892 } 12893 if (!printed) { 12894 if (needSep) pw.println(); 12895 needSep = true; 12896 pw.println(" Processes that are waiting to GC:"); 12897 printed = true; 12898 } 12899 pw.print(" Process "); pw.println(proc); 12900 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12901 pw.print(", last gced="); 12902 pw.print(now-proc.lastRequestedGc); 12903 pw.print(" ms ago, last lowMem="); 12904 pw.print(now-proc.lastLowMemory); 12905 pw.println(" ms ago"); 12906 12907 } 12908 } 12909 return needSep; 12910 } 12911 12912 void printOomLevel(PrintWriter pw, String name, int adj) { 12913 pw.print(" "); 12914 if (adj >= 0) { 12915 pw.print(' '); 12916 if (adj < 10) pw.print(' '); 12917 } else { 12918 if (adj > -10) pw.print(' '); 12919 } 12920 pw.print(adj); 12921 pw.print(": "); 12922 pw.print(name); 12923 pw.print(" ("); 12924 pw.print(mProcessList.getMemLevel(adj)/1024); 12925 pw.println(" kB)"); 12926 } 12927 12928 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12929 int opti, boolean dumpAll) { 12930 boolean needSep = false; 12931 12932 if (mLruProcesses.size() > 0) { 12933 if (needSep) pw.println(); 12934 needSep = true; 12935 pw.println(" OOM levels:"); 12936 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12937 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12938 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12939 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12940 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12941 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12942 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12943 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12944 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12945 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12946 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12947 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12948 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12949 12950 if (needSep) pw.println(); 12951 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12952 pw.print(" total, non-act at "); 12953 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12954 pw.print(", non-svc at "); 12955 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12956 pw.println("):"); 12957 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12958 needSep = true; 12959 } 12960 12961 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12962 12963 pw.println(); 12964 pw.println(" mHomeProcess: " + mHomeProcess); 12965 pw.println(" mPreviousProcess: " + mPreviousProcess); 12966 if (mHeavyWeightProcess != null) { 12967 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12968 } 12969 12970 return true; 12971 } 12972 12973 /** 12974 * There are three ways to call this: 12975 * - no provider specified: dump all the providers 12976 * - a flattened component name that matched an existing provider was specified as the 12977 * first arg: dump that one provider 12978 * - the first arg isn't the flattened component name of an existing provider: 12979 * dump all providers whose component contains the first arg as a substring 12980 */ 12981 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12982 int opti, boolean dumpAll) { 12983 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12984 } 12985 12986 static class ItemMatcher { 12987 ArrayList<ComponentName> components; 12988 ArrayList<String> strings; 12989 ArrayList<Integer> objects; 12990 boolean all; 12991 12992 ItemMatcher() { 12993 all = true; 12994 } 12995 12996 void build(String name) { 12997 ComponentName componentName = ComponentName.unflattenFromString(name); 12998 if (componentName != null) { 12999 if (components == null) { 13000 components = new ArrayList<ComponentName>(); 13001 } 13002 components.add(componentName); 13003 all = false; 13004 } else { 13005 int objectId = 0; 13006 // Not a '/' separated full component name; maybe an object ID? 13007 try { 13008 objectId = Integer.parseInt(name, 16); 13009 if (objects == null) { 13010 objects = new ArrayList<Integer>(); 13011 } 13012 objects.add(objectId); 13013 all = false; 13014 } catch (RuntimeException e) { 13015 // Not an integer; just do string match. 13016 if (strings == null) { 13017 strings = new ArrayList<String>(); 13018 } 13019 strings.add(name); 13020 all = false; 13021 } 13022 } 13023 } 13024 13025 int build(String[] args, int opti) { 13026 for (; opti<args.length; opti++) { 13027 String name = args[opti]; 13028 if ("--".equals(name)) { 13029 return opti+1; 13030 } 13031 build(name); 13032 } 13033 return opti; 13034 } 13035 13036 boolean match(Object object, ComponentName comp) { 13037 if (all) { 13038 return true; 13039 } 13040 if (components != null) { 13041 for (int i=0; i<components.size(); i++) { 13042 if (components.get(i).equals(comp)) { 13043 return true; 13044 } 13045 } 13046 } 13047 if (objects != null) { 13048 for (int i=0; i<objects.size(); i++) { 13049 if (System.identityHashCode(object) == objects.get(i)) { 13050 return true; 13051 } 13052 } 13053 } 13054 if (strings != null) { 13055 String flat = comp.flattenToString(); 13056 for (int i=0; i<strings.size(); i++) { 13057 if (flat.contains(strings.get(i))) { 13058 return true; 13059 } 13060 } 13061 } 13062 return false; 13063 } 13064 } 13065 13066 /** 13067 * There are three things that cmd can be: 13068 * - a flattened component name that matches an existing activity 13069 * - the cmd arg isn't the flattened component name of an existing activity: 13070 * dump all activity whose component contains the cmd as a substring 13071 * - A hex number of the ActivityRecord object instance. 13072 */ 13073 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 13074 int opti, boolean dumpAll) { 13075 ArrayList<ActivityRecord> activities; 13076 13077 synchronized (this) { 13078 activities = mStackSupervisor.getDumpActivitiesLocked(name); 13079 } 13080 13081 if (activities.size() <= 0) { 13082 return false; 13083 } 13084 13085 String[] newArgs = new String[args.length - opti]; 13086 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 13087 13088 TaskRecord lastTask = null; 13089 boolean needSep = false; 13090 for (int i=activities.size()-1; i>=0; i--) { 13091 ActivityRecord r = activities.get(i); 13092 if (needSep) { 13093 pw.println(); 13094 } 13095 needSep = true; 13096 synchronized (this) { 13097 if (lastTask != r.task) { 13098 lastTask = r.task; 13099 pw.print("TASK "); pw.print(lastTask.affinity); 13100 pw.print(" id="); pw.println(lastTask.taskId); 13101 if (dumpAll) { 13102 lastTask.dump(pw, " "); 13103 } 13104 } 13105 } 13106 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13107 } 13108 return true; 13109 } 13110 13111 /** 13112 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13113 * there is a thread associated with the activity. 13114 */ 13115 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13116 final ActivityRecord r, String[] args, boolean dumpAll) { 13117 String innerPrefix = prefix + " "; 13118 synchronized (this) { 13119 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13120 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13121 pw.print(" pid="); 13122 if (r.app != null) pw.println(r.app.pid); 13123 else pw.println("(not running)"); 13124 if (dumpAll) { 13125 r.dump(pw, innerPrefix); 13126 } 13127 } 13128 if (r.app != null && r.app.thread != null) { 13129 // flush anything that is already in the PrintWriter since the thread is going 13130 // to write to the file descriptor directly 13131 pw.flush(); 13132 try { 13133 TransferPipe tp = new TransferPipe(); 13134 try { 13135 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13136 r.appToken, innerPrefix, args); 13137 tp.go(fd); 13138 } finally { 13139 tp.kill(); 13140 } 13141 } catch (IOException e) { 13142 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13143 } catch (RemoteException e) { 13144 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13145 } 13146 } 13147 } 13148 13149 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13150 int opti, boolean dumpAll, String dumpPackage) { 13151 boolean needSep = false; 13152 boolean onlyHistory = false; 13153 boolean printedAnything = false; 13154 13155 if ("history".equals(dumpPackage)) { 13156 if (opti < args.length && "-s".equals(args[opti])) { 13157 dumpAll = false; 13158 } 13159 onlyHistory = true; 13160 dumpPackage = null; 13161 } 13162 13163 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13164 if (!onlyHistory && dumpAll) { 13165 if (mRegisteredReceivers.size() > 0) { 13166 boolean printed = false; 13167 Iterator it = mRegisteredReceivers.values().iterator(); 13168 while (it.hasNext()) { 13169 ReceiverList r = (ReceiverList)it.next(); 13170 if (dumpPackage != null && (r.app == null || 13171 !dumpPackage.equals(r.app.info.packageName))) { 13172 continue; 13173 } 13174 if (!printed) { 13175 pw.println(" Registered Receivers:"); 13176 needSep = true; 13177 printed = true; 13178 printedAnything = true; 13179 } 13180 pw.print(" * "); pw.println(r); 13181 r.dump(pw, " "); 13182 } 13183 } 13184 13185 if (mReceiverResolver.dump(pw, needSep ? 13186 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13187 " ", dumpPackage, false)) { 13188 needSep = true; 13189 printedAnything = true; 13190 } 13191 } 13192 13193 for (BroadcastQueue q : mBroadcastQueues) { 13194 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13195 printedAnything |= needSep; 13196 } 13197 13198 needSep = true; 13199 13200 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13201 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13202 if (needSep) { 13203 pw.println(); 13204 } 13205 needSep = true; 13206 printedAnything = true; 13207 pw.print(" Sticky broadcasts for user "); 13208 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13209 StringBuilder sb = new StringBuilder(128); 13210 for (Map.Entry<String, ArrayList<Intent>> ent 13211 : mStickyBroadcasts.valueAt(user).entrySet()) { 13212 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13213 if (dumpAll) { 13214 pw.println(":"); 13215 ArrayList<Intent> intents = ent.getValue(); 13216 final int N = intents.size(); 13217 for (int i=0; i<N; i++) { 13218 sb.setLength(0); 13219 sb.append(" Intent: "); 13220 intents.get(i).toShortString(sb, false, true, false, false); 13221 pw.println(sb.toString()); 13222 Bundle bundle = intents.get(i).getExtras(); 13223 if (bundle != null) { 13224 pw.print(" "); 13225 pw.println(bundle.toString()); 13226 } 13227 } 13228 } else { 13229 pw.println(""); 13230 } 13231 } 13232 } 13233 } 13234 13235 if (!onlyHistory && dumpAll) { 13236 pw.println(); 13237 for (BroadcastQueue queue : mBroadcastQueues) { 13238 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13239 + queue.mBroadcastsScheduled); 13240 } 13241 pw.println(" mHandler:"); 13242 mHandler.dump(new PrintWriterPrinter(pw), " "); 13243 needSep = true; 13244 printedAnything = true; 13245 } 13246 13247 if (!printedAnything) { 13248 pw.println(" (nothing)"); 13249 } 13250 } 13251 13252 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13253 int opti, boolean dumpAll, String dumpPackage) { 13254 boolean needSep; 13255 boolean printedAnything = false; 13256 13257 ItemMatcher matcher = new ItemMatcher(); 13258 matcher.build(args, opti); 13259 13260 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13261 13262 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13263 printedAnything |= needSep; 13264 13265 if (mLaunchingProviders.size() > 0) { 13266 boolean printed = false; 13267 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13268 ContentProviderRecord r = mLaunchingProviders.get(i); 13269 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13270 continue; 13271 } 13272 if (!printed) { 13273 if (needSep) pw.println(); 13274 needSep = true; 13275 pw.println(" Launching content providers:"); 13276 printed = true; 13277 printedAnything = true; 13278 } 13279 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13280 pw.println(r); 13281 } 13282 } 13283 13284 if (mGrantedUriPermissions.size() > 0) { 13285 boolean printed = false; 13286 int dumpUid = -2; 13287 if (dumpPackage != null) { 13288 try { 13289 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13290 } catch (NameNotFoundException e) { 13291 dumpUid = -1; 13292 } 13293 } 13294 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13295 int uid = mGrantedUriPermissions.keyAt(i); 13296 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13297 continue; 13298 } 13299 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13300 if (!printed) { 13301 if (needSep) pw.println(); 13302 needSep = true; 13303 pw.println(" Granted Uri Permissions:"); 13304 printed = true; 13305 printedAnything = true; 13306 } 13307 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13308 for (UriPermission perm : perms.values()) { 13309 pw.print(" "); pw.println(perm); 13310 if (dumpAll) { 13311 perm.dump(pw, " "); 13312 } 13313 } 13314 } 13315 } 13316 13317 if (!printedAnything) { 13318 pw.println(" (nothing)"); 13319 } 13320 } 13321 13322 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13323 int opti, boolean dumpAll, String dumpPackage) { 13324 boolean printed = false; 13325 13326 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13327 13328 if (mIntentSenderRecords.size() > 0) { 13329 Iterator<WeakReference<PendingIntentRecord>> it 13330 = mIntentSenderRecords.values().iterator(); 13331 while (it.hasNext()) { 13332 WeakReference<PendingIntentRecord> ref = it.next(); 13333 PendingIntentRecord rec = ref != null ? ref.get(): null; 13334 if (dumpPackage != null && (rec == null 13335 || !dumpPackage.equals(rec.key.packageName))) { 13336 continue; 13337 } 13338 printed = true; 13339 if (rec != null) { 13340 pw.print(" * "); pw.println(rec); 13341 if (dumpAll) { 13342 rec.dump(pw, " "); 13343 } 13344 } else { 13345 pw.print(" * "); pw.println(ref); 13346 } 13347 } 13348 } 13349 13350 if (!printed) { 13351 pw.println(" (nothing)"); 13352 } 13353 } 13354 13355 private static final int dumpProcessList(PrintWriter pw, 13356 ActivityManagerService service, List list, 13357 String prefix, String normalLabel, String persistentLabel, 13358 String dumpPackage) { 13359 int numPers = 0; 13360 final int N = list.size()-1; 13361 for (int i=N; i>=0; i--) { 13362 ProcessRecord r = (ProcessRecord)list.get(i); 13363 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13364 continue; 13365 } 13366 pw.println(String.format("%s%s #%2d: %s", 13367 prefix, (r.persistent ? persistentLabel : normalLabel), 13368 i, r.toString())); 13369 if (r.persistent) { 13370 numPers++; 13371 } 13372 } 13373 return numPers; 13374 } 13375 13376 private static final boolean dumpProcessOomList(PrintWriter pw, 13377 ActivityManagerService service, List<ProcessRecord> origList, 13378 String prefix, String normalLabel, String persistentLabel, 13379 boolean inclDetails, String dumpPackage) { 13380 13381 ArrayList<Pair<ProcessRecord, Integer>> list 13382 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13383 for (int i=0; i<origList.size(); i++) { 13384 ProcessRecord r = origList.get(i); 13385 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13386 continue; 13387 } 13388 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13389 } 13390 13391 if (list.size() <= 0) { 13392 return false; 13393 } 13394 13395 Comparator<Pair<ProcessRecord, Integer>> comparator 13396 = new Comparator<Pair<ProcessRecord, Integer>>() { 13397 @Override 13398 public int compare(Pair<ProcessRecord, Integer> object1, 13399 Pair<ProcessRecord, Integer> object2) { 13400 if (object1.first.setAdj != object2.first.setAdj) { 13401 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13402 } 13403 if (object1.second.intValue() != object2.second.intValue()) { 13404 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13405 } 13406 return 0; 13407 } 13408 }; 13409 13410 Collections.sort(list, comparator); 13411 13412 final long curRealtime = SystemClock.elapsedRealtime(); 13413 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13414 final long curUptime = SystemClock.uptimeMillis(); 13415 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13416 13417 for (int i=list.size()-1; i>=0; i--) { 13418 ProcessRecord r = list.get(i).first; 13419 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13420 char schedGroup; 13421 switch (r.setSchedGroup) { 13422 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13423 schedGroup = 'B'; 13424 break; 13425 case Process.THREAD_GROUP_DEFAULT: 13426 schedGroup = 'F'; 13427 break; 13428 default: 13429 schedGroup = '?'; 13430 break; 13431 } 13432 char foreground; 13433 if (r.foregroundActivities) { 13434 foreground = 'A'; 13435 } else if (r.foregroundServices) { 13436 foreground = 'S'; 13437 } else { 13438 foreground = ' '; 13439 } 13440 String procState = ProcessList.makeProcStateString(r.curProcState); 13441 pw.print(prefix); 13442 pw.print(r.persistent ? persistentLabel : normalLabel); 13443 pw.print(" #"); 13444 int num = (origList.size()-1)-list.get(i).second; 13445 if (num < 10) pw.print(' '); 13446 pw.print(num); 13447 pw.print(": "); 13448 pw.print(oomAdj); 13449 pw.print(' '); 13450 pw.print(schedGroup); 13451 pw.print('/'); 13452 pw.print(foreground); 13453 pw.print('/'); 13454 pw.print(procState); 13455 pw.print(" trm:"); 13456 if (r.trimMemoryLevel < 10) pw.print(' '); 13457 pw.print(r.trimMemoryLevel); 13458 pw.print(' '); 13459 pw.print(r.toShortString()); 13460 pw.print(" ("); 13461 pw.print(r.adjType); 13462 pw.println(')'); 13463 if (r.adjSource != null || r.adjTarget != null) { 13464 pw.print(prefix); 13465 pw.print(" "); 13466 if (r.adjTarget instanceof ComponentName) { 13467 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13468 } else if (r.adjTarget != null) { 13469 pw.print(r.adjTarget.toString()); 13470 } else { 13471 pw.print("{null}"); 13472 } 13473 pw.print("<="); 13474 if (r.adjSource instanceof ProcessRecord) { 13475 pw.print("Proc{"); 13476 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13477 pw.println("}"); 13478 } else if (r.adjSource != null) { 13479 pw.println(r.adjSource.toString()); 13480 } else { 13481 pw.println("{null}"); 13482 } 13483 } 13484 if (inclDetails) { 13485 pw.print(prefix); 13486 pw.print(" "); 13487 pw.print("oom: max="); pw.print(r.maxAdj); 13488 pw.print(" curRaw="); pw.print(r.curRawAdj); 13489 pw.print(" setRaw="); pw.print(r.setRawAdj); 13490 pw.print(" cur="); pw.print(r.curAdj); 13491 pw.print(" set="); pw.println(r.setAdj); 13492 pw.print(prefix); 13493 pw.print(" "); 13494 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13495 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13496 pw.print(" lastPss="); pw.print(r.lastPss); 13497 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13498 pw.print(prefix); 13499 pw.print(" "); 13500 pw.print("cached="); pw.print(r.cached); 13501 pw.print(" empty="); pw.print(r.empty); 13502 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13503 13504 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13505 if (r.lastWakeTime != 0) { 13506 long wtime; 13507 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13508 synchronized (stats) { 13509 wtime = stats.getProcessWakeTime(r.info.uid, 13510 r.pid, curRealtime); 13511 } 13512 long timeUsed = wtime - r.lastWakeTime; 13513 pw.print(prefix); 13514 pw.print(" "); 13515 pw.print("keep awake over "); 13516 TimeUtils.formatDuration(realtimeSince, pw); 13517 pw.print(" used "); 13518 TimeUtils.formatDuration(timeUsed, pw); 13519 pw.print(" ("); 13520 pw.print((timeUsed*100)/realtimeSince); 13521 pw.println("%)"); 13522 } 13523 if (r.lastCpuTime != 0) { 13524 long timeUsed = r.curCpuTime - r.lastCpuTime; 13525 pw.print(prefix); 13526 pw.print(" "); 13527 pw.print("run cpu over "); 13528 TimeUtils.formatDuration(uptimeSince, pw); 13529 pw.print(" used "); 13530 TimeUtils.formatDuration(timeUsed, pw); 13531 pw.print(" ("); 13532 pw.print((timeUsed*100)/uptimeSince); 13533 pw.println("%)"); 13534 } 13535 } 13536 } 13537 } 13538 return true; 13539 } 13540 13541 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13542 ArrayList<ProcessRecord> procs; 13543 synchronized (this) { 13544 if (args != null && args.length > start 13545 && args[start].charAt(0) != '-') { 13546 procs = new ArrayList<ProcessRecord>(); 13547 int pid = -1; 13548 try { 13549 pid = Integer.parseInt(args[start]); 13550 } catch (NumberFormatException e) { 13551 } 13552 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13553 ProcessRecord proc = mLruProcesses.get(i); 13554 if (proc.pid == pid) { 13555 procs.add(proc); 13556 } else if (proc.processName.equals(args[start])) { 13557 procs.add(proc); 13558 } 13559 } 13560 if (procs.size() <= 0) { 13561 return null; 13562 } 13563 } else { 13564 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13565 } 13566 } 13567 return procs; 13568 } 13569 13570 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13571 PrintWriter pw, String[] args) { 13572 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13573 if (procs == null) { 13574 pw.println("No process found for: " + args[0]); 13575 return; 13576 } 13577 13578 long uptime = SystemClock.uptimeMillis(); 13579 long realtime = SystemClock.elapsedRealtime(); 13580 pw.println("Applications Graphics Acceleration Info:"); 13581 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13582 13583 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13584 ProcessRecord r = procs.get(i); 13585 if (r.thread != null) { 13586 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13587 pw.flush(); 13588 try { 13589 TransferPipe tp = new TransferPipe(); 13590 try { 13591 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13592 tp.go(fd); 13593 } finally { 13594 tp.kill(); 13595 } 13596 } catch (IOException e) { 13597 pw.println("Failure while dumping the app: " + r); 13598 pw.flush(); 13599 } catch (RemoteException e) { 13600 pw.println("Got a RemoteException while dumping the app " + r); 13601 pw.flush(); 13602 } 13603 } 13604 } 13605 } 13606 13607 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13608 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13609 if (procs == null) { 13610 pw.println("No process found for: " + args[0]); 13611 return; 13612 } 13613 13614 pw.println("Applications Database Info:"); 13615 13616 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13617 ProcessRecord r = procs.get(i); 13618 if (r.thread != null) { 13619 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13620 pw.flush(); 13621 try { 13622 TransferPipe tp = new TransferPipe(); 13623 try { 13624 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13625 tp.go(fd); 13626 } finally { 13627 tp.kill(); 13628 } 13629 } catch (IOException e) { 13630 pw.println("Failure while dumping the app: " + r); 13631 pw.flush(); 13632 } catch (RemoteException e) { 13633 pw.println("Got a RemoteException while dumping the app " + r); 13634 pw.flush(); 13635 } 13636 } 13637 } 13638 } 13639 13640 final static class MemItem { 13641 final boolean isProc; 13642 final String label; 13643 final String shortLabel; 13644 final long pss; 13645 final int id; 13646 final boolean hasActivities; 13647 ArrayList<MemItem> subitems; 13648 13649 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13650 boolean _hasActivities) { 13651 isProc = true; 13652 label = _label; 13653 shortLabel = _shortLabel; 13654 pss = _pss; 13655 id = _id; 13656 hasActivities = _hasActivities; 13657 } 13658 13659 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13660 isProc = false; 13661 label = _label; 13662 shortLabel = _shortLabel; 13663 pss = _pss; 13664 id = _id; 13665 hasActivities = false; 13666 } 13667 } 13668 13669 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13670 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13671 if (sort && !isCompact) { 13672 Collections.sort(items, new Comparator<MemItem>() { 13673 @Override 13674 public int compare(MemItem lhs, MemItem rhs) { 13675 if (lhs.pss < rhs.pss) { 13676 return 1; 13677 } else if (lhs.pss > rhs.pss) { 13678 return -1; 13679 } 13680 return 0; 13681 } 13682 }); 13683 } 13684 13685 for (int i=0; i<items.size(); i++) { 13686 MemItem mi = items.get(i); 13687 if (!isCompact) { 13688 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13689 } else if (mi.isProc) { 13690 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13691 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13692 pw.println(mi.hasActivities ? ",a" : ",e"); 13693 } else { 13694 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13695 pw.println(mi.pss); 13696 } 13697 if (mi.subitems != null) { 13698 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13699 true, isCompact); 13700 } 13701 } 13702 } 13703 13704 // These are in KB. 13705 static final long[] DUMP_MEM_BUCKETS = new long[] { 13706 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13707 120*1024, 160*1024, 200*1024, 13708 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13709 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13710 }; 13711 13712 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13713 boolean stackLike) { 13714 int start = label.lastIndexOf('.'); 13715 if (start >= 0) start++; 13716 else start = 0; 13717 int end = label.length(); 13718 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13719 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13720 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13721 out.append(bucket); 13722 out.append(stackLike ? "MB." : "MB "); 13723 out.append(label, start, end); 13724 return; 13725 } 13726 } 13727 out.append(memKB/1024); 13728 out.append(stackLike ? "MB." : "MB "); 13729 out.append(label, start, end); 13730 } 13731 13732 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13733 ProcessList.NATIVE_ADJ, 13734 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13735 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13736 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13737 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13738 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13739 }; 13740 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13741 "Native", 13742 "System", "Persistent", "Foreground", 13743 "Visible", "Perceptible", 13744 "Heavy Weight", "Backup", 13745 "A Services", "Home", 13746 "Previous", "B Services", "Cached" 13747 }; 13748 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13749 "native", 13750 "sys", "pers", "fore", 13751 "vis", "percept", 13752 "heavy", "backup", 13753 "servicea", "home", 13754 "prev", "serviceb", "cached" 13755 }; 13756 13757 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13758 long realtime, boolean isCheckinRequest, boolean isCompact) { 13759 if (isCheckinRequest || isCompact) { 13760 // short checkin version 13761 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13762 } else { 13763 pw.println("Applications Memory Usage (kB):"); 13764 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13765 } 13766 } 13767 13768 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13769 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13770 boolean dumpDetails = false; 13771 boolean dumpFullDetails = false; 13772 boolean dumpDalvik = false; 13773 boolean oomOnly = false; 13774 boolean isCompact = false; 13775 boolean localOnly = false; 13776 13777 int opti = 0; 13778 while (opti < args.length) { 13779 String opt = args[opti]; 13780 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13781 break; 13782 } 13783 opti++; 13784 if ("-a".equals(opt)) { 13785 dumpDetails = true; 13786 dumpFullDetails = true; 13787 dumpDalvik = true; 13788 } else if ("-d".equals(opt)) { 13789 dumpDalvik = true; 13790 } else if ("-c".equals(opt)) { 13791 isCompact = true; 13792 } else if ("--oom".equals(opt)) { 13793 oomOnly = true; 13794 } else if ("--local".equals(opt)) { 13795 localOnly = true; 13796 } else if ("-h".equals(opt)) { 13797 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13798 pw.println(" -a: include all available information for each process."); 13799 pw.println(" -d: include dalvik details when dumping process details."); 13800 pw.println(" -c: dump in a compact machine-parseable representation."); 13801 pw.println(" --oom: only show processes organized by oom adj."); 13802 pw.println(" --local: only collect details locally, don't call process."); 13803 pw.println("If [process] is specified it can be the name or "); 13804 pw.println("pid of a specific process to dump."); 13805 return; 13806 } else { 13807 pw.println("Unknown argument: " + opt + "; use -h for help"); 13808 } 13809 } 13810 13811 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13812 long uptime = SystemClock.uptimeMillis(); 13813 long realtime = SystemClock.elapsedRealtime(); 13814 final long[] tmpLong = new long[1]; 13815 13816 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13817 if (procs == null) { 13818 // No Java processes. Maybe they want to print a native process. 13819 if (args != null && args.length > opti 13820 && args[opti].charAt(0) != '-') { 13821 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13822 = new ArrayList<ProcessCpuTracker.Stats>(); 13823 updateCpuStatsNow(); 13824 int findPid = -1; 13825 try { 13826 findPid = Integer.parseInt(args[opti]); 13827 } catch (NumberFormatException e) { 13828 } 13829 synchronized (mProcessCpuTracker) { 13830 final int N = mProcessCpuTracker.countStats(); 13831 for (int i=0; i<N; i++) { 13832 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13833 if (st.pid == findPid || (st.baseName != null 13834 && st.baseName.equals(args[opti]))) { 13835 nativeProcs.add(st); 13836 } 13837 } 13838 } 13839 if (nativeProcs.size() > 0) { 13840 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13841 isCompact); 13842 Debug.MemoryInfo mi = null; 13843 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13844 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13845 final int pid = r.pid; 13846 if (!isCheckinRequest && dumpDetails) { 13847 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13848 } 13849 if (mi == null) { 13850 mi = new Debug.MemoryInfo(); 13851 } 13852 if (dumpDetails || (!brief && !oomOnly)) { 13853 Debug.getMemoryInfo(pid, mi); 13854 } else { 13855 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13856 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13857 } 13858 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13859 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13860 if (isCheckinRequest) { 13861 pw.println(); 13862 } 13863 } 13864 return; 13865 } 13866 } 13867 pw.println("No process found for: " + args[opti]); 13868 return; 13869 } 13870 13871 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13872 dumpDetails = true; 13873 } 13874 13875 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13876 13877 String[] innerArgs = new String[args.length-opti]; 13878 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13879 13880 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13881 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13882 long nativePss=0, dalvikPss=0, otherPss=0; 13883 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13884 13885 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13886 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13887 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13888 13889 long totalPss = 0; 13890 long cachedPss = 0; 13891 13892 Debug.MemoryInfo mi = null; 13893 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13894 final ProcessRecord r = procs.get(i); 13895 final IApplicationThread thread; 13896 final int pid; 13897 final int oomAdj; 13898 final boolean hasActivities; 13899 synchronized (this) { 13900 thread = r.thread; 13901 pid = r.pid; 13902 oomAdj = r.getSetAdjWithServices(); 13903 hasActivities = r.activities.size() > 0; 13904 } 13905 if (thread != null) { 13906 if (!isCheckinRequest && dumpDetails) { 13907 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13908 } 13909 if (mi == null) { 13910 mi = new Debug.MemoryInfo(); 13911 } 13912 if (dumpDetails || (!brief && !oomOnly)) { 13913 Debug.getMemoryInfo(pid, mi); 13914 } else { 13915 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13916 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13917 } 13918 if (dumpDetails) { 13919 if (localOnly) { 13920 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13921 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13922 if (isCheckinRequest) { 13923 pw.println(); 13924 } 13925 } else { 13926 try { 13927 pw.flush(); 13928 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13929 dumpDalvik, innerArgs); 13930 } catch (RemoteException e) { 13931 if (!isCheckinRequest) { 13932 pw.println("Got RemoteException!"); 13933 pw.flush(); 13934 } 13935 } 13936 } 13937 } 13938 13939 final long myTotalPss = mi.getTotalPss(); 13940 final long myTotalUss = mi.getTotalUss(); 13941 13942 synchronized (this) { 13943 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13944 // Record this for posterity if the process has been stable. 13945 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13946 } 13947 } 13948 13949 if (!isCheckinRequest && mi != null) { 13950 totalPss += myTotalPss; 13951 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13952 (hasActivities ? " / activities)" : ")"), 13953 r.processName, myTotalPss, pid, hasActivities); 13954 procMems.add(pssItem); 13955 procMemsMap.put(pid, pssItem); 13956 13957 nativePss += mi.nativePss; 13958 dalvikPss += mi.dalvikPss; 13959 otherPss += mi.otherPss; 13960 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13961 long mem = mi.getOtherPss(j); 13962 miscPss[j] += mem; 13963 otherPss -= mem; 13964 } 13965 13966 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13967 cachedPss += myTotalPss; 13968 } 13969 13970 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13971 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13972 || oomIndex == (oomPss.length-1)) { 13973 oomPss[oomIndex] += myTotalPss; 13974 if (oomProcs[oomIndex] == null) { 13975 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13976 } 13977 oomProcs[oomIndex].add(pssItem); 13978 break; 13979 } 13980 } 13981 } 13982 } 13983 } 13984 13985 long nativeProcTotalPss = 0; 13986 13987 if (!isCheckinRequest && procs.size() > 1) { 13988 // If we are showing aggregations, also look for native processes to 13989 // include so that our aggregations are more accurate. 13990 updateCpuStatsNow(); 13991 synchronized (mProcessCpuTracker) { 13992 final int N = mProcessCpuTracker.countStats(); 13993 for (int i=0; i<N; i++) { 13994 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13995 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13996 if (mi == null) { 13997 mi = new Debug.MemoryInfo(); 13998 } 13999 if (!brief && !oomOnly) { 14000 Debug.getMemoryInfo(st.pid, mi); 14001 } else { 14002 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 14003 mi.nativePrivateDirty = (int)tmpLong[0]; 14004 } 14005 14006 final long myTotalPss = mi.getTotalPss(); 14007 totalPss += myTotalPss; 14008 nativeProcTotalPss += myTotalPss; 14009 14010 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 14011 st.name, myTotalPss, st.pid, false); 14012 procMems.add(pssItem); 14013 14014 nativePss += mi.nativePss; 14015 dalvikPss += mi.dalvikPss; 14016 otherPss += mi.otherPss; 14017 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14018 long mem = mi.getOtherPss(j); 14019 miscPss[j] += mem; 14020 otherPss -= mem; 14021 } 14022 oomPss[0] += myTotalPss; 14023 if (oomProcs[0] == null) { 14024 oomProcs[0] = new ArrayList<MemItem>(); 14025 } 14026 oomProcs[0].add(pssItem); 14027 } 14028 } 14029 } 14030 14031 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 14032 14033 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 14034 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 14035 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 14036 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 14037 String label = Debug.MemoryInfo.getOtherLabel(j); 14038 catMems.add(new MemItem(label, label, miscPss[j], j)); 14039 } 14040 14041 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 14042 for (int j=0; j<oomPss.length; j++) { 14043 if (oomPss[j] != 0) { 14044 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 14045 : DUMP_MEM_OOM_LABEL[j]; 14046 MemItem item = new MemItem(label, label, oomPss[j], 14047 DUMP_MEM_OOM_ADJ[j]); 14048 item.subitems = oomProcs[j]; 14049 oomMems.add(item); 14050 } 14051 } 14052 14053 if (!brief && !oomOnly && !isCompact) { 14054 pw.println(); 14055 pw.println("Total PSS by process:"); 14056 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 14057 pw.println(); 14058 } 14059 if (!isCompact) { 14060 pw.println("Total PSS by OOM adjustment:"); 14061 } 14062 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 14063 if (!brief && !oomOnly) { 14064 PrintWriter out = categoryPw != null ? categoryPw : pw; 14065 if (!isCompact) { 14066 out.println(); 14067 out.println("Total PSS by category:"); 14068 } 14069 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 14070 } 14071 if (!isCompact) { 14072 pw.println(); 14073 } 14074 MemInfoReader memInfo = new MemInfoReader(); 14075 memInfo.readMemInfo(); 14076 if (nativeProcTotalPss > 0) { 14077 synchronized (this) { 14078 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 14079 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 14080 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 14081 nativeProcTotalPss); 14082 } 14083 } 14084 if (!brief) { 14085 if (!isCompact) { 14086 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 14087 pw.print(" kB (status "); 14088 switch (mLastMemoryLevel) { 14089 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14090 pw.println("normal)"); 14091 break; 14092 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14093 pw.println("moderate)"); 14094 break; 14095 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14096 pw.println("low)"); 14097 break; 14098 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14099 pw.println("critical)"); 14100 break; 14101 default: 14102 pw.print(mLastMemoryLevel); 14103 pw.println(")"); 14104 break; 14105 } 14106 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14107 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14108 pw.print(cachedPss); pw.print(" cached pss + "); 14109 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14110 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14111 } else { 14112 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14113 pw.print(cachedPss + memInfo.getCachedSizeKb() 14114 + memInfo.getFreeSizeKb()); pw.print(","); 14115 pw.println(totalPss - cachedPss); 14116 } 14117 } 14118 if (!isCompact) { 14119 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14120 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14121 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14122 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14123 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14124 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14125 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14126 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14127 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14128 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14129 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14130 } 14131 if (!brief) { 14132 if (memInfo.getZramTotalSizeKb() != 0) { 14133 if (!isCompact) { 14134 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14135 pw.print(" kB physical used for "); 14136 pw.print(memInfo.getSwapTotalSizeKb() 14137 - memInfo.getSwapFreeSizeKb()); 14138 pw.print(" kB in swap ("); 14139 pw.print(memInfo.getSwapTotalSizeKb()); 14140 pw.println(" kB total swap)"); 14141 } else { 14142 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14143 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14144 pw.println(memInfo.getSwapFreeSizeKb()); 14145 } 14146 } 14147 final int[] SINGLE_LONG_FORMAT = new int[] { 14148 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14149 }; 14150 long[] longOut = new long[1]; 14151 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14152 SINGLE_LONG_FORMAT, null, longOut, null); 14153 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14154 longOut[0] = 0; 14155 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14156 SINGLE_LONG_FORMAT, null, longOut, null); 14157 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14158 longOut[0] = 0; 14159 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14160 SINGLE_LONG_FORMAT, null, longOut, null); 14161 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14162 longOut[0] = 0; 14163 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14164 SINGLE_LONG_FORMAT, null, longOut, null); 14165 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14166 if (!isCompact) { 14167 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14168 pw.print(" KSM: "); pw.print(sharing); 14169 pw.print(" kB saved from shared "); 14170 pw.print(shared); pw.println(" kB"); 14171 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14172 pw.print(voltile); pw.println(" kB volatile"); 14173 } 14174 pw.print(" Tuning: "); 14175 pw.print(ActivityManager.staticGetMemoryClass()); 14176 pw.print(" (large "); 14177 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14178 pw.print("), oom "); 14179 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14180 pw.print(" kB"); 14181 pw.print(", restore limit "); 14182 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14183 pw.print(" kB"); 14184 if (ActivityManager.isLowRamDeviceStatic()) { 14185 pw.print(" (low-ram)"); 14186 } 14187 if (ActivityManager.isHighEndGfx()) { 14188 pw.print(" (high-end-gfx)"); 14189 } 14190 pw.println(); 14191 } else { 14192 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14193 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14194 pw.println(voltile); 14195 pw.print("tuning,"); 14196 pw.print(ActivityManager.staticGetMemoryClass()); 14197 pw.print(','); 14198 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14199 pw.print(','); 14200 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14201 if (ActivityManager.isLowRamDeviceStatic()) { 14202 pw.print(",low-ram"); 14203 } 14204 if (ActivityManager.isHighEndGfx()) { 14205 pw.print(",high-end-gfx"); 14206 } 14207 pw.println(); 14208 } 14209 } 14210 } 14211 } 14212 14213 /** 14214 * Searches array of arguments for the specified string 14215 * @param args array of argument strings 14216 * @param value value to search for 14217 * @return true if the value is contained in the array 14218 */ 14219 private static boolean scanArgs(String[] args, String value) { 14220 if (args != null) { 14221 for (String arg : args) { 14222 if (value.equals(arg)) { 14223 return true; 14224 } 14225 } 14226 } 14227 return false; 14228 } 14229 14230 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14231 ContentProviderRecord cpr, boolean always) { 14232 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14233 14234 if (!inLaunching || always) { 14235 synchronized (cpr) { 14236 cpr.launchingApp = null; 14237 cpr.notifyAll(); 14238 } 14239 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14240 String names[] = cpr.info.authority.split(";"); 14241 for (int j = 0; j < names.length; j++) { 14242 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14243 } 14244 } 14245 14246 for (int i=0; i<cpr.connections.size(); i++) { 14247 ContentProviderConnection conn = cpr.connections.get(i); 14248 if (conn.waiting) { 14249 // If this connection is waiting for the provider, then we don't 14250 // need to mess with its process unless we are always removing 14251 // or for some reason the provider is not currently launching. 14252 if (inLaunching && !always) { 14253 continue; 14254 } 14255 } 14256 ProcessRecord capp = conn.client; 14257 conn.dead = true; 14258 if (conn.stableCount > 0) { 14259 if (!capp.persistent && capp.thread != null 14260 && capp.pid != 0 14261 && capp.pid != MY_PID) { 14262 capp.kill("depends on provider " 14263 + cpr.name.flattenToShortString() 14264 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14265 } 14266 } else if (capp.thread != null && conn.provider.provider != null) { 14267 try { 14268 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14269 } catch (RemoteException e) { 14270 } 14271 // In the protocol here, we don't expect the client to correctly 14272 // clean up this connection, we'll just remove it. 14273 cpr.connections.remove(i); 14274 conn.client.conProviders.remove(conn); 14275 } 14276 } 14277 14278 if (inLaunching && always) { 14279 mLaunchingProviders.remove(cpr); 14280 } 14281 return inLaunching; 14282 } 14283 14284 /** 14285 * Main code for cleaning up a process when it has gone away. This is 14286 * called both as a result of the process dying, or directly when stopping 14287 * a process when running in single process mode. 14288 */ 14289 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14290 boolean restarting, boolean allowRestart, int index) { 14291 if (index >= 0) { 14292 removeLruProcessLocked(app); 14293 ProcessList.remove(app.pid); 14294 } 14295 14296 mProcessesToGc.remove(app); 14297 mPendingPssProcesses.remove(app); 14298 14299 // Dismiss any open dialogs. 14300 if (app.crashDialog != null && !app.forceCrashReport) { 14301 app.crashDialog.dismiss(); 14302 app.crashDialog = null; 14303 } 14304 if (app.anrDialog != null) { 14305 app.anrDialog.dismiss(); 14306 app.anrDialog = null; 14307 } 14308 if (app.waitDialog != null) { 14309 app.waitDialog.dismiss(); 14310 app.waitDialog = null; 14311 } 14312 14313 app.crashing = false; 14314 app.notResponding = false; 14315 14316 app.resetPackageList(mProcessStats); 14317 app.unlinkDeathRecipient(); 14318 app.makeInactive(mProcessStats); 14319 app.waitingToKill = null; 14320 app.forcingToForeground = null; 14321 updateProcessForegroundLocked(app, false, false); 14322 app.foregroundActivities = false; 14323 app.hasShownUi = false; 14324 app.treatLikeActivity = false; 14325 app.hasAboveClient = false; 14326 app.hasClientActivities = false; 14327 14328 mServices.killServicesLocked(app, allowRestart); 14329 14330 boolean restart = false; 14331 14332 // Remove published content providers. 14333 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14334 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14335 final boolean always = app.bad || !allowRestart; 14336 if (removeDyingProviderLocked(app, cpr, always) || always) { 14337 // We left the provider in the launching list, need to 14338 // restart it. 14339 restart = true; 14340 } 14341 14342 cpr.provider = null; 14343 cpr.proc = null; 14344 } 14345 app.pubProviders.clear(); 14346 14347 // Take care of any launching providers waiting for this process. 14348 if (checkAppInLaunchingProvidersLocked(app, false)) { 14349 restart = true; 14350 } 14351 14352 // Unregister from connected content providers. 14353 if (!app.conProviders.isEmpty()) { 14354 for (int i=0; i<app.conProviders.size(); i++) { 14355 ContentProviderConnection conn = app.conProviders.get(i); 14356 conn.provider.connections.remove(conn); 14357 } 14358 app.conProviders.clear(); 14359 } 14360 14361 // At this point there may be remaining entries in mLaunchingProviders 14362 // where we were the only one waiting, so they are no longer of use. 14363 // Look for these and clean up if found. 14364 // XXX Commented out for now. Trying to figure out a way to reproduce 14365 // the actual situation to identify what is actually going on. 14366 if (false) { 14367 for (int i=0; i<mLaunchingProviders.size(); i++) { 14368 ContentProviderRecord cpr = (ContentProviderRecord) 14369 mLaunchingProviders.get(i); 14370 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14371 synchronized (cpr) { 14372 cpr.launchingApp = null; 14373 cpr.notifyAll(); 14374 } 14375 } 14376 } 14377 } 14378 14379 skipCurrentReceiverLocked(app); 14380 14381 // Unregister any receivers. 14382 for (int i=app.receivers.size()-1; i>=0; i--) { 14383 removeReceiverLocked(app.receivers.valueAt(i)); 14384 } 14385 app.receivers.clear(); 14386 14387 // If the app is undergoing backup, tell the backup manager about it 14388 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14389 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14390 + mBackupTarget.appInfo + " died during backup"); 14391 try { 14392 IBackupManager bm = IBackupManager.Stub.asInterface( 14393 ServiceManager.getService(Context.BACKUP_SERVICE)); 14394 bm.agentDisconnected(app.info.packageName); 14395 } catch (RemoteException e) { 14396 // can't happen; backup manager is local 14397 } 14398 } 14399 14400 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14401 ProcessChangeItem item = mPendingProcessChanges.get(i); 14402 if (item.pid == app.pid) { 14403 mPendingProcessChanges.remove(i); 14404 mAvailProcessChanges.add(item); 14405 } 14406 } 14407 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14408 14409 // If the caller is restarting this app, then leave it in its 14410 // current lists and let the caller take care of it. 14411 if (restarting) { 14412 return; 14413 } 14414 14415 if (!app.persistent || app.isolated) { 14416 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14417 "Removing non-persistent process during cleanup: " + app); 14418 mProcessNames.remove(app.processName, app.uid); 14419 mIsolatedProcesses.remove(app.uid); 14420 if (mHeavyWeightProcess == app) { 14421 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14422 mHeavyWeightProcess.userId, 0)); 14423 mHeavyWeightProcess = null; 14424 } 14425 } else if (!app.removed) { 14426 // This app is persistent, so we need to keep its record around. 14427 // If it is not already on the pending app list, add it there 14428 // and start a new process for it. 14429 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14430 mPersistentStartingProcesses.add(app); 14431 restart = true; 14432 } 14433 } 14434 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14435 "Clean-up removing on hold: " + app); 14436 mProcessesOnHold.remove(app); 14437 14438 if (app == mHomeProcess) { 14439 mHomeProcess = null; 14440 } 14441 if (app == mPreviousProcess) { 14442 mPreviousProcess = null; 14443 } 14444 14445 if (restart && !app.isolated) { 14446 // We have components that still need to be running in the 14447 // process, so re-launch it. 14448 mProcessNames.put(app.processName, app.uid, app); 14449 startProcessLocked(app, "restart", app.processName); 14450 } else if (app.pid > 0 && app.pid != MY_PID) { 14451 // Goodbye! 14452 boolean removed; 14453 synchronized (mPidsSelfLocked) { 14454 mPidsSelfLocked.remove(app.pid); 14455 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14456 } 14457 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14458 if (app.isolated) { 14459 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14460 } 14461 app.setPid(0); 14462 } 14463 } 14464 14465 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14466 // Look through the content providers we are waiting to have launched, 14467 // and if any run in this process then either schedule a restart of 14468 // the process or kill the client waiting for it if this process has 14469 // gone bad. 14470 int NL = mLaunchingProviders.size(); 14471 boolean restart = false; 14472 for (int i=0; i<NL; i++) { 14473 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14474 if (cpr.launchingApp == app) { 14475 if (!alwaysBad && !app.bad) { 14476 restart = true; 14477 } else { 14478 removeDyingProviderLocked(app, cpr, true); 14479 // cpr should have been removed from mLaunchingProviders 14480 NL = mLaunchingProviders.size(); 14481 i--; 14482 } 14483 } 14484 } 14485 return restart; 14486 } 14487 14488 // ========================================================= 14489 // SERVICES 14490 // ========================================================= 14491 14492 @Override 14493 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14494 int flags) { 14495 enforceNotIsolatedCaller("getServices"); 14496 synchronized (this) { 14497 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14498 } 14499 } 14500 14501 @Override 14502 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14503 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14504 synchronized (this) { 14505 return mServices.getRunningServiceControlPanelLocked(name); 14506 } 14507 } 14508 14509 @Override 14510 public ComponentName startService(IApplicationThread caller, Intent service, 14511 String resolvedType, int userId) { 14512 enforceNotIsolatedCaller("startService"); 14513 // Refuse possible leaked file descriptors 14514 if (service != null && service.hasFileDescriptors() == true) { 14515 throw new IllegalArgumentException("File descriptors passed in Intent"); 14516 } 14517 14518 if (DEBUG_SERVICE) 14519 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14520 synchronized(this) { 14521 final int callingPid = Binder.getCallingPid(); 14522 final int callingUid = Binder.getCallingUid(); 14523 final long origId = Binder.clearCallingIdentity(); 14524 ComponentName res = mServices.startServiceLocked(caller, service, 14525 resolvedType, callingPid, callingUid, userId); 14526 Binder.restoreCallingIdentity(origId); 14527 return res; 14528 } 14529 } 14530 14531 ComponentName startServiceInPackage(int uid, 14532 Intent service, String resolvedType, int userId) { 14533 synchronized(this) { 14534 if (DEBUG_SERVICE) 14535 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14536 final long origId = Binder.clearCallingIdentity(); 14537 ComponentName res = mServices.startServiceLocked(null, service, 14538 resolvedType, -1, uid, userId); 14539 Binder.restoreCallingIdentity(origId); 14540 return res; 14541 } 14542 } 14543 14544 @Override 14545 public int stopService(IApplicationThread caller, Intent service, 14546 String resolvedType, int userId) { 14547 enforceNotIsolatedCaller("stopService"); 14548 // Refuse possible leaked file descriptors 14549 if (service != null && service.hasFileDescriptors() == true) { 14550 throw new IllegalArgumentException("File descriptors passed in Intent"); 14551 } 14552 14553 synchronized(this) { 14554 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14555 } 14556 } 14557 14558 @Override 14559 public IBinder peekService(Intent service, String resolvedType) { 14560 enforceNotIsolatedCaller("peekService"); 14561 // Refuse possible leaked file descriptors 14562 if (service != null && service.hasFileDescriptors() == true) { 14563 throw new IllegalArgumentException("File descriptors passed in Intent"); 14564 } 14565 synchronized(this) { 14566 return mServices.peekServiceLocked(service, resolvedType); 14567 } 14568 } 14569 14570 @Override 14571 public boolean stopServiceToken(ComponentName className, IBinder token, 14572 int startId) { 14573 synchronized(this) { 14574 return mServices.stopServiceTokenLocked(className, token, startId); 14575 } 14576 } 14577 14578 @Override 14579 public void setServiceForeground(ComponentName className, IBinder token, 14580 int id, Notification notification, boolean removeNotification) { 14581 synchronized(this) { 14582 mServices.setServiceForegroundLocked(className, token, id, notification, 14583 removeNotification); 14584 } 14585 } 14586 14587 @Override 14588 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14589 boolean requireFull, String name, String callerPackage) { 14590 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14591 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14592 } 14593 14594 int unsafeConvertIncomingUser(int userId) { 14595 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14596 ? mCurrentUserId : userId; 14597 } 14598 14599 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14600 int allowMode, String name, String callerPackage) { 14601 final int callingUserId = UserHandle.getUserId(callingUid); 14602 if (callingUserId == userId) { 14603 return userId; 14604 } 14605 14606 // Note that we may be accessing mCurrentUserId outside of a lock... 14607 // shouldn't be a big deal, if this is being called outside 14608 // of a locked context there is intrinsically a race with 14609 // the value the caller will receive and someone else changing it. 14610 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14611 // we will switch to the calling user if access to the current user fails. 14612 int targetUserId = unsafeConvertIncomingUser(userId); 14613 14614 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14615 final boolean allow; 14616 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14617 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14618 // If the caller has this permission, they always pass go. And collect $200. 14619 allow = true; 14620 } else if (allowMode == ALLOW_FULL_ONLY) { 14621 // We require full access, sucks to be you. 14622 allow = false; 14623 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14624 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14625 // If the caller does not have either permission, they are always doomed. 14626 allow = false; 14627 } else if (allowMode == ALLOW_NON_FULL) { 14628 // We are blanket allowing non-full access, you lucky caller! 14629 allow = true; 14630 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14631 // We may or may not allow this depending on whether the two users are 14632 // in the same profile. 14633 synchronized (mUserProfileGroupIdsSelfLocked) { 14634 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14635 UserInfo.NO_PROFILE_GROUP_ID); 14636 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14637 UserInfo.NO_PROFILE_GROUP_ID); 14638 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14639 && callingProfile == targetProfile; 14640 } 14641 } else { 14642 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14643 } 14644 if (!allow) { 14645 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14646 // In this case, they would like to just execute as their 14647 // owner user instead of failing. 14648 targetUserId = callingUserId; 14649 } else { 14650 StringBuilder builder = new StringBuilder(128); 14651 builder.append("Permission Denial: "); 14652 builder.append(name); 14653 if (callerPackage != null) { 14654 builder.append(" from "); 14655 builder.append(callerPackage); 14656 } 14657 builder.append(" asks to run as user "); 14658 builder.append(userId); 14659 builder.append(" but is calling from user "); 14660 builder.append(UserHandle.getUserId(callingUid)); 14661 builder.append("; this requires "); 14662 builder.append(INTERACT_ACROSS_USERS_FULL); 14663 if (allowMode != ALLOW_FULL_ONLY) { 14664 builder.append(" or "); 14665 builder.append(INTERACT_ACROSS_USERS); 14666 } 14667 String msg = builder.toString(); 14668 Slog.w(TAG, msg); 14669 throw new SecurityException(msg); 14670 } 14671 } 14672 } 14673 if (!allowAll && targetUserId < 0) { 14674 throw new IllegalArgumentException( 14675 "Call does not support special user #" + targetUserId); 14676 } 14677 // Check shell permission 14678 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) { 14679 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, 14680 targetUserId)) { 14681 throw new SecurityException("Shell does not have permission to access user " 14682 + targetUserId + "\n " + Debug.getCallers(3)); 14683 } 14684 } 14685 return targetUserId; 14686 } 14687 14688 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14689 String className, int flags) { 14690 boolean result = false; 14691 // For apps that don't have pre-defined UIDs, check for permission 14692 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14693 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14694 if (ActivityManager.checkUidPermission( 14695 INTERACT_ACROSS_USERS, 14696 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14697 ComponentName comp = new ComponentName(aInfo.packageName, className); 14698 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14699 + " requests FLAG_SINGLE_USER, but app does not hold " 14700 + INTERACT_ACROSS_USERS; 14701 Slog.w(TAG, msg); 14702 throw new SecurityException(msg); 14703 } 14704 // Permission passed 14705 result = true; 14706 } 14707 } else if ("system".equals(componentProcessName)) { 14708 result = true; 14709 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14710 // Phone app and persistent apps are allowed to export singleuser providers. 14711 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14712 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14713 } 14714 if (DEBUG_MU) { 14715 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14716 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14717 } 14718 return result; 14719 } 14720 14721 /** 14722 * Checks to see if the caller is in the same app as the singleton 14723 * component, or the component is in a special app. It allows special apps 14724 * to export singleton components but prevents exporting singleton 14725 * components for regular apps. 14726 */ 14727 boolean isValidSingletonCall(int callingUid, int componentUid) { 14728 int componentAppId = UserHandle.getAppId(componentUid); 14729 return UserHandle.isSameApp(callingUid, componentUid) 14730 || componentAppId == Process.SYSTEM_UID 14731 || componentAppId == Process.PHONE_UID 14732 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14733 == PackageManager.PERMISSION_GRANTED; 14734 } 14735 14736 public int bindService(IApplicationThread caller, IBinder token, 14737 Intent service, String resolvedType, 14738 IServiceConnection connection, int flags, int userId) { 14739 enforceNotIsolatedCaller("bindService"); 14740 14741 // Refuse possible leaked file descriptors 14742 if (service != null && service.hasFileDescriptors() == true) { 14743 throw new IllegalArgumentException("File descriptors passed in Intent"); 14744 } 14745 14746 synchronized(this) { 14747 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14748 connection, flags, userId); 14749 } 14750 } 14751 14752 public boolean unbindService(IServiceConnection connection) { 14753 synchronized (this) { 14754 return mServices.unbindServiceLocked(connection); 14755 } 14756 } 14757 14758 public void publishService(IBinder token, Intent intent, IBinder service) { 14759 // Refuse possible leaked file descriptors 14760 if (intent != null && intent.hasFileDescriptors() == true) { 14761 throw new IllegalArgumentException("File descriptors passed in Intent"); 14762 } 14763 14764 synchronized(this) { 14765 if (!(token instanceof ServiceRecord)) { 14766 throw new IllegalArgumentException("Invalid service token"); 14767 } 14768 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14769 } 14770 } 14771 14772 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14773 // Refuse possible leaked file descriptors 14774 if (intent != null && intent.hasFileDescriptors() == true) { 14775 throw new IllegalArgumentException("File descriptors passed in Intent"); 14776 } 14777 14778 synchronized(this) { 14779 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14780 } 14781 } 14782 14783 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14784 synchronized(this) { 14785 if (!(token instanceof ServiceRecord)) { 14786 throw new IllegalArgumentException("Invalid service token"); 14787 } 14788 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14789 } 14790 } 14791 14792 // ========================================================= 14793 // BACKUP AND RESTORE 14794 // ========================================================= 14795 14796 // Cause the target app to be launched if necessary and its backup agent 14797 // instantiated. The backup agent will invoke backupAgentCreated() on the 14798 // activity manager to announce its creation. 14799 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14800 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14801 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14802 14803 synchronized(this) { 14804 // !!! TODO: currently no check here that we're already bound 14805 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14806 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14807 synchronized (stats) { 14808 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14809 } 14810 14811 // Backup agent is now in use, its package can't be stopped. 14812 try { 14813 AppGlobals.getPackageManager().setPackageStoppedState( 14814 app.packageName, false, UserHandle.getUserId(app.uid)); 14815 } catch (RemoteException e) { 14816 } catch (IllegalArgumentException e) { 14817 Slog.w(TAG, "Failed trying to unstop package " 14818 + app.packageName + ": " + e); 14819 } 14820 14821 BackupRecord r = new BackupRecord(ss, app, backupMode); 14822 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14823 ? new ComponentName(app.packageName, app.backupAgentName) 14824 : new ComponentName("android", "FullBackupAgent"); 14825 // startProcessLocked() returns existing proc's record if it's already running 14826 ProcessRecord proc = startProcessLocked(app.processName, app, 14827 false, 0, "backup", hostingName, false, false, false); 14828 if (proc == null) { 14829 Slog.e(TAG, "Unable to start backup agent process " + r); 14830 return false; 14831 } 14832 14833 r.app = proc; 14834 mBackupTarget = r; 14835 mBackupAppName = app.packageName; 14836 14837 // Try not to kill the process during backup 14838 updateOomAdjLocked(proc); 14839 14840 // If the process is already attached, schedule the creation of the backup agent now. 14841 // If it is not yet live, this will be done when it attaches to the framework. 14842 if (proc.thread != null) { 14843 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14844 try { 14845 proc.thread.scheduleCreateBackupAgent(app, 14846 compatibilityInfoForPackageLocked(app), backupMode); 14847 } catch (RemoteException e) { 14848 // Will time out on the backup manager side 14849 } 14850 } else { 14851 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14852 } 14853 // Invariants: at this point, the target app process exists and the application 14854 // is either already running or in the process of coming up. mBackupTarget and 14855 // mBackupAppName describe the app, so that when it binds back to the AM we 14856 // know that it's scheduled for a backup-agent operation. 14857 } 14858 14859 return true; 14860 } 14861 14862 @Override 14863 public void clearPendingBackup() { 14864 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14865 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14866 14867 synchronized (this) { 14868 mBackupTarget = null; 14869 mBackupAppName = null; 14870 } 14871 } 14872 14873 // A backup agent has just come up 14874 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14875 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14876 + " = " + agent); 14877 14878 synchronized(this) { 14879 if (!agentPackageName.equals(mBackupAppName)) { 14880 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14881 return; 14882 } 14883 } 14884 14885 long oldIdent = Binder.clearCallingIdentity(); 14886 try { 14887 IBackupManager bm = IBackupManager.Stub.asInterface( 14888 ServiceManager.getService(Context.BACKUP_SERVICE)); 14889 bm.agentConnected(agentPackageName, agent); 14890 } catch (RemoteException e) { 14891 // can't happen; the backup manager service is local 14892 } catch (Exception e) { 14893 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14894 e.printStackTrace(); 14895 } finally { 14896 Binder.restoreCallingIdentity(oldIdent); 14897 } 14898 } 14899 14900 // done with this agent 14901 public void unbindBackupAgent(ApplicationInfo appInfo) { 14902 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14903 if (appInfo == null) { 14904 Slog.w(TAG, "unbind backup agent for null app"); 14905 return; 14906 } 14907 14908 synchronized(this) { 14909 try { 14910 if (mBackupAppName == null) { 14911 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14912 return; 14913 } 14914 14915 if (!mBackupAppName.equals(appInfo.packageName)) { 14916 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14917 return; 14918 } 14919 14920 // Not backing this app up any more; reset its OOM adjustment 14921 final ProcessRecord proc = mBackupTarget.app; 14922 updateOomAdjLocked(proc); 14923 14924 // If the app crashed during backup, 'thread' will be null here 14925 if (proc.thread != null) { 14926 try { 14927 proc.thread.scheduleDestroyBackupAgent(appInfo, 14928 compatibilityInfoForPackageLocked(appInfo)); 14929 } catch (Exception e) { 14930 Slog.e(TAG, "Exception when unbinding backup agent:"); 14931 e.printStackTrace(); 14932 } 14933 } 14934 } finally { 14935 mBackupTarget = null; 14936 mBackupAppName = null; 14937 } 14938 } 14939 } 14940 // ========================================================= 14941 // BROADCASTS 14942 // ========================================================= 14943 14944 private final List getStickiesLocked(String action, IntentFilter filter, 14945 List cur, int userId) { 14946 final ContentResolver resolver = mContext.getContentResolver(); 14947 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14948 if (stickies == null) { 14949 return cur; 14950 } 14951 final ArrayList<Intent> list = stickies.get(action); 14952 if (list == null) { 14953 return cur; 14954 } 14955 int N = list.size(); 14956 for (int i=0; i<N; i++) { 14957 Intent intent = list.get(i); 14958 if (filter.match(resolver, intent, true, TAG) >= 0) { 14959 if (cur == null) { 14960 cur = new ArrayList<Intent>(); 14961 } 14962 cur.add(intent); 14963 } 14964 } 14965 return cur; 14966 } 14967 14968 boolean isPendingBroadcastProcessLocked(int pid) { 14969 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14970 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14971 } 14972 14973 void skipPendingBroadcastLocked(int pid) { 14974 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14975 for (BroadcastQueue queue : mBroadcastQueues) { 14976 queue.skipPendingBroadcastLocked(pid); 14977 } 14978 } 14979 14980 // The app just attached; send any pending broadcasts that it should receive 14981 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14982 boolean didSomething = false; 14983 for (BroadcastQueue queue : mBroadcastQueues) { 14984 didSomething |= queue.sendPendingBroadcastsLocked(app); 14985 } 14986 return didSomething; 14987 } 14988 14989 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14990 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14991 enforceNotIsolatedCaller("registerReceiver"); 14992 int callingUid; 14993 int callingPid; 14994 synchronized(this) { 14995 ProcessRecord callerApp = null; 14996 if (caller != null) { 14997 callerApp = getRecordForAppLocked(caller); 14998 if (callerApp == null) { 14999 throw new SecurityException( 15000 "Unable to find app for caller " + caller 15001 + " (pid=" + Binder.getCallingPid() 15002 + ") when registering receiver " + receiver); 15003 } 15004 if (callerApp.info.uid != Process.SYSTEM_UID && 15005 !callerApp.pkgList.containsKey(callerPackage) && 15006 !"android".equals(callerPackage)) { 15007 throw new SecurityException("Given caller package " + callerPackage 15008 + " is not running in process " + callerApp); 15009 } 15010 callingUid = callerApp.info.uid; 15011 callingPid = callerApp.pid; 15012 } else { 15013 callerPackage = null; 15014 callingUid = Binder.getCallingUid(); 15015 callingPid = Binder.getCallingPid(); 15016 } 15017 15018 userId = this.handleIncomingUser(callingPid, callingUid, userId, 15019 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 15020 15021 List allSticky = null; 15022 15023 // Look for any matching sticky broadcasts... 15024 Iterator actions = filter.actionsIterator(); 15025 if (actions != null) { 15026 while (actions.hasNext()) { 15027 String action = (String)actions.next(); 15028 allSticky = getStickiesLocked(action, filter, allSticky, 15029 UserHandle.USER_ALL); 15030 allSticky = getStickiesLocked(action, filter, allSticky, 15031 UserHandle.getUserId(callingUid)); 15032 } 15033 } else { 15034 allSticky = getStickiesLocked(null, filter, allSticky, 15035 UserHandle.USER_ALL); 15036 allSticky = getStickiesLocked(null, filter, allSticky, 15037 UserHandle.getUserId(callingUid)); 15038 } 15039 15040 // The first sticky in the list is returned directly back to 15041 // the client. 15042 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 15043 15044 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 15045 + ": " + sticky); 15046 15047 if (receiver == null) { 15048 return sticky; 15049 } 15050 15051 ReceiverList rl 15052 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 15053 if (rl == null) { 15054 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 15055 userId, receiver); 15056 if (rl.app != null) { 15057 rl.app.receivers.add(rl); 15058 } else { 15059 try { 15060 receiver.asBinder().linkToDeath(rl, 0); 15061 } catch (RemoteException e) { 15062 return sticky; 15063 } 15064 rl.linkedToDeath = true; 15065 } 15066 mRegisteredReceivers.put(receiver.asBinder(), rl); 15067 } else if (rl.uid != callingUid) { 15068 throw new IllegalArgumentException( 15069 "Receiver requested to register for uid " + callingUid 15070 + " was previously registered for uid " + rl.uid); 15071 } else if (rl.pid != callingPid) { 15072 throw new IllegalArgumentException( 15073 "Receiver requested to register for pid " + callingPid 15074 + " was previously registered for pid " + rl.pid); 15075 } else if (rl.userId != userId) { 15076 throw new IllegalArgumentException( 15077 "Receiver requested to register for user " + userId 15078 + " was previously registered for user " + rl.userId); 15079 } 15080 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 15081 permission, callingUid, userId); 15082 rl.add(bf); 15083 if (!bf.debugCheck()) { 15084 Slog.w(TAG, "==> For Dynamic broadast"); 15085 } 15086 mReceiverResolver.addFilter(bf); 15087 15088 // Enqueue broadcasts for all existing stickies that match 15089 // this filter. 15090 if (allSticky != null) { 15091 ArrayList receivers = new ArrayList(); 15092 receivers.add(bf); 15093 15094 int N = allSticky.size(); 15095 for (int i=0; i<N; i++) { 15096 Intent intent = (Intent)allSticky.get(i); 15097 BroadcastQueue queue = broadcastQueueForIntent(intent); 15098 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15099 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15100 null, null, false, true, true, -1); 15101 queue.enqueueParallelBroadcastLocked(r); 15102 queue.scheduleBroadcastsLocked(); 15103 } 15104 } 15105 15106 return sticky; 15107 } 15108 } 15109 15110 public void unregisterReceiver(IIntentReceiver receiver) { 15111 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15112 15113 final long origId = Binder.clearCallingIdentity(); 15114 try { 15115 boolean doTrim = false; 15116 15117 synchronized(this) { 15118 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15119 if (rl != null) { 15120 if (rl.curBroadcast != null) { 15121 BroadcastRecord r = rl.curBroadcast; 15122 final boolean doNext = finishReceiverLocked( 15123 receiver.asBinder(), r.resultCode, r.resultData, 15124 r.resultExtras, r.resultAbort); 15125 if (doNext) { 15126 doTrim = true; 15127 r.queue.processNextBroadcast(false); 15128 } 15129 } 15130 15131 if (rl.app != null) { 15132 rl.app.receivers.remove(rl); 15133 } 15134 removeReceiverLocked(rl); 15135 if (rl.linkedToDeath) { 15136 rl.linkedToDeath = false; 15137 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15138 } 15139 } 15140 } 15141 15142 // If we actually concluded any broadcasts, we might now be able 15143 // to trim the recipients' apps from our working set 15144 if (doTrim) { 15145 trimApplications(); 15146 return; 15147 } 15148 15149 } finally { 15150 Binder.restoreCallingIdentity(origId); 15151 } 15152 } 15153 15154 void removeReceiverLocked(ReceiverList rl) { 15155 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15156 int N = rl.size(); 15157 for (int i=0; i<N; i++) { 15158 mReceiverResolver.removeFilter(rl.get(i)); 15159 } 15160 } 15161 15162 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15163 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15164 ProcessRecord r = mLruProcesses.get(i); 15165 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15166 try { 15167 r.thread.dispatchPackageBroadcast(cmd, packages); 15168 } catch (RemoteException ex) { 15169 } 15170 } 15171 } 15172 } 15173 15174 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15175 int callingUid, int[] users) { 15176 List<ResolveInfo> receivers = null; 15177 try { 15178 HashSet<ComponentName> singleUserReceivers = null; 15179 boolean scannedFirstReceivers = false; 15180 for (int user : users) { 15181 // Skip users that have Shell restrictions 15182 if (callingUid == Process.SHELL_UID 15183 && getUserManagerLocked().hasUserRestriction( 15184 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) { 15185 continue; 15186 } 15187 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15188 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15189 if (user != 0 && newReceivers != null) { 15190 // If this is not the primary user, we need to check for 15191 // any receivers that should be filtered out. 15192 for (int i=0; i<newReceivers.size(); i++) { 15193 ResolveInfo ri = newReceivers.get(i); 15194 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15195 newReceivers.remove(i); 15196 i--; 15197 } 15198 } 15199 } 15200 if (newReceivers != null && newReceivers.size() == 0) { 15201 newReceivers = null; 15202 } 15203 if (receivers == null) { 15204 receivers = newReceivers; 15205 } else if (newReceivers != null) { 15206 // We need to concatenate the additional receivers 15207 // found with what we have do far. This would be easy, 15208 // but we also need to de-dup any receivers that are 15209 // singleUser. 15210 if (!scannedFirstReceivers) { 15211 // Collect any single user receivers we had already retrieved. 15212 scannedFirstReceivers = true; 15213 for (int i=0; i<receivers.size(); i++) { 15214 ResolveInfo ri = receivers.get(i); 15215 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15216 ComponentName cn = new ComponentName( 15217 ri.activityInfo.packageName, ri.activityInfo.name); 15218 if (singleUserReceivers == null) { 15219 singleUserReceivers = new HashSet<ComponentName>(); 15220 } 15221 singleUserReceivers.add(cn); 15222 } 15223 } 15224 } 15225 // Add the new results to the existing results, tracking 15226 // and de-dupping single user receivers. 15227 for (int i=0; i<newReceivers.size(); i++) { 15228 ResolveInfo ri = newReceivers.get(i); 15229 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15230 ComponentName cn = new ComponentName( 15231 ri.activityInfo.packageName, ri.activityInfo.name); 15232 if (singleUserReceivers == null) { 15233 singleUserReceivers = new HashSet<ComponentName>(); 15234 } 15235 if (!singleUserReceivers.contains(cn)) { 15236 singleUserReceivers.add(cn); 15237 receivers.add(ri); 15238 } 15239 } else { 15240 receivers.add(ri); 15241 } 15242 } 15243 } 15244 } 15245 } catch (RemoteException ex) { 15246 // pm is in same process, this will never happen. 15247 } 15248 return receivers; 15249 } 15250 15251 private final int broadcastIntentLocked(ProcessRecord callerApp, 15252 String callerPackage, Intent intent, String resolvedType, 15253 IIntentReceiver resultTo, int resultCode, String resultData, 15254 Bundle map, String requiredPermission, int appOp, 15255 boolean ordered, boolean sticky, int callingPid, int callingUid, 15256 int userId) { 15257 intent = new Intent(intent); 15258 15259 // By default broadcasts do not go to stopped apps. 15260 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15261 15262 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15263 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15264 + " ordered=" + ordered + " userid=" + userId); 15265 if ((resultTo != null) && !ordered) { 15266 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15267 } 15268 15269 userId = handleIncomingUser(callingPid, callingUid, userId, 15270 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15271 15272 // Make sure that the user who is receiving this broadcast is started. 15273 // If not, we will just skip it. 15274 15275 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15276 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15277 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15278 Slog.w(TAG, "Skipping broadcast of " + intent 15279 + ": user " + userId + " is stopped"); 15280 return ActivityManager.BROADCAST_SUCCESS; 15281 } 15282 } 15283 15284 /* 15285 * Prevent non-system code (defined here to be non-persistent 15286 * processes) from sending protected broadcasts. 15287 */ 15288 int callingAppId = UserHandle.getAppId(callingUid); 15289 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15290 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15291 || callingAppId == Process.NFC_UID || callingUid == 0) { 15292 // Always okay. 15293 } else if (callerApp == null || !callerApp.persistent) { 15294 try { 15295 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15296 intent.getAction())) { 15297 String msg = "Permission Denial: not allowed to send broadcast " 15298 + intent.getAction() + " from pid=" 15299 + callingPid + ", uid=" + callingUid; 15300 Slog.w(TAG, msg); 15301 throw new SecurityException(msg); 15302 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15303 // Special case for compatibility: we don't want apps to send this, 15304 // but historically it has not been protected and apps may be using it 15305 // to poke their own app widget. So, instead of making it protected, 15306 // just limit it to the caller. 15307 if (callerApp == null) { 15308 String msg = "Permission Denial: not allowed to send broadcast " 15309 + intent.getAction() + " from unknown caller."; 15310 Slog.w(TAG, msg); 15311 throw new SecurityException(msg); 15312 } else if (intent.getComponent() != null) { 15313 // They are good enough to send to an explicit component... verify 15314 // it is being sent to the calling app. 15315 if (!intent.getComponent().getPackageName().equals( 15316 callerApp.info.packageName)) { 15317 String msg = "Permission Denial: not allowed to send broadcast " 15318 + intent.getAction() + " to " 15319 + intent.getComponent().getPackageName() + " from " 15320 + callerApp.info.packageName; 15321 Slog.w(TAG, msg); 15322 throw new SecurityException(msg); 15323 } 15324 } else { 15325 // Limit broadcast to their own package. 15326 intent.setPackage(callerApp.info.packageName); 15327 } 15328 } 15329 } catch (RemoteException e) { 15330 Slog.w(TAG, "Remote exception", e); 15331 return ActivityManager.BROADCAST_SUCCESS; 15332 } 15333 } 15334 15335 // Handle special intents: if this broadcast is from the package 15336 // manager about a package being removed, we need to remove all of 15337 // its activities from the history stack. 15338 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15339 intent.getAction()); 15340 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15341 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15342 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15343 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15344 || uidRemoved) { 15345 if (checkComponentPermission( 15346 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15347 callingPid, callingUid, -1, true) 15348 == PackageManager.PERMISSION_GRANTED) { 15349 if (uidRemoved) { 15350 final Bundle intentExtras = intent.getExtras(); 15351 final int uid = intentExtras != null 15352 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15353 if (uid >= 0) { 15354 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15355 synchronized (bs) { 15356 bs.removeUidStatsLocked(uid); 15357 } 15358 mAppOpsService.uidRemoved(uid); 15359 } 15360 } else { 15361 // If resources are unavailable just force stop all 15362 // those packages and flush the attribute cache as well. 15363 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15364 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15365 if (list != null && (list.length > 0)) { 15366 for (String pkg : list) { 15367 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15368 "storage unmount"); 15369 } 15370 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15371 sendPackageBroadcastLocked( 15372 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15373 } 15374 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15375 intent.getAction())) { 15376 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15377 } else { 15378 Uri data = intent.getData(); 15379 String ssp; 15380 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15381 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15382 intent.getAction()); 15383 boolean fullUninstall = removed && 15384 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15385 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15386 forceStopPackageLocked(ssp, UserHandle.getAppId( 15387 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15388 false, fullUninstall, userId, 15389 removed ? "pkg removed" : "pkg changed"); 15390 } 15391 if (removed) { 15392 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15393 new String[] {ssp}, userId); 15394 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15395 mAppOpsService.packageRemoved( 15396 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15397 15398 // Remove all permissions granted from/to this package 15399 removeUriPermissionsForPackageLocked(ssp, userId, true); 15400 } 15401 } 15402 } 15403 } 15404 } 15405 } else { 15406 String msg = "Permission Denial: " + intent.getAction() 15407 + " broadcast from " + callerPackage + " (pid=" + callingPid 15408 + ", uid=" + callingUid + ")" 15409 + " requires " 15410 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15411 Slog.w(TAG, msg); 15412 throw new SecurityException(msg); 15413 } 15414 15415 // Special case for adding a package: by default turn on compatibility 15416 // mode. 15417 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15418 Uri data = intent.getData(); 15419 String ssp; 15420 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15421 mCompatModePackages.handlePackageAddedLocked(ssp, 15422 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15423 } 15424 } 15425 15426 /* 15427 * If this is the time zone changed action, queue up a message that will reset the timezone 15428 * of all currently running processes. This message will get queued up before the broadcast 15429 * happens. 15430 */ 15431 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15432 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15433 } 15434 15435 /* 15436 * If the user set the time, let all running processes know. 15437 */ 15438 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15439 final int is24Hour = intent.getBooleanExtra( 15440 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15441 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15442 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15443 synchronized (stats) { 15444 stats.noteCurrentTimeChangedLocked(); 15445 } 15446 } 15447 15448 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15449 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15450 } 15451 15452 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15453 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15454 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15455 } 15456 15457 // Add to the sticky list if requested. 15458 if (sticky) { 15459 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15460 callingPid, callingUid) 15461 != PackageManager.PERMISSION_GRANTED) { 15462 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15463 + callingPid + ", uid=" + callingUid 15464 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15465 Slog.w(TAG, msg); 15466 throw new SecurityException(msg); 15467 } 15468 if (requiredPermission != null) { 15469 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15470 + " and enforce permission " + requiredPermission); 15471 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15472 } 15473 if (intent.getComponent() != null) { 15474 throw new SecurityException( 15475 "Sticky broadcasts can't target a specific component"); 15476 } 15477 // We use userId directly here, since the "all" target is maintained 15478 // as a separate set of sticky broadcasts. 15479 if (userId != UserHandle.USER_ALL) { 15480 // But first, if this is not a broadcast to all users, then 15481 // make sure it doesn't conflict with an existing broadcast to 15482 // all users. 15483 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15484 UserHandle.USER_ALL); 15485 if (stickies != null) { 15486 ArrayList<Intent> list = stickies.get(intent.getAction()); 15487 if (list != null) { 15488 int N = list.size(); 15489 int i; 15490 for (i=0; i<N; i++) { 15491 if (intent.filterEquals(list.get(i))) { 15492 throw new IllegalArgumentException( 15493 "Sticky broadcast " + intent + " for user " 15494 + userId + " conflicts with existing global broadcast"); 15495 } 15496 } 15497 } 15498 } 15499 } 15500 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15501 if (stickies == null) { 15502 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15503 mStickyBroadcasts.put(userId, stickies); 15504 } 15505 ArrayList<Intent> list = stickies.get(intent.getAction()); 15506 if (list == null) { 15507 list = new ArrayList<Intent>(); 15508 stickies.put(intent.getAction(), list); 15509 } 15510 int N = list.size(); 15511 int i; 15512 for (i=0; i<N; i++) { 15513 if (intent.filterEquals(list.get(i))) { 15514 // This sticky already exists, replace it. 15515 list.set(i, new Intent(intent)); 15516 break; 15517 } 15518 } 15519 if (i >= N) { 15520 list.add(new Intent(intent)); 15521 } 15522 } 15523 15524 int[] users; 15525 if (userId == UserHandle.USER_ALL) { 15526 // Caller wants broadcast to go to all started users. 15527 users = mStartedUserArray; 15528 } else { 15529 // Caller wants broadcast to go to one specific user. 15530 users = new int[] {userId}; 15531 } 15532 15533 // Figure out who all will receive this broadcast. 15534 List receivers = null; 15535 List<BroadcastFilter> registeredReceivers = null; 15536 // Need to resolve the intent to interested receivers... 15537 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15538 == 0) { 15539 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 15540 } 15541 if (intent.getComponent() == null) { 15542 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 15543 // Query one target user at a time, excluding shell-restricted users 15544 UserManagerService ums = getUserManagerLocked(); 15545 for (int i = 0; i < users.length; i++) { 15546 if (ums.hasUserRestriction( 15547 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 15548 continue; 15549 } 15550 List<BroadcastFilter> registeredReceiversForUser = 15551 mReceiverResolver.queryIntent(intent, 15552 resolvedType, false, users[i]); 15553 if (registeredReceivers == null) { 15554 registeredReceivers = registeredReceiversForUser; 15555 } else if (registeredReceiversForUser != null) { 15556 registeredReceivers.addAll(registeredReceiversForUser); 15557 } 15558 } 15559 } else { 15560 registeredReceivers = mReceiverResolver.queryIntent(intent, 15561 resolvedType, false, userId); 15562 } 15563 } 15564 15565 final boolean replacePending = 15566 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15567 15568 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15569 + " replacePending=" + replacePending); 15570 15571 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15572 if (!ordered && NR > 0) { 15573 // If we are not serializing this broadcast, then send the 15574 // registered receivers separately so they don't wait for the 15575 // components to be launched. 15576 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15577 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15578 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15579 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15580 ordered, sticky, false, userId); 15581 if (DEBUG_BROADCAST) Slog.v( 15582 TAG, "Enqueueing parallel broadcast " + r); 15583 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15584 if (!replaced) { 15585 queue.enqueueParallelBroadcastLocked(r); 15586 queue.scheduleBroadcastsLocked(); 15587 } 15588 registeredReceivers = null; 15589 NR = 0; 15590 } 15591 15592 // Merge into one list. 15593 int ir = 0; 15594 if (receivers != null) { 15595 // A special case for PACKAGE_ADDED: do not allow the package 15596 // being added to see this broadcast. This prevents them from 15597 // using this as a back door to get run as soon as they are 15598 // installed. Maybe in the future we want to have a special install 15599 // broadcast or such for apps, but we'd like to deliberately make 15600 // this decision. 15601 String skipPackages[] = null; 15602 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15603 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15604 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15605 Uri data = intent.getData(); 15606 if (data != null) { 15607 String pkgName = data.getSchemeSpecificPart(); 15608 if (pkgName != null) { 15609 skipPackages = new String[] { pkgName }; 15610 } 15611 } 15612 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15613 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15614 } 15615 if (skipPackages != null && (skipPackages.length > 0)) { 15616 for (String skipPackage : skipPackages) { 15617 if (skipPackage != null) { 15618 int NT = receivers.size(); 15619 for (int it=0; it<NT; it++) { 15620 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15621 if (curt.activityInfo.packageName.equals(skipPackage)) { 15622 receivers.remove(it); 15623 it--; 15624 NT--; 15625 } 15626 } 15627 } 15628 } 15629 } 15630 15631 int NT = receivers != null ? receivers.size() : 0; 15632 int it = 0; 15633 ResolveInfo curt = null; 15634 BroadcastFilter curr = null; 15635 while (it < NT && ir < NR) { 15636 if (curt == null) { 15637 curt = (ResolveInfo)receivers.get(it); 15638 } 15639 if (curr == null) { 15640 curr = registeredReceivers.get(ir); 15641 } 15642 if (curr.getPriority() >= curt.priority) { 15643 // Insert this broadcast record into the final list. 15644 receivers.add(it, curr); 15645 ir++; 15646 curr = null; 15647 it++; 15648 NT++; 15649 } else { 15650 // Skip to the next ResolveInfo in the final list. 15651 it++; 15652 curt = null; 15653 } 15654 } 15655 } 15656 while (ir < NR) { 15657 if (receivers == null) { 15658 receivers = new ArrayList(); 15659 } 15660 receivers.add(registeredReceivers.get(ir)); 15661 ir++; 15662 } 15663 15664 if ((receivers != null && receivers.size() > 0) 15665 || resultTo != null) { 15666 BroadcastQueue queue = broadcastQueueForIntent(intent); 15667 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15668 callerPackage, callingPid, callingUid, resolvedType, 15669 requiredPermission, appOp, receivers, resultTo, resultCode, 15670 resultData, map, ordered, sticky, false, userId); 15671 if (DEBUG_BROADCAST) Slog.v( 15672 TAG, "Enqueueing ordered broadcast " + r 15673 + ": prev had " + queue.mOrderedBroadcasts.size()); 15674 if (DEBUG_BROADCAST) { 15675 int seq = r.intent.getIntExtra("seq", -1); 15676 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15677 } 15678 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15679 if (!replaced) { 15680 queue.enqueueOrderedBroadcastLocked(r); 15681 queue.scheduleBroadcastsLocked(); 15682 } 15683 } 15684 15685 return ActivityManager.BROADCAST_SUCCESS; 15686 } 15687 15688 final Intent verifyBroadcastLocked(Intent intent) { 15689 // Refuse possible leaked file descriptors 15690 if (intent != null && intent.hasFileDescriptors() == true) { 15691 throw new IllegalArgumentException("File descriptors passed in Intent"); 15692 } 15693 15694 int flags = intent.getFlags(); 15695 15696 if (!mProcessesReady) { 15697 // if the caller really truly claims to know what they're doing, go 15698 // ahead and allow the broadcast without launching any receivers 15699 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15700 intent = new Intent(intent); 15701 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15702 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15703 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15704 + " before boot completion"); 15705 throw new IllegalStateException("Cannot broadcast before boot completed"); 15706 } 15707 } 15708 15709 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15710 throw new IllegalArgumentException( 15711 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15712 } 15713 15714 return intent; 15715 } 15716 15717 public final int broadcastIntent(IApplicationThread caller, 15718 Intent intent, String resolvedType, IIntentReceiver resultTo, 15719 int resultCode, String resultData, Bundle map, 15720 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15721 enforceNotIsolatedCaller("broadcastIntent"); 15722 synchronized(this) { 15723 intent = verifyBroadcastLocked(intent); 15724 15725 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15726 final int callingPid = Binder.getCallingPid(); 15727 final int callingUid = Binder.getCallingUid(); 15728 final long origId = Binder.clearCallingIdentity(); 15729 int res = broadcastIntentLocked(callerApp, 15730 callerApp != null ? callerApp.info.packageName : null, 15731 intent, resolvedType, resultTo, 15732 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15733 callingPid, callingUid, userId); 15734 Binder.restoreCallingIdentity(origId); 15735 return res; 15736 } 15737 } 15738 15739 int broadcastIntentInPackage(String packageName, int uid, 15740 Intent intent, String resolvedType, IIntentReceiver resultTo, 15741 int resultCode, String resultData, Bundle map, 15742 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15743 synchronized(this) { 15744 intent = verifyBroadcastLocked(intent); 15745 15746 final long origId = Binder.clearCallingIdentity(); 15747 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15748 resultTo, resultCode, resultData, map, requiredPermission, 15749 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15750 Binder.restoreCallingIdentity(origId); 15751 return res; 15752 } 15753 } 15754 15755 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15756 // Refuse possible leaked file descriptors 15757 if (intent != null && intent.hasFileDescriptors() == true) { 15758 throw new IllegalArgumentException("File descriptors passed in Intent"); 15759 } 15760 15761 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15762 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15763 15764 synchronized(this) { 15765 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15766 != PackageManager.PERMISSION_GRANTED) { 15767 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15768 + Binder.getCallingPid() 15769 + ", uid=" + Binder.getCallingUid() 15770 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15771 Slog.w(TAG, msg); 15772 throw new SecurityException(msg); 15773 } 15774 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15775 if (stickies != null) { 15776 ArrayList<Intent> list = stickies.get(intent.getAction()); 15777 if (list != null) { 15778 int N = list.size(); 15779 int i; 15780 for (i=0; i<N; i++) { 15781 if (intent.filterEquals(list.get(i))) { 15782 list.remove(i); 15783 break; 15784 } 15785 } 15786 if (list.size() <= 0) { 15787 stickies.remove(intent.getAction()); 15788 } 15789 } 15790 if (stickies.size() <= 0) { 15791 mStickyBroadcasts.remove(userId); 15792 } 15793 } 15794 } 15795 } 15796 15797 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15798 String resultData, Bundle resultExtras, boolean resultAbort) { 15799 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15800 if (r == null) { 15801 Slog.w(TAG, "finishReceiver called but not found on queue"); 15802 return false; 15803 } 15804 15805 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15806 } 15807 15808 void backgroundServicesFinishedLocked(int userId) { 15809 for (BroadcastQueue queue : mBroadcastQueues) { 15810 queue.backgroundServicesFinishedLocked(userId); 15811 } 15812 } 15813 15814 public void finishReceiver(IBinder who, int resultCode, String resultData, 15815 Bundle resultExtras, boolean resultAbort) { 15816 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15817 15818 // Refuse possible leaked file descriptors 15819 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15820 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15821 } 15822 15823 final long origId = Binder.clearCallingIdentity(); 15824 try { 15825 boolean doNext = false; 15826 BroadcastRecord r; 15827 15828 synchronized(this) { 15829 r = broadcastRecordForReceiverLocked(who); 15830 if (r != null) { 15831 doNext = r.queue.finishReceiverLocked(r, resultCode, 15832 resultData, resultExtras, resultAbort, true); 15833 } 15834 } 15835 15836 if (doNext) { 15837 r.queue.processNextBroadcast(false); 15838 } 15839 trimApplications(); 15840 } finally { 15841 Binder.restoreCallingIdentity(origId); 15842 } 15843 } 15844 15845 // ========================================================= 15846 // INSTRUMENTATION 15847 // ========================================================= 15848 15849 public boolean startInstrumentation(ComponentName className, 15850 String profileFile, int flags, Bundle arguments, 15851 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15852 int userId, String abiOverride) { 15853 enforceNotIsolatedCaller("startInstrumentation"); 15854 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15855 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15856 // Refuse possible leaked file descriptors 15857 if (arguments != null && arguments.hasFileDescriptors()) { 15858 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15859 } 15860 15861 synchronized(this) { 15862 InstrumentationInfo ii = null; 15863 ApplicationInfo ai = null; 15864 try { 15865 ii = mContext.getPackageManager().getInstrumentationInfo( 15866 className, STOCK_PM_FLAGS); 15867 ai = AppGlobals.getPackageManager().getApplicationInfo( 15868 ii.targetPackage, STOCK_PM_FLAGS, userId); 15869 } catch (PackageManager.NameNotFoundException e) { 15870 } catch (RemoteException e) { 15871 } 15872 if (ii == null) { 15873 reportStartInstrumentationFailure(watcher, className, 15874 "Unable to find instrumentation info for: " + className); 15875 return false; 15876 } 15877 if (ai == null) { 15878 reportStartInstrumentationFailure(watcher, className, 15879 "Unable to find instrumentation target package: " + ii.targetPackage); 15880 return false; 15881 } 15882 15883 int match = mContext.getPackageManager().checkSignatures( 15884 ii.targetPackage, ii.packageName); 15885 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15886 String msg = "Permission Denial: starting instrumentation " 15887 + className + " from pid=" 15888 + Binder.getCallingPid() 15889 + ", uid=" + Binder.getCallingPid() 15890 + " not allowed because package " + ii.packageName 15891 + " does not have a signature matching the target " 15892 + ii.targetPackage; 15893 reportStartInstrumentationFailure(watcher, className, msg); 15894 throw new SecurityException(msg); 15895 } 15896 15897 final long origId = Binder.clearCallingIdentity(); 15898 // Instrumentation can kill and relaunch even persistent processes 15899 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15900 "start instr"); 15901 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15902 app.instrumentationClass = className; 15903 app.instrumentationInfo = ai; 15904 app.instrumentationProfileFile = profileFile; 15905 app.instrumentationArguments = arguments; 15906 app.instrumentationWatcher = watcher; 15907 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15908 app.instrumentationResultClass = className; 15909 Binder.restoreCallingIdentity(origId); 15910 } 15911 15912 return true; 15913 } 15914 15915 /** 15916 * Report errors that occur while attempting to start Instrumentation. Always writes the 15917 * error to the logs, but if somebody is watching, send the report there too. This enables 15918 * the "am" command to report errors with more information. 15919 * 15920 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15921 * @param cn The component name of the instrumentation. 15922 * @param report The error report. 15923 */ 15924 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15925 ComponentName cn, String report) { 15926 Slog.w(TAG, report); 15927 try { 15928 if (watcher != null) { 15929 Bundle results = new Bundle(); 15930 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15931 results.putString("Error", report); 15932 watcher.instrumentationStatus(cn, -1, results); 15933 } 15934 } catch (RemoteException e) { 15935 Slog.w(TAG, e); 15936 } 15937 } 15938 15939 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15940 if (app.instrumentationWatcher != null) { 15941 try { 15942 // NOTE: IInstrumentationWatcher *must* be oneway here 15943 app.instrumentationWatcher.instrumentationFinished( 15944 app.instrumentationClass, 15945 resultCode, 15946 results); 15947 } catch (RemoteException e) { 15948 } 15949 } 15950 if (app.instrumentationUiAutomationConnection != null) { 15951 try { 15952 app.instrumentationUiAutomationConnection.shutdown(); 15953 } catch (RemoteException re) { 15954 /* ignore */ 15955 } 15956 // Only a UiAutomation can set this flag and now that 15957 // it is finished we make sure it is reset to its default. 15958 mUserIsMonkey = false; 15959 } 15960 app.instrumentationWatcher = null; 15961 app.instrumentationUiAutomationConnection = null; 15962 app.instrumentationClass = null; 15963 app.instrumentationInfo = null; 15964 app.instrumentationProfileFile = null; 15965 app.instrumentationArguments = null; 15966 15967 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15968 "finished inst"); 15969 } 15970 15971 public void finishInstrumentation(IApplicationThread target, 15972 int resultCode, Bundle results) { 15973 int userId = UserHandle.getCallingUserId(); 15974 // Refuse possible leaked file descriptors 15975 if (results != null && results.hasFileDescriptors()) { 15976 throw new IllegalArgumentException("File descriptors passed in Intent"); 15977 } 15978 15979 synchronized(this) { 15980 ProcessRecord app = getRecordForAppLocked(target); 15981 if (app == null) { 15982 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15983 return; 15984 } 15985 final long origId = Binder.clearCallingIdentity(); 15986 finishInstrumentationLocked(app, resultCode, results); 15987 Binder.restoreCallingIdentity(origId); 15988 } 15989 } 15990 15991 // ========================================================= 15992 // CONFIGURATION 15993 // ========================================================= 15994 15995 public ConfigurationInfo getDeviceConfigurationInfo() { 15996 ConfigurationInfo config = new ConfigurationInfo(); 15997 synchronized (this) { 15998 config.reqTouchScreen = mConfiguration.touchscreen; 15999 config.reqKeyboardType = mConfiguration.keyboard; 16000 config.reqNavigation = mConfiguration.navigation; 16001 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 16002 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 16003 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16004 } 16005 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 16006 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 16007 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 16008 } 16009 config.reqGlEsVersion = GL_ES_VERSION; 16010 } 16011 return config; 16012 } 16013 16014 ActivityStack getFocusedStack() { 16015 return mStackSupervisor.getFocusedStack(); 16016 } 16017 16018 public Configuration getConfiguration() { 16019 Configuration ci; 16020 synchronized(this) { 16021 ci = new Configuration(mConfiguration); 16022 } 16023 return ci; 16024 } 16025 16026 public void updatePersistentConfiguration(Configuration values) { 16027 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16028 "updateConfiguration()"); 16029 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 16030 "updateConfiguration()"); 16031 if (values == null) { 16032 throw new NullPointerException("Configuration must not be null"); 16033 } 16034 16035 synchronized(this) { 16036 final long origId = Binder.clearCallingIdentity(); 16037 updateConfigurationLocked(values, null, true, false); 16038 Binder.restoreCallingIdentity(origId); 16039 } 16040 } 16041 16042 public void updateConfiguration(Configuration values) { 16043 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 16044 "updateConfiguration()"); 16045 16046 synchronized(this) { 16047 if (values == null && mWindowManager != null) { 16048 // sentinel: fetch the current configuration from the window manager 16049 values = mWindowManager.computeNewConfiguration(); 16050 } 16051 16052 if (mWindowManager != null) { 16053 mProcessList.applyDisplaySize(mWindowManager); 16054 } 16055 16056 final long origId = Binder.clearCallingIdentity(); 16057 if (values != null) { 16058 Settings.System.clearConfiguration(values); 16059 } 16060 updateConfigurationLocked(values, null, false, false); 16061 Binder.restoreCallingIdentity(origId); 16062 } 16063 } 16064 16065 /** 16066 * Do either or both things: (1) change the current configuration, and (2) 16067 * make sure the given activity is running with the (now) current 16068 * configuration. Returns true if the activity has been left running, or 16069 * false if <var>starting</var> is being destroyed to match the new 16070 * configuration. 16071 * @param persistent TODO 16072 */ 16073 boolean updateConfigurationLocked(Configuration values, 16074 ActivityRecord starting, boolean persistent, boolean initLocale) { 16075 int changes = 0; 16076 16077 if (values != null) { 16078 Configuration newConfig = new Configuration(mConfiguration); 16079 changes = newConfig.updateFrom(values); 16080 if (changes != 0) { 16081 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 16082 Slog.i(TAG, "Updating configuration to: " + values); 16083 } 16084 16085 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 16086 16087 if (values.locale != null && !initLocale) { 16088 saveLocaleLocked(values.locale, 16089 !values.locale.equals(mConfiguration.locale), 16090 values.userSetLocale); 16091 } 16092 16093 mConfigurationSeq++; 16094 if (mConfigurationSeq <= 0) { 16095 mConfigurationSeq = 1; 16096 } 16097 newConfig.seq = mConfigurationSeq; 16098 mConfiguration = newConfig; 16099 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 16100 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 16101 //mUsageStatsService.noteStartConfig(newConfig); 16102 16103 final Configuration configCopy = new Configuration(mConfiguration); 16104 16105 // TODO: If our config changes, should we auto dismiss any currently 16106 // showing dialogs? 16107 mShowDialogs = shouldShowDialogs(newConfig); 16108 16109 AttributeCache ac = AttributeCache.instance(); 16110 if (ac != null) { 16111 ac.updateConfiguration(configCopy); 16112 } 16113 16114 // Make sure all resources in our process are updated 16115 // right now, so that anyone who is going to retrieve 16116 // resource values after we return will be sure to get 16117 // the new ones. This is especially important during 16118 // boot, where the first config change needs to guarantee 16119 // all resources have that config before following boot 16120 // code is executed. 16121 mSystemThread.applyConfigurationToResources(configCopy); 16122 16123 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16124 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16125 msg.obj = new Configuration(configCopy); 16126 mHandler.sendMessage(msg); 16127 } 16128 16129 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16130 ProcessRecord app = mLruProcesses.get(i); 16131 try { 16132 if (app.thread != null) { 16133 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16134 + app.processName + " new config " + mConfiguration); 16135 app.thread.scheduleConfigurationChanged(configCopy); 16136 } 16137 } catch (Exception e) { 16138 } 16139 } 16140 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16141 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16142 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16143 | Intent.FLAG_RECEIVER_FOREGROUND); 16144 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16145 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16146 Process.SYSTEM_UID, UserHandle.USER_ALL); 16147 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16148 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16149 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16150 broadcastIntentLocked(null, null, intent, 16151 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16152 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16153 } 16154 } 16155 } 16156 16157 boolean kept = true; 16158 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16159 // mainStack is null during startup. 16160 if (mainStack != null) { 16161 if (changes != 0 && starting == null) { 16162 // If the configuration changed, and the caller is not already 16163 // in the process of starting an activity, then find the top 16164 // activity to check if its configuration needs to change. 16165 starting = mainStack.topRunningActivityLocked(null); 16166 } 16167 16168 if (starting != null) { 16169 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16170 // And we need to make sure at this point that all other activities 16171 // are made visible with the correct configuration. 16172 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16173 } 16174 } 16175 16176 if (values != null && mWindowManager != null) { 16177 mWindowManager.setNewConfiguration(mConfiguration); 16178 } 16179 16180 return kept; 16181 } 16182 16183 /** 16184 * Decide based on the configuration whether we should shouw the ANR, 16185 * crash, etc dialogs. The idea is that if there is no affordnace to 16186 * press the on-screen buttons, we shouldn't show the dialog. 16187 * 16188 * A thought: SystemUI might also want to get told about this, the Power 16189 * dialog / global actions also might want different behaviors. 16190 */ 16191 private static final boolean shouldShowDialogs(Configuration config) { 16192 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16193 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16194 } 16195 16196 /** 16197 * Save the locale. You must be inside a synchronized (this) block. 16198 */ 16199 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16200 if(isDiff) { 16201 SystemProperties.set("user.language", l.getLanguage()); 16202 SystemProperties.set("user.region", l.getCountry()); 16203 } 16204 16205 if(isPersist) { 16206 SystemProperties.set("persist.sys.language", l.getLanguage()); 16207 SystemProperties.set("persist.sys.country", l.getCountry()); 16208 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16209 } 16210 } 16211 16212 @Override 16213 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16214 synchronized (this) { 16215 ActivityRecord srec = ActivityRecord.forToken(token); 16216 if (srec.task != null && srec.task.stack != null) { 16217 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16218 } 16219 } 16220 return false; 16221 } 16222 16223 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16224 Intent resultData) { 16225 16226 synchronized (this) { 16227 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16228 if (stack != null) { 16229 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16230 } 16231 return false; 16232 } 16233 } 16234 16235 public int getLaunchedFromUid(IBinder activityToken) { 16236 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16237 if (srec == null) { 16238 return -1; 16239 } 16240 return srec.launchedFromUid; 16241 } 16242 16243 public String getLaunchedFromPackage(IBinder activityToken) { 16244 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16245 if (srec == null) { 16246 return null; 16247 } 16248 return srec.launchedFromPackage; 16249 } 16250 16251 // ========================================================= 16252 // LIFETIME MANAGEMENT 16253 // ========================================================= 16254 16255 // Returns which broadcast queue the app is the current [or imminent] receiver 16256 // on, or 'null' if the app is not an active broadcast recipient. 16257 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16258 BroadcastRecord r = app.curReceiver; 16259 if (r != null) { 16260 return r.queue; 16261 } 16262 16263 // It's not the current receiver, but it might be starting up to become one 16264 synchronized (this) { 16265 for (BroadcastQueue queue : mBroadcastQueues) { 16266 r = queue.mPendingBroadcast; 16267 if (r != null && r.curApp == app) { 16268 // found it; report which queue it's in 16269 return queue; 16270 } 16271 } 16272 } 16273 16274 return null; 16275 } 16276 16277 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16278 boolean doingAll, long now) { 16279 if (mAdjSeq == app.adjSeq) { 16280 // This adjustment has already been computed. 16281 return app.curRawAdj; 16282 } 16283 16284 if (app.thread == null) { 16285 app.adjSeq = mAdjSeq; 16286 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16287 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16288 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16289 } 16290 16291 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16292 app.adjSource = null; 16293 app.adjTarget = null; 16294 app.empty = false; 16295 app.cached = false; 16296 16297 final int activitiesSize = app.activities.size(); 16298 16299 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16300 // The max adjustment doesn't allow this app to be anything 16301 // below foreground, so it is not worth doing work for it. 16302 app.adjType = "fixed"; 16303 app.adjSeq = mAdjSeq; 16304 app.curRawAdj = app.maxAdj; 16305 app.foregroundActivities = false; 16306 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16307 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16308 // System processes can do UI, and when they do we want to have 16309 // them trim their memory after the user leaves the UI. To 16310 // facilitate this, here we need to determine whether or not it 16311 // is currently showing UI. 16312 app.systemNoUi = true; 16313 if (app == TOP_APP) { 16314 app.systemNoUi = false; 16315 } else if (activitiesSize > 0) { 16316 for (int j = 0; j < activitiesSize; j++) { 16317 final ActivityRecord r = app.activities.get(j); 16318 if (r.visible) { 16319 app.systemNoUi = false; 16320 } 16321 } 16322 } 16323 if (!app.systemNoUi) { 16324 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16325 } 16326 return (app.curAdj=app.maxAdj); 16327 } 16328 16329 app.systemNoUi = false; 16330 16331 // Determine the importance of the process, starting with most 16332 // important to least, and assign an appropriate OOM adjustment. 16333 int adj; 16334 int schedGroup; 16335 int procState; 16336 boolean foregroundActivities = false; 16337 BroadcastQueue queue; 16338 if (app == TOP_APP) { 16339 // The last app on the list is the foreground app. 16340 adj = ProcessList.FOREGROUND_APP_ADJ; 16341 schedGroup = Process.THREAD_GROUP_DEFAULT; 16342 app.adjType = "top-activity"; 16343 foregroundActivities = true; 16344 procState = ActivityManager.PROCESS_STATE_TOP; 16345 } else if (app.instrumentationClass != null) { 16346 // Don't want to kill running instrumentation. 16347 adj = ProcessList.FOREGROUND_APP_ADJ; 16348 schedGroup = Process.THREAD_GROUP_DEFAULT; 16349 app.adjType = "instrumentation"; 16350 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16351 } else if ((queue = isReceivingBroadcast(app)) != null) { 16352 // An app that is currently receiving a broadcast also 16353 // counts as being in the foreground for OOM killer purposes. 16354 // It's placed in a sched group based on the nature of the 16355 // broadcast as reflected by which queue it's active in. 16356 adj = ProcessList.FOREGROUND_APP_ADJ; 16357 schedGroup = (queue == mFgBroadcastQueue) 16358 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16359 app.adjType = "broadcast"; 16360 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16361 } else if (app.executingServices.size() > 0) { 16362 // An app that is currently executing a service callback also 16363 // counts as being in the foreground. 16364 adj = ProcessList.FOREGROUND_APP_ADJ; 16365 schedGroup = app.execServicesFg ? 16366 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16367 app.adjType = "exec-service"; 16368 procState = ActivityManager.PROCESS_STATE_SERVICE; 16369 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16370 } else { 16371 // As far as we know the process is empty. We may change our mind later. 16372 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16373 // At this point we don't actually know the adjustment. Use the cached adj 16374 // value that the caller wants us to. 16375 adj = cachedAdj; 16376 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16377 app.cached = true; 16378 app.empty = true; 16379 app.adjType = "cch-empty"; 16380 } 16381 16382 // Examine all activities if not already foreground. 16383 if (!foregroundActivities && activitiesSize > 0) { 16384 for (int j = 0; j < activitiesSize; j++) { 16385 final ActivityRecord r = app.activities.get(j); 16386 if (r.app != app) { 16387 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16388 + app + "?!?"); 16389 continue; 16390 } 16391 if (r.visible) { 16392 // App has a visible activity; only upgrade adjustment. 16393 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16394 adj = ProcessList.VISIBLE_APP_ADJ; 16395 app.adjType = "visible"; 16396 } 16397 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16398 procState = ActivityManager.PROCESS_STATE_TOP; 16399 } 16400 schedGroup = Process.THREAD_GROUP_DEFAULT; 16401 app.cached = false; 16402 app.empty = false; 16403 foregroundActivities = true; 16404 break; 16405 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16406 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16407 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16408 app.adjType = "pausing"; 16409 } 16410 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16411 procState = ActivityManager.PROCESS_STATE_TOP; 16412 } 16413 schedGroup = Process.THREAD_GROUP_DEFAULT; 16414 app.cached = false; 16415 app.empty = false; 16416 foregroundActivities = true; 16417 } else if (r.state == ActivityState.STOPPING) { 16418 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16419 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16420 app.adjType = "stopping"; 16421 } 16422 // For the process state, we will at this point consider the 16423 // process to be cached. It will be cached either as an activity 16424 // or empty depending on whether the activity is finishing. We do 16425 // this so that we can treat the process as cached for purposes of 16426 // memory trimming (determing current memory level, trim command to 16427 // send to process) since there can be an arbitrary number of stopping 16428 // processes and they should soon all go into the cached state. 16429 if (!r.finishing) { 16430 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16431 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16432 } 16433 } 16434 app.cached = false; 16435 app.empty = false; 16436 foregroundActivities = true; 16437 } else { 16438 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16439 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16440 app.adjType = "cch-act"; 16441 } 16442 } 16443 } 16444 } 16445 16446 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16447 if (app.foregroundServices) { 16448 // The user is aware of this app, so make it visible. 16449 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16450 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16451 app.cached = false; 16452 app.adjType = "fg-service"; 16453 schedGroup = Process.THREAD_GROUP_DEFAULT; 16454 } else if (app.forcingToForeground != null) { 16455 // The user is aware of this app, so make it visible. 16456 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16457 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16458 app.cached = false; 16459 app.adjType = "force-fg"; 16460 app.adjSource = app.forcingToForeground; 16461 schedGroup = Process.THREAD_GROUP_DEFAULT; 16462 } 16463 } 16464 16465 if (app == mHeavyWeightProcess) { 16466 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16467 // We don't want to kill the current heavy-weight process. 16468 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16469 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16470 app.cached = false; 16471 app.adjType = "heavy"; 16472 } 16473 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16474 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16475 } 16476 } 16477 16478 if (app == mHomeProcess) { 16479 if (adj > ProcessList.HOME_APP_ADJ) { 16480 // This process is hosting what we currently consider to be the 16481 // home app, so we don't want to let it go into the background. 16482 adj = ProcessList.HOME_APP_ADJ; 16483 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16484 app.cached = false; 16485 app.adjType = "home"; 16486 } 16487 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16488 procState = ActivityManager.PROCESS_STATE_HOME; 16489 } 16490 } 16491 16492 if (app == mPreviousProcess && app.activities.size() > 0) { 16493 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16494 // This was the previous process that showed UI to the user. 16495 // We want to try to keep it around more aggressively, to give 16496 // a good experience around switching between two apps. 16497 adj = ProcessList.PREVIOUS_APP_ADJ; 16498 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16499 app.cached = false; 16500 app.adjType = "previous"; 16501 } 16502 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16503 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16504 } 16505 } 16506 16507 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16508 + " reason=" + app.adjType); 16509 16510 // By default, we use the computed adjustment. It may be changed if 16511 // there are applications dependent on our services or providers, but 16512 // this gives us a baseline and makes sure we don't get into an 16513 // infinite recursion. 16514 app.adjSeq = mAdjSeq; 16515 app.curRawAdj = adj; 16516 app.hasStartedServices = false; 16517 16518 if (mBackupTarget != null && app == mBackupTarget.app) { 16519 // If possible we want to avoid killing apps while they're being backed up 16520 if (adj > ProcessList.BACKUP_APP_ADJ) { 16521 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16522 adj = ProcessList.BACKUP_APP_ADJ; 16523 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16524 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16525 } 16526 app.adjType = "backup"; 16527 app.cached = false; 16528 } 16529 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16530 procState = ActivityManager.PROCESS_STATE_BACKUP; 16531 } 16532 } 16533 16534 boolean mayBeTop = false; 16535 16536 for (int is = app.services.size()-1; 16537 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16538 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16539 || procState > ActivityManager.PROCESS_STATE_TOP); 16540 is--) { 16541 ServiceRecord s = app.services.valueAt(is); 16542 if (s.startRequested) { 16543 app.hasStartedServices = true; 16544 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16545 procState = ActivityManager.PROCESS_STATE_SERVICE; 16546 } 16547 if (app.hasShownUi && app != mHomeProcess) { 16548 // If this process has shown some UI, let it immediately 16549 // go to the LRU list because it may be pretty heavy with 16550 // UI stuff. We'll tag it with a label just to help 16551 // debug and understand what is going on. 16552 if (adj > ProcessList.SERVICE_ADJ) { 16553 app.adjType = "cch-started-ui-services"; 16554 } 16555 } else { 16556 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16557 // This service has seen some activity within 16558 // recent memory, so we will keep its process ahead 16559 // of the background processes. 16560 if (adj > ProcessList.SERVICE_ADJ) { 16561 adj = ProcessList.SERVICE_ADJ; 16562 app.adjType = "started-services"; 16563 app.cached = false; 16564 } 16565 } 16566 // If we have let the service slide into the background 16567 // state, still have some text describing what it is doing 16568 // even though the service no longer has an impact. 16569 if (adj > ProcessList.SERVICE_ADJ) { 16570 app.adjType = "cch-started-services"; 16571 } 16572 } 16573 } 16574 for (int conni = s.connections.size()-1; 16575 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16576 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16577 || procState > ActivityManager.PROCESS_STATE_TOP); 16578 conni--) { 16579 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16580 for (int i = 0; 16581 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16582 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16583 || procState > ActivityManager.PROCESS_STATE_TOP); 16584 i++) { 16585 // XXX should compute this based on the max of 16586 // all connected clients. 16587 ConnectionRecord cr = clist.get(i); 16588 if (cr.binding.client == app) { 16589 // Binding to ourself is not interesting. 16590 continue; 16591 } 16592 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16593 ProcessRecord client = cr.binding.client; 16594 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16595 TOP_APP, doingAll, now); 16596 int clientProcState = client.curProcState; 16597 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16598 // If the other app is cached for any reason, for purposes here 16599 // we are going to consider it empty. The specific cached state 16600 // doesn't propagate except under certain conditions. 16601 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16602 } 16603 String adjType = null; 16604 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16605 // Not doing bind OOM management, so treat 16606 // this guy more like a started service. 16607 if (app.hasShownUi && app != mHomeProcess) { 16608 // If this process has shown some UI, let it immediately 16609 // go to the LRU list because it may be pretty heavy with 16610 // UI stuff. We'll tag it with a label just to help 16611 // debug and understand what is going on. 16612 if (adj > clientAdj) { 16613 adjType = "cch-bound-ui-services"; 16614 } 16615 app.cached = false; 16616 clientAdj = adj; 16617 clientProcState = procState; 16618 } else { 16619 if (now >= (s.lastActivity 16620 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16621 // This service has not seen activity within 16622 // recent memory, so allow it to drop to the 16623 // LRU list if there is no other reason to keep 16624 // it around. We'll also tag it with a label just 16625 // to help debug and undertand what is going on. 16626 if (adj > clientAdj) { 16627 adjType = "cch-bound-services"; 16628 } 16629 clientAdj = adj; 16630 } 16631 } 16632 } 16633 if (adj > clientAdj) { 16634 // If this process has recently shown UI, and 16635 // the process that is binding to it is less 16636 // important than being visible, then we don't 16637 // care about the binding as much as we care 16638 // about letting this process get into the LRU 16639 // list to be killed and restarted if needed for 16640 // memory. 16641 if (app.hasShownUi && app != mHomeProcess 16642 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16643 adjType = "cch-bound-ui-services"; 16644 } else { 16645 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16646 |Context.BIND_IMPORTANT)) != 0) { 16647 adj = clientAdj; 16648 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16649 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16650 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16651 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16652 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16653 adj = clientAdj; 16654 } else { 16655 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16656 adj = ProcessList.VISIBLE_APP_ADJ; 16657 } 16658 } 16659 if (!client.cached) { 16660 app.cached = false; 16661 } 16662 adjType = "service"; 16663 } 16664 } 16665 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16666 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16667 schedGroup = Process.THREAD_GROUP_DEFAULT; 16668 } 16669 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16670 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16671 // Special handling of clients who are in the top state. 16672 // We *may* want to consider this process to be in the 16673 // top state as well, but only if there is not another 16674 // reason for it to be running. Being on the top is a 16675 // special state, meaning you are specifically running 16676 // for the current top app. If the process is already 16677 // running in the background for some other reason, it 16678 // is more important to continue considering it to be 16679 // in the background state. 16680 mayBeTop = true; 16681 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16682 } else { 16683 // Special handling for above-top states (persistent 16684 // processes). These should not bring the current process 16685 // into the top state, since they are not on top. Instead 16686 // give them the best state after that. 16687 clientProcState = 16688 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16689 } 16690 } 16691 } else { 16692 if (clientProcState < 16693 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16694 clientProcState = 16695 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16696 } 16697 } 16698 if (procState > clientProcState) { 16699 procState = clientProcState; 16700 } 16701 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16702 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16703 app.pendingUiClean = true; 16704 } 16705 if (adjType != null) { 16706 app.adjType = adjType; 16707 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16708 .REASON_SERVICE_IN_USE; 16709 app.adjSource = cr.binding.client; 16710 app.adjSourceProcState = clientProcState; 16711 app.adjTarget = s.name; 16712 } 16713 } 16714 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16715 app.treatLikeActivity = true; 16716 } 16717 final ActivityRecord a = cr.activity; 16718 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16719 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16720 (a.visible || a.state == ActivityState.RESUMED 16721 || a.state == ActivityState.PAUSING)) { 16722 adj = ProcessList.FOREGROUND_APP_ADJ; 16723 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16724 schedGroup = Process.THREAD_GROUP_DEFAULT; 16725 } 16726 app.cached = false; 16727 app.adjType = "service"; 16728 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16729 .REASON_SERVICE_IN_USE; 16730 app.adjSource = a; 16731 app.adjSourceProcState = procState; 16732 app.adjTarget = s.name; 16733 } 16734 } 16735 } 16736 } 16737 } 16738 16739 for (int provi = app.pubProviders.size()-1; 16740 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16741 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16742 || procState > ActivityManager.PROCESS_STATE_TOP); 16743 provi--) { 16744 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16745 for (int i = cpr.connections.size()-1; 16746 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16747 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16748 || procState > ActivityManager.PROCESS_STATE_TOP); 16749 i--) { 16750 ContentProviderConnection conn = cpr.connections.get(i); 16751 ProcessRecord client = conn.client; 16752 if (client == app) { 16753 // Being our own client is not interesting. 16754 continue; 16755 } 16756 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16757 int clientProcState = client.curProcState; 16758 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16759 // If the other app is cached for any reason, for purposes here 16760 // we are going to consider it empty. 16761 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16762 } 16763 if (adj > clientAdj) { 16764 if (app.hasShownUi && app != mHomeProcess 16765 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16766 app.adjType = "cch-ui-provider"; 16767 } else { 16768 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16769 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16770 app.adjType = "provider"; 16771 } 16772 app.cached &= client.cached; 16773 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16774 .REASON_PROVIDER_IN_USE; 16775 app.adjSource = client; 16776 app.adjSourceProcState = clientProcState; 16777 app.adjTarget = cpr.name; 16778 } 16779 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16780 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16781 // Special handling of clients who are in the top state. 16782 // We *may* want to consider this process to be in the 16783 // top state as well, but only if there is not another 16784 // reason for it to be running. Being on the top is a 16785 // special state, meaning you are specifically running 16786 // for the current top app. If the process is already 16787 // running in the background for some other reason, it 16788 // is more important to continue considering it to be 16789 // in the background state. 16790 mayBeTop = true; 16791 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16792 } else { 16793 // Special handling for above-top states (persistent 16794 // processes). These should not bring the current process 16795 // into the top state, since they are not on top. Instead 16796 // give them the best state after that. 16797 clientProcState = 16798 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16799 } 16800 } 16801 if (procState > clientProcState) { 16802 procState = clientProcState; 16803 } 16804 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16805 schedGroup = Process.THREAD_GROUP_DEFAULT; 16806 } 16807 } 16808 // If the provider has external (non-framework) process 16809 // dependencies, ensure that its adjustment is at least 16810 // FOREGROUND_APP_ADJ. 16811 if (cpr.hasExternalProcessHandles()) { 16812 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16813 adj = ProcessList.FOREGROUND_APP_ADJ; 16814 schedGroup = Process.THREAD_GROUP_DEFAULT; 16815 app.cached = false; 16816 app.adjType = "provider"; 16817 app.adjTarget = cpr.name; 16818 } 16819 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16820 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16821 } 16822 } 16823 } 16824 16825 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16826 // A client of one of our services or providers is in the top state. We 16827 // *may* want to be in the top state, but not if we are already running in 16828 // the background for some other reason. For the decision here, we are going 16829 // to pick out a few specific states that we want to remain in when a client 16830 // is top (states that tend to be longer-term) and otherwise allow it to go 16831 // to the top state. 16832 switch (procState) { 16833 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16834 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16835 case ActivityManager.PROCESS_STATE_SERVICE: 16836 // These all are longer-term states, so pull them up to the top 16837 // of the background states, but not all the way to the top state. 16838 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16839 break; 16840 default: 16841 // Otherwise, top is a better choice, so take it. 16842 procState = ActivityManager.PROCESS_STATE_TOP; 16843 break; 16844 } 16845 } 16846 16847 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16848 if (app.hasClientActivities) { 16849 // This is a cached process, but with client activities. Mark it so. 16850 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16851 app.adjType = "cch-client-act"; 16852 } else if (app.treatLikeActivity) { 16853 // This is a cached process, but somebody wants us to treat it like it has 16854 // an activity, okay! 16855 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16856 app.adjType = "cch-as-act"; 16857 } 16858 } 16859 16860 if (adj == ProcessList.SERVICE_ADJ) { 16861 if (doingAll) { 16862 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16863 mNewNumServiceProcs++; 16864 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16865 if (!app.serviceb) { 16866 // This service isn't far enough down on the LRU list to 16867 // normally be a B service, but if we are low on RAM and it 16868 // is large we want to force it down since we would prefer to 16869 // keep launcher over it. 16870 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16871 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16872 app.serviceHighRam = true; 16873 app.serviceb = true; 16874 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16875 } else { 16876 mNewNumAServiceProcs++; 16877 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16878 } 16879 } else { 16880 app.serviceHighRam = false; 16881 } 16882 } 16883 if (app.serviceb) { 16884 adj = ProcessList.SERVICE_B_ADJ; 16885 } 16886 } 16887 16888 app.curRawAdj = adj; 16889 16890 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16891 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16892 if (adj > app.maxAdj) { 16893 adj = app.maxAdj; 16894 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16895 schedGroup = Process.THREAD_GROUP_DEFAULT; 16896 } 16897 } 16898 16899 // Do final modification to adj. Everything we do between here and applying 16900 // the final setAdj must be done in this function, because we will also use 16901 // it when computing the final cached adj later. Note that we don't need to 16902 // worry about this for max adj above, since max adj will always be used to 16903 // keep it out of the cached vaues. 16904 app.curAdj = app.modifyRawOomAdj(adj); 16905 app.curSchedGroup = schedGroup; 16906 app.curProcState = procState; 16907 app.foregroundActivities = foregroundActivities; 16908 16909 return app.curRawAdj; 16910 } 16911 16912 /** 16913 * Schedule PSS collection of a process. 16914 */ 16915 void requestPssLocked(ProcessRecord proc, int procState) { 16916 if (mPendingPssProcesses.contains(proc)) { 16917 return; 16918 } 16919 if (mPendingPssProcesses.size() == 0) { 16920 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16921 } 16922 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16923 proc.pssProcState = procState; 16924 mPendingPssProcesses.add(proc); 16925 } 16926 16927 /** 16928 * Schedule PSS collection of all processes. 16929 */ 16930 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16931 if (!always) { 16932 if (now < (mLastFullPssTime + 16933 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16934 return; 16935 } 16936 } 16937 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16938 mLastFullPssTime = now; 16939 mFullPssPending = true; 16940 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16941 mPendingPssProcesses.clear(); 16942 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16943 ProcessRecord app = mLruProcesses.get(i); 16944 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16945 app.pssProcState = app.setProcState; 16946 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16947 isSleeping(), now); 16948 mPendingPssProcesses.add(app); 16949 } 16950 } 16951 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16952 } 16953 16954 /** 16955 * Ask a given process to GC right now. 16956 */ 16957 final void performAppGcLocked(ProcessRecord app) { 16958 try { 16959 app.lastRequestedGc = SystemClock.uptimeMillis(); 16960 if (app.thread != null) { 16961 if (app.reportLowMemory) { 16962 app.reportLowMemory = false; 16963 app.thread.scheduleLowMemory(); 16964 } else { 16965 app.thread.processInBackground(); 16966 } 16967 } 16968 } catch (Exception e) { 16969 // whatever. 16970 } 16971 } 16972 16973 /** 16974 * Returns true if things are idle enough to perform GCs. 16975 */ 16976 private final boolean canGcNowLocked() { 16977 boolean processingBroadcasts = false; 16978 for (BroadcastQueue q : mBroadcastQueues) { 16979 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16980 processingBroadcasts = true; 16981 } 16982 } 16983 return !processingBroadcasts 16984 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16985 } 16986 16987 /** 16988 * Perform GCs on all processes that are waiting for it, but only 16989 * if things are idle. 16990 */ 16991 final void performAppGcsLocked() { 16992 final int N = mProcessesToGc.size(); 16993 if (N <= 0) { 16994 return; 16995 } 16996 if (canGcNowLocked()) { 16997 while (mProcessesToGc.size() > 0) { 16998 ProcessRecord proc = mProcessesToGc.remove(0); 16999 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 17000 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 17001 <= SystemClock.uptimeMillis()) { 17002 // To avoid spamming the system, we will GC processes one 17003 // at a time, waiting a few seconds between each. 17004 performAppGcLocked(proc); 17005 scheduleAppGcsLocked(); 17006 return; 17007 } else { 17008 // It hasn't been long enough since we last GCed this 17009 // process... put it in the list to wait for its time. 17010 addProcessToGcListLocked(proc); 17011 break; 17012 } 17013 } 17014 } 17015 17016 scheduleAppGcsLocked(); 17017 } 17018 } 17019 17020 /** 17021 * If all looks good, perform GCs on all processes waiting for them. 17022 */ 17023 final void performAppGcsIfAppropriateLocked() { 17024 if (canGcNowLocked()) { 17025 performAppGcsLocked(); 17026 return; 17027 } 17028 // Still not idle, wait some more. 17029 scheduleAppGcsLocked(); 17030 } 17031 17032 /** 17033 * Schedule the execution of all pending app GCs. 17034 */ 17035 final void scheduleAppGcsLocked() { 17036 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 17037 17038 if (mProcessesToGc.size() > 0) { 17039 // Schedule a GC for the time to the next process. 17040 ProcessRecord proc = mProcessesToGc.get(0); 17041 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 17042 17043 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 17044 long now = SystemClock.uptimeMillis(); 17045 if (when < (now+GC_TIMEOUT)) { 17046 when = now + GC_TIMEOUT; 17047 } 17048 mHandler.sendMessageAtTime(msg, when); 17049 } 17050 } 17051 17052 /** 17053 * Add a process to the array of processes waiting to be GCed. Keeps the 17054 * list in sorted order by the last GC time. The process can't already be 17055 * on the list. 17056 */ 17057 final void addProcessToGcListLocked(ProcessRecord proc) { 17058 boolean added = false; 17059 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 17060 if (mProcessesToGc.get(i).lastRequestedGc < 17061 proc.lastRequestedGc) { 17062 added = true; 17063 mProcessesToGc.add(i+1, proc); 17064 break; 17065 } 17066 } 17067 if (!added) { 17068 mProcessesToGc.add(0, proc); 17069 } 17070 } 17071 17072 /** 17073 * Set up to ask a process to GC itself. This will either do it 17074 * immediately, or put it on the list of processes to gc the next 17075 * time things are idle. 17076 */ 17077 final void scheduleAppGcLocked(ProcessRecord app) { 17078 long now = SystemClock.uptimeMillis(); 17079 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 17080 return; 17081 } 17082 if (!mProcessesToGc.contains(app)) { 17083 addProcessToGcListLocked(app); 17084 scheduleAppGcsLocked(); 17085 } 17086 } 17087 17088 final void checkExcessivePowerUsageLocked(boolean doKills) { 17089 updateCpuStatsNow(); 17090 17091 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17092 boolean doWakeKills = doKills; 17093 boolean doCpuKills = doKills; 17094 if (mLastPowerCheckRealtime == 0) { 17095 doWakeKills = false; 17096 } 17097 if (mLastPowerCheckUptime == 0) { 17098 doCpuKills = false; 17099 } 17100 if (stats.isScreenOn()) { 17101 doWakeKills = false; 17102 } 17103 final long curRealtime = SystemClock.elapsedRealtime(); 17104 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 17105 final long curUptime = SystemClock.uptimeMillis(); 17106 final long uptimeSince = curUptime - mLastPowerCheckUptime; 17107 mLastPowerCheckRealtime = curRealtime; 17108 mLastPowerCheckUptime = curUptime; 17109 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 17110 doWakeKills = false; 17111 } 17112 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 17113 doCpuKills = false; 17114 } 17115 int i = mLruProcesses.size(); 17116 while (i > 0) { 17117 i--; 17118 ProcessRecord app = mLruProcesses.get(i); 17119 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17120 long wtime; 17121 synchronized (stats) { 17122 wtime = stats.getProcessWakeTime(app.info.uid, 17123 app.pid, curRealtime); 17124 } 17125 long wtimeUsed = wtime - app.lastWakeTime; 17126 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17127 if (DEBUG_POWER) { 17128 StringBuilder sb = new StringBuilder(128); 17129 sb.append("Wake for "); 17130 app.toShortString(sb); 17131 sb.append(": over "); 17132 TimeUtils.formatDuration(realtimeSince, sb); 17133 sb.append(" used "); 17134 TimeUtils.formatDuration(wtimeUsed, sb); 17135 sb.append(" ("); 17136 sb.append((wtimeUsed*100)/realtimeSince); 17137 sb.append("%)"); 17138 Slog.i(TAG, sb.toString()); 17139 sb.setLength(0); 17140 sb.append("CPU for "); 17141 app.toShortString(sb); 17142 sb.append(": over "); 17143 TimeUtils.formatDuration(uptimeSince, sb); 17144 sb.append(" used "); 17145 TimeUtils.formatDuration(cputimeUsed, sb); 17146 sb.append(" ("); 17147 sb.append((cputimeUsed*100)/uptimeSince); 17148 sb.append("%)"); 17149 Slog.i(TAG, sb.toString()); 17150 } 17151 // If a process has held a wake lock for more 17152 // than 50% of the time during this period, 17153 // that sounds bad. Kill! 17154 if (doWakeKills && realtimeSince > 0 17155 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17156 synchronized (stats) { 17157 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17158 realtimeSince, wtimeUsed); 17159 } 17160 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17161 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17162 } else if (doCpuKills && uptimeSince > 0 17163 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17164 synchronized (stats) { 17165 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17166 uptimeSince, cputimeUsed); 17167 } 17168 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17169 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17170 } else { 17171 app.lastWakeTime = wtime; 17172 app.lastCpuTime = app.curCpuTime; 17173 } 17174 } 17175 } 17176 } 17177 17178 private final boolean applyOomAdjLocked(ProcessRecord app, 17179 ProcessRecord TOP_APP, boolean doingAll, long now) { 17180 boolean success = true; 17181 17182 if (app.curRawAdj != app.setRawAdj) { 17183 app.setRawAdj = app.curRawAdj; 17184 } 17185 17186 int changes = 0; 17187 17188 if (app.curAdj != app.setAdj) { 17189 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17190 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17191 TAG, "Set " + app.pid + " " + app.processName + 17192 " adj " + app.curAdj + ": " + app.adjType); 17193 app.setAdj = app.curAdj; 17194 } 17195 17196 if (app.setSchedGroup != app.curSchedGroup) { 17197 app.setSchedGroup = app.curSchedGroup; 17198 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17199 "Setting process group of " + app.processName 17200 + " to " + app.curSchedGroup); 17201 if (app.waitingToKill != null && 17202 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17203 app.kill(app.waitingToKill, true); 17204 success = false; 17205 } else { 17206 if (true) { 17207 long oldId = Binder.clearCallingIdentity(); 17208 try { 17209 Process.setProcessGroup(app.pid, app.curSchedGroup); 17210 } catch (Exception e) { 17211 Slog.w(TAG, "Failed setting process group of " + app.pid 17212 + " to " + app.curSchedGroup); 17213 e.printStackTrace(); 17214 } finally { 17215 Binder.restoreCallingIdentity(oldId); 17216 } 17217 } else { 17218 if (app.thread != null) { 17219 try { 17220 app.thread.setSchedulingGroup(app.curSchedGroup); 17221 } catch (RemoteException e) { 17222 } 17223 } 17224 } 17225 Process.setSwappiness(app.pid, 17226 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17227 } 17228 } 17229 if (app.repForegroundActivities != app.foregroundActivities) { 17230 app.repForegroundActivities = app.foregroundActivities; 17231 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17232 } 17233 if (app.repProcState != app.curProcState) { 17234 app.repProcState = app.curProcState; 17235 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17236 if (app.thread != null) { 17237 try { 17238 if (false) { 17239 //RuntimeException h = new RuntimeException("here"); 17240 Slog.i(TAG, "Sending new process state " + app.repProcState 17241 + " to " + app /*, h*/); 17242 } 17243 app.thread.setProcessState(app.repProcState); 17244 } catch (RemoteException e) { 17245 } 17246 } 17247 } 17248 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17249 app.setProcState)) { 17250 app.lastStateTime = now; 17251 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17252 isSleeping(), now); 17253 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17254 + ProcessList.makeProcStateString(app.setProcState) + " to " 17255 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17256 + (app.nextPssTime-now) + ": " + app); 17257 } else { 17258 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17259 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17260 requestPssLocked(app, app.setProcState); 17261 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17262 isSleeping(), now); 17263 } else if (false && DEBUG_PSS) { 17264 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17265 } 17266 } 17267 if (app.setProcState != app.curProcState) { 17268 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17269 "Proc state change of " + app.processName 17270 + " to " + app.curProcState); 17271 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17272 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17273 if (setImportant && !curImportant) { 17274 // This app is no longer something we consider important enough to allow to 17275 // use arbitrary amounts of battery power. Note 17276 // its current wake lock time to later know to kill it if 17277 // it is not behaving well. 17278 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17279 synchronized (stats) { 17280 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17281 app.pid, SystemClock.elapsedRealtime()); 17282 } 17283 app.lastCpuTime = app.curCpuTime; 17284 17285 } 17286 app.setProcState = app.curProcState; 17287 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17288 app.notCachedSinceIdle = false; 17289 } 17290 if (!doingAll) { 17291 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17292 } else { 17293 app.procStateChanged = true; 17294 } 17295 } 17296 17297 if (changes != 0) { 17298 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17299 int i = mPendingProcessChanges.size()-1; 17300 ProcessChangeItem item = null; 17301 while (i >= 0) { 17302 item = mPendingProcessChanges.get(i); 17303 if (item.pid == app.pid) { 17304 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17305 break; 17306 } 17307 i--; 17308 } 17309 if (i < 0) { 17310 // No existing item in pending changes; need a new one. 17311 final int NA = mAvailProcessChanges.size(); 17312 if (NA > 0) { 17313 item = mAvailProcessChanges.remove(NA-1); 17314 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17315 } else { 17316 item = new ProcessChangeItem(); 17317 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17318 } 17319 item.changes = 0; 17320 item.pid = app.pid; 17321 item.uid = app.info.uid; 17322 if (mPendingProcessChanges.size() == 0) { 17323 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17324 "*** Enqueueing dispatch processes changed!"); 17325 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17326 } 17327 mPendingProcessChanges.add(item); 17328 } 17329 item.changes |= changes; 17330 item.processState = app.repProcState; 17331 item.foregroundActivities = app.repForegroundActivities; 17332 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17333 + Integer.toHexString(System.identityHashCode(item)) 17334 + " " + app.toShortString() + ": changes=" + item.changes 17335 + " procState=" + item.processState 17336 + " foreground=" + item.foregroundActivities 17337 + " type=" + app.adjType + " source=" + app.adjSource 17338 + " target=" + app.adjTarget); 17339 } 17340 17341 return success; 17342 } 17343 17344 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17345 if (proc.thread != null) { 17346 if (proc.baseProcessTracker != null) { 17347 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17348 } 17349 if (proc.repProcState >= 0) { 17350 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17351 proc.repProcState); 17352 } 17353 } 17354 } 17355 17356 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17357 ProcessRecord TOP_APP, boolean doingAll, long now) { 17358 if (app.thread == null) { 17359 return false; 17360 } 17361 17362 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17363 17364 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17365 } 17366 17367 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17368 boolean oomAdj) { 17369 if (isForeground != proc.foregroundServices) { 17370 proc.foregroundServices = isForeground; 17371 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17372 proc.info.uid); 17373 if (isForeground) { 17374 if (curProcs == null) { 17375 curProcs = new ArrayList<ProcessRecord>(); 17376 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17377 } 17378 if (!curProcs.contains(proc)) { 17379 curProcs.add(proc); 17380 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17381 proc.info.packageName, proc.info.uid); 17382 } 17383 } else { 17384 if (curProcs != null) { 17385 if (curProcs.remove(proc)) { 17386 mBatteryStatsService.noteEvent( 17387 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17388 proc.info.packageName, proc.info.uid); 17389 if (curProcs.size() <= 0) { 17390 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17391 } 17392 } 17393 } 17394 } 17395 if (oomAdj) { 17396 updateOomAdjLocked(); 17397 } 17398 } 17399 } 17400 17401 private final ActivityRecord resumedAppLocked() { 17402 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17403 String pkg; 17404 int uid; 17405 if (act != null) { 17406 pkg = act.packageName; 17407 uid = act.info.applicationInfo.uid; 17408 } else { 17409 pkg = null; 17410 uid = -1; 17411 } 17412 // Has the UID or resumed package name changed? 17413 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17414 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17415 if (mCurResumedPackage != null) { 17416 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17417 mCurResumedPackage, mCurResumedUid); 17418 } 17419 mCurResumedPackage = pkg; 17420 mCurResumedUid = uid; 17421 if (mCurResumedPackage != null) { 17422 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17423 mCurResumedPackage, mCurResumedUid); 17424 } 17425 } 17426 return act; 17427 } 17428 17429 final boolean updateOomAdjLocked(ProcessRecord app) { 17430 final ActivityRecord TOP_ACT = resumedAppLocked(); 17431 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17432 final boolean wasCached = app.cached; 17433 17434 mAdjSeq++; 17435 17436 // This is the desired cached adjusment we want to tell it to use. 17437 // If our app is currently cached, we know it, and that is it. Otherwise, 17438 // we don't know it yet, and it needs to now be cached we will then 17439 // need to do a complete oom adj. 17440 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17441 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17442 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17443 SystemClock.uptimeMillis()); 17444 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17445 // Changed to/from cached state, so apps after it in the LRU 17446 // list may also be changed. 17447 updateOomAdjLocked(); 17448 } 17449 return success; 17450 } 17451 17452 final void updateOomAdjLocked() { 17453 final ActivityRecord TOP_ACT = resumedAppLocked(); 17454 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17455 final long now = SystemClock.uptimeMillis(); 17456 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17457 final int N = mLruProcesses.size(); 17458 17459 if (false) { 17460 RuntimeException e = new RuntimeException(); 17461 e.fillInStackTrace(); 17462 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17463 } 17464 17465 mAdjSeq++; 17466 mNewNumServiceProcs = 0; 17467 mNewNumAServiceProcs = 0; 17468 17469 final int emptyProcessLimit; 17470 final int cachedProcessLimit; 17471 if (mProcessLimit <= 0) { 17472 emptyProcessLimit = cachedProcessLimit = 0; 17473 } else if (mProcessLimit == 1) { 17474 emptyProcessLimit = 1; 17475 cachedProcessLimit = 0; 17476 } else { 17477 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17478 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17479 } 17480 17481 // Let's determine how many processes we have running vs. 17482 // how many slots we have for background processes; we may want 17483 // to put multiple processes in a slot of there are enough of 17484 // them. 17485 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17486 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17487 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17488 if (numEmptyProcs > cachedProcessLimit) { 17489 // If there are more empty processes than our limit on cached 17490 // processes, then use the cached process limit for the factor. 17491 // This ensures that the really old empty processes get pushed 17492 // down to the bottom, so if we are running low on memory we will 17493 // have a better chance at keeping around more cached processes 17494 // instead of a gazillion empty processes. 17495 numEmptyProcs = cachedProcessLimit; 17496 } 17497 int emptyFactor = numEmptyProcs/numSlots; 17498 if (emptyFactor < 1) emptyFactor = 1; 17499 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17500 if (cachedFactor < 1) cachedFactor = 1; 17501 int stepCached = 0; 17502 int stepEmpty = 0; 17503 int numCached = 0; 17504 int numEmpty = 0; 17505 int numTrimming = 0; 17506 17507 mNumNonCachedProcs = 0; 17508 mNumCachedHiddenProcs = 0; 17509 17510 // First update the OOM adjustment for each of the 17511 // application processes based on their current state. 17512 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17513 int nextCachedAdj = curCachedAdj+1; 17514 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17515 int nextEmptyAdj = curEmptyAdj+2; 17516 for (int i=N-1; i>=0; i--) { 17517 ProcessRecord app = mLruProcesses.get(i); 17518 if (!app.killedByAm && app.thread != null) { 17519 app.procStateChanged = false; 17520 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17521 17522 // If we haven't yet assigned the final cached adj 17523 // to the process, do that now. 17524 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17525 switch (app.curProcState) { 17526 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17527 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17528 // This process is a cached process holding activities... 17529 // assign it the next cached value for that type, and then 17530 // step that cached level. 17531 app.curRawAdj = curCachedAdj; 17532 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17533 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17534 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17535 + ")"); 17536 if (curCachedAdj != nextCachedAdj) { 17537 stepCached++; 17538 if (stepCached >= cachedFactor) { 17539 stepCached = 0; 17540 curCachedAdj = nextCachedAdj; 17541 nextCachedAdj += 2; 17542 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17543 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17544 } 17545 } 17546 } 17547 break; 17548 default: 17549 // For everything else, assign next empty cached process 17550 // level and bump that up. Note that this means that 17551 // long-running services that have dropped down to the 17552 // cached level will be treated as empty (since their process 17553 // state is still as a service), which is what we want. 17554 app.curRawAdj = curEmptyAdj; 17555 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17556 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17557 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17558 + ")"); 17559 if (curEmptyAdj != nextEmptyAdj) { 17560 stepEmpty++; 17561 if (stepEmpty >= emptyFactor) { 17562 stepEmpty = 0; 17563 curEmptyAdj = nextEmptyAdj; 17564 nextEmptyAdj += 2; 17565 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17566 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17567 } 17568 } 17569 } 17570 break; 17571 } 17572 } 17573 17574 applyOomAdjLocked(app, TOP_APP, true, now); 17575 17576 // Count the number of process types. 17577 switch (app.curProcState) { 17578 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17579 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17580 mNumCachedHiddenProcs++; 17581 numCached++; 17582 if (numCached > cachedProcessLimit) { 17583 app.kill("cached #" + numCached, true); 17584 } 17585 break; 17586 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17587 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17588 && app.lastActivityTime < oldTime) { 17589 app.kill("empty for " 17590 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17591 / 1000) + "s", true); 17592 } else { 17593 numEmpty++; 17594 if (numEmpty > emptyProcessLimit) { 17595 app.kill("empty #" + numEmpty, true); 17596 } 17597 } 17598 break; 17599 default: 17600 mNumNonCachedProcs++; 17601 break; 17602 } 17603 17604 if (app.isolated && app.services.size() <= 0) { 17605 // If this is an isolated process, and there are no 17606 // services running in it, then the process is no longer 17607 // needed. We agressively kill these because we can by 17608 // definition not re-use the same process again, and it is 17609 // good to avoid having whatever code was running in them 17610 // left sitting around after no longer needed. 17611 app.kill("isolated not needed", true); 17612 } 17613 17614 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17615 && !app.killedByAm) { 17616 numTrimming++; 17617 } 17618 } 17619 } 17620 17621 mNumServiceProcs = mNewNumServiceProcs; 17622 17623 // Now determine the memory trimming level of background processes. 17624 // Unfortunately we need to start at the back of the list to do this 17625 // properly. We only do this if the number of background apps we 17626 // are managing to keep around is less than half the maximum we desire; 17627 // if we are keeping a good number around, we'll let them use whatever 17628 // memory they want. 17629 final int numCachedAndEmpty = numCached + numEmpty; 17630 int memFactor; 17631 if (numCached <= ProcessList.TRIM_CACHED_APPS 17632 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17633 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17634 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17635 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17636 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17637 } else { 17638 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17639 } 17640 } else { 17641 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17642 } 17643 // We always allow the memory level to go up (better). We only allow it to go 17644 // down if we are in a state where that is allowed, *and* the total number of processes 17645 // has gone down since last time. 17646 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17647 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17648 + " last=" + mLastNumProcesses); 17649 if (memFactor > mLastMemoryLevel) { 17650 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17651 memFactor = mLastMemoryLevel; 17652 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17653 } 17654 } 17655 mLastMemoryLevel = memFactor; 17656 mLastNumProcesses = mLruProcesses.size(); 17657 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17658 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17659 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17660 if (mLowRamStartTime == 0) { 17661 mLowRamStartTime = now; 17662 } 17663 int step = 0; 17664 int fgTrimLevel; 17665 switch (memFactor) { 17666 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17667 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17668 break; 17669 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17670 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17671 break; 17672 default: 17673 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17674 break; 17675 } 17676 int factor = numTrimming/3; 17677 int minFactor = 2; 17678 if (mHomeProcess != null) minFactor++; 17679 if (mPreviousProcess != null) minFactor++; 17680 if (factor < minFactor) factor = minFactor; 17681 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17682 for (int i=N-1; i>=0; i--) { 17683 ProcessRecord app = mLruProcesses.get(i); 17684 if (allChanged || app.procStateChanged) { 17685 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17686 app.procStateChanged = false; 17687 } 17688 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17689 && !app.killedByAm) { 17690 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17691 try { 17692 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17693 "Trimming memory of " + app.processName 17694 + " to " + curLevel); 17695 app.thread.scheduleTrimMemory(curLevel); 17696 } catch (RemoteException e) { 17697 } 17698 if (false) { 17699 // For now we won't do this; our memory trimming seems 17700 // to be good enough at this point that destroying 17701 // activities causes more harm than good. 17702 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17703 && app != mHomeProcess && app != mPreviousProcess) { 17704 // Need to do this on its own message because the stack may not 17705 // be in a consistent state at this point. 17706 // For these apps we will also finish their activities 17707 // to help them free memory. 17708 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17709 } 17710 } 17711 } 17712 app.trimMemoryLevel = curLevel; 17713 step++; 17714 if (step >= factor) { 17715 step = 0; 17716 switch (curLevel) { 17717 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17718 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17719 break; 17720 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17721 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17722 break; 17723 } 17724 } 17725 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17726 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17727 && app.thread != null) { 17728 try { 17729 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17730 "Trimming memory of heavy-weight " + app.processName 17731 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17732 app.thread.scheduleTrimMemory( 17733 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17734 } catch (RemoteException e) { 17735 } 17736 } 17737 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17738 } else { 17739 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17740 || app.systemNoUi) && app.pendingUiClean) { 17741 // If this application is now in the background and it 17742 // had done UI, then give it the special trim level to 17743 // have it free UI resources. 17744 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17745 if (app.trimMemoryLevel < level && app.thread != null) { 17746 try { 17747 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17748 "Trimming memory of bg-ui " + app.processName 17749 + " to " + level); 17750 app.thread.scheduleTrimMemory(level); 17751 } catch (RemoteException e) { 17752 } 17753 } 17754 app.pendingUiClean = false; 17755 } 17756 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17757 try { 17758 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17759 "Trimming memory of fg " + app.processName 17760 + " to " + fgTrimLevel); 17761 app.thread.scheduleTrimMemory(fgTrimLevel); 17762 } catch (RemoteException e) { 17763 } 17764 } 17765 app.trimMemoryLevel = fgTrimLevel; 17766 } 17767 } 17768 } else { 17769 if (mLowRamStartTime != 0) { 17770 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17771 mLowRamStartTime = 0; 17772 } 17773 for (int i=N-1; i>=0; i--) { 17774 ProcessRecord app = mLruProcesses.get(i); 17775 if (allChanged || app.procStateChanged) { 17776 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17777 app.procStateChanged = false; 17778 } 17779 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17780 || app.systemNoUi) && app.pendingUiClean) { 17781 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17782 && app.thread != null) { 17783 try { 17784 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17785 "Trimming memory of ui hidden " + app.processName 17786 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17787 app.thread.scheduleTrimMemory( 17788 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17789 } catch (RemoteException e) { 17790 } 17791 } 17792 app.pendingUiClean = false; 17793 } 17794 app.trimMemoryLevel = 0; 17795 } 17796 } 17797 17798 if (mAlwaysFinishActivities) { 17799 // Need to do this on its own message because the stack may not 17800 // be in a consistent state at this point. 17801 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17802 } 17803 17804 if (allChanged) { 17805 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17806 } 17807 17808 if (mProcessStats.shouldWriteNowLocked(now)) { 17809 mHandler.post(new Runnable() { 17810 @Override public void run() { 17811 synchronized (ActivityManagerService.this) { 17812 mProcessStats.writeStateAsyncLocked(); 17813 } 17814 } 17815 }); 17816 } 17817 17818 if (DEBUG_OOM_ADJ) { 17819 if (false) { 17820 RuntimeException here = new RuntimeException("here"); 17821 here.fillInStackTrace(); 17822 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here); 17823 } else { 17824 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17825 } 17826 } 17827 } 17828 17829 final void trimApplications() { 17830 synchronized (this) { 17831 int i; 17832 17833 // First remove any unused application processes whose package 17834 // has been removed. 17835 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17836 final ProcessRecord app = mRemovedProcesses.get(i); 17837 if (app.activities.size() == 0 17838 && app.curReceiver == null && app.services.size() == 0) { 17839 Slog.i( 17840 TAG, "Exiting empty application process " 17841 + app.processName + " (" 17842 + (app.thread != null ? app.thread.asBinder() : null) 17843 + ")\n"); 17844 if (app.pid > 0 && app.pid != MY_PID) { 17845 app.kill("empty", false); 17846 } else { 17847 try { 17848 app.thread.scheduleExit(); 17849 } catch (Exception e) { 17850 // Ignore exceptions. 17851 } 17852 } 17853 cleanUpApplicationRecordLocked(app, false, true, -1); 17854 mRemovedProcesses.remove(i); 17855 17856 if (app.persistent) { 17857 addAppLocked(app.info, false, null /* ABI override */); 17858 } 17859 } 17860 } 17861 17862 // Now update the oom adj for all processes. 17863 updateOomAdjLocked(); 17864 } 17865 } 17866 17867 /** This method sends the specified signal to each of the persistent apps */ 17868 public void signalPersistentProcesses(int sig) throws RemoteException { 17869 if (sig != Process.SIGNAL_USR1) { 17870 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17871 } 17872 17873 synchronized (this) { 17874 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17875 != PackageManager.PERMISSION_GRANTED) { 17876 throw new SecurityException("Requires permission " 17877 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17878 } 17879 17880 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17881 ProcessRecord r = mLruProcesses.get(i); 17882 if (r.thread != null && r.persistent) { 17883 Process.sendSignal(r.pid, sig); 17884 } 17885 } 17886 } 17887 } 17888 17889 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17890 if (proc == null || proc == mProfileProc) { 17891 proc = mProfileProc; 17892 profileType = mProfileType; 17893 clearProfilerLocked(); 17894 } 17895 if (proc == null) { 17896 return; 17897 } 17898 try { 17899 proc.thread.profilerControl(false, null, profileType); 17900 } catch (RemoteException e) { 17901 throw new IllegalStateException("Process disappeared"); 17902 } 17903 } 17904 17905 private void clearProfilerLocked() { 17906 if (mProfileFd != null) { 17907 try { 17908 mProfileFd.close(); 17909 } catch (IOException e) { 17910 } 17911 } 17912 mProfileApp = null; 17913 mProfileProc = null; 17914 mProfileFile = null; 17915 mProfileType = 0; 17916 mAutoStopProfiler = false; 17917 mSamplingInterval = 0; 17918 } 17919 17920 public boolean profileControl(String process, int userId, boolean start, 17921 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17922 17923 try { 17924 synchronized (this) { 17925 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17926 // its own permission. 17927 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17928 != PackageManager.PERMISSION_GRANTED) { 17929 throw new SecurityException("Requires permission " 17930 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17931 } 17932 17933 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17934 throw new IllegalArgumentException("null profile info or fd"); 17935 } 17936 17937 ProcessRecord proc = null; 17938 if (process != null) { 17939 proc = findProcessLocked(process, userId, "profileControl"); 17940 } 17941 17942 if (start && (proc == null || proc.thread == null)) { 17943 throw new IllegalArgumentException("Unknown process: " + process); 17944 } 17945 17946 if (start) { 17947 stopProfilerLocked(null, 0); 17948 setProfileApp(proc.info, proc.processName, profilerInfo); 17949 mProfileProc = proc; 17950 mProfileType = profileType; 17951 ParcelFileDescriptor fd = profilerInfo.profileFd; 17952 try { 17953 fd = fd.dup(); 17954 } catch (IOException e) { 17955 fd = null; 17956 } 17957 profilerInfo.profileFd = fd; 17958 proc.thread.profilerControl(start, profilerInfo, profileType); 17959 fd = null; 17960 mProfileFd = null; 17961 } else { 17962 stopProfilerLocked(proc, profileType); 17963 if (profilerInfo != null && profilerInfo.profileFd != null) { 17964 try { 17965 profilerInfo.profileFd.close(); 17966 } catch (IOException e) { 17967 } 17968 } 17969 } 17970 17971 return true; 17972 } 17973 } catch (RemoteException e) { 17974 throw new IllegalStateException("Process disappeared"); 17975 } finally { 17976 if (profilerInfo != null && profilerInfo.profileFd != null) { 17977 try { 17978 profilerInfo.profileFd.close(); 17979 } catch (IOException e) { 17980 } 17981 } 17982 } 17983 } 17984 17985 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17986 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17987 userId, true, ALLOW_FULL_ONLY, callName, null); 17988 ProcessRecord proc = null; 17989 try { 17990 int pid = Integer.parseInt(process); 17991 synchronized (mPidsSelfLocked) { 17992 proc = mPidsSelfLocked.get(pid); 17993 } 17994 } catch (NumberFormatException e) { 17995 } 17996 17997 if (proc == null) { 17998 ArrayMap<String, SparseArray<ProcessRecord>> all 17999 = mProcessNames.getMap(); 18000 SparseArray<ProcessRecord> procs = all.get(process); 18001 if (procs != null && procs.size() > 0) { 18002 proc = procs.valueAt(0); 18003 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 18004 for (int i=1; i<procs.size(); i++) { 18005 ProcessRecord thisProc = procs.valueAt(i); 18006 if (thisProc.userId == userId) { 18007 proc = thisProc; 18008 break; 18009 } 18010 } 18011 } 18012 } 18013 } 18014 18015 return proc; 18016 } 18017 18018 public boolean dumpHeap(String process, int userId, boolean managed, 18019 String path, ParcelFileDescriptor fd) throws RemoteException { 18020 18021 try { 18022 synchronized (this) { 18023 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 18024 // its own permission (same as profileControl). 18025 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 18026 != PackageManager.PERMISSION_GRANTED) { 18027 throw new SecurityException("Requires permission " 18028 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 18029 } 18030 18031 if (fd == null) { 18032 throw new IllegalArgumentException("null fd"); 18033 } 18034 18035 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 18036 if (proc == null || proc.thread == null) { 18037 throw new IllegalArgumentException("Unknown process: " + process); 18038 } 18039 18040 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 18041 if (!isDebuggable) { 18042 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 18043 throw new SecurityException("Process not debuggable: " + proc); 18044 } 18045 } 18046 18047 proc.thread.dumpHeap(managed, path, fd); 18048 fd = null; 18049 return true; 18050 } 18051 } catch (RemoteException e) { 18052 throw new IllegalStateException("Process disappeared"); 18053 } finally { 18054 if (fd != null) { 18055 try { 18056 fd.close(); 18057 } catch (IOException e) { 18058 } 18059 } 18060 } 18061 } 18062 18063 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 18064 public void monitor() { 18065 synchronized (this) { } 18066 } 18067 18068 void onCoreSettingsChange(Bundle settings) { 18069 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 18070 ProcessRecord processRecord = mLruProcesses.get(i); 18071 try { 18072 if (processRecord.thread != null) { 18073 processRecord.thread.setCoreSettings(settings); 18074 } 18075 } catch (RemoteException re) { 18076 /* ignore */ 18077 } 18078 } 18079 } 18080 18081 // Multi-user methods 18082 18083 /** 18084 * Start user, if its not already running, but don't bring it to foreground. 18085 */ 18086 @Override 18087 public boolean startUserInBackground(final int userId) { 18088 return startUser(userId, /* foreground */ false); 18089 } 18090 18091 /** 18092 * Start user, if its not already running, and bring it to foreground. 18093 */ 18094 boolean startUserInForeground(final int userId, Dialog dlg) { 18095 boolean result = startUser(userId, /* foreground */ true); 18096 dlg.dismiss(); 18097 return result; 18098 } 18099 18100 /** 18101 * Refreshes the list of users related to the current user when either a 18102 * user switch happens or when a new related user is started in the 18103 * background. 18104 */ 18105 private void updateCurrentProfileIdsLocked() { 18106 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18107 mCurrentUserId, false /* enabledOnly */); 18108 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 18109 for (int i = 0; i < currentProfileIds.length; i++) { 18110 currentProfileIds[i] = profiles.get(i).id; 18111 } 18112 mCurrentProfileIds = currentProfileIds; 18113 18114 synchronized (mUserProfileGroupIdsSelfLocked) { 18115 mUserProfileGroupIdsSelfLocked.clear(); 18116 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 18117 for (int i = 0; i < users.size(); i++) { 18118 UserInfo user = users.get(i); 18119 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 18120 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 18121 } 18122 } 18123 } 18124 } 18125 18126 private Set getProfileIdsLocked(int userId) { 18127 Set userIds = new HashSet<Integer>(); 18128 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18129 userId, false /* enabledOnly */); 18130 for (UserInfo user : profiles) { 18131 userIds.add(Integer.valueOf(user.id)); 18132 } 18133 return userIds; 18134 } 18135 18136 @Override 18137 public boolean switchUser(final int userId) { 18138 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18139 String userName; 18140 synchronized (this) { 18141 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18142 if (userInfo == null) { 18143 Slog.w(TAG, "No user info for user #" + userId); 18144 return false; 18145 } 18146 if (userInfo.isManagedProfile()) { 18147 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18148 return false; 18149 } 18150 userName = userInfo.name; 18151 mTargetUserId = userId; 18152 } 18153 mHandler.removeMessages(START_USER_SWITCH_MSG); 18154 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18155 return true; 18156 } 18157 18158 private void showUserSwitchDialog(int userId, String userName) { 18159 // The dialog will show and then initiate the user switch by calling startUserInForeground 18160 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18161 true /* above system */); 18162 d.show(); 18163 } 18164 18165 private boolean startUser(final int userId, final boolean foreground) { 18166 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18167 != PackageManager.PERMISSION_GRANTED) { 18168 String msg = "Permission Denial: switchUser() from pid=" 18169 + Binder.getCallingPid() 18170 + ", uid=" + Binder.getCallingUid() 18171 + " requires " + INTERACT_ACROSS_USERS_FULL; 18172 Slog.w(TAG, msg); 18173 throw new SecurityException(msg); 18174 } 18175 18176 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18177 18178 final long ident = Binder.clearCallingIdentity(); 18179 try { 18180 synchronized (this) { 18181 final int oldUserId = mCurrentUserId; 18182 if (oldUserId == userId) { 18183 return true; 18184 } 18185 18186 mStackSupervisor.setLockTaskModeLocked(null, false); 18187 18188 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18189 if (userInfo == null) { 18190 Slog.w(TAG, "No user info for user #" + userId); 18191 return false; 18192 } 18193 if (foreground && userInfo.isManagedProfile()) { 18194 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18195 return false; 18196 } 18197 18198 if (foreground) { 18199 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18200 R.anim.screen_user_enter); 18201 } 18202 18203 boolean needStart = false; 18204 18205 // If the user we are switching to is not currently started, then 18206 // we need to start it now. 18207 if (mStartedUsers.get(userId) == null) { 18208 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18209 updateStartedUserArrayLocked(); 18210 needStart = true; 18211 } 18212 18213 final Integer userIdInt = Integer.valueOf(userId); 18214 mUserLru.remove(userIdInt); 18215 mUserLru.add(userIdInt); 18216 18217 if (foreground) { 18218 mCurrentUserId = userId; 18219 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18220 updateCurrentProfileIdsLocked(); 18221 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18222 // Once the internal notion of the active user has switched, we lock the device 18223 // with the option to show the user switcher on the keyguard. 18224 mWindowManager.lockNow(null); 18225 } else { 18226 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18227 updateCurrentProfileIdsLocked(); 18228 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18229 mUserLru.remove(currentUserIdInt); 18230 mUserLru.add(currentUserIdInt); 18231 } 18232 18233 final UserStartedState uss = mStartedUsers.get(userId); 18234 18235 // Make sure user is in the started state. If it is currently 18236 // stopping, we need to knock that off. 18237 if (uss.mState == UserStartedState.STATE_STOPPING) { 18238 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18239 // so we can just fairly silently bring the user back from 18240 // the almost-dead. 18241 uss.mState = UserStartedState.STATE_RUNNING; 18242 updateStartedUserArrayLocked(); 18243 needStart = true; 18244 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18245 // This means ACTION_SHUTDOWN has been sent, so we will 18246 // need to treat this as a new boot of the user. 18247 uss.mState = UserStartedState.STATE_BOOTING; 18248 updateStartedUserArrayLocked(); 18249 needStart = true; 18250 } 18251 18252 if (uss.mState == UserStartedState.STATE_BOOTING) { 18253 // Booting up a new user, need to tell system services about it. 18254 // Note that this is on the same handler as scheduling of broadcasts, 18255 // which is important because it needs to go first. 18256 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18257 } 18258 18259 if (foreground) { 18260 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18261 oldUserId)); 18262 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18263 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18264 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18265 oldUserId, userId, uss)); 18266 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18267 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18268 } 18269 18270 if (needStart) { 18271 // Send USER_STARTED broadcast 18272 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18273 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18274 | Intent.FLAG_RECEIVER_FOREGROUND); 18275 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18276 broadcastIntentLocked(null, null, intent, 18277 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18278 false, false, MY_PID, Process.SYSTEM_UID, userId); 18279 } 18280 18281 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18282 if (userId != UserHandle.USER_OWNER) { 18283 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18284 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18285 broadcastIntentLocked(null, null, intent, null, 18286 new IIntentReceiver.Stub() { 18287 public void performReceive(Intent intent, int resultCode, 18288 String data, Bundle extras, boolean ordered, 18289 boolean sticky, int sendingUser) { 18290 onUserInitialized(uss, foreground, oldUserId, userId); 18291 } 18292 }, 0, null, null, null, AppOpsManager.OP_NONE, 18293 true, false, MY_PID, Process.SYSTEM_UID, 18294 userId); 18295 uss.initializing = true; 18296 } else { 18297 getUserManagerLocked().makeInitialized(userInfo.id); 18298 } 18299 } 18300 18301 if (foreground) { 18302 if (!uss.initializing) { 18303 moveUserToForeground(uss, oldUserId, userId); 18304 } 18305 } else { 18306 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18307 } 18308 18309 if (needStart) { 18310 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18311 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18312 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18313 broadcastIntentLocked(null, null, intent, 18314 null, new IIntentReceiver.Stub() { 18315 @Override 18316 public void performReceive(Intent intent, int resultCode, String data, 18317 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18318 throws RemoteException { 18319 } 18320 }, 0, null, null, 18321 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18322 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18323 } 18324 } 18325 } finally { 18326 Binder.restoreCallingIdentity(ident); 18327 } 18328 18329 return true; 18330 } 18331 18332 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18333 long ident = Binder.clearCallingIdentity(); 18334 try { 18335 Intent intent; 18336 if (oldUserId >= 0) { 18337 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18338 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18339 int count = profiles.size(); 18340 for (int i = 0; i < count; i++) { 18341 int profileUserId = profiles.get(i).id; 18342 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18343 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18344 | Intent.FLAG_RECEIVER_FOREGROUND); 18345 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18346 broadcastIntentLocked(null, null, intent, 18347 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18348 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18349 } 18350 } 18351 if (newUserId >= 0) { 18352 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18353 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18354 int count = profiles.size(); 18355 for (int i = 0; i < count; i++) { 18356 int profileUserId = profiles.get(i).id; 18357 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18358 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18359 | Intent.FLAG_RECEIVER_FOREGROUND); 18360 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18361 broadcastIntentLocked(null, null, intent, 18362 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18363 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18364 } 18365 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18366 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18367 | Intent.FLAG_RECEIVER_FOREGROUND); 18368 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18369 broadcastIntentLocked(null, null, intent, 18370 null, null, 0, null, null, 18371 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18372 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18373 } 18374 } finally { 18375 Binder.restoreCallingIdentity(ident); 18376 } 18377 } 18378 18379 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18380 final int newUserId) { 18381 final int N = mUserSwitchObservers.beginBroadcast(); 18382 if (N > 0) { 18383 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18384 int mCount = 0; 18385 @Override 18386 public void sendResult(Bundle data) throws RemoteException { 18387 synchronized (ActivityManagerService.this) { 18388 if (mCurUserSwitchCallback == this) { 18389 mCount++; 18390 if (mCount == N) { 18391 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18392 } 18393 } 18394 } 18395 } 18396 }; 18397 synchronized (this) { 18398 uss.switching = true; 18399 mCurUserSwitchCallback = callback; 18400 } 18401 for (int i=0; i<N; i++) { 18402 try { 18403 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18404 newUserId, callback); 18405 } catch (RemoteException e) { 18406 } 18407 } 18408 } else { 18409 synchronized (this) { 18410 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18411 } 18412 } 18413 mUserSwitchObservers.finishBroadcast(); 18414 } 18415 18416 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18417 synchronized (this) { 18418 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18419 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18420 } 18421 } 18422 18423 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18424 mCurUserSwitchCallback = null; 18425 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18426 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18427 oldUserId, newUserId, uss)); 18428 } 18429 18430 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18431 synchronized (this) { 18432 if (foreground) { 18433 moveUserToForeground(uss, oldUserId, newUserId); 18434 } 18435 } 18436 18437 completeSwitchAndInitalize(uss, newUserId, true, false); 18438 } 18439 18440 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18441 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18442 if (homeInFront) { 18443 startHomeActivityLocked(newUserId); 18444 } else { 18445 mStackSupervisor.resumeTopActivitiesLocked(); 18446 } 18447 EventLogTags.writeAmSwitchUser(newUserId); 18448 getUserManagerLocked().userForeground(newUserId); 18449 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18450 } 18451 18452 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18453 completeSwitchAndInitalize(uss, newUserId, false, true); 18454 } 18455 18456 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18457 boolean clearInitializing, boolean clearSwitching) { 18458 boolean unfrozen = false; 18459 synchronized (this) { 18460 if (clearInitializing) { 18461 uss.initializing = false; 18462 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18463 } 18464 if (clearSwitching) { 18465 uss.switching = false; 18466 } 18467 if (!uss.switching && !uss.initializing) { 18468 mWindowManager.stopFreezingScreen(); 18469 unfrozen = true; 18470 } 18471 } 18472 if (unfrozen) { 18473 final int N = mUserSwitchObservers.beginBroadcast(); 18474 for (int i=0; i<N; i++) { 18475 try { 18476 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18477 } catch (RemoteException e) { 18478 } 18479 } 18480 mUserSwitchObservers.finishBroadcast(); 18481 } 18482 } 18483 18484 void scheduleStartProfilesLocked() { 18485 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18486 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18487 DateUtils.SECOND_IN_MILLIS); 18488 } 18489 } 18490 18491 void startProfilesLocked() { 18492 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18493 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18494 mCurrentUserId, false /* enabledOnly */); 18495 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18496 for (UserInfo user : profiles) { 18497 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18498 && user.id != mCurrentUserId) { 18499 toStart.add(user); 18500 } 18501 } 18502 final int n = toStart.size(); 18503 int i = 0; 18504 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18505 startUserInBackground(toStart.get(i).id); 18506 } 18507 if (i < n) { 18508 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18509 } 18510 } 18511 18512 void finishUserBoot(UserStartedState uss) { 18513 synchronized (this) { 18514 if (uss.mState == UserStartedState.STATE_BOOTING 18515 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18516 uss.mState = UserStartedState.STATE_RUNNING; 18517 final int userId = uss.mHandle.getIdentifier(); 18518 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18519 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18520 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18521 broadcastIntentLocked(null, null, intent, 18522 null, null, 0, null, null, 18523 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18524 true, false, MY_PID, Process.SYSTEM_UID, userId); 18525 } 18526 } 18527 } 18528 18529 void finishUserSwitch(UserStartedState uss) { 18530 synchronized (this) { 18531 finishUserBoot(uss); 18532 18533 startProfilesLocked(); 18534 18535 int num = mUserLru.size(); 18536 int i = 0; 18537 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18538 Integer oldUserId = mUserLru.get(i); 18539 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18540 if (oldUss == null) { 18541 // Shouldn't happen, but be sane if it does. 18542 mUserLru.remove(i); 18543 num--; 18544 continue; 18545 } 18546 if (oldUss.mState == UserStartedState.STATE_STOPPING 18547 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18548 // This user is already stopping, doesn't count. 18549 num--; 18550 i++; 18551 continue; 18552 } 18553 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18554 // Owner and current can't be stopped, but count as running. 18555 i++; 18556 continue; 18557 } 18558 // This is a user to be stopped. 18559 stopUserLocked(oldUserId, null); 18560 num--; 18561 i++; 18562 } 18563 } 18564 } 18565 18566 @Override 18567 public int stopUser(final int userId, final IStopUserCallback callback) { 18568 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18569 != PackageManager.PERMISSION_GRANTED) { 18570 String msg = "Permission Denial: switchUser() from pid=" 18571 + Binder.getCallingPid() 18572 + ", uid=" + Binder.getCallingUid() 18573 + " requires " + INTERACT_ACROSS_USERS_FULL; 18574 Slog.w(TAG, msg); 18575 throw new SecurityException(msg); 18576 } 18577 if (userId <= 0) { 18578 throw new IllegalArgumentException("Can't stop primary user " + userId); 18579 } 18580 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId); 18581 synchronized (this) { 18582 return stopUserLocked(userId, callback); 18583 } 18584 } 18585 18586 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18587 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18588 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18589 return ActivityManager.USER_OP_IS_CURRENT; 18590 } 18591 18592 final UserStartedState uss = mStartedUsers.get(userId); 18593 if (uss == null) { 18594 // User is not started, nothing to do... but we do need to 18595 // callback if requested. 18596 if (callback != null) { 18597 mHandler.post(new Runnable() { 18598 @Override 18599 public void run() { 18600 try { 18601 callback.userStopped(userId); 18602 } catch (RemoteException e) { 18603 } 18604 } 18605 }); 18606 } 18607 return ActivityManager.USER_OP_SUCCESS; 18608 } 18609 18610 if (callback != null) { 18611 uss.mStopCallbacks.add(callback); 18612 } 18613 18614 if (uss.mState != UserStartedState.STATE_STOPPING 18615 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18616 uss.mState = UserStartedState.STATE_STOPPING; 18617 updateStartedUserArrayLocked(); 18618 18619 long ident = Binder.clearCallingIdentity(); 18620 try { 18621 // We are going to broadcast ACTION_USER_STOPPING and then 18622 // once that is done send a final ACTION_SHUTDOWN and then 18623 // stop the user. 18624 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18625 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18626 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18627 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18628 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18629 // This is the result receiver for the final shutdown broadcast. 18630 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18631 @Override 18632 public void performReceive(Intent intent, int resultCode, String data, 18633 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18634 finishUserStop(uss); 18635 } 18636 }; 18637 // This is the result receiver for the initial stopping broadcast. 18638 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18639 @Override 18640 public void performReceive(Intent intent, int resultCode, String data, 18641 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18642 // On to the next. 18643 synchronized (ActivityManagerService.this) { 18644 if (uss.mState != UserStartedState.STATE_STOPPING) { 18645 // Whoops, we are being started back up. Abort, abort! 18646 return; 18647 } 18648 uss.mState = UserStartedState.STATE_SHUTDOWN; 18649 } 18650 mBatteryStatsService.noteEvent( 18651 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18652 Integer.toString(userId), userId); 18653 mSystemServiceManager.stopUser(userId); 18654 broadcastIntentLocked(null, null, shutdownIntent, 18655 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18656 true, false, MY_PID, Process.SYSTEM_UID, userId); 18657 } 18658 }; 18659 // Kick things off. 18660 broadcastIntentLocked(null, null, stoppingIntent, 18661 null, stoppingReceiver, 0, null, null, 18662 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18663 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18664 } finally { 18665 Binder.restoreCallingIdentity(ident); 18666 } 18667 } 18668 18669 return ActivityManager.USER_OP_SUCCESS; 18670 } 18671 18672 void finishUserStop(UserStartedState uss) { 18673 final int userId = uss.mHandle.getIdentifier(); 18674 boolean stopped; 18675 ArrayList<IStopUserCallback> callbacks; 18676 synchronized (this) { 18677 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18678 if (mStartedUsers.get(userId) != uss) { 18679 stopped = false; 18680 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18681 stopped = false; 18682 } else { 18683 stopped = true; 18684 // User can no longer run. 18685 mStartedUsers.remove(userId); 18686 mUserLru.remove(Integer.valueOf(userId)); 18687 updateStartedUserArrayLocked(); 18688 18689 // Clean up all state and processes associated with the user. 18690 // Kill all the processes for the user. 18691 forceStopUserLocked(userId, "finish user"); 18692 } 18693 18694 // Explicitly remove the old information in mRecentTasks. 18695 removeRecentTasksForUserLocked(userId); 18696 } 18697 18698 for (int i=0; i<callbacks.size(); i++) { 18699 try { 18700 if (stopped) callbacks.get(i).userStopped(userId); 18701 else callbacks.get(i).userStopAborted(userId); 18702 } catch (RemoteException e) { 18703 } 18704 } 18705 18706 if (stopped) { 18707 mSystemServiceManager.cleanupUser(userId); 18708 synchronized (this) { 18709 mStackSupervisor.removeUserLocked(userId); 18710 } 18711 } 18712 } 18713 18714 @Override 18715 public UserInfo getCurrentUser() { 18716 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18717 != PackageManager.PERMISSION_GRANTED) && ( 18718 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18719 != PackageManager.PERMISSION_GRANTED)) { 18720 String msg = "Permission Denial: getCurrentUser() from pid=" 18721 + Binder.getCallingPid() 18722 + ", uid=" + Binder.getCallingUid() 18723 + " requires " + INTERACT_ACROSS_USERS; 18724 Slog.w(TAG, msg); 18725 throw new SecurityException(msg); 18726 } 18727 synchronized (this) { 18728 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18729 return getUserManagerLocked().getUserInfo(userId); 18730 } 18731 } 18732 18733 int getCurrentUserIdLocked() { 18734 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18735 } 18736 18737 @Override 18738 public boolean isUserRunning(int userId, boolean orStopped) { 18739 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18740 != PackageManager.PERMISSION_GRANTED) { 18741 String msg = "Permission Denial: isUserRunning() from pid=" 18742 + Binder.getCallingPid() 18743 + ", uid=" + Binder.getCallingUid() 18744 + " requires " + INTERACT_ACROSS_USERS; 18745 Slog.w(TAG, msg); 18746 throw new SecurityException(msg); 18747 } 18748 synchronized (this) { 18749 return isUserRunningLocked(userId, orStopped); 18750 } 18751 } 18752 18753 boolean isUserRunningLocked(int userId, boolean orStopped) { 18754 UserStartedState state = mStartedUsers.get(userId); 18755 if (state == null) { 18756 return false; 18757 } 18758 if (orStopped) { 18759 return true; 18760 } 18761 return state.mState != UserStartedState.STATE_STOPPING 18762 && state.mState != UserStartedState.STATE_SHUTDOWN; 18763 } 18764 18765 @Override 18766 public int[] getRunningUserIds() { 18767 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18768 != PackageManager.PERMISSION_GRANTED) { 18769 String msg = "Permission Denial: isUserRunning() from pid=" 18770 + Binder.getCallingPid() 18771 + ", uid=" + Binder.getCallingUid() 18772 + " requires " + INTERACT_ACROSS_USERS; 18773 Slog.w(TAG, msg); 18774 throw new SecurityException(msg); 18775 } 18776 synchronized (this) { 18777 return mStartedUserArray; 18778 } 18779 } 18780 18781 private void updateStartedUserArrayLocked() { 18782 int num = 0; 18783 for (int i=0; i<mStartedUsers.size(); i++) { 18784 UserStartedState uss = mStartedUsers.valueAt(i); 18785 // This list does not include stopping users. 18786 if (uss.mState != UserStartedState.STATE_STOPPING 18787 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18788 num++; 18789 } 18790 } 18791 mStartedUserArray = new int[num]; 18792 num = 0; 18793 for (int i=0; i<mStartedUsers.size(); i++) { 18794 UserStartedState uss = mStartedUsers.valueAt(i); 18795 if (uss.mState != UserStartedState.STATE_STOPPING 18796 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18797 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18798 num++; 18799 } 18800 } 18801 } 18802 18803 @Override 18804 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18805 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18806 != PackageManager.PERMISSION_GRANTED) { 18807 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18808 + Binder.getCallingPid() 18809 + ", uid=" + Binder.getCallingUid() 18810 + " requires " + INTERACT_ACROSS_USERS_FULL; 18811 Slog.w(TAG, msg); 18812 throw new SecurityException(msg); 18813 } 18814 18815 mUserSwitchObservers.register(observer); 18816 } 18817 18818 @Override 18819 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18820 mUserSwitchObservers.unregister(observer); 18821 } 18822 18823 private boolean userExists(int userId) { 18824 if (userId == 0) { 18825 return true; 18826 } 18827 UserManagerService ums = getUserManagerLocked(); 18828 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18829 } 18830 18831 int[] getUsersLocked() { 18832 UserManagerService ums = getUserManagerLocked(); 18833 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18834 } 18835 18836 UserManagerService getUserManagerLocked() { 18837 if (mUserManager == null) { 18838 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18839 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18840 } 18841 return mUserManager; 18842 } 18843 18844 private int applyUserId(int uid, int userId) { 18845 return UserHandle.getUid(userId, uid); 18846 } 18847 18848 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18849 if (info == null) return null; 18850 ApplicationInfo newInfo = new ApplicationInfo(info); 18851 newInfo.uid = applyUserId(info.uid, userId); 18852 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18853 + info.packageName; 18854 return newInfo; 18855 } 18856 18857 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18858 if (aInfo == null 18859 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18860 return aInfo; 18861 } 18862 18863 ActivityInfo info = new ActivityInfo(aInfo); 18864 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18865 return info; 18866 } 18867 18868 private final class LocalService extends ActivityManagerInternal { 18869 @Override 18870 public void goingToSleep() { 18871 ActivityManagerService.this.goingToSleep(); 18872 } 18873 18874 @Override 18875 public void wakingUp() { 18876 ActivityManagerService.this.wakingUp(); 18877 } 18878 18879 @Override 18880 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18881 String processName, String abiOverride, int uid, Runnable crashHandler) { 18882 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18883 processName, abiOverride, uid, crashHandler); 18884 } 18885 } 18886 18887 /** 18888 * An implementation of IAppTask, that allows an app to manage its own tasks via 18889 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18890 * only the process that calls getAppTasks() can call the AppTask methods. 18891 */ 18892 class AppTaskImpl extends IAppTask.Stub { 18893 private int mTaskId; 18894 private int mCallingUid; 18895 18896 public AppTaskImpl(int taskId, int callingUid) { 18897 mTaskId = taskId; 18898 mCallingUid = callingUid; 18899 } 18900 18901 private void checkCaller() { 18902 if (mCallingUid != Binder.getCallingUid()) { 18903 throw new SecurityException("Caller " + mCallingUid 18904 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18905 } 18906 } 18907 18908 @Override 18909 public void finishAndRemoveTask() { 18910 checkCaller(); 18911 18912 synchronized (ActivityManagerService.this) { 18913 long origId = Binder.clearCallingIdentity(); 18914 try { 18915 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18916 if (tr == null) { 18917 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18918 } 18919 // Only kill the process if we are not a new document 18920 int flags = tr.getBaseIntent().getFlags(); 18921 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18922 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18923 removeTaskByIdLocked(mTaskId, 18924 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18925 } finally { 18926 Binder.restoreCallingIdentity(origId); 18927 } 18928 } 18929 } 18930 18931 @Override 18932 public ActivityManager.RecentTaskInfo getTaskInfo() { 18933 checkCaller(); 18934 18935 synchronized (ActivityManagerService.this) { 18936 long origId = Binder.clearCallingIdentity(); 18937 try { 18938 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18939 if (tr == null) { 18940 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18941 } 18942 return createRecentTaskInfoFromTaskRecord(tr); 18943 } finally { 18944 Binder.restoreCallingIdentity(origId); 18945 } 18946 } 18947 } 18948 18949 @Override 18950 public void moveToFront() { 18951 checkCaller(); 18952 18953 final TaskRecord tr; 18954 synchronized (ActivityManagerService.this) { 18955 tr = recentTaskForIdLocked(mTaskId); 18956 if (tr == null) { 18957 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18958 } 18959 if (tr.getRootActivity() != null) { 18960 moveTaskToFrontLocked(tr.taskId, 0, null); 18961 } 18962 } 18963 18964 startActivityFromRecentsInner(tr.taskId, null); 18965 } 18966 18967 @Override 18968 public int startActivity(IBinder whoThread, String callingPackage, 18969 Intent intent, String resolvedType, Bundle options) { 18970 checkCaller(); 18971 18972 int callingUser = UserHandle.getCallingUserId(); 18973 TaskRecord tr; 18974 IApplicationThread appThread; 18975 synchronized (ActivityManagerService.this) { 18976 tr = recentTaskForIdLocked(mTaskId); 18977 if (tr == null) { 18978 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18979 } 18980 appThread = ApplicationThreadNative.asInterface(whoThread); 18981 if (appThread == null) { 18982 throw new IllegalArgumentException("Bad app thread " + appThread); 18983 } 18984 } 18985 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18986 resolvedType, null, null, null, null, 0, 0, null, null, 18987 null, options, callingUser, null, tr); 18988 } 18989 18990 @Override 18991 public void setExcludeFromRecents(boolean exclude) { 18992 checkCaller(); 18993 18994 synchronized (ActivityManagerService.this) { 18995 long origId = Binder.clearCallingIdentity(); 18996 try { 18997 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18998 if (tr == null) { 18999 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 19000 } 19001 Intent intent = tr.getBaseIntent(); 19002 if (exclude) { 19003 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19004 } else { 19005 intent.setFlags(intent.getFlags() 19006 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 19007 } 19008 } finally { 19009 Binder.restoreCallingIdentity(origId); 19010 } 19011 } 19012 } 19013 } 19014} 19015