ActivityManagerService.java revision a42c0de977fcd06e6c7a5be5b072fd661101ac58
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.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199 200import java.io.BufferedInputStream; 201import java.io.BufferedOutputStream; 202import java.io.DataInputStream; 203import java.io.DataOutputStream; 204import java.io.File; 205import java.io.FileDescriptor; 206import java.io.FileInputStream; 207import java.io.FileNotFoundException; 208import java.io.FileOutputStream; 209import java.io.IOException; 210import java.io.InputStreamReader; 211import java.io.PrintWriter; 212import java.io.StringWriter; 213import java.lang.ref.WeakReference; 214import java.util.ArrayList; 215import java.util.Arrays; 216import java.util.Collections; 217import java.util.Comparator; 218import java.util.HashMap; 219import java.util.HashSet; 220import java.util.Iterator; 221import java.util.List; 222import java.util.Locale; 223import java.util.Map; 224import java.util.Set; 225import java.util.concurrent.atomic.AtomicBoolean; 226import java.util.concurrent.atomic.AtomicLong; 227 228public final class ActivityManagerService extends ActivityManagerNative 229 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 230 231 private static final String USER_DATA_DIR = "/data/user/"; 232 // File that stores last updated system version and called preboot receivers 233 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 234 235 static final String TAG = "ActivityManager"; 236 static final String TAG_MU = "ActivityManagerServiceMU"; 237 static final boolean DEBUG = false; 238 static final boolean localLOGV = DEBUG; 239 static final boolean DEBUG_BACKUP = localLOGV || false; 240 static final boolean DEBUG_BROADCAST = localLOGV || false; 241 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 242 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_CLEANUP = localLOGV || false; 244 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 245 static final boolean DEBUG_FOCUS = false; 246 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 247 static final boolean DEBUG_MU = localLOGV || false; 248 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 249 static final boolean DEBUG_LRU = localLOGV || false; 250 static final boolean DEBUG_PAUSE = localLOGV || false; 251 static final boolean DEBUG_POWER = localLOGV || false; 252 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 253 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 254 static final boolean DEBUG_PROCESSES = localLOGV || false; 255 static final boolean DEBUG_PROVIDER = localLOGV || false; 256 static final boolean DEBUG_RESULTS = localLOGV || false; 257 static final boolean DEBUG_SERVICE = localLOGV || false; 258 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 259 static final boolean DEBUG_STACK = localLOGV || false; 260 static final boolean DEBUG_SWITCH = localLOGV || false; 261 static final boolean DEBUG_TASKS = localLOGV || false; 262 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 263 static final boolean DEBUG_TRANSITION = localLOGV || false; 264 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 265 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 266 static final boolean DEBUG_VISBILITY = localLOGV || false; 267 static final boolean DEBUG_PSS = localLOGV || false; 268 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 269 static final boolean DEBUG_RECENTS = localLOGV || false; 270 static final boolean VALIDATE_TOKENS = false; 271 static final boolean SHOW_ACTIVITY_START_TIME = true; 272 273 // Control over CPU and battery monitoring. 274 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 275 static final boolean MONITOR_CPU_USAGE = true; 276 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 277 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 278 static final boolean MONITOR_THREAD_CPU_USAGE = false; 279 280 // The flags that are set for all calls we make to the package manager. 281 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 282 283 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 284 285 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 286 287 // Maximum number recent bitmaps to keep in memory. 288 static final int MAX_RECENT_BITMAPS = 5; 289 290 // Amount of time after a call to stopAppSwitches() during which we will 291 // prevent further untrusted switches from happening. 292 static final long APP_SWITCH_DELAY_TIME = 5*1000; 293 294 // How long we wait for a launched process to attach to the activity manager 295 // before we decide it's never going to come up for real. 296 static final int PROC_START_TIMEOUT = 10*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real, when the process was 300 // started with a wrapper for instrumentation (such as Valgrind) because it 301 // could take much longer than usual. 302 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 303 304 // How long to wait after going idle before forcing apps to GC. 305 static final int GC_TIMEOUT = 5*1000; 306 307 // The minimum amount of time between successive GC requests for a process. 308 static final int GC_MIN_INTERVAL = 60*1000; 309 310 // The minimum amount of time between successive PSS requests for a process. 311 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 312 313 // The minimum amount of time between successive PSS requests for a process 314 // when the request is due to the memory state being lowered. 315 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 316 317 // The rate at which we check for apps using excessive power -- 15 mins. 318 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 319 320 // The minimum sample duration we will allow before deciding we have 321 // enough data on wake locks to start killing things. 322 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on CPU usage to start killing things. 326 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // How long we allow a receiver to run before giving up on it. 329 static final int BROADCAST_FG_TIMEOUT = 10*1000; 330 static final int BROADCAST_BG_TIMEOUT = 60*1000; 331 332 // How long we wait until we timeout on key dispatching. 333 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 334 335 // How long we wait until we timeout on key dispatching during instrumentation. 336 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 337 338 // Amount of time we wait for observers to handle a user switch before 339 // giving up on them and unfreezing the screen. 340 static final int USER_SWITCH_TIMEOUT = 2*1000; 341 342 // Maximum number of users we allow to be running at a time. 343 static final int MAX_RUNNING_USERS = 3; 344 345 // How long to wait in getAssistContextExtras for the activity and foreground services 346 // to respond with the result. 347 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 348 349 // Maximum number of persisted Uri grants a package is allowed 350 static final int MAX_PERSISTED_URI_GRANTS = 128; 351 352 static final int MY_PID = Process.myPid(); 353 354 static final String[] EMPTY_STRING_ARRAY = new String[0]; 355 356 // How many bytes to write into the dropbox log before truncating 357 static final int DROPBOX_MAX_SIZE = 256 * 1024; 358 359 // Access modes for handleIncomingUser. 360 static final int ALLOW_NON_FULL = 0; 361 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 362 static final int ALLOW_FULL_ONLY = 2; 363 364 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 365 366 /** All system services */ 367 SystemServiceManager mSystemServiceManager; 368 369 /** Run all ActivityStacks through this */ 370 ActivityStackSupervisor mStackSupervisor; 371 372 public IntentFirewall mIntentFirewall; 373 374 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 375 // default actuion automatically. Important for devices without direct input 376 // devices. 377 private boolean mShowDialogs = true; 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 415 416 /** 417 * For addAppTask: cached of the last activity component that was added. 418 */ 419 ComponentName mLastAddedTaskComponent; 420 421 /** 422 * For addAppTask: cached of the last activity uid that was added. 423 */ 424 int mLastAddedTaskUid; 425 426 /** 427 * For addAppTask: cached of the last ActivityInfo that was added. 428 */ 429 ActivityInfo mLastAddedTaskActivity; 430 431 public class PendingAssistExtras extends Binder implements Runnable { 432 public final ActivityRecord activity; 433 public boolean haveResult = false; 434 public Bundle result = null; 435 public PendingAssistExtras(ActivityRecord _activity) { 436 activity = _activity; 437 } 438 @Override 439 public void run() { 440 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 441 synchronized (this) { 442 haveResult = true; 443 notifyAll(); 444 } 445 } 446 } 447 448 final ArrayList<PendingAssistExtras> mPendingAssistExtras 449 = new ArrayList<PendingAssistExtras>(); 450 451 /** 452 * Process management. 453 */ 454 final ProcessList mProcessList = new ProcessList(); 455 456 /** 457 * All of the applications we currently have running organized by name. 458 * The keys are strings of the application package name (as 459 * returned by the package manager), and the keys are ApplicationRecord 460 * objects. 461 */ 462 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 463 464 /** 465 * Tracking long-term execution of processes to look for abuse and other 466 * bad app behavior. 467 */ 468 final ProcessStatsService mProcessStats; 469 470 /** 471 * The currently running isolated processes. 472 */ 473 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 474 475 /** 476 * Counter for assigning isolated process uids, to avoid frequently reusing the 477 * same ones. 478 */ 479 int mNextIsolatedProcessUid = 0; 480 481 /** 482 * The currently running heavy-weight process, if any. 483 */ 484 ProcessRecord mHeavyWeightProcess = null; 485 486 /** 487 * The last time that various processes have crashed. 488 */ 489 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 490 491 /** 492 * Information about a process that is currently marked as bad. 493 */ 494 static final class BadProcessInfo { 495 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 496 this.time = time; 497 this.shortMsg = shortMsg; 498 this.longMsg = longMsg; 499 this.stack = stack; 500 } 501 502 final long time; 503 final String shortMsg; 504 final String longMsg; 505 final String stack; 506 } 507 508 /** 509 * Set of applications that we consider to be bad, and will reject 510 * incoming broadcasts from (which the user has no control over). 511 * Processes are added to this set when they have crashed twice within 512 * a minimum amount of time; they are removed from it when they are 513 * later restarted (hopefully due to some user action). The value is the 514 * time it was added to the list. 515 */ 516 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 517 518 /** 519 * All of the processes we currently have running organized by pid. 520 * The keys are the pid running the application. 521 * 522 * <p>NOTE: This object is protected by its own lock, NOT the global 523 * activity manager lock! 524 */ 525 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 526 527 /** 528 * All of the processes that have been forced to be foreground. The key 529 * is the pid of the caller who requested it (we hold a death 530 * link on it). 531 */ 532 abstract class ForegroundToken implements IBinder.DeathRecipient { 533 int pid; 534 IBinder token; 535 } 536 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 537 538 /** 539 * List of records for processes that someone had tried to start before the 540 * system was ready. We don't start them at that point, but ensure they 541 * are started by the time booting is complete. 542 */ 543 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 544 545 /** 546 * List of persistent applications that are in the process 547 * of being started. 548 */ 549 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes that are being forcibly torn down. 553 */ 554 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * List of running applications, sorted by recent usage. 558 * The first entry in the list is the least recently used. 559 */ 560 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Where in mLruProcesses that the processes hosting activities start. 564 */ 565 int mLruProcessActivityStart = 0; 566 567 /** 568 * Where in mLruProcesses that the processes hosting services start. 569 * This is after (lower index) than mLruProcessesActivityStart. 570 */ 571 int mLruProcessServiceStart = 0; 572 573 /** 574 * List of processes that should gc as soon as things are idle. 575 */ 576 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes we want to collect PSS data from. 580 */ 581 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * Last time we requested PSS data of all processes. 585 */ 586 long mLastFullPssTime = SystemClock.uptimeMillis(); 587 588 /** 589 * If set, the next time we collect PSS data we should do a full collection 590 * with data from native processes and the kernel. 591 */ 592 boolean mFullPssPending = false; 593 594 /** 595 * This is the process holding what we currently consider to be 596 * the "home" activity. 597 */ 598 ProcessRecord mHomeProcess; 599 600 /** 601 * This is the process holding the activity the user last visited that 602 * is in a different process from the one they are currently in. 603 */ 604 ProcessRecord mPreviousProcess; 605 606 /** 607 * The time at which the previous process was last visible. 608 */ 609 long mPreviousProcessVisibleTime; 610 611 /** 612 * Which uses have been started, so are allowed to run code. 613 */ 614 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 615 616 /** 617 * LRU list of history of current users. Most recently current is at the end. 618 */ 619 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 620 621 /** 622 * Constant array of the users that are currently started. 623 */ 624 int[] mStartedUserArray = new int[] { 0 }; 625 626 /** 627 * Registered observers of the user switching mechanics. 628 */ 629 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 630 = new RemoteCallbackList<IUserSwitchObserver>(); 631 632 /** 633 * Currently active user switch. 634 */ 635 Object mCurUserSwitchCallback; 636 637 /** 638 * Packages that the user has asked to have run in screen size 639 * compatibility mode instead of filling the screen. 640 */ 641 final CompatModePackages mCompatModePackages; 642 643 /** 644 * Set of IntentSenderRecord objects that are currently active. 645 */ 646 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 647 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 648 649 /** 650 * Fingerprints (hashCode()) of stack traces that we've 651 * already logged DropBox entries for. Guarded by itself. If 652 * something (rogue user app) forces this over 653 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 654 */ 655 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 656 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 657 658 /** 659 * Strict Mode background batched logging state. 660 * 661 * The string buffer is guarded by itself, and its lock is also 662 * used to determine if another batched write is already 663 * in-flight. 664 */ 665 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 666 667 /** 668 * Keeps track of all IIntentReceivers that have been registered for 669 * broadcasts. Hash keys are the receiver IBinder, hash value is 670 * a ReceiverList. 671 */ 672 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 673 new HashMap<IBinder, ReceiverList>(); 674 675 /** 676 * Resolver for broadcast intents to registered receivers. 677 * Holds BroadcastFilter (subclass of IntentFilter). 678 */ 679 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 680 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 681 @Override 682 protected boolean allowFilterResult( 683 BroadcastFilter filter, List<BroadcastFilter> dest) { 684 IBinder target = filter.receiverList.receiver.asBinder(); 685 for (int i=dest.size()-1; i>=0; i--) { 686 if (dest.get(i).receiverList.receiver.asBinder() == target) { 687 return false; 688 } 689 } 690 return true; 691 } 692 693 @Override 694 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 695 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 696 || userId == filter.owningUserId) { 697 return super.newResult(filter, match, userId); 698 } 699 return null; 700 } 701 702 @Override 703 protected BroadcastFilter[] newArray(int size) { 704 return new BroadcastFilter[size]; 705 } 706 707 @Override 708 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 709 return packageName.equals(filter.packageName); 710 } 711 }; 712 713 /** 714 * State of all active sticky broadcasts per user. Keys are the action of the 715 * sticky Intent, values are an ArrayList of all broadcasted intents with 716 * that action (which should usually be one). The SparseArray is keyed 717 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 718 * for stickies that are sent to all users. 719 */ 720 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 721 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 722 723 final ActiveServices mServices; 724 725 /** 726 * Backup/restore process management 727 */ 728 String mBackupAppName = null; 729 BackupRecord mBackupTarget = null; 730 731 final ProviderMap mProviderMap; 732 733 /** 734 * List of content providers who have clients waiting for them. The 735 * application is currently being launched and the provider will be 736 * removed from this list once it is published. 737 */ 738 final ArrayList<ContentProviderRecord> mLaunchingProviders 739 = new ArrayList<ContentProviderRecord>(); 740 741 /** 742 * File storing persisted {@link #mGrantedUriPermissions}. 743 */ 744 private final AtomicFile mGrantFile; 745 746 /** XML constants used in {@link #mGrantFile} */ 747 private static final String TAG_URI_GRANTS = "uri-grants"; 748 private static final String TAG_URI_GRANT = "uri-grant"; 749 private static final String ATTR_USER_HANDLE = "userHandle"; 750 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 751 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 752 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 753 private static final String ATTR_TARGET_PKG = "targetPkg"; 754 private static final String ATTR_URI = "uri"; 755 private static final String ATTR_MODE_FLAGS = "modeFlags"; 756 private static final String ATTR_CREATED_TIME = "createdTime"; 757 private static final String ATTR_PREFIX = "prefix"; 758 759 /** 760 * Global set of specific {@link Uri} permissions that have been granted. 761 * This optimized lookup structure maps from {@link UriPermission#targetUid} 762 * to {@link UriPermission#uri} to {@link UriPermission}. 763 */ 764 @GuardedBy("this") 765 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 766 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 767 768 public static class GrantUri { 769 public final int sourceUserId; 770 public final Uri uri; 771 public boolean prefix; 772 773 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 774 this.sourceUserId = sourceUserId; 775 this.uri = uri; 776 this.prefix = prefix; 777 } 778 779 @Override 780 public int hashCode() { 781 return toString().hashCode(); 782 } 783 784 @Override 785 public boolean equals(Object o) { 786 if (o instanceof GrantUri) { 787 GrantUri other = (GrantUri) o; 788 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 789 && prefix == other.prefix; 790 } 791 return false; 792 } 793 794 @Override 795 public String toString() { 796 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 797 if (prefix) result += " [prefix]"; 798 return result; 799 } 800 801 public String toSafeString() { 802 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 803 if (prefix) result += " [prefix]"; 804 return result; 805 } 806 807 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 808 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 809 ContentProvider.getUriWithoutUserId(uri), false); 810 } 811 } 812 813 CoreSettingsObserver mCoreSettingsObserver; 814 815 /** 816 * Thread-local storage used to carry caller permissions over through 817 * indirect content-provider access. 818 */ 819 private class Identity { 820 public int pid; 821 public int uid; 822 823 Identity(int _pid, int _uid) { 824 pid = _pid; 825 uid = _uid; 826 } 827 } 828 829 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 830 831 /** 832 * All information we have collected about the runtime performance of 833 * any user id that can impact battery performance. 834 */ 835 final BatteryStatsService mBatteryStatsService; 836 837 /** 838 * Information about component usage 839 */ 840 UsageStatsManagerInternal mUsageStatsService; 841 842 /** 843 * Information about and control over application operations 844 */ 845 final AppOpsService mAppOpsService; 846 847 /** 848 * Save recent tasks information across reboots. 849 */ 850 final TaskPersister mTaskPersister; 851 852 /** 853 * Current configuration information. HistoryRecord objects are given 854 * a reference to this object to indicate which configuration they are 855 * currently running in, so this object must be kept immutable. 856 */ 857 Configuration mConfiguration = new Configuration(); 858 859 /** 860 * Current sequencing integer of the configuration, for skipping old 861 * configurations. 862 */ 863 int mConfigurationSeq = 0; 864 865 /** 866 * Hardware-reported OpenGLES version. 867 */ 868 final int GL_ES_VERSION; 869 870 /** 871 * List of initialization arguments to pass to all processes when binding applications to them. 872 * For example, references to the commonly used services. 873 */ 874 HashMap<String, IBinder> mAppBindArgs; 875 876 /** 877 * Temporary to avoid allocations. Protected by main lock. 878 */ 879 final StringBuilder mStringBuilder = new StringBuilder(256); 880 881 /** 882 * Used to control how we initialize the service. 883 */ 884 ComponentName mTopComponent; 885 String mTopAction = Intent.ACTION_MAIN; 886 String mTopData; 887 boolean mProcessesReady = false; 888 boolean mSystemReady = false; 889 boolean mBooting = false; 890 boolean mWaitingUpdate = false; 891 boolean mDidUpdate = false; 892 boolean mOnBattery = false; 893 boolean mLaunchWarningShown = false; 894 895 Context mContext; 896 897 int mFactoryTest; 898 899 boolean mCheckedForSetup; 900 901 /** 902 * The time at which we will allow normal application switches again, 903 * after a call to {@link #stopAppSwitches()}. 904 */ 905 long mAppSwitchesAllowedTime; 906 907 /** 908 * This is set to true after the first switch after mAppSwitchesAllowedTime 909 * is set; any switches after that will clear the time. 910 */ 911 boolean mDidAppSwitch; 912 913 /** 914 * Last time (in realtime) at which we checked for power usage. 915 */ 916 long mLastPowerCheckRealtime; 917 918 /** 919 * Last time (in uptime) at which we checked for power usage. 920 */ 921 long mLastPowerCheckUptime; 922 923 /** 924 * Set while we are wanting to sleep, to prevent any 925 * activities from being started/resumed. 926 */ 927 private boolean mSleeping = false; 928 929 /** 930 * Set while we are running a voice interaction. This overrides 931 * sleeping while it is active. 932 */ 933 private boolean mRunningVoice = false; 934 935 /** 936 * State of external calls telling us if the device is asleep. 937 */ 938 private boolean mWentToSleep = false; 939 940 /** 941 * State of external call telling us if the lock screen is shown. 942 */ 943 private boolean mLockScreenShown = false; 944 945 /** 946 * Set if we are shutting down the system, similar to sleeping. 947 */ 948 boolean mShuttingDown = false; 949 950 /** 951 * Current sequence id for oom_adj computation traversal. 952 */ 953 int mAdjSeq = 0; 954 955 /** 956 * Current sequence id for process LRU updating. 957 */ 958 int mLruSeq = 0; 959 960 /** 961 * Keep track of the non-cached/empty process we last found, to help 962 * determine how to distribute cached/empty processes next time. 963 */ 964 int mNumNonCachedProcs = 0; 965 966 /** 967 * Keep track of the number of cached hidden procs, to balance oom adj 968 * distribution between those and empty procs. 969 */ 970 int mNumCachedHiddenProcs = 0; 971 972 /** 973 * Keep track of the number of service processes we last found, to 974 * determine on the next iteration which should be B services. 975 */ 976 int mNumServiceProcs = 0; 977 int mNewNumAServiceProcs = 0; 978 int mNewNumServiceProcs = 0; 979 980 /** 981 * Allow the current computed overall memory level of the system to go down? 982 * This is set to false when we are killing processes for reasons other than 983 * memory management, so that the now smaller process list will not be taken as 984 * an indication that memory is tighter. 985 */ 986 boolean mAllowLowerMemLevel = false; 987 988 /** 989 * The last computed memory level, for holding when we are in a state that 990 * processes are going away for other reasons. 991 */ 992 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 993 994 /** 995 * The last total number of process we have, to determine if changes actually look 996 * like a shrinking number of process due to lower RAM. 997 */ 998 int mLastNumProcesses; 999 1000 /** 1001 * The uptime of the last time we performed idle maintenance. 1002 */ 1003 long mLastIdleTime = SystemClock.uptimeMillis(); 1004 1005 /** 1006 * Total time spent with RAM that has been added in the past since the last idle time. 1007 */ 1008 long mLowRamTimeSinceLastIdle = 0; 1009 1010 /** 1011 * If RAM is currently low, when that horrible situation started. 1012 */ 1013 long mLowRamStartTime = 0; 1014 1015 /** 1016 * For reporting to battery stats the current top application. 1017 */ 1018 private String mCurResumedPackage = null; 1019 private int mCurResumedUid = -1; 1020 1021 /** 1022 * For reporting to battery stats the apps currently running foreground 1023 * service. The ProcessMap is package/uid tuples; each of these contain 1024 * an array of the currently foreground processes. 1025 */ 1026 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1027 = new ProcessMap<ArrayList<ProcessRecord>>(); 1028 1029 /** 1030 * This is set if we had to do a delayed dexopt of an app before launching 1031 * it, to increase the ANR timeouts in that case. 1032 */ 1033 boolean mDidDexOpt; 1034 1035 /** 1036 * Set if the systemServer made a call to enterSafeMode. 1037 */ 1038 boolean mSafeMode; 1039 1040 String mDebugApp = null; 1041 boolean mWaitForDebugger = false; 1042 boolean mDebugTransient = false; 1043 String mOrigDebugApp = null; 1044 boolean mOrigWaitForDebugger = false; 1045 boolean mAlwaysFinishActivities = false; 1046 IActivityController mController = null; 1047 String mProfileApp = null; 1048 ProcessRecord mProfileProc = null; 1049 String mProfileFile; 1050 ParcelFileDescriptor mProfileFd; 1051 int mSamplingInterval = 0; 1052 boolean mAutoStopProfiler = false; 1053 int mProfileType = 0; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 // Holds the current foreground user's id 1111 int mCurrentUserId = 0; 1112 // Holds the target user's id during a user switch 1113 int mTargetUserId = UserHandle.USER_NULL; 1114 // If there are multiple profiles for the current user, their ids are here 1115 // Currently only the primary user can have managed profiles 1116 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1117 1118 /** 1119 * Mapping from each known user ID to the profile group ID it is associated with. 1120 */ 1121 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1122 1123 private UserManagerService mUserManager; 1124 1125 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1126 final ProcessRecord mApp; 1127 final int mPid; 1128 final IApplicationThread mAppThread; 1129 1130 AppDeathRecipient(ProcessRecord app, int pid, 1131 IApplicationThread thread) { 1132 if (localLOGV) Slog.v( 1133 TAG, "New death recipient " + this 1134 + " for thread " + thread.asBinder()); 1135 mApp = app; 1136 mPid = pid; 1137 mAppThread = thread; 1138 } 1139 1140 @Override 1141 public void binderDied() { 1142 if (localLOGV) Slog.v( 1143 TAG, "Death received in " + this 1144 + " for thread " + mAppThread.asBinder()); 1145 synchronized(ActivityManagerService.this) { 1146 appDiedLocked(mApp, mPid, mAppThread); 1147 } 1148 } 1149 } 1150 1151 static final int SHOW_ERROR_MSG = 1; 1152 static final int SHOW_NOT_RESPONDING_MSG = 2; 1153 static final int SHOW_FACTORY_ERROR_MSG = 3; 1154 static final int UPDATE_CONFIGURATION_MSG = 4; 1155 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1156 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1157 static final int SERVICE_TIMEOUT_MSG = 12; 1158 static final int UPDATE_TIME_ZONE = 13; 1159 static final int SHOW_UID_ERROR_MSG = 14; 1160 static final int IM_FEELING_LUCKY_MSG = 15; 1161 static final int PROC_START_TIMEOUT_MSG = 20; 1162 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1163 static final int KILL_APPLICATION_MSG = 22; 1164 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1165 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1166 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1167 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1168 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1169 static final int CLEAR_DNS_CACHE_MSG = 28; 1170 static final int UPDATE_HTTP_PROXY_MSG = 29; 1171 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1172 static final int DISPATCH_PROCESSES_CHANGED = 31; 1173 static final int DISPATCH_PROCESS_DIED = 32; 1174 static final int REPORT_MEM_USAGE_MSG = 33; 1175 static final int REPORT_USER_SWITCH_MSG = 34; 1176 static final int CONTINUE_USER_SWITCH_MSG = 35; 1177 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1178 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1179 static final int PERSIST_URI_GRANTS_MSG = 38; 1180 static final int REQUEST_ALL_PSS_MSG = 39; 1181 static final int START_PROFILES_MSG = 40; 1182 static final int UPDATE_TIME = 41; 1183 static final int SYSTEM_USER_START_MSG = 42; 1184 static final int SYSTEM_USER_CURRENT_MSG = 43; 1185 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1186 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1187 static final int START_USER_SWITCH_MSG = 46; 1188 1189 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1190 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1191 static final int FIRST_COMPAT_MODE_MSG = 300; 1192 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1193 1194 AlertDialog mUidAlert; 1195 CompatModeDialog mCompatModeDialog; 1196 long mLastMemUsageReportTime = 0; 1197 1198 private LockToAppRequestDialog mLockToAppRequest; 1199 1200 /** 1201 * Flag whether the current user is a "monkey", i.e. whether 1202 * the UI is driven by a UI automation tool. 1203 */ 1204 private boolean mUserIsMonkey; 1205 1206 /** Flag whether the device has a Recents UI */ 1207 boolean mHasRecents; 1208 1209 /** The dimensions of the thumbnails in the Recents UI. */ 1210 int mThumbnailWidth; 1211 int mThumbnailHeight; 1212 1213 final ServiceThread mHandlerThread; 1214 final MainHandler mHandler; 1215 1216 final class MainHandler extends Handler { 1217 public MainHandler(Looper looper) { 1218 super(looper, null, true); 1219 } 1220 1221 @Override 1222 public void handleMessage(Message msg) { 1223 switch (msg.what) { 1224 case SHOW_ERROR_MSG: { 1225 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1226 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1227 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1228 synchronized (ActivityManagerService.this) { 1229 ProcessRecord proc = (ProcessRecord)data.get("app"); 1230 AppErrorResult res = (AppErrorResult) data.get("result"); 1231 if (proc != null && proc.crashDialog != null) { 1232 Slog.e(TAG, "App already has crash dialog: " + proc); 1233 if (res != null) { 1234 res.set(0); 1235 } 1236 return; 1237 } 1238 boolean isBackground = (UserHandle.getAppId(proc.uid) 1239 >= Process.FIRST_APPLICATION_UID 1240 && proc.pid != MY_PID); 1241 for (int userId : mCurrentProfileIds) { 1242 isBackground &= (proc.userId != userId); 1243 } 1244 if (isBackground && !showBackground) { 1245 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1246 if (res != null) { 1247 res.set(0); 1248 } 1249 return; 1250 } 1251 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1252 Dialog d = new AppErrorDialog(mContext, 1253 ActivityManagerService.this, res, proc); 1254 d.show(); 1255 proc.crashDialog = d; 1256 } else { 1257 // The device is asleep, so just pretend that the user 1258 // saw a crash dialog and hit "force quit". 1259 if (res != null) { 1260 res.set(0); 1261 } 1262 } 1263 } 1264 1265 ensureBootCompleted(); 1266 } break; 1267 case SHOW_NOT_RESPONDING_MSG: { 1268 synchronized (ActivityManagerService.this) { 1269 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1270 ProcessRecord proc = (ProcessRecord)data.get("app"); 1271 if (proc != null && proc.anrDialog != null) { 1272 Slog.e(TAG, "App already has anr dialog: " + proc); 1273 return; 1274 } 1275 1276 Intent intent = new Intent("android.intent.action.ANR"); 1277 if (!mProcessesReady) { 1278 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1279 | Intent.FLAG_RECEIVER_FOREGROUND); 1280 } 1281 broadcastIntentLocked(null, null, intent, 1282 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1283 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1284 1285 if (mShowDialogs) { 1286 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1287 mContext, proc, (ActivityRecord)data.get("activity"), 1288 msg.arg1 != 0); 1289 d.show(); 1290 proc.anrDialog = d; 1291 } else { 1292 // Just kill the app if there is no dialog to be shown. 1293 killAppAtUsersRequest(proc, null); 1294 } 1295 } 1296 1297 ensureBootCompleted(); 1298 } break; 1299 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1300 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1301 synchronized (ActivityManagerService.this) { 1302 ProcessRecord proc = (ProcessRecord) data.get("app"); 1303 if (proc == null) { 1304 Slog.e(TAG, "App not found when showing strict mode dialog."); 1305 break; 1306 } 1307 if (proc.crashDialog != null) { 1308 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1309 return; 1310 } 1311 AppErrorResult res = (AppErrorResult) data.get("result"); 1312 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1313 Dialog d = new StrictModeViolationDialog(mContext, 1314 ActivityManagerService.this, res, proc); 1315 d.show(); 1316 proc.crashDialog = d; 1317 } else { 1318 // The device is asleep, so just pretend that the user 1319 // saw a crash dialog and hit "force quit". 1320 res.set(0); 1321 } 1322 } 1323 ensureBootCompleted(); 1324 } break; 1325 case SHOW_FACTORY_ERROR_MSG: { 1326 Dialog d = new FactoryErrorDialog( 1327 mContext, msg.getData().getCharSequence("msg")); 1328 d.show(); 1329 ensureBootCompleted(); 1330 } break; 1331 case UPDATE_CONFIGURATION_MSG: { 1332 final ContentResolver resolver = mContext.getContentResolver(); 1333 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1334 } break; 1335 case GC_BACKGROUND_PROCESSES_MSG: { 1336 synchronized (ActivityManagerService.this) { 1337 performAppGcsIfAppropriateLocked(); 1338 } 1339 } break; 1340 case WAIT_FOR_DEBUGGER_MSG: { 1341 synchronized (ActivityManagerService.this) { 1342 ProcessRecord app = (ProcessRecord)msg.obj; 1343 if (msg.arg1 != 0) { 1344 if (!app.waitedForDebugger) { 1345 Dialog d = new AppWaitingForDebuggerDialog( 1346 ActivityManagerService.this, 1347 mContext, app); 1348 app.waitDialog = d; 1349 app.waitedForDebugger = true; 1350 d.show(); 1351 } 1352 } else { 1353 if (app.waitDialog != null) { 1354 app.waitDialog.dismiss(); 1355 app.waitDialog = null; 1356 } 1357 } 1358 } 1359 } break; 1360 case SERVICE_TIMEOUT_MSG: { 1361 if (mDidDexOpt) { 1362 mDidDexOpt = false; 1363 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1364 nmsg.obj = msg.obj; 1365 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1366 return; 1367 } 1368 mServices.serviceTimeout((ProcessRecord)msg.obj); 1369 } break; 1370 case UPDATE_TIME_ZONE: { 1371 synchronized (ActivityManagerService.this) { 1372 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1373 ProcessRecord r = mLruProcesses.get(i); 1374 if (r.thread != null) { 1375 try { 1376 r.thread.updateTimeZone(); 1377 } catch (RemoteException ex) { 1378 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1379 } 1380 } 1381 } 1382 } 1383 } break; 1384 case CLEAR_DNS_CACHE_MSG: { 1385 synchronized (ActivityManagerService.this) { 1386 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1387 ProcessRecord r = mLruProcesses.get(i); 1388 if (r.thread != null) { 1389 try { 1390 r.thread.clearDnsCache(); 1391 } catch (RemoteException ex) { 1392 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1393 } 1394 } 1395 } 1396 } 1397 } break; 1398 case UPDATE_HTTP_PROXY_MSG: { 1399 ProxyInfo proxy = (ProxyInfo)msg.obj; 1400 String host = ""; 1401 String port = ""; 1402 String exclList = ""; 1403 Uri pacFileUrl = Uri.EMPTY; 1404 if (proxy != null) { 1405 host = proxy.getHost(); 1406 port = Integer.toString(proxy.getPort()); 1407 exclList = proxy.getExclusionListAsString(); 1408 pacFileUrl = proxy.getPacFileUrl(); 1409 } 1410 synchronized (ActivityManagerService.this) { 1411 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1412 ProcessRecord r = mLruProcesses.get(i); 1413 if (r.thread != null) { 1414 try { 1415 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1416 } catch (RemoteException ex) { 1417 Slog.w(TAG, "Failed to update http proxy for: " + 1418 r.info.processName); 1419 } 1420 } 1421 } 1422 } 1423 } break; 1424 case SHOW_UID_ERROR_MSG: { 1425 String title = "System UIDs Inconsistent"; 1426 String text = "UIDs on the system are inconsistent, you need to wipe your" 1427 + " data partition or your device will be unstable."; 1428 Log.e(TAG, title + ": " + text); 1429 if (mShowDialogs) { 1430 // XXX This is a temporary dialog, no need to localize. 1431 AlertDialog d = new BaseErrorDialog(mContext); 1432 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1433 d.setCancelable(false); 1434 d.setTitle(title); 1435 d.setMessage(text); 1436 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1437 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1438 mUidAlert = d; 1439 d.show(); 1440 } 1441 } break; 1442 case IM_FEELING_LUCKY_MSG: { 1443 if (mUidAlert != null) { 1444 mUidAlert.dismiss(); 1445 mUidAlert = null; 1446 } 1447 } break; 1448 case PROC_START_TIMEOUT_MSG: { 1449 if (mDidDexOpt) { 1450 mDidDexOpt = false; 1451 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1452 nmsg.obj = msg.obj; 1453 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1454 return; 1455 } 1456 ProcessRecord app = (ProcessRecord)msg.obj; 1457 synchronized (ActivityManagerService.this) { 1458 processStartTimedOutLocked(app); 1459 } 1460 } break; 1461 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1462 synchronized (ActivityManagerService.this) { 1463 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1464 } 1465 } break; 1466 case KILL_APPLICATION_MSG: { 1467 synchronized (ActivityManagerService.this) { 1468 int appid = msg.arg1; 1469 boolean restart = (msg.arg2 == 1); 1470 Bundle bundle = (Bundle)msg.obj; 1471 String pkg = bundle.getString("pkg"); 1472 String reason = bundle.getString("reason"); 1473 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1474 false, UserHandle.USER_ALL, reason); 1475 } 1476 } break; 1477 case FINALIZE_PENDING_INTENT_MSG: { 1478 ((PendingIntentRecord)msg.obj).completeFinalize(); 1479 } break; 1480 case POST_HEAVY_NOTIFICATION_MSG: { 1481 INotificationManager inm = NotificationManager.getService(); 1482 if (inm == null) { 1483 return; 1484 } 1485 1486 ActivityRecord root = (ActivityRecord)msg.obj; 1487 ProcessRecord process = root.app; 1488 if (process == null) { 1489 return; 1490 } 1491 1492 try { 1493 Context context = mContext.createPackageContext(process.info.packageName, 0); 1494 String text = mContext.getString(R.string.heavy_weight_notification, 1495 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1496 Notification notification = new Notification(); 1497 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1498 notification.when = 0; 1499 notification.flags = Notification.FLAG_ONGOING_EVENT; 1500 notification.tickerText = text; 1501 notification.defaults = 0; // please be quiet 1502 notification.sound = null; 1503 notification.vibrate = null; 1504 notification.color = mContext.getResources().getColor( 1505 com.android.internal.R.color.system_notification_accent_color); 1506 notification.setLatestEventInfo(context, text, 1507 mContext.getText(R.string.heavy_weight_notification_detail), 1508 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1509 PendingIntent.FLAG_CANCEL_CURRENT, null, 1510 new UserHandle(root.userId))); 1511 1512 try { 1513 int[] outId = new int[1]; 1514 inm.enqueueNotificationWithTag("android", "android", null, 1515 R.string.heavy_weight_notification, 1516 notification, outId, root.userId); 1517 } catch (RuntimeException e) { 1518 Slog.w(ActivityManagerService.TAG, 1519 "Error showing notification for heavy-weight app", e); 1520 } catch (RemoteException e) { 1521 } 1522 } catch (NameNotFoundException e) { 1523 Slog.w(TAG, "Unable to create context for heavy notification", e); 1524 } 1525 } break; 1526 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1527 INotificationManager inm = NotificationManager.getService(); 1528 if (inm == null) { 1529 return; 1530 } 1531 try { 1532 inm.cancelNotificationWithTag("android", null, 1533 R.string.heavy_weight_notification, msg.arg1); 1534 } catch (RuntimeException e) { 1535 Slog.w(ActivityManagerService.TAG, 1536 "Error canceling notification for service", e); 1537 } catch (RemoteException e) { 1538 } 1539 } break; 1540 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1541 synchronized (ActivityManagerService.this) { 1542 checkExcessivePowerUsageLocked(true); 1543 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1544 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1545 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1546 } 1547 } break; 1548 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1549 synchronized (ActivityManagerService.this) { 1550 ActivityRecord ar = (ActivityRecord)msg.obj; 1551 if (mCompatModeDialog != null) { 1552 if (mCompatModeDialog.mAppInfo.packageName.equals( 1553 ar.info.applicationInfo.packageName)) { 1554 return; 1555 } 1556 mCompatModeDialog.dismiss(); 1557 mCompatModeDialog = null; 1558 } 1559 if (ar != null && false) { 1560 if (mCompatModePackages.getPackageAskCompatModeLocked( 1561 ar.packageName)) { 1562 int mode = mCompatModePackages.computeCompatModeLocked( 1563 ar.info.applicationInfo); 1564 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1565 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1566 mCompatModeDialog = new CompatModeDialog( 1567 ActivityManagerService.this, mContext, 1568 ar.info.applicationInfo); 1569 mCompatModeDialog.show(); 1570 } 1571 } 1572 } 1573 } 1574 break; 1575 } 1576 case DISPATCH_PROCESSES_CHANGED: { 1577 dispatchProcessesChanged(); 1578 break; 1579 } 1580 case DISPATCH_PROCESS_DIED: { 1581 final int pid = msg.arg1; 1582 final int uid = msg.arg2; 1583 dispatchProcessDied(pid, uid); 1584 break; 1585 } 1586 case REPORT_MEM_USAGE_MSG: { 1587 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1588 Thread thread = new Thread() { 1589 @Override public void run() { 1590 final SparseArray<ProcessMemInfo> infoMap 1591 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1592 for (int i=0, N=memInfos.size(); i<N; i++) { 1593 ProcessMemInfo mi = memInfos.get(i); 1594 infoMap.put(mi.pid, mi); 1595 } 1596 updateCpuStatsNow(); 1597 synchronized (mProcessCpuThread) { 1598 final int N = mProcessCpuTracker.countStats(); 1599 for (int i=0; i<N; i++) { 1600 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1601 if (st.vsize > 0) { 1602 long pss = Debug.getPss(st.pid, null); 1603 if (pss > 0) { 1604 if (infoMap.indexOfKey(st.pid) < 0) { 1605 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1606 ProcessList.NATIVE_ADJ, -1, "native", null); 1607 mi.pss = pss; 1608 memInfos.add(mi); 1609 } 1610 } 1611 } 1612 } 1613 } 1614 1615 long totalPss = 0; 1616 for (int i=0, N=memInfos.size(); i<N; i++) { 1617 ProcessMemInfo mi = memInfos.get(i); 1618 if (mi.pss == 0) { 1619 mi.pss = Debug.getPss(mi.pid, null); 1620 } 1621 totalPss += mi.pss; 1622 } 1623 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1624 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1625 if (lhs.oomAdj != rhs.oomAdj) { 1626 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1627 } 1628 if (lhs.pss != rhs.pss) { 1629 return lhs.pss < rhs.pss ? 1 : -1; 1630 } 1631 return 0; 1632 } 1633 }); 1634 1635 StringBuilder tag = new StringBuilder(128); 1636 StringBuilder stack = new StringBuilder(128); 1637 tag.append("Low on memory -- "); 1638 appendMemBucket(tag, totalPss, "total", false); 1639 appendMemBucket(stack, totalPss, "total", true); 1640 1641 StringBuilder logBuilder = new StringBuilder(1024); 1642 logBuilder.append("Low on memory:\n"); 1643 1644 boolean firstLine = true; 1645 int lastOomAdj = Integer.MIN_VALUE; 1646 for (int i=0, N=memInfos.size(); i<N; i++) { 1647 ProcessMemInfo mi = memInfos.get(i); 1648 1649 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1650 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1651 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1652 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1653 if (lastOomAdj != mi.oomAdj) { 1654 lastOomAdj = mi.oomAdj; 1655 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1656 tag.append(" / "); 1657 } 1658 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1659 if (firstLine) { 1660 stack.append(":"); 1661 firstLine = false; 1662 } 1663 stack.append("\n\t at "); 1664 } else { 1665 stack.append("$"); 1666 } 1667 } else { 1668 tag.append(" "); 1669 stack.append("$"); 1670 } 1671 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1672 appendMemBucket(tag, mi.pss, mi.name, false); 1673 } 1674 appendMemBucket(stack, mi.pss, mi.name, true); 1675 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1676 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1677 stack.append("("); 1678 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1679 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1680 stack.append(DUMP_MEM_OOM_LABEL[k]); 1681 stack.append(":"); 1682 stack.append(DUMP_MEM_OOM_ADJ[k]); 1683 } 1684 } 1685 stack.append(")"); 1686 } 1687 } 1688 1689 logBuilder.append(" "); 1690 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1691 logBuilder.append(' '); 1692 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1693 logBuilder.append(' '); 1694 ProcessList.appendRamKb(logBuilder, mi.pss); 1695 logBuilder.append(" kB: "); 1696 logBuilder.append(mi.name); 1697 logBuilder.append(" ("); 1698 logBuilder.append(mi.pid); 1699 logBuilder.append(") "); 1700 logBuilder.append(mi.adjType); 1701 logBuilder.append('\n'); 1702 if (mi.adjReason != null) { 1703 logBuilder.append(" "); 1704 logBuilder.append(mi.adjReason); 1705 logBuilder.append('\n'); 1706 } 1707 } 1708 1709 logBuilder.append(" "); 1710 ProcessList.appendRamKb(logBuilder, totalPss); 1711 logBuilder.append(" kB: TOTAL\n"); 1712 1713 long[] infos = new long[Debug.MEMINFO_COUNT]; 1714 Debug.getMemInfo(infos); 1715 logBuilder.append(" MemInfo: "); 1716 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1717 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1718 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1719 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1720 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1721 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1722 logBuilder.append(" ZRAM: "); 1723 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1724 logBuilder.append(" kB RAM, "); 1725 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1726 logBuilder.append(" kB swap total, "); 1727 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1728 logBuilder.append(" kB swap free\n"); 1729 } 1730 Slog.i(TAG, logBuilder.toString()); 1731 1732 StringBuilder dropBuilder = new StringBuilder(1024); 1733 /* 1734 StringWriter oomSw = new StringWriter(); 1735 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1736 StringWriter catSw = new StringWriter(); 1737 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1738 String[] emptyArgs = new String[] { }; 1739 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1740 oomPw.flush(); 1741 String oomString = oomSw.toString(); 1742 */ 1743 dropBuilder.append(stack); 1744 dropBuilder.append('\n'); 1745 dropBuilder.append('\n'); 1746 dropBuilder.append(logBuilder); 1747 dropBuilder.append('\n'); 1748 /* 1749 dropBuilder.append(oomString); 1750 dropBuilder.append('\n'); 1751 */ 1752 StringWriter catSw = new StringWriter(); 1753 synchronized (ActivityManagerService.this) { 1754 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1755 String[] emptyArgs = new String[] { }; 1756 catPw.println(); 1757 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1758 catPw.println(); 1759 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1760 false, false, null); 1761 catPw.println(); 1762 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1763 catPw.flush(); 1764 } 1765 dropBuilder.append(catSw.toString()); 1766 addErrorToDropBox("lowmem", null, "system_server", null, 1767 null, tag.toString(), dropBuilder.toString(), null, null); 1768 //Slog.i(TAG, "Sent to dropbox:"); 1769 //Slog.i(TAG, dropBuilder.toString()); 1770 synchronized (ActivityManagerService.this) { 1771 long now = SystemClock.uptimeMillis(); 1772 if (mLastMemUsageReportTime < now) { 1773 mLastMemUsageReportTime = now; 1774 } 1775 } 1776 } 1777 }; 1778 thread.start(); 1779 break; 1780 } 1781 case START_USER_SWITCH_MSG: { 1782 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1783 break; 1784 } 1785 case REPORT_USER_SWITCH_MSG: { 1786 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1787 break; 1788 } 1789 case CONTINUE_USER_SWITCH_MSG: { 1790 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1791 break; 1792 } 1793 case USER_SWITCH_TIMEOUT_MSG: { 1794 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1795 break; 1796 } 1797 case IMMERSIVE_MODE_LOCK_MSG: { 1798 final boolean nextState = (msg.arg1 != 0); 1799 if (mUpdateLock.isHeld() != nextState) { 1800 if (DEBUG_IMMERSIVE) { 1801 final ActivityRecord r = (ActivityRecord) msg.obj; 1802 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1803 } 1804 if (nextState) { 1805 mUpdateLock.acquire(); 1806 } else { 1807 mUpdateLock.release(); 1808 } 1809 } 1810 break; 1811 } 1812 case PERSIST_URI_GRANTS_MSG: { 1813 writeGrantedUriPermissions(); 1814 break; 1815 } 1816 case REQUEST_ALL_PSS_MSG: { 1817 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1818 break; 1819 } 1820 case START_PROFILES_MSG: { 1821 synchronized (ActivityManagerService.this) { 1822 startProfilesLocked(); 1823 } 1824 break; 1825 } 1826 case UPDATE_TIME: { 1827 synchronized (ActivityManagerService.this) { 1828 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1829 ProcessRecord r = mLruProcesses.get(i); 1830 if (r.thread != null) { 1831 try { 1832 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1833 } catch (RemoteException ex) { 1834 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1835 } 1836 } 1837 } 1838 } 1839 break; 1840 } 1841 case SYSTEM_USER_START_MSG: { 1842 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1843 Integer.toString(msg.arg1), msg.arg1); 1844 mSystemServiceManager.startUser(msg.arg1); 1845 break; 1846 } 1847 case SYSTEM_USER_CURRENT_MSG: { 1848 mBatteryStatsService.noteEvent( 1849 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1850 Integer.toString(msg.arg2), msg.arg2); 1851 mBatteryStatsService.noteEvent( 1852 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1853 Integer.toString(msg.arg1), msg.arg1); 1854 mSystemServiceManager.switchUser(msg.arg1); 1855 mLockToAppRequest.clearPrompt(); 1856 break; 1857 } 1858 case ENTER_ANIMATION_COMPLETE_MSG: { 1859 synchronized (ActivityManagerService.this) { 1860 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1861 if (r != null && r.app != null && r.app.thread != null) { 1862 try { 1863 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1864 } catch (RemoteException e) { 1865 } 1866 } 1867 } 1868 break; 1869 } 1870 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1871 enableScreenAfterBoot(); 1872 break; 1873 } 1874 } 1875 } 1876 }; 1877 1878 static final int COLLECT_PSS_BG_MSG = 1; 1879 1880 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1881 @Override 1882 public void handleMessage(Message msg) { 1883 switch (msg.what) { 1884 case COLLECT_PSS_BG_MSG: { 1885 long start = SystemClock.uptimeMillis(); 1886 MemInfoReader memInfo = null; 1887 synchronized (ActivityManagerService.this) { 1888 if (mFullPssPending) { 1889 mFullPssPending = false; 1890 memInfo = new MemInfoReader(); 1891 } 1892 } 1893 if (memInfo != null) { 1894 updateCpuStatsNow(); 1895 long nativeTotalPss = 0; 1896 synchronized (mProcessCpuThread) { 1897 final int N = mProcessCpuTracker.countStats(); 1898 for (int j=0; j<N; j++) { 1899 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1900 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1901 // This is definitely an application process; skip it. 1902 continue; 1903 } 1904 synchronized (mPidsSelfLocked) { 1905 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1906 // This is one of our own processes; skip it. 1907 continue; 1908 } 1909 } 1910 nativeTotalPss += Debug.getPss(st.pid, null); 1911 } 1912 } 1913 memInfo.readMemInfo(); 1914 synchronized (this) { 1915 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1916 + (SystemClock.uptimeMillis()-start) + "ms"); 1917 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1918 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1919 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1920 +memInfo.getSlabSizeKb(), 1921 nativeTotalPss); 1922 } 1923 } 1924 1925 int i=0, num=0; 1926 long[] tmp = new long[1]; 1927 do { 1928 ProcessRecord proc; 1929 int procState; 1930 int pid; 1931 synchronized (ActivityManagerService.this) { 1932 if (i >= mPendingPssProcesses.size()) { 1933 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1934 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1935 mPendingPssProcesses.clear(); 1936 return; 1937 } 1938 proc = mPendingPssProcesses.get(i); 1939 procState = proc.pssProcState; 1940 if (proc.thread != null && procState == proc.setProcState) { 1941 pid = proc.pid; 1942 } else { 1943 proc = null; 1944 pid = 0; 1945 } 1946 i++; 1947 } 1948 if (proc != null) { 1949 long pss = Debug.getPss(pid, tmp); 1950 synchronized (ActivityManagerService.this) { 1951 if (proc.thread != null && proc.setProcState == procState 1952 && proc.pid == pid) { 1953 num++; 1954 proc.lastPssTime = SystemClock.uptimeMillis(); 1955 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1956 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1957 + ": " + pss + " lastPss=" + proc.lastPss 1958 + " state=" + ProcessList.makeProcStateString(procState)); 1959 if (proc.initialIdlePss == 0) { 1960 proc.initialIdlePss = pss; 1961 } 1962 proc.lastPss = pss; 1963 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1964 proc.lastCachedPss = pss; 1965 } 1966 } 1967 } 1968 } 1969 } while (true); 1970 } 1971 } 1972 } 1973 }; 1974 1975 /** 1976 * Monitor for package changes and update our internal state. 1977 */ 1978 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1979 @Override 1980 public void onPackageRemoved(String packageName, int uid) { 1981 // Remove all tasks with activities in the specified package from the list of recent tasks 1982 synchronized (ActivityManagerService.this) { 1983 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1984 TaskRecord tr = mRecentTasks.get(i); 1985 ComponentName cn = tr.intent.getComponent(); 1986 if (cn != null && cn.getPackageName().equals(packageName)) { 1987 // If the package name matches, remove the task and kill the process 1988 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1989 } 1990 } 1991 } 1992 } 1993 1994 @Override 1995 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1996 onPackageModified(packageName); 1997 return true; 1998 } 1999 2000 @Override 2001 public void onPackageModified(String packageName) { 2002 final PackageManager pm = mContext.getPackageManager(); 2003 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2004 new ArrayList<Pair<Intent, Integer>>(); 2005 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2006 // Copy the list of recent tasks so that we don't hold onto the lock on 2007 // ActivityManagerService for long periods while checking if components exist. 2008 synchronized (ActivityManagerService.this) { 2009 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2010 TaskRecord tr = mRecentTasks.get(i); 2011 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2012 } 2013 } 2014 // Check the recent tasks and filter out all tasks with components that no longer exist. 2015 Intent tmpI = new Intent(); 2016 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2017 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2018 ComponentName cn = p.first.getComponent(); 2019 if (cn != null && cn.getPackageName().equals(packageName)) { 2020 try { 2021 // Add the task to the list to remove if the component no longer exists 2022 tmpI.setComponent(cn); 2023 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2024 tasksToRemove.add(p.second); 2025 } 2026 } catch (Exception e) {} 2027 } 2028 } 2029 // Prune all the tasks with removed components from the list of recent tasks 2030 synchronized (ActivityManagerService.this) { 2031 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2032 // Remove the task but don't kill the process (since other components in that 2033 // package may still be running and in the background) 2034 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2035 } 2036 } 2037 } 2038 2039 @Override 2040 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2041 // Force stop the specified packages 2042 if (packages != null) { 2043 for (String pkg : packages) { 2044 synchronized (ActivityManagerService.this) { 2045 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2046 "finished booting")) { 2047 return true; 2048 } 2049 } 2050 } 2051 } 2052 return false; 2053 } 2054 }; 2055 2056 public void setSystemProcess() { 2057 try { 2058 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2059 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2060 ServiceManager.addService("meminfo", new MemBinder(this)); 2061 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2062 ServiceManager.addService("dbinfo", new DbBinder(this)); 2063 if (MONITOR_CPU_USAGE) { 2064 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2065 } 2066 ServiceManager.addService("permission", new PermissionController(this)); 2067 2068 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2069 "android", STOCK_PM_FLAGS); 2070 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2071 2072 synchronized (this) { 2073 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2074 app.persistent = true; 2075 app.pid = MY_PID; 2076 app.maxAdj = ProcessList.SYSTEM_ADJ; 2077 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2078 mProcessNames.put(app.processName, app.uid, app); 2079 synchronized (mPidsSelfLocked) { 2080 mPidsSelfLocked.put(app.pid, app); 2081 } 2082 updateLruProcessLocked(app, false, null); 2083 updateOomAdjLocked(); 2084 } 2085 } catch (PackageManager.NameNotFoundException e) { 2086 throw new RuntimeException( 2087 "Unable to find android system package", e); 2088 } 2089 } 2090 2091 public void setWindowManager(WindowManagerService wm) { 2092 mWindowManager = wm; 2093 mStackSupervisor.setWindowManager(wm); 2094 } 2095 2096 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2097 mUsageStatsService = usageStatsManager; 2098 } 2099 2100 public void startObservingNativeCrashes() { 2101 final NativeCrashListener ncl = new NativeCrashListener(this); 2102 ncl.start(); 2103 } 2104 2105 public IAppOpsService getAppOpsService() { 2106 return mAppOpsService; 2107 } 2108 2109 static class MemBinder extends Binder { 2110 ActivityManagerService mActivityManagerService; 2111 MemBinder(ActivityManagerService activityManagerService) { 2112 mActivityManagerService = activityManagerService; 2113 } 2114 2115 @Override 2116 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2117 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2118 != PackageManager.PERMISSION_GRANTED) { 2119 pw.println("Permission Denial: can't dump meminfo from from pid=" 2120 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2121 + " without permission " + android.Manifest.permission.DUMP); 2122 return; 2123 } 2124 2125 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2126 } 2127 } 2128 2129 static class GraphicsBinder extends Binder { 2130 ActivityManagerService mActivityManagerService; 2131 GraphicsBinder(ActivityManagerService activityManagerService) { 2132 mActivityManagerService = activityManagerService; 2133 } 2134 2135 @Override 2136 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2137 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2138 != PackageManager.PERMISSION_GRANTED) { 2139 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2140 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2141 + " without permission " + android.Manifest.permission.DUMP); 2142 return; 2143 } 2144 2145 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2146 } 2147 } 2148 2149 static class DbBinder extends Binder { 2150 ActivityManagerService mActivityManagerService; 2151 DbBinder(ActivityManagerService activityManagerService) { 2152 mActivityManagerService = activityManagerService; 2153 } 2154 2155 @Override 2156 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2157 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2158 != PackageManager.PERMISSION_GRANTED) { 2159 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2160 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2161 + " without permission " + android.Manifest.permission.DUMP); 2162 return; 2163 } 2164 2165 mActivityManagerService.dumpDbInfo(fd, pw, args); 2166 } 2167 } 2168 2169 static class CpuBinder extends Binder { 2170 ActivityManagerService mActivityManagerService; 2171 CpuBinder(ActivityManagerService activityManagerService) { 2172 mActivityManagerService = activityManagerService; 2173 } 2174 2175 @Override 2176 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2177 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2178 != PackageManager.PERMISSION_GRANTED) { 2179 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2180 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2181 + " without permission " + android.Manifest.permission.DUMP); 2182 return; 2183 } 2184 2185 synchronized (mActivityManagerService.mProcessCpuThread) { 2186 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2187 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2188 SystemClock.uptimeMillis())); 2189 } 2190 } 2191 } 2192 2193 public static final class Lifecycle extends SystemService { 2194 private final ActivityManagerService mService; 2195 2196 public Lifecycle(Context context) { 2197 super(context); 2198 mService = new ActivityManagerService(context); 2199 } 2200 2201 @Override 2202 public void onStart() { 2203 mService.start(); 2204 } 2205 2206 public ActivityManagerService getService() { 2207 return mService; 2208 } 2209 } 2210 2211 // Note: This method is invoked on the main thread but may need to attach various 2212 // handlers to other threads. So take care to be explicit about the looper. 2213 public ActivityManagerService(Context systemContext) { 2214 mContext = systemContext; 2215 mFactoryTest = FactoryTest.getMode(); 2216 mSystemThread = ActivityThread.currentActivityThread(); 2217 2218 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2219 2220 mHandlerThread = new ServiceThread(TAG, 2221 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2222 mHandlerThread.start(); 2223 mHandler = new MainHandler(mHandlerThread.getLooper()); 2224 2225 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2226 "foreground", BROADCAST_FG_TIMEOUT, false); 2227 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2228 "background", BROADCAST_BG_TIMEOUT, true); 2229 mBroadcastQueues[0] = mFgBroadcastQueue; 2230 mBroadcastQueues[1] = mBgBroadcastQueue; 2231 2232 mServices = new ActiveServices(this); 2233 mProviderMap = new ProviderMap(this); 2234 2235 // TODO: Move creation of battery stats service outside of activity manager service. 2236 File dataDir = Environment.getDataDirectory(); 2237 File systemDir = new File(dataDir, "system"); 2238 systemDir.mkdirs(); 2239 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2240 mBatteryStatsService.getActiveStatistics().readLocked(); 2241 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2242 mOnBattery = DEBUG_POWER ? true 2243 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2244 mBatteryStatsService.getActiveStatistics().setCallback(this); 2245 2246 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2247 2248 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2249 2250 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2251 2252 // User 0 is the first and only user that runs at boot. 2253 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2254 mUserLru.add(Integer.valueOf(0)); 2255 updateStartedUserArrayLocked(); 2256 2257 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2258 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2259 2260 mConfiguration.setToDefaults(); 2261 mConfiguration.setLocale(Locale.getDefault()); 2262 2263 mConfigurationSeq = mConfiguration.seq = 1; 2264 mProcessCpuTracker.init(); 2265 2266 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2267 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2268 mStackSupervisor = new ActivityStackSupervisor(this); 2269 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2270 2271 mProcessCpuThread = new Thread("CpuTracker") { 2272 @Override 2273 public void run() { 2274 while (true) { 2275 try { 2276 try { 2277 synchronized(this) { 2278 final long now = SystemClock.uptimeMillis(); 2279 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2280 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2281 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2282 // + ", write delay=" + nextWriteDelay); 2283 if (nextWriteDelay < nextCpuDelay) { 2284 nextCpuDelay = nextWriteDelay; 2285 } 2286 if (nextCpuDelay > 0) { 2287 mProcessCpuMutexFree.set(true); 2288 this.wait(nextCpuDelay); 2289 } 2290 } 2291 } catch (InterruptedException e) { 2292 } 2293 updateCpuStatsNow(); 2294 } catch (Exception e) { 2295 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2296 } 2297 } 2298 } 2299 }; 2300 2301 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2302 2303 Watchdog.getInstance().addMonitor(this); 2304 Watchdog.getInstance().addThread(mHandler); 2305 } 2306 2307 public void setSystemServiceManager(SystemServiceManager mgr) { 2308 mSystemServiceManager = mgr; 2309 } 2310 2311 private void start() { 2312 Process.removeAllProcessGroups(); 2313 mProcessCpuThread.start(); 2314 2315 mBatteryStatsService.publish(mContext); 2316 mAppOpsService.publish(mContext); 2317 Slog.d("AppOps", "AppOpsService published"); 2318 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2319 } 2320 2321 public void initPowerManagement() { 2322 mStackSupervisor.initPowerManagement(); 2323 mBatteryStatsService.initPowerManagement(); 2324 } 2325 2326 @Override 2327 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2328 throws RemoteException { 2329 if (code == SYSPROPS_TRANSACTION) { 2330 // We need to tell all apps about the system property change. 2331 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2332 synchronized(this) { 2333 final int NP = mProcessNames.getMap().size(); 2334 for (int ip=0; ip<NP; ip++) { 2335 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2336 final int NA = apps.size(); 2337 for (int ia=0; ia<NA; ia++) { 2338 ProcessRecord app = apps.valueAt(ia); 2339 if (app.thread != null) { 2340 procs.add(app.thread.asBinder()); 2341 } 2342 } 2343 } 2344 } 2345 2346 int N = procs.size(); 2347 for (int i=0; i<N; i++) { 2348 Parcel data2 = Parcel.obtain(); 2349 try { 2350 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2351 } catch (RemoteException e) { 2352 } 2353 data2.recycle(); 2354 } 2355 } 2356 try { 2357 return super.onTransact(code, data, reply, flags); 2358 } catch (RuntimeException e) { 2359 // The activity manager only throws security exceptions, so let's 2360 // log all others. 2361 if (!(e instanceof SecurityException)) { 2362 Slog.wtf(TAG, "Activity Manager Crash", e); 2363 } 2364 throw e; 2365 } 2366 } 2367 2368 void updateCpuStats() { 2369 final long now = SystemClock.uptimeMillis(); 2370 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2371 return; 2372 } 2373 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2374 synchronized (mProcessCpuThread) { 2375 mProcessCpuThread.notify(); 2376 } 2377 } 2378 } 2379 2380 void updateCpuStatsNow() { 2381 synchronized (mProcessCpuThread) { 2382 mProcessCpuMutexFree.set(false); 2383 final long now = SystemClock.uptimeMillis(); 2384 boolean haveNewCpuStats = false; 2385 2386 if (MONITOR_CPU_USAGE && 2387 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2388 mLastCpuTime.set(now); 2389 haveNewCpuStats = true; 2390 mProcessCpuTracker.update(); 2391 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2392 //Slog.i(TAG, "Total CPU usage: " 2393 // + mProcessCpu.getTotalCpuPercent() + "%"); 2394 2395 // Slog the cpu usage if the property is set. 2396 if ("true".equals(SystemProperties.get("events.cpu"))) { 2397 int user = mProcessCpuTracker.getLastUserTime(); 2398 int system = mProcessCpuTracker.getLastSystemTime(); 2399 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2400 int irq = mProcessCpuTracker.getLastIrqTime(); 2401 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2402 int idle = mProcessCpuTracker.getLastIdleTime(); 2403 2404 int total = user + system + iowait + irq + softIrq + idle; 2405 if (total == 0) total = 1; 2406 2407 EventLog.writeEvent(EventLogTags.CPU, 2408 ((user+system+iowait+irq+softIrq) * 100) / total, 2409 (user * 100) / total, 2410 (system * 100) / total, 2411 (iowait * 100) / total, 2412 (irq * 100) / total, 2413 (softIrq * 100) / total); 2414 } 2415 } 2416 2417 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2418 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2419 synchronized(bstats) { 2420 synchronized(mPidsSelfLocked) { 2421 if (haveNewCpuStats) { 2422 if (mOnBattery) { 2423 int perc = bstats.startAddingCpuLocked(); 2424 int totalUTime = 0; 2425 int totalSTime = 0; 2426 final int N = mProcessCpuTracker.countStats(); 2427 for (int i=0; i<N; i++) { 2428 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2429 if (!st.working) { 2430 continue; 2431 } 2432 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2433 int otherUTime = (st.rel_utime*perc)/100; 2434 int otherSTime = (st.rel_stime*perc)/100; 2435 totalUTime += otherUTime; 2436 totalSTime += otherSTime; 2437 if (pr != null) { 2438 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2439 if (ps == null || !ps.isActive()) { 2440 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2441 pr.info.uid, pr.processName); 2442 } 2443 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2444 st.rel_stime-otherSTime); 2445 ps.addSpeedStepTimes(cpuSpeedTimes); 2446 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2447 } else { 2448 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2449 if (ps == null || !ps.isActive()) { 2450 st.batteryStats = ps = bstats.getProcessStatsLocked( 2451 bstats.mapUid(st.uid), st.name); 2452 } 2453 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2454 st.rel_stime-otherSTime); 2455 ps.addSpeedStepTimes(cpuSpeedTimes); 2456 } 2457 } 2458 bstats.finishAddingCpuLocked(perc, totalUTime, 2459 totalSTime, cpuSpeedTimes); 2460 } 2461 } 2462 } 2463 2464 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2465 mLastWriteTime = now; 2466 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2467 } 2468 } 2469 } 2470 } 2471 2472 @Override 2473 public void batteryNeedsCpuUpdate() { 2474 updateCpuStatsNow(); 2475 } 2476 2477 @Override 2478 public void batteryPowerChanged(boolean onBattery) { 2479 // When plugging in, update the CPU stats first before changing 2480 // the plug state. 2481 updateCpuStatsNow(); 2482 synchronized (this) { 2483 synchronized(mPidsSelfLocked) { 2484 mOnBattery = DEBUG_POWER ? true : onBattery; 2485 } 2486 } 2487 } 2488 2489 /** 2490 * Initialize the application bind args. These are passed to each 2491 * process when the bindApplication() IPC is sent to the process. They're 2492 * lazily setup to make sure the services are running when they're asked for. 2493 */ 2494 private HashMap<String, IBinder> getCommonServicesLocked() { 2495 if (mAppBindArgs == null) { 2496 mAppBindArgs = new HashMap<String, IBinder>(); 2497 2498 // Setup the application init args 2499 mAppBindArgs.put("package", ServiceManager.getService("package")); 2500 mAppBindArgs.put("window", ServiceManager.getService("window")); 2501 mAppBindArgs.put(Context.ALARM_SERVICE, 2502 ServiceManager.getService(Context.ALARM_SERVICE)); 2503 } 2504 return mAppBindArgs; 2505 } 2506 2507 final void setFocusedActivityLocked(ActivityRecord r) { 2508 if (mFocusedActivity != r) { 2509 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2510 mFocusedActivity = r; 2511 if (r.task != null && r.task.voiceInteractor != null) { 2512 startRunningVoiceLocked(); 2513 } else { 2514 finishRunningVoiceLocked(); 2515 } 2516 mStackSupervisor.setFocusedStack(r); 2517 if (r != null) { 2518 mWindowManager.setFocusedApp(r.appToken, true); 2519 } 2520 applyUpdateLockStateLocked(r); 2521 } 2522 } 2523 2524 final void clearFocusedActivity(ActivityRecord r) { 2525 if (mFocusedActivity == r) { 2526 mFocusedActivity = null; 2527 } 2528 } 2529 2530 @Override 2531 public void setFocusedStack(int stackId) { 2532 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2533 synchronized (ActivityManagerService.this) { 2534 ActivityStack stack = mStackSupervisor.getStack(stackId); 2535 if (stack != null) { 2536 ActivityRecord r = stack.topRunningActivityLocked(null); 2537 if (r != null) { 2538 setFocusedActivityLocked(r); 2539 } 2540 } 2541 } 2542 } 2543 2544 @Override 2545 public void notifyActivityDrawn(IBinder token) { 2546 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2547 synchronized (this) { 2548 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2549 if (r != null) { 2550 r.task.stack.notifyActivityDrawnLocked(r); 2551 } 2552 } 2553 } 2554 2555 final void applyUpdateLockStateLocked(ActivityRecord r) { 2556 // Modifications to the UpdateLock state are done on our handler, outside 2557 // the activity manager's locks. The new state is determined based on the 2558 // state *now* of the relevant activity record. The object is passed to 2559 // the handler solely for logging detail, not to be consulted/modified. 2560 final boolean nextState = r != null && r.immersive; 2561 mHandler.sendMessage( 2562 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2563 } 2564 2565 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2566 Message msg = Message.obtain(); 2567 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2568 msg.obj = r.task.askedCompatMode ? null : r; 2569 mHandler.sendMessage(msg); 2570 } 2571 2572 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2573 String what, Object obj, ProcessRecord srcApp) { 2574 app.lastActivityTime = now; 2575 2576 if (app.activities.size() > 0) { 2577 // Don't want to touch dependent processes that are hosting activities. 2578 return index; 2579 } 2580 2581 int lrui = mLruProcesses.lastIndexOf(app); 2582 if (lrui < 0) { 2583 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2584 + what + " " + obj + " from " + srcApp); 2585 return index; 2586 } 2587 2588 if (lrui >= index) { 2589 // Don't want to cause this to move dependent processes *back* in the 2590 // list as if they were less frequently used. 2591 return index; 2592 } 2593 2594 if (lrui >= mLruProcessActivityStart) { 2595 // Don't want to touch dependent processes that are hosting activities. 2596 return index; 2597 } 2598 2599 mLruProcesses.remove(lrui); 2600 if (index > 0) { 2601 index--; 2602 } 2603 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2604 + " in LRU list: " + app); 2605 mLruProcesses.add(index, app); 2606 return index; 2607 } 2608 2609 final void removeLruProcessLocked(ProcessRecord app) { 2610 int lrui = mLruProcesses.lastIndexOf(app); 2611 if (lrui >= 0) { 2612 if (lrui <= mLruProcessActivityStart) { 2613 mLruProcessActivityStart--; 2614 } 2615 if (lrui <= mLruProcessServiceStart) { 2616 mLruProcessServiceStart--; 2617 } 2618 mLruProcesses.remove(lrui); 2619 } 2620 } 2621 2622 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2623 ProcessRecord client) { 2624 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2625 || app.treatLikeActivity; 2626 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2627 if (!activityChange && hasActivity) { 2628 // The process has activities, so we are only allowing activity-based adjustments 2629 // to move it. It should be kept in the front of the list with other 2630 // processes that have activities, and we don't want those to change their 2631 // order except due to activity operations. 2632 return; 2633 } 2634 2635 mLruSeq++; 2636 final long now = SystemClock.uptimeMillis(); 2637 app.lastActivityTime = now; 2638 2639 // First a quick reject: if the app is already at the position we will 2640 // put it, then there is nothing to do. 2641 if (hasActivity) { 2642 final int N = mLruProcesses.size(); 2643 if (N > 0 && mLruProcesses.get(N-1) == app) { 2644 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2645 return; 2646 } 2647 } else { 2648 if (mLruProcessServiceStart > 0 2649 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2650 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2651 return; 2652 } 2653 } 2654 2655 int lrui = mLruProcesses.lastIndexOf(app); 2656 2657 if (app.persistent && lrui >= 0) { 2658 // We don't care about the position of persistent processes, as long as 2659 // they are in the list. 2660 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2661 return; 2662 } 2663 2664 /* In progress: compute new position first, so we can avoid doing work 2665 if the process is not actually going to move. Not yet working. 2666 int addIndex; 2667 int nextIndex; 2668 boolean inActivity = false, inService = false; 2669 if (hasActivity) { 2670 // Process has activities, put it at the very tipsy-top. 2671 addIndex = mLruProcesses.size(); 2672 nextIndex = mLruProcessServiceStart; 2673 inActivity = true; 2674 } else if (hasService) { 2675 // Process has services, put it at the top of the service list. 2676 addIndex = mLruProcessActivityStart; 2677 nextIndex = mLruProcessServiceStart; 2678 inActivity = true; 2679 inService = true; 2680 } else { 2681 // Process not otherwise of interest, it goes to the top of the non-service area. 2682 addIndex = mLruProcessServiceStart; 2683 if (client != null) { 2684 int clientIndex = mLruProcesses.lastIndexOf(client); 2685 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2686 + app); 2687 if (clientIndex >= 0 && addIndex > clientIndex) { 2688 addIndex = clientIndex; 2689 } 2690 } 2691 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2692 } 2693 2694 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2695 + mLruProcessActivityStart + "): " + app); 2696 */ 2697 2698 if (lrui >= 0) { 2699 if (lrui < mLruProcessActivityStart) { 2700 mLruProcessActivityStart--; 2701 } 2702 if (lrui < mLruProcessServiceStart) { 2703 mLruProcessServiceStart--; 2704 } 2705 /* 2706 if (addIndex > lrui) { 2707 addIndex--; 2708 } 2709 if (nextIndex > lrui) { 2710 nextIndex--; 2711 } 2712 */ 2713 mLruProcesses.remove(lrui); 2714 } 2715 2716 /* 2717 mLruProcesses.add(addIndex, app); 2718 if (inActivity) { 2719 mLruProcessActivityStart++; 2720 } 2721 if (inService) { 2722 mLruProcessActivityStart++; 2723 } 2724 */ 2725 2726 int nextIndex; 2727 if (hasActivity) { 2728 final int N = mLruProcesses.size(); 2729 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2730 // Process doesn't have activities, but has clients with 2731 // activities... move it up, but one below the top (the top 2732 // should always have a real activity). 2733 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2734 mLruProcesses.add(N-1, app); 2735 // To keep it from spamming the LRU list (by making a bunch of clients), 2736 // we will push down any other entries owned by the app. 2737 final int uid = app.info.uid; 2738 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2739 ProcessRecord subProc = mLruProcesses.get(i); 2740 if (subProc.info.uid == uid) { 2741 // We want to push this one down the list. If the process after 2742 // it is for the same uid, however, don't do so, because we don't 2743 // want them internally to be re-ordered. 2744 if (mLruProcesses.get(i-1).info.uid != uid) { 2745 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2746 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2747 ProcessRecord tmp = mLruProcesses.get(i); 2748 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2749 mLruProcesses.set(i-1, tmp); 2750 i--; 2751 } 2752 } else { 2753 // A gap, we can stop here. 2754 break; 2755 } 2756 } 2757 } else { 2758 // Process has activities, put it at the very tipsy-top. 2759 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2760 mLruProcesses.add(app); 2761 } 2762 nextIndex = mLruProcessServiceStart; 2763 } else if (hasService) { 2764 // Process has services, put it at the top of the service list. 2765 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2766 mLruProcesses.add(mLruProcessActivityStart, app); 2767 nextIndex = mLruProcessServiceStart; 2768 mLruProcessActivityStart++; 2769 } else { 2770 // Process not otherwise of interest, it goes to the top of the non-service area. 2771 int index = mLruProcessServiceStart; 2772 if (client != null) { 2773 // If there is a client, don't allow the process to be moved up higher 2774 // in the list than that client. 2775 int clientIndex = mLruProcesses.lastIndexOf(client); 2776 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2777 + " when updating " + app); 2778 if (clientIndex <= lrui) { 2779 // Don't allow the client index restriction to push it down farther in the 2780 // list than it already is. 2781 clientIndex = lrui; 2782 } 2783 if (clientIndex >= 0 && index > clientIndex) { 2784 index = clientIndex; 2785 } 2786 } 2787 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2788 mLruProcesses.add(index, app); 2789 nextIndex = index-1; 2790 mLruProcessActivityStart++; 2791 mLruProcessServiceStart++; 2792 } 2793 2794 // If the app is currently using a content provider or service, 2795 // bump those processes as well. 2796 for (int j=app.connections.size()-1; j>=0; j--) { 2797 ConnectionRecord cr = app.connections.valueAt(j); 2798 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2799 && cr.binding.service.app != null 2800 && cr.binding.service.app.lruSeq != mLruSeq 2801 && !cr.binding.service.app.persistent) { 2802 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2803 "service connection", cr, app); 2804 } 2805 } 2806 for (int j=app.conProviders.size()-1; j>=0; j--) { 2807 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2808 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2809 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2810 "provider reference", cpr, app); 2811 } 2812 } 2813 } 2814 2815 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2816 if (uid == Process.SYSTEM_UID) { 2817 // The system gets to run in any process. If there are multiple 2818 // processes with the same uid, just pick the first (this 2819 // should never happen). 2820 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2821 if (procs == null) return null; 2822 final int N = procs.size(); 2823 for (int i = 0; i < N; i++) { 2824 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2825 } 2826 } 2827 ProcessRecord proc = mProcessNames.get(processName, uid); 2828 if (false && proc != null && !keepIfLarge 2829 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2830 && proc.lastCachedPss >= 4000) { 2831 // Turn this condition on to cause killing to happen regularly, for testing. 2832 if (proc.baseProcessTracker != null) { 2833 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2834 } 2835 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2836 } else if (proc != null && !keepIfLarge 2837 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2838 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2839 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2840 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2841 if (proc.baseProcessTracker != null) { 2842 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2843 } 2844 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2845 } 2846 } 2847 return proc; 2848 } 2849 2850 void ensurePackageDexOpt(String packageName) { 2851 IPackageManager pm = AppGlobals.getPackageManager(); 2852 try { 2853 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2854 mDidDexOpt = true; 2855 } 2856 } catch (RemoteException e) { 2857 } 2858 } 2859 2860 boolean isNextTransitionForward() { 2861 int transit = mWindowManager.getPendingAppTransition(); 2862 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2863 || transit == AppTransition.TRANSIT_TASK_OPEN 2864 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2865 } 2866 2867 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2868 String processName, String abiOverride, int uid, Runnable crashHandler) { 2869 synchronized(this) { 2870 ApplicationInfo info = new ApplicationInfo(); 2871 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2872 // For isolated processes, the former contains the parent's uid and the latter the 2873 // actual uid of the isolated process. 2874 // In the special case introduced by this method (which is, starting an isolated 2875 // process directly from the SystemServer without an actual parent app process) the 2876 // closest thing to a parent's uid is SYSTEM_UID. 2877 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2878 // the |isolated| logic in the ProcessRecord constructor. 2879 info.uid = Process.SYSTEM_UID; 2880 info.processName = processName; 2881 info.className = entryPoint; 2882 info.packageName = "android"; 2883 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2884 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2885 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2886 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2887 crashHandler); 2888 return proc != null ? proc.pid : 0; 2889 } 2890 } 2891 2892 final ProcessRecord startProcessLocked(String processName, 2893 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2894 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2895 boolean isolated, boolean keepIfLarge) { 2896 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2897 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2898 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2899 null /* crashHandler */); 2900 } 2901 2902 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2903 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2904 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2905 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2906 long startTime = SystemClock.elapsedRealtime(); 2907 ProcessRecord app; 2908 if (!isolated) { 2909 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2910 checkTime(startTime, "startProcess: after getProcessRecord"); 2911 } else { 2912 // If this is an isolated process, it can't re-use an existing process. 2913 app = null; 2914 } 2915 // We don't have to do anything more if: 2916 // (1) There is an existing application record; and 2917 // (2) The caller doesn't think it is dead, OR there is no thread 2918 // object attached to it so we know it couldn't have crashed; and 2919 // (3) There is a pid assigned to it, so it is either starting or 2920 // already running. 2921 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2922 + " app=" + app + " knownToBeDead=" + knownToBeDead 2923 + " thread=" + (app != null ? app.thread : null) 2924 + " pid=" + (app != null ? app.pid : -1)); 2925 if (app != null && app.pid > 0) { 2926 if (!knownToBeDead || app.thread == null) { 2927 // We already have the app running, or are waiting for it to 2928 // come up (we have a pid but not yet its thread), so keep it. 2929 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2930 // If this is a new package in the process, add the package to the list 2931 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2932 checkTime(startTime, "startProcess: done, added package to proc"); 2933 return app; 2934 } 2935 2936 // An application record is attached to a previous process, 2937 // clean it up now. 2938 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2939 checkTime(startTime, "startProcess: bad proc running, killing"); 2940 Process.killProcessGroup(app.info.uid, app.pid); 2941 handleAppDiedLocked(app, true, true); 2942 checkTime(startTime, "startProcess: done killing old proc"); 2943 } 2944 2945 String hostingNameStr = hostingName != null 2946 ? hostingName.flattenToShortString() : null; 2947 2948 if (!isolated) { 2949 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2950 // If we are in the background, then check to see if this process 2951 // is bad. If so, we will just silently fail. 2952 if (mBadProcesses.get(info.processName, info.uid) != null) { 2953 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2954 + "/" + info.processName); 2955 return null; 2956 } 2957 } else { 2958 // When the user is explicitly starting a process, then clear its 2959 // crash count so that we won't make it bad until they see at 2960 // least one crash dialog again, and make the process good again 2961 // if it had been bad. 2962 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2963 + "/" + info.processName); 2964 mProcessCrashTimes.remove(info.processName, info.uid); 2965 if (mBadProcesses.get(info.processName, info.uid) != null) { 2966 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2967 UserHandle.getUserId(info.uid), info.uid, 2968 info.processName); 2969 mBadProcesses.remove(info.processName, info.uid); 2970 if (app != null) { 2971 app.bad = false; 2972 } 2973 } 2974 } 2975 } 2976 2977 if (app == null) { 2978 checkTime(startTime, "startProcess: creating new process record"); 2979 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2980 app.crashHandler = crashHandler; 2981 if (app == null) { 2982 Slog.w(TAG, "Failed making new process record for " 2983 + processName + "/" + info.uid + " isolated=" + isolated); 2984 return null; 2985 } 2986 mProcessNames.put(processName, app.uid, app); 2987 if (isolated) { 2988 mIsolatedProcesses.put(app.uid, app); 2989 } 2990 checkTime(startTime, "startProcess: done creating new process record"); 2991 } else { 2992 // If this is a new package in the process, add the package to the list 2993 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2994 checkTime(startTime, "startProcess: added package to existing proc"); 2995 } 2996 2997 // If the system is not ready yet, then hold off on starting this 2998 // process until it is. 2999 if (!mProcessesReady 3000 && !isAllowedWhileBooting(info) 3001 && !allowWhileBooting) { 3002 if (!mProcessesOnHold.contains(app)) { 3003 mProcessesOnHold.add(app); 3004 } 3005 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3006 checkTime(startTime, "startProcess: returning with proc on hold"); 3007 return app; 3008 } 3009 3010 checkTime(startTime, "startProcess: stepping in to startProcess"); 3011 startProcessLocked( 3012 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3013 checkTime(startTime, "startProcess: done starting proc!"); 3014 return (app.pid != 0) ? app : null; 3015 } 3016 3017 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3018 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3019 } 3020 3021 private final void startProcessLocked(ProcessRecord app, 3022 String hostingType, String hostingNameStr) { 3023 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3024 null /* entryPoint */, null /* entryPointArgs */); 3025 } 3026 3027 private final void startProcessLocked(ProcessRecord app, String hostingType, 3028 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3029 long startTime = SystemClock.elapsedRealtime(); 3030 if (app.pid > 0 && app.pid != MY_PID) { 3031 checkTime(startTime, "startProcess: removing from pids map"); 3032 synchronized (mPidsSelfLocked) { 3033 mPidsSelfLocked.remove(app.pid); 3034 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3035 } 3036 checkTime(startTime, "startProcess: done removing from pids map"); 3037 app.setPid(0); 3038 } 3039 3040 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3041 "startProcessLocked removing on hold: " + app); 3042 mProcessesOnHold.remove(app); 3043 3044 checkTime(startTime, "startProcess: starting to update cpu stats"); 3045 updateCpuStats(); 3046 checkTime(startTime, "startProcess: done updating cpu stats"); 3047 3048 try { 3049 int uid = app.uid; 3050 3051 int[] gids = null; 3052 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3053 if (!app.isolated) { 3054 int[] permGids = null; 3055 try { 3056 checkTime(startTime, "startProcess: getting gids from package manager"); 3057 final PackageManager pm = mContext.getPackageManager(); 3058 permGids = pm.getPackageGids(app.info.packageName); 3059 3060 if (Environment.isExternalStorageEmulated()) { 3061 checkTime(startTime, "startProcess: checking external storage perm"); 3062 if (pm.checkPermission( 3063 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3064 app.info.packageName) == PERMISSION_GRANTED) { 3065 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3066 } else { 3067 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3068 } 3069 } 3070 } catch (PackageManager.NameNotFoundException e) { 3071 Slog.w(TAG, "Unable to retrieve gids", e); 3072 } 3073 3074 /* 3075 * Add shared application and profile GIDs so applications can share some 3076 * resources like shared libraries and access user-wide resources 3077 */ 3078 if (permGids == null) { 3079 gids = new int[2]; 3080 } else { 3081 gids = new int[permGids.length + 2]; 3082 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3083 } 3084 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3085 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3086 } 3087 checkTime(startTime, "startProcess: building args"); 3088 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3089 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3090 && mTopComponent != null 3091 && app.processName.equals(mTopComponent.getPackageName())) { 3092 uid = 0; 3093 } 3094 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3095 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3096 uid = 0; 3097 } 3098 } 3099 int debugFlags = 0; 3100 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3101 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3102 // Also turn on CheckJNI for debuggable apps. It's quite 3103 // awkward to turn on otherwise. 3104 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3105 } 3106 // Run the app in safe mode if its manifest requests so or the 3107 // system is booted in safe mode. 3108 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3109 mSafeMode == true) { 3110 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3111 } 3112 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3113 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3114 } 3115 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3116 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3117 } 3118 if ("1".equals(SystemProperties.get("debug.assert"))) { 3119 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3120 } 3121 3122 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3123 if (requiredAbi == null) { 3124 requiredAbi = Build.SUPPORTED_ABIS[0]; 3125 } 3126 3127 // Start the process. It will either succeed and return a result containing 3128 // the PID of the new process, or else throw a RuntimeException. 3129 boolean isActivityProcess = (entryPoint == null); 3130 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3131 checkTime(startTime, "startProcess: asking zygote to start proc"); 3132 Process.ProcessStartResult startResult = Process.start(entryPoint, 3133 app.processName, uid, uid, gids, debugFlags, mountExternal, 3134 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3135 checkTime(startTime, "startProcess: returned from zygote!"); 3136 3137 if (app.isolated) { 3138 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3139 } 3140 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3141 checkTime(startTime, "startProcess: done updating battery stats"); 3142 3143 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3144 UserHandle.getUserId(uid), startResult.pid, uid, 3145 app.processName, hostingType, 3146 hostingNameStr != null ? hostingNameStr : ""); 3147 3148 if (app.persistent) { 3149 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3150 } 3151 3152 checkTime(startTime, "startProcess: building log message"); 3153 StringBuilder buf = mStringBuilder; 3154 buf.setLength(0); 3155 buf.append("Start proc "); 3156 buf.append(app.processName); 3157 if (!isActivityProcess) { 3158 buf.append(" ["); 3159 buf.append(entryPoint); 3160 buf.append("]"); 3161 } 3162 buf.append(" for "); 3163 buf.append(hostingType); 3164 if (hostingNameStr != null) { 3165 buf.append(" "); 3166 buf.append(hostingNameStr); 3167 } 3168 buf.append(": pid="); 3169 buf.append(startResult.pid); 3170 buf.append(" uid="); 3171 buf.append(uid); 3172 buf.append(" gids={"); 3173 if (gids != null) { 3174 for (int gi=0; gi<gids.length; gi++) { 3175 if (gi != 0) buf.append(", "); 3176 buf.append(gids[gi]); 3177 3178 } 3179 } 3180 buf.append("}"); 3181 if (requiredAbi != null) { 3182 buf.append(" abi="); 3183 buf.append(requiredAbi); 3184 } 3185 Slog.i(TAG, buf.toString()); 3186 app.setPid(startResult.pid); 3187 app.usingWrapper = startResult.usingWrapper; 3188 app.removed = false; 3189 app.killedByAm = false; 3190 checkTime(startTime, "startProcess: starting to update pids map"); 3191 synchronized (mPidsSelfLocked) { 3192 this.mPidsSelfLocked.put(startResult.pid, app); 3193 if (isActivityProcess) { 3194 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3195 msg.obj = app; 3196 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3197 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3198 } 3199 } 3200 checkTime(startTime, "startProcess: done updating pids map"); 3201 } catch (RuntimeException e) { 3202 // XXX do better error recovery. 3203 app.setPid(0); 3204 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3205 if (app.isolated) { 3206 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3207 } 3208 Slog.e(TAG, "Failure starting process " + app.processName, e); 3209 } 3210 } 3211 3212 void updateUsageStats(ActivityRecord component, boolean resumed) { 3213 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3214 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3215 if (resumed) { 3216 if (mUsageStatsService != null) { 3217 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3218 System.currentTimeMillis(), 3219 UsageEvents.Event.MOVE_TO_FOREGROUND); 3220 } 3221 synchronized (stats) { 3222 stats.noteActivityResumedLocked(component.app.uid); 3223 } 3224 } else { 3225 if (mUsageStatsService != null) { 3226 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3227 System.currentTimeMillis(), 3228 UsageEvents.Event.MOVE_TO_BACKGROUND); 3229 } 3230 synchronized (stats) { 3231 stats.noteActivityPausedLocked(component.app.uid); 3232 } 3233 } 3234 } 3235 3236 Intent getHomeIntent() { 3237 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3238 intent.setComponent(mTopComponent); 3239 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3240 intent.addCategory(Intent.CATEGORY_HOME); 3241 } 3242 return intent; 3243 } 3244 3245 boolean startHomeActivityLocked(int userId) { 3246 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3247 && mTopAction == null) { 3248 // We are running in factory test mode, but unable to find 3249 // the factory test app, so just sit around displaying the 3250 // error message and don't try to start anything. 3251 return false; 3252 } 3253 Intent intent = getHomeIntent(); 3254 ActivityInfo aInfo = 3255 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3256 if (aInfo != null) { 3257 intent.setComponent(new ComponentName( 3258 aInfo.applicationInfo.packageName, aInfo.name)); 3259 // Don't do this if the home app is currently being 3260 // instrumented. 3261 aInfo = new ActivityInfo(aInfo); 3262 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3263 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3264 aInfo.applicationInfo.uid, true); 3265 if (app == null || app.instrumentationClass == null) { 3266 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3267 mStackSupervisor.startHomeActivity(intent, aInfo); 3268 } 3269 } 3270 3271 return true; 3272 } 3273 3274 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3275 ActivityInfo ai = null; 3276 ComponentName comp = intent.getComponent(); 3277 try { 3278 if (comp != null) { 3279 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3280 } else { 3281 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3282 intent, 3283 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3284 flags, userId); 3285 3286 if (info != null) { 3287 ai = info.activityInfo; 3288 } 3289 } 3290 } catch (RemoteException e) { 3291 // ignore 3292 } 3293 3294 return ai; 3295 } 3296 3297 /** 3298 * Starts the "new version setup screen" if appropriate. 3299 */ 3300 void startSetupActivityLocked() { 3301 // Only do this once per boot. 3302 if (mCheckedForSetup) { 3303 return; 3304 } 3305 3306 // We will show this screen if the current one is a different 3307 // version than the last one shown, and we are not running in 3308 // low-level factory test mode. 3309 final ContentResolver resolver = mContext.getContentResolver(); 3310 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3311 Settings.Global.getInt(resolver, 3312 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3313 mCheckedForSetup = true; 3314 3315 // See if we should be showing the platform update setup UI. 3316 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3317 List<ResolveInfo> ris = mContext.getPackageManager() 3318 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3319 3320 // We don't allow third party apps to replace this. 3321 ResolveInfo ri = null; 3322 for (int i=0; ris != null && i<ris.size(); i++) { 3323 if ((ris.get(i).activityInfo.applicationInfo.flags 3324 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3325 ri = ris.get(i); 3326 break; 3327 } 3328 } 3329 3330 if (ri != null) { 3331 String vers = ri.activityInfo.metaData != null 3332 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3333 : null; 3334 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3335 vers = ri.activityInfo.applicationInfo.metaData.getString( 3336 Intent.METADATA_SETUP_VERSION); 3337 } 3338 String lastVers = Settings.Secure.getString( 3339 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3340 if (vers != null && !vers.equals(lastVers)) { 3341 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3342 intent.setComponent(new ComponentName( 3343 ri.activityInfo.packageName, ri.activityInfo.name)); 3344 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3345 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3346 null); 3347 } 3348 } 3349 } 3350 } 3351 3352 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3353 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3354 } 3355 3356 void enforceNotIsolatedCaller(String caller) { 3357 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3358 throw new SecurityException("Isolated process not allowed to call " + caller); 3359 } 3360 } 3361 3362 @Override 3363 public int getFrontActivityScreenCompatMode() { 3364 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3365 synchronized (this) { 3366 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3367 } 3368 } 3369 3370 @Override 3371 public void setFrontActivityScreenCompatMode(int mode) { 3372 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3373 "setFrontActivityScreenCompatMode"); 3374 synchronized (this) { 3375 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3376 } 3377 } 3378 3379 @Override 3380 public int getPackageScreenCompatMode(String packageName) { 3381 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3382 synchronized (this) { 3383 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3384 } 3385 } 3386 3387 @Override 3388 public void setPackageScreenCompatMode(String packageName, int mode) { 3389 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3390 "setPackageScreenCompatMode"); 3391 synchronized (this) { 3392 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3393 } 3394 } 3395 3396 @Override 3397 public boolean getPackageAskScreenCompat(String packageName) { 3398 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3399 synchronized (this) { 3400 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3401 } 3402 } 3403 3404 @Override 3405 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3406 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3407 "setPackageAskScreenCompat"); 3408 synchronized (this) { 3409 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3410 } 3411 } 3412 3413 private void dispatchProcessesChanged() { 3414 int N; 3415 synchronized (this) { 3416 N = mPendingProcessChanges.size(); 3417 if (mActiveProcessChanges.length < N) { 3418 mActiveProcessChanges = new ProcessChangeItem[N]; 3419 } 3420 mPendingProcessChanges.toArray(mActiveProcessChanges); 3421 mAvailProcessChanges.addAll(mPendingProcessChanges); 3422 mPendingProcessChanges.clear(); 3423 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3424 } 3425 3426 int i = mProcessObservers.beginBroadcast(); 3427 while (i > 0) { 3428 i--; 3429 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3430 if (observer != null) { 3431 try { 3432 for (int j=0; j<N; j++) { 3433 ProcessChangeItem item = mActiveProcessChanges[j]; 3434 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3435 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3436 + item.pid + " uid=" + item.uid + ": " 3437 + item.foregroundActivities); 3438 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3439 item.foregroundActivities); 3440 } 3441 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3442 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3443 + item.pid + " uid=" + item.uid + ": " + item.processState); 3444 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3445 } 3446 } 3447 } catch (RemoteException e) { 3448 } 3449 } 3450 } 3451 mProcessObservers.finishBroadcast(); 3452 } 3453 3454 private void dispatchProcessDied(int pid, int uid) { 3455 int i = mProcessObservers.beginBroadcast(); 3456 while (i > 0) { 3457 i--; 3458 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3459 if (observer != null) { 3460 try { 3461 observer.onProcessDied(pid, uid); 3462 } catch (RemoteException e) { 3463 } 3464 } 3465 } 3466 mProcessObservers.finishBroadcast(); 3467 } 3468 3469 @Override 3470 public final int startActivity(IApplicationThread caller, String callingPackage, 3471 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3472 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3473 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3474 resultWho, requestCode, startFlags, profilerInfo, options, 3475 UserHandle.getCallingUserId()); 3476 } 3477 3478 @Override 3479 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3480 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3481 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3482 enforceNotIsolatedCaller("startActivity"); 3483 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3484 false, ALLOW_FULL_ONLY, "startActivity", null); 3485 // TODO: Switch to user app stacks here. 3486 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3487 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3488 profilerInfo, null, null, options, userId, null, null); 3489 } 3490 3491 @Override 3492 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3493 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3494 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3495 3496 // This is very dangerous -- it allows you to perform a start activity (including 3497 // permission grants) as any app that may launch one of your own activities. So 3498 // we will only allow this to be done from activities that are part of the core framework, 3499 // and then only when they are running as the system. 3500 final ActivityRecord sourceRecord; 3501 final int targetUid; 3502 final String targetPackage; 3503 synchronized (this) { 3504 if (resultTo == null) { 3505 throw new SecurityException("Must be called from an activity"); 3506 } 3507 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3508 if (sourceRecord == null) { 3509 throw new SecurityException("Called with bad activity token: " + resultTo); 3510 } 3511 if (!sourceRecord.info.packageName.equals("android")) { 3512 throw new SecurityException( 3513 "Must be called from an activity that is declared in the android package"); 3514 } 3515 if (sourceRecord.app == null) { 3516 throw new SecurityException("Called without a process attached to activity"); 3517 } 3518 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3519 // This is still okay, as long as this activity is running under the 3520 // uid of the original calling activity. 3521 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3522 throw new SecurityException( 3523 "Calling activity in uid " + sourceRecord.app.uid 3524 + " must be system uid or original calling uid " 3525 + sourceRecord.launchedFromUid); 3526 } 3527 } 3528 targetUid = sourceRecord.launchedFromUid; 3529 targetPackage = sourceRecord.launchedFromPackage; 3530 } 3531 3532 // TODO: Switch to user app stacks here. 3533 try { 3534 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3535 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3536 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3537 return ret; 3538 } catch (SecurityException e) { 3539 // XXX need to figure out how to propagate to original app. 3540 // A SecurityException here is generally actually a fault of the original 3541 // calling activity (such as a fairly granting permissions), so propagate it 3542 // back to them. 3543 /* 3544 StringBuilder msg = new StringBuilder(); 3545 msg.append("While launching"); 3546 msg.append(intent.toString()); 3547 msg.append(": "); 3548 msg.append(e.getMessage()); 3549 */ 3550 throw e; 3551 } 3552 } 3553 3554 @Override 3555 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3556 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3557 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3558 enforceNotIsolatedCaller("startActivityAndWait"); 3559 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3560 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3561 WaitResult res = new WaitResult(); 3562 // TODO: Switch to user app stacks here. 3563 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3564 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3565 options, userId, null, null); 3566 return res; 3567 } 3568 3569 @Override 3570 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3571 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3572 int startFlags, Configuration config, Bundle options, int userId) { 3573 enforceNotIsolatedCaller("startActivityWithConfig"); 3574 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3575 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3576 // TODO: Switch to user app stacks here. 3577 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3578 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3579 null, null, config, options, userId, null, null); 3580 return ret; 3581 } 3582 3583 @Override 3584 public int startActivityIntentSender(IApplicationThread caller, 3585 IntentSender intent, Intent fillInIntent, String resolvedType, 3586 IBinder resultTo, String resultWho, int requestCode, 3587 int flagsMask, int flagsValues, Bundle options) { 3588 enforceNotIsolatedCaller("startActivityIntentSender"); 3589 // Refuse possible leaked file descriptors 3590 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3591 throw new IllegalArgumentException("File descriptors passed in Intent"); 3592 } 3593 3594 IIntentSender sender = intent.getTarget(); 3595 if (!(sender instanceof PendingIntentRecord)) { 3596 throw new IllegalArgumentException("Bad PendingIntent object"); 3597 } 3598 3599 PendingIntentRecord pir = (PendingIntentRecord)sender; 3600 3601 synchronized (this) { 3602 // If this is coming from the currently resumed activity, it is 3603 // effectively saying that app switches are allowed at this point. 3604 final ActivityStack stack = getFocusedStack(); 3605 if (stack.mResumedActivity != null && 3606 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3607 mAppSwitchesAllowedTime = 0; 3608 } 3609 } 3610 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3611 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3612 return ret; 3613 } 3614 3615 @Override 3616 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3617 Intent intent, String resolvedType, IVoiceInteractionSession session, 3618 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3619 Bundle options, int userId) { 3620 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3621 != PackageManager.PERMISSION_GRANTED) { 3622 String msg = "Permission Denial: startVoiceActivity() from pid=" 3623 + Binder.getCallingPid() 3624 + ", uid=" + Binder.getCallingUid() 3625 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3626 Slog.w(TAG, msg); 3627 throw new SecurityException(msg); 3628 } 3629 if (session == null || interactor == null) { 3630 throw new NullPointerException("null session or interactor"); 3631 } 3632 userId = handleIncomingUser(callingPid, callingUid, userId, 3633 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3634 // TODO: Switch to user app stacks here. 3635 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3636 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3637 null, options, userId, null, null); 3638 } 3639 3640 @Override 3641 public boolean startNextMatchingActivity(IBinder callingActivity, 3642 Intent intent, Bundle options) { 3643 // Refuse possible leaked file descriptors 3644 if (intent != null && intent.hasFileDescriptors() == true) { 3645 throw new IllegalArgumentException("File descriptors passed in Intent"); 3646 } 3647 3648 synchronized (this) { 3649 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3650 if (r == null) { 3651 ActivityOptions.abort(options); 3652 return false; 3653 } 3654 if (r.app == null || r.app.thread == null) { 3655 // The caller is not running... d'oh! 3656 ActivityOptions.abort(options); 3657 return false; 3658 } 3659 intent = new Intent(intent); 3660 // The caller is not allowed to change the data. 3661 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3662 // And we are resetting to find the next component... 3663 intent.setComponent(null); 3664 3665 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3666 3667 ActivityInfo aInfo = null; 3668 try { 3669 List<ResolveInfo> resolves = 3670 AppGlobals.getPackageManager().queryIntentActivities( 3671 intent, r.resolvedType, 3672 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3673 UserHandle.getCallingUserId()); 3674 3675 // Look for the original activity in the list... 3676 final int N = resolves != null ? resolves.size() : 0; 3677 for (int i=0; i<N; i++) { 3678 ResolveInfo rInfo = resolves.get(i); 3679 if (rInfo.activityInfo.packageName.equals(r.packageName) 3680 && rInfo.activityInfo.name.equals(r.info.name)) { 3681 // We found the current one... the next matching is 3682 // after it. 3683 i++; 3684 if (i<N) { 3685 aInfo = resolves.get(i).activityInfo; 3686 } 3687 if (debug) { 3688 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3689 + "/" + r.info.name); 3690 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3691 + "/" + aInfo.name); 3692 } 3693 break; 3694 } 3695 } 3696 } catch (RemoteException e) { 3697 } 3698 3699 if (aInfo == null) { 3700 // Nobody who is next! 3701 ActivityOptions.abort(options); 3702 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3703 return false; 3704 } 3705 3706 intent.setComponent(new ComponentName( 3707 aInfo.applicationInfo.packageName, aInfo.name)); 3708 intent.setFlags(intent.getFlags()&~( 3709 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3710 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3711 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3712 Intent.FLAG_ACTIVITY_NEW_TASK)); 3713 3714 // Okay now we need to start the new activity, replacing the 3715 // currently running activity. This is a little tricky because 3716 // we want to start the new one as if the current one is finished, 3717 // but not finish the current one first so that there is no flicker. 3718 // And thus... 3719 final boolean wasFinishing = r.finishing; 3720 r.finishing = true; 3721 3722 // Propagate reply information over to the new activity. 3723 final ActivityRecord resultTo = r.resultTo; 3724 final String resultWho = r.resultWho; 3725 final int requestCode = r.requestCode; 3726 r.resultTo = null; 3727 if (resultTo != null) { 3728 resultTo.removeResultsLocked(r, resultWho, requestCode); 3729 } 3730 3731 final long origId = Binder.clearCallingIdentity(); 3732 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3733 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3734 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3735 options, false, null, null, null); 3736 Binder.restoreCallingIdentity(origId); 3737 3738 r.finishing = wasFinishing; 3739 if (res != ActivityManager.START_SUCCESS) { 3740 return false; 3741 } 3742 return true; 3743 } 3744 } 3745 3746 @Override 3747 public final int startActivityFromRecents(int taskId, Bundle options) { 3748 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3749 String msg = "Permission Denial: startActivityFromRecents called without " + 3750 START_TASKS_FROM_RECENTS; 3751 Slog.w(TAG, msg); 3752 throw new SecurityException(msg); 3753 } 3754 return startActivityFromRecentsInner(taskId, options); 3755 } 3756 3757 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3758 final TaskRecord task; 3759 final int callingUid; 3760 final String callingPackage; 3761 final Intent intent; 3762 final int userId; 3763 synchronized (this) { 3764 task = recentTaskForIdLocked(taskId); 3765 if (task == null) { 3766 throw new IllegalArgumentException("Task " + taskId + " not found."); 3767 } 3768 callingUid = task.mCallingUid; 3769 callingPackage = task.mCallingPackage; 3770 intent = task.intent; 3771 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3772 userId = task.userId; 3773 } 3774 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3775 options, userId, null, task); 3776 } 3777 3778 final int startActivityInPackage(int uid, String callingPackage, 3779 Intent intent, String resolvedType, IBinder resultTo, 3780 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3781 IActivityContainer container, TaskRecord inTask) { 3782 3783 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3784 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3785 3786 // TODO: Switch to user app stacks here. 3787 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3788 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3789 null, null, null, options, userId, container, inTask); 3790 return ret; 3791 } 3792 3793 @Override 3794 public final int startActivities(IApplicationThread caller, String callingPackage, 3795 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3796 int userId) { 3797 enforceNotIsolatedCaller("startActivities"); 3798 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3799 false, ALLOW_FULL_ONLY, "startActivity", null); 3800 // TODO: Switch to user app stacks here. 3801 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3802 resolvedTypes, resultTo, options, userId); 3803 return ret; 3804 } 3805 3806 final int startActivitiesInPackage(int uid, String callingPackage, 3807 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3808 Bundle options, int userId) { 3809 3810 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3811 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3812 // TODO: Switch to user app stacks here. 3813 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3814 resultTo, options, userId); 3815 return ret; 3816 } 3817 3818 //explicitly remove thd old information in mRecentTasks when removing existing user. 3819 private void removeRecentTasksForUserLocked(int userId) { 3820 if(userId <= 0) { 3821 Slog.i(TAG, "Can't remove recent task on user " + userId); 3822 return; 3823 } 3824 3825 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3826 TaskRecord tr = mRecentTasks.get(i); 3827 if (tr.userId == userId) { 3828 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3829 + " when finishing user" + userId); 3830 mRecentTasks.remove(i); 3831 tr.removedFromRecents(mTaskPersister); 3832 } 3833 } 3834 3835 // Remove tasks from persistent storage. 3836 mTaskPersister.wakeup(null, true); 3837 } 3838 3839 /** 3840 * Update the recent tasks lists: make sure tasks should still be here (their 3841 * applications / activities still exist), update their availability, fixup ordering 3842 * of affiliations. 3843 */ 3844 void cleanupRecentTasksLocked(int userId) { 3845 if (mRecentTasks == null) { 3846 // Happens when called from the packagemanager broadcast before boot. 3847 return; 3848 } 3849 3850 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3851 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3852 final IPackageManager pm = AppGlobals.getPackageManager(); 3853 final ActivityInfo dummyAct = new ActivityInfo(); 3854 final ApplicationInfo dummyApp = new ApplicationInfo(); 3855 3856 int N = mRecentTasks.size(); 3857 3858 int[] users = userId == UserHandle.USER_ALL 3859 ? getUsersLocked() : new int[] { userId }; 3860 for (int user : users) { 3861 for (int i = 0; i < N; i++) { 3862 TaskRecord task = mRecentTasks.get(i); 3863 if (task.userId != user) { 3864 // Only look at tasks for the user ID of interest. 3865 continue; 3866 } 3867 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3868 // This situation is broken, and we should just get rid of it now. 3869 mRecentTasks.remove(i); 3870 task.removedFromRecents(mTaskPersister); 3871 i--; 3872 N--; 3873 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3874 continue; 3875 } 3876 // Check whether this activity is currently available. 3877 if (task.realActivity != null) { 3878 ActivityInfo ai = availActCache.get(task.realActivity); 3879 if (ai == null) { 3880 try { 3881 ai = pm.getActivityInfo(task.realActivity, 3882 PackageManager.GET_UNINSTALLED_PACKAGES 3883 | PackageManager.GET_DISABLED_COMPONENTS, user); 3884 } catch (RemoteException e) { 3885 // Will never happen. 3886 continue; 3887 } 3888 if (ai == null) { 3889 ai = dummyAct; 3890 } 3891 availActCache.put(task.realActivity, ai); 3892 } 3893 if (ai == dummyAct) { 3894 // This could be either because the activity no longer exists, or the 3895 // app is temporarily gone. For the former we want to remove the recents 3896 // entry; for the latter we want to mark it as unavailable. 3897 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3898 if (app == null) { 3899 try { 3900 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3901 PackageManager.GET_UNINSTALLED_PACKAGES 3902 | PackageManager.GET_DISABLED_COMPONENTS, user); 3903 } catch (RemoteException e) { 3904 // Will never happen. 3905 continue; 3906 } 3907 if (app == null) { 3908 app = dummyApp; 3909 } 3910 availAppCache.put(task.realActivity.getPackageName(), app); 3911 } 3912 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3913 // Doesn't exist any more! Good-bye. 3914 mRecentTasks.remove(i); 3915 task.removedFromRecents(mTaskPersister); 3916 i--; 3917 N--; 3918 Slog.w(TAG, "Removing no longer valid recent: " + task); 3919 continue; 3920 } else { 3921 // Otherwise just not available for now. 3922 if (task.isAvailable) { 3923 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3924 + task); 3925 } 3926 task.isAvailable = false; 3927 } 3928 } else { 3929 if (!ai.enabled || !ai.applicationInfo.enabled 3930 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3931 if (task.isAvailable) { 3932 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3933 + task + " (enabled=" + ai.enabled + "/" 3934 + ai.applicationInfo.enabled + " flags=" 3935 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3936 } 3937 task.isAvailable = false; 3938 } else { 3939 if (!task.isAvailable) { 3940 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3941 + task); 3942 } 3943 task.isAvailable = true; 3944 } 3945 } 3946 } 3947 } 3948 } 3949 3950 // Verify the affiliate chain for each task. 3951 for (int i = 0; i < N; ) { 3952 TaskRecord task = mRecentTasks.remove(i); 3953 if (mTmpRecents.contains(task)) { 3954 continue; 3955 } 3956 int affiliatedTaskId = task.mAffiliatedTaskId; 3957 while (true) { 3958 TaskRecord next = task.mNextAffiliate; 3959 if (next == null) { 3960 break; 3961 } 3962 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3963 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3964 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3965 task.setNextAffiliate(null); 3966 if (next.mPrevAffiliate == task) { 3967 next.setPrevAffiliate(null); 3968 } 3969 break; 3970 } 3971 if (next.mPrevAffiliate != task) { 3972 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3973 next.mPrevAffiliate + " task=" + task); 3974 next.setPrevAffiliate(null); 3975 task.setNextAffiliate(null); 3976 break; 3977 } 3978 if (!mRecentTasks.contains(next)) { 3979 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3980 task.setNextAffiliate(null); 3981 // We know that next.mPrevAffiliate is always task, from above, so clear 3982 // its previous affiliate. 3983 next.setPrevAffiliate(null); 3984 break; 3985 } 3986 task = next; 3987 } 3988 // task is now the end of the list 3989 do { 3990 mRecentTasks.remove(task); 3991 mRecentTasks.add(i++, task); 3992 mTmpRecents.add(task); 3993 task.inRecents = true; 3994 } while ((task = task.mPrevAffiliate) != null); 3995 } 3996 mTmpRecents.clear(); 3997 // mRecentTasks is now in sorted, affiliated order. 3998 } 3999 4000 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4001 int N = mRecentTasks.size(); 4002 TaskRecord top = task; 4003 int topIndex = taskIndex; 4004 while (top.mNextAffiliate != null && topIndex > 0) { 4005 top = top.mNextAffiliate; 4006 topIndex--; 4007 } 4008 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4009 + topIndex + " from intial " + taskIndex); 4010 // Find the end of the chain, doing a sanity check along the way. 4011 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4012 int endIndex = topIndex; 4013 TaskRecord prev = top; 4014 while (endIndex < N) { 4015 TaskRecord cur = mRecentTasks.get(endIndex); 4016 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4017 + endIndex + " " + cur); 4018 if (cur == top) { 4019 // Verify start of the chain. 4020 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4021 Slog.wtf(TAG, "Bad chain @" + endIndex 4022 + ": first task has next affiliate: " + prev); 4023 sane = false; 4024 break; 4025 } 4026 } else { 4027 // Verify middle of the chain's next points back to the one before. 4028 if (cur.mNextAffiliate != prev 4029 || cur.mNextAffiliateTaskId != prev.taskId) { 4030 Slog.wtf(TAG, "Bad chain @" + endIndex 4031 + ": middle task " + cur + " @" + endIndex 4032 + " has bad next affiliate " 4033 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4034 + ", expected " + prev); 4035 sane = false; 4036 break; 4037 } 4038 } 4039 if (cur.mPrevAffiliateTaskId == -1) { 4040 // Chain ends here. 4041 if (cur.mPrevAffiliate != null) { 4042 Slog.wtf(TAG, "Bad chain @" + endIndex 4043 + ": last task " + cur + " has previous affiliate " 4044 + cur.mPrevAffiliate); 4045 sane = false; 4046 } 4047 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4048 break; 4049 } else { 4050 // Verify middle of the chain's prev points to a valid item. 4051 if (cur.mPrevAffiliate == null) { 4052 Slog.wtf(TAG, "Bad chain @" + endIndex 4053 + ": task " + cur + " has previous affiliate " 4054 + cur.mPrevAffiliate + " but should be id " 4055 + cur.mPrevAffiliate); 4056 sane = false; 4057 break; 4058 } 4059 } 4060 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4061 Slog.wtf(TAG, "Bad chain @" + endIndex 4062 + ": task " + cur + " has affiliated id " 4063 + cur.mAffiliatedTaskId + " but should be " 4064 + task.mAffiliatedTaskId); 4065 sane = false; 4066 break; 4067 } 4068 prev = cur; 4069 endIndex++; 4070 if (endIndex >= N) { 4071 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4072 + ": last task " + prev); 4073 sane = false; 4074 break; 4075 } 4076 } 4077 if (sane) { 4078 if (endIndex < taskIndex) { 4079 Slog.wtf(TAG, "Bad chain @" + endIndex 4080 + ": did not extend to task " + task + " @" + taskIndex); 4081 sane = false; 4082 } 4083 } 4084 if (sane) { 4085 // All looks good, we can just move all of the affiliated tasks 4086 // to the top. 4087 for (int i=topIndex; i<=endIndex; i++) { 4088 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4089 + " from " + i + " to " + (i-topIndex)); 4090 TaskRecord cur = mRecentTasks.remove(i); 4091 mRecentTasks.add(i-topIndex, cur); 4092 } 4093 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4094 + " to " + endIndex); 4095 return true; 4096 } 4097 4098 // Whoops, couldn't do it. 4099 return false; 4100 } 4101 4102 final void addRecentTaskLocked(TaskRecord task) { 4103 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4104 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4105 4106 int N = mRecentTasks.size(); 4107 // Quick case: check if the top-most recent task is the same. 4108 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4109 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4110 return; 4111 } 4112 // Another quick case: check if this is part of a set of affiliated 4113 // tasks that are at the top. 4114 if (isAffiliated && N > 0 && task.inRecents 4115 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4116 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4117 + " at top when adding " + task); 4118 return; 4119 } 4120 // Another quick case: never add voice sessions. 4121 if (task.voiceSession != null) { 4122 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4123 return; 4124 } 4125 4126 boolean needAffiliationFix = false; 4127 4128 // Slightly less quick case: the task is already in recents, so all we need 4129 // to do is move it. 4130 if (task.inRecents) { 4131 int taskIndex = mRecentTasks.indexOf(task); 4132 if (taskIndex >= 0) { 4133 if (!isAffiliated) { 4134 // Simple case: this is not an affiliated task, so we just move it to the front. 4135 mRecentTasks.remove(taskIndex); 4136 mRecentTasks.add(0, task); 4137 notifyTaskPersisterLocked(task, false); 4138 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4139 + " from " + taskIndex); 4140 return; 4141 } else { 4142 // More complicated: need to keep all affiliated tasks together. 4143 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4144 // All went well. 4145 return; 4146 } 4147 4148 // Uh oh... something bad in the affiliation chain, try to rebuild 4149 // everything and then go through our general path of adding a new task. 4150 needAffiliationFix = true; 4151 } 4152 } else { 4153 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4154 needAffiliationFix = true; 4155 } 4156 } 4157 4158 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4159 trimRecentsForTask(task, true); 4160 4161 N = mRecentTasks.size(); 4162 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4163 final TaskRecord tr = mRecentTasks.remove(N - 1); 4164 tr.removedFromRecents(mTaskPersister); 4165 N--; 4166 } 4167 task.inRecents = true; 4168 if (!isAffiliated || needAffiliationFix) { 4169 // If this is a simple non-affiliated task, or we had some failure trying to 4170 // handle it as part of an affilated task, then just place it at the top. 4171 mRecentTasks.add(0, task); 4172 } else if (isAffiliated) { 4173 // If this is a new affiliated task, then move all of the affiliated tasks 4174 // to the front and insert this new one. 4175 TaskRecord other = task.mNextAffiliate; 4176 if (other == null) { 4177 other = task.mPrevAffiliate; 4178 } 4179 if (other != null) { 4180 int otherIndex = mRecentTasks.indexOf(other); 4181 if (otherIndex >= 0) { 4182 // Insert new task at appropriate location. 4183 int taskIndex; 4184 if (other == task.mNextAffiliate) { 4185 // We found the index of our next affiliation, which is who is 4186 // before us in the list, so add after that point. 4187 taskIndex = otherIndex+1; 4188 } else { 4189 // We found the index of our previous affiliation, which is who is 4190 // after us in the list, so add at their position. 4191 taskIndex = otherIndex; 4192 } 4193 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4194 + taskIndex + ": " + task); 4195 mRecentTasks.add(taskIndex, task); 4196 4197 // Now move everything to the front. 4198 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4199 // All went well. 4200 return; 4201 } 4202 4203 // Uh oh... something bad in the affiliation chain, try to rebuild 4204 // everything and then go through our general path of adding a new task. 4205 needAffiliationFix = true; 4206 } else { 4207 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4208 + other); 4209 needAffiliationFix = true; 4210 } 4211 } else { 4212 if (DEBUG_RECENTS) Slog.d(TAG, 4213 "addRecent: adding affiliated task without next/prev:" + task); 4214 needAffiliationFix = true; 4215 } 4216 } 4217 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4218 4219 if (needAffiliationFix) { 4220 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4221 cleanupRecentTasksLocked(task.userId); 4222 } 4223 } 4224 4225 /** 4226 * If needed, remove oldest existing entries in recents that are for the same kind 4227 * of task as the given one. 4228 */ 4229 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4230 int N = mRecentTasks.size(); 4231 final Intent intent = task.intent; 4232 final boolean document = intent != null && intent.isDocument(); 4233 4234 int maxRecents = task.maxRecents - 1; 4235 for (int i=0; i<N; i++) { 4236 final TaskRecord tr = mRecentTasks.get(i); 4237 if (task != tr) { 4238 if (task.userId != tr.userId) { 4239 continue; 4240 } 4241 if (i > MAX_RECENT_BITMAPS) { 4242 tr.freeLastThumbnail(); 4243 } 4244 final Intent trIntent = tr.intent; 4245 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4246 (intent == null || !intent.filterEquals(trIntent))) { 4247 continue; 4248 } 4249 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4250 if (document && trIsDocument) { 4251 // These are the same document activity (not necessarily the same doc). 4252 if (maxRecents > 0) { 4253 --maxRecents; 4254 continue; 4255 } 4256 // Hit the maximum number of documents for this task. Fall through 4257 // and remove this document from recents. 4258 } else if (document || trIsDocument) { 4259 // Only one of these is a document. Not the droid we're looking for. 4260 continue; 4261 } 4262 } 4263 4264 if (!doTrim) { 4265 // If the caller is not actually asking for a trim, just tell them we reached 4266 // a point where the trim would happen. 4267 return i; 4268 } 4269 4270 // Either task and tr are the same or, their affinities match or their intents match 4271 // and neither of them is a document, or they are documents using the same activity 4272 // and their maxRecents has been reached. 4273 tr.disposeThumbnail(); 4274 mRecentTasks.remove(i); 4275 if (task != tr) { 4276 tr.removedFromRecents(mTaskPersister); 4277 } 4278 i--; 4279 N--; 4280 if (task.intent == null) { 4281 // If the new recent task we are adding is not fully 4282 // specified, then replace it with the existing recent task. 4283 task = tr; 4284 } 4285 notifyTaskPersisterLocked(tr, false); 4286 } 4287 4288 return -1; 4289 } 4290 4291 @Override 4292 public void reportActivityFullyDrawn(IBinder token) { 4293 synchronized (this) { 4294 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4295 if (r == null) { 4296 return; 4297 } 4298 r.reportFullyDrawnLocked(); 4299 } 4300 } 4301 4302 @Override 4303 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4304 synchronized (this) { 4305 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4306 if (r == null) { 4307 return; 4308 } 4309 final long origId = Binder.clearCallingIdentity(); 4310 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4311 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4312 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4313 if (config != null) { 4314 r.frozenBeforeDestroy = true; 4315 if (!updateConfigurationLocked(config, r, false, false)) { 4316 mStackSupervisor.resumeTopActivitiesLocked(); 4317 } 4318 } 4319 Binder.restoreCallingIdentity(origId); 4320 } 4321 } 4322 4323 @Override 4324 public int getRequestedOrientation(IBinder token) { 4325 synchronized (this) { 4326 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4327 if (r == null) { 4328 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4329 } 4330 return mWindowManager.getAppOrientation(r.appToken); 4331 } 4332 } 4333 4334 /** 4335 * This is the internal entry point for handling Activity.finish(). 4336 * 4337 * @param token The Binder token referencing the Activity we want to finish. 4338 * @param resultCode Result code, if any, from this Activity. 4339 * @param resultData Result data (Intent), if any, from this Activity. 4340 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4341 * the root Activity in the task. 4342 * 4343 * @return Returns true if the activity successfully finished, or false if it is still running. 4344 */ 4345 @Override 4346 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4347 boolean finishTask) { 4348 // Refuse possible leaked file descriptors 4349 if (resultData != null && resultData.hasFileDescriptors() == true) { 4350 throw new IllegalArgumentException("File descriptors passed in Intent"); 4351 } 4352 4353 synchronized(this) { 4354 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4355 if (r == null) { 4356 return true; 4357 } 4358 // Keep track of the root activity of the task before we finish it 4359 TaskRecord tr = r.task; 4360 ActivityRecord rootR = tr.getRootActivity(); 4361 // Do not allow task to finish in Lock Task mode. 4362 if (tr == mStackSupervisor.mLockTaskModeTask) { 4363 if (rootR == r) { 4364 mStackSupervisor.showLockTaskToast(); 4365 return false; 4366 } 4367 } 4368 if (mController != null) { 4369 // Find the first activity that is not finishing. 4370 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4371 if (next != null) { 4372 // ask watcher if this is allowed 4373 boolean resumeOK = true; 4374 try { 4375 resumeOK = mController.activityResuming(next.packageName); 4376 } catch (RemoteException e) { 4377 mController = null; 4378 Watchdog.getInstance().setActivityController(null); 4379 } 4380 4381 if (!resumeOK) { 4382 return false; 4383 } 4384 } 4385 } 4386 final long origId = Binder.clearCallingIdentity(); 4387 try { 4388 boolean res; 4389 if (finishTask && r == rootR) { 4390 // If requested, remove the task that is associated to this activity only if it 4391 // was the root activity in the task. The result code and data is ignored because 4392 // we don't support returning them across task boundaries. 4393 res = removeTaskByIdLocked(tr.taskId, 0); 4394 } else { 4395 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4396 resultData, "app-request", true); 4397 } 4398 return res; 4399 } finally { 4400 Binder.restoreCallingIdentity(origId); 4401 } 4402 } 4403 } 4404 4405 @Override 4406 public final void finishHeavyWeightApp() { 4407 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4408 != PackageManager.PERMISSION_GRANTED) { 4409 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4410 + Binder.getCallingPid() 4411 + ", uid=" + Binder.getCallingUid() 4412 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4413 Slog.w(TAG, msg); 4414 throw new SecurityException(msg); 4415 } 4416 4417 synchronized(this) { 4418 if (mHeavyWeightProcess == null) { 4419 return; 4420 } 4421 4422 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4423 mHeavyWeightProcess.activities); 4424 for (int i=0; i<activities.size(); i++) { 4425 ActivityRecord r = activities.get(i); 4426 if (!r.finishing) { 4427 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4428 null, "finish-heavy", true); 4429 } 4430 } 4431 4432 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4433 mHeavyWeightProcess.userId, 0)); 4434 mHeavyWeightProcess = null; 4435 } 4436 } 4437 4438 @Override 4439 public void crashApplication(int uid, int initialPid, String packageName, 4440 String message) { 4441 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4442 != PackageManager.PERMISSION_GRANTED) { 4443 String msg = "Permission Denial: crashApplication() from pid=" 4444 + Binder.getCallingPid() 4445 + ", uid=" + Binder.getCallingUid() 4446 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4447 Slog.w(TAG, msg); 4448 throw new SecurityException(msg); 4449 } 4450 4451 synchronized(this) { 4452 ProcessRecord proc = null; 4453 4454 // Figure out which process to kill. We don't trust that initialPid 4455 // still has any relation to current pids, so must scan through the 4456 // list. 4457 synchronized (mPidsSelfLocked) { 4458 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4459 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4460 if (p.uid != uid) { 4461 continue; 4462 } 4463 if (p.pid == initialPid) { 4464 proc = p; 4465 break; 4466 } 4467 if (p.pkgList.containsKey(packageName)) { 4468 proc = p; 4469 } 4470 } 4471 } 4472 4473 if (proc == null) { 4474 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4475 + " initialPid=" + initialPid 4476 + " packageName=" + packageName); 4477 return; 4478 } 4479 4480 if (proc.thread != null) { 4481 if (proc.pid == Process.myPid()) { 4482 Log.w(TAG, "crashApplication: trying to crash self!"); 4483 return; 4484 } 4485 long ident = Binder.clearCallingIdentity(); 4486 try { 4487 proc.thread.scheduleCrash(message); 4488 } catch (RemoteException e) { 4489 } 4490 Binder.restoreCallingIdentity(ident); 4491 } 4492 } 4493 } 4494 4495 @Override 4496 public final void finishSubActivity(IBinder token, String resultWho, 4497 int requestCode) { 4498 synchronized(this) { 4499 final long origId = Binder.clearCallingIdentity(); 4500 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4501 if (r != null) { 4502 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4503 } 4504 Binder.restoreCallingIdentity(origId); 4505 } 4506 } 4507 4508 @Override 4509 public boolean finishActivityAffinity(IBinder token) { 4510 synchronized(this) { 4511 final long origId = Binder.clearCallingIdentity(); 4512 try { 4513 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4514 4515 ActivityRecord rootR = r.task.getRootActivity(); 4516 // Do not allow task to finish in Lock Task mode. 4517 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4518 if (rootR == r) { 4519 mStackSupervisor.showLockTaskToast(); 4520 return false; 4521 } 4522 } 4523 boolean res = false; 4524 if (r != null) { 4525 res = r.task.stack.finishActivityAffinityLocked(r); 4526 } 4527 return res; 4528 } finally { 4529 Binder.restoreCallingIdentity(origId); 4530 } 4531 } 4532 } 4533 4534 @Override 4535 public void finishVoiceTask(IVoiceInteractionSession session) { 4536 synchronized(this) { 4537 final long origId = Binder.clearCallingIdentity(); 4538 try { 4539 mStackSupervisor.finishVoiceTask(session); 4540 } finally { 4541 Binder.restoreCallingIdentity(origId); 4542 } 4543 } 4544 4545 } 4546 4547 @Override 4548 public boolean releaseActivityInstance(IBinder token) { 4549 synchronized(this) { 4550 final long origId = Binder.clearCallingIdentity(); 4551 try { 4552 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4553 if (r.task == null || r.task.stack == null) { 4554 return false; 4555 } 4556 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4557 } finally { 4558 Binder.restoreCallingIdentity(origId); 4559 } 4560 } 4561 } 4562 4563 @Override 4564 public void releaseSomeActivities(IApplicationThread appInt) { 4565 synchronized(this) { 4566 final long origId = Binder.clearCallingIdentity(); 4567 try { 4568 ProcessRecord app = getRecordForAppLocked(appInt); 4569 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4570 } finally { 4571 Binder.restoreCallingIdentity(origId); 4572 } 4573 } 4574 } 4575 4576 @Override 4577 public boolean willActivityBeVisible(IBinder token) { 4578 synchronized(this) { 4579 ActivityStack stack = ActivityRecord.getStackLocked(token); 4580 if (stack != null) { 4581 return stack.willActivityBeVisibleLocked(token); 4582 } 4583 return false; 4584 } 4585 } 4586 4587 @Override 4588 public void overridePendingTransition(IBinder token, String packageName, 4589 int enterAnim, int exitAnim) { 4590 synchronized(this) { 4591 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4592 if (self == null) { 4593 return; 4594 } 4595 4596 final long origId = Binder.clearCallingIdentity(); 4597 4598 if (self.state == ActivityState.RESUMED 4599 || self.state == ActivityState.PAUSING) { 4600 mWindowManager.overridePendingAppTransition(packageName, 4601 enterAnim, exitAnim, null); 4602 } 4603 4604 Binder.restoreCallingIdentity(origId); 4605 } 4606 } 4607 4608 /** 4609 * Main function for removing an existing process from the activity manager 4610 * as a result of that process going away. Clears out all connections 4611 * to the process. 4612 */ 4613 private final void handleAppDiedLocked(ProcessRecord app, 4614 boolean restarting, boolean allowRestart) { 4615 int pid = app.pid; 4616 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4617 if (!restarting) { 4618 removeLruProcessLocked(app); 4619 if (pid > 0) { 4620 ProcessList.remove(pid); 4621 } 4622 } 4623 4624 if (mProfileProc == app) { 4625 clearProfilerLocked(); 4626 } 4627 4628 // Remove this application's activities from active lists. 4629 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4630 4631 app.activities.clear(); 4632 4633 if (app.instrumentationClass != null) { 4634 Slog.w(TAG, "Crash of app " + app.processName 4635 + " running instrumentation " + app.instrumentationClass); 4636 Bundle info = new Bundle(); 4637 info.putString("shortMsg", "Process crashed."); 4638 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4639 } 4640 4641 if (!restarting) { 4642 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4643 // If there was nothing to resume, and we are not already 4644 // restarting this process, but there is a visible activity that 4645 // is hosted by the process... then make sure all visible 4646 // activities are running, taking care of restarting this 4647 // process. 4648 if (hasVisibleActivities) { 4649 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4650 } 4651 } 4652 } 4653 } 4654 4655 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4656 IBinder threadBinder = thread.asBinder(); 4657 // Find the application record. 4658 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4659 ProcessRecord rec = mLruProcesses.get(i); 4660 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4661 return i; 4662 } 4663 } 4664 return -1; 4665 } 4666 4667 final ProcessRecord getRecordForAppLocked( 4668 IApplicationThread thread) { 4669 if (thread == null) { 4670 return null; 4671 } 4672 4673 int appIndex = getLRURecordIndexForAppLocked(thread); 4674 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4675 } 4676 4677 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4678 // If there are no longer any background processes running, 4679 // and the app that died was not running instrumentation, 4680 // then tell everyone we are now low on memory. 4681 boolean haveBg = false; 4682 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4683 ProcessRecord rec = mLruProcesses.get(i); 4684 if (rec.thread != null 4685 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4686 haveBg = true; 4687 break; 4688 } 4689 } 4690 4691 if (!haveBg) { 4692 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4693 if (doReport) { 4694 long now = SystemClock.uptimeMillis(); 4695 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4696 doReport = false; 4697 } else { 4698 mLastMemUsageReportTime = now; 4699 } 4700 } 4701 final ArrayList<ProcessMemInfo> memInfos 4702 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4703 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4704 long now = SystemClock.uptimeMillis(); 4705 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4706 ProcessRecord rec = mLruProcesses.get(i); 4707 if (rec == dyingProc || rec.thread == null) { 4708 continue; 4709 } 4710 if (doReport) { 4711 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4712 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4713 } 4714 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4715 // The low memory report is overriding any current 4716 // state for a GC request. Make sure to do 4717 // heavy/important/visible/foreground processes first. 4718 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4719 rec.lastRequestedGc = 0; 4720 } else { 4721 rec.lastRequestedGc = rec.lastLowMemory; 4722 } 4723 rec.reportLowMemory = true; 4724 rec.lastLowMemory = now; 4725 mProcessesToGc.remove(rec); 4726 addProcessToGcListLocked(rec); 4727 } 4728 } 4729 if (doReport) { 4730 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4731 mHandler.sendMessage(msg); 4732 } 4733 scheduleAppGcsLocked(); 4734 } 4735 } 4736 4737 final void appDiedLocked(ProcessRecord app) { 4738 appDiedLocked(app, app.pid, app.thread); 4739 } 4740 4741 final void appDiedLocked(ProcessRecord app, int pid, 4742 IApplicationThread thread) { 4743 4744 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4745 synchronized (stats) { 4746 stats.noteProcessDiedLocked(app.info.uid, pid); 4747 } 4748 4749 Process.killProcessGroup(app.info.uid, pid); 4750 4751 // Clean up already done if the process has been re-started. 4752 if (app.pid == pid && app.thread != null && 4753 app.thread.asBinder() == thread.asBinder()) { 4754 boolean doLowMem = app.instrumentationClass == null; 4755 boolean doOomAdj = doLowMem; 4756 if (!app.killedByAm) { 4757 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4758 + ") has died."); 4759 mAllowLowerMemLevel = true; 4760 } else { 4761 // Note that we always want to do oom adj to update our state with the 4762 // new number of procs. 4763 mAllowLowerMemLevel = false; 4764 doLowMem = false; 4765 } 4766 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4767 if (DEBUG_CLEANUP) Slog.v( 4768 TAG, "Dying app: " + app + ", pid: " + pid 4769 + ", thread: " + thread.asBinder()); 4770 handleAppDiedLocked(app, false, true); 4771 4772 if (doOomAdj) { 4773 updateOomAdjLocked(); 4774 } 4775 if (doLowMem) { 4776 doLowMemReportIfNeededLocked(app); 4777 } 4778 } else if (app.pid != pid) { 4779 // A new process has already been started. 4780 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4781 + ") has died and restarted (pid " + app.pid + ")."); 4782 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4783 } else if (DEBUG_PROCESSES) { 4784 Slog.d(TAG, "Received spurious death notification for thread " 4785 + thread.asBinder()); 4786 } 4787 } 4788 4789 /** 4790 * If a stack trace dump file is configured, dump process stack traces. 4791 * @param clearTraces causes the dump file to be erased prior to the new 4792 * traces being written, if true; when false, the new traces will be 4793 * appended to any existing file content. 4794 * @param firstPids of dalvik VM processes to dump stack traces for first 4795 * @param lastPids of dalvik VM processes to dump stack traces for last 4796 * @param nativeProcs optional list of native process names to dump stack crawls 4797 * @return file containing stack traces, or null if no dump file is configured 4798 */ 4799 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4800 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4801 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4802 if (tracesPath == null || tracesPath.length() == 0) { 4803 return null; 4804 } 4805 4806 File tracesFile = new File(tracesPath); 4807 try { 4808 File tracesDir = tracesFile.getParentFile(); 4809 if (!tracesDir.exists()) { 4810 tracesFile.mkdirs(); 4811 if (!SELinux.restorecon(tracesDir)) { 4812 return null; 4813 } 4814 } 4815 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4816 4817 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4818 tracesFile.createNewFile(); 4819 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4820 } catch (IOException e) { 4821 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4822 return null; 4823 } 4824 4825 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4826 return tracesFile; 4827 } 4828 4829 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4830 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4831 // Use a FileObserver to detect when traces finish writing. 4832 // The order of traces is considered important to maintain for legibility. 4833 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4834 @Override 4835 public synchronized void onEvent(int event, String path) { notify(); } 4836 }; 4837 4838 try { 4839 observer.startWatching(); 4840 4841 // First collect all of the stacks of the most important pids. 4842 if (firstPids != null) { 4843 try { 4844 int num = firstPids.size(); 4845 for (int i = 0; i < num; i++) { 4846 synchronized (observer) { 4847 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4848 observer.wait(200); // Wait for write-close, give up after 200msec 4849 } 4850 } 4851 } catch (InterruptedException e) { 4852 Log.wtf(TAG, e); 4853 } 4854 } 4855 4856 // Next collect the stacks of the native pids 4857 if (nativeProcs != null) { 4858 int[] pids = Process.getPidsForCommands(nativeProcs); 4859 if (pids != null) { 4860 for (int pid : pids) { 4861 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4862 } 4863 } 4864 } 4865 4866 // Lastly, measure CPU usage. 4867 if (processCpuTracker != null) { 4868 processCpuTracker.init(); 4869 System.gc(); 4870 processCpuTracker.update(); 4871 try { 4872 synchronized (processCpuTracker) { 4873 processCpuTracker.wait(500); // measure over 1/2 second. 4874 } 4875 } catch (InterruptedException e) { 4876 } 4877 processCpuTracker.update(); 4878 4879 // We'll take the stack crawls of just the top apps using CPU. 4880 final int N = processCpuTracker.countWorkingStats(); 4881 int numProcs = 0; 4882 for (int i=0; i<N && numProcs<5; i++) { 4883 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4884 if (lastPids.indexOfKey(stats.pid) >= 0) { 4885 numProcs++; 4886 try { 4887 synchronized (observer) { 4888 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4889 observer.wait(200); // Wait for write-close, give up after 200msec 4890 } 4891 } catch (InterruptedException e) { 4892 Log.wtf(TAG, e); 4893 } 4894 4895 } 4896 } 4897 } 4898 } finally { 4899 observer.stopWatching(); 4900 } 4901 } 4902 4903 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4904 if (true || IS_USER_BUILD) { 4905 return; 4906 } 4907 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4908 if (tracesPath == null || tracesPath.length() == 0) { 4909 return; 4910 } 4911 4912 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4913 StrictMode.allowThreadDiskWrites(); 4914 try { 4915 final File tracesFile = new File(tracesPath); 4916 final File tracesDir = tracesFile.getParentFile(); 4917 final File tracesTmp = new File(tracesDir, "__tmp__"); 4918 try { 4919 if (!tracesDir.exists()) { 4920 tracesFile.mkdirs(); 4921 if (!SELinux.restorecon(tracesDir.getPath())) { 4922 return; 4923 } 4924 } 4925 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4926 4927 if (tracesFile.exists()) { 4928 tracesTmp.delete(); 4929 tracesFile.renameTo(tracesTmp); 4930 } 4931 StringBuilder sb = new StringBuilder(); 4932 Time tobj = new Time(); 4933 tobj.set(System.currentTimeMillis()); 4934 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4935 sb.append(": "); 4936 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4937 sb.append(" since "); 4938 sb.append(msg); 4939 FileOutputStream fos = new FileOutputStream(tracesFile); 4940 fos.write(sb.toString().getBytes()); 4941 if (app == null) { 4942 fos.write("\n*** No application process!".getBytes()); 4943 } 4944 fos.close(); 4945 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4946 } catch (IOException e) { 4947 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4948 return; 4949 } 4950 4951 if (app != null) { 4952 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4953 firstPids.add(app.pid); 4954 dumpStackTraces(tracesPath, firstPids, null, null, null); 4955 } 4956 4957 File lastTracesFile = null; 4958 File curTracesFile = null; 4959 for (int i=9; i>=0; i--) { 4960 String name = String.format(Locale.US, "slow%02d.txt", i); 4961 curTracesFile = new File(tracesDir, name); 4962 if (curTracesFile.exists()) { 4963 if (lastTracesFile != null) { 4964 curTracesFile.renameTo(lastTracesFile); 4965 } else { 4966 curTracesFile.delete(); 4967 } 4968 } 4969 lastTracesFile = curTracesFile; 4970 } 4971 tracesFile.renameTo(curTracesFile); 4972 if (tracesTmp.exists()) { 4973 tracesTmp.renameTo(tracesFile); 4974 } 4975 } finally { 4976 StrictMode.setThreadPolicy(oldPolicy); 4977 } 4978 } 4979 4980 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4981 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4982 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4983 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4984 4985 if (mController != null) { 4986 try { 4987 // 0 == continue, -1 = kill process immediately 4988 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4989 if (res < 0 && app.pid != MY_PID) { 4990 app.kill("anr", true); 4991 } 4992 } catch (RemoteException e) { 4993 mController = null; 4994 Watchdog.getInstance().setActivityController(null); 4995 } 4996 } 4997 4998 long anrTime = SystemClock.uptimeMillis(); 4999 if (MONITOR_CPU_USAGE) { 5000 updateCpuStatsNow(); 5001 } 5002 5003 synchronized (this) { 5004 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5005 if (mShuttingDown) { 5006 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5007 return; 5008 } else if (app.notResponding) { 5009 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5010 return; 5011 } else if (app.crashing) { 5012 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5013 return; 5014 } 5015 5016 // In case we come through here for the same app before completing 5017 // this one, mark as anring now so we will bail out. 5018 app.notResponding = true; 5019 5020 // Log the ANR to the event log. 5021 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5022 app.processName, app.info.flags, annotation); 5023 5024 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5025 firstPids.add(app.pid); 5026 5027 int parentPid = app.pid; 5028 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5029 if (parentPid != app.pid) firstPids.add(parentPid); 5030 5031 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5032 5033 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5034 ProcessRecord r = mLruProcesses.get(i); 5035 if (r != null && r.thread != null) { 5036 int pid = r.pid; 5037 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5038 if (r.persistent) { 5039 firstPids.add(pid); 5040 } else { 5041 lastPids.put(pid, Boolean.TRUE); 5042 } 5043 } 5044 } 5045 } 5046 } 5047 5048 // Log the ANR to the main log. 5049 StringBuilder info = new StringBuilder(); 5050 info.setLength(0); 5051 info.append("ANR in ").append(app.processName); 5052 if (activity != null && activity.shortComponentName != null) { 5053 info.append(" (").append(activity.shortComponentName).append(")"); 5054 } 5055 info.append("\n"); 5056 info.append("PID: ").append(app.pid).append("\n"); 5057 if (annotation != null) { 5058 info.append("Reason: ").append(annotation).append("\n"); 5059 } 5060 if (parent != null && parent != activity) { 5061 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5062 } 5063 5064 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5065 5066 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5067 NATIVE_STACKS_OF_INTEREST); 5068 5069 String cpuInfo = null; 5070 if (MONITOR_CPU_USAGE) { 5071 updateCpuStatsNow(); 5072 synchronized (mProcessCpuThread) { 5073 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5074 } 5075 info.append(processCpuTracker.printCurrentLoad()); 5076 info.append(cpuInfo); 5077 } 5078 5079 info.append(processCpuTracker.printCurrentState(anrTime)); 5080 5081 Slog.e(TAG, info.toString()); 5082 if (tracesFile == null) { 5083 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5084 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5085 } 5086 5087 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5088 cpuInfo, tracesFile, null); 5089 5090 if (mController != null) { 5091 try { 5092 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5093 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5094 if (res != 0) { 5095 if (res < 0 && app.pid != MY_PID) { 5096 app.kill("anr", true); 5097 } else { 5098 synchronized (this) { 5099 mServices.scheduleServiceTimeoutLocked(app); 5100 } 5101 } 5102 return; 5103 } 5104 } catch (RemoteException e) { 5105 mController = null; 5106 Watchdog.getInstance().setActivityController(null); 5107 } 5108 } 5109 5110 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5111 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5112 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5113 5114 synchronized (this) { 5115 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5116 app.kill("bg anr", true); 5117 return; 5118 } 5119 5120 // Set the app's notResponding state, and look up the errorReportReceiver 5121 makeAppNotRespondingLocked(app, 5122 activity != null ? activity.shortComponentName : null, 5123 annotation != null ? "ANR " + annotation : "ANR", 5124 info.toString()); 5125 5126 // Bring up the infamous App Not Responding dialog 5127 Message msg = Message.obtain(); 5128 HashMap<String, Object> map = new HashMap<String, Object>(); 5129 msg.what = SHOW_NOT_RESPONDING_MSG; 5130 msg.obj = map; 5131 msg.arg1 = aboveSystem ? 1 : 0; 5132 map.put("app", app); 5133 if (activity != null) { 5134 map.put("activity", activity); 5135 } 5136 5137 mHandler.sendMessage(msg); 5138 } 5139 } 5140 5141 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5142 if (!mLaunchWarningShown) { 5143 mLaunchWarningShown = true; 5144 mHandler.post(new Runnable() { 5145 @Override 5146 public void run() { 5147 synchronized (ActivityManagerService.this) { 5148 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5149 d.show(); 5150 mHandler.postDelayed(new Runnable() { 5151 @Override 5152 public void run() { 5153 synchronized (ActivityManagerService.this) { 5154 d.dismiss(); 5155 mLaunchWarningShown = false; 5156 } 5157 } 5158 }, 4000); 5159 } 5160 } 5161 }); 5162 } 5163 } 5164 5165 @Override 5166 public boolean clearApplicationUserData(final String packageName, 5167 final IPackageDataObserver observer, int userId) { 5168 enforceNotIsolatedCaller("clearApplicationUserData"); 5169 int uid = Binder.getCallingUid(); 5170 int pid = Binder.getCallingPid(); 5171 userId = handleIncomingUser(pid, uid, 5172 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5173 long callingId = Binder.clearCallingIdentity(); 5174 try { 5175 IPackageManager pm = AppGlobals.getPackageManager(); 5176 int pkgUid = -1; 5177 synchronized(this) { 5178 try { 5179 pkgUid = pm.getPackageUid(packageName, userId); 5180 } catch (RemoteException e) { 5181 } 5182 if (pkgUid == -1) { 5183 Slog.w(TAG, "Invalid packageName: " + packageName); 5184 if (observer != null) { 5185 try { 5186 observer.onRemoveCompleted(packageName, false); 5187 } catch (RemoteException e) { 5188 Slog.i(TAG, "Observer no longer exists."); 5189 } 5190 } 5191 return false; 5192 } 5193 if (uid == pkgUid || checkComponentPermission( 5194 android.Manifest.permission.CLEAR_APP_USER_DATA, 5195 pid, uid, -1, true) 5196 == PackageManager.PERMISSION_GRANTED) { 5197 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5198 } else { 5199 throw new SecurityException("PID " + pid + " does not have permission " 5200 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5201 + " of package " + packageName); 5202 } 5203 5204 // Remove all tasks match the cleared application package and user 5205 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5206 final TaskRecord tr = mRecentTasks.get(i); 5207 final String taskPackageName = 5208 tr.getBaseIntent().getComponent().getPackageName(); 5209 if (tr.userId != userId) continue; 5210 if (!taskPackageName.equals(packageName)) continue; 5211 removeTaskByIdLocked(tr.taskId, 0); 5212 } 5213 } 5214 5215 try { 5216 // Clear application user data 5217 pm.clearApplicationUserData(packageName, observer, userId); 5218 5219 synchronized(this) { 5220 // Remove all permissions granted from/to this package 5221 removeUriPermissionsForPackageLocked(packageName, userId, true); 5222 } 5223 5224 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5225 Uri.fromParts("package", packageName, null)); 5226 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5227 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5228 null, null, 0, null, null, null, false, false, userId); 5229 } catch (RemoteException e) { 5230 } 5231 } finally { 5232 Binder.restoreCallingIdentity(callingId); 5233 } 5234 return true; 5235 } 5236 5237 @Override 5238 public void killBackgroundProcesses(final String packageName, int userId) { 5239 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5240 != PackageManager.PERMISSION_GRANTED && 5241 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5242 != PackageManager.PERMISSION_GRANTED) { 5243 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5244 + Binder.getCallingPid() 5245 + ", uid=" + Binder.getCallingUid() 5246 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5247 Slog.w(TAG, msg); 5248 throw new SecurityException(msg); 5249 } 5250 5251 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5252 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5253 long callingId = Binder.clearCallingIdentity(); 5254 try { 5255 IPackageManager pm = AppGlobals.getPackageManager(); 5256 synchronized(this) { 5257 int appId = -1; 5258 try { 5259 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5260 } catch (RemoteException e) { 5261 } 5262 if (appId == -1) { 5263 Slog.w(TAG, "Invalid packageName: " + packageName); 5264 return; 5265 } 5266 killPackageProcessesLocked(packageName, appId, userId, 5267 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5268 } 5269 } finally { 5270 Binder.restoreCallingIdentity(callingId); 5271 } 5272 } 5273 5274 @Override 5275 public void killAllBackgroundProcesses() { 5276 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5277 != PackageManager.PERMISSION_GRANTED) { 5278 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5279 + Binder.getCallingPid() 5280 + ", uid=" + Binder.getCallingUid() 5281 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5282 Slog.w(TAG, msg); 5283 throw new SecurityException(msg); 5284 } 5285 5286 long callingId = Binder.clearCallingIdentity(); 5287 try { 5288 synchronized(this) { 5289 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5290 final int NP = mProcessNames.getMap().size(); 5291 for (int ip=0; ip<NP; ip++) { 5292 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5293 final int NA = apps.size(); 5294 for (int ia=0; ia<NA; ia++) { 5295 ProcessRecord app = apps.valueAt(ia); 5296 if (app.persistent) { 5297 // we don't kill persistent processes 5298 continue; 5299 } 5300 if (app.removed) { 5301 procs.add(app); 5302 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5303 app.removed = true; 5304 procs.add(app); 5305 } 5306 } 5307 } 5308 5309 int N = procs.size(); 5310 for (int i=0; i<N; i++) { 5311 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5312 } 5313 mAllowLowerMemLevel = true; 5314 updateOomAdjLocked(); 5315 doLowMemReportIfNeededLocked(null); 5316 } 5317 } finally { 5318 Binder.restoreCallingIdentity(callingId); 5319 } 5320 } 5321 5322 @Override 5323 public void forceStopPackage(final String packageName, int userId) { 5324 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5325 != PackageManager.PERMISSION_GRANTED) { 5326 String msg = "Permission Denial: forceStopPackage() from pid=" 5327 + Binder.getCallingPid() 5328 + ", uid=" + Binder.getCallingUid() 5329 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5330 Slog.w(TAG, msg); 5331 throw new SecurityException(msg); 5332 } 5333 final int callingPid = Binder.getCallingPid(); 5334 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5335 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5336 long callingId = Binder.clearCallingIdentity(); 5337 try { 5338 IPackageManager pm = AppGlobals.getPackageManager(); 5339 synchronized(this) { 5340 int[] users = userId == UserHandle.USER_ALL 5341 ? getUsersLocked() : new int[] { userId }; 5342 for (int user : users) { 5343 int pkgUid = -1; 5344 try { 5345 pkgUid = pm.getPackageUid(packageName, user); 5346 } catch (RemoteException e) { 5347 } 5348 if (pkgUid == -1) { 5349 Slog.w(TAG, "Invalid packageName: " + packageName); 5350 continue; 5351 } 5352 try { 5353 pm.setPackageStoppedState(packageName, true, user); 5354 } catch (RemoteException e) { 5355 } catch (IllegalArgumentException e) { 5356 Slog.w(TAG, "Failed trying to unstop package " 5357 + packageName + ": " + e); 5358 } 5359 if (isUserRunningLocked(user, false)) { 5360 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5361 } 5362 } 5363 } 5364 } finally { 5365 Binder.restoreCallingIdentity(callingId); 5366 } 5367 } 5368 5369 @Override 5370 public void addPackageDependency(String packageName) { 5371 synchronized (this) { 5372 int callingPid = Binder.getCallingPid(); 5373 if (callingPid == Process.myPid()) { 5374 // Yeah, um, no. 5375 Slog.w(TAG, "Can't addPackageDependency on system process"); 5376 return; 5377 } 5378 ProcessRecord proc; 5379 synchronized (mPidsSelfLocked) { 5380 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5381 } 5382 if (proc != null) { 5383 if (proc.pkgDeps == null) { 5384 proc.pkgDeps = new ArraySet<String>(1); 5385 } 5386 proc.pkgDeps.add(packageName); 5387 } 5388 } 5389 } 5390 5391 /* 5392 * The pkg name and app id have to be specified. 5393 */ 5394 @Override 5395 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5396 if (pkg == null) { 5397 return; 5398 } 5399 // Make sure the uid is valid. 5400 if (appid < 0) { 5401 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5402 return; 5403 } 5404 int callerUid = Binder.getCallingUid(); 5405 // Only the system server can kill an application 5406 if (callerUid == Process.SYSTEM_UID) { 5407 // Post an aysnc message to kill the application 5408 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5409 msg.arg1 = appid; 5410 msg.arg2 = 0; 5411 Bundle bundle = new Bundle(); 5412 bundle.putString("pkg", pkg); 5413 bundle.putString("reason", reason); 5414 msg.obj = bundle; 5415 mHandler.sendMessage(msg); 5416 } else { 5417 throw new SecurityException(callerUid + " cannot kill pkg: " + 5418 pkg); 5419 } 5420 } 5421 5422 @Override 5423 public void closeSystemDialogs(String reason) { 5424 enforceNotIsolatedCaller("closeSystemDialogs"); 5425 5426 final int pid = Binder.getCallingPid(); 5427 final int uid = Binder.getCallingUid(); 5428 final long origId = Binder.clearCallingIdentity(); 5429 try { 5430 synchronized (this) { 5431 // Only allow this from foreground processes, so that background 5432 // applications can't abuse it to prevent system UI from being shown. 5433 if (uid >= Process.FIRST_APPLICATION_UID) { 5434 ProcessRecord proc; 5435 synchronized (mPidsSelfLocked) { 5436 proc = mPidsSelfLocked.get(pid); 5437 } 5438 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5439 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5440 + " from background process " + proc); 5441 return; 5442 } 5443 } 5444 closeSystemDialogsLocked(reason); 5445 } 5446 } finally { 5447 Binder.restoreCallingIdentity(origId); 5448 } 5449 } 5450 5451 void closeSystemDialogsLocked(String reason) { 5452 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5453 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5454 | Intent.FLAG_RECEIVER_FOREGROUND); 5455 if (reason != null) { 5456 intent.putExtra("reason", reason); 5457 } 5458 mWindowManager.closeSystemDialogs(reason); 5459 5460 mStackSupervisor.closeSystemDialogsLocked(); 5461 5462 broadcastIntentLocked(null, null, intent, null, 5463 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5464 Process.SYSTEM_UID, UserHandle.USER_ALL); 5465 } 5466 5467 @Override 5468 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5469 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5470 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5471 for (int i=pids.length-1; i>=0; i--) { 5472 ProcessRecord proc; 5473 int oomAdj; 5474 synchronized (this) { 5475 synchronized (mPidsSelfLocked) { 5476 proc = mPidsSelfLocked.get(pids[i]); 5477 oomAdj = proc != null ? proc.setAdj : 0; 5478 } 5479 } 5480 infos[i] = new Debug.MemoryInfo(); 5481 Debug.getMemoryInfo(pids[i], infos[i]); 5482 if (proc != null) { 5483 synchronized (this) { 5484 if (proc.thread != null && proc.setAdj == oomAdj) { 5485 // Record this for posterity if the process has been stable. 5486 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5487 infos[i].getTotalUss(), false, proc.pkgList); 5488 } 5489 } 5490 } 5491 } 5492 return infos; 5493 } 5494 5495 @Override 5496 public long[] getProcessPss(int[] pids) { 5497 enforceNotIsolatedCaller("getProcessPss"); 5498 long[] pss = new long[pids.length]; 5499 for (int i=pids.length-1; i>=0; i--) { 5500 ProcessRecord proc; 5501 int oomAdj; 5502 synchronized (this) { 5503 synchronized (mPidsSelfLocked) { 5504 proc = mPidsSelfLocked.get(pids[i]); 5505 oomAdj = proc != null ? proc.setAdj : 0; 5506 } 5507 } 5508 long[] tmpUss = new long[1]; 5509 pss[i] = Debug.getPss(pids[i], tmpUss); 5510 if (proc != null) { 5511 synchronized (this) { 5512 if (proc.thread != null && proc.setAdj == oomAdj) { 5513 // Record this for posterity if the process has been stable. 5514 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5515 } 5516 } 5517 } 5518 } 5519 return pss; 5520 } 5521 5522 @Override 5523 public void killApplicationProcess(String processName, int uid) { 5524 if (processName == null) { 5525 return; 5526 } 5527 5528 int callerUid = Binder.getCallingUid(); 5529 // Only the system server can kill an application 5530 if (callerUid == Process.SYSTEM_UID) { 5531 synchronized (this) { 5532 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5533 if (app != null && app.thread != null) { 5534 try { 5535 app.thread.scheduleSuicide(); 5536 } catch (RemoteException e) { 5537 // If the other end already died, then our work here is done. 5538 } 5539 } else { 5540 Slog.w(TAG, "Process/uid not found attempting kill of " 5541 + processName + " / " + uid); 5542 } 5543 } 5544 } else { 5545 throw new SecurityException(callerUid + " cannot kill app process: " + 5546 processName); 5547 } 5548 } 5549 5550 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5551 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5552 false, true, false, false, UserHandle.getUserId(uid), reason); 5553 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5554 Uri.fromParts("package", packageName, null)); 5555 if (!mProcessesReady) { 5556 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5557 | Intent.FLAG_RECEIVER_FOREGROUND); 5558 } 5559 intent.putExtra(Intent.EXTRA_UID, uid); 5560 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5561 broadcastIntentLocked(null, null, intent, 5562 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5563 false, false, 5564 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5565 } 5566 5567 private void forceStopUserLocked(int userId, String reason) { 5568 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5569 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5570 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5571 | Intent.FLAG_RECEIVER_FOREGROUND); 5572 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5573 broadcastIntentLocked(null, null, intent, 5574 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5575 false, false, 5576 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5577 } 5578 5579 private final boolean killPackageProcessesLocked(String packageName, int appId, 5580 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5581 boolean doit, boolean evenPersistent, String reason) { 5582 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5583 5584 // Remove all processes this package may have touched: all with the 5585 // same UID (except for the system or root user), and all whose name 5586 // matches the package name. 5587 final int NP = mProcessNames.getMap().size(); 5588 for (int ip=0; ip<NP; ip++) { 5589 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5590 final int NA = apps.size(); 5591 for (int ia=0; ia<NA; ia++) { 5592 ProcessRecord app = apps.valueAt(ia); 5593 if (app.persistent && !evenPersistent) { 5594 // we don't kill persistent processes 5595 continue; 5596 } 5597 if (app.removed) { 5598 if (doit) { 5599 procs.add(app); 5600 } 5601 continue; 5602 } 5603 5604 // Skip process if it doesn't meet our oom adj requirement. 5605 if (app.setAdj < minOomAdj) { 5606 continue; 5607 } 5608 5609 // If no package is specified, we call all processes under the 5610 // give user id. 5611 if (packageName == null) { 5612 if (app.userId != userId) { 5613 continue; 5614 } 5615 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5616 continue; 5617 } 5618 // Package has been specified, we want to hit all processes 5619 // that match it. We need to qualify this by the processes 5620 // that are running under the specified app and user ID. 5621 } else { 5622 final boolean isDep = app.pkgDeps != null 5623 && app.pkgDeps.contains(packageName); 5624 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5625 continue; 5626 } 5627 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5628 continue; 5629 } 5630 if (!app.pkgList.containsKey(packageName) && !isDep) { 5631 continue; 5632 } 5633 } 5634 5635 // Process has passed all conditions, kill it! 5636 if (!doit) { 5637 return true; 5638 } 5639 app.removed = true; 5640 procs.add(app); 5641 } 5642 } 5643 5644 int N = procs.size(); 5645 for (int i=0; i<N; i++) { 5646 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5647 } 5648 updateOomAdjLocked(); 5649 return N > 0; 5650 } 5651 5652 private final boolean forceStopPackageLocked(String name, int appId, 5653 boolean callerWillRestart, boolean purgeCache, boolean doit, 5654 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5655 int i; 5656 int N; 5657 5658 if (userId == UserHandle.USER_ALL && name == null) { 5659 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5660 } 5661 5662 if (appId < 0 && name != null) { 5663 try { 5664 appId = UserHandle.getAppId( 5665 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5666 } catch (RemoteException e) { 5667 } 5668 } 5669 5670 if (doit) { 5671 if (name != null) { 5672 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5673 + " user=" + userId + ": " + reason); 5674 } else { 5675 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5676 } 5677 5678 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5679 for (int ip=pmap.size()-1; ip>=0; ip--) { 5680 SparseArray<Long> ba = pmap.valueAt(ip); 5681 for (i=ba.size()-1; i>=0; i--) { 5682 boolean remove = false; 5683 final int entUid = ba.keyAt(i); 5684 if (name != null) { 5685 if (userId == UserHandle.USER_ALL) { 5686 if (UserHandle.getAppId(entUid) == appId) { 5687 remove = true; 5688 } 5689 } else { 5690 if (entUid == UserHandle.getUid(userId, appId)) { 5691 remove = true; 5692 } 5693 } 5694 } else if (UserHandle.getUserId(entUid) == userId) { 5695 remove = true; 5696 } 5697 if (remove) { 5698 ba.removeAt(i); 5699 } 5700 } 5701 if (ba.size() == 0) { 5702 pmap.removeAt(ip); 5703 } 5704 } 5705 } 5706 5707 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5708 -100, callerWillRestart, true, doit, evenPersistent, 5709 name == null ? ("stop user " + userId) : ("stop " + name)); 5710 5711 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5712 if (!doit) { 5713 return true; 5714 } 5715 didSomething = true; 5716 } 5717 5718 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5719 if (!doit) { 5720 return true; 5721 } 5722 didSomething = true; 5723 } 5724 5725 if (name == null) { 5726 // Remove all sticky broadcasts from this user. 5727 mStickyBroadcasts.remove(userId); 5728 } 5729 5730 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5731 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5732 userId, providers)) { 5733 if (!doit) { 5734 return true; 5735 } 5736 didSomething = true; 5737 } 5738 N = providers.size(); 5739 for (i=0; i<N; i++) { 5740 removeDyingProviderLocked(null, providers.get(i), true); 5741 } 5742 5743 // Remove transient permissions granted from/to this package/user 5744 removeUriPermissionsForPackageLocked(name, userId, false); 5745 5746 if (name == null || uninstalling) { 5747 // Remove pending intents. For now we only do this when force 5748 // stopping users, because we have some problems when doing this 5749 // for packages -- app widgets are not currently cleaned up for 5750 // such packages, so they can be left with bad pending intents. 5751 if (mIntentSenderRecords.size() > 0) { 5752 Iterator<WeakReference<PendingIntentRecord>> it 5753 = mIntentSenderRecords.values().iterator(); 5754 while (it.hasNext()) { 5755 WeakReference<PendingIntentRecord> wpir = it.next(); 5756 if (wpir == null) { 5757 it.remove(); 5758 continue; 5759 } 5760 PendingIntentRecord pir = wpir.get(); 5761 if (pir == null) { 5762 it.remove(); 5763 continue; 5764 } 5765 if (name == null) { 5766 // Stopping user, remove all objects for the user. 5767 if (pir.key.userId != userId) { 5768 // Not the same user, skip it. 5769 continue; 5770 } 5771 } else { 5772 if (UserHandle.getAppId(pir.uid) != appId) { 5773 // Different app id, skip it. 5774 continue; 5775 } 5776 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5777 // Different user, skip it. 5778 continue; 5779 } 5780 if (!pir.key.packageName.equals(name)) { 5781 // Different package, skip it. 5782 continue; 5783 } 5784 } 5785 if (!doit) { 5786 return true; 5787 } 5788 didSomething = true; 5789 it.remove(); 5790 pir.canceled = true; 5791 if (pir.key.activity != null) { 5792 pir.key.activity.pendingResults.remove(pir.ref); 5793 } 5794 } 5795 } 5796 } 5797 5798 if (doit) { 5799 if (purgeCache && name != null) { 5800 AttributeCache ac = AttributeCache.instance(); 5801 if (ac != null) { 5802 ac.removePackage(name); 5803 } 5804 } 5805 if (mBooted) { 5806 mStackSupervisor.resumeTopActivitiesLocked(); 5807 mStackSupervisor.scheduleIdleLocked(); 5808 } 5809 } 5810 5811 return didSomething; 5812 } 5813 5814 private final boolean removeProcessLocked(ProcessRecord app, 5815 boolean callerWillRestart, boolean allowRestart, String reason) { 5816 final String name = app.processName; 5817 final int uid = app.uid; 5818 if (DEBUG_PROCESSES) Slog.d( 5819 TAG, "Force removing proc " + app.toShortString() + " (" + name 5820 + "/" + uid + ")"); 5821 5822 mProcessNames.remove(name, uid); 5823 mIsolatedProcesses.remove(app.uid); 5824 if (mHeavyWeightProcess == app) { 5825 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5826 mHeavyWeightProcess.userId, 0)); 5827 mHeavyWeightProcess = null; 5828 } 5829 boolean needRestart = false; 5830 if (app.pid > 0 && app.pid != MY_PID) { 5831 int pid = app.pid; 5832 synchronized (mPidsSelfLocked) { 5833 mPidsSelfLocked.remove(pid); 5834 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5835 } 5836 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5837 if (app.isolated) { 5838 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5839 } 5840 app.kill(reason, true); 5841 handleAppDiedLocked(app, true, allowRestart); 5842 removeLruProcessLocked(app); 5843 5844 if (app.persistent && !app.isolated) { 5845 if (!callerWillRestart) { 5846 addAppLocked(app.info, false, null /* ABI override */); 5847 } else { 5848 needRestart = true; 5849 } 5850 } 5851 } else { 5852 mRemovedProcesses.add(app); 5853 } 5854 5855 return needRestart; 5856 } 5857 5858 private final void processStartTimedOutLocked(ProcessRecord app) { 5859 final int pid = app.pid; 5860 boolean gone = false; 5861 synchronized (mPidsSelfLocked) { 5862 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5863 if (knownApp != null && knownApp.thread == null) { 5864 mPidsSelfLocked.remove(pid); 5865 gone = true; 5866 } 5867 } 5868 5869 if (gone) { 5870 Slog.w(TAG, "Process " + app + " failed to attach"); 5871 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5872 pid, app.uid, app.processName); 5873 mProcessNames.remove(app.processName, app.uid); 5874 mIsolatedProcesses.remove(app.uid); 5875 if (mHeavyWeightProcess == app) { 5876 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5877 mHeavyWeightProcess.userId, 0)); 5878 mHeavyWeightProcess = null; 5879 } 5880 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5881 if (app.isolated) { 5882 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5883 } 5884 // Take care of any launching providers waiting for this process. 5885 checkAppInLaunchingProvidersLocked(app, true); 5886 // Take care of any services that are waiting for the process. 5887 mServices.processStartTimedOutLocked(app); 5888 app.kill("start timeout", true); 5889 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5890 Slog.w(TAG, "Unattached app died before backup, skipping"); 5891 try { 5892 IBackupManager bm = IBackupManager.Stub.asInterface( 5893 ServiceManager.getService(Context.BACKUP_SERVICE)); 5894 bm.agentDisconnected(app.info.packageName); 5895 } catch (RemoteException e) { 5896 // Can't happen; the backup manager is local 5897 } 5898 } 5899 if (isPendingBroadcastProcessLocked(pid)) { 5900 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5901 skipPendingBroadcastLocked(pid); 5902 } 5903 } else { 5904 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5905 } 5906 } 5907 5908 private final boolean attachApplicationLocked(IApplicationThread thread, 5909 int pid) { 5910 5911 // Find the application record that is being attached... either via 5912 // the pid if we are running in multiple processes, or just pull the 5913 // next app record if we are emulating process with anonymous threads. 5914 ProcessRecord app; 5915 if (pid != MY_PID && pid >= 0) { 5916 synchronized (mPidsSelfLocked) { 5917 app = mPidsSelfLocked.get(pid); 5918 } 5919 } else { 5920 app = null; 5921 } 5922 5923 if (app == null) { 5924 Slog.w(TAG, "No pending application record for pid " + pid 5925 + " (IApplicationThread " + thread + "); dropping process"); 5926 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5927 if (pid > 0 && pid != MY_PID) { 5928 Process.killProcessQuiet(pid); 5929 //TODO: Process.killProcessGroup(app.info.uid, pid); 5930 } else { 5931 try { 5932 thread.scheduleExit(); 5933 } catch (Exception e) { 5934 // Ignore exceptions. 5935 } 5936 } 5937 return false; 5938 } 5939 5940 // If this application record is still attached to a previous 5941 // process, clean it up now. 5942 if (app.thread != null) { 5943 handleAppDiedLocked(app, true, true); 5944 } 5945 5946 // Tell the process all about itself. 5947 5948 if (localLOGV) Slog.v( 5949 TAG, "Binding process pid " + pid + " to record " + app); 5950 5951 final String processName = app.processName; 5952 try { 5953 AppDeathRecipient adr = new AppDeathRecipient( 5954 app, pid, thread); 5955 thread.asBinder().linkToDeath(adr, 0); 5956 app.deathRecipient = adr; 5957 } catch (RemoteException e) { 5958 app.resetPackageList(mProcessStats); 5959 startProcessLocked(app, "link fail", processName); 5960 return false; 5961 } 5962 5963 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5964 5965 app.makeActive(thread, mProcessStats); 5966 app.curAdj = app.setAdj = -100; 5967 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5968 app.forcingToForeground = null; 5969 updateProcessForegroundLocked(app, false, false); 5970 app.hasShownUi = false; 5971 app.debugging = false; 5972 app.cached = false; 5973 5974 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5975 5976 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5977 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5978 5979 if (!normalMode) { 5980 Slog.i(TAG, "Launching preboot mode app: " + app); 5981 } 5982 5983 if (localLOGV) Slog.v( 5984 TAG, "New app record " + app 5985 + " thread=" + thread.asBinder() + " pid=" + pid); 5986 try { 5987 int testMode = IApplicationThread.DEBUG_OFF; 5988 if (mDebugApp != null && mDebugApp.equals(processName)) { 5989 testMode = mWaitForDebugger 5990 ? IApplicationThread.DEBUG_WAIT 5991 : IApplicationThread.DEBUG_ON; 5992 app.debugging = true; 5993 if (mDebugTransient) { 5994 mDebugApp = mOrigDebugApp; 5995 mWaitForDebugger = mOrigWaitForDebugger; 5996 } 5997 } 5998 String profileFile = app.instrumentationProfileFile; 5999 ParcelFileDescriptor profileFd = null; 6000 int samplingInterval = 0; 6001 boolean profileAutoStop = false; 6002 if (mProfileApp != null && mProfileApp.equals(processName)) { 6003 mProfileProc = app; 6004 profileFile = mProfileFile; 6005 profileFd = mProfileFd; 6006 samplingInterval = mSamplingInterval; 6007 profileAutoStop = mAutoStopProfiler; 6008 } 6009 boolean enableOpenGlTrace = false; 6010 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6011 enableOpenGlTrace = true; 6012 mOpenGlTraceApp = null; 6013 } 6014 6015 // If the app is being launched for restore or full backup, set it up specially 6016 boolean isRestrictedBackupMode = false; 6017 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6018 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6019 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6020 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6021 } 6022 6023 ensurePackageDexOpt(app.instrumentationInfo != null 6024 ? app.instrumentationInfo.packageName 6025 : app.info.packageName); 6026 if (app.instrumentationClass != null) { 6027 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6028 } 6029 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6030 + processName + " with config " + mConfiguration); 6031 ApplicationInfo appInfo = app.instrumentationInfo != null 6032 ? app.instrumentationInfo : app.info; 6033 app.compat = compatibilityInfoForPackageLocked(appInfo); 6034 if (profileFd != null) { 6035 profileFd = profileFd.dup(); 6036 } 6037 ProfilerInfo profilerInfo = profileFile == null ? null 6038 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6039 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6040 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6041 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6042 isRestrictedBackupMode || !normalMode, app.persistent, 6043 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6044 mCoreSettingsObserver.getCoreSettingsLocked()); 6045 updateLruProcessLocked(app, false, null); 6046 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6047 } catch (Exception e) { 6048 // todo: Yikes! What should we do? For now we will try to 6049 // start another process, but that could easily get us in 6050 // an infinite loop of restarting processes... 6051 Slog.w(TAG, "Exception thrown during bind!", e); 6052 6053 app.resetPackageList(mProcessStats); 6054 app.unlinkDeathRecipient(); 6055 startProcessLocked(app, "bind fail", processName); 6056 return false; 6057 } 6058 6059 // Remove this record from the list of starting applications. 6060 mPersistentStartingProcesses.remove(app); 6061 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6062 "Attach application locked removing on hold: " + app); 6063 mProcessesOnHold.remove(app); 6064 6065 boolean badApp = false; 6066 boolean didSomething = false; 6067 6068 // See if the top visible activity is waiting to run in this process... 6069 if (normalMode) { 6070 try { 6071 if (mStackSupervisor.attachApplicationLocked(app)) { 6072 didSomething = true; 6073 } 6074 } catch (Exception e) { 6075 badApp = true; 6076 } 6077 } 6078 6079 // Find any services that should be running in this process... 6080 if (!badApp) { 6081 try { 6082 didSomething |= mServices.attachApplicationLocked(app, processName); 6083 } catch (Exception e) { 6084 badApp = true; 6085 } 6086 } 6087 6088 // Check if a next-broadcast receiver is in this process... 6089 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6090 try { 6091 didSomething |= sendPendingBroadcastsLocked(app); 6092 } catch (Exception e) { 6093 // If the app died trying to launch the receiver we declare it 'bad' 6094 badApp = true; 6095 } 6096 } 6097 6098 // Check whether the next backup agent is in this process... 6099 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6100 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6101 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6102 try { 6103 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6104 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6105 mBackupTarget.backupMode); 6106 } catch (Exception e) { 6107 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6108 e.printStackTrace(); 6109 } 6110 } 6111 6112 if (badApp) { 6113 // todo: Also need to kill application to deal with all 6114 // kinds of exceptions. 6115 handleAppDiedLocked(app, false, true); 6116 return false; 6117 } 6118 6119 if (!didSomething) { 6120 updateOomAdjLocked(); 6121 } 6122 6123 return true; 6124 } 6125 6126 @Override 6127 public final void attachApplication(IApplicationThread thread) { 6128 synchronized (this) { 6129 int callingPid = Binder.getCallingPid(); 6130 final long origId = Binder.clearCallingIdentity(); 6131 attachApplicationLocked(thread, callingPid); 6132 Binder.restoreCallingIdentity(origId); 6133 } 6134 } 6135 6136 @Override 6137 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6138 final long origId = Binder.clearCallingIdentity(); 6139 synchronized (this) { 6140 ActivityStack stack = ActivityRecord.getStackLocked(token); 6141 if (stack != null) { 6142 ActivityRecord r = 6143 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6144 if (stopProfiling) { 6145 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6146 try { 6147 mProfileFd.close(); 6148 } catch (IOException e) { 6149 } 6150 clearProfilerLocked(); 6151 } 6152 } 6153 } 6154 } 6155 Binder.restoreCallingIdentity(origId); 6156 } 6157 6158 void postEnableScreenAfterBootLocked() { 6159 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6160 } 6161 6162 void enableScreenAfterBoot() { 6163 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6164 SystemClock.uptimeMillis()); 6165 mWindowManager.enableScreenAfterBoot(); 6166 6167 synchronized (this) { 6168 updateEventDispatchingLocked(); 6169 } 6170 } 6171 6172 @Override 6173 public void showBootMessage(final CharSequence msg, final boolean always) { 6174 enforceNotIsolatedCaller("showBootMessage"); 6175 mWindowManager.showBootMessage(msg, always); 6176 } 6177 6178 @Override 6179 public void keyguardWaitingForActivityDrawn() { 6180 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6181 final long token = Binder.clearCallingIdentity(); 6182 try { 6183 synchronized (this) { 6184 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6185 mWindowManager.keyguardWaitingForActivityDrawn(); 6186 } 6187 } finally { 6188 Binder.restoreCallingIdentity(token); 6189 } 6190 } 6191 6192 final void finishBooting() { 6193 // Register receivers to handle package update events 6194 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6195 6196 // Let system services know. 6197 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6198 6199 synchronized (this) { 6200 // Ensure that any processes we had put on hold are now started 6201 // up. 6202 final int NP = mProcessesOnHold.size(); 6203 if (NP > 0) { 6204 ArrayList<ProcessRecord> procs = 6205 new ArrayList<ProcessRecord>(mProcessesOnHold); 6206 for (int ip=0; ip<NP; ip++) { 6207 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6208 + procs.get(ip)); 6209 startProcessLocked(procs.get(ip), "on-hold", null); 6210 } 6211 } 6212 6213 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6214 // Start looking for apps that are abusing wake locks. 6215 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6216 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6217 // Tell anyone interested that we are done booting! 6218 SystemProperties.set("sys.boot_completed", "1"); 6219 SystemProperties.set("dev.bootcomplete", "1"); 6220 for (int i=0; i<mStartedUsers.size(); i++) { 6221 UserStartedState uss = mStartedUsers.valueAt(i); 6222 if (uss.mState == UserStartedState.STATE_BOOTING) { 6223 uss.mState = UserStartedState.STATE_RUNNING; 6224 final int userId = mStartedUsers.keyAt(i); 6225 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6226 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6227 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6228 broadcastIntentLocked(null, null, intent, null, 6229 new IIntentReceiver.Stub() { 6230 @Override 6231 public void performReceive(Intent intent, int resultCode, 6232 String data, Bundle extras, boolean ordered, 6233 boolean sticky, int sendingUser) { 6234 synchronized (ActivityManagerService.this) { 6235 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6236 true, false); 6237 } 6238 } 6239 }, 6240 0, null, null, 6241 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6242 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6243 userId); 6244 } 6245 } 6246 scheduleStartProfilesLocked(); 6247 } 6248 } 6249 } 6250 6251 final void ensureBootCompleted() { 6252 boolean booting; 6253 boolean enableScreen; 6254 synchronized (this) { 6255 booting = mBooting; 6256 mBooting = false; 6257 enableScreen = !mBooted; 6258 mBooted = true; 6259 } 6260 6261 if (booting) { 6262 finishBooting(); 6263 } 6264 6265 if (enableScreen) { 6266 enableScreenAfterBoot(); 6267 } 6268 } 6269 6270 @Override 6271 public final void activityResumed(IBinder token) { 6272 final long origId = Binder.clearCallingIdentity(); 6273 synchronized(this) { 6274 ActivityStack stack = ActivityRecord.getStackLocked(token); 6275 if (stack != null) { 6276 ActivityRecord.activityResumedLocked(token); 6277 } 6278 } 6279 Binder.restoreCallingIdentity(origId); 6280 } 6281 6282 @Override 6283 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6284 final long origId = Binder.clearCallingIdentity(); 6285 synchronized(this) { 6286 ActivityStack stack = ActivityRecord.getStackLocked(token); 6287 if (stack != null) { 6288 stack.activityPausedLocked(token, false, persistentState); 6289 } 6290 } 6291 Binder.restoreCallingIdentity(origId); 6292 } 6293 6294 @Override 6295 public final void activityStopped(IBinder token, Bundle icicle, 6296 PersistableBundle persistentState, CharSequence description) { 6297 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6298 6299 // Refuse possible leaked file descriptors 6300 if (icicle != null && icicle.hasFileDescriptors()) { 6301 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6302 } 6303 6304 final long origId = Binder.clearCallingIdentity(); 6305 6306 synchronized (this) { 6307 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6308 if (r != null) { 6309 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6310 } 6311 } 6312 6313 trimApplications(); 6314 6315 Binder.restoreCallingIdentity(origId); 6316 } 6317 6318 @Override 6319 public final void activityDestroyed(IBinder token) { 6320 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6321 synchronized (this) { 6322 ActivityStack stack = ActivityRecord.getStackLocked(token); 6323 if (stack != null) { 6324 stack.activityDestroyedLocked(token); 6325 } 6326 } 6327 } 6328 6329 @Override 6330 public final void backgroundResourcesReleased(IBinder token) { 6331 final long origId = Binder.clearCallingIdentity(); 6332 try { 6333 synchronized (this) { 6334 ActivityStack stack = ActivityRecord.getStackLocked(token); 6335 if (stack != null) { 6336 stack.backgroundResourcesReleased(token); 6337 } 6338 } 6339 } finally { 6340 Binder.restoreCallingIdentity(origId); 6341 } 6342 } 6343 6344 @Override 6345 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6346 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6347 } 6348 6349 @Override 6350 public final void notifyEnterAnimationComplete(IBinder token) { 6351 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6352 } 6353 6354 @Override 6355 public String getCallingPackage(IBinder token) { 6356 synchronized (this) { 6357 ActivityRecord r = getCallingRecordLocked(token); 6358 return r != null ? r.info.packageName : null; 6359 } 6360 } 6361 6362 @Override 6363 public ComponentName getCallingActivity(IBinder token) { 6364 synchronized (this) { 6365 ActivityRecord r = getCallingRecordLocked(token); 6366 return r != null ? r.intent.getComponent() : null; 6367 } 6368 } 6369 6370 private ActivityRecord getCallingRecordLocked(IBinder token) { 6371 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6372 if (r == null) { 6373 return null; 6374 } 6375 return r.resultTo; 6376 } 6377 6378 @Override 6379 public ComponentName getActivityClassForToken(IBinder token) { 6380 synchronized(this) { 6381 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6382 if (r == null) { 6383 return null; 6384 } 6385 return r.intent.getComponent(); 6386 } 6387 } 6388 6389 @Override 6390 public String getPackageForToken(IBinder token) { 6391 synchronized(this) { 6392 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6393 if (r == null) { 6394 return null; 6395 } 6396 return r.packageName; 6397 } 6398 } 6399 6400 @Override 6401 public IIntentSender getIntentSender(int type, 6402 String packageName, IBinder token, String resultWho, 6403 int requestCode, Intent[] intents, String[] resolvedTypes, 6404 int flags, Bundle options, int userId) { 6405 enforceNotIsolatedCaller("getIntentSender"); 6406 // Refuse possible leaked file descriptors 6407 if (intents != null) { 6408 if (intents.length < 1) { 6409 throw new IllegalArgumentException("Intents array length must be >= 1"); 6410 } 6411 for (int i=0; i<intents.length; i++) { 6412 Intent intent = intents[i]; 6413 if (intent != null) { 6414 if (intent.hasFileDescriptors()) { 6415 throw new IllegalArgumentException("File descriptors passed in Intent"); 6416 } 6417 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6418 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6419 throw new IllegalArgumentException( 6420 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6421 } 6422 intents[i] = new Intent(intent); 6423 } 6424 } 6425 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6426 throw new IllegalArgumentException( 6427 "Intent array length does not match resolvedTypes length"); 6428 } 6429 } 6430 if (options != null) { 6431 if (options.hasFileDescriptors()) { 6432 throw new IllegalArgumentException("File descriptors passed in options"); 6433 } 6434 } 6435 6436 synchronized(this) { 6437 int callingUid = Binder.getCallingUid(); 6438 int origUserId = userId; 6439 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6440 type == ActivityManager.INTENT_SENDER_BROADCAST, 6441 ALLOW_NON_FULL, "getIntentSender", null); 6442 if (origUserId == UserHandle.USER_CURRENT) { 6443 // We don't want to evaluate this until the pending intent is 6444 // actually executed. However, we do want to always do the 6445 // security checking for it above. 6446 userId = UserHandle.USER_CURRENT; 6447 } 6448 try { 6449 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6450 int uid = AppGlobals.getPackageManager() 6451 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6452 if (!UserHandle.isSameApp(callingUid, uid)) { 6453 String msg = "Permission Denial: getIntentSender() from pid=" 6454 + Binder.getCallingPid() 6455 + ", uid=" + Binder.getCallingUid() 6456 + ", (need uid=" + uid + ")" 6457 + " is not allowed to send as package " + packageName; 6458 Slog.w(TAG, msg); 6459 throw new SecurityException(msg); 6460 } 6461 } 6462 6463 return getIntentSenderLocked(type, packageName, callingUid, userId, 6464 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6465 6466 } catch (RemoteException e) { 6467 throw new SecurityException(e); 6468 } 6469 } 6470 } 6471 6472 IIntentSender getIntentSenderLocked(int type, String packageName, 6473 int callingUid, int userId, IBinder token, String resultWho, 6474 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6475 Bundle options) { 6476 if (DEBUG_MU) 6477 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6478 ActivityRecord activity = null; 6479 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6480 activity = ActivityRecord.isInStackLocked(token); 6481 if (activity == null) { 6482 return null; 6483 } 6484 if (activity.finishing) { 6485 return null; 6486 } 6487 } 6488 6489 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6490 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6491 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6492 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6493 |PendingIntent.FLAG_UPDATE_CURRENT); 6494 6495 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6496 type, packageName, activity, resultWho, 6497 requestCode, intents, resolvedTypes, flags, options, userId); 6498 WeakReference<PendingIntentRecord> ref; 6499 ref = mIntentSenderRecords.get(key); 6500 PendingIntentRecord rec = ref != null ? ref.get() : null; 6501 if (rec != null) { 6502 if (!cancelCurrent) { 6503 if (updateCurrent) { 6504 if (rec.key.requestIntent != null) { 6505 rec.key.requestIntent.replaceExtras(intents != null ? 6506 intents[intents.length - 1] : null); 6507 } 6508 if (intents != null) { 6509 intents[intents.length-1] = rec.key.requestIntent; 6510 rec.key.allIntents = intents; 6511 rec.key.allResolvedTypes = resolvedTypes; 6512 } else { 6513 rec.key.allIntents = null; 6514 rec.key.allResolvedTypes = null; 6515 } 6516 } 6517 return rec; 6518 } 6519 rec.canceled = true; 6520 mIntentSenderRecords.remove(key); 6521 } 6522 if (noCreate) { 6523 return rec; 6524 } 6525 rec = new PendingIntentRecord(this, key, callingUid); 6526 mIntentSenderRecords.put(key, rec.ref); 6527 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6528 if (activity.pendingResults == null) { 6529 activity.pendingResults 6530 = new HashSet<WeakReference<PendingIntentRecord>>(); 6531 } 6532 activity.pendingResults.add(rec.ref); 6533 } 6534 return rec; 6535 } 6536 6537 @Override 6538 public void cancelIntentSender(IIntentSender sender) { 6539 if (!(sender instanceof PendingIntentRecord)) { 6540 return; 6541 } 6542 synchronized(this) { 6543 PendingIntentRecord rec = (PendingIntentRecord)sender; 6544 try { 6545 int uid = AppGlobals.getPackageManager() 6546 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6547 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6548 String msg = "Permission Denial: cancelIntentSender() from pid=" 6549 + Binder.getCallingPid() 6550 + ", uid=" + Binder.getCallingUid() 6551 + " is not allowed to cancel packges " 6552 + rec.key.packageName; 6553 Slog.w(TAG, msg); 6554 throw new SecurityException(msg); 6555 } 6556 } catch (RemoteException e) { 6557 throw new SecurityException(e); 6558 } 6559 cancelIntentSenderLocked(rec, true); 6560 } 6561 } 6562 6563 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6564 rec.canceled = true; 6565 mIntentSenderRecords.remove(rec.key); 6566 if (cleanActivity && rec.key.activity != null) { 6567 rec.key.activity.pendingResults.remove(rec.ref); 6568 } 6569 } 6570 6571 @Override 6572 public String getPackageForIntentSender(IIntentSender pendingResult) { 6573 if (!(pendingResult instanceof PendingIntentRecord)) { 6574 return null; 6575 } 6576 try { 6577 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6578 return res.key.packageName; 6579 } catch (ClassCastException e) { 6580 } 6581 return null; 6582 } 6583 6584 @Override 6585 public int getUidForIntentSender(IIntentSender sender) { 6586 if (sender instanceof PendingIntentRecord) { 6587 try { 6588 PendingIntentRecord res = (PendingIntentRecord)sender; 6589 return res.uid; 6590 } catch (ClassCastException e) { 6591 } 6592 } 6593 return -1; 6594 } 6595 6596 @Override 6597 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6598 if (!(pendingResult instanceof PendingIntentRecord)) { 6599 return false; 6600 } 6601 try { 6602 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6603 if (res.key.allIntents == null) { 6604 return false; 6605 } 6606 for (int i=0; i<res.key.allIntents.length; i++) { 6607 Intent intent = res.key.allIntents[i]; 6608 if (intent.getPackage() != null && intent.getComponent() != null) { 6609 return false; 6610 } 6611 } 6612 return true; 6613 } catch (ClassCastException e) { 6614 } 6615 return false; 6616 } 6617 6618 @Override 6619 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6620 if (!(pendingResult instanceof PendingIntentRecord)) { 6621 return false; 6622 } 6623 try { 6624 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6625 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6626 return true; 6627 } 6628 return false; 6629 } catch (ClassCastException e) { 6630 } 6631 return false; 6632 } 6633 6634 @Override 6635 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6636 if (!(pendingResult instanceof PendingIntentRecord)) { 6637 return null; 6638 } 6639 try { 6640 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6641 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6642 } catch (ClassCastException e) { 6643 } 6644 return null; 6645 } 6646 6647 @Override 6648 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6649 if (!(pendingResult instanceof PendingIntentRecord)) { 6650 return null; 6651 } 6652 try { 6653 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6654 Intent intent = res.key.requestIntent; 6655 if (intent != null) { 6656 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6657 || res.lastTagPrefix.equals(prefix))) { 6658 return res.lastTag; 6659 } 6660 res.lastTagPrefix = prefix; 6661 StringBuilder sb = new StringBuilder(128); 6662 if (prefix != null) { 6663 sb.append(prefix); 6664 } 6665 if (intent.getAction() != null) { 6666 sb.append(intent.getAction()); 6667 } else if (intent.getComponent() != null) { 6668 intent.getComponent().appendShortString(sb); 6669 } else { 6670 sb.append("?"); 6671 } 6672 return res.lastTag = sb.toString(); 6673 } 6674 } catch (ClassCastException e) { 6675 } 6676 return null; 6677 } 6678 6679 @Override 6680 public void setProcessLimit(int max) { 6681 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6682 "setProcessLimit()"); 6683 synchronized (this) { 6684 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6685 mProcessLimitOverride = max; 6686 } 6687 trimApplications(); 6688 } 6689 6690 @Override 6691 public int getProcessLimit() { 6692 synchronized (this) { 6693 return mProcessLimitOverride; 6694 } 6695 } 6696 6697 void foregroundTokenDied(ForegroundToken token) { 6698 synchronized (ActivityManagerService.this) { 6699 synchronized (mPidsSelfLocked) { 6700 ForegroundToken cur 6701 = mForegroundProcesses.get(token.pid); 6702 if (cur != token) { 6703 return; 6704 } 6705 mForegroundProcesses.remove(token.pid); 6706 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6707 if (pr == null) { 6708 return; 6709 } 6710 pr.forcingToForeground = null; 6711 updateProcessForegroundLocked(pr, false, false); 6712 } 6713 updateOomAdjLocked(); 6714 } 6715 } 6716 6717 @Override 6718 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6719 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6720 "setProcessForeground()"); 6721 synchronized(this) { 6722 boolean changed = false; 6723 6724 synchronized (mPidsSelfLocked) { 6725 ProcessRecord pr = mPidsSelfLocked.get(pid); 6726 if (pr == null && isForeground) { 6727 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6728 return; 6729 } 6730 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6731 if (oldToken != null) { 6732 oldToken.token.unlinkToDeath(oldToken, 0); 6733 mForegroundProcesses.remove(pid); 6734 if (pr != null) { 6735 pr.forcingToForeground = null; 6736 } 6737 changed = true; 6738 } 6739 if (isForeground && token != null) { 6740 ForegroundToken newToken = new ForegroundToken() { 6741 @Override 6742 public void binderDied() { 6743 foregroundTokenDied(this); 6744 } 6745 }; 6746 newToken.pid = pid; 6747 newToken.token = token; 6748 try { 6749 token.linkToDeath(newToken, 0); 6750 mForegroundProcesses.put(pid, newToken); 6751 pr.forcingToForeground = token; 6752 changed = true; 6753 } catch (RemoteException e) { 6754 // If the process died while doing this, we will later 6755 // do the cleanup with the process death link. 6756 } 6757 } 6758 } 6759 6760 if (changed) { 6761 updateOomAdjLocked(); 6762 } 6763 } 6764 } 6765 6766 // ========================================================= 6767 // PERMISSIONS 6768 // ========================================================= 6769 6770 static class PermissionController extends IPermissionController.Stub { 6771 ActivityManagerService mActivityManagerService; 6772 PermissionController(ActivityManagerService activityManagerService) { 6773 mActivityManagerService = activityManagerService; 6774 } 6775 6776 @Override 6777 public boolean checkPermission(String permission, int pid, int uid) { 6778 return mActivityManagerService.checkPermission(permission, pid, 6779 uid) == PackageManager.PERMISSION_GRANTED; 6780 } 6781 } 6782 6783 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6784 @Override 6785 public int checkComponentPermission(String permission, int pid, int uid, 6786 int owningUid, boolean exported) { 6787 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6788 owningUid, exported); 6789 } 6790 6791 @Override 6792 public Object getAMSLock() { 6793 return ActivityManagerService.this; 6794 } 6795 } 6796 6797 /** 6798 * This can be called with or without the global lock held. 6799 */ 6800 int checkComponentPermission(String permission, int pid, int uid, 6801 int owningUid, boolean exported) { 6802 // We might be performing an operation on behalf of an indirect binder 6803 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6804 // client identity accordingly before proceeding. 6805 Identity tlsIdentity = sCallerIdentity.get(); 6806 if (tlsIdentity != null) { 6807 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6808 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6809 uid = tlsIdentity.uid; 6810 pid = tlsIdentity.pid; 6811 } 6812 6813 if (pid == MY_PID) { 6814 return PackageManager.PERMISSION_GRANTED; 6815 } 6816 6817 return ActivityManager.checkComponentPermission(permission, uid, 6818 owningUid, exported); 6819 } 6820 6821 /** 6822 * As the only public entry point for permissions checking, this method 6823 * can enforce the semantic that requesting a check on a null global 6824 * permission is automatically denied. (Internally a null permission 6825 * string is used when calling {@link #checkComponentPermission} in cases 6826 * when only uid-based security is needed.) 6827 * 6828 * This can be called with or without the global lock held. 6829 */ 6830 @Override 6831 public int checkPermission(String permission, int pid, int uid) { 6832 if (permission == null) { 6833 return PackageManager.PERMISSION_DENIED; 6834 } 6835 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6836 } 6837 6838 /** 6839 * Binder IPC calls go through the public entry point. 6840 * This can be called with or without the global lock held. 6841 */ 6842 int checkCallingPermission(String permission) { 6843 return checkPermission(permission, 6844 Binder.getCallingPid(), 6845 UserHandle.getAppId(Binder.getCallingUid())); 6846 } 6847 6848 /** 6849 * This can be called with or without the global lock held. 6850 */ 6851 void enforceCallingPermission(String permission, String func) { 6852 if (checkCallingPermission(permission) 6853 == PackageManager.PERMISSION_GRANTED) { 6854 return; 6855 } 6856 6857 String msg = "Permission Denial: " + func + " from pid=" 6858 + Binder.getCallingPid() 6859 + ", uid=" + Binder.getCallingUid() 6860 + " requires " + permission; 6861 Slog.w(TAG, msg); 6862 throw new SecurityException(msg); 6863 } 6864 6865 /** 6866 * Determine if UID is holding permissions required to access {@link Uri} in 6867 * the given {@link ProviderInfo}. Final permission checking is always done 6868 * in {@link ContentProvider}. 6869 */ 6870 private final boolean checkHoldingPermissionsLocked( 6871 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6872 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6873 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6874 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6875 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6876 != PERMISSION_GRANTED) { 6877 return false; 6878 } 6879 } 6880 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6881 } 6882 6883 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6884 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6885 if (pi.applicationInfo.uid == uid) { 6886 return true; 6887 } else if (!pi.exported) { 6888 return false; 6889 } 6890 6891 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6892 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6893 try { 6894 // check if target holds top-level <provider> permissions 6895 if (!readMet && pi.readPermission != null && considerUidPermissions 6896 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6897 readMet = true; 6898 } 6899 if (!writeMet && pi.writePermission != null && considerUidPermissions 6900 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6901 writeMet = true; 6902 } 6903 6904 // track if unprotected read/write is allowed; any denied 6905 // <path-permission> below removes this ability 6906 boolean allowDefaultRead = pi.readPermission == null; 6907 boolean allowDefaultWrite = pi.writePermission == null; 6908 6909 // check if target holds any <path-permission> that match uri 6910 final PathPermission[] pps = pi.pathPermissions; 6911 if (pps != null) { 6912 final String path = grantUri.uri.getPath(); 6913 int i = pps.length; 6914 while (i > 0 && (!readMet || !writeMet)) { 6915 i--; 6916 PathPermission pp = pps[i]; 6917 if (pp.match(path)) { 6918 if (!readMet) { 6919 final String pprperm = pp.getReadPermission(); 6920 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6921 + pprperm + " for " + pp.getPath() 6922 + ": match=" + pp.match(path) 6923 + " check=" + pm.checkUidPermission(pprperm, uid)); 6924 if (pprperm != null) { 6925 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6926 == PERMISSION_GRANTED) { 6927 readMet = true; 6928 } else { 6929 allowDefaultRead = false; 6930 } 6931 } 6932 } 6933 if (!writeMet) { 6934 final String ppwperm = pp.getWritePermission(); 6935 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6936 + ppwperm + " for " + pp.getPath() 6937 + ": match=" + pp.match(path) 6938 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6939 if (ppwperm != null) { 6940 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6941 == PERMISSION_GRANTED) { 6942 writeMet = true; 6943 } else { 6944 allowDefaultWrite = false; 6945 } 6946 } 6947 } 6948 } 6949 } 6950 } 6951 6952 // grant unprotected <provider> read/write, if not blocked by 6953 // <path-permission> above 6954 if (allowDefaultRead) readMet = true; 6955 if (allowDefaultWrite) writeMet = true; 6956 6957 } catch (RemoteException e) { 6958 return false; 6959 } 6960 6961 return readMet && writeMet; 6962 } 6963 6964 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6965 ProviderInfo pi = null; 6966 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6967 if (cpr != null) { 6968 pi = cpr.info; 6969 } else { 6970 try { 6971 pi = AppGlobals.getPackageManager().resolveContentProvider( 6972 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6973 } catch (RemoteException ex) { 6974 } 6975 } 6976 return pi; 6977 } 6978 6979 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6980 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6981 if (targetUris != null) { 6982 return targetUris.get(grantUri); 6983 } 6984 return null; 6985 } 6986 6987 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6988 String targetPkg, int targetUid, GrantUri grantUri) { 6989 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6990 if (targetUris == null) { 6991 targetUris = Maps.newArrayMap(); 6992 mGrantedUriPermissions.put(targetUid, targetUris); 6993 } 6994 6995 UriPermission perm = targetUris.get(grantUri); 6996 if (perm == null) { 6997 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6998 targetUris.put(grantUri, perm); 6999 } 7000 7001 return perm; 7002 } 7003 7004 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7005 final int modeFlags) { 7006 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7007 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7008 : UriPermission.STRENGTH_OWNED; 7009 7010 // Root gets to do everything. 7011 if (uid == 0) { 7012 return true; 7013 } 7014 7015 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7016 if (perms == null) return false; 7017 7018 // First look for exact match 7019 final UriPermission exactPerm = perms.get(grantUri); 7020 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7021 return true; 7022 } 7023 7024 // No exact match, look for prefixes 7025 final int N = perms.size(); 7026 for (int i = 0; i < N; i++) { 7027 final UriPermission perm = perms.valueAt(i); 7028 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7029 && perm.getStrength(modeFlags) >= minStrength) { 7030 return true; 7031 } 7032 } 7033 7034 return false; 7035 } 7036 7037 /** 7038 * @param uri This uri must NOT contain an embedded userId. 7039 * @param userId The userId in which the uri is to be resolved. 7040 */ 7041 @Override 7042 public int checkUriPermission(Uri uri, int pid, int uid, 7043 final int modeFlags, int userId) { 7044 enforceNotIsolatedCaller("checkUriPermission"); 7045 7046 // Another redirected-binder-call permissions check as in 7047 // {@link checkComponentPermission}. 7048 Identity tlsIdentity = sCallerIdentity.get(); 7049 if (tlsIdentity != null) { 7050 uid = tlsIdentity.uid; 7051 pid = tlsIdentity.pid; 7052 } 7053 7054 // Our own process gets to do everything. 7055 if (pid == MY_PID) { 7056 return PackageManager.PERMISSION_GRANTED; 7057 } 7058 synchronized (this) { 7059 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7060 ? PackageManager.PERMISSION_GRANTED 7061 : PackageManager.PERMISSION_DENIED; 7062 } 7063 } 7064 7065 /** 7066 * Check if the targetPkg can be granted permission to access uri by 7067 * the callingUid using the given modeFlags. Throws a security exception 7068 * if callingUid is not allowed to do this. Returns the uid of the target 7069 * if the URI permission grant should be performed; returns -1 if it is not 7070 * needed (for example targetPkg already has permission to access the URI). 7071 * If you already know the uid of the target, you can supply it in 7072 * lastTargetUid else set that to -1. 7073 */ 7074 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7075 final int modeFlags, int lastTargetUid) { 7076 if (!Intent.isAccessUriMode(modeFlags)) { 7077 return -1; 7078 } 7079 7080 if (targetPkg != null) { 7081 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7082 "Checking grant " + targetPkg + " permission to " + grantUri); 7083 } 7084 7085 final IPackageManager pm = AppGlobals.getPackageManager(); 7086 7087 // If this is not a content: uri, we can't do anything with it. 7088 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7089 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7090 "Can't grant URI permission for non-content URI: " + grantUri); 7091 return -1; 7092 } 7093 7094 final String authority = grantUri.uri.getAuthority(); 7095 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7096 if (pi == null) { 7097 Slog.w(TAG, "No content provider found for permission check: " + 7098 grantUri.uri.toSafeString()); 7099 return -1; 7100 } 7101 7102 int targetUid = lastTargetUid; 7103 if (targetUid < 0 && targetPkg != null) { 7104 try { 7105 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7106 if (targetUid < 0) { 7107 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7108 "Can't grant URI permission no uid for: " + targetPkg); 7109 return -1; 7110 } 7111 } catch (RemoteException ex) { 7112 return -1; 7113 } 7114 } 7115 7116 if (targetUid >= 0) { 7117 // First... does the target actually need this permission? 7118 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7119 // No need to grant the target this permission. 7120 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7121 "Target " + targetPkg + " already has full permission to " + grantUri); 7122 return -1; 7123 } 7124 } else { 7125 // First... there is no target package, so can anyone access it? 7126 boolean allowed = pi.exported; 7127 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7128 if (pi.readPermission != null) { 7129 allowed = false; 7130 } 7131 } 7132 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7133 if (pi.writePermission != null) { 7134 allowed = false; 7135 } 7136 } 7137 if (allowed) { 7138 return -1; 7139 } 7140 } 7141 7142 /* There is a special cross user grant if: 7143 * - The target is on another user. 7144 * - Apps on the current user can access the uri without any uid permissions. 7145 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7146 * grant uri permissions. 7147 */ 7148 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7149 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7150 modeFlags, false /*without considering the uid permissions*/); 7151 7152 // Second... is the provider allowing granting of URI permissions? 7153 if (!specialCrossUserGrant) { 7154 if (!pi.grantUriPermissions) { 7155 throw new SecurityException("Provider " + pi.packageName 7156 + "/" + pi.name 7157 + " does not allow granting of Uri permissions (uri " 7158 + grantUri + ")"); 7159 } 7160 if (pi.uriPermissionPatterns != null) { 7161 final int N = pi.uriPermissionPatterns.length; 7162 boolean allowed = false; 7163 for (int i=0; i<N; i++) { 7164 if (pi.uriPermissionPatterns[i] != null 7165 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7166 allowed = true; 7167 break; 7168 } 7169 } 7170 if (!allowed) { 7171 throw new SecurityException("Provider " + pi.packageName 7172 + "/" + pi.name 7173 + " does not allow granting of permission to path of Uri " 7174 + grantUri); 7175 } 7176 } 7177 } 7178 7179 // Third... does the caller itself have permission to access 7180 // this uri? 7181 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7182 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7183 // Require they hold a strong enough Uri permission 7184 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7185 throw new SecurityException("Uid " + callingUid 7186 + " does not have permission to uri " + grantUri); 7187 } 7188 } 7189 } 7190 return targetUid; 7191 } 7192 7193 /** 7194 * @param uri This uri must NOT contain an embedded userId. 7195 * @param userId The userId in which the uri is to be resolved. 7196 */ 7197 @Override 7198 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7199 final int modeFlags, int userId) { 7200 enforceNotIsolatedCaller("checkGrantUriPermission"); 7201 synchronized(this) { 7202 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7203 new GrantUri(userId, uri, false), modeFlags, -1); 7204 } 7205 } 7206 7207 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7208 final int modeFlags, UriPermissionOwner owner) { 7209 if (!Intent.isAccessUriMode(modeFlags)) { 7210 return; 7211 } 7212 7213 // So here we are: the caller has the assumed permission 7214 // to the uri, and the target doesn't. Let's now give this to 7215 // the target. 7216 7217 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7218 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7219 7220 final String authority = grantUri.uri.getAuthority(); 7221 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7222 if (pi == null) { 7223 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7224 return; 7225 } 7226 7227 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7228 grantUri.prefix = true; 7229 } 7230 final UriPermission perm = findOrCreateUriPermissionLocked( 7231 pi.packageName, targetPkg, targetUid, grantUri); 7232 perm.grantModes(modeFlags, owner); 7233 } 7234 7235 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7236 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7237 if (targetPkg == null) { 7238 throw new NullPointerException("targetPkg"); 7239 } 7240 int targetUid; 7241 final IPackageManager pm = AppGlobals.getPackageManager(); 7242 try { 7243 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7244 } catch (RemoteException ex) { 7245 return; 7246 } 7247 7248 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7249 targetUid); 7250 if (targetUid < 0) { 7251 return; 7252 } 7253 7254 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7255 owner); 7256 } 7257 7258 static class NeededUriGrants extends ArrayList<GrantUri> { 7259 final String targetPkg; 7260 final int targetUid; 7261 final int flags; 7262 7263 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7264 this.targetPkg = targetPkg; 7265 this.targetUid = targetUid; 7266 this.flags = flags; 7267 } 7268 } 7269 7270 /** 7271 * Like checkGrantUriPermissionLocked, but takes an Intent. 7272 */ 7273 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7274 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7275 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7276 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7277 + " clip=" + (intent != null ? intent.getClipData() : null) 7278 + " from " + intent + "; flags=0x" 7279 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7280 7281 if (targetPkg == null) { 7282 throw new NullPointerException("targetPkg"); 7283 } 7284 7285 if (intent == null) { 7286 return null; 7287 } 7288 Uri data = intent.getData(); 7289 ClipData clip = intent.getClipData(); 7290 if (data == null && clip == null) { 7291 return null; 7292 } 7293 // Default userId for uris in the intent (if they don't specify it themselves) 7294 int contentUserHint = intent.getContentUserHint(); 7295 if (contentUserHint == UserHandle.USER_CURRENT) { 7296 contentUserHint = UserHandle.getUserId(callingUid); 7297 } 7298 final IPackageManager pm = AppGlobals.getPackageManager(); 7299 int targetUid; 7300 if (needed != null) { 7301 targetUid = needed.targetUid; 7302 } else { 7303 try { 7304 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7305 } catch (RemoteException ex) { 7306 return null; 7307 } 7308 if (targetUid < 0) { 7309 if (DEBUG_URI_PERMISSION) { 7310 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7311 + " on user " + targetUserId); 7312 } 7313 return null; 7314 } 7315 } 7316 if (data != null) { 7317 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7318 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7319 targetUid); 7320 if (targetUid > 0) { 7321 if (needed == null) { 7322 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7323 } 7324 needed.add(grantUri); 7325 } 7326 } 7327 if (clip != null) { 7328 for (int i=0; i<clip.getItemCount(); i++) { 7329 Uri uri = clip.getItemAt(i).getUri(); 7330 if (uri != null) { 7331 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7332 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7333 targetUid); 7334 if (targetUid > 0) { 7335 if (needed == null) { 7336 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7337 } 7338 needed.add(grantUri); 7339 } 7340 } else { 7341 Intent clipIntent = clip.getItemAt(i).getIntent(); 7342 if (clipIntent != null) { 7343 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7344 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7345 if (newNeeded != null) { 7346 needed = newNeeded; 7347 } 7348 } 7349 } 7350 } 7351 } 7352 7353 return needed; 7354 } 7355 7356 /** 7357 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7358 */ 7359 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7360 UriPermissionOwner owner) { 7361 if (needed != null) { 7362 for (int i=0; i<needed.size(); i++) { 7363 GrantUri grantUri = needed.get(i); 7364 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7365 grantUri, needed.flags, owner); 7366 } 7367 } 7368 } 7369 7370 void grantUriPermissionFromIntentLocked(int callingUid, 7371 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7372 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7373 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7374 if (needed == null) { 7375 return; 7376 } 7377 7378 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7379 } 7380 7381 /** 7382 * @param uri This uri must NOT contain an embedded userId. 7383 * @param userId The userId in which the uri is to be resolved. 7384 */ 7385 @Override 7386 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7387 final int modeFlags, int userId) { 7388 enforceNotIsolatedCaller("grantUriPermission"); 7389 GrantUri grantUri = new GrantUri(userId, uri, false); 7390 synchronized(this) { 7391 final ProcessRecord r = getRecordForAppLocked(caller); 7392 if (r == null) { 7393 throw new SecurityException("Unable to find app for caller " 7394 + caller 7395 + " when granting permission to uri " + grantUri); 7396 } 7397 if (targetPkg == null) { 7398 throw new IllegalArgumentException("null target"); 7399 } 7400 if (grantUri == null) { 7401 throw new IllegalArgumentException("null uri"); 7402 } 7403 7404 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7405 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7406 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7407 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7408 7409 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7410 UserHandle.getUserId(r.uid)); 7411 } 7412 } 7413 7414 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7415 if (perm.modeFlags == 0) { 7416 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7417 perm.targetUid); 7418 if (perms != null) { 7419 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7420 "Removing " + perm.targetUid + " permission to " + perm.uri); 7421 7422 perms.remove(perm.uri); 7423 if (perms.isEmpty()) { 7424 mGrantedUriPermissions.remove(perm.targetUid); 7425 } 7426 } 7427 } 7428 } 7429 7430 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7431 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7432 7433 final IPackageManager pm = AppGlobals.getPackageManager(); 7434 final String authority = grantUri.uri.getAuthority(); 7435 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7436 if (pi == null) { 7437 Slog.w(TAG, "No content provider found for permission revoke: " 7438 + grantUri.toSafeString()); 7439 return; 7440 } 7441 7442 // Does the caller have this permission on the URI? 7443 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7444 // Right now, if you are not the original owner of the permission, 7445 // you are not allowed to revoke it. 7446 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7447 throw new SecurityException("Uid " + callingUid 7448 + " does not have permission to uri " + grantUri); 7449 //} 7450 } 7451 7452 boolean persistChanged = false; 7453 7454 // Go through all of the permissions and remove any that match. 7455 int N = mGrantedUriPermissions.size(); 7456 for (int i = 0; i < N; i++) { 7457 final int targetUid = mGrantedUriPermissions.keyAt(i); 7458 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7459 7460 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7461 final UriPermission perm = it.next(); 7462 if (perm.uri.sourceUserId == grantUri.sourceUserId 7463 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7464 if (DEBUG_URI_PERMISSION) 7465 Slog.v(TAG, 7466 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7467 persistChanged |= perm.revokeModes( 7468 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7469 if (perm.modeFlags == 0) { 7470 it.remove(); 7471 } 7472 } 7473 } 7474 7475 if (perms.isEmpty()) { 7476 mGrantedUriPermissions.remove(targetUid); 7477 N--; 7478 i--; 7479 } 7480 } 7481 7482 if (persistChanged) { 7483 schedulePersistUriGrants(); 7484 } 7485 } 7486 7487 /** 7488 * @param uri This uri must NOT contain an embedded userId. 7489 * @param userId The userId in which the uri is to be resolved. 7490 */ 7491 @Override 7492 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7493 int userId) { 7494 enforceNotIsolatedCaller("revokeUriPermission"); 7495 synchronized(this) { 7496 final ProcessRecord r = getRecordForAppLocked(caller); 7497 if (r == null) { 7498 throw new SecurityException("Unable to find app for caller " 7499 + caller 7500 + " when revoking permission to uri " + uri); 7501 } 7502 if (uri == null) { 7503 Slog.w(TAG, "revokeUriPermission: null uri"); 7504 return; 7505 } 7506 7507 if (!Intent.isAccessUriMode(modeFlags)) { 7508 return; 7509 } 7510 7511 final IPackageManager pm = AppGlobals.getPackageManager(); 7512 final String authority = uri.getAuthority(); 7513 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7514 if (pi == null) { 7515 Slog.w(TAG, "No content provider found for permission revoke: " 7516 + uri.toSafeString()); 7517 return; 7518 } 7519 7520 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7521 } 7522 } 7523 7524 /** 7525 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7526 * given package. 7527 * 7528 * @param packageName Package name to match, or {@code null} to apply to all 7529 * packages. 7530 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7531 * to all users. 7532 * @param persistable If persistable grants should be removed. 7533 */ 7534 private void removeUriPermissionsForPackageLocked( 7535 String packageName, int userHandle, boolean persistable) { 7536 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7537 throw new IllegalArgumentException("Must narrow by either package or user"); 7538 } 7539 7540 boolean persistChanged = false; 7541 7542 int N = mGrantedUriPermissions.size(); 7543 for (int i = 0; i < N; i++) { 7544 final int targetUid = mGrantedUriPermissions.keyAt(i); 7545 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7546 7547 // Only inspect grants matching user 7548 if (userHandle == UserHandle.USER_ALL 7549 || userHandle == UserHandle.getUserId(targetUid)) { 7550 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7551 final UriPermission perm = it.next(); 7552 7553 // Only inspect grants matching package 7554 if (packageName == null || perm.sourcePkg.equals(packageName) 7555 || perm.targetPkg.equals(packageName)) { 7556 persistChanged |= perm.revokeModes( 7557 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7558 7559 // Only remove when no modes remain; any persisted grants 7560 // will keep this alive. 7561 if (perm.modeFlags == 0) { 7562 it.remove(); 7563 } 7564 } 7565 } 7566 7567 if (perms.isEmpty()) { 7568 mGrantedUriPermissions.remove(targetUid); 7569 N--; 7570 i--; 7571 } 7572 } 7573 } 7574 7575 if (persistChanged) { 7576 schedulePersistUriGrants(); 7577 } 7578 } 7579 7580 @Override 7581 public IBinder newUriPermissionOwner(String name) { 7582 enforceNotIsolatedCaller("newUriPermissionOwner"); 7583 synchronized(this) { 7584 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7585 return owner.getExternalTokenLocked(); 7586 } 7587 } 7588 7589 /** 7590 * @param uri This uri must NOT contain an embedded userId. 7591 * @param sourceUserId The userId in which the uri is to be resolved. 7592 * @param targetUserId The userId of the app that receives the grant. 7593 */ 7594 @Override 7595 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7596 final int modeFlags, int sourceUserId, int targetUserId) { 7597 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7598 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7599 synchronized(this) { 7600 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7601 if (owner == null) { 7602 throw new IllegalArgumentException("Unknown owner: " + token); 7603 } 7604 if (fromUid != Binder.getCallingUid()) { 7605 if (Binder.getCallingUid() != Process.myUid()) { 7606 // Only system code can grant URI permissions on behalf 7607 // of other users. 7608 throw new SecurityException("nice try"); 7609 } 7610 } 7611 if (targetPkg == null) { 7612 throw new IllegalArgumentException("null target"); 7613 } 7614 if (uri == null) { 7615 throw new IllegalArgumentException("null uri"); 7616 } 7617 7618 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7619 modeFlags, owner, targetUserId); 7620 } 7621 } 7622 7623 /** 7624 * @param uri This uri must NOT contain an embedded userId. 7625 * @param userId The userId in which the uri is to be resolved. 7626 */ 7627 @Override 7628 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7629 synchronized(this) { 7630 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7631 if (owner == null) { 7632 throw new IllegalArgumentException("Unknown owner: " + token); 7633 } 7634 7635 if (uri == null) { 7636 owner.removeUriPermissionsLocked(mode); 7637 } else { 7638 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7639 } 7640 } 7641 } 7642 7643 private void schedulePersistUriGrants() { 7644 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7645 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7646 10 * DateUtils.SECOND_IN_MILLIS); 7647 } 7648 } 7649 7650 private void writeGrantedUriPermissions() { 7651 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7652 7653 // Snapshot permissions so we can persist without lock 7654 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7655 synchronized (this) { 7656 final int size = mGrantedUriPermissions.size(); 7657 for (int i = 0; i < size; i++) { 7658 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7659 for (UriPermission perm : perms.values()) { 7660 if (perm.persistedModeFlags != 0) { 7661 persist.add(perm.snapshot()); 7662 } 7663 } 7664 } 7665 } 7666 7667 FileOutputStream fos = null; 7668 try { 7669 fos = mGrantFile.startWrite(); 7670 7671 XmlSerializer out = new FastXmlSerializer(); 7672 out.setOutput(fos, "utf-8"); 7673 out.startDocument(null, true); 7674 out.startTag(null, TAG_URI_GRANTS); 7675 for (UriPermission.Snapshot perm : persist) { 7676 out.startTag(null, TAG_URI_GRANT); 7677 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7678 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7679 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7680 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7681 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7682 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7683 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7684 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7685 out.endTag(null, TAG_URI_GRANT); 7686 } 7687 out.endTag(null, TAG_URI_GRANTS); 7688 out.endDocument(); 7689 7690 mGrantFile.finishWrite(fos); 7691 } catch (IOException e) { 7692 if (fos != null) { 7693 mGrantFile.failWrite(fos); 7694 } 7695 } 7696 } 7697 7698 private void readGrantedUriPermissionsLocked() { 7699 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7700 7701 final long now = System.currentTimeMillis(); 7702 7703 FileInputStream fis = null; 7704 try { 7705 fis = mGrantFile.openRead(); 7706 final XmlPullParser in = Xml.newPullParser(); 7707 in.setInput(fis, null); 7708 7709 int type; 7710 while ((type = in.next()) != END_DOCUMENT) { 7711 final String tag = in.getName(); 7712 if (type == START_TAG) { 7713 if (TAG_URI_GRANT.equals(tag)) { 7714 final int sourceUserId; 7715 final int targetUserId; 7716 final int userHandle = readIntAttribute(in, 7717 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7718 if (userHandle != UserHandle.USER_NULL) { 7719 // For backwards compatibility. 7720 sourceUserId = userHandle; 7721 targetUserId = userHandle; 7722 } else { 7723 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7724 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7725 } 7726 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7727 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7728 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7729 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7730 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7731 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7732 7733 // Sanity check that provider still belongs to source package 7734 final ProviderInfo pi = getProviderInfoLocked( 7735 uri.getAuthority(), sourceUserId); 7736 if (pi != null && sourcePkg.equals(pi.packageName)) { 7737 int targetUid = -1; 7738 try { 7739 targetUid = AppGlobals.getPackageManager() 7740 .getPackageUid(targetPkg, targetUserId); 7741 } catch (RemoteException e) { 7742 } 7743 if (targetUid != -1) { 7744 final UriPermission perm = findOrCreateUriPermissionLocked( 7745 sourcePkg, targetPkg, targetUid, 7746 new GrantUri(sourceUserId, uri, prefix)); 7747 perm.initPersistedModes(modeFlags, createdTime); 7748 } 7749 } else { 7750 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7751 + " but instead found " + pi); 7752 } 7753 } 7754 } 7755 } 7756 } catch (FileNotFoundException e) { 7757 // Missing grants is okay 7758 } catch (IOException e) { 7759 Log.wtf(TAG, "Failed reading Uri grants", e); 7760 } catch (XmlPullParserException e) { 7761 Log.wtf(TAG, "Failed reading Uri grants", e); 7762 } finally { 7763 IoUtils.closeQuietly(fis); 7764 } 7765 } 7766 7767 /** 7768 * @param uri This uri must NOT contain an embedded userId. 7769 * @param userId The userId in which the uri is to be resolved. 7770 */ 7771 @Override 7772 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7773 enforceNotIsolatedCaller("takePersistableUriPermission"); 7774 7775 Preconditions.checkFlagsArgument(modeFlags, 7776 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7777 7778 synchronized (this) { 7779 final int callingUid = Binder.getCallingUid(); 7780 boolean persistChanged = false; 7781 GrantUri grantUri = new GrantUri(userId, uri, false); 7782 7783 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7784 new GrantUri(userId, uri, false)); 7785 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7786 new GrantUri(userId, uri, true)); 7787 7788 final boolean exactValid = (exactPerm != null) 7789 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7790 final boolean prefixValid = (prefixPerm != null) 7791 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7792 7793 if (!(exactValid || prefixValid)) { 7794 throw new SecurityException("No persistable permission grants found for UID " 7795 + callingUid + " and Uri " + grantUri.toSafeString()); 7796 } 7797 7798 if (exactValid) { 7799 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7800 } 7801 if (prefixValid) { 7802 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7803 } 7804 7805 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7806 7807 if (persistChanged) { 7808 schedulePersistUriGrants(); 7809 } 7810 } 7811 } 7812 7813 /** 7814 * @param uri This uri must NOT contain an embedded userId. 7815 * @param userId The userId in which the uri is to be resolved. 7816 */ 7817 @Override 7818 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7819 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7820 7821 Preconditions.checkFlagsArgument(modeFlags, 7822 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7823 7824 synchronized (this) { 7825 final int callingUid = Binder.getCallingUid(); 7826 boolean persistChanged = false; 7827 7828 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7829 new GrantUri(userId, uri, false)); 7830 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7831 new GrantUri(userId, uri, true)); 7832 if (exactPerm == null && prefixPerm == null) { 7833 throw new SecurityException("No permission grants found for UID " + callingUid 7834 + " and Uri " + uri.toSafeString()); 7835 } 7836 7837 if (exactPerm != null) { 7838 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7839 removeUriPermissionIfNeededLocked(exactPerm); 7840 } 7841 if (prefixPerm != null) { 7842 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7843 removeUriPermissionIfNeededLocked(prefixPerm); 7844 } 7845 7846 if (persistChanged) { 7847 schedulePersistUriGrants(); 7848 } 7849 } 7850 } 7851 7852 /** 7853 * Prune any older {@link UriPermission} for the given UID until outstanding 7854 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7855 * 7856 * @return if any mutations occured that require persisting. 7857 */ 7858 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7859 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7860 if (perms == null) return false; 7861 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7862 7863 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7864 for (UriPermission perm : perms.values()) { 7865 if (perm.persistedModeFlags != 0) { 7866 persisted.add(perm); 7867 } 7868 } 7869 7870 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7871 if (trimCount <= 0) return false; 7872 7873 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7874 for (int i = 0; i < trimCount; i++) { 7875 final UriPermission perm = persisted.get(i); 7876 7877 if (DEBUG_URI_PERMISSION) { 7878 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7879 } 7880 7881 perm.releasePersistableModes(~0); 7882 removeUriPermissionIfNeededLocked(perm); 7883 } 7884 7885 return true; 7886 } 7887 7888 @Override 7889 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7890 String packageName, boolean incoming) { 7891 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7892 Preconditions.checkNotNull(packageName, "packageName"); 7893 7894 final int callingUid = Binder.getCallingUid(); 7895 final IPackageManager pm = AppGlobals.getPackageManager(); 7896 try { 7897 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7898 if (packageUid != callingUid) { 7899 throw new SecurityException( 7900 "Package " + packageName + " does not belong to calling UID " + callingUid); 7901 } 7902 } catch (RemoteException e) { 7903 throw new SecurityException("Failed to verify package name ownership"); 7904 } 7905 7906 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7907 synchronized (this) { 7908 if (incoming) { 7909 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7910 callingUid); 7911 if (perms == null) { 7912 Slog.w(TAG, "No permission grants found for " + packageName); 7913 } else { 7914 for (UriPermission perm : perms.values()) { 7915 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7916 result.add(perm.buildPersistedPublicApiObject()); 7917 } 7918 } 7919 } 7920 } else { 7921 final int size = mGrantedUriPermissions.size(); 7922 for (int i = 0; i < size; i++) { 7923 final ArrayMap<GrantUri, UriPermission> perms = 7924 mGrantedUriPermissions.valueAt(i); 7925 for (UriPermission perm : perms.values()) { 7926 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7927 result.add(perm.buildPersistedPublicApiObject()); 7928 } 7929 } 7930 } 7931 } 7932 } 7933 return new ParceledListSlice<android.content.UriPermission>(result); 7934 } 7935 7936 @Override 7937 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7938 synchronized (this) { 7939 ProcessRecord app = 7940 who != null ? getRecordForAppLocked(who) : null; 7941 if (app == null) return; 7942 7943 Message msg = Message.obtain(); 7944 msg.what = WAIT_FOR_DEBUGGER_MSG; 7945 msg.obj = app; 7946 msg.arg1 = waiting ? 1 : 0; 7947 mHandler.sendMessage(msg); 7948 } 7949 } 7950 7951 @Override 7952 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7953 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7954 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7955 outInfo.availMem = Process.getFreeMemory(); 7956 outInfo.totalMem = Process.getTotalMemory(); 7957 outInfo.threshold = homeAppMem; 7958 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7959 outInfo.hiddenAppThreshold = cachedAppMem; 7960 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7961 ProcessList.SERVICE_ADJ); 7962 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7963 ProcessList.VISIBLE_APP_ADJ); 7964 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7965 ProcessList.FOREGROUND_APP_ADJ); 7966 } 7967 7968 // ========================================================= 7969 // TASK MANAGEMENT 7970 // ========================================================= 7971 7972 @Override 7973 public List<IAppTask> getAppTasks(String callingPackage) { 7974 int callingUid = Binder.getCallingUid(); 7975 long ident = Binder.clearCallingIdentity(); 7976 7977 synchronized(this) { 7978 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7979 try { 7980 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7981 7982 final int N = mRecentTasks.size(); 7983 for (int i = 0; i < N; i++) { 7984 TaskRecord tr = mRecentTasks.get(i); 7985 // Skip tasks that do not match the caller. We don't need to verify 7986 // callingPackage, because we are also limiting to callingUid and know 7987 // that will limit to the correct security sandbox. 7988 if (tr.effectiveUid != callingUid) { 7989 continue; 7990 } 7991 Intent intent = tr.getBaseIntent(); 7992 if (intent == null || 7993 !callingPackage.equals(intent.getComponent().getPackageName())) { 7994 continue; 7995 } 7996 ActivityManager.RecentTaskInfo taskInfo = 7997 createRecentTaskInfoFromTaskRecord(tr); 7998 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7999 list.add(taskImpl); 8000 } 8001 } finally { 8002 Binder.restoreCallingIdentity(ident); 8003 } 8004 return list; 8005 } 8006 } 8007 8008 @Override 8009 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8010 final int callingUid = Binder.getCallingUid(); 8011 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8012 8013 synchronized(this) { 8014 if (localLOGV) Slog.v( 8015 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8016 8017 final boolean allowed = checkCallingPermission( 8018 android.Manifest.permission.GET_TASKS) 8019 == PackageManager.PERMISSION_GRANTED; 8020 if (!allowed) { 8021 Slog.w(TAG, "getTasks: caller " + callingUid 8022 + " does not hold GET_TASKS; limiting output"); 8023 } 8024 8025 // TODO: Improve with MRU list from all ActivityStacks. 8026 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8027 } 8028 8029 return list; 8030 } 8031 8032 TaskRecord getMostRecentTask() { 8033 return mRecentTasks.get(0); 8034 } 8035 8036 /** 8037 * Creates a new RecentTaskInfo from a TaskRecord. 8038 */ 8039 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8040 // Update the task description to reflect any changes in the task stack 8041 tr.updateTaskDescription(); 8042 8043 // Compose the recent task info 8044 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8045 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8046 rti.persistentId = tr.taskId; 8047 rti.baseIntent = new Intent(tr.getBaseIntent()); 8048 rti.origActivity = tr.origActivity; 8049 rti.description = tr.lastDescription; 8050 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8051 rti.userId = tr.userId; 8052 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8053 rti.firstActiveTime = tr.firstActiveTime; 8054 rti.lastActiveTime = tr.lastActiveTime; 8055 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8056 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8057 return rti; 8058 } 8059 8060 @Override 8061 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8062 final int callingUid = Binder.getCallingUid(); 8063 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8064 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8065 8066 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8067 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8068 synchronized (this) { 8069 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8070 == PackageManager.PERMISSION_GRANTED; 8071 if (!allowed) { 8072 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8073 + " does not hold GET_TASKS; limiting output"); 8074 } 8075 final boolean detailed = checkCallingPermission( 8076 android.Manifest.permission.GET_DETAILED_TASKS) 8077 == PackageManager.PERMISSION_GRANTED; 8078 8079 final int N = mRecentTasks.size(); 8080 ArrayList<ActivityManager.RecentTaskInfo> res 8081 = new ArrayList<ActivityManager.RecentTaskInfo>( 8082 maxNum < N ? maxNum : N); 8083 8084 final Set<Integer> includedUsers; 8085 if (includeProfiles) { 8086 includedUsers = getProfileIdsLocked(userId); 8087 } else { 8088 includedUsers = new HashSet<Integer>(); 8089 } 8090 includedUsers.add(Integer.valueOf(userId)); 8091 8092 for (int i=0; i<N && maxNum > 0; i++) { 8093 TaskRecord tr = mRecentTasks.get(i); 8094 // Only add calling user or related users recent tasks 8095 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8096 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8097 continue; 8098 } 8099 8100 // Return the entry if desired by the caller. We always return 8101 // the first entry, because callers always expect this to be the 8102 // foreground app. We may filter others if the caller has 8103 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8104 // we should exclude the entry. 8105 8106 if (i == 0 8107 || withExcluded 8108 || (tr.intent == null) 8109 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8110 == 0)) { 8111 if (!allowed) { 8112 // If the caller doesn't have the GET_TASKS permission, then only 8113 // allow them to see a small subset of tasks -- their own and home. 8114 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8115 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8116 continue; 8117 } 8118 } 8119 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8120 if (tr.stack != null && tr.stack.isHomeStack()) { 8121 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8122 continue; 8123 } 8124 } 8125 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8126 // Don't include auto remove tasks that are finished or finishing. 8127 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8128 + tr); 8129 continue; 8130 } 8131 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8132 && !tr.isAvailable) { 8133 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8134 continue; 8135 } 8136 8137 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8138 if (!detailed) { 8139 rti.baseIntent.replaceExtras((Bundle)null); 8140 } 8141 8142 res.add(rti); 8143 maxNum--; 8144 } 8145 } 8146 return res; 8147 } 8148 } 8149 8150 private TaskRecord recentTaskForIdLocked(int id) { 8151 final int N = mRecentTasks.size(); 8152 for (int i=0; i<N; i++) { 8153 TaskRecord tr = mRecentTasks.get(i); 8154 if (tr.taskId == id) { 8155 return tr; 8156 } 8157 } 8158 return null; 8159 } 8160 8161 @Override 8162 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8163 synchronized (this) { 8164 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8165 "getTaskThumbnail()"); 8166 TaskRecord tr = recentTaskForIdLocked(id); 8167 if (tr != null) { 8168 return tr.getTaskThumbnailLocked(); 8169 } 8170 } 8171 return null; 8172 } 8173 8174 @Override 8175 public int addAppTask(IBinder activityToken, Intent intent, 8176 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8177 final int callingUid = Binder.getCallingUid(); 8178 final long callingIdent = Binder.clearCallingIdentity(); 8179 8180 try { 8181 synchronized (this) { 8182 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8183 if (r == null) { 8184 throw new IllegalArgumentException("Activity does not exist; token=" 8185 + activityToken); 8186 } 8187 ComponentName comp = intent.getComponent(); 8188 if (comp == null) { 8189 throw new IllegalArgumentException("Intent " + intent 8190 + " must specify explicit component"); 8191 } 8192 if (thumbnail.getWidth() != mThumbnailWidth 8193 || thumbnail.getHeight() != mThumbnailHeight) { 8194 throw new IllegalArgumentException("Bad thumbnail size: got " 8195 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8196 + mThumbnailWidth + "x" + mThumbnailHeight); 8197 } 8198 if (intent.getSelector() != null) { 8199 intent.setSelector(null); 8200 } 8201 if (intent.getSourceBounds() != null) { 8202 intent.setSourceBounds(null); 8203 } 8204 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8205 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8206 // The caller has added this as an auto-remove task... that makes no 8207 // sense, so turn off auto-remove. 8208 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8209 } 8210 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8211 // Must be a new task. 8212 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8213 } 8214 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8215 mLastAddedTaskActivity = null; 8216 } 8217 ActivityInfo ainfo = mLastAddedTaskActivity; 8218 if (ainfo == null) { 8219 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8220 comp, 0, UserHandle.getUserId(callingUid)); 8221 if (ainfo.applicationInfo.uid != callingUid) { 8222 throw new SecurityException( 8223 "Can't add task for another application: target uid=" 8224 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8225 } 8226 } 8227 8228 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8229 intent, description); 8230 8231 int trimIdx = trimRecentsForTask(task, false); 8232 if (trimIdx >= 0) { 8233 // If this would have caused a trim, then we'll abort because that 8234 // means it would be added at the end of the list but then just removed. 8235 return -1; 8236 } 8237 8238 final int N = mRecentTasks.size(); 8239 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8240 final TaskRecord tr = mRecentTasks.remove(N - 1); 8241 tr.removedFromRecents(mTaskPersister); 8242 } 8243 8244 task.inRecents = true; 8245 mRecentTasks.add(task); 8246 r.task.stack.addTask(task, false, false); 8247 8248 task.setLastThumbnail(thumbnail); 8249 task.freeLastThumbnail(); 8250 8251 return task.taskId; 8252 } 8253 } finally { 8254 Binder.restoreCallingIdentity(callingIdent); 8255 } 8256 } 8257 8258 @Override 8259 public Point getAppTaskThumbnailSize() { 8260 synchronized (this) { 8261 return new Point(mThumbnailWidth, mThumbnailHeight); 8262 } 8263 } 8264 8265 @Override 8266 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8267 synchronized (this) { 8268 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8269 if (r != null) { 8270 r.taskDescription = td; 8271 r.task.updateTaskDescription(); 8272 } 8273 } 8274 } 8275 8276 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8277 mRecentTasks.remove(tr); 8278 tr.removedFromRecents(mTaskPersister); 8279 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8280 Intent baseIntent = new Intent( 8281 tr.intent != null ? tr.intent : tr.affinityIntent); 8282 ComponentName component = baseIntent.getComponent(); 8283 if (component == null) { 8284 Slog.w(TAG, "Now component for base intent of task: " + tr); 8285 return; 8286 } 8287 8288 // Find any running services associated with this app. 8289 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8290 8291 if (killProcesses) { 8292 // Find any running processes associated with this app. 8293 final String pkg = component.getPackageName(); 8294 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8295 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8296 for (int i=0; i<pmap.size(); i++) { 8297 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8298 for (int j=0; j<uids.size(); j++) { 8299 ProcessRecord proc = uids.valueAt(j); 8300 if (proc.userId != tr.userId) { 8301 continue; 8302 } 8303 if (!proc.pkgList.containsKey(pkg)) { 8304 continue; 8305 } 8306 procs.add(proc); 8307 } 8308 } 8309 8310 // Kill the running processes. 8311 for (int i=0; i<procs.size(); i++) { 8312 ProcessRecord pr = procs.get(i); 8313 if (pr == mHomeProcess) { 8314 // Don't kill the home process along with tasks from the same package. 8315 continue; 8316 } 8317 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8318 pr.kill("remove task", true); 8319 } else { 8320 pr.waitingToKill = "remove task"; 8321 } 8322 } 8323 } 8324 } 8325 8326 /** 8327 * Removes the task with the specified task id. 8328 * 8329 * @param taskId Identifier of the task to be removed. 8330 * @param flags Additional operational flags. May be 0 or 8331 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8332 * @return Returns true if the given task was found and removed. 8333 */ 8334 private boolean removeTaskByIdLocked(int taskId, int flags) { 8335 TaskRecord tr = recentTaskForIdLocked(taskId); 8336 if (tr != null) { 8337 tr.removeTaskActivitiesLocked(); 8338 cleanUpRemovedTaskLocked(tr, flags); 8339 if (tr.isPersistable) { 8340 notifyTaskPersisterLocked(null, true); 8341 } 8342 return true; 8343 } 8344 return false; 8345 } 8346 8347 @Override 8348 public boolean removeTask(int taskId, int flags) { 8349 synchronized (this) { 8350 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8351 "removeTask()"); 8352 long ident = Binder.clearCallingIdentity(); 8353 try { 8354 return removeTaskByIdLocked(taskId, flags); 8355 } finally { 8356 Binder.restoreCallingIdentity(ident); 8357 } 8358 } 8359 } 8360 8361 /** 8362 * TODO: Add mController hook 8363 */ 8364 @Override 8365 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8366 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8367 "moveTaskToFront()"); 8368 8369 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8370 synchronized(this) { 8371 moveTaskToFrontLocked(taskId, flags, options); 8372 } 8373 } 8374 8375 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8376 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8377 Binder.getCallingUid(), "Task to front")) { 8378 ActivityOptions.abort(options); 8379 return; 8380 } 8381 final long origId = Binder.clearCallingIdentity(); 8382 try { 8383 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8384 if (task == null) { 8385 return; 8386 } 8387 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8388 mStackSupervisor.showLockTaskToast(); 8389 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8390 return; 8391 } 8392 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8393 if (prev != null && prev.isRecentsActivity()) { 8394 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8395 } 8396 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8397 } finally { 8398 Binder.restoreCallingIdentity(origId); 8399 } 8400 ActivityOptions.abort(options); 8401 } 8402 8403 @Override 8404 public void moveTaskToBack(int taskId) { 8405 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8406 "moveTaskToBack()"); 8407 8408 synchronized(this) { 8409 TaskRecord tr = recentTaskForIdLocked(taskId); 8410 if (tr != null) { 8411 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8412 ActivityStack stack = tr.stack; 8413 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8414 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8415 Binder.getCallingUid(), "Task to back")) { 8416 return; 8417 } 8418 } 8419 final long origId = Binder.clearCallingIdentity(); 8420 try { 8421 stack.moveTaskToBackLocked(taskId, null); 8422 } finally { 8423 Binder.restoreCallingIdentity(origId); 8424 } 8425 } 8426 } 8427 } 8428 8429 /** 8430 * Moves an activity, and all of the other activities within the same task, to the bottom 8431 * of the history stack. The activity's order within the task is unchanged. 8432 * 8433 * @param token A reference to the activity we wish to move 8434 * @param nonRoot If false then this only works if the activity is the root 8435 * of a task; if true it will work for any activity in a task. 8436 * @return Returns true if the move completed, false if not. 8437 */ 8438 @Override 8439 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8440 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8441 synchronized(this) { 8442 final long origId = Binder.clearCallingIdentity(); 8443 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8444 if (taskId >= 0) { 8445 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8446 } 8447 Binder.restoreCallingIdentity(origId); 8448 } 8449 return false; 8450 } 8451 8452 @Override 8453 public void moveTaskBackwards(int task) { 8454 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8455 "moveTaskBackwards()"); 8456 8457 synchronized(this) { 8458 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8459 Binder.getCallingUid(), "Task backwards")) { 8460 return; 8461 } 8462 final long origId = Binder.clearCallingIdentity(); 8463 moveTaskBackwardsLocked(task); 8464 Binder.restoreCallingIdentity(origId); 8465 } 8466 } 8467 8468 private final void moveTaskBackwardsLocked(int task) { 8469 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8470 } 8471 8472 @Override 8473 public IBinder getHomeActivityToken() throws RemoteException { 8474 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8475 "getHomeActivityToken()"); 8476 synchronized (this) { 8477 return mStackSupervisor.getHomeActivityToken(); 8478 } 8479 } 8480 8481 @Override 8482 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8483 IActivityContainerCallback callback) throws RemoteException { 8484 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8485 "createActivityContainer()"); 8486 synchronized (this) { 8487 if (parentActivityToken == null) { 8488 throw new IllegalArgumentException("parent token must not be null"); 8489 } 8490 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8491 if (r == null) { 8492 return null; 8493 } 8494 if (callback == null) { 8495 throw new IllegalArgumentException("callback must not be null"); 8496 } 8497 return mStackSupervisor.createActivityContainer(r, callback); 8498 } 8499 } 8500 8501 @Override 8502 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8503 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8504 "deleteActivityContainer()"); 8505 synchronized (this) { 8506 mStackSupervisor.deleteActivityContainer(container); 8507 } 8508 } 8509 8510 @Override 8511 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8512 throws RemoteException { 8513 synchronized (this) { 8514 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8515 if (stack != null) { 8516 return stack.mActivityContainer; 8517 } 8518 return null; 8519 } 8520 } 8521 8522 @Override 8523 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8524 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8525 "moveTaskToStack()"); 8526 if (stackId == HOME_STACK_ID) { 8527 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8528 new RuntimeException("here").fillInStackTrace()); 8529 } 8530 synchronized (this) { 8531 long ident = Binder.clearCallingIdentity(); 8532 try { 8533 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8534 + stackId + " toTop=" + toTop); 8535 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8536 } finally { 8537 Binder.restoreCallingIdentity(ident); 8538 } 8539 } 8540 } 8541 8542 @Override 8543 public void resizeStack(int stackBoxId, Rect bounds) { 8544 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8545 "resizeStackBox()"); 8546 long ident = Binder.clearCallingIdentity(); 8547 try { 8548 mWindowManager.resizeStack(stackBoxId, bounds); 8549 } finally { 8550 Binder.restoreCallingIdentity(ident); 8551 } 8552 } 8553 8554 @Override 8555 public List<StackInfo> getAllStackInfos() { 8556 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8557 "getAllStackInfos()"); 8558 long ident = Binder.clearCallingIdentity(); 8559 try { 8560 synchronized (this) { 8561 return mStackSupervisor.getAllStackInfosLocked(); 8562 } 8563 } finally { 8564 Binder.restoreCallingIdentity(ident); 8565 } 8566 } 8567 8568 @Override 8569 public StackInfo getStackInfo(int stackId) { 8570 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8571 "getStackInfo()"); 8572 long ident = Binder.clearCallingIdentity(); 8573 try { 8574 synchronized (this) { 8575 return mStackSupervisor.getStackInfoLocked(stackId); 8576 } 8577 } finally { 8578 Binder.restoreCallingIdentity(ident); 8579 } 8580 } 8581 8582 @Override 8583 public boolean isInHomeStack(int taskId) { 8584 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8585 "getStackInfo()"); 8586 long ident = Binder.clearCallingIdentity(); 8587 try { 8588 synchronized (this) { 8589 TaskRecord tr = recentTaskForIdLocked(taskId); 8590 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8591 } 8592 } finally { 8593 Binder.restoreCallingIdentity(ident); 8594 } 8595 } 8596 8597 @Override 8598 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8599 synchronized(this) { 8600 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8601 } 8602 } 8603 8604 private boolean isLockTaskAuthorized(String pkg) { 8605 final DevicePolicyManager dpm = (DevicePolicyManager) 8606 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8607 try { 8608 int uid = mContext.getPackageManager().getPackageUid(pkg, 8609 Binder.getCallingUserHandle().getIdentifier()); 8610 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8611 } catch (NameNotFoundException e) { 8612 return false; 8613 } 8614 } 8615 8616 void startLockTaskMode(TaskRecord task) { 8617 final String pkg; 8618 synchronized (this) { 8619 pkg = task.intent.getComponent().getPackageName(); 8620 } 8621 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8622 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8623 final TaskRecord taskRecord = task; 8624 mHandler.post(new Runnable() { 8625 @Override 8626 public void run() { 8627 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8628 } 8629 }); 8630 return; 8631 } 8632 long ident = Binder.clearCallingIdentity(); 8633 try { 8634 synchronized (this) { 8635 // Since we lost lock on task, make sure it is still there. 8636 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8637 if (task != null) { 8638 if (!isSystemInitiated 8639 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8640 throw new IllegalArgumentException("Invalid task, not in foreground"); 8641 } 8642 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8643 } 8644 } 8645 } finally { 8646 Binder.restoreCallingIdentity(ident); 8647 } 8648 } 8649 8650 @Override 8651 public void startLockTaskMode(int taskId) { 8652 final TaskRecord task; 8653 long ident = Binder.clearCallingIdentity(); 8654 try { 8655 synchronized (this) { 8656 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8657 } 8658 } finally { 8659 Binder.restoreCallingIdentity(ident); 8660 } 8661 if (task != null) { 8662 startLockTaskMode(task); 8663 } 8664 } 8665 8666 @Override 8667 public void startLockTaskMode(IBinder token) { 8668 final TaskRecord task; 8669 long ident = Binder.clearCallingIdentity(); 8670 try { 8671 synchronized (this) { 8672 final ActivityRecord r = ActivityRecord.forToken(token); 8673 if (r == null) { 8674 return; 8675 } 8676 task = r.task; 8677 } 8678 } finally { 8679 Binder.restoreCallingIdentity(ident); 8680 } 8681 if (task != null) { 8682 startLockTaskMode(task); 8683 } 8684 } 8685 8686 @Override 8687 public void startLockTaskModeOnCurrent() throws RemoteException { 8688 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8689 ActivityRecord r = null; 8690 synchronized (this) { 8691 r = mStackSupervisor.topRunningActivityLocked(); 8692 } 8693 startLockTaskMode(r.task); 8694 } 8695 8696 @Override 8697 public void stopLockTaskMode() { 8698 // Verify that the user matches the package of the intent for the TaskRecord 8699 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8700 // and stopLockTaskMode. 8701 final int callingUid = Binder.getCallingUid(); 8702 if (callingUid != Process.SYSTEM_UID) { 8703 try { 8704 String pkg = 8705 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8706 int uid = mContext.getPackageManager().getPackageUid(pkg, 8707 Binder.getCallingUserHandle().getIdentifier()); 8708 if (uid != callingUid) { 8709 throw new SecurityException("Invalid uid, expected " + uid); 8710 } 8711 } catch (NameNotFoundException e) { 8712 Log.d(TAG, "stopLockTaskMode " + e); 8713 return; 8714 } 8715 } 8716 long ident = Binder.clearCallingIdentity(); 8717 try { 8718 Log.d(TAG, "stopLockTaskMode"); 8719 // Stop lock task 8720 synchronized (this) { 8721 mStackSupervisor.setLockTaskModeLocked(null, false); 8722 } 8723 } finally { 8724 Binder.restoreCallingIdentity(ident); 8725 } 8726 } 8727 8728 @Override 8729 public void stopLockTaskModeOnCurrent() throws RemoteException { 8730 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8731 long ident = Binder.clearCallingIdentity(); 8732 try { 8733 stopLockTaskMode(); 8734 } finally { 8735 Binder.restoreCallingIdentity(ident); 8736 } 8737 } 8738 8739 @Override 8740 public boolean isInLockTaskMode() { 8741 synchronized (this) { 8742 return mStackSupervisor.isInLockTaskMode(); 8743 } 8744 } 8745 8746 // ========================================================= 8747 // CONTENT PROVIDERS 8748 // ========================================================= 8749 8750 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8751 List<ProviderInfo> providers = null; 8752 try { 8753 providers = AppGlobals.getPackageManager(). 8754 queryContentProviders(app.processName, app.uid, 8755 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8756 } catch (RemoteException ex) { 8757 } 8758 if (DEBUG_MU) 8759 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8760 int userId = app.userId; 8761 if (providers != null) { 8762 int N = providers.size(); 8763 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8764 for (int i=0; i<N; i++) { 8765 ProviderInfo cpi = 8766 (ProviderInfo)providers.get(i); 8767 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8768 cpi.name, cpi.flags); 8769 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8770 // This is a singleton provider, but a user besides the 8771 // default user is asking to initialize a process it runs 8772 // in... well, no, it doesn't actually run in this process, 8773 // it runs in the process of the default user. Get rid of it. 8774 providers.remove(i); 8775 N--; 8776 i--; 8777 continue; 8778 } 8779 8780 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8781 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8782 if (cpr == null) { 8783 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8784 mProviderMap.putProviderByClass(comp, cpr); 8785 } 8786 if (DEBUG_MU) 8787 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8788 app.pubProviders.put(cpi.name, cpr); 8789 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8790 // Don't add this if it is a platform component that is marked 8791 // to run in multiple processes, because this is actually 8792 // part of the framework so doesn't make sense to track as a 8793 // separate apk in the process. 8794 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8795 mProcessStats); 8796 } 8797 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8798 } 8799 } 8800 return providers; 8801 } 8802 8803 /** 8804 * Check if {@link ProcessRecord} has a possible chance at accessing the 8805 * given {@link ProviderInfo}. Final permission checking is always done 8806 * in {@link ContentProvider}. 8807 */ 8808 private final String checkContentProviderPermissionLocked( 8809 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8810 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8811 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8812 boolean checkedGrants = false; 8813 if (checkUser) { 8814 // Looking for cross-user grants before enforcing the typical cross-users permissions 8815 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8816 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8817 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8818 return null; 8819 } 8820 checkedGrants = true; 8821 } 8822 userId = handleIncomingUser(callingPid, callingUid, userId, 8823 false, ALLOW_NON_FULL, 8824 "checkContentProviderPermissionLocked " + cpi.authority, null); 8825 if (userId != tmpTargetUserId) { 8826 // When we actually went to determine the final targer user ID, this ended 8827 // up different than our initial check for the authority. This is because 8828 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8829 // SELF. So we need to re-check the grants again. 8830 checkedGrants = false; 8831 } 8832 } 8833 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8834 cpi.applicationInfo.uid, cpi.exported) 8835 == PackageManager.PERMISSION_GRANTED) { 8836 return null; 8837 } 8838 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8839 cpi.applicationInfo.uid, cpi.exported) 8840 == PackageManager.PERMISSION_GRANTED) { 8841 return null; 8842 } 8843 8844 PathPermission[] pps = cpi.pathPermissions; 8845 if (pps != null) { 8846 int i = pps.length; 8847 while (i > 0) { 8848 i--; 8849 PathPermission pp = pps[i]; 8850 String pprperm = pp.getReadPermission(); 8851 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8852 cpi.applicationInfo.uid, cpi.exported) 8853 == PackageManager.PERMISSION_GRANTED) { 8854 return null; 8855 } 8856 String ppwperm = pp.getWritePermission(); 8857 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8858 cpi.applicationInfo.uid, cpi.exported) 8859 == PackageManager.PERMISSION_GRANTED) { 8860 return null; 8861 } 8862 } 8863 } 8864 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8865 return null; 8866 } 8867 8868 String msg; 8869 if (!cpi.exported) { 8870 msg = "Permission Denial: opening provider " + cpi.name 8871 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8872 + ", uid=" + callingUid + ") that is not exported from uid " 8873 + cpi.applicationInfo.uid; 8874 } else { 8875 msg = "Permission Denial: opening provider " + cpi.name 8876 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8877 + ", uid=" + callingUid + ") requires " 8878 + cpi.readPermission + " or " + cpi.writePermission; 8879 } 8880 Slog.w(TAG, msg); 8881 return msg; 8882 } 8883 8884 /** 8885 * Returns if the ContentProvider has granted a uri to callingUid 8886 */ 8887 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8888 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8889 if (perms != null) { 8890 for (int i=perms.size()-1; i>=0; i--) { 8891 GrantUri grantUri = perms.keyAt(i); 8892 if (grantUri.sourceUserId == userId || !checkUser) { 8893 if (matchesProvider(grantUri.uri, cpi)) { 8894 return true; 8895 } 8896 } 8897 } 8898 } 8899 return false; 8900 } 8901 8902 /** 8903 * Returns true if the uri authority is one of the authorities specified in the provider. 8904 */ 8905 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8906 String uriAuth = uri.getAuthority(); 8907 String cpiAuth = cpi.authority; 8908 if (cpiAuth.indexOf(';') == -1) { 8909 return cpiAuth.equals(uriAuth); 8910 } 8911 String[] cpiAuths = cpiAuth.split(";"); 8912 int length = cpiAuths.length; 8913 for (int i = 0; i < length; i++) { 8914 if (cpiAuths[i].equals(uriAuth)) return true; 8915 } 8916 return false; 8917 } 8918 8919 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8920 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8921 if (r != null) { 8922 for (int i=0; i<r.conProviders.size(); i++) { 8923 ContentProviderConnection conn = r.conProviders.get(i); 8924 if (conn.provider == cpr) { 8925 if (DEBUG_PROVIDER) Slog.v(TAG, 8926 "Adding provider requested by " 8927 + r.processName + " from process " 8928 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8929 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8930 if (stable) { 8931 conn.stableCount++; 8932 conn.numStableIncs++; 8933 } else { 8934 conn.unstableCount++; 8935 conn.numUnstableIncs++; 8936 } 8937 return conn; 8938 } 8939 } 8940 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8941 if (stable) { 8942 conn.stableCount = 1; 8943 conn.numStableIncs = 1; 8944 } else { 8945 conn.unstableCount = 1; 8946 conn.numUnstableIncs = 1; 8947 } 8948 cpr.connections.add(conn); 8949 r.conProviders.add(conn); 8950 return conn; 8951 } 8952 cpr.addExternalProcessHandleLocked(externalProcessToken); 8953 return null; 8954 } 8955 8956 boolean decProviderCountLocked(ContentProviderConnection conn, 8957 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8958 if (conn != null) { 8959 cpr = conn.provider; 8960 if (DEBUG_PROVIDER) Slog.v(TAG, 8961 "Removing provider requested by " 8962 + conn.client.processName + " from process " 8963 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8964 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8965 if (stable) { 8966 conn.stableCount--; 8967 } else { 8968 conn.unstableCount--; 8969 } 8970 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8971 cpr.connections.remove(conn); 8972 conn.client.conProviders.remove(conn); 8973 return true; 8974 } 8975 return false; 8976 } 8977 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8978 return false; 8979 } 8980 8981 private void checkTime(long startTime, String where) { 8982 long now = SystemClock.elapsedRealtime(); 8983 if ((now-startTime) > 1000) { 8984 // If we are taking more than a second, log about it. 8985 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 8986 } 8987 } 8988 8989 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8990 String name, IBinder token, boolean stable, int userId) { 8991 ContentProviderRecord cpr; 8992 ContentProviderConnection conn = null; 8993 ProviderInfo cpi = null; 8994 8995 synchronized(this) { 8996 long startTime = SystemClock.elapsedRealtime(); 8997 8998 ProcessRecord r = null; 8999 if (caller != null) { 9000 r = getRecordForAppLocked(caller); 9001 if (r == null) { 9002 throw new SecurityException( 9003 "Unable to find app for caller " + caller 9004 + " (pid=" + Binder.getCallingPid() 9005 + ") when getting content provider " + name); 9006 } 9007 } 9008 9009 boolean checkCrossUser = true; 9010 9011 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9012 9013 // First check if this content provider has been published... 9014 cpr = mProviderMap.getProviderByName(name, userId); 9015 // If that didn't work, check if it exists for user 0 and then 9016 // verify that it's a singleton provider before using it. 9017 if (cpr == null && userId != UserHandle.USER_OWNER) { 9018 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9019 if (cpr != null) { 9020 cpi = cpr.info; 9021 if (isSingleton(cpi.processName, cpi.applicationInfo, 9022 cpi.name, cpi.flags) 9023 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9024 userId = UserHandle.USER_OWNER; 9025 checkCrossUser = false; 9026 } else { 9027 cpr = null; 9028 cpi = null; 9029 } 9030 } 9031 } 9032 9033 boolean providerRunning = cpr != null; 9034 if (providerRunning) { 9035 cpi = cpr.info; 9036 String msg; 9037 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9038 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9039 != null) { 9040 throw new SecurityException(msg); 9041 } 9042 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9043 9044 if (r != null && cpr.canRunHere(r)) { 9045 // This provider has been published or is in the process 9046 // of being published... but it is also allowed to run 9047 // in the caller's process, so don't make a connection 9048 // and just let the caller instantiate its own instance. 9049 ContentProviderHolder holder = cpr.newHolder(null); 9050 // don't give caller the provider object, it needs 9051 // to make its own. 9052 holder.provider = null; 9053 return holder; 9054 } 9055 9056 final long origId = Binder.clearCallingIdentity(); 9057 9058 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9059 9060 // In this case the provider instance already exists, so we can 9061 // return it right away. 9062 conn = incProviderCountLocked(r, cpr, token, stable); 9063 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9064 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9065 // If this is a perceptible app accessing the provider, 9066 // make sure to count it as being accessed and thus 9067 // back up on the LRU list. This is good because 9068 // content providers are often expensive to start. 9069 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9070 updateLruProcessLocked(cpr.proc, false, null); 9071 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9072 } 9073 } 9074 9075 if (cpr.proc != null) { 9076 if (false) { 9077 if (cpr.name.flattenToShortString().equals( 9078 "com.android.providers.calendar/.CalendarProvider2")) { 9079 Slog.v(TAG, "****************** KILLING " 9080 + cpr.name.flattenToShortString()); 9081 Process.killProcess(cpr.proc.pid); 9082 } 9083 } 9084 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9085 boolean success = updateOomAdjLocked(cpr.proc); 9086 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9087 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9088 // NOTE: there is still a race here where a signal could be 9089 // pending on the process even though we managed to update its 9090 // adj level. Not sure what to do about this, but at least 9091 // the race is now smaller. 9092 if (!success) { 9093 // Uh oh... it looks like the provider's process 9094 // has been killed on us. We need to wait for a new 9095 // process to be started, and make sure its death 9096 // doesn't kill our process. 9097 Slog.i(TAG, 9098 "Existing provider " + cpr.name.flattenToShortString() 9099 + " is crashing; detaching " + r); 9100 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9101 checkTime(startTime, "getContentProviderImpl: before appDied"); 9102 appDiedLocked(cpr.proc); 9103 checkTime(startTime, "getContentProviderImpl: after appDied"); 9104 if (!lastRef) { 9105 // This wasn't the last ref our process had on 9106 // the provider... we have now been killed, bail. 9107 return null; 9108 } 9109 providerRunning = false; 9110 conn = null; 9111 } 9112 } 9113 9114 Binder.restoreCallingIdentity(origId); 9115 } 9116 9117 boolean singleton; 9118 if (!providerRunning) { 9119 try { 9120 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9121 cpi = AppGlobals.getPackageManager(). 9122 resolveContentProvider(name, 9123 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9124 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9125 } catch (RemoteException ex) { 9126 } 9127 if (cpi == null) { 9128 return null; 9129 } 9130 // If the provider is a singleton AND 9131 // (it's a call within the same user || the provider is a 9132 // privileged app) 9133 // Then allow connecting to the singleton provider 9134 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9135 cpi.name, cpi.flags) 9136 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9137 if (singleton) { 9138 userId = UserHandle.USER_OWNER; 9139 } 9140 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9141 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9142 9143 String msg; 9144 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9145 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9146 != null) { 9147 throw new SecurityException(msg); 9148 } 9149 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9150 9151 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9152 && !cpi.processName.equals("system")) { 9153 // If this content provider does not run in the system 9154 // process, and the system is not yet ready to run other 9155 // processes, then fail fast instead of hanging. 9156 throw new IllegalArgumentException( 9157 "Attempt to launch content provider before system ready"); 9158 } 9159 9160 // Make sure that the user who owns this provider is started. If not, 9161 // we don't want to allow it to run. 9162 if (mStartedUsers.get(userId) == null) { 9163 Slog.w(TAG, "Unable to launch app " 9164 + cpi.applicationInfo.packageName + "/" 9165 + cpi.applicationInfo.uid + " for provider " 9166 + name + ": user " + userId + " is stopped"); 9167 return null; 9168 } 9169 9170 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9171 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9172 cpr = mProviderMap.getProviderByClass(comp, userId); 9173 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9174 final boolean firstClass = cpr == null; 9175 if (firstClass) { 9176 try { 9177 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9178 ApplicationInfo ai = 9179 AppGlobals.getPackageManager(). 9180 getApplicationInfo( 9181 cpi.applicationInfo.packageName, 9182 STOCK_PM_FLAGS, userId); 9183 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9184 if (ai == null) { 9185 Slog.w(TAG, "No package info for content provider " 9186 + cpi.name); 9187 return null; 9188 } 9189 ai = getAppInfoForUser(ai, userId); 9190 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9191 } catch (RemoteException ex) { 9192 // pm is in same process, this will never happen. 9193 } 9194 } 9195 9196 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9197 9198 if (r != null && cpr.canRunHere(r)) { 9199 // If this is a multiprocess provider, then just return its 9200 // info and allow the caller to instantiate it. Only do 9201 // this if the provider is the same user as the caller's 9202 // process, or can run as root (so can be in any process). 9203 return cpr.newHolder(null); 9204 } 9205 9206 if (DEBUG_PROVIDER) { 9207 RuntimeException e = new RuntimeException("here"); 9208 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9209 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9210 } 9211 9212 // This is single process, and our app is now connecting to it. 9213 // See if we are already in the process of launching this 9214 // provider. 9215 final int N = mLaunchingProviders.size(); 9216 int i; 9217 for (i=0; i<N; i++) { 9218 if (mLaunchingProviders.get(i) == cpr) { 9219 break; 9220 } 9221 } 9222 9223 // If the provider is not already being launched, then get it 9224 // started. 9225 if (i >= N) { 9226 final long origId = Binder.clearCallingIdentity(); 9227 9228 try { 9229 // Content provider is now in use, its package can't be stopped. 9230 try { 9231 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9232 AppGlobals.getPackageManager().setPackageStoppedState( 9233 cpr.appInfo.packageName, false, userId); 9234 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9235 } catch (RemoteException e) { 9236 } catch (IllegalArgumentException e) { 9237 Slog.w(TAG, "Failed trying to unstop package " 9238 + cpr.appInfo.packageName + ": " + e); 9239 } 9240 9241 // Use existing process if already started 9242 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9243 ProcessRecord proc = getProcessRecordLocked( 9244 cpi.processName, cpr.appInfo.uid, false); 9245 if (proc != null && proc.thread != null) { 9246 if (DEBUG_PROVIDER) { 9247 Slog.d(TAG, "Installing in existing process " + proc); 9248 } 9249 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9250 proc.pubProviders.put(cpi.name, cpr); 9251 try { 9252 proc.thread.scheduleInstallProvider(cpi); 9253 } catch (RemoteException e) { 9254 } 9255 } else { 9256 checkTime(startTime, "getContentProviderImpl: before start process"); 9257 proc = startProcessLocked(cpi.processName, 9258 cpr.appInfo, false, 0, "content provider", 9259 new ComponentName(cpi.applicationInfo.packageName, 9260 cpi.name), false, false, false); 9261 checkTime(startTime, "getContentProviderImpl: after start process"); 9262 if (proc == null) { 9263 Slog.w(TAG, "Unable to launch app " 9264 + cpi.applicationInfo.packageName + "/" 9265 + cpi.applicationInfo.uid + " for provider " 9266 + name + ": process is bad"); 9267 return null; 9268 } 9269 } 9270 cpr.launchingApp = proc; 9271 mLaunchingProviders.add(cpr); 9272 } finally { 9273 Binder.restoreCallingIdentity(origId); 9274 } 9275 } 9276 9277 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9278 9279 // Make sure the provider is published (the same provider class 9280 // may be published under multiple names). 9281 if (firstClass) { 9282 mProviderMap.putProviderByClass(comp, cpr); 9283 } 9284 9285 mProviderMap.putProviderByName(name, cpr); 9286 conn = incProviderCountLocked(r, cpr, token, stable); 9287 if (conn != null) { 9288 conn.waiting = true; 9289 } 9290 } 9291 checkTime(startTime, "getContentProviderImpl: done!"); 9292 } 9293 9294 // Wait for the provider to be published... 9295 synchronized (cpr) { 9296 while (cpr.provider == null) { 9297 if (cpr.launchingApp == null) { 9298 Slog.w(TAG, "Unable to launch app " 9299 + cpi.applicationInfo.packageName + "/" 9300 + cpi.applicationInfo.uid + " for provider " 9301 + name + ": launching app became null"); 9302 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9303 UserHandle.getUserId(cpi.applicationInfo.uid), 9304 cpi.applicationInfo.packageName, 9305 cpi.applicationInfo.uid, name); 9306 return null; 9307 } 9308 try { 9309 if (DEBUG_MU) { 9310 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9311 + cpr.launchingApp); 9312 } 9313 if (conn != null) { 9314 conn.waiting = true; 9315 } 9316 cpr.wait(); 9317 } catch (InterruptedException ex) { 9318 } finally { 9319 if (conn != null) { 9320 conn.waiting = false; 9321 } 9322 } 9323 } 9324 } 9325 return cpr != null ? cpr.newHolder(conn) : null; 9326 } 9327 9328 @Override 9329 public final ContentProviderHolder getContentProvider( 9330 IApplicationThread caller, String name, int userId, boolean stable) { 9331 enforceNotIsolatedCaller("getContentProvider"); 9332 if (caller == null) { 9333 String msg = "null IApplicationThread when getting content provider " 9334 + name; 9335 Slog.w(TAG, msg); 9336 throw new SecurityException(msg); 9337 } 9338 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9339 // with cross-user grant. 9340 return getContentProviderImpl(caller, name, null, stable, userId); 9341 } 9342 9343 public ContentProviderHolder getContentProviderExternal( 9344 String name, int userId, IBinder token) { 9345 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9346 "Do not have permission in call getContentProviderExternal()"); 9347 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9348 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9349 return getContentProviderExternalUnchecked(name, token, userId); 9350 } 9351 9352 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9353 IBinder token, int userId) { 9354 return getContentProviderImpl(null, name, token, true, userId); 9355 } 9356 9357 /** 9358 * Drop a content provider from a ProcessRecord's bookkeeping 9359 */ 9360 public void removeContentProvider(IBinder connection, boolean stable) { 9361 enforceNotIsolatedCaller("removeContentProvider"); 9362 long ident = Binder.clearCallingIdentity(); 9363 try { 9364 synchronized (this) { 9365 ContentProviderConnection conn; 9366 try { 9367 conn = (ContentProviderConnection)connection; 9368 } catch (ClassCastException e) { 9369 String msg ="removeContentProvider: " + connection 9370 + " not a ContentProviderConnection"; 9371 Slog.w(TAG, msg); 9372 throw new IllegalArgumentException(msg); 9373 } 9374 if (conn == null) { 9375 throw new NullPointerException("connection is null"); 9376 } 9377 if (decProviderCountLocked(conn, null, null, stable)) { 9378 updateOomAdjLocked(); 9379 } 9380 } 9381 } finally { 9382 Binder.restoreCallingIdentity(ident); 9383 } 9384 } 9385 9386 public void removeContentProviderExternal(String name, IBinder token) { 9387 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9388 "Do not have permission in call removeContentProviderExternal()"); 9389 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9390 } 9391 9392 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9393 synchronized (this) { 9394 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9395 if(cpr == null) { 9396 //remove from mProvidersByClass 9397 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9398 return; 9399 } 9400 9401 //update content provider record entry info 9402 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9403 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9404 if (localCpr.hasExternalProcessHandles()) { 9405 if (localCpr.removeExternalProcessHandleLocked(token)) { 9406 updateOomAdjLocked(); 9407 } else { 9408 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9409 + " with no external reference for token: " 9410 + token + "."); 9411 } 9412 } else { 9413 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9414 + " with no external references."); 9415 } 9416 } 9417 } 9418 9419 public final void publishContentProviders(IApplicationThread caller, 9420 List<ContentProviderHolder> providers) { 9421 if (providers == null) { 9422 return; 9423 } 9424 9425 enforceNotIsolatedCaller("publishContentProviders"); 9426 synchronized (this) { 9427 final ProcessRecord r = getRecordForAppLocked(caller); 9428 if (DEBUG_MU) 9429 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9430 if (r == null) { 9431 throw new SecurityException( 9432 "Unable to find app for caller " + caller 9433 + " (pid=" + Binder.getCallingPid() 9434 + ") when publishing content providers"); 9435 } 9436 9437 final long origId = Binder.clearCallingIdentity(); 9438 9439 final int N = providers.size(); 9440 for (int i=0; i<N; i++) { 9441 ContentProviderHolder src = providers.get(i); 9442 if (src == null || src.info == null || src.provider == null) { 9443 continue; 9444 } 9445 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9446 if (DEBUG_MU) 9447 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9448 if (dst != null) { 9449 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9450 mProviderMap.putProviderByClass(comp, dst); 9451 String names[] = dst.info.authority.split(";"); 9452 for (int j = 0; j < names.length; j++) { 9453 mProviderMap.putProviderByName(names[j], dst); 9454 } 9455 9456 int NL = mLaunchingProviders.size(); 9457 int j; 9458 for (j=0; j<NL; j++) { 9459 if (mLaunchingProviders.get(j) == dst) { 9460 mLaunchingProviders.remove(j); 9461 j--; 9462 NL--; 9463 } 9464 } 9465 synchronized (dst) { 9466 dst.provider = src.provider; 9467 dst.proc = r; 9468 dst.notifyAll(); 9469 } 9470 updateOomAdjLocked(r); 9471 } 9472 } 9473 9474 Binder.restoreCallingIdentity(origId); 9475 } 9476 } 9477 9478 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9479 ContentProviderConnection conn; 9480 try { 9481 conn = (ContentProviderConnection)connection; 9482 } catch (ClassCastException e) { 9483 String msg ="refContentProvider: " + connection 9484 + " not a ContentProviderConnection"; 9485 Slog.w(TAG, msg); 9486 throw new IllegalArgumentException(msg); 9487 } 9488 if (conn == null) { 9489 throw new NullPointerException("connection is null"); 9490 } 9491 9492 synchronized (this) { 9493 if (stable > 0) { 9494 conn.numStableIncs += stable; 9495 } 9496 stable = conn.stableCount + stable; 9497 if (stable < 0) { 9498 throw new IllegalStateException("stableCount < 0: " + stable); 9499 } 9500 9501 if (unstable > 0) { 9502 conn.numUnstableIncs += unstable; 9503 } 9504 unstable = conn.unstableCount + unstable; 9505 if (unstable < 0) { 9506 throw new IllegalStateException("unstableCount < 0: " + unstable); 9507 } 9508 9509 if ((stable+unstable) <= 0) { 9510 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9511 + stable + " unstable=" + unstable); 9512 } 9513 conn.stableCount = stable; 9514 conn.unstableCount = unstable; 9515 return !conn.dead; 9516 } 9517 } 9518 9519 public void unstableProviderDied(IBinder connection) { 9520 ContentProviderConnection conn; 9521 try { 9522 conn = (ContentProviderConnection)connection; 9523 } catch (ClassCastException e) { 9524 String msg ="refContentProvider: " + connection 9525 + " not a ContentProviderConnection"; 9526 Slog.w(TAG, msg); 9527 throw new IllegalArgumentException(msg); 9528 } 9529 if (conn == null) { 9530 throw new NullPointerException("connection is null"); 9531 } 9532 9533 // Safely retrieve the content provider associated with the connection. 9534 IContentProvider provider; 9535 synchronized (this) { 9536 provider = conn.provider.provider; 9537 } 9538 9539 if (provider == null) { 9540 // Um, yeah, we're way ahead of you. 9541 return; 9542 } 9543 9544 // Make sure the caller is being honest with us. 9545 if (provider.asBinder().pingBinder()) { 9546 // Er, no, still looks good to us. 9547 synchronized (this) { 9548 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9549 + " says " + conn + " died, but we don't agree"); 9550 return; 9551 } 9552 } 9553 9554 // Well look at that! It's dead! 9555 synchronized (this) { 9556 if (conn.provider.provider != provider) { 9557 // But something changed... good enough. 9558 return; 9559 } 9560 9561 ProcessRecord proc = conn.provider.proc; 9562 if (proc == null || proc.thread == null) { 9563 // Seems like the process is already cleaned up. 9564 return; 9565 } 9566 9567 // As far as we're concerned, this is just like receiving a 9568 // death notification... just a bit prematurely. 9569 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9570 + ") early provider death"); 9571 final long ident = Binder.clearCallingIdentity(); 9572 try { 9573 appDiedLocked(proc); 9574 } finally { 9575 Binder.restoreCallingIdentity(ident); 9576 } 9577 } 9578 } 9579 9580 @Override 9581 public void appNotRespondingViaProvider(IBinder connection) { 9582 enforceCallingPermission( 9583 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9584 9585 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9586 if (conn == null) { 9587 Slog.w(TAG, "ContentProviderConnection is null"); 9588 return; 9589 } 9590 9591 final ProcessRecord host = conn.provider.proc; 9592 if (host == null) { 9593 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9594 return; 9595 } 9596 9597 final long token = Binder.clearCallingIdentity(); 9598 try { 9599 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9600 } finally { 9601 Binder.restoreCallingIdentity(token); 9602 } 9603 } 9604 9605 public final void installSystemProviders() { 9606 List<ProviderInfo> providers; 9607 synchronized (this) { 9608 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9609 providers = generateApplicationProvidersLocked(app); 9610 if (providers != null) { 9611 for (int i=providers.size()-1; i>=0; i--) { 9612 ProviderInfo pi = (ProviderInfo)providers.get(i); 9613 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9614 Slog.w(TAG, "Not installing system proc provider " + pi.name 9615 + ": not system .apk"); 9616 providers.remove(i); 9617 } 9618 } 9619 } 9620 } 9621 if (providers != null) { 9622 mSystemThread.installSystemProviders(providers); 9623 } 9624 9625 mCoreSettingsObserver = new CoreSettingsObserver(this); 9626 9627 //mUsageStatsService.monitorPackages(); 9628 } 9629 9630 /** 9631 * Allows apps to retrieve the MIME type of a URI. 9632 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9633 * users, then it does not need permission to access the ContentProvider. 9634 * Either, it needs cross-user uri grants. 9635 * 9636 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9637 * 9638 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9639 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9640 */ 9641 public String getProviderMimeType(Uri uri, int userId) { 9642 enforceNotIsolatedCaller("getProviderMimeType"); 9643 final String name = uri.getAuthority(); 9644 int callingUid = Binder.getCallingUid(); 9645 int callingPid = Binder.getCallingPid(); 9646 long ident = 0; 9647 boolean clearedIdentity = false; 9648 userId = unsafeConvertIncomingUser(userId); 9649 if (UserHandle.getUserId(callingUid) != userId) { 9650 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9651 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9652 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9653 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9654 clearedIdentity = true; 9655 ident = Binder.clearCallingIdentity(); 9656 } 9657 } 9658 ContentProviderHolder holder = null; 9659 try { 9660 holder = getContentProviderExternalUnchecked(name, null, userId); 9661 if (holder != null) { 9662 return holder.provider.getType(uri); 9663 } 9664 } catch (RemoteException e) { 9665 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9666 return null; 9667 } finally { 9668 // We need to clear the identity to call removeContentProviderExternalUnchecked 9669 if (!clearedIdentity) { 9670 ident = Binder.clearCallingIdentity(); 9671 } 9672 try { 9673 if (holder != null) { 9674 removeContentProviderExternalUnchecked(name, null, userId); 9675 } 9676 } finally { 9677 Binder.restoreCallingIdentity(ident); 9678 } 9679 } 9680 9681 return null; 9682 } 9683 9684 // ========================================================= 9685 // GLOBAL MANAGEMENT 9686 // ========================================================= 9687 9688 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9689 boolean isolated, int isolatedUid) { 9690 String proc = customProcess != null ? customProcess : info.processName; 9691 BatteryStatsImpl.Uid.Proc ps = null; 9692 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9693 int uid = info.uid; 9694 if (isolated) { 9695 if (isolatedUid == 0) { 9696 int userId = UserHandle.getUserId(uid); 9697 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9698 while (true) { 9699 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9700 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9701 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9702 } 9703 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9704 mNextIsolatedProcessUid++; 9705 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9706 // No process for this uid, use it. 9707 break; 9708 } 9709 stepsLeft--; 9710 if (stepsLeft <= 0) { 9711 return null; 9712 } 9713 } 9714 } else { 9715 // Special case for startIsolatedProcess (internal only), where 9716 // the uid of the isolated process is specified by the caller. 9717 uid = isolatedUid; 9718 } 9719 } 9720 return new ProcessRecord(stats, info, proc, uid); 9721 } 9722 9723 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9724 String abiOverride) { 9725 ProcessRecord app; 9726 if (!isolated) { 9727 app = getProcessRecordLocked(info.processName, info.uid, true); 9728 } else { 9729 app = null; 9730 } 9731 9732 if (app == null) { 9733 app = newProcessRecordLocked(info, null, isolated, 0); 9734 mProcessNames.put(info.processName, app.uid, app); 9735 if (isolated) { 9736 mIsolatedProcesses.put(app.uid, app); 9737 } 9738 updateLruProcessLocked(app, false, null); 9739 updateOomAdjLocked(); 9740 } 9741 9742 // This package really, really can not be stopped. 9743 try { 9744 AppGlobals.getPackageManager().setPackageStoppedState( 9745 info.packageName, false, UserHandle.getUserId(app.uid)); 9746 } catch (RemoteException e) { 9747 } catch (IllegalArgumentException e) { 9748 Slog.w(TAG, "Failed trying to unstop package " 9749 + info.packageName + ": " + e); 9750 } 9751 9752 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9753 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9754 app.persistent = true; 9755 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9756 } 9757 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9758 mPersistentStartingProcesses.add(app); 9759 startProcessLocked(app, "added application", app.processName, abiOverride, 9760 null /* entryPoint */, null /* entryPointArgs */); 9761 } 9762 9763 return app; 9764 } 9765 9766 public void unhandledBack() { 9767 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9768 "unhandledBack()"); 9769 9770 synchronized(this) { 9771 final long origId = Binder.clearCallingIdentity(); 9772 try { 9773 getFocusedStack().unhandledBackLocked(); 9774 } finally { 9775 Binder.restoreCallingIdentity(origId); 9776 } 9777 } 9778 } 9779 9780 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9781 enforceNotIsolatedCaller("openContentUri"); 9782 final int userId = UserHandle.getCallingUserId(); 9783 String name = uri.getAuthority(); 9784 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9785 ParcelFileDescriptor pfd = null; 9786 if (cph != null) { 9787 // We record the binder invoker's uid in thread-local storage before 9788 // going to the content provider to open the file. Later, in the code 9789 // that handles all permissions checks, we look for this uid and use 9790 // that rather than the Activity Manager's own uid. The effect is that 9791 // we do the check against the caller's permissions even though it looks 9792 // to the content provider like the Activity Manager itself is making 9793 // the request. 9794 sCallerIdentity.set(new Identity( 9795 Binder.getCallingPid(), Binder.getCallingUid())); 9796 try { 9797 pfd = cph.provider.openFile(null, uri, "r", null); 9798 } catch (FileNotFoundException e) { 9799 // do nothing; pfd will be returned null 9800 } finally { 9801 // Ensure that whatever happens, we clean up the identity state 9802 sCallerIdentity.remove(); 9803 } 9804 9805 // We've got the fd now, so we're done with the provider. 9806 removeContentProviderExternalUnchecked(name, null, userId); 9807 } else { 9808 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9809 } 9810 return pfd; 9811 } 9812 9813 // Actually is sleeping or shutting down or whatever else in the future 9814 // is an inactive state. 9815 public boolean isSleepingOrShuttingDown() { 9816 return mSleeping || mShuttingDown; 9817 } 9818 9819 public boolean isSleeping() { 9820 return mSleeping; 9821 } 9822 9823 void goingToSleep() { 9824 synchronized(this) { 9825 mWentToSleep = true; 9826 updateEventDispatchingLocked(); 9827 goToSleepIfNeededLocked(); 9828 } 9829 } 9830 9831 void finishRunningVoiceLocked() { 9832 if (mRunningVoice) { 9833 mRunningVoice = false; 9834 goToSleepIfNeededLocked(); 9835 } 9836 } 9837 9838 void goToSleepIfNeededLocked() { 9839 if (mWentToSleep && !mRunningVoice) { 9840 if (!mSleeping) { 9841 mSleeping = true; 9842 mStackSupervisor.goingToSleepLocked(); 9843 9844 // Initialize the wake times of all processes. 9845 checkExcessivePowerUsageLocked(false); 9846 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9847 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9848 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9849 } 9850 } 9851 } 9852 9853 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9854 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9855 // Never persist the home stack. 9856 return; 9857 } 9858 mTaskPersister.wakeup(task, flush); 9859 } 9860 9861 @Override 9862 public boolean shutdown(int timeout) { 9863 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9864 != PackageManager.PERMISSION_GRANTED) { 9865 throw new SecurityException("Requires permission " 9866 + android.Manifest.permission.SHUTDOWN); 9867 } 9868 9869 boolean timedout = false; 9870 9871 synchronized(this) { 9872 mShuttingDown = true; 9873 updateEventDispatchingLocked(); 9874 timedout = mStackSupervisor.shutdownLocked(timeout); 9875 } 9876 9877 mAppOpsService.shutdown(); 9878 if (mUsageStatsService != null) { 9879 mUsageStatsService.prepareShutdown(); 9880 } 9881 mBatteryStatsService.shutdown(); 9882 synchronized (this) { 9883 mProcessStats.shutdownLocked(); 9884 } 9885 notifyTaskPersisterLocked(null, true); 9886 9887 return timedout; 9888 } 9889 9890 public final void activitySlept(IBinder token) { 9891 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9892 9893 final long origId = Binder.clearCallingIdentity(); 9894 9895 synchronized (this) { 9896 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9897 if (r != null) { 9898 mStackSupervisor.activitySleptLocked(r); 9899 } 9900 } 9901 9902 Binder.restoreCallingIdentity(origId); 9903 } 9904 9905 void logLockScreen(String msg) { 9906 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9907 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9908 mWentToSleep + " mSleeping=" + mSleeping); 9909 } 9910 9911 private void comeOutOfSleepIfNeededLocked() { 9912 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9913 if (mSleeping) { 9914 mSleeping = false; 9915 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9916 } 9917 } 9918 } 9919 9920 void wakingUp() { 9921 synchronized(this) { 9922 mWentToSleep = false; 9923 updateEventDispatchingLocked(); 9924 comeOutOfSleepIfNeededLocked(); 9925 } 9926 } 9927 9928 void startRunningVoiceLocked() { 9929 if (!mRunningVoice) { 9930 mRunningVoice = true; 9931 comeOutOfSleepIfNeededLocked(); 9932 } 9933 } 9934 9935 private void updateEventDispatchingLocked() { 9936 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9937 } 9938 9939 public void setLockScreenShown(boolean shown) { 9940 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9941 != PackageManager.PERMISSION_GRANTED) { 9942 throw new SecurityException("Requires permission " 9943 + android.Manifest.permission.DEVICE_POWER); 9944 } 9945 9946 synchronized(this) { 9947 long ident = Binder.clearCallingIdentity(); 9948 try { 9949 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9950 mLockScreenShown = shown; 9951 comeOutOfSleepIfNeededLocked(); 9952 } finally { 9953 Binder.restoreCallingIdentity(ident); 9954 } 9955 } 9956 } 9957 9958 @Override 9959 public void stopAppSwitches() { 9960 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9961 != PackageManager.PERMISSION_GRANTED) { 9962 throw new SecurityException("Requires permission " 9963 + android.Manifest.permission.STOP_APP_SWITCHES); 9964 } 9965 9966 synchronized(this) { 9967 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9968 + APP_SWITCH_DELAY_TIME; 9969 mDidAppSwitch = false; 9970 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9971 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9972 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9973 } 9974 } 9975 9976 public void resumeAppSwitches() { 9977 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9978 != PackageManager.PERMISSION_GRANTED) { 9979 throw new SecurityException("Requires permission " 9980 + android.Manifest.permission.STOP_APP_SWITCHES); 9981 } 9982 9983 synchronized(this) { 9984 // Note that we don't execute any pending app switches... we will 9985 // let those wait until either the timeout, or the next start 9986 // activity request. 9987 mAppSwitchesAllowedTime = 0; 9988 } 9989 } 9990 9991 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9992 String name) { 9993 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9994 return true; 9995 } 9996 9997 final int perm = checkComponentPermission( 9998 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9999 callingUid, -1, true); 10000 if (perm == PackageManager.PERMISSION_GRANTED) { 10001 return true; 10002 } 10003 10004 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 10005 return false; 10006 } 10007 10008 public void setDebugApp(String packageName, boolean waitForDebugger, 10009 boolean persistent) { 10010 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10011 "setDebugApp()"); 10012 10013 long ident = Binder.clearCallingIdentity(); 10014 try { 10015 // Note that this is not really thread safe if there are multiple 10016 // callers into it at the same time, but that's not a situation we 10017 // care about. 10018 if (persistent) { 10019 final ContentResolver resolver = mContext.getContentResolver(); 10020 Settings.Global.putString( 10021 resolver, Settings.Global.DEBUG_APP, 10022 packageName); 10023 Settings.Global.putInt( 10024 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10025 waitForDebugger ? 1 : 0); 10026 } 10027 10028 synchronized (this) { 10029 if (!persistent) { 10030 mOrigDebugApp = mDebugApp; 10031 mOrigWaitForDebugger = mWaitForDebugger; 10032 } 10033 mDebugApp = packageName; 10034 mWaitForDebugger = waitForDebugger; 10035 mDebugTransient = !persistent; 10036 if (packageName != null) { 10037 forceStopPackageLocked(packageName, -1, false, false, true, true, 10038 false, UserHandle.USER_ALL, "set debug app"); 10039 } 10040 } 10041 } finally { 10042 Binder.restoreCallingIdentity(ident); 10043 } 10044 } 10045 10046 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10047 synchronized (this) { 10048 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10049 if (!isDebuggable) { 10050 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10051 throw new SecurityException("Process not debuggable: " + app.packageName); 10052 } 10053 } 10054 10055 mOpenGlTraceApp = processName; 10056 } 10057 } 10058 10059 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10060 synchronized (this) { 10061 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10062 if (!isDebuggable) { 10063 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10064 throw new SecurityException("Process not debuggable: " + app.packageName); 10065 } 10066 } 10067 mProfileApp = processName; 10068 mProfileFile = profilerInfo.profileFile; 10069 if (mProfileFd != null) { 10070 try { 10071 mProfileFd.close(); 10072 } catch (IOException e) { 10073 } 10074 mProfileFd = null; 10075 } 10076 mProfileFd = profilerInfo.profileFd; 10077 mSamplingInterval = profilerInfo.samplingInterval; 10078 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10079 mProfileType = 0; 10080 } 10081 } 10082 10083 @Override 10084 public void setAlwaysFinish(boolean enabled) { 10085 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10086 "setAlwaysFinish()"); 10087 10088 Settings.Global.putInt( 10089 mContext.getContentResolver(), 10090 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10091 10092 synchronized (this) { 10093 mAlwaysFinishActivities = enabled; 10094 } 10095 } 10096 10097 @Override 10098 public void setActivityController(IActivityController controller) { 10099 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10100 "setActivityController()"); 10101 synchronized (this) { 10102 mController = controller; 10103 Watchdog.getInstance().setActivityController(controller); 10104 } 10105 } 10106 10107 @Override 10108 public void setUserIsMonkey(boolean userIsMonkey) { 10109 synchronized (this) { 10110 synchronized (mPidsSelfLocked) { 10111 final int callingPid = Binder.getCallingPid(); 10112 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10113 if (precessRecord == null) { 10114 throw new SecurityException("Unknown process: " + callingPid); 10115 } 10116 if (precessRecord.instrumentationUiAutomationConnection == null) { 10117 throw new SecurityException("Only an instrumentation process " 10118 + "with a UiAutomation can call setUserIsMonkey"); 10119 } 10120 } 10121 mUserIsMonkey = userIsMonkey; 10122 } 10123 } 10124 10125 @Override 10126 public boolean isUserAMonkey() { 10127 synchronized (this) { 10128 // If there is a controller also implies the user is a monkey. 10129 return (mUserIsMonkey || mController != null); 10130 } 10131 } 10132 10133 public void requestBugReport() { 10134 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10135 SystemProperties.set("ctl.start", "bugreport"); 10136 } 10137 10138 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10139 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10140 } 10141 10142 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10143 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10144 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10145 } 10146 return KEY_DISPATCHING_TIMEOUT; 10147 } 10148 10149 @Override 10150 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10151 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10152 != PackageManager.PERMISSION_GRANTED) { 10153 throw new SecurityException("Requires permission " 10154 + android.Manifest.permission.FILTER_EVENTS); 10155 } 10156 ProcessRecord proc; 10157 long timeout; 10158 synchronized (this) { 10159 synchronized (mPidsSelfLocked) { 10160 proc = mPidsSelfLocked.get(pid); 10161 } 10162 timeout = getInputDispatchingTimeoutLocked(proc); 10163 } 10164 10165 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10166 return -1; 10167 } 10168 10169 return timeout; 10170 } 10171 10172 /** 10173 * Handle input dispatching timeouts. 10174 * Returns whether input dispatching should be aborted or not. 10175 */ 10176 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10177 final ActivityRecord activity, final ActivityRecord parent, 10178 final boolean aboveSystem, String reason) { 10179 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10180 != PackageManager.PERMISSION_GRANTED) { 10181 throw new SecurityException("Requires permission " 10182 + android.Manifest.permission.FILTER_EVENTS); 10183 } 10184 10185 final String annotation; 10186 if (reason == null) { 10187 annotation = "Input dispatching timed out"; 10188 } else { 10189 annotation = "Input dispatching timed out (" + reason + ")"; 10190 } 10191 10192 if (proc != null) { 10193 synchronized (this) { 10194 if (proc.debugging) { 10195 return false; 10196 } 10197 10198 if (mDidDexOpt) { 10199 // Give more time since we were dexopting. 10200 mDidDexOpt = false; 10201 return false; 10202 } 10203 10204 if (proc.instrumentationClass != null) { 10205 Bundle info = new Bundle(); 10206 info.putString("shortMsg", "keyDispatchingTimedOut"); 10207 info.putString("longMsg", annotation); 10208 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10209 return true; 10210 } 10211 } 10212 mHandler.post(new Runnable() { 10213 @Override 10214 public void run() { 10215 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10216 } 10217 }); 10218 } 10219 10220 return true; 10221 } 10222 10223 public Bundle getAssistContextExtras(int requestType) { 10224 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10225 "getAssistContextExtras()"); 10226 PendingAssistExtras pae; 10227 Bundle extras = new Bundle(); 10228 synchronized (this) { 10229 ActivityRecord activity = getFocusedStack().mResumedActivity; 10230 if (activity == null) { 10231 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10232 return null; 10233 } 10234 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10235 if (activity.app == null || activity.app.thread == null) { 10236 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10237 return extras; 10238 } 10239 if (activity.app.pid == Binder.getCallingPid()) { 10240 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10241 return extras; 10242 } 10243 pae = new PendingAssistExtras(activity); 10244 try { 10245 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10246 requestType); 10247 mPendingAssistExtras.add(pae); 10248 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10249 } catch (RemoteException e) { 10250 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10251 return extras; 10252 } 10253 } 10254 synchronized (pae) { 10255 while (!pae.haveResult) { 10256 try { 10257 pae.wait(); 10258 } catch (InterruptedException e) { 10259 } 10260 } 10261 if (pae.result != null) { 10262 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10263 } 10264 } 10265 synchronized (this) { 10266 mPendingAssistExtras.remove(pae); 10267 mHandler.removeCallbacks(pae); 10268 } 10269 return extras; 10270 } 10271 10272 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10273 PendingAssistExtras pae = (PendingAssistExtras)token; 10274 synchronized (pae) { 10275 pae.result = extras; 10276 pae.haveResult = true; 10277 pae.notifyAll(); 10278 } 10279 } 10280 10281 public void registerProcessObserver(IProcessObserver observer) { 10282 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10283 "registerProcessObserver()"); 10284 synchronized (this) { 10285 mProcessObservers.register(observer); 10286 } 10287 } 10288 10289 @Override 10290 public void unregisterProcessObserver(IProcessObserver observer) { 10291 synchronized (this) { 10292 mProcessObservers.unregister(observer); 10293 } 10294 } 10295 10296 @Override 10297 public boolean convertFromTranslucent(IBinder token) { 10298 final long origId = Binder.clearCallingIdentity(); 10299 try { 10300 synchronized (this) { 10301 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10302 if (r == null) { 10303 return false; 10304 } 10305 final boolean translucentChanged = r.changeWindowTranslucency(true); 10306 if (translucentChanged) { 10307 r.task.stack.releaseBackgroundResources(); 10308 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10309 } 10310 mWindowManager.setAppFullscreen(token, true); 10311 return translucentChanged; 10312 } 10313 } finally { 10314 Binder.restoreCallingIdentity(origId); 10315 } 10316 } 10317 10318 @Override 10319 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10320 final long origId = Binder.clearCallingIdentity(); 10321 try { 10322 synchronized (this) { 10323 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10324 if (r == null) { 10325 return false; 10326 } 10327 int index = r.task.mActivities.lastIndexOf(r); 10328 if (index > 0) { 10329 ActivityRecord under = r.task.mActivities.get(index - 1); 10330 under.returningOptions = options; 10331 } 10332 final boolean translucentChanged = r.changeWindowTranslucency(false); 10333 if (translucentChanged) { 10334 r.task.stack.convertToTranslucent(r); 10335 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10336 } 10337 mWindowManager.setAppFullscreen(token, false); 10338 return translucentChanged; 10339 } 10340 } finally { 10341 Binder.restoreCallingIdentity(origId); 10342 } 10343 } 10344 10345 @Override 10346 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10347 final long origId = Binder.clearCallingIdentity(); 10348 try { 10349 synchronized (this) { 10350 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10351 if (r != null) { 10352 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10353 } 10354 } 10355 return false; 10356 } finally { 10357 Binder.restoreCallingIdentity(origId); 10358 } 10359 } 10360 10361 @Override 10362 public boolean isBackgroundVisibleBehind(IBinder token) { 10363 final long origId = Binder.clearCallingIdentity(); 10364 try { 10365 synchronized (this) { 10366 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10367 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10368 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10369 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10370 return visible; 10371 } 10372 } finally { 10373 Binder.restoreCallingIdentity(origId); 10374 } 10375 } 10376 10377 @Override 10378 public ActivityOptions getActivityOptions(IBinder token) { 10379 final long origId = Binder.clearCallingIdentity(); 10380 try { 10381 synchronized (this) { 10382 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10383 if (r != null) { 10384 final ActivityOptions activityOptions = r.pendingOptions; 10385 r.pendingOptions = null; 10386 return activityOptions; 10387 } 10388 return null; 10389 } 10390 } finally { 10391 Binder.restoreCallingIdentity(origId); 10392 } 10393 } 10394 10395 @Override 10396 public void setImmersive(IBinder token, boolean immersive) { 10397 synchronized(this) { 10398 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10399 if (r == null) { 10400 throw new IllegalArgumentException(); 10401 } 10402 r.immersive = immersive; 10403 10404 // update associated state if we're frontmost 10405 if (r == mFocusedActivity) { 10406 if (DEBUG_IMMERSIVE) { 10407 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10408 } 10409 applyUpdateLockStateLocked(r); 10410 } 10411 } 10412 } 10413 10414 @Override 10415 public boolean isImmersive(IBinder token) { 10416 synchronized (this) { 10417 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10418 if (r == null) { 10419 throw new IllegalArgumentException(); 10420 } 10421 return r.immersive; 10422 } 10423 } 10424 10425 public boolean isTopActivityImmersive() { 10426 enforceNotIsolatedCaller("startActivity"); 10427 synchronized (this) { 10428 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10429 return (r != null) ? r.immersive : false; 10430 } 10431 } 10432 10433 @Override 10434 public boolean isTopOfTask(IBinder token) { 10435 synchronized (this) { 10436 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10437 if (r == null) { 10438 throw new IllegalArgumentException(); 10439 } 10440 return r.task.getTopActivity() == r; 10441 } 10442 } 10443 10444 public final void enterSafeMode() { 10445 synchronized(this) { 10446 // It only makes sense to do this before the system is ready 10447 // and started launching other packages. 10448 if (!mSystemReady) { 10449 try { 10450 AppGlobals.getPackageManager().enterSafeMode(); 10451 } catch (RemoteException e) { 10452 } 10453 } 10454 10455 mSafeMode = true; 10456 } 10457 } 10458 10459 public final void showSafeModeOverlay() { 10460 View v = LayoutInflater.from(mContext).inflate( 10461 com.android.internal.R.layout.safe_mode, null); 10462 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10463 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10464 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10465 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10466 lp.gravity = Gravity.BOTTOM | Gravity.START; 10467 lp.format = v.getBackground().getOpacity(); 10468 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10469 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10470 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10471 ((WindowManager)mContext.getSystemService( 10472 Context.WINDOW_SERVICE)).addView(v, lp); 10473 } 10474 10475 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10476 if (!(sender instanceof PendingIntentRecord)) { 10477 return; 10478 } 10479 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10480 synchronized (stats) { 10481 if (mBatteryStatsService.isOnBattery()) { 10482 mBatteryStatsService.enforceCallingPermission(); 10483 PendingIntentRecord rec = (PendingIntentRecord)sender; 10484 int MY_UID = Binder.getCallingUid(); 10485 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10486 BatteryStatsImpl.Uid.Pkg pkg = 10487 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10488 sourcePkg != null ? sourcePkg : rec.key.packageName); 10489 pkg.incWakeupsLocked(); 10490 } 10491 } 10492 } 10493 10494 public boolean killPids(int[] pids, String pReason, boolean secure) { 10495 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10496 throw new SecurityException("killPids only available to the system"); 10497 } 10498 String reason = (pReason == null) ? "Unknown" : pReason; 10499 // XXX Note: don't acquire main activity lock here, because the window 10500 // manager calls in with its locks held. 10501 10502 boolean killed = false; 10503 synchronized (mPidsSelfLocked) { 10504 int[] types = new int[pids.length]; 10505 int worstType = 0; 10506 for (int i=0; i<pids.length; i++) { 10507 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10508 if (proc != null) { 10509 int type = proc.setAdj; 10510 types[i] = type; 10511 if (type > worstType) { 10512 worstType = type; 10513 } 10514 } 10515 } 10516 10517 // If the worst oom_adj is somewhere in the cached proc LRU range, 10518 // then constrain it so we will kill all cached procs. 10519 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10520 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10521 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10522 } 10523 10524 // If this is not a secure call, don't let it kill processes that 10525 // are important. 10526 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10527 worstType = ProcessList.SERVICE_ADJ; 10528 } 10529 10530 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10531 for (int i=0; i<pids.length; i++) { 10532 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10533 if (proc == null) { 10534 continue; 10535 } 10536 int adj = proc.setAdj; 10537 if (adj >= worstType && !proc.killedByAm) { 10538 proc.kill(reason, true); 10539 killed = true; 10540 } 10541 } 10542 } 10543 return killed; 10544 } 10545 10546 @Override 10547 public void killUid(int uid, String reason) { 10548 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10549 throw new SecurityException("killUid only available to the system"); 10550 } 10551 synchronized (this) { 10552 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10553 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10554 reason != null ? reason : "kill uid"); 10555 } 10556 } 10557 10558 @Override 10559 public boolean killProcessesBelowForeground(String reason) { 10560 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10561 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10562 } 10563 10564 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10565 } 10566 10567 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10568 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10569 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10570 } 10571 10572 boolean killed = false; 10573 synchronized (mPidsSelfLocked) { 10574 final int size = mPidsSelfLocked.size(); 10575 for (int i = 0; i < size; i++) { 10576 final int pid = mPidsSelfLocked.keyAt(i); 10577 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10578 if (proc == null) continue; 10579 10580 final int adj = proc.setAdj; 10581 if (adj > belowAdj && !proc.killedByAm) { 10582 proc.kill(reason, true); 10583 killed = true; 10584 } 10585 } 10586 } 10587 return killed; 10588 } 10589 10590 @Override 10591 public void hang(final IBinder who, boolean allowRestart) { 10592 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10593 != PackageManager.PERMISSION_GRANTED) { 10594 throw new SecurityException("Requires permission " 10595 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10596 } 10597 10598 final IBinder.DeathRecipient death = new DeathRecipient() { 10599 @Override 10600 public void binderDied() { 10601 synchronized (this) { 10602 notifyAll(); 10603 } 10604 } 10605 }; 10606 10607 try { 10608 who.linkToDeath(death, 0); 10609 } catch (RemoteException e) { 10610 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10611 return; 10612 } 10613 10614 synchronized (this) { 10615 Watchdog.getInstance().setAllowRestart(allowRestart); 10616 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10617 synchronized (death) { 10618 while (who.isBinderAlive()) { 10619 try { 10620 death.wait(); 10621 } catch (InterruptedException e) { 10622 } 10623 } 10624 } 10625 Watchdog.getInstance().setAllowRestart(true); 10626 } 10627 } 10628 10629 @Override 10630 public void restart() { 10631 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10632 != PackageManager.PERMISSION_GRANTED) { 10633 throw new SecurityException("Requires permission " 10634 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10635 } 10636 10637 Log.i(TAG, "Sending shutdown broadcast..."); 10638 10639 BroadcastReceiver br = new BroadcastReceiver() { 10640 @Override public void onReceive(Context context, Intent intent) { 10641 // Now the broadcast is done, finish up the low-level shutdown. 10642 Log.i(TAG, "Shutting down activity manager..."); 10643 shutdown(10000); 10644 Log.i(TAG, "Shutdown complete, restarting!"); 10645 Process.killProcess(Process.myPid()); 10646 System.exit(10); 10647 } 10648 }; 10649 10650 // First send the high-level shut down broadcast. 10651 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10652 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10653 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10654 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10655 mContext.sendOrderedBroadcastAsUser(intent, 10656 UserHandle.ALL, null, br, mHandler, 0, null, null); 10657 */ 10658 br.onReceive(mContext, intent); 10659 } 10660 10661 private long getLowRamTimeSinceIdle(long now) { 10662 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10663 } 10664 10665 @Override 10666 public void performIdleMaintenance() { 10667 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10668 != PackageManager.PERMISSION_GRANTED) { 10669 throw new SecurityException("Requires permission " 10670 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10671 } 10672 10673 synchronized (this) { 10674 final long now = SystemClock.uptimeMillis(); 10675 final long timeSinceLastIdle = now - mLastIdleTime; 10676 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10677 mLastIdleTime = now; 10678 mLowRamTimeSinceLastIdle = 0; 10679 if (mLowRamStartTime != 0) { 10680 mLowRamStartTime = now; 10681 } 10682 10683 StringBuilder sb = new StringBuilder(128); 10684 sb.append("Idle maintenance over "); 10685 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10686 sb.append(" low RAM for "); 10687 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10688 Slog.i(TAG, sb.toString()); 10689 10690 // If at least 1/3 of our time since the last idle period has been spent 10691 // with RAM low, then we want to kill processes. 10692 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10693 10694 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10695 ProcessRecord proc = mLruProcesses.get(i); 10696 if (proc.notCachedSinceIdle) { 10697 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10698 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10699 if (doKilling && proc.initialIdlePss != 0 10700 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10701 proc.kill("idle maint (pss " + proc.lastPss 10702 + " from " + proc.initialIdlePss + ")", true); 10703 } 10704 } 10705 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10706 proc.notCachedSinceIdle = true; 10707 proc.initialIdlePss = 0; 10708 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10709 isSleeping(), now); 10710 } 10711 } 10712 10713 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10714 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10715 } 10716 } 10717 10718 private void retrieveSettings() { 10719 final ContentResolver resolver = mContext.getContentResolver(); 10720 String debugApp = Settings.Global.getString( 10721 resolver, Settings.Global.DEBUG_APP); 10722 boolean waitForDebugger = Settings.Global.getInt( 10723 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10724 boolean alwaysFinishActivities = Settings.Global.getInt( 10725 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10726 boolean forceRtl = Settings.Global.getInt( 10727 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10728 // Transfer any global setting for forcing RTL layout, into a System Property 10729 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10730 10731 Configuration configuration = new Configuration(); 10732 Settings.System.getConfiguration(resolver, configuration); 10733 if (forceRtl) { 10734 // This will take care of setting the correct layout direction flags 10735 configuration.setLayoutDirection(configuration.locale); 10736 } 10737 10738 synchronized (this) { 10739 mDebugApp = mOrigDebugApp = debugApp; 10740 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10741 mAlwaysFinishActivities = alwaysFinishActivities; 10742 // This happens before any activities are started, so we can 10743 // change mConfiguration in-place. 10744 updateConfigurationLocked(configuration, null, false, true); 10745 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10746 } 10747 } 10748 10749 /** Loads resources after the current configuration has been set. */ 10750 private void loadResourcesOnSystemReady() { 10751 final Resources res = mContext.getResources(); 10752 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10753 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10754 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10755 } 10756 10757 public boolean testIsSystemReady() { 10758 // no need to synchronize(this) just to read & return the value 10759 return mSystemReady; 10760 } 10761 10762 private static File getCalledPreBootReceiversFile() { 10763 File dataDir = Environment.getDataDirectory(); 10764 File systemDir = new File(dataDir, "system"); 10765 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10766 return fname; 10767 } 10768 10769 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10770 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10771 File file = getCalledPreBootReceiversFile(); 10772 FileInputStream fis = null; 10773 try { 10774 fis = new FileInputStream(file); 10775 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10776 int fvers = dis.readInt(); 10777 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10778 String vers = dis.readUTF(); 10779 String codename = dis.readUTF(); 10780 String build = dis.readUTF(); 10781 if (android.os.Build.VERSION.RELEASE.equals(vers) 10782 && android.os.Build.VERSION.CODENAME.equals(codename) 10783 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10784 int num = dis.readInt(); 10785 while (num > 0) { 10786 num--; 10787 String pkg = dis.readUTF(); 10788 String cls = dis.readUTF(); 10789 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10790 } 10791 } 10792 } 10793 } catch (FileNotFoundException e) { 10794 } catch (IOException e) { 10795 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10796 } finally { 10797 if (fis != null) { 10798 try { 10799 fis.close(); 10800 } catch (IOException e) { 10801 } 10802 } 10803 } 10804 return lastDoneReceivers; 10805 } 10806 10807 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10808 File file = getCalledPreBootReceiversFile(); 10809 FileOutputStream fos = null; 10810 DataOutputStream dos = null; 10811 try { 10812 fos = new FileOutputStream(file); 10813 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10814 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10815 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10816 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10817 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10818 dos.writeInt(list.size()); 10819 for (int i=0; i<list.size(); i++) { 10820 dos.writeUTF(list.get(i).getPackageName()); 10821 dos.writeUTF(list.get(i).getClassName()); 10822 } 10823 } catch (IOException e) { 10824 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10825 file.delete(); 10826 } finally { 10827 FileUtils.sync(fos); 10828 if (dos != null) { 10829 try { 10830 dos.close(); 10831 } catch (IOException e) { 10832 // TODO Auto-generated catch block 10833 e.printStackTrace(); 10834 } 10835 } 10836 } 10837 } 10838 10839 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10840 ArrayList<ComponentName> doneReceivers, int userId) { 10841 boolean waitingUpdate = false; 10842 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10843 List<ResolveInfo> ris = null; 10844 try { 10845 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10846 intent, null, 0, userId); 10847 } catch (RemoteException e) { 10848 } 10849 if (ris != null) { 10850 for (int i=ris.size()-1; i>=0; i--) { 10851 if ((ris.get(i).activityInfo.applicationInfo.flags 10852 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10853 ris.remove(i); 10854 } 10855 } 10856 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10857 10858 // For User 0, load the version number. When delivering to a new user, deliver 10859 // to all receivers. 10860 if (userId == UserHandle.USER_OWNER) { 10861 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10862 for (int i=0; i<ris.size(); i++) { 10863 ActivityInfo ai = ris.get(i).activityInfo; 10864 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10865 if (lastDoneReceivers.contains(comp)) { 10866 // We already did the pre boot receiver for this app with the current 10867 // platform version, so don't do it again... 10868 ris.remove(i); 10869 i--; 10870 // ...however, do keep it as one that has been done, so we don't 10871 // forget about it when rewriting the file of last done receivers. 10872 doneReceivers.add(comp); 10873 } 10874 } 10875 } 10876 10877 // If primary user, send broadcast to all available users, else just to userId 10878 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10879 : new int[] { userId }; 10880 for (int i = 0; i < ris.size(); i++) { 10881 ActivityInfo ai = ris.get(i).activityInfo; 10882 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10883 doneReceivers.add(comp); 10884 intent.setComponent(comp); 10885 for (int j=0; j<users.length; j++) { 10886 IIntentReceiver finisher = null; 10887 // On last receiver and user, set up a completion callback 10888 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10889 finisher = new IIntentReceiver.Stub() { 10890 public void performReceive(Intent intent, int resultCode, 10891 String data, Bundle extras, boolean ordered, 10892 boolean sticky, int sendingUser) { 10893 // The raw IIntentReceiver interface is called 10894 // with the AM lock held, so redispatch to 10895 // execute our code without the lock. 10896 mHandler.post(onFinishCallback); 10897 } 10898 }; 10899 } 10900 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10901 + " for user " + users[j]); 10902 broadcastIntentLocked(null, null, intent, null, finisher, 10903 0, null, null, null, AppOpsManager.OP_NONE, 10904 true, false, MY_PID, Process.SYSTEM_UID, 10905 users[j]); 10906 if (finisher != null) { 10907 waitingUpdate = true; 10908 } 10909 } 10910 } 10911 } 10912 10913 return waitingUpdate; 10914 } 10915 10916 public void systemReady(final Runnable goingCallback) { 10917 synchronized(this) { 10918 if (mSystemReady) { 10919 // If we're done calling all the receivers, run the next "boot phase" passed in 10920 // by the SystemServer 10921 if (goingCallback != null) { 10922 goingCallback.run(); 10923 } 10924 return; 10925 } 10926 10927 // Make sure we have the current profile info, since it is needed for 10928 // security checks. 10929 updateCurrentProfileIdsLocked(); 10930 10931 if (mRecentTasks == null) { 10932 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10933 if (!mRecentTasks.isEmpty()) { 10934 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10935 } 10936 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10937 mTaskPersister.startPersisting(); 10938 } 10939 10940 // Check to see if there are any update receivers to run. 10941 if (!mDidUpdate) { 10942 if (mWaitingUpdate) { 10943 return; 10944 } 10945 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10946 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10947 public void run() { 10948 synchronized (ActivityManagerService.this) { 10949 mDidUpdate = true; 10950 } 10951 writeLastDonePreBootReceivers(doneReceivers); 10952 showBootMessage(mContext.getText( 10953 R.string.android_upgrading_complete), 10954 false); 10955 systemReady(goingCallback); 10956 } 10957 }, doneReceivers, UserHandle.USER_OWNER); 10958 10959 if (mWaitingUpdate) { 10960 return; 10961 } 10962 mDidUpdate = true; 10963 } 10964 10965 mAppOpsService.systemReady(); 10966 mSystemReady = true; 10967 } 10968 10969 ArrayList<ProcessRecord> procsToKill = null; 10970 synchronized(mPidsSelfLocked) { 10971 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10972 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10973 if (!isAllowedWhileBooting(proc.info)){ 10974 if (procsToKill == null) { 10975 procsToKill = new ArrayList<ProcessRecord>(); 10976 } 10977 procsToKill.add(proc); 10978 } 10979 } 10980 } 10981 10982 synchronized(this) { 10983 if (procsToKill != null) { 10984 for (int i=procsToKill.size()-1; i>=0; i--) { 10985 ProcessRecord proc = procsToKill.get(i); 10986 Slog.i(TAG, "Removing system update proc: " + proc); 10987 removeProcessLocked(proc, true, false, "system update done"); 10988 } 10989 } 10990 10991 // Now that we have cleaned up any update processes, we 10992 // are ready to start launching real processes and know that 10993 // we won't trample on them any more. 10994 mProcessesReady = true; 10995 } 10996 10997 Slog.i(TAG, "System now ready"); 10998 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10999 SystemClock.uptimeMillis()); 11000 11001 synchronized(this) { 11002 // Make sure we have no pre-ready processes sitting around. 11003 11004 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11005 ResolveInfo ri = mContext.getPackageManager() 11006 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11007 STOCK_PM_FLAGS); 11008 CharSequence errorMsg = null; 11009 if (ri != null) { 11010 ActivityInfo ai = ri.activityInfo; 11011 ApplicationInfo app = ai.applicationInfo; 11012 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11013 mTopAction = Intent.ACTION_FACTORY_TEST; 11014 mTopData = null; 11015 mTopComponent = new ComponentName(app.packageName, 11016 ai.name); 11017 } else { 11018 errorMsg = mContext.getResources().getText( 11019 com.android.internal.R.string.factorytest_not_system); 11020 } 11021 } else { 11022 errorMsg = mContext.getResources().getText( 11023 com.android.internal.R.string.factorytest_no_action); 11024 } 11025 if (errorMsg != null) { 11026 mTopAction = null; 11027 mTopData = null; 11028 mTopComponent = null; 11029 Message msg = Message.obtain(); 11030 msg.what = SHOW_FACTORY_ERROR_MSG; 11031 msg.getData().putCharSequence("msg", errorMsg); 11032 mHandler.sendMessage(msg); 11033 } 11034 } 11035 } 11036 11037 retrieveSettings(); 11038 loadResourcesOnSystemReady(); 11039 11040 synchronized (this) { 11041 readGrantedUriPermissionsLocked(); 11042 } 11043 11044 if (goingCallback != null) goingCallback.run(); 11045 11046 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11047 Integer.toString(mCurrentUserId), mCurrentUserId); 11048 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11049 Integer.toString(mCurrentUserId), mCurrentUserId); 11050 mSystemServiceManager.startUser(mCurrentUserId); 11051 11052 synchronized (this) { 11053 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11054 try { 11055 List apps = AppGlobals.getPackageManager(). 11056 getPersistentApplications(STOCK_PM_FLAGS); 11057 if (apps != null) { 11058 int N = apps.size(); 11059 int i; 11060 for (i=0; i<N; i++) { 11061 ApplicationInfo info 11062 = (ApplicationInfo)apps.get(i); 11063 if (info != null && 11064 !info.packageName.equals("android")) { 11065 addAppLocked(info, false, null /* ABI override */); 11066 } 11067 } 11068 } 11069 } catch (RemoteException ex) { 11070 // pm is in same process, this will never happen. 11071 } 11072 } 11073 11074 // Start up initial activity. 11075 mBooting = true; 11076 11077 try { 11078 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11079 Message msg = Message.obtain(); 11080 msg.what = SHOW_UID_ERROR_MSG; 11081 mHandler.sendMessage(msg); 11082 } 11083 } catch (RemoteException e) { 11084 } 11085 11086 long ident = Binder.clearCallingIdentity(); 11087 try { 11088 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11089 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11090 | Intent.FLAG_RECEIVER_FOREGROUND); 11091 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11092 broadcastIntentLocked(null, null, intent, 11093 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11094 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11095 intent = new Intent(Intent.ACTION_USER_STARTING); 11096 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11097 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11098 broadcastIntentLocked(null, null, intent, 11099 null, new IIntentReceiver.Stub() { 11100 @Override 11101 public void performReceive(Intent intent, int resultCode, String data, 11102 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11103 throws RemoteException { 11104 } 11105 }, 0, null, null, 11106 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11107 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11108 } catch (Throwable t) { 11109 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11110 } finally { 11111 Binder.restoreCallingIdentity(ident); 11112 } 11113 mStackSupervisor.resumeTopActivitiesLocked(); 11114 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11115 } 11116 } 11117 11118 private boolean makeAppCrashingLocked(ProcessRecord app, 11119 String shortMsg, String longMsg, String stackTrace) { 11120 app.crashing = true; 11121 app.crashingReport = generateProcessError(app, 11122 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11123 startAppProblemLocked(app); 11124 app.stopFreezingAllLocked(); 11125 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11126 } 11127 11128 private void makeAppNotRespondingLocked(ProcessRecord app, 11129 String activity, String shortMsg, String longMsg) { 11130 app.notResponding = true; 11131 app.notRespondingReport = generateProcessError(app, 11132 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11133 activity, shortMsg, longMsg, null); 11134 startAppProblemLocked(app); 11135 app.stopFreezingAllLocked(); 11136 } 11137 11138 /** 11139 * Generate a process error record, suitable for attachment to a ProcessRecord. 11140 * 11141 * @param app The ProcessRecord in which the error occurred. 11142 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11143 * ActivityManager.AppErrorStateInfo 11144 * @param activity The activity associated with the crash, if known. 11145 * @param shortMsg Short message describing the crash. 11146 * @param longMsg Long message describing the crash. 11147 * @param stackTrace Full crash stack trace, may be null. 11148 * 11149 * @return Returns a fully-formed AppErrorStateInfo record. 11150 */ 11151 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11152 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11153 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11154 11155 report.condition = condition; 11156 report.processName = app.processName; 11157 report.pid = app.pid; 11158 report.uid = app.info.uid; 11159 report.tag = activity; 11160 report.shortMsg = shortMsg; 11161 report.longMsg = longMsg; 11162 report.stackTrace = stackTrace; 11163 11164 return report; 11165 } 11166 11167 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11168 synchronized (this) { 11169 app.crashing = false; 11170 app.crashingReport = null; 11171 app.notResponding = false; 11172 app.notRespondingReport = null; 11173 if (app.anrDialog == fromDialog) { 11174 app.anrDialog = null; 11175 } 11176 if (app.waitDialog == fromDialog) { 11177 app.waitDialog = null; 11178 } 11179 if (app.pid > 0 && app.pid != MY_PID) { 11180 handleAppCrashLocked(app, null, null, null); 11181 app.kill("user request after error", true); 11182 } 11183 } 11184 } 11185 11186 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11187 String stackTrace) { 11188 long now = SystemClock.uptimeMillis(); 11189 11190 Long crashTime; 11191 if (!app.isolated) { 11192 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11193 } else { 11194 crashTime = null; 11195 } 11196 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11197 // This process loses! 11198 Slog.w(TAG, "Process " + app.info.processName 11199 + " has crashed too many times: killing!"); 11200 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11201 app.userId, app.info.processName, app.uid); 11202 mStackSupervisor.handleAppCrashLocked(app); 11203 if (!app.persistent) { 11204 // We don't want to start this process again until the user 11205 // explicitly does so... but for persistent process, we really 11206 // need to keep it running. If a persistent process is actually 11207 // repeatedly crashing, then badness for everyone. 11208 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11209 app.info.processName); 11210 if (!app.isolated) { 11211 // XXX We don't have a way to mark isolated processes 11212 // as bad, since they don't have a peristent identity. 11213 mBadProcesses.put(app.info.processName, app.uid, 11214 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11215 mProcessCrashTimes.remove(app.info.processName, app.uid); 11216 } 11217 app.bad = true; 11218 app.removed = true; 11219 // Don't let services in this process be restarted and potentially 11220 // annoy the user repeatedly. Unless it is persistent, since those 11221 // processes run critical code. 11222 removeProcessLocked(app, false, false, "crash"); 11223 mStackSupervisor.resumeTopActivitiesLocked(); 11224 return false; 11225 } 11226 mStackSupervisor.resumeTopActivitiesLocked(); 11227 } else { 11228 mStackSupervisor.finishTopRunningActivityLocked(app); 11229 } 11230 11231 // Bump up the crash count of any services currently running in the proc. 11232 for (int i=app.services.size()-1; i>=0; i--) { 11233 // Any services running in the application need to be placed 11234 // back in the pending list. 11235 ServiceRecord sr = app.services.valueAt(i); 11236 sr.crashCount++; 11237 } 11238 11239 // If the crashing process is what we consider to be the "home process" and it has been 11240 // replaced by a third-party app, clear the package preferred activities from packages 11241 // with a home activity running in the process to prevent a repeatedly crashing app 11242 // from blocking the user to manually clear the list. 11243 final ArrayList<ActivityRecord> activities = app.activities; 11244 if (app == mHomeProcess && activities.size() > 0 11245 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11246 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11247 final ActivityRecord r = activities.get(activityNdx); 11248 if (r.isHomeActivity()) { 11249 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11250 try { 11251 ActivityThread.getPackageManager() 11252 .clearPackagePreferredActivities(r.packageName); 11253 } catch (RemoteException c) { 11254 // pm is in same process, this will never happen. 11255 } 11256 } 11257 } 11258 } 11259 11260 if (!app.isolated) { 11261 // XXX Can't keep track of crash times for isolated processes, 11262 // because they don't have a perisistent identity. 11263 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11264 } 11265 11266 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11267 return true; 11268 } 11269 11270 void startAppProblemLocked(ProcessRecord app) { 11271 // If this app is not running under the current user, then we 11272 // can't give it a report button because that would require 11273 // launching the report UI under a different user. 11274 app.errorReportReceiver = null; 11275 11276 for (int userId : mCurrentProfileIds) { 11277 if (app.userId == userId) { 11278 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11279 mContext, app.info.packageName, app.info.flags); 11280 } 11281 } 11282 skipCurrentReceiverLocked(app); 11283 } 11284 11285 void skipCurrentReceiverLocked(ProcessRecord app) { 11286 for (BroadcastQueue queue : mBroadcastQueues) { 11287 queue.skipCurrentReceiverLocked(app); 11288 } 11289 } 11290 11291 /** 11292 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11293 * The application process will exit immediately after this call returns. 11294 * @param app object of the crashing app, null for the system server 11295 * @param crashInfo describing the exception 11296 */ 11297 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11298 ProcessRecord r = findAppProcess(app, "Crash"); 11299 final String processName = app == null ? "system_server" 11300 : (r == null ? "unknown" : r.processName); 11301 11302 handleApplicationCrashInner("crash", r, processName, crashInfo); 11303 } 11304 11305 /* Native crash reporting uses this inner version because it needs to be somewhat 11306 * decoupled from the AM-managed cleanup lifecycle 11307 */ 11308 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11309 ApplicationErrorReport.CrashInfo crashInfo) { 11310 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11311 UserHandle.getUserId(Binder.getCallingUid()), processName, 11312 r == null ? -1 : r.info.flags, 11313 crashInfo.exceptionClassName, 11314 crashInfo.exceptionMessage, 11315 crashInfo.throwFileName, 11316 crashInfo.throwLineNumber); 11317 11318 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11319 11320 crashApplication(r, crashInfo); 11321 } 11322 11323 public void handleApplicationStrictModeViolation( 11324 IBinder app, 11325 int violationMask, 11326 StrictMode.ViolationInfo info) { 11327 ProcessRecord r = findAppProcess(app, "StrictMode"); 11328 if (r == null) { 11329 return; 11330 } 11331 11332 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11333 Integer stackFingerprint = info.hashCode(); 11334 boolean logIt = true; 11335 synchronized (mAlreadyLoggedViolatedStacks) { 11336 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11337 logIt = false; 11338 // TODO: sub-sample into EventLog for these, with 11339 // the info.durationMillis? Then we'd get 11340 // the relative pain numbers, without logging all 11341 // the stack traces repeatedly. We'd want to do 11342 // likewise in the client code, which also does 11343 // dup suppression, before the Binder call. 11344 } else { 11345 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11346 mAlreadyLoggedViolatedStacks.clear(); 11347 } 11348 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11349 } 11350 } 11351 if (logIt) { 11352 logStrictModeViolationToDropBox(r, info); 11353 } 11354 } 11355 11356 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11357 AppErrorResult result = new AppErrorResult(); 11358 synchronized (this) { 11359 final long origId = Binder.clearCallingIdentity(); 11360 11361 Message msg = Message.obtain(); 11362 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11363 HashMap<String, Object> data = new HashMap<String, Object>(); 11364 data.put("result", result); 11365 data.put("app", r); 11366 data.put("violationMask", violationMask); 11367 data.put("info", info); 11368 msg.obj = data; 11369 mHandler.sendMessage(msg); 11370 11371 Binder.restoreCallingIdentity(origId); 11372 } 11373 int res = result.get(); 11374 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11375 } 11376 } 11377 11378 // Depending on the policy in effect, there could be a bunch of 11379 // these in quick succession so we try to batch these together to 11380 // minimize disk writes, number of dropbox entries, and maximize 11381 // compression, by having more fewer, larger records. 11382 private void logStrictModeViolationToDropBox( 11383 ProcessRecord process, 11384 StrictMode.ViolationInfo info) { 11385 if (info == null) { 11386 return; 11387 } 11388 final boolean isSystemApp = process == null || 11389 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11390 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11391 final String processName = process == null ? "unknown" : process.processName; 11392 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11393 final DropBoxManager dbox = (DropBoxManager) 11394 mContext.getSystemService(Context.DROPBOX_SERVICE); 11395 11396 // Exit early if the dropbox isn't configured to accept this report type. 11397 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11398 11399 boolean bufferWasEmpty; 11400 boolean needsFlush; 11401 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11402 synchronized (sb) { 11403 bufferWasEmpty = sb.length() == 0; 11404 appendDropBoxProcessHeaders(process, processName, sb); 11405 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11406 sb.append("System-App: ").append(isSystemApp).append("\n"); 11407 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11408 if (info.violationNumThisLoop != 0) { 11409 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11410 } 11411 if (info.numAnimationsRunning != 0) { 11412 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11413 } 11414 if (info.broadcastIntentAction != null) { 11415 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11416 } 11417 if (info.durationMillis != -1) { 11418 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11419 } 11420 if (info.numInstances != -1) { 11421 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11422 } 11423 if (info.tags != null) { 11424 for (String tag : info.tags) { 11425 sb.append("Span-Tag: ").append(tag).append("\n"); 11426 } 11427 } 11428 sb.append("\n"); 11429 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11430 sb.append(info.crashInfo.stackTrace); 11431 } 11432 sb.append("\n"); 11433 11434 // Only buffer up to ~64k. Various logging bits truncate 11435 // things at 128k. 11436 needsFlush = (sb.length() > 64 * 1024); 11437 } 11438 11439 // Flush immediately if the buffer's grown too large, or this 11440 // is a non-system app. Non-system apps are isolated with a 11441 // different tag & policy and not batched. 11442 // 11443 // Batching is useful during internal testing with 11444 // StrictMode settings turned up high. Without batching, 11445 // thousands of separate files could be created on boot. 11446 if (!isSystemApp || needsFlush) { 11447 new Thread("Error dump: " + dropboxTag) { 11448 @Override 11449 public void run() { 11450 String report; 11451 synchronized (sb) { 11452 report = sb.toString(); 11453 sb.delete(0, sb.length()); 11454 sb.trimToSize(); 11455 } 11456 if (report.length() != 0) { 11457 dbox.addText(dropboxTag, report); 11458 } 11459 } 11460 }.start(); 11461 return; 11462 } 11463 11464 // System app batching: 11465 if (!bufferWasEmpty) { 11466 // An existing dropbox-writing thread is outstanding, so 11467 // we don't need to start it up. The existing thread will 11468 // catch the buffer appends we just did. 11469 return; 11470 } 11471 11472 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11473 // (After this point, we shouldn't access AMS internal data structures.) 11474 new Thread("Error dump: " + dropboxTag) { 11475 @Override 11476 public void run() { 11477 // 5 second sleep to let stacks arrive and be batched together 11478 try { 11479 Thread.sleep(5000); // 5 seconds 11480 } catch (InterruptedException e) {} 11481 11482 String errorReport; 11483 synchronized (mStrictModeBuffer) { 11484 errorReport = mStrictModeBuffer.toString(); 11485 if (errorReport.length() == 0) { 11486 return; 11487 } 11488 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11489 mStrictModeBuffer.trimToSize(); 11490 } 11491 dbox.addText(dropboxTag, errorReport); 11492 } 11493 }.start(); 11494 } 11495 11496 /** 11497 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11498 * @param app object of the crashing app, null for the system server 11499 * @param tag reported by the caller 11500 * @param system whether this wtf is coming from the system 11501 * @param crashInfo describing the context of the error 11502 * @return true if the process should exit immediately (WTF is fatal) 11503 */ 11504 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11505 final ApplicationErrorReport.CrashInfo crashInfo) { 11506 final ProcessRecord r = findAppProcess(app, "WTF"); 11507 final String processName = app == null ? "system_server" 11508 : (r == null ? "unknown" : r.processName); 11509 11510 EventLog.writeEvent(EventLogTags.AM_WTF, 11511 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11512 processName, 11513 r == null ? -1 : r.info.flags, 11514 tag, crashInfo.exceptionMessage); 11515 11516 if (system) { 11517 // If this is coming from the system, we could very well have low-level 11518 // system locks held, so we want to do this all asynchronously. And we 11519 // never want this to become fatal, so there is that too. 11520 mHandler.post(new Runnable() { 11521 @Override public void run() { 11522 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11523 crashInfo); 11524 } 11525 }); 11526 return false; 11527 } 11528 11529 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11530 11531 if (r != null && r.pid != Process.myPid() && 11532 Settings.Global.getInt(mContext.getContentResolver(), 11533 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11534 crashApplication(r, crashInfo); 11535 return true; 11536 } else { 11537 return false; 11538 } 11539 } 11540 11541 /** 11542 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11543 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11544 */ 11545 private ProcessRecord findAppProcess(IBinder app, String reason) { 11546 if (app == null) { 11547 return null; 11548 } 11549 11550 synchronized (this) { 11551 final int NP = mProcessNames.getMap().size(); 11552 for (int ip=0; ip<NP; ip++) { 11553 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11554 final int NA = apps.size(); 11555 for (int ia=0; ia<NA; ia++) { 11556 ProcessRecord p = apps.valueAt(ia); 11557 if (p.thread != null && p.thread.asBinder() == app) { 11558 return p; 11559 } 11560 } 11561 } 11562 11563 Slog.w(TAG, "Can't find mystery application for " + reason 11564 + " from pid=" + Binder.getCallingPid() 11565 + " uid=" + Binder.getCallingUid() + ": " + app); 11566 return null; 11567 } 11568 } 11569 11570 /** 11571 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11572 * to append various headers to the dropbox log text. 11573 */ 11574 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11575 StringBuilder sb) { 11576 // Watchdog thread ends up invoking this function (with 11577 // a null ProcessRecord) to add the stack file to dropbox. 11578 // Do not acquire a lock on this (am) in such cases, as it 11579 // could cause a potential deadlock, if and when watchdog 11580 // is invoked due to unavailability of lock on am and it 11581 // would prevent watchdog from killing system_server. 11582 if (process == null) { 11583 sb.append("Process: ").append(processName).append("\n"); 11584 return; 11585 } 11586 // Note: ProcessRecord 'process' is guarded by the service 11587 // instance. (notably process.pkgList, which could otherwise change 11588 // concurrently during execution of this method) 11589 synchronized (this) { 11590 sb.append("Process: ").append(processName).append("\n"); 11591 int flags = process.info.flags; 11592 IPackageManager pm = AppGlobals.getPackageManager(); 11593 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11594 for (int ip=0; ip<process.pkgList.size(); ip++) { 11595 String pkg = process.pkgList.keyAt(ip); 11596 sb.append("Package: ").append(pkg); 11597 try { 11598 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11599 if (pi != null) { 11600 sb.append(" v").append(pi.versionCode); 11601 if (pi.versionName != null) { 11602 sb.append(" (").append(pi.versionName).append(")"); 11603 } 11604 } 11605 } catch (RemoteException e) { 11606 Slog.e(TAG, "Error getting package info: " + pkg, e); 11607 } 11608 sb.append("\n"); 11609 } 11610 } 11611 } 11612 11613 private static String processClass(ProcessRecord process) { 11614 if (process == null || process.pid == MY_PID) { 11615 return "system_server"; 11616 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11617 return "system_app"; 11618 } else { 11619 return "data_app"; 11620 } 11621 } 11622 11623 /** 11624 * Write a description of an error (crash, WTF, ANR) to the drop box. 11625 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11626 * @param process which caused the error, null means the system server 11627 * @param activity which triggered the error, null if unknown 11628 * @param parent activity related to the error, null if unknown 11629 * @param subject line related to the error, null if absent 11630 * @param report in long form describing the error, null if absent 11631 * @param logFile to include in the report, null if none 11632 * @param crashInfo giving an application stack trace, null if absent 11633 */ 11634 public void addErrorToDropBox(String eventType, 11635 ProcessRecord process, String processName, ActivityRecord activity, 11636 ActivityRecord parent, String subject, 11637 final String report, final File logFile, 11638 final ApplicationErrorReport.CrashInfo crashInfo) { 11639 // NOTE -- this must never acquire the ActivityManagerService lock, 11640 // otherwise the watchdog may be prevented from resetting the system. 11641 11642 final String dropboxTag = processClass(process) + "_" + eventType; 11643 final DropBoxManager dbox = (DropBoxManager) 11644 mContext.getSystemService(Context.DROPBOX_SERVICE); 11645 11646 // Exit early if the dropbox isn't configured to accept this report type. 11647 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11648 11649 final StringBuilder sb = new StringBuilder(1024); 11650 appendDropBoxProcessHeaders(process, processName, sb); 11651 if (activity != null) { 11652 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11653 } 11654 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11655 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11656 } 11657 if (parent != null && parent != activity) { 11658 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11659 } 11660 if (subject != null) { 11661 sb.append("Subject: ").append(subject).append("\n"); 11662 } 11663 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11664 if (Debug.isDebuggerConnected()) { 11665 sb.append("Debugger: Connected\n"); 11666 } 11667 sb.append("\n"); 11668 11669 // Do the rest in a worker thread to avoid blocking the caller on I/O 11670 // (After this point, we shouldn't access AMS internal data structures.) 11671 Thread worker = new Thread("Error dump: " + dropboxTag) { 11672 @Override 11673 public void run() { 11674 if (report != null) { 11675 sb.append(report); 11676 } 11677 if (logFile != null) { 11678 try { 11679 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11680 "\n\n[[TRUNCATED]]")); 11681 } catch (IOException e) { 11682 Slog.e(TAG, "Error reading " + logFile, e); 11683 } 11684 } 11685 if (crashInfo != null && crashInfo.stackTrace != null) { 11686 sb.append(crashInfo.stackTrace); 11687 } 11688 11689 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11690 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11691 if (lines > 0) { 11692 sb.append("\n"); 11693 11694 // Merge several logcat streams, and take the last N lines 11695 InputStreamReader input = null; 11696 try { 11697 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11698 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11699 "-b", "crash", 11700 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11701 11702 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11703 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11704 input = new InputStreamReader(logcat.getInputStream()); 11705 11706 int num; 11707 char[] buf = new char[8192]; 11708 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11709 } catch (IOException e) { 11710 Slog.e(TAG, "Error running logcat", e); 11711 } finally { 11712 if (input != null) try { input.close(); } catch (IOException e) {} 11713 } 11714 } 11715 11716 dbox.addText(dropboxTag, sb.toString()); 11717 } 11718 }; 11719 11720 if (process == null) { 11721 // If process is null, we are being called from some internal code 11722 // and may be about to die -- run this synchronously. 11723 worker.run(); 11724 } else { 11725 worker.start(); 11726 } 11727 } 11728 11729 /** 11730 * Bring up the "unexpected error" dialog box for a crashing app. 11731 * Deal with edge cases (intercepts from instrumented applications, 11732 * ActivityController, error intent receivers, that sort of thing). 11733 * @param r the application crashing 11734 * @param crashInfo describing the failure 11735 */ 11736 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11737 long timeMillis = System.currentTimeMillis(); 11738 String shortMsg = crashInfo.exceptionClassName; 11739 String longMsg = crashInfo.exceptionMessage; 11740 String stackTrace = crashInfo.stackTrace; 11741 if (shortMsg != null && longMsg != null) { 11742 longMsg = shortMsg + ": " + longMsg; 11743 } else if (shortMsg != null) { 11744 longMsg = shortMsg; 11745 } 11746 11747 AppErrorResult result = new AppErrorResult(); 11748 synchronized (this) { 11749 if (mController != null) { 11750 try { 11751 String name = r != null ? r.processName : null; 11752 int pid = r != null ? r.pid : Binder.getCallingPid(); 11753 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11754 if (!mController.appCrashed(name, pid, 11755 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11756 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11757 && "Native crash".equals(crashInfo.exceptionClassName)) { 11758 Slog.w(TAG, "Skip killing native crashed app " + name 11759 + "(" + pid + ") during testing"); 11760 } else { 11761 Slog.w(TAG, "Force-killing crashed app " + name 11762 + " at watcher's request"); 11763 if (r != null) { 11764 r.kill("crash", true); 11765 } else { 11766 // Huh. 11767 Process.killProcess(pid); 11768 Process.killProcessGroup(uid, pid); 11769 } 11770 } 11771 return; 11772 } 11773 } catch (RemoteException e) { 11774 mController = null; 11775 Watchdog.getInstance().setActivityController(null); 11776 } 11777 } 11778 11779 final long origId = Binder.clearCallingIdentity(); 11780 11781 // If this process is running instrumentation, finish it. 11782 if (r != null && r.instrumentationClass != null) { 11783 Slog.w(TAG, "Error in app " + r.processName 11784 + " running instrumentation " + r.instrumentationClass + ":"); 11785 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11786 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11787 Bundle info = new Bundle(); 11788 info.putString("shortMsg", shortMsg); 11789 info.putString("longMsg", longMsg); 11790 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11791 Binder.restoreCallingIdentity(origId); 11792 return; 11793 } 11794 11795 // If we can't identify the process or it's already exceeded its crash quota, 11796 // quit right away without showing a crash dialog. 11797 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11798 Binder.restoreCallingIdentity(origId); 11799 return; 11800 } 11801 11802 Message msg = Message.obtain(); 11803 msg.what = SHOW_ERROR_MSG; 11804 HashMap data = new HashMap(); 11805 data.put("result", result); 11806 data.put("app", r); 11807 msg.obj = data; 11808 mHandler.sendMessage(msg); 11809 11810 Binder.restoreCallingIdentity(origId); 11811 } 11812 11813 int res = result.get(); 11814 11815 Intent appErrorIntent = null; 11816 synchronized (this) { 11817 if (r != null && !r.isolated) { 11818 // XXX Can't keep track of crash time for isolated processes, 11819 // since they don't have a persistent identity. 11820 mProcessCrashTimes.put(r.info.processName, r.uid, 11821 SystemClock.uptimeMillis()); 11822 } 11823 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11824 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11825 } 11826 } 11827 11828 if (appErrorIntent != null) { 11829 try { 11830 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11831 } catch (ActivityNotFoundException e) { 11832 Slog.w(TAG, "bug report receiver dissappeared", e); 11833 } 11834 } 11835 } 11836 11837 Intent createAppErrorIntentLocked(ProcessRecord r, 11838 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11839 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11840 if (report == null) { 11841 return null; 11842 } 11843 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11844 result.setComponent(r.errorReportReceiver); 11845 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11846 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11847 return result; 11848 } 11849 11850 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11851 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11852 if (r.errorReportReceiver == null) { 11853 return null; 11854 } 11855 11856 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11857 return null; 11858 } 11859 11860 ApplicationErrorReport report = new ApplicationErrorReport(); 11861 report.packageName = r.info.packageName; 11862 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11863 report.processName = r.processName; 11864 report.time = timeMillis; 11865 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11866 11867 if (r.crashing || r.forceCrashReport) { 11868 report.type = ApplicationErrorReport.TYPE_CRASH; 11869 report.crashInfo = crashInfo; 11870 } else if (r.notResponding) { 11871 report.type = ApplicationErrorReport.TYPE_ANR; 11872 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11873 11874 report.anrInfo.activity = r.notRespondingReport.tag; 11875 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11876 report.anrInfo.info = r.notRespondingReport.longMsg; 11877 } 11878 11879 return report; 11880 } 11881 11882 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11883 enforceNotIsolatedCaller("getProcessesInErrorState"); 11884 // assume our apps are happy - lazy create the list 11885 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11886 11887 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11888 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11889 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11890 11891 synchronized (this) { 11892 11893 // iterate across all processes 11894 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11895 ProcessRecord app = mLruProcesses.get(i); 11896 if (!allUsers && app.userId != userId) { 11897 continue; 11898 } 11899 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11900 // This one's in trouble, so we'll generate a report for it 11901 // crashes are higher priority (in case there's a crash *and* an anr) 11902 ActivityManager.ProcessErrorStateInfo report = null; 11903 if (app.crashing) { 11904 report = app.crashingReport; 11905 } else if (app.notResponding) { 11906 report = app.notRespondingReport; 11907 } 11908 11909 if (report != null) { 11910 if (errList == null) { 11911 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11912 } 11913 errList.add(report); 11914 } else { 11915 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11916 " crashing = " + app.crashing + 11917 " notResponding = " + app.notResponding); 11918 } 11919 } 11920 } 11921 } 11922 11923 return errList; 11924 } 11925 11926 static int procStateToImportance(int procState, int memAdj, 11927 ActivityManager.RunningAppProcessInfo currApp) { 11928 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11929 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11930 currApp.lru = memAdj; 11931 } else { 11932 currApp.lru = 0; 11933 } 11934 return imp; 11935 } 11936 11937 private void fillInProcMemInfo(ProcessRecord app, 11938 ActivityManager.RunningAppProcessInfo outInfo) { 11939 outInfo.pid = app.pid; 11940 outInfo.uid = app.info.uid; 11941 if (mHeavyWeightProcess == app) { 11942 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11943 } 11944 if (app.persistent) { 11945 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11946 } 11947 if (app.activities.size() > 0) { 11948 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11949 } 11950 outInfo.lastTrimLevel = app.trimMemoryLevel; 11951 int adj = app.curAdj; 11952 int procState = app.curProcState; 11953 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11954 outInfo.importanceReasonCode = app.adjTypeCode; 11955 outInfo.processState = app.curProcState; 11956 } 11957 11958 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11959 enforceNotIsolatedCaller("getRunningAppProcesses"); 11960 // Lazy instantiation of list 11961 List<ActivityManager.RunningAppProcessInfo> runList = null; 11962 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11963 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11964 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11965 synchronized (this) { 11966 // Iterate across all processes 11967 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11968 ProcessRecord app = mLruProcesses.get(i); 11969 if (!allUsers && app.userId != userId) { 11970 continue; 11971 } 11972 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11973 // Generate process state info for running application 11974 ActivityManager.RunningAppProcessInfo currApp = 11975 new ActivityManager.RunningAppProcessInfo(app.processName, 11976 app.pid, app.getPackageList()); 11977 fillInProcMemInfo(app, currApp); 11978 if (app.adjSource instanceof ProcessRecord) { 11979 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11980 currApp.importanceReasonImportance = 11981 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11982 app.adjSourceProcState); 11983 } else if (app.adjSource instanceof ActivityRecord) { 11984 ActivityRecord r = (ActivityRecord)app.adjSource; 11985 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11986 } 11987 if (app.adjTarget instanceof ComponentName) { 11988 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11989 } 11990 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11991 // + " lru=" + currApp.lru); 11992 if (runList == null) { 11993 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11994 } 11995 runList.add(currApp); 11996 } 11997 } 11998 } 11999 return runList; 12000 } 12001 12002 public List<ApplicationInfo> getRunningExternalApplications() { 12003 enforceNotIsolatedCaller("getRunningExternalApplications"); 12004 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12005 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12006 if (runningApps != null && runningApps.size() > 0) { 12007 Set<String> extList = new HashSet<String>(); 12008 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12009 if (app.pkgList != null) { 12010 for (String pkg : app.pkgList) { 12011 extList.add(pkg); 12012 } 12013 } 12014 } 12015 IPackageManager pm = AppGlobals.getPackageManager(); 12016 for (String pkg : extList) { 12017 try { 12018 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12019 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12020 retList.add(info); 12021 } 12022 } catch (RemoteException e) { 12023 } 12024 } 12025 } 12026 return retList; 12027 } 12028 12029 @Override 12030 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12031 enforceNotIsolatedCaller("getMyMemoryState"); 12032 synchronized (this) { 12033 ProcessRecord proc; 12034 synchronized (mPidsSelfLocked) { 12035 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12036 } 12037 fillInProcMemInfo(proc, outInfo); 12038 } 12039 } 12040 12041 @Override 12042 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12043 if (checkCallingPermission(android.Manifest.permission.DUMP) 12044 != PackageManager.PERMISSION_GRANTED) { 12045 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12046 + Binder.getCallingPid() 12047 + ", uid=" + Binder.getCallingUid() 12048 + " without permission " 12049 + android.Manifest.permission.DUMP); 12050 return; 12051 } 12052 12053 boolean dumpAll = false; 12054 boolean dumpClient = false; 12055 String dumpPackage = null; 12056 12057 int opti = 0; 12058 while (opti < args.length) { 12059 String opt = args[opti]; 12060 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12061 break; 12062 } 12063 opti++; 12064 if ("-a".equals(opt)) { 12065 dumpAll = true; 12066 } else if ("-c".equals(opt)) { 12067 dumpClient = true; 12068 } else if ("-h".equals(opt)) { 12069 pw.println("Activity manager dump options:"); 12070 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12071 pw.println(" cmd may be one of:"); 12072 pw.println(" a[ctivities]: activity stack state"); 12073 pw.println(" r[recents]: recent activities state"); 12074 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12075 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12076 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12077 pw.println(" o[om]: out of memory management"); 12078 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12079 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12080 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12081 pw.println(" service [COMP_SPEC]: service client-side state"); 12082 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12083 pw.println(" all: dump all activities"); 12084 pw.println(" top: dump the top activity"); 12085 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12086 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12087 pw.println(" a partial substring in a component name, a"); 12088 pw.println(" hex object identifier."); 12089 pw.println(" -a: include all available server state."); 12090 pw.println(" -c: include client state."); 12091 return; 12092 } else { 12093 pw.println("Unknown argument: " + opt + "; use -h for help"); 12094 } 12095 } 12096 12097 long origId = Binder.clearCallingIdentity(); 12098 boolean more = false; 12099 // Is the caller requesting to dump a particular piece of data? 12100 if (opti < args.length) { 12101 String cmd = args[opti]; 12102 opti++; 12103 if ("activities".equals(cmd) || "a".equals(cmd)) { 12104 synchronized (this) { 12105 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12106 } 12107 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12108 synchronized (this) { 12109 dumpRecentsLocked(fd, pw, args, opti, true, null); 12110 } 12111 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12112 String[] newArgs; 12113 String name; 12114 if (opti >= args.length) { 12115 name = null; 12116 newArgs = EMPTY_STRING_ARRAY; 12117 } else { 12118 name = args[opti]; 12119 opti++; 12120 newArgs = new String[args.length - opti]; 12121 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12122 args.length - opti); 12123 } 12124 synchronized (this) { 12125 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12126 } 12127 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12128 String[] newArgs; 12129 String name; 12130 if (opti >= args.length) { 12131 name = null; 12132 newArgs = EMPTY_STRING_ARRAY; 12133 } else { 12134 name = args[opti]; 12135 opti++; 12136 newArgs = new String[args.length - opti]; 12137 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12138 args.length - opti); 12139 } 12140 synchronized (this) { 12141 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12142 } 12143 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12144 String[] newArgs; 12145 String name; 12146 if (opti >= args.length) { 12147 name = null; 12148 newArgs = EMPTY_STRING_ARRAY; 12149 } else { 12150 name = args[opti]; 12151 opti++; 12152 newArgs = new String[args.length - opti]; 12153 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12154 args.length - opti); 12155 } 12156 synchronized (this) { 12157 dumpProcessesLocked(fd, pw, args, opti, true, name); 12158 } 12159 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12160 synchronized (this) { 12161 dumpOomLocked(fd, pw, args, opti, true); 12162 } 12163 } else if ("provider".equals(cmd)) { 12164 String[] newArgs; 12165 String name; 12166 if (opti >= args.length) { 12167 name = null; 12168 newArgs = EMPTY_STRING_ARRAY; 12169 } else { 12170 name = args[opti]; 12171 opti++; 12172 newArgs = new String[args.length - opti]; 12173 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12174 } 12175 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12176 pw.println("No providers match: " + name); 12177 pw.println("Use -h for help."); 12178 } 12179 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12180 synchronized (this) { 12181 dumpProvidersLocked(fd, pw, args, opti, true, null); 12182 } 12183 } else if ("service".equals(cmd)) { 12184 String[] newArgs; 12185 String name; 12186 if (opti >= args.length) { 12187 name = null; 12188 newArgs = EMPTY_STRING_ARRAY; 12189 } else { 12190 name = args[opti]; 12191 opti++; 12192 newArgs = new String[args.length - opti]; 12193 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12194 args.length - opti); 12195 } 12196 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12197 pw.println("No services match: " + name); 12198 pw.println("Use -h for help."); 12199 } 12200 } else if ("package".equals(cmd)) { 12201 String[] newArgs; 12202 if (opti >= args.length) { 12203 pw.println("package: no package name specified"); 12204 pw.println("Use -h for help."); 12205 } else { 12206 dumpPackage = args[opti]; 12207 opti++; 12208 newArgs = new String[args.length - opti]; 12209 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12210 args.length - opti); 12211 args = newArgs; 12212 opti = 0; 12213 more = true; 12214 } 12215 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12216 synchronized (this) { 12217 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12218 } 12219 } else { 12220 // Dumping a single activity? 12221 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12222 pw.println("Bad activity command, or no activities match: " + cmd); 12223 pw.println("Use -h for help."); 12224 } 12225 } 12226 if (!more) { 12227 Binder.restoreCallingIdentity(origId); 12228 return; 12229 } 12230 } 12231 12232 // No piece of data specified, dump everything. 12233 synchronized (this) { 12234 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12235 pw.println(); 12236 if (dumpAll) { 12237 pw.println("-------------------------------------------------------------------------------"); 12238 } 12239 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12240 pw.println(); 12241 if (dumpAll) { 12242 pw.println("-------------------------------------------------------------------------------"); 12243 } 12244 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12245 pw.println(); 12246 if (dumpAll) { 12247 pw.println("-------------------------------------------------------------------------------"); 12248 } 12249 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12250 pw.println(); 12251 if (dumpAll) { 12252 pw.println("-------------------------------------------------------------------------------"); 12253 } 12254 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12255 pw.println(); 12256 if (dumpAll) { 12257 pw.println("-------------------------------------------------------------------------------"); 12258 } 12259 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12260 pw.println(); 12261 if (dumpAll) { 12262 pw.println("-------------------------------------------------------------------------------"); 12263 } 12264 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12265 } 12266 Binder.restoreCallingIdentity(origId); 12267 } 12268 12269 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12270 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12271 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12272 12273 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12274 dumpPackage); 12275 boolean needSep = printedAnything; 12276 12277 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12278 dumpPackage, needSep, " mFocusedActivity: "); 12279 if (printed) { 12280 printedAnything = true; 12281 needSep = false; 12282 } 12283 12284 if (dumpPackage == null) { 12285 if (needSep) { 12286 pw.println(); 12287 } 12288 needSep = true; 12289 printedAnything = true; 12290 mStackSupervisor.dump(pw, " "); 12291 } 12292 12293 if (!printedAnything) { 12294 pw.println(" (nothing)"); 12295 } 12296 } 12297 12298 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12299 int opti, boolean dumpAll, String dumpPackage) { 12300 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12301 12302 boolean printedAnything = false; 12303 12304 if (mRecentTasks.size() > 0) { 12305 boolean printedHeader = false; 12306 12307 final int N = mRecentTasks.size(); 12308 for (int i=0; i<N; i++) { 12309 TaskRecord tr = mRecentTasks.get(i); 12310 if (dumpPackage != null) { 12311 if (tr.realActivity == null || 12312 !dumpPackage.equals(tr.realActivity)) { 12313 continue; 12314 } 12315 } 12316 if (!printedHeader) { 12317 pw.println(" Recent tasks:"); 12318 printedHeader = true; 12319 printedAnything = true; 12320 } 12321 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12322 pw.println(tr); 12323 if (dumpAll) { 12324 mRecentTasks.get(i).dump(pw, " "); 12325 } 12326 } 12327 } 12328 12329 if (!printedAnything) { 12330 pw.println(" (nothing)"); 12331 } 12332 } 12333 12334 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12335 int opti, boolean dumpAll, String dumpPackage) { 12336 boolean needSep = false; 12337 boolean printedAnything = false; 12338 int numPers = 0; 12339 12340 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12341 12342 if (dumpAll) { 12343 final int NP = mProcessNames.getMap().size(); 12344 for (int ip=0; ip<NP; ip++) { 12345 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12346 final int NA = procs.size(); 12347 for (int ia=0; ia<NA; ia++) { 12348 ProcessRecord r = procs.valueAt(ia); 12349 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12350 continue; 12351 } 12352 if (!needSep) { 12353 pw.println(" All known processes:"); 12354 needSep = true; 12355 printedAnything = true; 12356 } 12357 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12358 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12359 pw.print(" "); pw.println(r); 12360 r.dump(pw, " "); 12361 if (r.persistent) { 12362 numPers++; 12363 } 12364 } 12365 } 12366 } 12367 12368 if (mIsolatedProcesses.size() > 0) { 12369 boolean printed = false; 12370 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12371 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12372 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12373 continue; 12374 } 12375 if (!printed) { 12376 if (needSep) { 12377 pw.println(); 12378 } 12379 pw.println(" Isolated process list (sorted by uid):"); 12380 printedAnything = true; 12381 printed = true; 12382 needSep = true; 12383 } 12384 pw.println(String.format("%sIsolated #%2d: %s", 12385 " ", i, r.toString())); 12386 } 12387 } 12388 12389 if (mLruProcesses.size() > 0) { 12390 if (needSep) { 12391 pw.println(); 12392 } 12393 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12394 pw.print(" total, non-act at "); 12395 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12396 pw.print(", non-svc at "); 12397 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12398 pw.println("):"); 12399 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12400 needSep = true; 12401 printedAnything = true; 12402 } 12403 12404 if (dumpAll || dumpPackage != null) { 12405 synchronized (mPidsSelfLocked) { 12406 boolean printed = false; 12407 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12408 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12409 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12410 continue; 12411 } 12412 if (!printed) { 12413 if (needSep) pw.println(); 12414 needSep = true; 12415 pw.println(" PID mappings:"); 12416 printed = true; 12417 printedAnything = true; 12418 } 12419 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12420 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12421 } 12422 } 12423 } 12424 12425 if (mForegroundProcesses.size() > 0) { 12426 synchronized (mPidsSelfLocked) { 12427 boolean printed = false; 12428 for (int i=0; i<mForegroundProcesses.size(); i++) { 12429 ProcessRecord r = mPidsSelfLocked.get( 12430 mForegroundProcesses.valueAt(i).pid); 12431 if (dumpPackage != null && (r == null 12432 || !r.pkgList.containsKey(dumpPackage))) { 12433 continue; 12434 } 12435 if (!printed) { 12436 if (needSep) pw.println(); 12437 needSep = true; 12438 pw.println(" Foreground Processes:"); 12439 printed = true; 12440 printedAnything = true; 12441 } 12442 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12443 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12444 } 12445 } 12446 } 12447 12448 if (mPersistentStartingProcesses.size() > 0) { 12449 if (needSep) pw.println(); 12450 needSep = true; 12451 printedAnything = true; 12452 pw.println(" Persisent processes that are starting:"); 12453 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12454 "Starting Norm", "Restarting PERS", dumpPackage); 12455 } 12456 12457 if (mRemovedProcesses.size() > 0) { 12458 if (needSep) pw.println(); 12459 needSep = true; 12460 printedAnything = true; 12461 pw.println(" Processes that are being removed:"); 12462 dumpProcessList(pw, this, mRemovedProcesses, " ", 12463 "Removed Norm", "Removed PERS", dumpPackage); 12464 } 12465 12466 if (mProcessesOnHold.size() > 0) { 12467 if (needSep) pw.println(); 12468 needSep = true; 12469 printedAnything = true; 12470 pw.println(" Processes that are on old until the system is ready:"); 12471 dumpProcessList(pw, this, mProcessesOnHold, " ", 12472 "OnHold Norm", "OnHold PERS", dumpPackage); 12473 } 12474 12475 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12476 12477 if (mProcessCrashTimes.getMap().size() > 0) { 12478 boolean printed = false; 12479 long now = SystemClock.uptimeMillis(); 12480 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12481 final int NP = pmap.size(); 12482 for (int ip=0; ip<NP; ip++) { 12483 String pname = pmap.keyAt(ip); 12484 SparseArray<Long> uids = pmap.valueAt(ip); 12485 final int N = uids.size(); 12486 for (int i=0; i<N; i++) { 12487 int puid = uids.keyAt(i); 12488 ProcessRecord r = mProcessNames.get(pname, puid); 12489 if (dumpPackage != null && (r == null 12490 || !r.pkgList.containsKey(dumpPackage))) { 12491 continue; 12492 } 12493 if (!printed) { 12494 if (needSep) pw.println(); 12495 needSep = true; 12496 pw.println(" Time since processes crashed:"); 12497 printed = true; 12498 printedAnything = true; 12499 } 12500 pw.print(" Process "); pw.print(pname); 12501 pw.print(" uid "); pw.print(puid); 12502 pw.print(": last crashed "); 12503 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12504 pw.println(" ago"); 12505 } 12506 } 12507 } 12508 12509 if (mBadProcesses.getMap().size() > 0) { 12510 boolean printed = false; 12511 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12512 final int NP = pmap.size(); 12513 for (int ip=0; ip<NP; ip++) { 12514 String pname = pmap.keyAt(ip); 12515 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12516 final int N = uids.size(); 12517 for (int i=0; i<N; i++) { 12518 int puid = uids.keyAt(i); 12519 ProcessRecord r = mProcessNames.get(pname, puid); 12520 if (dumpPackage != null && (r == null 12521 || !r.pkgList.containsKey(dumpPackage))) { 12522 continue; 12523 } 12524 if (!printed) { 12525 if (needSep) pw.println(); 12526 needSep = true; 12527 pw.println(" Bad processes:"); 12528 printedAnything = true; 12529 } 12530 BadProcessInfo info = uids.valueAt(i); 12531 pw.print(" Bad process "); pw.print(pname); 12532 pw.print(" uid "); pw.print(puid); 12533 pw.print(": crashed at time "); pw.println(info.time); 12534 if (info.shortMsg != null) { 12535 pw.print(" Short msg: "); pw.println(info.shortMsg); 12536 } 12537 if (info.longMsg != null) { 12538 pw.print(" Long msg: "); pw.println(info.longMsg); 12539 } 12540 if (info.stack != null) { 12541 pw.println(" Stack:"); 12542 int lastPos = 0; 12543 for (int pos=0; pos<info.stack.length(); pos++) { 12544 if (info.stack.charAt(pos) == '\n') { 12545 pw.print(" "); 12546 pw.write(info.stack, lastPos, pos-lastPos); 12547 pw.println(); 12548 lastPos = pos+1; 12549 } 12550 } 12551 if (lastPos < info.stack.length()) { 12552 pw.print(" "); 12553 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12554 pw.println(); 12555 } 12556 } 12557 } 12558 } 12559 } 12560 12561 if (dumpPackage == null) { 12562 pw.println(); 12563 needSep = false; 12564 pw.println(" mStartedUsers:"); 12565 for (int i=0; i<mStartedUsers.size(); i++) { 12566 UserStartedState uss = mStartedUsers.valueAt(i); 12567 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12568 pw.print(": "); uss.dump("", pw); 12569 } 12570 pw.print(" mStartedUserArray: ["); 12571 for (int i=0; i<mStartedUserArray.length; i++) { 12572 if (i > 0) pw.print(", "); 12573 pw.print(mStartedUserArray[i]); 12574 } 12575 pw.println("]"); 12576 pw.print(" mUserLru: ["); 12577 for (int i=0; i<mUserLru.size(); i++) { 12578 if (i > 0) pw.print(", "); 12579 pw.print(mUserLru.get(i)); 12580 } 12581 pw.println("]"); 12582 if (dumpAll) { 12583 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12584 } 12585 synchronized (mUserProfileGroupIdsSelfLocked) { 12586 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12587 pw.println(" mUserProfileGroupIds:"); 12588 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12589 pw.print(" User #"); 12590 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12591 pw.print(" -> profile #"); 12592 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12593 } 12594 } 12595 } 12596 } 12597 if (mHomeProcess != null && (dumpPackage == null 12598 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12599 if (needSep) { 12600 pw.println(); 12601 needSep = false; 12602 } 12603 pw.println(" mHomeProcess: " + mHomeProcess); 12604 } 12605 if (mPreviousProcess != null && (dumpPackage == null 12606 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12607 if (needSep) { 12608 pw.println(); 12609 needSep = false; 12610 } 12611 pw.println(" mPreviousProcess: " + mPreviousProcess); 12612 } 12613 if (dumpAll) { 12614 StringBuilder sb = new StringBuilder(128); 12615 sb.append(" mPreviousProcessVisibleTime: "); 12616 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12617 pw.println(sb); 12618 } 12619 if (mHeavyWeightProcess != null && (dumpPackage == null 12620 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12621 if (needSep) { 12622 pw.println(); 12623 needSep = false; 12624 } 12625 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12626 } 12627 if (dumpPackage == null) { 12628 pw.println(" mConfiguration: " + mConfiguration); 12629 } 12630 if (dumpAll) { 12631 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12632 if (mCompatModePackages.getPackages().size() > 0) { 12633 boolean printed = false; 12634 for (Map.Entry<String, Integer> entry 12635 : mCompatModePackages.getPackages().entrySet()) { 12636 String pkg = entry.getKey(); 12637 int mode = entry.getValue(); 12638 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12639 continue; 12640 } 12641 if (!printed) { 12642 pw.println(" mScreenCompatPackages:"); 12643 printed = true; 12644 } 12645 pw.print(" "); pw.print(pkg); pw.print(": "); 12646 pw.print(mode); pw.println(); 12647 } 12648 } 12649 } 12650 if (dumpPackage == null) { 12651 if (mSleeping || mWentToSleep || mLockScreenShown) { 12652 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12653 + " mLockScreenShown " + mLockScreenShown); 12654 } 12655 if (mShuttingDown || mRunningVoice) { 12656 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12657 } 12658 } 12659 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12660 || mOrigWaitForDebugger) { 12661 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12662 || dumpPackage.equals(mOrigDebugApp)) { 12663 if (needSep) { 12664 pw.println(); 12665 needSep = false; 12666 } 12667 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12668 + " mDebugTransient=" + mDebugTransient 12669 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12670 } 12671 } 12672 if (mOpenGlTraceApp != null) { 12673 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12674 if (needSep) { 12675 pw.println(); 12676 needSep = false; 12677 } 12678 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12679 } 12680 } 12681 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12682 || mProfileFd != null) { 12683 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12684 if (needSep) { 12685 pw.println(); 12686 needSep = false; 12687 } 12688 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12689 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12690 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12691 + mAutoStopProfiler); 12692 pw.println(" mProfileType=" + mProfileType); 12693 } 12694 } 12695 if (dumpPackage == null) { 12696 if (mAlwaysFinishActivities || mController != null) { 12697 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12698 + " mController=" + mController); 12699 } 12700 if (dumpAll) { 12701 pw.println(" Total persistent processes: " + numPers); 12702 pw.println(" mProcessesReady=" + mProcessesReady 12703 + " mSystemReady=" + mSystemReady); 12704 pw.println(" mBooting=" + mBooting 12705 + " mBooted=" + mBooted 12706 + " mFactoryTest=" + mFactoryTest); 12707 pw.print(" mLastPowerCheckRealtime="); 12708 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12709 pw.println(""); 12710 pw.print(" mLastPowerCheckUptime="); 12711 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12712 pw.println(""); 12713 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12714 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12715 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12716 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12717 + " (" + mLruProcesses.size() + " total)" 12718 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12719 + " mNumServiceProcs=" + mNumServiceProcs 12720 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12721 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12722 + " mLastMemoryLevel" + mLastMemoryLevel 12723 + " mLastNumProcesses" + mLastNumProcesses); 12724 long now = SystemClock.uptimeMillis(); 12725 pw.print(" mLastIdleTime="); 12726 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12727 pw.print(" mLowRamSinceLastIdle="); 12728 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12729 pw.println(); 12730 } 12731 } 12732 12733 if (!printedAnything) { 12734 pw.println(" (nothing)"); 12735 } 12736 } 12737 12738 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12739 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12740 if (mProcessesToGc.size() > 0) { 12741 boolean printed = false; 12742 long now = SystemClock.uptimeMillis(); 12743 for (int i=0; i<mProcessesToGc.size(); i++) { 12744 ProcessRecord proc = mProcessesToGc.get(i); 12745 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12746 continue; 12747 } 12748 if (!printed) { 12749 if (needSep) pw.println(); 12750 needSep = true; 12751 pw.println(" Processes that are waiting to GC:"); 12752 printed = true; 12753 } 12754 pw.print(" Process "); pw.println(proc); 12755 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12756 pw.print(", last gced="); 12757 pw.print(now-proc.lastRequestedGc); 12758 pw.print(" ms ago, last lowMem="); 12759 pw.print(now-proc.lastLowMemory); 12760 pw.println(" ms ago"); 12761 12762 } 12763 } 12764 return needSep; 12765 } 12766 12767 void printOomLevel(PrintWriter pw, String name, int adj) { 12768 pw.print(" "); 12769 if (adj >= 0) { 12770 pw.print(' '); 12771 if (adj < 10) pw.print(' '); 12772 } else { 12773 if (adj > -10) pw.print(' '); 12774 } 12775 pw.print(adj); 12776 pw.print(": "); 12777 pw.print(name); 12778 pw.print(" ("); 12779 pw.print(mProcessList.getMemLevel(adj)/1024); 12780 pw.println(" kB)"); 12781 } 12782 12783 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12784 int opti, boolean dumpAll) { 12785 boolean needSep = false; 12786 12787 if (mLruProcesses.size() > 0) { 12788 if (needSep) pw.println(); 12789 needSep = true; 12790 pw.println(" OOM levels:"); 12791 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12792 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12793 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12794 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12795 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12796 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12797 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12798 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12799 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12800 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12801 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12802 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12803 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12804 12805 if (needSep) pw.println(); 12806 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12807 pw.print(" total, non-act at "); 12808 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12809 pw.print(", non-svc at "); 12810 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12811 pw.println("):"); 12812 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12813 needSep = true; 12814 } 12815 12816 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12817 12818 pw.println(); 12819 pw.println(" mHomeProcess: " + mHomeProcess); 12820 pw.println(" mPreviousProcess: " + mPreviousProcess); 12821 if (mHeavyWeightProcess != null) { 12822 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12823 } 12824 12825 return true; 12826 } 12827 12828 /** 12829 * There are three ways to call this: 12830 * - no provider specified: dump all the providers 12831 * - a flattened component name that matched an existing provider was specified as the 12832 * first arg: dump that one provider 12833 * - the first arg isn't the flattened component name of an existing provider: 12834 * dump all providers whose component contains the first arg as a substring 12835 */ 12836 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12837 int opti, boolean dumpAll) { 12838 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12839 } 12840 12841 static class ItemMatcher { 12842 ArrayList<ComponentName> components; 12843 ArrayList<String> strings; 12844 ArrayList<Integer> objects; 12845 boolean all; 12846 12847 ItemMatcher() { 12848 all = true; 12849 } 12850 12851 void build(String name) { 12852 ComponentName componentName = ComponentName.unflattenFromString(name); 12853 if (componentName != null) { 12854 if (components == null) { 12855 components = new ArrayList<ComponentName>(); 12856 } 12857 components.add(componentName); 12858 all = false; 12859 } else { 12860 int objectId = 0; 12861 // Not a '/' separated full component name; maybe an object ID? 12862 try { 12863 objectId = Integer.parseInt(name, 16); 12864 if (objects == null) { 12865 objects = new ArrayList<Integer>(); 12866 } 12867 objects.add(objectId); 12868 all = false; 12869 } catch (RuntimeException e) { 12870 // Not an integer; just do string match. 12871 if (strings == null) { 12872 strings = new ArrayList<String>(); 12873 } 12874 strings.add(name); 12875 all = false; 12876 } 12877 } 12878 } 12879 12880 int build(String[] args, int opti) { 12881 for (; opti<args.length; opti++) { 12882 String name = args[opti]; 12883 if ("--".equals(name)) { 12884 return opti+1; 12885 } 12886 build(name); 12887 } 12888 return opti; 12889 } 12890 12891 boolean match(Object object, ComponentName comp) { 12892 if (all) { 12893 return true; 12894 } 12895 if (components != null) { 12896 for (int i=0; i<components.size(); i++) { 12897 if (components.get(i).equals(comp)) { 12898 return true; 12899 } 12900 } 12901 } 12902 if (objects != null) { 12903 for (int i=0; i<objects.size(); i++) { 12904 if (System.identityHashCode(object) == objects.get(i)) { 12905 return true; 12906 } 12907 } 12908 } 12909 if (strings != null) { 12910 String flat = comp.flattenToString(); 12911 for (int i=0; i<strings.size(); i++) { 12912 if (flat.contains(strings.get(i))) { 12913 return true; 12914 } 12915 } 12916 } 12917 return false; 12918 } 12919 } 12920 12921 /** 12922 * There are three things that cmd can be: 12923 * - a flattened component name that matches an existing activity 12924 * - the cmd arg isn't the flattened component name of an existing activity: 12925 * dump all activity whose component contains the cmd as a substring 12926 * - A hex number of the ActivityRecord object instance. 12927 */ 12928 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12929 int opti, boolean dumpAll) { 12930 ArrayList<ActivityRecord> activities; 12931 12932 synchronized (this) { 12933 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12934 } 12935 12936 if (activities.size() <= 0) { 12937 return false; 12938 } 12939 12940 String[] newArgs = new String[args.length - opti]; 12941 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12942 12943 TaskRecord lastTask = null; 12944 boolean needSep = false; 12945 for (int i=activities.size()-1; i>=0; i--) { 12946 ActivityRecord r = activities.get(i); 12947 if (needSep) { 12948 pw.println(); 12949 } 12950 needSep = true; 12951 synchronized (this) { 12952 if (lastTask != r.task) { 12953 lastTask = r.task; 12954 pw.print("TASK "); pw.print(lastTask.affinity); 12955 pw.print(" id="); pw.println(lastTask.taskId); 12956 if (dumpAll) { 12957 lastTask.dump(pw, " "); 12958 } 12959 } 12960 } 12961 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12962 } 12963 return true; 12964 } 12965 12966 /** 12967 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12968 * there is a thread associated with the activity. 12969 */ 12970 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12971 final ActivityRecord r, String[] args, boolean dumpAll) { 12972 String innerPrefix = prefix + " "; 12973 synchronized (this) { 12974 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12975 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12976 pw.print(" pid="); 12977 if (r.app != null) pw.println(r.app.pid); 12978 else pw.println("(not running)"); 12979 if (dumpAll) { 12980 r.dump(pw, innerPrefix); 12981 } 12982 } 12983 if (r.app != null && r.app.thread != null) { 12984 // flush anything that is already in the PrintWriter since the thread is going 12985 // to write to the file descriptor directly 12986 pw.flush(); 12987 try { 12988 TransferPipe tp = new TransferPipe(); 12989 try { 12990 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12991 r.appToken, innerPrefix, args); 12992 tp.go(fd); 12993 } finally { 12994 tp.kill(); 12995 } 12996 } catch (IOException e) { 12997 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12998 } catch (RemoteException e) { 12999 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13000 } 13001 } 13002 } 13003 13004 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13005 int opti, boolean dumpAll, String dumpPackage) { 13006 boolean needSep = false; 13007 boolean onlyHistory = false; 13008 boolean printedAnything = false; 13009 13010 if ("history".equals(dumpPackage)) { 13011 if (opti < args.length && "-s".equals(args[opti])) { 13012 dumpAll = false; 13013 } 13014 onlyHistory = true; 13015 dumpPackage = null; 13016 } 13017 13018 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13019 if (!onlyHistory && dumpAll) { 13020 if (mRegisteredReceivers.size() > 0) { 13021 boolean printed = false; 13022 Iterator it = mRegisteredReceivers.values().iterator(); 13023 while (it.hasNext()) { 13024 ReceiverList r = (ReceiverList)it.next(); 13025 if (dumpPackage != null && (r.app == null || 13026 !dumpPackage.equals(r.app.info.packageName))) { 13027 continue; 13028 } 13029 if (!printed) { 13030 pw.println(" Registered Receivers:"); 13031 needSep = true; 13032 printed = true; 13033 printedAnything = true; 13034 } 13035 pw.print(" * "); pw.println(r); 13036 r.dump(pw, " "); 13037 } 13038 } 13039 13040 if (mReceiverResolver.dump(pw, needSep ? 13041 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13042 " ", dumpPackage, false)) { 13043 needSep = true; 13044 printedAnything = true; 13045 } 13046 } 13047 13048 for (BroadcastQueue q : mBroadcastQueues) { 13049 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13050 printedAnything |= needSep; 13051 } 13052 13053 needSep = true; 13054 13055 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13056 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13057 if (needSep) { 13058 pw.println(); 13059 } 13060 needSep = true; 13061 printedAnything = true; 13062 pw.print(" Sticky broadcasts for user "); 13063 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13064 StringBuilder sb = new StringBuilder(128); 13065 for (Map.Entry<String, ArrayList<Intent>> ent 13066 : mStickyBroadcasts.valueAt(user).entrySet()) { 13067 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13068 if (dumpAll) { 13069 pw.println(":"); 13070 ArrayList<Intent> intents = ent.getValue(); 13071 final int N = intents.size(); 13072 for (int i=0; i<N; i++) { 13073 sb.setLength(0); 13074 sb.append(" Intent: "); 13075 intents.get(i).toShortString(sb, false, true, false, false); 13076 pw.println(sb.toString()); 13077 Bundle bundle = intents.get(i).getExtras(); 13078 if (bundle != null) { 13079 pw.print(" "); 13080 pw.println(bundle.toString()); 13081 } 13082 } 13083 } else { 13084 pw.println(""); 13085 } 13086 } 13087 } 13088 } 13089 13090 if (!onlyHistory && dumpAll) { 13091 pw.println(); 13092 for (BroadcastQueue queue : mBroadcastQueues) { 13093 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13094 + queue.mBroadcastsScheduled); 13095 } 13096 pw.println(" mHandler:"); 13097 mHandler.dump(new PrintWriterPrinter(pw), " "); 13098 needSep = true; 13099 printedAnything = true; 13100 } 13101 13102 if (!printedAnything) { 13103 pw.println(" (nothing)"); 13104 } 13105 } 13106 13107 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13108 int opti, boolean dumpAll, String dumpPackage) { 13109 boolean needSep; 13110 boolean printedAnything = false; 13111 13112 ItemMatcher matcher = new ItemMatcher(); 13113 matcher.build(args, opti); 13114 13115 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13116 13117 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13118 printedAnything |= needSep; 13119 13120 if (mLaunchingProviders.size() > 0) { 13121 boolean printed = false; 13122 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13123 ContentProviderRecord r = mLaunchingProviders.get(i); 13124 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13125 continue; 13126 } 13127 if (!printed) { 13128 if (needSep) pw.println(); 13129 needSep = true; 13130 pw.println(" Launching content providers:"); 13131 printed = true; 13132 printedAnything = true; 13133 } 13134 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13135 pw.println(r); 13136 } 13137 } 13138 13139 if (mGrantedUriPermissions.size() > 0) { 13140 boolean printed = false; 13141 int dumpUid = -2; 13142 if (dumpPackage != null) { 13143 try { 13144 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13145 } catch (NameNotFoundException e) { 13146 dumpUid = -1; 13147 } 13148 } 13149 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13150 int uid = mGrantedUriPermissions.keyAt(i); 13151 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13152 continue; 13153 } 13154 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13155 if (!printed) { 13156 if (needSep) pw.println(); 13157 needSep = true; 13158 pw.println(" Granted Uri Permissions:"); 13159 printed = true; 13160 printedAnything = true; 13161 } 13162 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13163 for (UriPermission perm : perms.values()) { 13164 pw.print(" "); pw.println(perm); 13165 if (dumpAll) { 13166 perm.dump(pw, " "); 13167 } 13168 } 13169 } 13170 } 13171 13172 if (!printedAnything) { 13173 pw.println(" (nothing)"); 13174 } 13175 } 13176 13177 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13178 int opti, boolean dumpAll, String dumpPackage) { 13179 boolean printed = false; 13180 13181 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13182 13183 if (mIntentSenderRecords.size() > 0) { 13184 Iterator<WeakReference<PendingIntentRecord>> it 13185 = mIntentSenderRecords.values().iterator(); 13186 while (it.hasNext()) { 13187 WeakReference<PendingIntentRecord> ref = it.next(); 13188 PendingIntentRecord rec = ref != null ? ref.get(): null; 13189 if (dumpPackage != null && (rec == null 13190 || !dumpPackage.equals(rec.key.packageName))) { 13191 continue; 13192 } 13193 printed = true; 13194 if (rec != null) { 13195 pw.print(" * "); pw.println(rec); 13196 if (dumpAll) { 13197 rec.dump(pw, " "); 13198 } 13199 } else { 13200 pw.print(" * "); pw.println(ref); 13201 } 13202 } 13203 } 13204 13205 if (!printed) { 13206 pw.println(" (nothing)"); 13207 } 13208 } 13209 13210 private static final int dumpProcessList(PrintWriter pw, 13211 ActivityManagerService service, List list, 13212 String prefix, String normalLabel, String persistentLabel, 13213 String dumpPackage) { 13214 int numPers = 0; 13215 final int N = list.size()-1; 13216 for (int i=N; i>=0; i--) { 13217 ProcessRecord r = (ProcessRecord)list.get(i); 13218 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13219 continue; 13220 } 13221 pw.println(String.format("%s%s #%2d: %s", 13222 prefix, (r.persistent ? persistentLabel : normalLabel), 13223 i, r.toString())); 13224 if (r.persistent) { 13225 numPers++; 13226 } 13227 } 13228 return numPers; 13229 } 13230 13231 private static final boolean dumpProcessOomList(PrintWriter pw, 13232 ActivityManagerService service, List<ProcessRecord> origList, 13233 String prefix, String normalLabel, String persistentLabel, 13234 boolean inclDetails, String dumpPackage) { 13235 13236 ArrayList<Pair<ProcessRecord, Integer>> list 13237 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13238 for (int i=0; i<origList.size(); i++) { 13239 ProcessRecord r = origList.get(i); 13240 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13241 continue; 13242 } 13243 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13244 } 13245 13246 if (list.size() <= 0) { 13247 return false; 13248 } 13249 13250 Comparator<Pair<ProcessRecord, Integer>> comparator 13251 = new Comparator<Pair<ProcessRecord, Integer>>() { 13252 @Override 13253 public int compare(Pair<ProcessRecord, Integer> object1, 13254 Pair<ProcessRecord, Integer> object2) { 13255 if (object1.first.setAdj != object2.first.setAdj) { 13256 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13257 } 13258 if (object1.second.intValue() != object2.second.intValue()) { 13259 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13260 } 13261 return 0; 13262 } 13263 }; 13264 13265 Collections.sort(list, comparator); 13266 13267 final long curRealtime = SystemClock.elapsedRealtime(); 13268 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13269 final long curUptime = SystemClock.uptimeMillis(); 13270 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13271 13272 for (int i=list.size()-1; i>=0; i--) { 13273 ProcessRecord r = list.get(i).first; 13274 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13275 char schedGroup; 13276 switch (r.setSchedGroup) { 13277 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13278 schedGroup = 'B'; 13279 break; 13280 case Process.THREAD_GROUP_DEFAULT: 13281 schedGroup = 'F'; 13282 break; 13283 default: 13284 schedGroup = '?'; 13285 break; 13286 } 13287 char foreground; 13288 if (r.foregroundActivities) { 13289 foreground = 'A'; 13290 } else if (r.foregroundServices) { 13291 foreground = 'S'; 13292 } else { 13293 foreground = ' '; 13294 } 13295 String procState = ProcessList.makeProcStateString(r.curProcState); 13296 pw.print(prefix); 13297 pw.print(r.persistent ? persistentLabel : normalLabel); 13298 pw.print(" #"); 13299 int num = (origList.size()-1)-list.get(i).second; 13300 if (num < 10) pw.print(' '); 13301 pw.print(num); 13302 pw.print(": "); 13303 pw.print(oomAdj); 13304 pw.print(' '); 13305 pw.print(schedGroup); 13306 pw.print('/'); 13307 pw.print(foreground); 13308 pw.print('/'); 13309 pw.print(procState); 13310 pw.print(" trm:"); 13311 if (r.trimMemoryLevel < 10) pw.print(' '); 13312 pw.print(r.trimMemoryLevel); 13313 pw.print(' '); 13314 pw.print(r.toShortString()); 13315 pw.print(" ("); 13316 pw.print(r.adjType); 13317 pw.println(')'); 13318 if (r.adjSource != null || r.adjTarget != null) { 13319 pw.print(prefix); 13320 pw.print(" "); 13321 if (r.adjTarget instanceof ComponentName) { 13322 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13323 } else if (r.adjTarget != null) { 13324 pw.print(r.adjTarget.toString()); 13325 } else { 13326 pw.print("{null}"); 13327 } 13328 pw.print("<="); 13329 if (r.adjSource instanceof ProcessRecord) { 13330 pw.print("Proc{"); 13331 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13332 pw.println("}"); 13333 } else if (r.adjSource != null) { 13334 pw.println(r.adjSource.toString()); 13335 } else { 13336 pw.println("{null}"); 13337 } 13338 } 13339 if (inclDetails) { 13340 pw.print(prefix); 13341 pw.print(" "); 13342 pw.print("oom: max="); pw.print(r.maxAdj); 13343 pw.print(" curRaw="); pw.print(r.curRawAdj); 13344 pw.print(" setRaw="); pw.print(r.setRawAdj); 13345 pw.print(" cur="); pw.print(r.curAdj); 13346 pw.print(" set="); pw.println(r.setAdj); 13347 pw.print(prefix); 13348 pw.print(" "); 13349 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13350 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13351 pw.print(" lastPss="); pw.print(r.lastPss); 13352 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13353 pw.print(prefix); 13354 pw.print(" "); 13355 pw.print("cached="); pw.print(r.cached); 13356 pw.print(" empty="); pw.print(r.empty); 13357 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13358 13359 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13360 if (r.lastWakeTime != 0) { 13361 long wtime; 13362 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13363 synchronized (stats) { 13364 wtime = stats.getProcessWakeTime(r.info.uid, 13365 r.pid, curRealtime); 13366 } 13367 long timeUsed = wtime - r.lastWakeTime; 13368 pw.print(prefix); 13369 pw.print(" "); 13370 pw.print("keep awake over "); 13371 TimeUtils.formatDuration(realtimeSince, pw); 13372 pw.print(" used "); 13373 TimeUtils.formatDuration(timeUsed, pw); 13374 pw.print(" ("); 13375 pw.print((timeUsed*100)/realtimeSince); 13376 pw.println("%)"); 13377 } 13378 if (r.lastCpuTime != 0) { 13379 long timeUsed = r.curCpuTime - r.lastCpuTime; 13380 pw.print(prefix); 13381 pw.print(" "); 13382 pw.print("run cpu over "); 13383 TimeUtils.formatDuration(uptimeSince, pw); 13384 pw.print(" used "); 13385 TimeUtils.formatDuration(timeUsed, pw); 13386 pw.print(" ("); 13387 pw.print((timeUsed*100)/uptimeSince); 13388 pw.println("%)"); 13389 } 13390 } 13391 } 13392 } 13393 return true; 13394 } 13395 13396 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13397 ArrayList<ProcessRecord> procs; 13398 synchronized (this) { 13399 if (args != null && args.length > start 13400 && args[start].charAt(0) != '-') { 13401 procs = new ArrayList<ProcessRecord>(); 13402 int pid = -1; 13403 try { 13404 pid = Integer.parseInt(args[start]); 13405 } catch (NumberFormatException e) { 13406 } 13407 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13408 ProcessRecord proc = mLruProcesses.get(i); 13409 if (proc.pid == pid) { 13410 procs.add(proc); 13411 } else if (proc.processName.equals(args[start])) { 13412 procs.add(proc); 13413 } 13414 } 13415 if (procs.size() <= 0) { 13416 return null; 13417 } 13418 } else { 13419 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13420 } 13421 } 13422 return procs; 13423 } 13424 13425 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13426 PrintWriter pw, String[] args) { 13427 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13428 if (procs == null) { 13429 pw.println("No process found for: " + args[0]); 13430 return; 13431 } 13432 13433 long uptime = SystemClock.uptimeMillis(); 13434 long realtime = SystemClock.elapsedRealtime(); 13435 pw.println("Applications Graphics Acceleration Info:"); 13436 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13437 13438 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13439 ProcessRecord r = procs.get(i); 13440 if (r.thread != null) { 13441 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13442 pw.flush(); 13443 try { 13444 TransferPipe tp = new TransferPipe(); 13445 try { 13446 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13447 tp.go(fd); 13448 } finally { 13449 tp.kill(); 13450 } 13451 } catch (IOException e) { 13452 pw.println("Failure while dumping the app: " + r); 13453 pw.flush(); 13454 } catch (RemoteException e) { 13455 pw.println("Got a RemoteException while dumping the app " + r); 13456 pw.flush(); 13457 } 13458 } 13459 } 13460 } 13461 13462 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13463 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13464 if (procs == null) { 13465 pw.println("No process found for: " + args[0]); 13466 return; 13467 } 13468 13469 pw.println("Applications Database Info:"); 13470 13471 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13472 ProcessRecord r = procs.get(i); 13473 if (r.thread != null) { 13474 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13475 pw.flush(); 13476 try { 13477 TransferPipe tp = new TransferPipe(); 13478 try { 13479 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13480 tp.go(fd); 13481 } finally { 13482 tp.kill(); 13483 } 13484 } catch (IOException e) { 13485 pw.println("Failure while dumping the app: " + r); 13486 pw.flush(); 13487 } catch (RemoteException e) { 13488 pw.println("Got a RemoteException while dumping the app " + r); 13489 pw.flush(); 13490 } 13491 } 13492 } 13493 } 13494 13495 final static class MemItem { 13496 final boolean isProc; 13497 final String label; 13498 final String shortLabel; 13499 final long pss; 13500 final int id; 13501 final boolean hasActivities; 13502 ArrayList<MemItem> subitems; 13503 13504 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13505 boolean _hasActivities) { 13506 isProc = true; 13507 label = _label; 13508 shortLabel = _shortLabel; 13509 pss = _pss; 13510 id = _id; 13511 hasActivities = _hasActivities; 13512 } 13513 13514 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13515 isProc = false; 13516 label = _label; 13517 shortLabel = _shortLabel; 13518 pss = _pss; 13519 id = _id; 13520 hasActivities = false; 13521 } 13522 } 13523 13524 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13525 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13526 if (sort && !isCompact) { 13527 Collections.sort(items, new Comparator<MemItem>() { 13528 @Override 13529 public int compare(MemItem lhs, MemItem rhs) { 13530 if (lhs.pss < rhs.pss) { 13531 return 1; 13532 } else if (lhs.pss > rhs.pss) { 13533 return -1; 13534 } 13535 return 0; 13536 } 13537 }); 13538 } 13539 13540 for (int i=0; i<items.size(); i++) { 13541 MemItem mi = items.get(i); 13542 if (!isCompact) { 13543 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13544 } else if (mi.isProc) { 13545 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13546 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13547 pw.println(mi.hasActivities ? ",a" : ",e"); 13548 } else { 13549 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13550 pw.println(mi.pss); 13551 } 13552 if (mi.subitems != null) { 13553 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13554 true, isCompact); 13555 } 13556 } 13557 } 13558 13559 // These are in KB. 13560 static final long[] DUMP_MEM_BUCKETS = new long[] { 13561 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13562 120*1024, 160*1024, 200*1024, 13563 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13564 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13565 }; 13566 13567 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13568 boolean stackLike) { 13569 int start = label.lastIndexOf('.'); 13570 if (start >= 0) start++; 13571 else start = 0; 13572 int end = label.length(); 13573 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13574 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13575 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13576 out.append(bucket); 13577 out.append(stackLike ? "MB." : "MB "); 13578 out.append(label, start, end); 13579 return; 13580 } 13581 } 13582 out.append(memKB/1024); 13583 out.append(stackLike ? "MB." : "MB "); 13584 out.append(label, start, end); 13585 } 13586 13587 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13588 ProcessList.NATIVE_ADJ, 13589 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13590 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13591 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13592 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13593 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13594 }; 13595 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13596 "Native", 13597 "System", "Persistent", "Foreground", 13598 "Visible", "Perceptible", 13599 "Heavy Weight", "Backup", 13600 "A Services", "Home", 13601 "Previous", "B Services", "Cached" 13602 }; 13603 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13604 "native", 13605 "sys", "pers", "fore", 13606 "vis", "percept", 13607 "heavy", "backup", 13608 "servicea", "home", 13609 "prev", "serviceb", "cached" 13610 }; 13611 13612 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13613 long realtime, boolean isCheckinRequest, boolean isCompact) { 13614 if (isCheckinRequest || isCompact) { 13615 // short checkin version 13616 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13617 } else { 13618 pw.println("Applications Memory Usage (kB):"); 13619 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13620 } 13621 } 13622 13623 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13624 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13625 boolean dumpDetails = false; 13626 boolean dumpFullDetails = false; 13627 boolean dumpDalvik = false; 13628 boolean oomOnly = false; 13629 boolean isCompact = false; 13630 boolean localOnly = false; 13631 13632 int opti = 0; 13633 while (opti < args.length) { 13634 String opt = args[opti]; 13635 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13636 break; 13637 } 13638 opti++; 13639 if ("-a".equals(opt)) { 13640 dumpDetails = true; 13641 dumpFullDetails = true; 13642 dumpDalvik = true; 13643 } else if ("-d".equals(opt)) { 13644 dumpDalvik = true; 13645 } else if ("-c".equals(opt)) { 13646 isCompact = true; 13647 } else if ("--oom".equals(opt)) { 13648 oomOnly = true; 13649 } else if ("--local".equals(opt)) { 13650 localOnly = true; 13651 } else if ("-h".equals(opt)) { 13652 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13653 pw.println(" -a: include all available information for each process."); 13654 pw.println(" -d: include dalvik details when dumping process details."); 13655 pw.println(" -c: dump in a compact machine-parseable representation."); 13656 pw.println(" --oom: only show processes organized by oom adj."); 13657 pw.println(" --local: only collect details locally, don't call process."); 13658 pw.println("If [process] is specified it can be the name or "); 13659 pw.println("pid of a specific process to dump."); 13660 return; 13661 } else { 13662 pw.println("Unknown argument: " + opt + "; use -h for help"); 13663 } 13664 } 13665 13666 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13667 long uptime = SystemClock.uptimeMillis(); 13668 long realtime = SystemClock.elapsedRealtime(); 13669 final long[] tmpLong = new long[1]; 13670 13671 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13672 if (procs == null) { 13673 // No Java processes. Maybe they want to print a native process. 13674 if (args != null && args.length > opti 13675 && args[opti].charAt(0) != '-') { 13676 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13677 = new ArrayList<ProcessCpuTracker.Stats>(); 13678 updateCpuStatsNow(); 13679 int findPid = -1; 13680 try { 13681 findPid = Integer.parseInt(args[opti]); 13682 } catch (NumberFormatException e) { 13683 } 13684 synchronized (mProcessCpuThread) { 13685 final int N = mProcessCpuTracker.countStats(); 13686 for (int i=0; i<N; i++) { 13687 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13688 if (st.pid == findPid || (st.baseName != null 13689 && st.baseName.equals(args[opti]))) { 13690 nativeProcs.add(st); 13691 } 13692 } 13693 } 13694 if (nativeProcs.size() > 0) { 13695 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13696 isCompact); 13697 Debug.MemoryInfo mi = null; 13698 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13699 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13700 final int pid = r.pid; 13701 if (!isCheckinRequest && dumpDetails) { 13702 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13703 } 13704 if (mi == null) { 13705 mi = new Debug.MemoryInfo(); 13706 } 13707 if (dumpDetails || (!brief && !oomOnly)) { 13708 Debug.getMemoryInfo(pid, mi); 13709 } else { 13710 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13711 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13712 } 13713 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13714 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13715 if (isCheckinRequest) { 13716 pw.println(); 13717 } 13718 } 13719 return; 13720 } 13721 } 13722 pw.println("No process found for: " + args[opti]); 13723 return; 13724 } 13725 13726 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13727 dumpDetails = true; 13728 } 13729 13730 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13731 13732 String[] innerArgs = new String[args.length-opti]; 13733 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13734 13735 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13736 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13737 long nativePss=0, dalvikPss=0, otherPss=0; 13738 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13739 13740 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13741 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13742 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13743 13744 long totalPss = 0; 13745 long cachedPss = 0; 13746 13747 Debug.MemoryInfo mi = null; 13748 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13749 final ProcessRecord r = procs.get(i); 13750 final IApplicationThread thread; 13751 final int pid; 13752 final int oomAdj; 13753 final boolean hasActivities; 13754 synchronized (this) { 13755 thread = r.thread; 13756 pid = r.pid; 13757 oomAdj = r.getSetAdjWithServices(); 13758 hasActivities = r.activities.size() > 0; 13759 } 13760 if (thread != null) { 13761 if (!isCheckinRequest && dumpDetails) { 13762 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13763 } 13764 if (mi == null) { 13765 mi = new Debug.MemoryInfo(); 13766 } 13767 if (dumpDetails || (!brief && !oomOnly)) { 13768 Debug.getMemoryInfo(pid, mi); 13769 } else { 13770 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13771 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13772 } 13773 if (dumpDetails) { 13774 if (localOnly) { 13775 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13776 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13777 if (isCheckinRequest) { 13778 pw.println(); 13779 } 13780 } else { 13781 try { 13782 pw.flush(); 13783 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13784 dumpDalvik, innerArgs); 13785 } catch (RemoteException e) { 13786 if (!isCheckinRequest) { 13787 pw.println("Got RemoteException!"); 13788 pw.flush(); 13789 } 13790 } 13791 } 13792 } 13793 13794 final long myTotalPss = mi.getTotalPss(); 13795 final long myTotalUss = mi.getTotalUss(); 13796 13797 synchronized (this) { 13798 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13799 // Record this for posterity if the process has been stable. 13800 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13801 } 13802 } 13803 13804 if (!isCheckinRequest && mi != null) { 13805 totalPss += myTotalPss; 13806 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13807 (hasActivities ? " / activities)" : ")"), 13808 r.processName, myTotalPss, pid, hasActivities); 13809 procMems.add(pssItem); 13810 procMemsMap.put(pid, pssItem); 13811 13812 nativePss += mi.nativePss; 13813 dalvikPss += mi.dalvikPss; 13814 otherPss += mi.otherPss; 13815 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13816 long mem = mi.getOtherPss(j); 13817 miscPss[j] += mem; 13818 otherPss -= mem; 13819 } 13820 13821 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13822 cachedPss += myTotalPss; 13823 } 13824 13825 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13826 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13827 || oomIndex == (oomPss.length-1)) { 13828 oomPss[oomIndex] += myTotalPss; 13829 if (oomProcs[oomIndex] == null) { 13830 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13831 } 13832 oomProcs[oomIndex].add(pssItem); 13833 break; 13834 } 13835 } 13836 } 13837 } 13838 } 13839 13840 long nativeProcTotalPss = 0; 13841 13842 if (!isCheckinRequest && procs.size() > 1) { 13843 // If we are showing aggregations, also look for native processes to 13844 // include so that our aggregations are more accurate. 13845 updateCpuStatsNow(); 13846 synchronized (mProcessCpuThread) { 13847 final int N = mProcessCpuTracker.countStats(); 13848 for (int i=0; i<N; i++) { 13849 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13850 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13851 if (mi == null) { 13852 mi = new Debug.MemoryInfo(); 13853 } 13854 if (!brief && !oomOnly) { 13855 Debug.getMemoryInfo(st.pid, mi); 13856 } else { 13857 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13858 mi.nativePrivateDirty = (int)tmpLong[0]; 13859 } 13860 13861 final long myTotalPss = mi.getTotalPss(); 13862 totalPss += myTotalPss; 13863 nativeProcTotalPss += myTotalPss; 13864 13865 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13866 st.name, myTotalPss, st.pid, false); 13867 procMems.add(pssItem); 13868 13869 nativePss += mi.nativePss; 13870 dalvikPss += mi.dalvikPss; 13871 otherPss += mi.otherPss; 13872 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13873 long mem = mi.getOtherPss(j); 13874 miscPss[j] += mem; 13875 otherPss -= mem; 13876 } 13877 oomPss[0] += myTotalPss; 13878 if (oomProcs[0] == null) { 13879 oomProcs[0] = new ArrayList<MemItem>(); 13880 } 13881 oomProcs[0].add(pssItem); 13882 } 13883 } 13884 } 13885 13886 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13887 13888 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13889 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13890 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13891 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13892 String label = Debug.MemoryInfo.getOtherLabel(j); 13893 catMems.add(new MemItem(label, label, miscPss[j], j)); 13894 } 13895 13896 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13897 for (int j=0; j<oomPss.length; j++) { 13898 if (oomPss[j] != 0) { 13899 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13900 : DUMP_MEM_OOM_LABEL[j]; 13901 MemItem item = new MemItem(label, label, oomPss[j], 13902 DUMP_MEM_OOM_ADJ[j]); 13903 item.subitems = oomProcs[j]; 13904 oomMems.add(item); 13905 } 13906 } 13907 13908 if (!brief && !oomOnly && !isCompact) { 13909 pw.println(); 13910 pw.println("Total PSS by process:"); 13911 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13912 pw.println(); 13913 } 13914 if (!isCompact) { 13915 pw.println("Total PSS by OOM adjustment:"); 13916 } 13917 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13918 if (!brief && !oomOnly) { 13919 PrintWriter out = categoryPw != null ? categoryPw : pw; 13920 if (!isCompact) { 13921 out.println(); 13922 out.println("Total PSS by category:"); 13923 } 13924 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13925 } 13926 if (!isCompact) { 13927 pw.println(); 13928 } 13929 MemInfoReader memInfo = new MemInfoReader(); 13930 memInfo.readMemInfo(); 13931 if (nativeProcTotalPss > 0) { 13932 synchronized (this) { 13933 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13934 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13935 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13936 nativeProcTotalPss); 13937 } 13938 } 13939 if (!brief) { 13940 if (!isCompact) { 13941 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13942 pw.print(" kB (status "); 13943 switch (mLastMemoryLevel) { 13944 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13945 pw.println("normal)"); 13946 break; 13947 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13948 pw.println("moderate)"); 13949 break; 13950 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13951 pw.println("low)"); 13952 break; 13953 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13954 pw.println("critical)"); 13955 break; 13956 default: 13957 pw.print(mLastMemoryLevel); 13958 pw.println(")"); 13959 break; 13960 } 13961 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13962 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13963 pw.print(cachedPss); pw.print(" cached pss + "); 13964 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13965 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13966 } else { 13967 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13968 pw.print(cachedPss + memInfo.getCachedSizeKb() 13969 + memInfo.getFreeSizeKb()); pw.print(","); 13970 pw.println(totalPss - cachedPss); 13971 } 13972 } 13973 if (!isCompact) { 13974 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13975 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13976 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13977 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13978 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13979 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13980 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13981 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13982 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13983 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13984 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13985 } 13986 if (!brief) { 13987 if (memInfo.getZramTotalSizeKb() != 0) { 13988 if (!isCompact) { 13989 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13990 pw.print(" kB physical used for "); 13991 pw.print(memInfo.getSwapTotalSizeKb() 13992 - memInfo.getSwapFreeSizeKb()); 13993 pw.print(" kB in swap ("); 13994 pw.print(memInfo.getSwapTotalSizeKb()); 13995 pw.println(" kB total swap)"); 13996 } else { 13997 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13998 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13999 pw.println(memInfo.getSwapFreeSizeKb()); 14000 } 14001 } 14002 final int[] SINGLE_LONG_FORMAT = new int[] { 14003 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14004 }; 14005 long[] longOut = new long[1]; 14006 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14007 SINGLE_LONG_FORMAT, null, longOut, null); 14008 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14009 longOut[0] = 0; 14010 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14011 SINGLE_LONG_FORMAT, null, longOut, null); 14012 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14013 longOut[0] = 0; 14014 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14015 SINGLE_LONG_FORMAT, null, longOut, null); 14016 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14017 longOut[0] = 0; 14018 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14019 SINGLE_LONG_FORMAT, null, longOut, null); 14020 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14021 if (!isCompact) { 14022 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14023 pw.print(" KSM: "); pw.print(sharing); 14024 pw.print(" kB saved from shared "); 14025 pw.print(shared); pw.println(" kB"); 14026 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14027 pw.print(voltile); pw.println(" kB volatile"); 14028 } 14029 pw.print(" Tuning: "); 14030 pw.print(ActivityManager.staticGetMemoryClass()); 14031 pw.print(" (large "); 14032 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14033 pw.print("), oom "); 14034 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14035 pw.print(" kB"); 14036 pw.print(", restore limit "); 14037 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14038 pw.print(" kB"); 14039 if (ActivityManager.isLowRamDeviceStatic()) { 14040 pw.print(" (low-ram)"); 14041 } 14042 if (ActivityManager.isHighEndGfx()) { 14043 pw.print(" (high-end-gfx)"); 14044 } 14045 pw.println(); 14046 } else { 14047 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14048 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14049 pw.println(voltile); 14050 pw.print("tuning,"); 14051 pw.print(ActivityManager.staticGetMemoryClass()); 14052 pw.print(','); 14053 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14054 pw.print(','); 14055 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14056 if (ActivityManager.isLowRamDeviceStatic()) { 14057 pw.print(",low-ram"); 14058 } 14059 if (ActivityManager.isHighEndGfx()) { 14060 pw.print(",high-end-gfx"); 14061 } 14062 pw.println(); 14063 } 14064 } 14065 } 14066 } 14067 14068 /** 14069 * Searches array of arguments for the specified string 14070 * @param args array of argument strings 14071 * @param value value to search for 14072 * @return true if the value is contained in the array 14073 */ 14074 private static boolean scanArgs(String[] args, String value) { 14075 if (args != null) { 14076 for (String arg : args) { 14077 if (value.equals(arg)) { 14078 return true; 14079 } 14080 } 14081 } 14082 return false; 14083 } 14084 14085 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14086 ContentProviderRecord cpr, boolean always) { 14087 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14088 14089 if (!inLaunching || always) { 14090 synchronized (cpr) { 14091 cpr.launchingApp = null; 14092 cpr.notifyAll(); 14093 } 14094 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14095 String names[] = cpr.info.authority.split(";"); 14096 for (int j = 0; j < names.length; j++) { 14097 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14098 } 14099 } 14100 14101 for (int i=0; i<cpr.connections.size(); i++) { 14102 ContentProviderConnection conn = cpr.connections.get(i); 14103 if (conn.waiting) { 14104 // If this connection is waiting for the provider, then we don't 14105 // need to mess with its process unless we are always removing 14106 // or for some reason the provider is not currently launching. 14107 if (inLaunching && !always) { 14108 continue; 14109 } 14110 } 14111 ProcessRecord capp = conn.client; 14112 conn.dead = true; 14113 if (conn.stableCount > 0) { 14114 if (!capp.persistent && capp.thread != null 14115 && capp.pid != 0 14116 && capp.pid != MY_PID) { 14117 capp.kill("depends on provider " 14118 + cpr.name.flattenToShortString() 14119 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14120 } 14121 } else if (capp.thread != null && conn.provider.provider != null) { 14122 try { 14123 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14124 } catch (RemoteException e) { 14125 } 14126 // In the protocol here, we don't expect the client to correctly 14127 // clean up this connection, we'll just remove it. 14128 cpr.connections.remove(i); 14129 conn.client.conProviders.remove(conn); 14130 } 14131 } 14132 14133 if (inLaunching && always) { 14134 mLaunchingProviders.remove(cpr); 14135 } 14136 return inLaunching; 14137 } 14138 14139 /** 14140 * Main code for cleaning up a process when it has gone away. This is 14141 * called both as a result of the process dying, or directly when stopping 14142 * a process when running in single process mode. 14143 */ 14144 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14145 boolean restarting, boolean allowRestart, int index) { 14146 if (index >= 0) { 14147 removeLruProcessLocked(app); 14148 ProcessList.remove(app.pid); 14149 } 14150 14151 mProcessesToGc.remove(app); 14152 mPendingPssProcesses.remove(app); 14153 14154 // Dismiss any open dialogs. 14155 if (app.crashDialog != null && !app.forceCrashReport) { 14156 app.crashDialog.dismiss(); 14157 app.crashDialog = null; 14158 } 14159 if (app.anrDialog != null) { 14160 app.anrDialog.dismiss(); 14161 app.anrDialog = null; 14162 } 14163 if (app.waitDialog != null) { 14164 app.waitDialog.dismiss(); 14165 app.waitDialog = null; 14166 } 14167 14168 app.crashing = false; 14169 app.notResponding = false; 14170 14171 app.resetPackageList(mProcessStats); 14172 app.unlinkDeathRecipient(); 14173 app.makeInactive(mProcessStats); 14174 app.waitingToKill = null; 14175 app.forcingToForeground = null; 14176 updateProcessForegroundLocked(app, false, false); 14177 app.foregroundActivities = false; 14178 app.hasShownUi = false; 14179 app.treatLikeActivity = false; 14180 app.hasAboveClient = false; 14181 app.hasClientActivities = false; 14182 14183 mServices.killServicesLocked(app, allowRestart); 14184 14185 boolean restart = false; 14186 14187 // Remove published content providers. 14188 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14189 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14190 final boolean always = app.bad || !allowRestart; 14191 if (removeDyingProviderLocked(app, cpr, always) || always) { 14192 // We left the provider in the launching list, need to 14193 // restart it. 14194 restart = true; 14195 } 14196 14197 cpr.provider = null; 14198 cpr.proc = null; 14199 } 14200 app.pubProviders.clear(); 14201 14202 // Take care of any launching providers waiting for this process. 14203 if (checkAppInLaunchingProvidersLocked(app, false)) { 14204 restart = true; 14205 } 14206 14207 // Unregister from connected content providers. 14208 if (!app.conProviders.isEmpty()) { 14209 for (int i=0; i<app.conProviders.size(); i++) { 14210 ContentProviderConnection conn = app.conProviders.get(i); 14211 conn.provider.connections.remove(conn); 14212 } 14213 app.conProviders.clear(); 14214 } 14215 14216 // At this point there may be remaining entries in mLaunchingProviders 14217 // where we were the only one waiting, so they are no longer of use. 14218 // Look for these and clean up if found. 14219 // XXX Commented out for now. Trying to figure out a way to reproduce 14220 // the actual situation to identify what is actually going on. 14221 if (false) { 14222 for (int i=0; i<mLaunchingProviders.size(); i++) { 14223 ContentProviderRecord cpr = (ContentProviderRecord) 14224 mLaunchingProviders.get(i); 14225 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14226 synchronized (cpr) { 14227 cpr.launchingApp = null; 14228 cpr.notifyAll(); 14229 } 14230 } 14231 } 14232 } 14233 14234 skipCurrentReceiverLocked(app); 14235 14236 // Unregister any receivers. 14237 for (int i=app.receivers.size()-1; i>=0; i--) { 14238 removeReceiverLocked(app.receivers.valueAt(i)); 14239 } 14240 app.receivers.clear(); 14241 14242 // If the app is undergoing backup, tell the backup manager about it 14243 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14244 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14245 + mBackupTarget.appInfo + " died during backup"); 14246 try { 14247 IBackupManager bm = IBackupManager.Stub.asInterface( 14248 ServiceManager.getService(Context.BACKUP_SERVICE)); 14249 bm.agentDisconnected(app.info.packageName); 14250 } catch (RemoteException e) { 14251 // can't happen; backup manager is local 14252 } 14253 } 14254 14255 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14256 ProcessChangeItem item = mPendingProcessChanges.get(i); 14257 if (item.pid == app.pid) { 14258 mPendingProcessChanges.remove(i); 14259 mAvailProcessChanges.add(item); 14260 } 14261 } 14262 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14263 14264 // If the caller is restarting this app, then leave it in its 14265 // current lists and let the caller take care of it. 14266 if (restarting) { 14267 return; 14268 } 14269 14270 if (!app.persistent || app.isolated) { 14271 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14272 "Removing non-persistent process during cleanup: " + app); 14273 mProcessNames.remove(app.processName, app.uid); 14274 mIsolatedProcesses.remove(app.uid); 14275 if (mHeavyWeightProcess == app) { 14276 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14277 mHeavyWeightProcess.userId, 0)); 14278 mHeavyWeightProcess = null; 14279 } 14280 } else if (!app.removed) { 14281 // This app is persistent, so we need to keep its record around. 14282 // If it is not already on the pending app list, add it there 14283 // and start a new process for it. 14284 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14285 mPersistentStartingProcesses.add(app); 14286 restart = true; 14287 } 14288 } 14289 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14290 "Clean-up removing on hold: " + app); 14291 mProcessesOnHold.remove(app); 14292 14293 if (app == mHomeProcess) { 14294 mHomeProcess = null; 14295 } 14296 if (app == mPreviousProcess) { 14297 mPreviousProcess = null; 14298 } 14299 14300 if (restart && !app.isolated) { 14301 // We have components that still need to be running in the 14302 // process, so re-launch it. 14303 mProcessNames.put(app.processName, app.uid, app); 14304 startProcessLocked(app, "restart", app.processName); 14305 } else if (app.pid > 0 && app.pid != MY_PID) { 14306 // Goodbye! 14307 boolean removed; 14308 synchronized (mPidsSelfLocked) { 14309 mPidsSelfLocked.remove(app.pid); 14310 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14311 } 14312 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14313 if (app.isolated) { 14314 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14315 } 14316 app.setPid(0); 14317 } 14318 } 14319 14320 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14321 // Look through the content providers we are waiting to have launched, 14322 // and if any run in this process then either schedule a restart of 14323 // the process or kill the client waiting for it if this process has 14324 // gone bad. 14325 int NL = mLaunchingProviders.size(); 14326 boolean restart = false; 14327 for (int i=0; i<NL; i++) { 14328 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14329 if (cpr.launchingApp == app) { 14330 if (!alwaysBad && !app.bad) { 14331 restart = true; 14332 } else { 14333 removeDyingProviderLocked(app, cpr, true); 14334 // cpr should have been removed from mLaunchingProviders 14335 NL = mLaunchingProviders.size(); 14336 i--; 14337 } 14338 } 14339 } 14340 return restart; 14341 } 14342 14343 // ========================================================= 14344 // SERVICES 14345 // ========================================================= 14346 14347 @Override 14348 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14349 int flags) { 14350 enforceNotIsolatedCaller("getServices"); 14351 synchronized (this) { 14352 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14353 } 14354 } 14355 14356 @Override 14357 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14358 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14359 synchronized (this) { 14360 return mServices.getRunningServiceControlPanelLocked(name); 14361 } 14362 } 14363 14364 @Override 14365 public ComponentName startService(IApplicationThread caller, Intent service, 14366 String resolvedType, int userId) { 14367 enforceNotIsolatedCaller("startService"); 14368 // Refuse possible leaked file descriptors 14369 if (service != null && service.hasFileDescriptors() == true) { 14370 throw new IllegalArgumentException("File descriptors passed in Intent"); 14371 } 14372 14373 if (DEBUG_SERVICE) 14374 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14375 synchronized(this) { 14376 final int callingPid = Binder.getCallingPid(); 14377 final int callingUid = Binder.getCallingUid(); 14378 final long origId = Binder.clearCallingIdentity(); 14379 ComponentName res = mServices.startServiceLocked(caller, service, 14380 resolvedType, callingPid, callingUid, userId); 14381 Binder.restoreCallingIdentity(origId); 14382 return res; 14383 } 14384 } 14385 14386 ComponentName startServiceInPackage(int uid, 14387 Intent service, String resolvedType, int userId) { 14388 synchronized(this) { 14389 if (DEBUG_SERVICE) 14390 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14391 final long origId = Binder.clearCallingIdentity(); 14392 ComponentName res = mServices.startServiceLocked(null, service, 14393 resolvedType, -1, uid, userId); 14394 Binder.restoreCallingIdentity(origId); 14395 return res; 14396 } 14397 } 14398 14399 @Override 14400 public int stopService(IApplicationThread caller, Intent service, 14401 String resolvedType, int userId) { 14402 enforceNotIsolatedCaller("stopService"); 14403 // Refuse possible leaked file descriptors 14404 if (service != null && service.hasFileDescriptors() == true) { 14405 throw new IllegalArgumentException("File descriptors passed in Intent"); 14406 } 14407 14408 synchronized(this) { 14409 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14410 } 14411 } 14412 14413 @Override 14414 public IBinder peekService(Intent service, String resolvedType) { 14415 enforceNotIsolatedCaller("peekService"); 14416 // Refuse possible leaked file descriptors 14417 if (service != null && service.hasFileDescriptors() == true) { 14418 throw new IllegalArgumentException("File descriptors passed in Intent"); 14419 } 14420 synchronized(this) { 14421 return mServices.peekServiceLocked(service, resolvedType); 14422 } 14423 } 14424 14425 @Override 14426 public boolean stopServiceToken(ComponentName className, IBinder token, 14427 int startId) { 14428 synchronized(this) { 14429 return mServices.stopServiceTokenLocked(className, token, startId); 14430 } 14431 } 14432 14433 @Override 14434 public void setServiceForeground(ComponentName className, IBinder token, 14435 int id, Notification notification, boolean removeNotification) { 14436 synchronized(this) { 14437 mServices.setServiceForegroundLocked(className, token, id, notification, 14438 removeNotification); 14439 } 14440 } 14441 14442 @Override 14443 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14444 boolean requireFull, String name, String callerPackage) { 14445 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14446 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14447 } 14448 14449 int unsafeConvertIncomingUser(int userId) { 14450 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14451 ? mCurrentUserId : userId; 14452 } 14453 14454 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14455 int allowMode, String name, String callerPackage) { 14456 final int callingUserId = UserHandle.getUserId(callingUid); 14457 if (callingUserId == userId) { 14458 return userId; 14459 } 14460 14461 // Note that we may be accessing mCurrentUserId outside of a lock... 14462 // shouldn't be a big deal, if this is being called outside 14463 // of a locked context there is intrinsically a race with 14464 // the value the caller will receive and someone else changing it. 14465 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14466 // we will switch to the calling user if access to the current user fails. 14467 int targetUserId = unsafeConvertIncomingUser(userId); 14468 14469 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14470 final boolean allow; 14471 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14472 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14473 // If the caller has this permission, they always pass go. And collect $200. 14474 allow = true; 14475 } else if (allowMode == ALLOW_FULL_ONLY) { 14476 // We require full access, sucks to be you. 14477 allow = false; 14478 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14479 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14480 // If the caller does not have either permission, they are always doomed. 14481 allow = false; 14482 } else if (allowMode == ALLOW_NON_FULL) { 14483 // We are blanket allowing non-full access, you lucky caller! 14484 allow = true; 14485 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14486 // We may or may not allow this depending on whether the two users are 14487 // in the same profile. 14488 synchronized (mUserProfileGroupIdsSelfLocked) { 14489 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14490 UserInfo.NO_PROFILE_GROUP_ID); 14491 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14492 UserInfo.NO_PROFILE_GROUP_ID); 14493 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14494 && callingProfile == targetProfile; 14495 } 14496 } else { 14497 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14498 } 14499 if (!allow) { 14500 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14501 // In this case, they would like to just execute as their 14502 // owner user instead of failing. 14503 targetUserId = callingUserId; 14504 } else { 14505 StringBuilder builder = new StringBuilder(128); 14506 builder.append("Permission Denial: "); 14507 builder.append(name); 14508 if (callerPackage != null) { 14509 builder.append(" from "); 14510 builder.append(callerPackage); 14511 } 14512 builder.append(" asks to run as user "); 14513 builder.append(userId); 14514 builder.append(" but is calling from user "); 14515 builder.append(UserHandle.getUserId(callingUid)); 14516 builder.append("; this requires "); 14517 builder.append(INTERACT_ACROSS_USERS_FULL); 14518 if (allowMode != ALLOW_FULL_ONLY) { 14519 builder.append(" or "); 14520 builder.append(INTERACT_ACROSS_USERS); 14521 } 14522 String msg = builder.toString(); 14523 Slog.w(TAG, msg); 14524 throw new SecurityException(msg); 14525 } 14526 } 14527 } 14528 if (!allowAll && targetUserId < 0) { 14529 throw new IllegalArgumentException( 14530 "Call does not support special user #" + targetUserId); 14531 } 14532 return targetUserId; 14533 } 14534 14535 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14536 String className, int flags) { 14537 boolean result = false; 14538 // For apps that don't have pre-defined UIDs, check for permission 14539 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14540 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14541 if (ActivityManager.checkUidPermission( 14542 INTERACT_ACROSS_USERS, 14543 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14544 ComponentName comp = new ComponentName(aInfo.packageName, className); 14545 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14546 + " requests FLAG_SINGLE_USER, but app does not hold " 14547 + INTERACT_ACROSS_USERS; 14548 Slog.w(TAG, msg); 14549 throw new SecurityException(msg); 14550 } 14551 // Permission passed 14552 result = true; 14553 } 14554 } else if ("system".equals(componentProcessName)) { 14555 result = true; 14556 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14557 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14558 // Phone app is allowed to export singleuser providers. 14559 result = true; 14560 } else { 14561 // App with pre-defined UID, check if it's a persistent app 14562 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14563 } 14564 if (DEBUG_MU) { 14565 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14566 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14567 } 14568 return result; 14569 } 14570 14571 /** 14572 * Checks to see if the caller is in the same app as the singleton 14573 * component, or the component is in a special app. It allows special apps 14574 * to export singleton components but prevents exporting singleton 14575 * components for regular apps. 14576 */ 14577 boolean isValidSingletonCall(int callingUid, int componentUid) { 14578 int componentAppId = UserHandle.getAppId(componentUid); 14579 return UserHandle.isSameApp(callingUid, componentUid) 14580 || componentAppId == Process.SYSTEM_UID 14581 || componentAppId == Process.PHONE_UID 14582 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14583 == PackageManager.PERMISSION_GRANTED; 14584 } 14585 14586 public int bindService(IApplicationThread caller, IBinder token, 14587 Intent service, String resolvedType, 14588 IServiceConnection connection, int flags, int userId) { 14589 enforceNotIsolatedCaller("bindService"); 14590 // Refuse possible leaked file descriptors 14591 if (service != null && service.hasFileDescriptors() == true) { 14592 throw new IllegalArgumentException("File descriptors passed in Intent"); 14593 } 14594 14595 synchronized(this) { 14596 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14597 connection, flags, userId); 14598 } 14599 } 14600 14601 public boolean unbindService(IServiceConnection connection) { 14602 synchronized (this) { 14603 return mServices.unbindServiceLocked(connection); 14604 } 14605 } 14606 14607 public void publishService(IBinder token, Intent intent, IBinder service) { 14608 // Refuse possible leaked file descriptors 14609 if (intent != null && intent.hasFileDescriptors() == true) { 14610 throw new IllegalArgumentException("File descriptors passed in Intent"); 14611 } 14612 14613 synchronized(this) { 14614 if (!(token instanceof ServiceRecord)) { 14615 throw new IllegalArgumentException("Invalid service token"); 14616 } 14617 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14618 } 14619 } 14620 14621 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14622 // Refuse possible leaked file descriptors 14623 if (intent != null && intent.hasFileDescriptors() == true) { 14624 throw new IllegalArgumentException("File descriptors passed in Intent"); 14625 } 14626 14627 synchronized(this) { 14628 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14629 } 14630 } 14631 14632 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14633 synchronized(this) { 14634 if (!(token instanceof ServiceRecord)) { 14635 throw new IllegalArgumentException("Invalid service token"); 14636 } 14637 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14638 } 14639 } 14640 14641 // ========================================================= 14642 // BACKUP AND RESTORE 14643 // ========================================================= 14644 14645 // Cause the target app to be launched if necessary and its backup agent 14646 // instantiated. The backup agent will invoke backupAgentCreated() on the 14647 // activity manager to announce its creation. 14648 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14649 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14650 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14651 14652 synchronized(this) { 14653 // !!! TODO: currently no check here that we're already bound 14654 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14655 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14656 synchronized (stats) { 14657 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14658 } 14659 14660 // Backup agent is now in use, its package can't be stopped. 14661 try { 14662 AppGlobals.getPackageManager().setPackageStoppedState( 14663 app.packageName, false, UserHandle.getUserId(app.uid)); 14664 } catch (RemoteException e) { 14665 } catch (IllegalArgumentException e) { 14666 Slog.w(TAG, "Failed trying to unstop package " 14667 + app.packageName + ": " + e); 14668 } 14669 14670 BackupRecord r = new BackupRecord(ss, app, backupMode); 14671 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14672 ? new ComponentName(app.packageName, app.backupAgentName) 14673 : new ComponentName("android", "FullBackupAgent"); 14674 // startProcessLocked() returns existing proc's record if it's already running 14675 ProcessRecord proc = startProcessLocked(app.processName, app, 14676 false, 0, "backup", hostingName, false, false, false); 14677 if (proc == null) { 14678 Slog.e(TAG, "Unable to start backup agent process " + r); 14679 return false; 14680 } 14681 14682 r.app = proc; 14683 mBackupTarget = r; 14684 mBackupAppName = app.packageName; 14685 14686 // Try not to kill the process during backup 14687 updateOomAdjLocked(proc); 14688 14689 // If the process is already attached, schedule the creation of the backup agent now. 14690 // If it is not yet live, this will be done when it attaches to the framework. 14691 if (proc.thread != null) { 14692 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14693 try { 14694 proc.thread.scheduleCreateBackupAgent(app, 14695 compatibilityInfoForPackageLocked(app), backupMode); 14696 } catch (RemoteException e) { 14697 // Will time out on the backup manager side 14698 } 14699 } else { 14700 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14701 } 14702 // Invariants: at this point, the target app process exists and the application 14703 // is either already running or in the process of coming up. mBackupTarget and 14704 // mBackupAppName describe the app, so that when it binds back to the AM we 14705 // know that it's scheduled for a backup-agent operation. 14706 } 14707 14708 return true; 14709 } 14710 14711 @Override 14712 public void clearPendingBackup() { 14713 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14714 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14715 14716 synchronized (this) { 14717 mBackupTarget = null; 14718 mBackupAppName = null; 14719 } 14720 } 14721 14722 // A backup agent has just come up 14723 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14724 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14725 + " = " + agent); 14726 14727 synchronized(this) { 14728 if (!agentPackageName.equals(mBackupAppName)) { 14729 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14730 return; 14731 } 14732 } 14733 14734 long oldIdent = Binder.clearCallingIdentity(); 14735 try { 14736 IBackupManager bm = IBackupManager.Stub.asInterface( 14737 ServiceManager.getService(Context.BACKUP_SERVICE)); 14738 bm.agentConnected(agentPackageName, agent); 14739 } catch (RemoteException e) { 14740 // can't happen; the backup manager service is local 14741 } catch (Exception e) { 14742 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14743 e.printStackTrace(); 14744 } finally { 14745 Binder.restoreCallingIdentity(oldIdent); 14746 } 14747 } 14748 14749 // done with this agent 14750 public void unbindBackupAgent(ApplicationInfo appInfo) { 14751 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14752 if (appInfo == null) { 14753 Slog.w(TAG, "unbind backup agent for null app"); 14754 return; 14755 } 14756 14757 synchronized(this) { 14758 try { 14759 if (mBackupAppName == null) { 14760 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14761 return; 14762 } 14763 14764 if (!mBackupAppName.equals(appInfo.packageName)) { 14765 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14766 return; 14767 } 14768 14769 // Not backing this app up any more; reset its OOM adjustment 14770 final ProcessRecord proc = mBackupTarget.app; 14771 updateOomAdjLocked(proc); 14772 14773 // If the app crashed during backup, 'thread' will be null here 14774 if (proc.thread != null) { 14775 try { 14776 proc.thread.scheduleDestroyBackupAgent(appInfo, 14777 compatibilityInfoForPackageLocked(appInfo)); 14778 } catch (Exception e) { 14779 Slog.e(TAG, "Exception when unbinding backup agent:"); 14780 e.printStackTrace(); 14781 } 14782 } 14783 } finally { 14784 mBackupTarget = null; 14785 mBackupAppName = null; 14786 } 14787 } 14788 } 14789 // ========================================================= 14790 // BROADCASTS 14791 // ========================================================= 14792 14793 private final List getStickiesLocked(String action, IntentFilter filter, 14794 List cur, int userId) { 14795 final ContentResolver resolver = mContext.getContentResolver(); 14796 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14797 if (stickies == null) { 14798 return cur; 14799 } 14800 final ArrayList<Intent> list = stickies.get(action); 14801 if (list == null) { 14802 return cur; 14803 } 14804 int N = list.size(); 14805 for (int i=0; i<N; i++) { 14806 Intent intent = list.get(i); 14807 if (filter.match(resolver, intent, true, TAG) >= 0) { 14808 if (cur == null) { 14809 cur = new ArrayList<Intent>(); 14810 } 14811 cur.add(intent); 14812 } 14813 } 14814 return cur; 14815 } 14816 14817 boolean isPendingBroadcastProcessLocked(int pid) { 14818 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14819 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14820 } 14821 14822 void skipPendingBroadcastLocked(int pid) { 14823 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14824 for (BroadcastQueue queue : mBroadcastQueues) { 14825 queue.skipPendingBroadcastLocked(pid); 14826 } 14827 } 14828 14829 // The app just attached; send any pending broadcasts that it should receive 14830 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14831 boolean didSomething = false; 14832 for (BroadcastQueue queue : mBroadcastQueues) { 14833 didSomething |= queue.sendPendingBroadcastsLocked(app); 14834 } 14835 return didSomething; 14836 } 14837 14838 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14839 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14840 enforceNotIsolatedCaller("registerReceiver"); 14841 int callingUid; 14842 int callingPid; 14843 synchronized(this) { 14844 ProcessRecord callerApp = null; 14845 if (caller != null) { 14846 callerApp = getRecordForAppLocked(caller); 14847 if (callerApp == null) { 14848 throw new SecurityException( 14849 "Unable to find app for caller " + caller 14850 + " (pid=" + Binder.getCallingPid() 14851 + ") when registering receiver " + receiver); 14852 } 14853 if (callerApp.info.uid != Process.SYSTEM_UID && 14854 !callerApp.pkgList.containsKey(callerPackage) && 14855 !"android".equals(callerPackage)) { 14856 throw new SecurityException("Given caller package " + callerPackage 14857 + " is not running in process " + callerApp); 14858 } 14859 callingUid = callerApp.info.uid; 14860 callingPid = callerApp.pid; 14861 } else { 14862 callerPackage = null; 14863 callingUid = Binder.getCallingUid(); 14864 callingPid = Binder.getCallingPid(); 14865 } 14866 14867 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14868 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14869 14870 List allSticky = null; 14871 14872 // Look for any matching sticky broadcasts... 14873 Iterator actions = filter.actionsIterator(); 14874 if (actions != null) { 14875 while (actions.hasNext()) { 14876 String action = (String)actions.next(); 14877 allSticky = getStickiesLocked(action, filter, allSticky, 14878 UserHandle.USER_ALL); 14879 allSticky = getStickiesLocked(action, filter, allSticky, 14880 UserHandle.getUserId(callingUid)); 14881 } 14882 } else { 14883 allSticky = getStickiesLocked(null, filter, allSticky, 14884 UserHandle.USER_ALL); 14885 allSticky = getStickiesLocked(null, filter, allSticky, 14886 UserHandle.getUserId(callingUid)); 14887 } 14888 14889 // The first sticky in the list is returned directly back to 14890 // the client. 14891 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14892 14893 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14894 + ": " + sticky); 14895 14896 if (receiver == null) { 14897 return sticky; 14898 } 14899 14900 ReceiverList rl 14901 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14902 if (rl == null) { 14903 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14904 userId, receiver); 14905 if (rl.app != null) { 14906 rl.app.receivers.add(rl); 14907 } else { 14908 try { 14909 receiver.asBinder().linkToDeath(rl, 0); 14910 } catch (RemoteException e) { 14911 return sticky; 14912 } 14913 rl.linkedToDeath = true; 14914 } 14915 mRegisteredReceivers.put(receiver.asBinder(), rl); 14916 } else if (rl.uid != callingUid) { 14917 throw new IllegalArgumentException( 14918 "Receiver requested to register for uid " + callingUid 14919 + " was previously registered for uid " + rl.uid); 14920 } else if (rl.pid != callingPid) { 14921 throw new IllegalArgumentException( 14922 "Receiver requested to register for pid " + callingPid 14923 + " was previously registered for pid " + rl.pid); 14924 } else if (rl.userId != userId) { 14925 throw new IllegalArgumentException( 14926 "Receiver requested to register for user " + userId 14927 + " was previously registered for user " + rl.userId); 14928 } 14929 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14930 permission, callingUid, userId); 14931 rl.add(bf); 14932 if (!bf.debugCheck()) { 14933 Slog.w(TAG, "==> For Dynamic broadast"); 14934 } 14935 mReceiverResolver.addFilter(bf); 14936 14937 // Enqueue broadcasts for all existing stickies that match 14938 // this filter. 14939 if (allSticky != null) { 14940 ArrayList receivers = new ArrayList(); 14941 receivers.add(bf); 14942 14943 int N = allSticky.size(); 14944 for (int i=0; i<N; i++) { 14945 Intent intent = (Intent)allSticky.get(i); 14946 BroadcastQueue queue = broadcastQueueForIntent(intent); 14947 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14948 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14949 null, null, false, true, true, -1); 14950 queue.enqueueParallelBroadcastLocked(r); 14951 queue.scheduleBroadcastsLocked(); 14952 } 14953 } 14954 14955 return sticky; 14956 } 14957 } 14958 14959 public void unregisterReceiver(IIntentReceiver receiver) { 14960 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14961 14962 final long origId = Binder.clearCallingIdentity(); 14963 try { 14964 boolean doTrim = false; 14965 14966 synchronized(this) { 14967 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14968 if (rl != null) { 14969 if (rl.curBroadcast != null) { 14970 BroadcastRecord r = rl.curBroadcast; 14971 final boolean doNext = finishReceiverLocked( 14972 receiver.asBinder(), r.resultCode, r.resultData, 14973 r.resultExtras, r.resultAbort); 14974 if (doNext) { 14975 doTrim = true; 14976 r.queue.processNextBroadcast(false); 14977 } 14978 } 14979 14980 if (rl.app != null) { 14981 rl.app.receivers.remove(rl); 14982 } 14983 removeReceiverLocked(rl); 14984 if (rl.linkedToDeath) { 14985 rl.linkedToDeath = false; 14986 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14987 } 14988 } 14989 } 14990 14991 // If we actually concluded any broadcasts, we might now be able 14992 // to trim the recipients' apps from our working set 14993 if (doTrim) { 14994 trimApplications(); 14995 return; 14996 } 14997 14998 } finally { 14999 Binder.restoreCallingIdentity(origId); 15000 } 15001 } 15002 15003 void removeReceiverLocked(ReceiverList rl) { 15004 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15005 int N = rl.size(); 15006 for (int i=0; i<N; i++) { 15007 mReceiverResolver.removeFilter(rl.get(i)); 15008 } 15009 } 15010 15011 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15012 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15013 ProcessRecord r = mLruProcesses.get(i); 15014 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15015 try { 15016 r.thread.dispatchPackageBroadcast(cmd, packages); 15017 } catch (RemoteException ex) { 15018 } 15019 } 15020 } 15021 } 15022 15023 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15024 int[] users) { 15025 List<ResolveInfo> receivers = null; 15026 try { 15027 HashSet<ComponentName> singleUserReceivers = null; 15028 boolean scannedFirstReceivers = false; 15029 for (int user : users) { 15030 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15031 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15032 if (user != 0 && newReceivers != null) { 15033 // If this is not the primary user, we need to check for 15034 // any receivers that should be filtered out. 15035 for (int i=0; i<newReceivers.size(); i++) { 15036 ResolveInfo ri = newReceivers.get(i); 15037 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15038 newReceivers.remove(i); 15039 i--; 15040 } 15041 } 15042 } 15043 if (newReceivers != null && newReceivers.size() == 0) { 15044 newReceivers = null; 15045 } 15046 if (receivers == null) { 15047 receivers = newReceivers; 15048 } else if (newReceivers != null) { 15049 // We need to concatenate the additional receivers 15050 // found with what we have do far. This would be easy, 15051 // but we also need to de-dup any receivers that are 15052 // singleUser. 15053 if (!scannedFirstReceivers) { 15054 // Collect any single user receivers we had already retrieved. 15055 scannedFirstReceivers = true; 15056 for (int i=0; i<receivers.size(); i++) { 15057 ResolveInfo ri = receivers.get(i); 15058 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15059 ComponentName cn = new ComponentName( 15060 ri.activityInfo.packageName, ri.activityInfo.name); 15061 if (singleUserReceivers == null) { 15062 singleUserReceivers = new HashSet<ComponentName>(); 15063 } 15064 singleUserReceivers.add(cn); 15065 } 15066 } 15067 } 15068 // Add the new results to the existing results, tracking 15069 // and de-dupping single user receivers. 15070 for (int i=0; i<newReceivers.size(); i++) { 15071 ResolveInfo ri = newReceivers.get(i); 15072 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15073 ComponentName cn = new ComponentName( 15074 ri.activityInfo.packageName, ri.activityInfo.name); 15075 if (singleUserReceivers == null) { 15076 singleUserReceivers = new HashSet<ComponentName>(); 15077 } 15078 if (!singleUserReceivers.contains(cn)) { 15079 singleUserReceivers.add(cn); 15080 receivers.add(ri); 15081 } 15082 } else { 15083 receivers.add(ri); 15084 } 15085 } 15086 } 15087 } 15088 } catch (RemoteException ex) { 15089 // pm is in same process, this will never happen. 15090 } 15091 return receivers; 15092 } 15093 15094 private final int broadcastIntentLocked(ProcessRecord callerApp, 15095 String callerPackage, Intent intent, String resolvedType, 15096 IIntentReceiver resultTo, int resultCode, String resultData, 15097 Bundle map, String requiredPermission, int appOp, 15098 boolean ordered, boolean sticky, int callingPid, int callingUid, 15099 int userId) { 15100 intent = new Intent(intent); 15101 15102 // By default broadcasts do not go to stopped apps. 15103 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15104 15105 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15106 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15107 + " ordered=" + ordered + " userid=" + userId); 15108 if ((resultTo != null) && !ordered) { 15109 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15110 } 15111 15112 userId = handleIncomingUser(callingPid, callingUid, userId, 15113 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15114 15115 // Make sure that the user who is receiving this broadcast is started. 15116 // If not, we will just skip it. 15117 15118 15119 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15120 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15121 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15122 Slog.w(TAG, "Skipping broadcast of " + intent 15123 + ": user " + userId + " is stopped"); 15124 return ActivityManager.BROADCAST_SUCCESS; 15125 } 15126 } 15127 15128 /* 15129 * Prevent non-system code (defined here to be non-persistent 15130 * processes) from sending protected broadcasts. 15131 */ 15132 int callingAppId = UserHandle.getAppId(callingUid); 15133 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15134 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15135 || callingAppId == Process.NFC_UID || callingUid == 0) { 15136 // Always okay. 15137 } else if (callerApp == null || !callerApp.persistent) { 15138 try { 15139 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15140 intent.getAction())) { 15141 String msg = "Permission Denial: not allowed to send broadcast " 15142 + intent.getAction() + " from pid=" 15143 + callingPid + ", uid=" + callingUid; 15144 Slog.w(TAG, msg); 15145 throw new SecurityException(msg); 15146 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15147 // Special case for compatibility: we don't want apps to send this, 15148 // but historically it has not been protected and apps may be using it 15149 // to poke their own app widget. So, instead of making it protected, 15150 // just limit it to the caller. 15151 if (callerApp == null) { 15152 String msg = "Permission Denial: not allowed to send broadcast " 15153 + intent.getAction() + " from unknown caller."; 15154 Slog.w(TAG, msg); 15155 throw new SecurityException(msg); 15156 } else if (intent.getComponent() != null) { 15157 // They are good enough to send to an explicit component... verify 15158 // it is being sent to the calling app. 15159 if (!intent.getComponent().getPackageName().equals( 15160 callerApp.info.packageName)) { 15161 String msg = "Permission Denial: not allowed to send broadcast " 15162 + intent.getAction() + " to " 15163 + intent.getComponent().getPackageName() + " from " 15164 + callerApp.info.packageName; 15165 Slog.w(TAG, msg); 15166 throw new SecurityException(msg); 15167 } 15168 } else { 15169 // Limit broadcast to their own package. 15170 intent.setPackage(callerApp.info.packageName); 15171 } 15172 } 15173 } catch (RemoteException e) { 15174 Slog.w(TAG, "Remote exception", e); 15175 return ActivityManager.BROADCAST_SUCCESS; 15176 } 15177 } 15178 15179 // Handle special intents: if this broadcast is from the package 15180 // manager about a package being removed, we need to remove all of 15181 // its activities from the history stack. 15182 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15183 intent.getAction()); 15184 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15185 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15186 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15187 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15188 || uidRemoved) { 15189 if (checkComponentPermission( 15190 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15191 callingPid, callingUid, -1, true) 15192 == PackageManager.PERMISSION_GRANTED) { 15193 if (uidRemoved) { 15194 final Bundle intentExtras = intent.getExtras(); 15195 final int uid = intentExtras != null 15196 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15197 if (uid >= 0) { 15198 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15199 synchronized (bs) { 15200 bs.removeUidStatsLocked(uid); 15201 } 15202 mAppOpsService.uidRemoved(uid); 15203 } 15204 } else { 15205 // If resources are unavailable just force stop all 15206 // those packages and flush the attribute cache as well. 15207 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15208 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15209 if (list != null && (list.length > 0)) { 15210 for (String pkg : list) { 15211 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15212 "storage unmount"); 15213 } 15214 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15215 sendPackageBroadcastLocked( 15216 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15217 } 15218 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15219 intent.getAction())) { 15220 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15221 } else { 15222 Uri data = intent.getData(); 15223 String ssp; 15224 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15225 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15226 intent.getAction()); 15227 boolean fullUninstall = removed && 15228 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15229 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15230 forceStopPackageLocked(ssp, UserHandle.getAppId( 15231 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15232 false, fullUninstall, userId, 15233 removed ? "pkg removed" : "pkg changed"); 15234 } 15235 if (removed) { 15236 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15237 new String[] {ssp}, userId); 15238 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15239 mAppOpsService.packageRemoved( 15240 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15241 15242 // Remove all permissions granted from/to this package 15243 removeUriPermissionsForPackageLocked(ssp, userId, true); 15244 } 15245 } 15246 } 15247 } 15248 } 15249 } else { 15250 String msg = "Permission Denial: " + intent.getAction() 15251 + " broadcast from " + callerPackage + " (pid=" + callingPid 15252 + ", uid=" + callingUid + ")" 15253 + " requires " 15254 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15255 Slog.w(TAG, msg); 15256 throw new SecurityException(msg); 15257 } 15258 15259 // Special case for adding a package: by default turn on compatibility 15260 // mode. 15261 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15262 Uri data = intent.getData(); 15263 String ssp; 15264 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15265 mCompatModePackages.handlePackageAddedLocked(ssp, 15266 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15267 } 15268 } 15269 15270 /* 15271 * If this is the time zone changed action, queue up a message that will reset the timezone 15272 * of all currently running processes. This message will get queued up before the broadcast 15273 * happens. 15274 */ 15275 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15276 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15277 } 15278 15279 /* 15280 * If the user set the time, let all running processes know. 15281 */ 15282 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15283 final int is24Hour = intent.getBooleanExtra( 15284 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15285 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15286 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15287 synchronized (stats) { 15288 stats.noteCurrentTimeChangedLocked(); 15289 } 15290 } 15291 15292 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15293 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15294 } 15295 15296 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15297 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15298 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15299 } 15300 15301 // Add to the sticky list if requested. 15302 if (sticky) { 15303 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15304 callingPid, callingUid) 15305 != PackageManager.PERMISSION_GRANTED) { 15306 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15307 + callingPid + ", uid=" + callingUid 15308 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15309 Slog.w(TAG, msg); 15310 throw new SecurityException(msg); 15311 } 15312 if (requiredPermission != null) { 15313 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15314 + " and enforce permission " + requiredPermission); 15315 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15316 } 15317 if (intent.getComponent() != null) { 15318 throw new SecurityException( 15319 "Sticky broadcasts can't target a specific component"); 15320 } 15321 // We use userId directly here, since the "all" target is maintained 15322 // as a separate set of sticky broadcasts. 15323 if (userId != UserHandle.USER_ALL) { 15324 // But first, if this is not a broadcast to all users, then 15325 // make sure it doesn't conflict with an existing broadcast to 15326 // all users. 15327 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15328 UserHandle.USER_ALL); 15329 if (stickies != null) { 15330 ArrayList<Intent> list = stickies.get(intent.getAction()); 15331 if (list != null) { 15332 int N = list.size(); 15333 int i; 15334 for (i=0; i<N; i++) { 15335 if (intent.filterEquals(list.get(i))) { 15336 throw new IllegalArgumentException( 15337 "Sticky broadcast " + intent + " for user " 15338 + userId + " conflicts with existing global broadcast"); 15339 } 15340 } 15341 } 15342 } 15343 } 15344 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15345 if (stickies == null) { 15346 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15347 mStickyBroadcasts.put(userId, stickies); 15348 } 15349 ArrayList<Intent> list = stickies.get(intent.getAction()); 15350 if (list == null) { 15351 list = new ArrayList<Intent>(); 15352 stickies.put(intent.getAction(), list); 15353 } 15354 int N = list.size(); 15355 int i; 15356 for (i=0; i<N; i++) { 15357 if (intent.filterEquals(list.get(i))) { 15358 // This sticky already exists, replace it. 15359 list.set(i, new Intent(intent)); 15360 break; 15361 } 15362 } 15363 if (i >= N) { 15364 list.add(new Intent(intent)); 15365 } 15366 } 15367 15368 int[] users; 15369 if (userId == UserHandle.USER_ALL) { 15370 // Caller wants broadcast to go to all started users. 15371 users = mStartedUserArray; 15372 } else { 15373 // Caller wants broadcast to go to one specific user. 15374 users = new int[] {userId}; 15375 } 15376 15377 // Figure out who all will receive this broadcast. 15378 List receivers = null; 15379 List<BroadcastFilter> registeredReceivers = null; 15380 // Need to resolve the intent to interested receivers... 15381 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15382 == 0) { 15383 receivers = collectReceiverComponents(intent, resolvedType, users); 15384 } 15385 if (intent.getComponent() == null) { 15386 registeredReceivers = mReceiverResolver.queryIntent(intent, 15387 resolvedType, false, userId); 15388 } 15389 15390 final boolean replacePending = 15391 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15392 15393 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15394 + " replacePending=" + replacePending); 15395 15396 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15397 if (!ordered && NR > 0) { 15398 // If we are not serializing this broadcast, then send the 15399 // registered receivers separately so they don't wait for the 15400 // components to be launched. 15401 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15402 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15403 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15404 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15405 ordered, sticky, false, userId); 15406 if (DEBUG_BROADCAST) Slog.v( 15407 TAG, "Enqueueing parallel broadcast " + r); 15408 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15409 if (!replaced) { 15410 queue.enqueueParallelBroadcastLocked(r); 15411 queue.scheduleBroadcastsLocked(); 15412 } 15413 registeredReceivers = null; 15414 NR = 0; 15415 } 15416 15417 // Merge into one list. 15418 int ir = 0; 15419 if (receivers != null) { 15420 // A special case for PACKAGE_ADDED: do not allow the package 15421 // being added to see this broadcast. This prevents them from 15422 // using this as a back door to get run as soon as they are 15423 // installed. Maybe in the future we want to have a special install 15424 // broadcast or such for apps, but we'd like to deliberately make 15425 // this decision. 15426 String skipPackages[] = null; 15427 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15428 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15429 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15430 Uri data = intent.getData(); 15431 if (data != null) { 15432 String pkgName = data.getSchemeSpecificPart(); 15433 if (pkgName != null) { 15434 skipPackages = new String[] { pkgName }; 15435 } 15436 } 15437 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15438 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15439 } 15440 if (skipPackages != null && (skipPackages.length > 0)) { 15441 for (String skipPackage : skipPackages) { 15442 if (skipPackage != null) { 15443 int NT = receivers.size(); 15444 for (int it=0; it<NT; it++) { 15445 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15446 if (curt.activityInfo.packageName.equals(skipPackage)) { 15447 receivers.remove(it); 15448 it--; 15449 NT--; 15450 } 15451 } 15452 } 15453 } 15454 } 15455 15456 int NT = receivers != null ? receivers.size() : 0; 15457 int it = 0; 15458 ResolveInfo curt = null; 15459 BroadcastFilter curr = null; 15460 while (it < NT && ir < NR) { 15461 if (curt == null) { 15462 curt = (ResolveInfo)receivers.get(it); 15463 } 15464 if (curr == null) { 15465 curr = registeredReceivers.get(ir); 15466 } 15467 if (curr.getPriority() >= curt.priority) { 15468 // Insert this broadcast record into the final list. 15469 receivers.add(it, curr); 15470 ir++; 15471 curr = null; 15472 it++; 15473 NT++; 15474 } else { 15475 // Skip to the next ResolveInfo in the final list. 15476 it++; 15477 curt = null; 15478 } 15479 } 15480 } 15481 while (ir < NR) { 15482 if (receivers == null) { 15483 receivers = new ArrayList(); 15484 } 15485 receivers.add(registeredReceivers.get(ir)); 15486 ir++; 15487 } 15488 15489 if ((receivers != null && receivers.size() > 0) 15490 || resultTo != null) { 15491 BroadcastQueue queue = broadcastQueueForIntent(intent); 15492 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15493 callerPackage, callingPid, callingUid, resolvedType, 15494 requiredPermission, appOp, receivers, resultTo, resultCode, 15495 resultData, map, ordered, sticky, false, userId); 15496 if (DEBUG_BROADCAST) Slog.v( 15497 TAG, "Enqueueing ordered broadcast " + r 15498 + ": prev had " + queue.mOrderedBroadcasts.size()); 15499 if (DEBUG_BROADCAST) { 15500 int seq = r.intent.getIntExtra("seq", -1); 15501 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15502 } 15503 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15504 if (!replaced) { 15505 queue.enqueueOrderedBroadcastLocked(r); 15506 queue.scheduleBroadcastsLocked(); 15507 } 15508 } 15509 15510 return ActivityManager.BROADCAST_SUCCESS; 15511 } 15512 15513 final Intent verifyBroadcastLocked(Intent intent) { 15514 // Refuse possible leaked file descriptors 15515 if (intent != null && intent.hasFileDescriptors() == true) { 15516 throw new IllegalArgumentException("File descriptors passed in Intent"); 15517 } 15518 15519 int flags = intent.getFlags(); 15520 15521 if (!mProcessesReady) { 15522 // if the caller really truly claims to know what they're doing, go 15523 // ahead and allow the broadcast without launching any receivers 15524 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15525 intent = new Intent(intent); 15526 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15527 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15528 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15529 + " before boot completion"); 15530 throw new IllegalStateException("Cannot broadcast before boot completed"); 15531 } 15532 } 15533 15534 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15535 throw new IllegalArgumentException( 15536 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15537 } 15538 15539 return intent; 15540 } 15541 15542 public final int broadcastIntent(IApplicationThread caller, 15543 Intent intent, String resolvedType, IIntentReceiver resultTo, 15544 int resultCode, String resultData, Bundle map, 15545 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15546 enforceNotIsolatedCaller("broadcastIntent"); 15547 synchronized(this) { 15548 intent = verifyBroadcastLocked(intent); 15549 15550 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15551 final int callingPid = Binder.getCallingPid(); 15552 final int callingUid = Binder.getCallingUid(); 15553 final long origId = Binder.clearCallingIdentity(); 15554 int res = broadcastIntentLocked(callerApp, 15555 callerApp != null ? callerApp.info.packageName : null, 15556 intent, resolvedType, resultTo, 15557 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15558 callingPid, callingUid, userId); 15559 Binder.restoreCallingIdentity(origId); 15560 return res; 15561 } 15562 } 15563 15564 int broadcastIntentInPackage(String packageName, int uid, 15565 Intent intent, String resolvedType, IIntentReceiver resultTo, 15566 int resultCode, String resultData, Bundle map, 15567 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15568 synchronized(this) { 15569 intent = verifyBroadcastLocked(intent); 15570 15571 final long origId = Binder.clearCallingIdentity(); 15572 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15573 resultTo, resultCode, resultData, map, requiredPermission, 15574 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15575 Binder.restoreCallingIdentity(origId); 15576 return res; 15577 } 15578 } 15579 15580 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15581 // Refuse possible leaked file descriptors 15582 if (intent != null && intent.hasFileDescriptors() == true) { 15583 throw new IllegalArgumentException("File descriptors passed in Intent"); 15584 } 15585 15586 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15587 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15588 15589 synchronized(this) { 15590 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15591 != PackageManager.PERMISSION_GRANTED) { 15592 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15593 + Binder.getCallingPid() 15594 + ", uid=" + Binder.getCallingUid() 15595 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15596 Slog.w(TAG, msg); 15597 throw new SecurityException(msg); 15598 } 15599 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15600 if (stickies != null) { 15601 ArrayList<Intent> list = stickies.get(intent.getAction()); 15602 if (list != null) { 15603 int N = list.size(); 15604 int i; 15605 for (i=0; i<N; i++) { 15606 if (intent.filterEquals(list.get(i))) { 15607 list.remove(i); 15608 break; 15609 } 15610 } 15611 if (list.size() <= 0) { 15612 stickies.remove(intent.getAction()); 15613 } 15614 } 15615 if (stickies.size() <= 0) { 15616 mStickyBroadcasts.remove(userId); 15617 } 15618 } 15619 } 15620 } 15621 15622 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15623 String resultData, Bundle resultExtras, boolean resultAbort) { 15624 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15625 if (r == null) { 15626 Slog.w(TAG, "finishReceiver called but not found on queue"); 15627 return false; 15628 } 15629 15630 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15631 } 15632 15633 void backgroundServicesFinishedLocked(int userId) { 15634 for (BroadcastQueue queue : mBroadcastQueues) { 15635 queue.backgroundServicesFinishedLocked(userId); 15636 } 15637 } 15638 15639 public void finishReceiver(IBinder who, int resultCode, String resultData, 15640 Bundle resultExtras, boolean resultAbort) { 15641 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15642 15643 // Refuse possible leaked file descriptors 15644 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15645 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15646 } 15647 15648 final long origId = Binder.clearCallingIdentity(); 15649 try { 15650 boolean doNext = false; 15651 BroadcastRecord r; 15652 15653 synchronized(this) { 15654 r = broadcastRecordForReceiverLocked(who); 15655 if (r != null) { 15656 doNext = r.queue.finishReceiverLocked(r, resultCode, 15657 resultData, resultExtras, resultAbort, true); 15658 } 15659 } 15660 15661 if (doNext) { 15662 r.queue.processNextBroadcast(false); 15663 } 15664 trimApplications(); 15665 } finally { 15666 Binder.restoreCallingIdentity(origId); 15667 } 15668 } 15669 15670 // ========================================================= 15671 // INSTRUMENTATION 15672 // ========================================================= 15673 15674 public boolean startInstrumentation(ComponentName className, 15675 String profileFile, int flags, Bundle arguments, 15676 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15677 int userId, String abiOverride) { 15678 enforceNotIsolatedCaller("startInstrumentation"); 15679 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15680 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15681 // Refuse possible leaked file descriptors 15682 if (arguments != null && arguments.hasFileDescriptors()) { 15683 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15684 } 15685 15686 synchronized(this) { 15687 InstrumentationInfo ii = null; 15688 ApplicationInfo ai = null; 15689 try { 15690 ii = mContext.getPackageManager().getInstrumentationInfo( 15691 className, STOCK_PM_FLAGS); 15692 ai = AppGlobals.getPackageManager().getApplicationInfo( 15693 ii.targetPackage, STOCK_PM_FLAGS, userId); 15694 } catch (PackageManager.NameNotFoundException e) { 15695 } catch (RemoteException e) { 15696 } 15697 if (ii == null) { 15698 reportStartInstrumentationFailure(watcher, className, 15699 "Unable to find instrumentation info for: " + className); 15700 return false; 15701 } 15702 if (ai == null) { 15703 reportStartInstrumentationFailure(watcher, className, 15704 "Unable to find instrumentation target package: " + ii.targetPackage); 15705 return false; 15706 } 15707 15708 int match = mContext.getPackageManager().checkSignatures( 15709 ii.targetPackage, ii.packageName); 15710 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15711 String msg = "Permission Denial: starting instrumentation " 15712 + className + " from pid=" 15713 + Binder.getCallingPid() 15714 + ", uid=" + Binder.getCallingPid() 15715 + " not allowed because package " + ii.packageName 15716 + " does not have a signature matching the target " 15717 + ii.targetPackage; 15718 reportStartInstrumentationFailure(watcher, className, msg); 15719 throw new SecurityException(msg); 15720 } 15721 15722 final long origId = Binder.clearCallingIdentity(); 15723 // Instrumentation can kill and relaunch even persistent processes 15724 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15725 "start instr"); 15726 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15727 app.instrumentationClass = className; 15728 app.instrumentationInfo = ai; 15729 app.instrumentationProfileFile = profileFile; 15730 app.instrumentationArguments = arguments; 15731 app.instrumentationWatcher = watcher; 15732 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15733 app.instrumentationResultClass = className; 15734 Binder.restoreCallingIdentity(origId); 15735 } 15736 15737 return true; 15738 } 15739 15740 /** 15741 * Report errors that occur while attempting to start Instrumentation. Always writes the 15742 * error to the logs, but if somebody is watching, send the report there too. This enables 15743 * the "am" command to report errors with more information. 15744 * 15745 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15746 * @param cn The component name of the instrumentation. 15747 * @param report The error report. 15748 */ 15749 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15750 ComponentName cn, String report) { 15751 Slog.w(TAG, report); 15752 try { 15753 if (watcher != null) { 15754 Bundle results = new Bundle(); 15755 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15756 results.putString("Error", report); 15757 watcher.instrumentationStatus(cn, -1, results); 15758 } 15759 } catch (RemoteException e) { 15760 Slog.w(TAG, e); 15761 } 15762 } 15763 15764 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15765 if (app.instrumentationWatcher != null) { 15766 try { 15767 // NOTE: IInstrumentationWatcher *must* be oneway here 15768 app.instrumentationWatcher.instrumentationFinished( 15769 app.instrumentationClass, 15770 resultCode, 15771 results); 15772 } catch (RemoteException e) { 15773 } 15774 } 15775 if (app.instrumentationUiAutomationConnection != null) { 15776 try { 15777 app.instrumentationUiAutomationConnection.shutdown(); 15778 } catch (RemoteException re) { 15779 /* ignore */ 15780 } 15781 // Only a UiAutomation can set this flag and now that 15782 // it is finished we make sure it is reset to its default. 15783 mUserIsMonkey = false; 15784 } 15785 app.instrumentationWatcher = null; 15786 app.instrumentationUiAutomationConnection = null; 15787 app.instrumentationClass = null; 15788 app.instrumentationInfo = null; 15789 app.instrumentationProfileFile = null; 15790 app.instrumentationArguments = null; 15791 15792 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15793 "finished inst"); 15794 } 15795 15796 public void finishInstrumentation(IApplicationThread target, 15797 int resultCode, Bundle results) { 15798 int userId = UserHandle.getCallingUserId(); 15799 // Refuse possible leaked file descriptors 15800 if (results != null && results.hasFileDescriptors()) { 15801 throw new IllegalArgumentException("File descriptors passed in Intent"); 15802 } 15803 15804 synchronized(this) { 15805 ProcessRecord app = getRecordForAppLocked(target); 15806 if (app == null) { 15807 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15808 return; 15809 } 15810 final long origId = Binder.clearCallingIdentity(); 15811 finishInstrumentationLocked(app, resultCode, results); 15812 Binder.restoreCallingIdentity(origId); 15813 } 15814 } 15815 15816 // ========================================================= 15817 // CONFIGURATION 15818 // ========================================================= 15819 15820 public ConfigurationInfo getDeviceConfigurationInfo() { 15821 ConfigurationInfo config = new ConfigurationInfo(); 15822 synchronized (this) { 15823 config.reqTouchScreen = mConfiguration.touchscreen; 15824 config.reqKeyboardType = mConfiguration.keyboard; 15825 config.reqNavigation = mConfiguration.navigation; 15826 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15827 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15828 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15829 } 15830 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15831 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15832 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15833 } 15834 config.reqGlEsVersion = GL_ES_VERSION; 15835 } 15836 return config; 15837 } 15838 15839 ActivityStack getFocusedStack() { 15840 return mStackSupervisor.getFocusedStack(); 15841 } 15842 15843 public Configuration getConfiguration() { 15844 Configuration ci; 15845 synchronized(this) { 15846 ci = new Configuration(mConfiguration); 15847 } 15848 return ci; 15849 } 15850 15851 public void updatePersistentConfiguration(Configuration values) { 15852 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15853 "updateConfiguration()"); 15854 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15855 "updateConfiguration()"); 15856 if (values == null) { 15857 throw new NullPointerException("Configuration must not be null"); 15858 } 15859 15860 synchronized(this) { 15861 final long origId = Binder.clearCallingIdentity(); 15862 updateConfigurationLocked(values, null, true, false); 15863 Binder.restoreCallingIdentity(origId); 15864 } 15865 } 15866 15867 public void updateConfiguration(Configuration values) { 15868 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15869 "updateConfiguration()"); 15870 15871 synchronized(this) { 15872 if (values == null && mWindowManager != null) { 15873 // sentinel: fetch the current configuration from the window manager 15874 values = mWindowManager.computeNewConfiguration(); 15875 } 15876 15877 if (mWindowManager != null) { 15878 mProcessList.applyDisplaySize(mWindowManager); 15879 } 15880 15881 final long origId = Binder.clearCallingIdentity(); 15882 if (values != null) { 15883 Settings.System.clearConfiguration(values); 15884 } 15885 updateConfigurationLocked(values, null, false, false); 15886 Binder.restoreCallingIdentity(origId); 15887 } 15888 } 15889 15890 /** 15891 * Do either or both things: (1) change the current configuration, and (2) 15892 * make sure the given activity is running with the (now) current 15893 * configuration. Returns true if the activity has been left running, or 15894 * false if <var>starting</var> is being destroyed to match the new 15895 * configuration. 15896 * @param persistent TODO 15897 */ 15898 boolean updateConfigurationLocked(Configuration values, 15899 ActivityRecord starting, boolean persistent, boolean initLocale) { 15900 int changes = 0; 15901 15902 if (values != null) { 15903 Configuration newConfig = new Configuration(mConfiguration); 15904 changes = newConfig.updateFrom(values); 15905 if (changes != 0) { 15906 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15907 Slog.i(TAG, "Updating configuration to: " + values); 15908 } 15909 15910 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15911 15912 if (values.locale != null && !initLocale) { 15913 saveLocaleLocked(values.locale, 15914 !values.locale.equals(mConfiguration.locale), 15915 values.userSetLocale); 15916 } 15917 15918 mConfigurationSeq++; 15919 if (mConfigurationSeq <= 0) { 15920 mConfigurationSeq = 1; 15921 } 15922 newConfig.seq = mConfigurationSeq; 15923 mConfiguration = newConfig; 15924 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15925 //mUsageStatsService.noteStartConfig(newConfig); 15926 15927 final Configuration configCopy = new Configuration(mConfiguration); 15928 15929 // TODO: If our config changes, should we auto dismiss any currently 15930 // showing dialogs? 15931 mShowDialogs = shouldShowDialogs(newConfig); 15932 15933 AttributeCache ac = AttributeCache.instance(); 15934 if (ac != null) { 15935 ac.updateConfiguration(configCopy); 15936 } 15937 15938 // Make sure all resources in our process are updated 15939 // right now, so that anyone who is going to retrieve 15940 // resource values after we return will be sure to get 15941 // the new ones. This is especially important during 15942 // boot, where the first config change needs to guarantee 15943 // all resources have that config before following boot 15944 // code is executed. 15945 mSystemThread.applyConfigurationToResources(configCopy); 15946 15947 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15948 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15949 msg.obj = new Configuration(configCopy); 15950 mHandler.sendMessage(msg); 15951 } 15952 15953 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15954 ProcessRecord app = mLruProcesses.get(i); 15955 try { 15956 if (app.thread != null) { 15957 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15958 + app.processName + " new config " + mConfiguration); 15959 app.thread.scheduleConfigurationChanged(configCopy); 15960 } 15961 } catch (Exception e) { 15962 } 15963 } 15964 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15965 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15966 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15967 | Intent.FLAG_RECEIVER_FOREGROUND); 15968 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15969 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15970 Process.SYSTEM_UID, UserHandle.USER_ALL); 15971 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15972 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15973 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15974 broadcastIntentLocked(null, null, intent, 15975 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15976 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15977 } 15978 } 15979 } 15980 15981 boolean kept = true; 15982 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15983 // mainStack is null during startup. 15984 if (mainStack != null) { 15985 if (changes != 0 && starting == null) { 15986 // If the configuration changed, and the caller is not already 15987 // in the process of starting an activity, then find the top 15988 // activity to check if its configuration needs to change. 15989 starting = mainStack.topRunningActivityLocked(null); 15990 } 15991 15992 if (starting != null) { 15993 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15994 // And we need to make sure at this point that all other activities 15995 // are made visible with the correct configuration. 15996 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15997 } 15998 } 15999 16000 if (values != null && mWindowManager != null) { 16001 mWindowManager.setNewConfiguration(mConfiguration); 16002 } 16003 16004 return kept; 16005 } 16006 16007 /** 16008 * Decide based on the configuration whether we should shouw the ANR, 16009 * crash, etc dialogs. The idea is that if there is no affordnace to 16010 * press the on-screen buttons, we shouldn't show the dialog. 16011 * 16012 * A thought: SystemUI might also want to get told about this, the Power 16013 * dialog / global actions also might want different behaviors. 16014 */ 16015 private static final boolean shouldShowDialogs(Configuration config) { 16016 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16017 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16018 } 16019 16020 /** 16021 * Save the locale. You must be inside a synchronized (this) block. 16022 */ 16023 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16024 if(isDiff) { 16025 SystemProperties.set("user.language", l.getLanguage()); 16026 SystemProperties.set("user.region", l.getCountry()); 16027 } 16028 16029 if(isPersist) { 16030 SystemProperties.set("persist.sys.language", l.getLanguage()); 16031 SystemProperties.set("persist.sys.country", l.getCountry()); 16032 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16033 } 16034 } 16035 16036 @Override 16037 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16038 synchronized (this) { 16039 ActivityRecord srec = ActivityRecord.forToken(token); 16040 if (srec.task != null && srec.task.stack != null) { 16041 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16042 } 16043 } 16044 return false; 16045 } 16046 16047 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16048 Intent resultData) { 16049 16050 synchronized (this) { 16051 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16052 if (stack != null) { 16053 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16054 } 16055 return false; 16056 } 16057 } 16058 16059 public int getLaunchedFromUid(IBinder activityToken) { 16060 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16061 if (srec == null) { 16062 return -1; 16063 } 16064 return srec.launchedFromUid; 16065 } 16066 16067 public String getLaunchedFromPackage(IBinder activityToken) { 16068 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16069 if (srec == null) { 16070 return null; 16071 } 16072 return srec.launchedFromPackage; 16073 } 16074 16075 // ========================================================= 16076 // LIFETIME MANAGEMENT 16077 // ========================================================= 16078 16079 // Returns which broadcast queue the app is the current [or imminent] receiver 16080 // on, or 'null' if the app is not an active broadcast recipient. 16081 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16082 BroadcastRecord r = app.curReceiver; 16083 if (r != null) { 16084 return r.queue; 16085 } 16086 16087 // It's not the current receiver, but it might be starting up to become one 16088 synchronized (this) { 16089 for (BroadcastQueue queue : mBroadcastQueues) { 16090 r = queue.mPendingBroadcast; 16091 if (r != null && r.curApp == app) { 16092 // found it; report which queue it's in 16093 return queue; 16094 } 16095 } 16096 } 16097 16098 return null; 16099 } 16100 16101 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16102 boolean doingAll, long now) { 16103 if (mAdjSeq == app.adjSeq) { 16104 // This adjustment has already been computed. 16105 return app.curRawAdj; 16106 } 16107 16108 if (app.thread == null) { 16109 app.adjSeq = mAdjSeq; 16110 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16111 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16112 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16113 } 16114 16115 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16116 app.adjSource = null; 16117 app.adjTarget = null; 16118 app.empty = false; 16119 app.cached = false; 16120 16121 final int activitiesSize = app.activities.size(); 16122 16123 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16124 // The max adjustment doesn't allow this app to be anything 16125 // below foreground, so it is not worth doing work for it. 16126 app.adjType = "fixed"; 16127 app.adjSeq = mAdjSeq; 16128 app.curRawAdj = app.maxAdj; 16129 app.foregroundActivities = false; 16130 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16131 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16132 // System processes can do UI, and when they do we want to have 16133 // them trim their memory after the user leaves the UI. To 16134 // facilitate this, here we need to determine whether or not it 16135 // is currently showing UI. 16136 app.systemNoUi = true; 16137 if (app == TOP_APP) { 16138 app.systemNoUi = false; 16139 } else if (activitiesSize > 0) { 16140 for (int j = 0; j < activitiesSize; j++) { 16141 final ActivityRecord r = app.activities.get(j); 16142 if (r.visible) { 16143 app.systemNoUi = false; 16144 } 16145 } 16146 } 16147 if (!app.systemNoUi) { 16148 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16149 } 16150 return (app.curAdj=app.maxAdj); 16151 } 16152 16153 app.systemNoUi = false; 16154 16155 // Determine the importance of the process, starting with most 16156 // important to least, and assign an appropriate OOM adjustment. 16157 int adj; 16158 int schedGroup; 16159 int procState; 16160 boolean foregroundActivities = false; 16161 BroadcastQueue queue; 16162 if (app == TOP_APP) { 16163 // The last app on the list is the foreground app. 16164 adj = ProcessList.FOREGROUND_APP_ADJ; 16165 schedGroup = Process.THREAD_GROUP_DEFAULT; 16166 app.adjType = "top-activity"; 16167 foregroundActivities = true; 16168 procState = ActivityManager.PROCESS_STATE_TOP; 16169 } else if (app.instrumentationClass != null) { 16170 // Don't want to kill running instrumentation. 16171 adj = ProcessList.FOREGROUND_APP_ADJ; 16172 schedGroup = Process.THREAD_GROUP_DEFAULT; 16173 app.adjType = "instrumentation"; 16174 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16175 } else if ((queue = isReceivingBroadcast(app)) != null) { 16176 // An app that is currently receiving a broadcast also 16177 // counts as being in the foreground for OOM killer purposes. 16178 // It's placed in a sched group based on the nature of the 16179 // broadcast as reflected by which queue it's active in. 16180 adj = ProcessList.FOREGROUND_APP_ADJ; 16181 schedGroup = (queue == mFgBroadcastQueue) 16182 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16183 app.adjType = "broadcast"; 16184 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16185 } else if (app.executingServices.size() > 0) { 16186 // An app that is currently executing a service callback also 16187 // counts as being in the foreground. 16188 adj = ProcessList.FOREGROUND_APP_ADJ; 16189 schedGroup = app.execServicesFg ? 16190 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16191 app.adjType = "exec-service"; 16192 procState = ActivityManager.PROCESS_STATE_SERVICE; 16193 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16194 } else { 16195 // As far as we know the process is empty. We may change our mind later. 16196 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16197 // At this point we don't actually know the adjustment. Use the cached adj 16198 // value that the caller wants us to. 16199 adj = cachedAdj; 16200 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16201 app.cached = true; 16202 app.empty = true; 16203 app.adjType = "cch-empty"; 16204 } 16205 16206 // Examine all activities if not already foreground. 16207 if (!foregroundActivities && activitiesSize > 0) { 16208 for (int j = 0; j < activitiesSize; j++) { 16209 final ActivityRecord r = app.activities.get(j); 16210 if (r.app != app) { 16211 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16212 + app + "?!?"); 16213 continue; 16214 } 16215 if (r.visible) { 16216 // App has a visible activity; only upgrade adjustment. 16217 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16218 adj = ProcessList.VISIBLE_APP_ADJ; 16219 app.adjType = "visible"; 16220 } 16221 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16222 procState = ActivityManager.PROCESS_STATE_TOP; 16223 } 16224 schedGroup = Process.THREAD_GROUP_DEFAULT; 16225 app.cached = false; 16226 app.empty = false; 16227 foregroundActivities = true; 16228 break; 16229 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16230 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16231 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16232 app.adjType = "pausing"; 16233 } 16234 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16235 procState = ActivityManager.PROCESS_STATE_TOP; 16236 } 16237 schedGroup = Process.THREAD_GROUP_DEFAULT; 16238 app.cached = false; 16239 app.empty = false; 16240 foregroundActivities = true; 16241 } else if (r.state == ActivityState.STOPPING) { 16242 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16243 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16244 app.adjType = "stopping"; 16245 } 16246 // For the process state, we will at this point consider the 16247 // process to be cached. It will be cached either as an activity 16248 // or empty depending on whether the activity is finishing. We do 16249 // this so that we can treat the process as cached for purposes of 16250 // memory trimming (determing current memory level, trim command to 16251 // send to process) since there can be an arbitrary number of stopping 16252 // processes and they should soon all go into the cached state. 16253 if (!r.finishing) { 16254 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16255 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16256 } 16257 } 16258 app.cached = false; 16259 app.empty = false; 16260 foregroundActivities = true; 16261 } else { 16262 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16263 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16264 app.adjType = "cch-act"; 16265 } 16266 } 16267 } 16268 } 16269 16270 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16271 if (app.foregroundServices) { 16272 // The user is aware of this app, so make it visible. 16273 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16274 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16275 app.cached = false; 16276 app.adjType = "fg-service"; 16277 schedGroup = Process.THREAD_GROUP_DEFAULT; 16278 } else if (app.forcingToForeground != null) { 16279 // The user is aware of this app, so make it visible. 16280 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16281 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16282 app.cached = false; 16283 app.adjType = "force-fg"; 16284 app.adjSource = app.forcingToForeground; 16285 schedGroup = Process.THREAD_GROUP_DEFAULT; 16286 } 16287 } 16288 16289 if (app == mHeavyWeightProcess) { 16290 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16291 // We don't want to kill the current heavy-weight process. 16292 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16293 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16294 app.cached = false; 16295 app.adjType = "heavy"; 16296 } 16297 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16298 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16299 } 16300 } 16301 16302 if (app == mHomeProcess) { 16303 if (adj > ProcessList.HOME_APP_ADJ) { 16304 // This process is hosting what we currently consider to be the 16305 // home app, so we don't want to let it go into the background. 16306 adj = ProcessList.HOME_APP_ADJ; 16307 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16308 app.cached = false; 16309 app.adjType = "home"; 16310 } 16311 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16312 procState = ActivityManager.PROCESS_STATE_HOME; 16313 } 16314 } 16315 16316 if (app == mPreviousProcess && app.activities.size() > 0) { 16317 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16318 // This was the previous process that showed UI to the user. 16319 // We want to try to keep it around more aggressively, to give 16320 // a good experience around switching between two apps. 16321 adj = ProcessList.PREVIOUS_APP_ADJ; 16322 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16323 app.cached = false; 16324 app.adjType = "previous"; 16325 } 16326 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16327 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16328 } 16329 } 16330 16331 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16332 + " reason=" + app.adjType); 16333 16334 // By default, we use the computed adjustment. It may be changed if 16335 // there are applications dependent on our services or providers, but 16336 // this gives us a baseline and makes sure we don't get into an 16337 // infinite recursion. 16338 app.adjSeq = mAdjSeq; 16339 app.curRawAdj = adj; 16340 app.hasStartedServices = false; 16341 16342 if (mBackupTarget != null && app == mBackupTarget.app) { 16343 // If possible we want to avoid killing apps while they're being backed up 16344 if (adj > ProcessList.BACKUP_APP_ADJ) { 16345 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16346 adj = ProcessList.BACKUP_APP_ADJ; 16347 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16348 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16349 } 16350 app.adjType = "backup"; 16351 app.cached = false; 16352 } 16353 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16354 procState = ActivityManager.PROCESS_STATE_BACKUP; 16355 } 16356 } 16357 16358 boolean mayBeTop = false; 16359 16360 for (int is = app.services.size()-1; 16361 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16362 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16363 || procState > ActivityManager.PROCESS_STATE_TOP); 16364 is--) { 16365 ServiceRecord s = app.services.valueAt(is); 16366 if (s.startRequested) { 16367 app.hasStartedServices = true; 16368 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16369 procState = ActivityManager.PROCESS_STATE_SERVICE; 16370 } 16371 if (app.hasShownUi && app != mHomeProcess) { 16372 // If this process has shown some UI, let it immediately 16373 // go to the LRU list because it may be pretty heavy with 16374 // UI stuff. We'll tag it with a label just to help 16375 // debug and understand what is going on. 16376 if (adj > ProcessList.SERVICE_ADJ) { 16377 app.adjType = "cch-started-ui-services"; 16378 } 16379 } else { 16380 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16381 // This service has seen some activity within 16382 // recent memory, so we will keep its process ahead 16383 // of the background processes. 16384 if (adj > ProcessList.SERVICE_ADJ) { 16385 adj = ProcessList.SERVICE_ADJ; 16386 app.adjType = "started-services"; 16387 app.cached = false; 16388 } 16389 } 16390 // If we have let the service slide into the background 16391 // state, still have some text describing what it is doing 16392 // even though the service no longer has an impact. 16393 if (adj > ProcessList.SERVICE_ADJ) { 16394 app.adjType = "cch-started-services"; 16395 } 16396 } 16397 } 16398 for (int conni = s.connections.size()-1; 16399 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16400 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16401 || procState > ActivityManager.PROCESS_STATE_TOP); 16402 conni--) { 16403 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16404 for (int i = 0; 16405 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16406 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16407 || procState > ActivityManager.PROCESS_STATE_TOP); 16408 i++) { 16409 // XXX should compute this based on the max of 16410 // all connected clients. 16411 ConnectionRecord cr = clist.get(i); 16412 if (cr.binding.client == app) { 16413 // Binding to ourself is not interesting. 16414 continue; 16415 } 16416 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16417 ProcessRecord client = cr.binding.client; 16418 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16419 TOP_APP, doingAll, now); 16420 int clientProcState = client.curProcState; 16421 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16422 // If the other app is cached for any reason, for purposes here 16423 // we are going to consider it empty. The specific cached state 16424 // doesn't propagate except under certain conditions. 16425 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16426 } 16427 String adjType = null; 16428 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16429 // Not doing bind OOM management, so treat 16430 // this guy more like a started service. 16431 if (app.hasShownUi && app != mHomeProcess) { 16432 // If this process has shown some UI, let it immediately 16433 // go to the LRU list because it may be pretty heavy with 16434 // UI stuff. We'll tag it with a label just to help 16435 // debug and understand what is going on. 16436 if (adj > clientAdj) { 16437 adjType = "cch-bound-ui-services"; 16438 } 16439 app.cached = false; 16440 clientAdj = adj; 16441 clientProcState = procState; 16442 } else { 16443 if (now >= (s.lastActivity 16444 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16445 // This service has not seen activity within 16446 // recent memory, so allow it to drop to the 16447 // LRU list if there is no other reason to keep 16448 // it around. We'll also tag it with a label just 16449 // to help debug and undertand what is going on. 16450 if (adj > clientAdj) { 16451 adjType = "cch-bound-services"; 16452 } 16453 clientAdj = adj; 16454 } 16455 } 16456 } 16457 if (adj > clientAdj) { 16458 // If this process has recently shown UI, and 16459 // the process that is binding to it is less 16460 // important than being visible, then we don't 16461 // care about the binding as much as we care 16462 // about letting this process get into the LRU 16463 // list to be killed and restarted if needed for 16464 // memory. 16465 if (app.hasShownUi && app != mHomeProcess 16466 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16467 adjType = "cch-bound-ui-services"; 16468 } else { 16469 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16470 |Context.BIND_IMPORTANT)) != 0) { 16471 adj = clientAdj; 16472 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16473 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16474 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16475 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16476 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16477 adj = clientAdj; 16478 } else { 16479 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16480 adj = ProcessList.VISIBLE_APP_ADJ; 16481 } 16482 } 16483 if (!client.cached) { 16484 app.cached = false; 16485 } 16486 adjType = "service"; 16487 } 16488 } 16489 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16490 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16491 schedGroup = Process.THREAD_GROUP_DEFAULT; 16492 } 16493 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16494 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16495 // Special handling of clients who are in the top state. 16496 // We *may* want to consider this process to be in the 16497 // top state as well, but only if there is not another 16498 // reason for it to be running. Being on the top is a 16499 // special state, meaning you are specifically running 16500 // for the current top app. If the process is already 16501 // running in the background for some other reason, it 16502 // is more important to continue considering it to be 16503 // in the background state. 16504 mayBeTop = true; 16505 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16506 } else { 16507 // Special handling for above-top states (persistent 16508 // processes). These should not bring the current process 16509 // into the top state, since they are not on top. Instead 16510 // give them the best state after that. 16511 clientProcState = 16512 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16513 } 16514 } 16515 } else { 16516 if (clientProcState < 16517 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16518 clientProcState = 16519 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16520 } 16521 } 16522 if (procState > clientProcState) { 16523 procState = clientProcState; 16524 } 16525 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16526 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16527 app.pendingUiClean = true; 16528 } 16529 if (adjType != null) { 16530 app.adjType = adjType; 16531 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16532 .REASON_SERVICE_IN_USE; 16533 app.adjSource = cr.binding.client; 16534 app.adjSourceProcState = clientProcState; 16535 app.adjTarget = s.name; 16536 } 16537 } 16538 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16539 app.treatLikeActivity = true; 16540 } 16541 final ActivityRecord a = cr.activity; 16542 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16543 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16544 (a.visible || a.state == ActivityState.RESUMED 16545 || a.state == ActivityState.PAUSING)) { 16546 adj = ProcessList.FOREGROUND_APP_ADJ; 16547 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16548 schedGroup = Process.THREAD_GROUP_DEFAULT; 16549 } 16550 app.cached = false; 16551 app.adjType = "service"; 16552 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16553 .REASON_SERVICE_IN_USE; 16554 app.adjSource = a; 16555 app.adjSourceProcState = procState; 16556 app.adjTarget = s.name; 16557 } 16558 } 16559 } 16560 } 16561 } 16562 16563 for (int provi = app.pubProviders.size()-1; 16564 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16565 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16566 || procState > ActivityManager.PROCESS_STATE_TOP); 16567 provi--) { 16568 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16569 for (int i = cpr.connections.size()-1; 16570 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16571 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16572 || procState > ActivityManager.PROCESS_STATE_TOP); 16573 i--) { 16574 ContentProviderConnection conn = cpr.connections.get(i); 16575 ProcessRecord client = conn.client; 16576 if (client == app) { 16577 // Being our own client is not interesting. 16578 continue; 16579 } 16580 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16581 int clientProcState = client.curProcState; 16582 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16583 // If the other app is cached for any reason, for purposes here 16584 // we are going to consider it empty. 16585 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16586 } 16587 if (adj > clientAdj) { 16588 if (app.hasShownUi && app != mHomeProcess 16589 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16590 app.adjType = "cch-ui-provider"; 16591 } else { 16592 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16593 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16594 app.adjType = "provider"; 16595 } 16596 app.cached &= client.cached; 16597 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16598 .REASON_PROVIDER_IN_USE; 16599 app.adjSource = client; 16600 app.adjSourceProcState = clientProcState; 16601 app.adjTarget = cpr.name; 16602 } 16603 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16604 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16605 // Special handling of clients who are in the top state. 16606 // We *may* want to consider this process to be in the 16607 // top state as well, but only if there is not another 16608 // reason for it to be running. Being on the top is a 16609 // special state, meaning you are specifically running 16610 // for the current top app. If the process is already 16611 // running in the background for some other reason, it 16612 // is more important to continue considering it to be 16613 // in the background state. 16614 mayBeTop = true; 16615 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16616 } else { 16617 // Special handling for above-top states (persistent 16618 // processes). These should not bring the current process 16619 // into the top state, since they are not on top. Instead 16620 // give them the best state after that. 16621 clientProcState = 16622 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16623 } 16624 } 16625 if (procState > clientProcState) { 16626 procState = clientProcState; 16627 } 16628 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16629 schedGroup = Process.THREAD_GROUP_DEFAULT; 16630 } 16631 } 16632 // If the provider has external (non-framework) process 16633 // dependencies, ensure that its adjustment is at least 16634 // FOREGROUND_APP_ADJ. 16635 if (cpr.hasExternalProcessHandles()) { 16636 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16637 adj = ProcessList.FOREGROUND_APP_ADJ; 16638 schedGroup = Process.THREAD_GROUP_DEFAULT; 16639 app.cached = false; 16640 app.adjType = "provider"; 16641 app.adjTarget = cpr.name; 16642 } 16643 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16644 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16645 } 16646 } 16647 } 16648 16649 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16650 // A client of one of our services or providers is in the top state. We 16651 // *may* want to be in the top state, but not if we are already running in 16652 // the background for some other reason. For the decision here, we are going 16653 // to pick out a few specific states that we want to remain in when a client 16654 // is top (states that tend to be longer-term) and otherwise allow it to go 16655 // to the top state. 16656 switch (procState) { 16657 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16658 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16659 case ActivityManager.PROCESS_STATE_SERVICE: 16660 // These all are longer-term states, so pull them up to the top 16661 // of the background states, but not all the way to the top state. 16662 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16663 break; 16664 default: 16665 // Otherwise, top is a better choice, so take it. 16666 procState = ActivityManager.PROCESS_STATE_TOP; 16667 break; 16668 } 16669 } 16670 16671 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16672 if (app.hasClientActivities) { 16673 // This is a cached process, but with client activities. Mark it so. 16674 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16675 app.adjType = "cch-client-act"; 16676 } else if (app.treatLikeActivity) { 16677 // This is a cached process, but somebody wants us to treat it like it has 16678 // an activity, okay! 16679 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16680 app.adjType = "cch-as-act"; 16681 } 16682 } 16683 16684 if (adj == ProcessList.SERVICE_ADJ) { 16685 if (doingAll) { 16686 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16687 mNewNumServiceProcs++; 16688 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16689 if (!app.serviceb) { 16690 // This service isn't far enough down on the LRU list to 16691 // normally be a B service, but if we are low on RAM and it 16692 // is large we want to force it down since we would prefer to 16693 // keep launcher over it. 16694 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16695 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16696 app.serviceHighRam = true; 16697 app.serviceb = true; 16698 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16699 } else { 16700 mNewNumAServiceProcs++; 16701 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16702 } 16703 } else { 16704 app.serviceHighRam = false; 16705 } 16706 } 16707 if (app.serviceb) { 16708 adj = ProcessList.SERVICE_B_ADJ; 16709 } 16710 } 16711 16712 app.curRawAdj = adj; 16713 16714 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16715 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16716 if (adj > app.maxAdj) { 16717 adj = app.maxAdj; 16718 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16719 schedGroup = Process.THREAD_GROUP_DEFAULT; 16720 } 16721 } 16722 16723 // Do final modification to adj. Everything we do between here and applying 16724 // the final setAdj must be done in this function, because we will also use 16725 // it when computing the final cached adj later. Note that we don't need to 16726 // worry about this for max adj above, since max adj will always be used to 16727 // keep it out of the cached vaues. 16728 app.curAdj = app.modifyRawOomAdj(adj); 16729 app.curSchedGroup = schedGroup; 16730 app.curProcState = procState; 16731 app.foregroundActivities = foregroundActivities; 16732 16733 return app.curRawAdj; 16734 } 16735 16736 /** 16737 * Schedule PSS collection of a process. 16738 */ 16739 void requestPssLocked(ProcessRecord proc, int procState) { 16740 if (mPendingPssProcesses.contains(proc)) { 16741 return; 16742 } 16743 if (mPendingPssProcesses.size() == 0) { 16744 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16745 } 16746 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16747 proc.pssProcState = procState; 16748 mPendingPssProcesses.add(proc); 16749 } 16750 16751 /** 16752 * Schedule PSS collection of all processes. 16753 */ 16754 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16755 if (!always) { 16756 if (now < (mLastFullPssTime + 16757 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16758 return; 16759 } 16760 } 16761 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16762 mLastFullPssTime = now; 16763 mFullPssPending = true; 16764 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16765 mPendingPssProcesses.clear(); 16766 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16767 ProcessRecord app = mLruProcesses.get(i); 16768 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16769 app.pssProcState = app.setProcState; 16770 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16771 isSleeping(), now); 16772 mPendingPssProcesses.add(app); 16773 } 16774 } 16775 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16776 } 16777 16778 /** 16779 * Ask a given process to GC right now. 16780 */ 16781 final void performAppGcLocked(ProcessRecord app) { 16782 try { 16783 app.lastRequestedGc = SystemClock.uptimeMillis(); 16784 if (app.thread != null) { 16785 if (app.reportLowMemory) { 16786 app.reportLowMemory = false; 16787 app.thread.scheduleLowMemory(); 16788 } else { 16789 app.thread.processInBackground(); 16790 } 16791 } 16792 } catch (Exception e) { 16793 // whatever. 16794 } 16795 } 16796 16797 /** 16798 * Returns true if things are idle enough to perform GCs. 16799 */ 16800 private final boolean canGcNowLocked() { 16801 boolean processingBroadcasts = false; 16802 for (BroadcastQueue q : mBroadcastQueues) { 16803 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16804 processingBroadcasts = true; 16805 } 16806 } 16807 return !processingBroadcasts 16808 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16809 } 16810 16811 /** 16812 * Perform GCs on all processes that are waiting for it, but only 16813 * if things are idle. 16814 */ 16815 final void performAppGcsLocked() { 16816 final int N = mProcessesToGc.size(); 16817 if (N <= 0) { 16818 return; 16819 } 16820 if (canGcNowLocked()) { 16821 while (mProcessesToGc.size() > 0) { 16822 ProcessRecord proc = mProcessesToGc.remove(0); 16823 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16824 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16825 <= SystemClock.uptimeMillis()) { 16826 // To avoid spamming the system, we will GC processes one 16827 // at a time, waiting a few seconds between each. 16828 performAppGcLocked(proc); 16829 scheduleAppGcsLocked(); 16830 return; 16831 } else { 16832 // It hasn't been long enough since we last GCed this 16833 // process... put it in the list to wait for its time. 16834 addProcessToGcListLocked(proc); 16835 break; 16836 } 16837 } 16838 } 16839 16840 scheduleAppGcsLocked(); 16841 } 16842 } 16843 16844 /** 16845 * If all looks good, perform GCs on all processes waiting for them. 16846 */ 16847 final void performAppGcsIfAppropriateLocked() { 16848 if (canGcNowLocked()) { 16849 performAppGcsLocked(); 16850 return; 16851 } 16852 // Still not idle, wait some more. 16853 scheduleAppGcsLocked(); 16854 } 16855 16856 /** 16857 * Schedule the execution of all pending app GCs. 16858 */ 16859 final void scheduleAppGcsLocked() { 16860 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16861 16862 if (mProcessesToGc.size() > 0) { 16863 // Schedule a GC for the time to the next process. 16864 ProcessRecord proc = mProcessesToGc.get(0); 16865 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16866 16867 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16868 long now = SystemClock.uptimeMillis(); 16869 if (when < (now+GC_TIMEOUT)) { 16870 when = now + GC_TIMEOUT; 16871 } 16872 mHandler.sendMessageAtTime(msg, when); 16873 } 16874 } 16875 16876 /** 16877 * Add a process to the array of processes waiting to be GCed. Keeps the 16878 * list in sorted order by the last GC time. The process can't already be 16879 * on the list. 16880 */ 16881 final void addProcessToGcListLocked(ProcessRecord proc) { 16882 boolean added = false; 16883 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16884 if (mProcessesToGc.get(i).lastRequestedGc < 16885 proc.lastRequestedGc) { 16886 added = true; 16887 mProcessesToGc.add(i+1, proc); 16888 break; 16889 } 16890 } 16891 if (!added) { 16892 mProcessesToGc.add(0, proc); 16893 } 16894 } 16895 16896 /** 16897 * Set up to ask a process to GC itself. This will either do it 16898 * immediately, or put it on the list of processes to gc the next 16899 * time things are idle. 16900 */ 16901 final void scheduleAppGcLocked(ProcessRecord app) { 16902 long now = SystemClock.uptimeMillis(); 16903 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16904 return; 16905 } 16906 if (!mProcessesToGc.contains(app)) { 16907 addProcessToGcListLocked(app); 16908 scheduleAppGcsLocked(); 16909 } 16910 } 16911 16912 final void checkExcessivePowerUsageLocked(boolean doKills) { 16913 updateCpuStatsNow(); 16914 16915 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16916 boolean doWakeKills = doKills; 16917 boolean doCpuKills = doKills; 16918 if (mLastPowerCheckRealtime == 0) { 16919 doWakeKills = false; 16920 } 16921 if (mLastPowerCheckUptime == 0) { 16922 doCpuKills = false; 16923 } 16924 if (stats.isScreenOn()) { 16925 doWakeKills = false; 16926 } 16927 final long curRealtime = SystemClock.elapsedRealtime(); 16928 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16929 final long curUptime = SystemClock.uptimeMillis(); 16930 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16931 mLastPowerCheckRealtime = curRealtime; 16932 mLastPowerCheckUptime = curUptime; 16933 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16934 doWakeKills = false; 16935 } 16936 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16937 doCpuKills = false; 16938 } 16939 int i = mLruProcesses.size(); 16940 while (i > 0) { 16941 i--; 16942 ProcessRecord app = mLruProcesses.get(i); 16943 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16944 long wtime; 16945 synchronized (stats) { 16946 wtime = stats.getProcessWakeTime(app.info.uid, 16947 app.pid, curRealtime); 16948 } 16949 long wtimeUsed = wtime - app.lastWakeTime; 16950 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16951 if (DEBUG_POWER) { 16952 StringBuilder sb = new StringBuilder(128); 16953 sb.append("Wake for "); 16954 app.toShortString(sb); 16955 sb.append(": over "); 16956 TimeUtils.formatDuration(realtimeSince, sb); 16957 sb.append(" used "); 16958 TimeUtils.formatDuration(wtimeUsed, sb); 16959 sb.append(" ("); 16960 sb.append((wtimeUsed*100)/realtimeSince); 16961 sb.append("%)"); 16962 Slog.i(TAG, sb.toString()); 16963 sb.setLength(0); 16964 sb.append("CPU for "); 16965 app.toShortString(sb); 16966 sb.append(": over "); 16967 TimeUtils.formatDuration(uptimeSince, sb); 16968 sb.append(" used "); 16969 TimeUtils.formatDuration(cputimeUsed, sb); 16970 sb.append(" ("); 16971 sb.append((cputimeUsed*100)/uptimeSince); 16972 sb.append("%)"); 16973 Slog.i(TAG, sb.toString()); 16974 } 16975 // If a process has held a wake lock for more 16976 // than 50% of the time during this period, 16977 // that sounds bad. Kill! 16978 if (doWakeKills && realtimeSince > 0 16979 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16980 synchronized (stats) { 16981 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16982 realtimeSince, wtimeUsed); 16983 } 16984 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16985 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16986 } else if (doCpuKills && uptimeSince > 0 16987 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16988 synchronized (stats) { 16989 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16990 uptimeSince, cputimeUsed); 16991 } 16992 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 16993 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16994 } else { 16995 app.lastWakeTime = wtime; 16996 app.lastCpuTime = app.curCpuTime; 16997 } 16998 } 16999 } 17000 } 17001 17002 private final boolean applyOomAdjLocked(ProcessRecord app, 17003 ProcessRecord TOP_APP, boolean doingAll, long now) { 17004 boolean success = true; 17005 17006 if (app.curRawAdj != app.setRawAdj) { 17007 app.setRawAdj = app.curRawAdj; 17008 } 17009 17010 int changes = 0; 17011 17012 if (app.curAdj != app.setAdj) { 17013 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17014 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17015 TAG, "Set " + app.pid + " " + app.processName + 17016 " adj " + app.curAdj + ": " + app.adjType); 17017 app.setAdj = app.curAdj; 17018 } 17019 17020 if (app.setSchedGroup != app.curSchedGroup) { 17021 app.setSchedGroup = app.curSchedGroup; 17022 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17023 "Setting process group of " + app.processName 17024 + " to " + app.curSchedGroup); 17025 if (app.waitingToKill != null && 17026 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17027 app.kill(app.waitingToKill, true); 17028 success = false; 17029 } else { 17030 if (true) { 17031 long oldId = Binder.clearCallingIdentity(); 17032 try { 17033 Process.setProcessGroup(app.pid, app.curSchedGroup); 17034 } catch (Exception e) { 17035 Slog.w(TAG, "Failed setting process group of " + app.pid 17036 + " to " + app.curSchedGroup); 17037 e.printStackTrace(); 17038 } finally { 17039 Binder.restoreCallingIdentity(oldId); 17040 } 17041 } else { 17042 if (app.thread != null) { 17043 try { 17044 app.thread.setSchedulingGroup(app.curSchedGroup); 17045 } catch (RemoteException e) { 17046 } 17047 } 17048 } 17049 Process.setSwappiness(app.pid, 17050 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17051 } 17052 } 17053 if (app.repForegroundActivities != app.foregroundActivities) { 17054 app.repForegroundActivities = app.foregroundActivities; 17055 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17056 } 17057 if (app.repProcState != app.curProcState) { 17058 app.repProcState = app.curProcState; 17059 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17060 if (app.thread != null) { 17061 try { 17062 if (false) { 17063 //RuntimeException h = new RuntimeException("here"); 17064 Slog.i(TAG, "Sending new process state " + app.repProcState 17065 + " to " + app /*, h*/); 17066 } 17067 app.thread.setProcessState(app.repProcState); 17068 } catch (RemoteException e) { 17069 } 17070 } 17071 } 17072 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17073 app.setProcState)) { 17074 app.lastStateTime = now; 17075 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17076 isSleeping(), now); 17077 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17078 + ProcessList.makeProcStateString(app.setProcState) + " to " 17079 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17080 + (app.nextPssTime-now) + ": " + app); 17081 } else { 17082 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17083 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17084 requestPssLocked(app, app.setProcState); 17085 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17086 isSleeping(), now); 17087 } else if (false && DEBUG_PSS) { 17088 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17089 } 17090 } 17091 if (app.setProcState != app.curProcState) { 17092 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17093 "Proc state change of " + app.processName 17094 + " to " + app.curProcState); 17095 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17096 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17097 if (setImportant && !curImportant) { 17098 // This app is no longer something we consider important enough to allow to 17099 // use arbitrary amounts of battery power. Note 17100 // its current wake lock time to later know to kill it if 17101 // it is not behaving well. 17102 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17103 synchronized (stats) { 17104 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17105 app.pid, SystemClock.elapsedRealtime()); 17106 } 17107 app.lastCpuTime = app.curCpuTime; 17108 17109 } 17110 app.setProcState = app.curProcState; 17111 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17112 app.notCachedSinceIdle = false; 17113 } 17114 if (!doingAll) { 17115 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17116 } else { 17117 app.procStateChanged = true; 17118 } 17119 } 17120 17121 if (changes != 0) { 17122 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17123 int i = mPendingProcessChanges.size()-1; 17124 ProcessChangeItem item = null; 17125 while (i >= 0) { 17126 item = mPendingProcessChanges.get(i); 17127 if (item.pid == app.pid) { 17128 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17129 break; 17130 } 17131 i--; 17132 } 17133 if (i < 0) { 17134 // No existing item in pending changes; need a new one. 17135 final int NA = mAvailProcessChanges.size(); 17136 if (NA > 0) { 17137 item = mAvailProcessChanges.remove(NA-1); 17138 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17139 } else { 17140 item = new ProcessChangeItem(); 17141 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17142 } 17143 item.changes = 0; 17144 item.pid = app.pid; 17145 item.uid = app.info.uid; 17146 if (mPendingProcessChanges.size() == 0) { 17147 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17148 "*** Enqueueing dispatch processes changed!"); 17149 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17150 } 17151 mPendingProcessChanges.add(item); 17152 } 17153 item.changes |= changes; 17154 item.processState = app.repProcState; 17155 item.foregroundActivities = app.repForegroundActivities; 17156 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17157 + Integer.toHexString(System.identityHashCode(item)) 17158 + " " + app.toShortString() + ": changes=" + item.changes 17159 + " procState=" + item.processState 17160 + " foreground=" + item.foregroundActivities 17161 + " type=" + app.adjType + " source=" + app.adjSource 17162 + " target=" + app.adjTarget); 17163 } 17164 17165 return success; 17166 } 17167 17168 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17169 if (proc.thread != null) { 17170 if (proc.baseProcessTracker != null) { 17171 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17172 } 17173 if (proc.repProcState >= 0) { 17174 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17175 proc.repProcState); 17176 } 17177 } 17178 } 17179 17180 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17181 ProcessRecord TOP_APP, boolean doingAll, long now) { 17182 if (app.thread == null) { 17183 return false; 17184 } 17185 17186 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17187 17188 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17189 } 17190 17191 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17192 boolean oomAdj) { 17193 if (isForeground != proc.foregroundServices) { 17194 proc.foregroundServices = isForeground; 17195 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17196 proc.info.uid); 17197 if (isForeground) { 17198 if (curProcs == null) { 17199 curProcs = new ArrayList<ProcessRecord>(); 17200 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17201 } 17202 if (!curProcs.contains(proc)) { 17203 curProcs.add(proc); 17204 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17205 proc.info.packageName, proc.info.uid); 17206 } 17207 } else { 17208 if (curProcs != null) { 17209 if (curProcs.remove(proc)) { 17210 mBatteryStatsService.noteEvent( 17211 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17212 proc.info.packageName, proc.info.uid); 17213 if (curProcs.size() <= 0) { 17214 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17215 } 17216 } 17217 } 17218 } 17219 if (oomAdj) { 17220 updateOomAdjLocked(); 17221 } 17222 } 17223 } 17224 17225 private final ActivityRecord resumedAppLocked() { 17226 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17227 String pkg; 17228 int uid; 17229 if (act != null) { 17230 pkg = act.packageName; 17231 uid = act.info.applicationInfo.uid; 17232 } else { 17233 pkg = null; 17234 uid = -1; 17235 } 17236 // Has the UID or resumed package name changed? 17237 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17238 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17239 if (mCurResumedPackage != null) { 17240 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17241 mCurResumedPackage, mCurResumedUid); 17242 } 17243 mCurResumedPackage = pkg; 17244 mCurResumedUid = uid; 17245 if (mCurResumedPackage != null) { 17246 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17247 mCurResumedPackage, mCurResumedUid); 17248 } 17249 } 17250 return act; 17251 } 17252 17253 final boolean updateOomAdjLocked(ProcessRecord app) { 17254 final ActivityRecord TOP_ACT = resumedAppLocked(); 17255 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17256 final boolean wasCached = app.cached; 17257 17258 mAdjSeq++; 17259 17260 // This is the desired cached adjusment we want to tell it to use. 17261 // If our app is currently cached, we know it, and that is it. Otherwise, 17262 // we don't know it yet, and it needs to now be cached we will then 17263 // need to do a complete oom adj. 17264 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17265 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17266 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17267 SystemClock.uptimeMillis()); 17268 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17269 // Changed to/from cached state, so apps after it in the LRU 17270 // list may also be changed. 17271 updateOomAdjLocked(); 17272 } 17273 return success; 17274 } 17275 17276 final void updateOomAdjLocked() { 17277 final ActivityRecord TOP_ACT = resumedAppLocked(); 17278 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17279 final long now = SystemClock.uptimeMillis(); 17280 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17281 final int N = mLruProcesses.size(); 17282 17283 if (false) { 17284 RuntimeException e = new RuntimeException(); 17285 e.fillInStackTrace(); 17286 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17287 } 17288 17289 mAdjSeq++; 17290 mNewNumServiceProcs = 0; 17291 mNewNumAServiceProcs = 0; 17292 17293 final int emptyProcessLimit; 17294 final int cachedProcessLimit; 17295 if (mProcessLimit <= 0) { 17296 emptyProcessLimit = cachedProcessLimit = 0; 17297 } else if (mProcessLimit == 1) { 17298 emptyProcessLimit = 1; 17299 cachedProcessLimit = 0; 17300 } else { 17301 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17302 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17303 } 17304 17305 // Let's determine how many processes we have running vs. 17306 // how many slots we have for background processes; we may want 17307 // to put multiple processes in a slot of there are enough of 17308 // them. 17309 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17310 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17311 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17312 if (numEmptyProcs > cachedProcessLimit) { 17313 // If there are more empty processes than our limit on cached 17314 // processes, then use the cached process limit for the factor. 17315 // This ensures that the really old empty processes get pushed 17316 // down to the bottom, so if we are running low on memory we will 17317 // have a better chance at keeping around more cached processes 17318 // instead of a gazillion empty processes. 17319 numEmptyProcs = cachedProcessLimit; 17320 } 17321 int emptyFactor = numEmptyProcs/numSlots; 17322 if (emptyFactor < 1) emptyFactor = 1; 17323 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17324 if (cachedFactor < 1) cachedFactor = 1; 17325 int stepCached = 0; 17326 int stepEmpty = 0; 17327 int numCached = 0; 17328 int numEmpty = 0; 17329 int numTrimming = 0; 17330 17331 mNumNonCachedProcs = 0; 17332 mNumCachedHiddenProcs = 0; 17333 17334 // First update the OOM adjustment for each of the 17335 // application processes based on their current state. 17336 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17337 int nextCachedAdj = curCachedAdj+1; 17338 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17339 int nextEmptyAdj = curEmptyAdj+2; 17340 for (int i=N-1; i>=0; i--) { 17341 ProcessRecord app = mLruProcesses.get(i); 17342 if (!app.killedByAm && app.thread != null) { 17343 app.procStateChanged = false; 17344 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17345 17346 // If we haven't yet assigned the final cached adj 17347 // to the process, do that now. 17348 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17349 switch (app.curProcState) { 17350 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17351 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17352 // This process is a cached process holding activities... 17353 // assign it the next cached value for that type, and then 17354 // step that cached level. 17355 app.curRawAdj = curCachedAdj; 17356 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17357 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17358 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17359 + ")"); 17360 if (curCachedAdj != nextCachedAdj) { 17361 stepCached++; 17362 if (stepCached >= cachedFactor) { 17363 stepCached = 0; 17364 curCachedAdj = nextCachedAdj; 17365 nextCachedAdj += 2; 17366 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17367 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17368 } 17369 } 17370 } 17371 break; 17372 default: 17373 // For everything else, assign next empty cached process 17374 // level and bump that up. Note that this means that 17375 // long-running services that have dropped down to the 17376 // cached level will be treated as empty (since their process 17377 // state is still as a service), which is what we want. 17378 app.curRawAdj = curEmptyAdj; 17379 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17380 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17381 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17382 + ")"); 17383 if (curEmptyAdj != nextEmptyAdj) { 17384 stepEmpty++; 17385 if (stepEmpty >= emptyFactor) { 17386 stepEmpty = 0; 17387 curEmptyAdj = nextEmptyAdj; 17388 nextEmptyAdj += 2; 17389 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17390 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17391 } 17392 } 17393 } 17394 break; 17395 } 17396 } 17397 17398 applyOomAdjLocked(app, TOP_APP, true, now); 17399 17400 // Count the number of process types. 17401 switch (app.curProcState) { 17402 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17403 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17404 mNumCachedHiddenProcs++; 17405 numCached++; 17406 if (numCached > cachedProcessLimit) { 17407 app.kill("cached #" + numCached, true); 17408 } 17409 break; 17410 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17411 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17412 && app.lastActivityTime < oldTime) { 17413 app.kill("empty for " 17414 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17415 / 1000) + "s", true); 17416 } else { 17417 numEmpty++; 17418 if (numEmpty > emptyProcessLimit) { 17419 app.kill("empty #" + numEmpty, true); 17420 } 17421 } 17422 break; 17423 default: 17424 mNumNonCachedProcs++; 17425 break; 17426 } 17427 17428 if (app.isolated && app.services.size() <= 0) { 17429 // If this is an isolated process, and there are no 17430 // services running in it, then the process is no longer 17431 // needed. We agressively kill these because we can by 17432 // definition not re-use the same process again, and it is 17433 // good to avoid having whatever code was running in them 17434 // left sitting around after no longer needed. 17435 app.kill("isolated not needed", true); 17436 } 17437 17438 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17439 && !app.killedByAm) { 17440 numTrimming++; 17441 } 17442 } 17443 } 17444 17445 mNumServiceProcs = mNewNumServiceProcs; 17446 17447 // Now determine the memory trimming level of background processes. 17448 // Unfortunately we need to start at the back of the list to do this 17449 // properly. We only do this if the number of background apps we 17450 // are managing to keep around is less than half the maximum we desire; 17451 // if we are keeping a good number around, we'll let them use whatever 17452 // memory they want. 17453 final int numCachedAndEmpty = numCached + numEmpty; 17454 int memFactor; 17455 if (numCached <= ProcessList.TRIM_CACHED_APPS 17456 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17457 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17458 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17459 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17460 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17461 } else { 17462 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17463 } 17464 } else { 17465 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17466 } 17467 // We always allow the memory level to go up (better). We only allow it to go 17468 // down if we are in a state where that is allowed, *and* the total number of processes 17469 // has gone down since last time. 17470 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17471 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17472 + " last=" + mLastNumProcesses); 17473 if (memFactor > mLastMemoryLevel) { 17474 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17475 memFactor = mLastMemoryLevel; 17476 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17477 } 17478 } 17479 mLastMemoryLevel = memFactor; 17480 mLastNumProcesses = mLruProcesses.size(); 17481 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17482 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17483 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17484 if (mLowRamStartTime == 0) { 17485 mLowRamStartTime = now; 17486 } 17487 int step = 0; 17488 int fgTrimLevel; 17489 switch (memFactor) { 17490 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17491 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17492 break; 17493 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17494 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17495 break; 17496 default: 17497 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17498 break; 17499 } 17500 int factor = numTrimming/3; 17501 int minFactor = 2; 17502 if (mHomeProcess != null) minFactor++; 17503 if (mPreviousProcess != null) minFactor++; 17504 if (factor < minFactor) factor = minFactor; 17505 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17506 for (int i=N-1; i>=0; i--) { 17507 ProcessRecord app = mLruProcesses.get(i); 17508 if (allChanged || app.procStateChanged) { 17509 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17510 app.procStateChanged = false; 17511 } 17512 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17513 && !app.killedByAm) { 17514 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17515 try { 17516 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17517 "Trimming memory of " + app.processName 17518 + " to " + curLevel); 17519 app.thread.scheduleTrimMemory(curLevel); 17520 } catch (RemoteException e) { 17521 } 17522 if (false) { 17523 // For now we won't do this; our memory trimming seems 17524 // to be good enough at this point that destroying 17525 // activities causes more harm than good. 17526 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17527 && app != mHomeProcess && app != mPreviousProcess) { 17528 // Need to do this on its own message because the stack may not 17529 // be in a consistent state at this point. 17530 // For these apps we will also finish their activities 17531 // to help them free memory. 17532 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17533 } 17534 } 17535 } 17536 app.trimMemoryLevel = curLevel; 17537 step++; 17538 if (step >= factor) { 17539 step = 0; 17540 switch (curLevel) { 17541 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17542 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17543 break; 17544 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17545 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17546 break; 17547 } 17548 } 17549 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17550 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17551 && app.thread != null) { 17552 try { 17553 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17554 "Trimming memory of heavy-weight " + app.processName 17555 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17556 app.thread.scheduleTrimMemory( 17557 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17558 } catch (RemoteException e) { 17559 } 17560 } 17561 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17562 } else { 17563 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17564 || app.systemNoUi) && app.pendingUiClean) { 17565 // If this application is now in the background and it 17566 // had done UI, then give it the special trim level to 17567 // have it free UI resources. 17568 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17569 if (app.trimMemoryLevel < level && app.thread != null) { 17570 try { 17571 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17572 "Trimming memory of bg-ui " + app.processName 17573 + " to " + level); 17574 app.thread.scheduleTrimMemory(level); 17575 } catch (RemoteException e) { 17576 } 17577 } 17578 app.pendingUiClean = false; 17579 } 17580 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17581 try { 17582 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17583 "Trimming memory of fg " + app.processName 17584 + " to " + fgTrimLevel); 17585 app.thread.scheduleTrimMemory(fgTrimLevel); 17586 } catch (RemoteException e) { 17587 } 17588 } 17589 app.trimMemoryLevel = fgTrimLevel; 17590 } 17591 } 17592 } else { 17593 if (mLowRamStartTime != 0) { 17594 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17595 mLowRamStartTime = 0; 17596 } 17597 for (int i=N-1; i>=0; i--) { 17598 ProcessRecord app = mLruProcesses.get(i); 17599 if (allChanged || app.procStateChanged) { 17600 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17601 app.procStateChanged = false; 17602 } 17603 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17604 || app.systemNoUi) && app.pendingUiClean) { 17605 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17606 && app.thread != null) { 17607 try { 17608 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17609 "Trimming memory of ui hidden " + app.processName 17610 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17611 app.thread.scheduleTrimMemory( 17612 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17613 } catch (RemoteException e) { 17614 } 17615 } 17616 app.pendingUiClean = false; 17617 } 17618 app.trimMemoryLevel = 0; 17619 } 17620 } 17621 17622 if (mAlwaysFinishActivities) { 17623 // Need to do this on its own message because the stack may not 17624 // be in a consistent state at this point. 17625 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17626 } 17627 17628 if (allChanged) { 17629 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17630 } 17631 17632 if (mProcessStats.shouldWriteNowLocked(now)) { 17633 mHandler.post(new Runnable() { 17634 @Override public void run() { 17635 synchronized (ActivityManagerService.this) { 17636 mProcessStats.writeStateAsyncLocked(); 17637 } 17638 } 17639 }); 17640 } 17641 17642 if (DEBUG_OOM_ADJ) { 17643 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17644 } 17645 } 17646 17647 final void trimApplications() { 17648 synchronized (this) { 17649 int i; 17650 17651 // First remove any unused application processes whose package 17652 // has been removed. 17653 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17654 final ProcessRecord app = mRemovedProcesses.get(i); 17655 if (app.activities.size() == 0 17656 && app.curReceiver == null && app.services.size() == 0) { 17657 Slog.i( 17658 TAG, "Exiting empty application process " 17659 + app.processName + " (" 17660 + (app.thread != null ? app.thread.asBinder() : null) 17661 + ")\n"); 17662 if (app.pid > 0 && app.pid != MY_PID) { 17663 app.kill("empty", false); 17664 } else { 17665 try { 17666 app.thread.scheduleExit(); 17667 } catch (Exception e) { 17668 // Ignore exceptions. 17669 } 17670 } 17671 cleanUpApplicationRecordLocked(app, false, true, -1); 17672 mRemovedProcesses.remove(i); 17673 17674 if (app.persistent) { 17675 addAppLocked(app.info, false, null /* ABI override */); 17676 } 17677 } 17678 } 17679 17680 // Now update the oom adj for all processes. 17681 updateOomAdjLocked(); 17682 } 17683 } 17684 17685 /** This method sends the specified signal to each of the persistent apps */ 17686 public void signalPersistentProcesses(int sig) throws RemoteException { 17687 if (sig != Process.SIGNAL_USR1) { 17688 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17689 } 17690 17691 synchronized (this) { 17692 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17693 != PackageManager.PERMISSION_GRANTED) { 17694 throw new SecurityException("Requires permission " 17695 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17696 } 17697 17698 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17699 ProcessRecord r = mLruProcesses.get(i); 17700 if (r.thread != null && r.persistent) { 17701 Process.sendSignal(r.pid, sig); 17702 } 17703 } 17704 } 17705 } 17706 17707 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17708 if (proc == null || proc == mProfileProc) { 17709 proc = mProfileProc; 17710 profileType = mProfileType; 17711 clearProfilerLocked(); 17712 } 17713 if (proc == null) { 17714 return; 17715 } 17716 try { 17717 proc.thread.profilerControl(false, null, profileType); 17718 } catch (RemoteException e) { 17719 throw new IllegalStateException("Process disappeared"); 17720 } 17721 } 17722 17723 private void clearProfilerLocked() { 17724 if (mProfileFd != null) { 17725 try { 17726 mProfileFd.close(); 17727 } catch (IOException e) { 17728 } 17729 } 17730 mProfileApp = null; 17731 mProfileProc = null; 17732 mProfileFile = null; 17733 mProfileType = 0; 17734 mAutoStopProfiler = false; 17735 mSamplingInterval = 0; 17736 } 17737 17738 public boolean profileControl(String process, int userId, boolean start, 17739 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17740 17741 try { 17742 synchronized (this) { 17743 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17744 // its own permission. 17745 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17746 != PackageManager.PERMISSION_GRANTED) { 17747 throw new SecurityException("Requires permission " 17748 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17749 } 17750 17751 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17752 throw new IllegalArgumentException("null profile info or fd"); 17753 } 17754 17755 ProcessRecord proc = null; 17756 if (process != null) { 17757 proc = findProcessLocked(process, userId, "profileControl"); 17758 } 17759 17760 if (start && (proc == null || proc.thread == null)) { 17761 throw new IllegalArgumentException("Unknown process: " + process); 17762 } 17763 17764 if (start) { 17765 stopProfilerLocked(null, 0); 17766 setProfileApp(proc.info, proc.processName, profilerInfo); 17767 mProfileProc = proc; 17768 mProfileType = profileType; 17769 ParcelFileDescriptor fd = profilerInfo.profileFd; 17770 try { 17771 fd = fd.dup(); 17772 } catch (IOException e) { 17773 fd = null; 17774 } 17775 profilerInfo.profileFd = fd; 17776 proc.thread.profilerControl(start, profilerInfo, profileType); 17777 fd = null; 17778 mProfileFd = null; 17779 } else { 17780 stopProfilerLocked(proc, profileType); 17781 if (profilerInfo != null && profilerInfo.profileFd != null) { 17782 try { 17783 profilerInfo.profileFd.close(); 17784 } catch (IOException e) { 17785 } 17786 } 17787 } 17788 17789 return true; 17790 } 17791 } catch (RemoteException e) { 17792 throw new IllegalStateException("Process disappeared"); 17793 } finally { 17794 if (profilerInfo != null && profilerInfo.profileFd != null) { 17795 try { 17796 profilerInfo.profileFd.close(); 17797 } catch (IOException e) { 17798 } 17799 } 17800 } 17801 } 17802 17803 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17804 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17805 userId, true, ALLOW_FULL_ONLY, callName, null); 17806 ProcessRecord proc = null; 17807 try { 17808 int pid = Integer.parseInt(process); 17809 synchronized (mPidsSelfLocked) { 17810 proc = mPidsSelfLocked.get(pid); 17811 } 17812 } catch (NumberFormatException e) { 17813 } 17814 17815 if (proc == null) { 17816 ArrayMap<String, SparseArray<ProcessRecord>> all 17817 = mProcessNames.getMap(); 17818 SparseArray<ProcessRecord> procs = all.get(process); 17819 if (procs != null && procs.size() > 0) { 17820 proc = procs.valueAt(0); 17821 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17822 for (int i=1; i<procs.size(); i++) { 17823 ProcessRecord thisProc = procs.valueAt(i); 17824 if (thisProc.userId == userId) { 17825 proc = thisProc; 17826 break; 17827 } 17828 } 17829 } 17830 } 17831 } 17832 17833 return proc; 17834 } 17835 17836 public boolean dumpHeap(String process, int userId, boolean managed, 17837 String path, ParcelFileDescriptor fd) throws RemoteException { 17838 17839 try { 17840 synchronized (this) { 17841 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17842 // its own permission (same as profileControl). 17843 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17844 != PackageManager.PERMISSION_GRANTED) { 17845 throw new SecurityException("Requires permission " 17846 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17847 } 17848 17849 if (fd == null) { 17850 throw new IllegalArgumentException("null fd"); 17851 } 17852 17853 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17854 if (proc == null || proc.thread == null) { 17855 throw new IllegalArgumentException("Unknown process: " + process); 17856 } 17857 17858 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17859 if (!isDebuggable) { 17860 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17861 throw new SecurityException("Process not debuggable: " + proc); 17862 } 17863 } 17864 17865 proc.thread.dumpHeap(managed, path, fd); 17866 fd = null; 17867 return true; 17868 } 17869 } catch (RemoteException e) { 17870 throw new IllegalStateException("Process disappeared"); 17871 } finally { 17872 if (fd != null) { 17873 try { 17874 fd.close(); 17875 } catch (IOException e) { 17876 } 17877 } 17878 } 17879 } 17880 17881 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17882 public void monitor() { 17883 synchronized (this) { } 17884 } 17885 17886 void onCoreSettingsChange(Bundle settings) { 17887 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17888 ProcessRecord processRecord = mLruProcesses.get(i); 17889 try { 17890 if (processRecord.thread != null) { 17891 processRecord.thread.setCoreSettings(settings); 17892 } 17893 } catch (RemoteException re) { 17894 /* ignore */ 17895 } 17896 } 17897 } 17898 17899 // Multi-user methods 17900 17901 /** 17902 * Start user, if its not already running, but don't bring it to foreground. 17903 */ 17904 @Override 17905 public boolean startUserInBackground(final int userId) { 17906 return startUser(userId, /* foreground */ false); 17907 } 17908 17909 /** 17910 * Start user, if its not already running, and bring it to foreground. 17911 */ 17912 boolean startUserInForeground(final int userId, Dialog dlg) { 17913 boolean result = startUser(userId, /* foreground */ true); 17914 dlg.dismiss(); 17915 return result; 17916 } 17917 17918 /** 17919 * Refreshes the list of users related to the current user when either a 17920 * user switch happens or when a new related user is started in the 17921 * background. 17922 */ 17923 private void updateCurrentProfileIdsLocked() { 17924 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17925 mCurrentUserId, false /* enabledOnly */); 17926 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17927 for (int i = 0; i < currentProfileIds.length; i++) { 17928 currentProfileIds[i] = profiles.get(i).id; 17929 } 17930 mCurrentProfileIds = currentProfileIds; 17931 17932 synchronized (mUserProfileGroupIdsSelfLocked) { 17933 mUserProfileGroupIdsSelfLocked.clear(); 17934 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17935 for (int i = 0; i < users.size(); i++) { 17936 UserInfo user = users.get(i); 17937 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17938 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17939 } 17940 } 17941 } 17942 } 17943 17944 private Set getProfileIdsLocked(int userId) { 17945 Set userIds = new HashSet<Integer>(); 17946 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17947 userId, false /* enabledOnly */); 17948 for (UserInfo user : profiles) { 17949 userIds.add(Integer.valueOf(user.id)); 17950 } 17951 return userIds; 17952 } 17953 17954 @Override 17955 public boolean switchUser(final int userId) { 17956 String userName; 17957 synchronized (this) { 17958 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17959 if (userInfo == null) { 17960 Slog.w(TAG, "No user info for user #" + userId); 17961 return false; 17962 } 17963 if (userInfo.isManagedProfile()) { 17964 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17965 return false; 17966 } 17967 userName = userInfo.name; 17968 mTargetUserId = userId; 17969 } 17970 mHandler.removeMessages(START_USER_SWITCH_MSG); 17971 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17972 return true; 17973 } 17974 17975 private void showUserSwitchDialog(int userId, String userName) { 17976 // The dialog will show and then initiate the user switch by calling startUserInForeground 17977 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17978 true /* above system */); 17979 d.show(); 17980 } 17981 17982 private boolean startUser(final int userId, final boolean foreground) { 17983 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17984 != PackageManager.PERMISSION_GRANTED) { 17985 String msg = "Permission Denial: switchUser() from pid=" 17986 + Binder.getCallingPid() 17987 + ", uid=" + Binder.getCallingUid() 17988 + " requires " + INTERACT_ACROSS_USERS_FULL; 17989 Slog.w(TAG, msg); 17990 throw new SecurityException(msg); 17991 } 17992 17993 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17994 17995 final long ident = Binder.clearCallingIdentity(); 17996 try { 17997 synchronized (this) { 17998 final int oldUserId = mCurrentUserId; 17999 if (oldUserId == userId) { 18000 return true; 18001 } 18002 18003 mStackSupervisor.setLockTaskModeLocked(null, false); 18004 18005 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18006 if (userInfo == null) { 18007 Slog.w(TAG, "No user info for user #" + userId); 18008 return false; 18009 } 18010 if (foreground && userInfo.isManagedProfile()) { 18011 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18012 return false; 18013 } 18014 18015 if (foreground) { 18016 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18017 R.anim.screen_user_enter); 18018 } 18019 18020 boolean needStart = false; 18021 18022 // If the user we are switching to is not currently started, then 18023 // we need to start it now. 18024 if (mStartedUsers.get(userId) == null) { 18025 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18026 updateStartedUserArrayLocked(); 18027 needStart = true; 18028 } 18029 18030 final Integer userIdInt = Integer.valueOf(userId); 18031 mUserLru.remove(userIdInt); 18032 mUserLru.add(userIdInt); 18033 18034 if (foreground) { 18035 mCurrentUserId = userId; 18036 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18037 updateCurrentProfileIdsLocked(); 18038 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18039 // Once the internal notion of the active user has switched, we lock the device 18040 // with the option to show the user switcher on the keyguard. 18041 mWindowManager.lockNow(null); 18042 } else { 18043 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18044 updateCurrentProfileIdsLocked(); 18045 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18046 mUserLru.remove(currentUserIdInt); 18047 mUserLru.add(currentUserIdInt); 18048 } 18049 18050 final UserStartedState uss = mStartedUsers.get(userId); 18051 18052 // Make sure user is in the started state. If it is currently 18053 // stopping, we need to knock that off. 18054 if (uss.mState == UserStartedState.STATE_STOPPING) { 18055 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18056 // so we can just fairly silently bring the user back from 18057 // the almost-dead. 18058 uss.mState = UserStartedState.STATE_RUNNING; 18059 updateStartedUserArrayLocked(); 18060 needStart = true; 18061 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18062 // This means ACTION_SHUTDOWN has been sent, so we will 18063 // need to treat this as a new boot of the user. 18064 uss.mState = UserStartedState.STATE_BOOTING; 18065 updateStartedUserArrayLocked(); 18066 needStart = true; 18067 } 18068 18069 if (uss.mState == UserStartedState.STATE_BOOTING) { 18070 // Booting up a new user, need to tell system services about it. 18071 // Note that this is on the same handler as scheduling of broadcasts, 18072 // which is important because it needs to go first. 18073 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18074 } 18075 18076 if (foreground) { 18077 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18078 oldUserId)); 18079 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18080 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18081 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18082 oldUserId, userId, uss)); 18083 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18084 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18085 } 18086 18087 if (needStart) { 18088 // Send USER_STARTED broadcast 18089 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18090 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18091 | Intent.FLAG_RECEIVER_FOREGROUND); 18092 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18093 broadcastIntentLocked(null, null, intent, 18094 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18095 false, false, MY_PID, Process.SYSTEM_UID, userId); 18096 } 18097 18098 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18099 if (userId != UserHandle.USER_OWNER) { 18100 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18101 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18102 broadcastIntentLocked(null, null, intent, null, 18103 new IIntentReceiver.Stub() { 18104 public void performReceive(Intent intent, int resultCode, 18105 String data, Bundle extras, boolean ordered, 18106 boolean sticky, int sendingUser) { 18107 onUserInitialized(uss, foreground, oldUserId, userId); 18108 } 18109 }, 0, null, null, null, AppOpsManager.OP_NONE, 18110 true, false, MY_PID, Process.SYSTEM_UID, 18111 userId); 18112 uss.initializing = true; 18113 } else { 18114 getUserManagerLocked().makeInitialized(userInfo.id); 18115 } 18116 } 18117 18118 if (foreground) { 18119 if (!uss.initializing) { 18120 moveUserToForeground(uss, oldUserId, userId); 18121 } 18122 } else { 18123 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18124 } 18125 18126 if (needStart) { 18127 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18128 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18129 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18130 broadcastIntentLocked(null, null, intent, 18131 null, new IIntentReceiver.Stub() { 18132 @Override 18133 public void performReceive(Intent intent, int resultCode, String data, 18134 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18135 throws RemoteException { 18136 } 18137 }, 0, null, null, 18138 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18139 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18140 } 18141 } 18142 } finally { 18143 Binder.restoreCallingIdentity(ident); 18144 } 18145 18146 return true; 18147 } 18148 18149 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18150 long ident = Binder.clearCallingIdentity(); 18151 try { 18152 Intent intent; 18153 if (oldUserId >= 0) { 18154 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18155 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18156 int count = profiles.size(); 18157 for (int i = 0; i < count; i++) { 18158 int profileUserId = profiles.get(i).id; 18159 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18160 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18161 | Intent.FLAG_RECEIVER_FOREGROUND); 18162 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18163 broadcastIntentLocked(null, null, intent, 18164 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18165 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18166 } 18167 } 18168 if (newUserId >= 0) { 18169 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18170 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18171 int count = profiles.size(); 18172 for (int i = 0; i < count; i++) { 18173 int profileUserId = profiles.get(i).id; 18174 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18175 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18176 | Intent.FLAG_RECEIVER_FOREGROUND); 18177 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18178 broadcastIntentLocked(null, null, intent, 18179 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18180 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18181 } 18182 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18183 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18184 | Intent.FLAG_RECEIVER_FOREGROUND); 18185 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18186 broadcastIntentLocked(null, null, intent, 18187 null, null, 0, null, null, 18188 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18189 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18190 } 18191 } finally { 18192 Binder.restoreCallingIdentity(ident); 18193 } 18194 } 18195 18196 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18197 final int newUserId) { 18198 final int N = mUserSwitchObservers.beginBroadcast(); 18199 if (N > 0) { 18200 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18201 int mCount = 0; 18202 @Override 18203 public void sendResult(Bundle data) throws RemoteException { 18204 synchronized (ActivityManagerService.this) { 18205 if (mCurUserSwitchCallback == this) { 18206 mCount++; 18207 if (mCount == N) { 18208 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18209 } 18210 } 18211 } 18212 } 18213 }; 18214 synchronized (this) { 18215 uss.switching = true; 18216 mCurUserSwitchCallback = callback; 18217 } 18218 for (int i=0; i<N; i++) { 18219 try { 18220 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18221 newUserId, callback); 18222 } catch (RemoteException e) { 18223 } 18224 } 18225 } else { 18226 synchronized (this) { 18227 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18228 } 18229 } 18230 mUserSwitchObservers.finishBroadcast(); 18231 } 18232 18233 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18234 synchronized (this) { 18235 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18236 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18237 } 18238 } 18239 18240 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18241 mCurUserSwitchCallback = null; 18242 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18243 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18244 oldUserId, newUserId, uss)); 18245 } 18246 18247 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18248 synchronized (this) { 18249 if (foreground) { 18250 moveUserToForeground(uss, oldUserId, newUserId); 18251 } 18252 } 18253 18254 completeSwitchAndInitalize(uss, newUserId, true, false); 18255 } 18256 18257 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18258 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18259 if (homeInFront) { 18260 startHomeActivityLocked(newUserId); 18261 } else { 18262 mStackSupervisor.resumeTopActivitiesLocked(); 18263 } 18264 EventLogTags.writeAmSwitchUser(newUserId); 18265 getUserManagerLocked().userForeground(newUserId); 18266 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18267 } 18268 18269 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18270 completeSwitchAndInitalize(uss, newUserId, false, true); 18271 } 18272 18273 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18274 boolean clearInitializing, boolean clearSwitching) { 18275 boolean unfrozen = false; 18276 synchronized (this) { 18277 if (clearInitializing) { 18278 uss.initializing = false; 18279 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18280 } 18281 if (clearSwitching) { 18282 uss.switching = false; 18283 } 18284 if (!uss.switching && !uss.initializing) { 18285 mWindowManager.stopFreezingScreen(); 18286 unfrozen = true; 18287 } 18288 } 18289 if (unfrozen) { 18290 final int N = mUserSwitchObservers.beginBroadcast(); 18291 for (int i=0; i<N; i++) { 18292 try { 18293 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18294 } catch (RemoteException e) { 18295 } 18296 } 18297 mUserSwitchObservers.finishBroadcast(); 18298 } 18299 } 18300 18301 void scheduleStartProfilesLocked() { 18302 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18303 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18304 DateUtils.SECOND_IN_MILLIS); 18305 } 18306 } 18307 18308 void startProfilesLocked() { 18309 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18310 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18311 mCurrentUserId, false /* enabledOnly */); 18312 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18313 for (UserInfo user : profiles) { 18314 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18315 && user.id != mCurrentUserId) { 18316 toStart.add(user); 18317 } 18318 } 18319 final int n = toStart.size(); 18320 int i = 0; 18321 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18322 startUserInBackground(toStart.get(i).id); 18323 } 18324 if (i < n) { 18325 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18326 } 18327 } 18328 18329 void finishUserBoot(UserStartedState uss) { 18330 synchronized (this) { 18331 if (uss.mState == UserStartedState.STATE_BOOTING 18332 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18333 uss.mState = UserStartedState.STATE_RUNNING; 18334 final int userId = uss.mHandle.getIdentifier(); 18335 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18336 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18337 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18338 broadcastIntentLocked(null, null, intent, 18339 null, null, 0, null, null, 18340 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18341 true, false, MY_PID, Process.SYSTEM_UID, userId); 18342 } 18343 } 18344 } 18345 18346 void finishUserSwitch(UserStartedState uss) { 18347 synchronized (this) { 18348 finishUserBoot(uss); 18349 18350 startProfilesLocked(); 18351 18352 int num = mUserLru.size(); 18353 int i = 0; 18354 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18355 Integer oldUserId = mUserLru.get(i); 18356 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18357 if (oldUss == null) { 18358 // Shouldn't happen, but be sane if it does. 18359 mUserLru.remove(i); 18360 num--; 18361 continue; 18362 } 18363 if (oldUss.mState == UserStartedState.STATE_STOPPING 18364 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18365 // This user is already stopping, doesn't count. 18366 num--; 18367 i++; 18368 continue; 18369 } 18370 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18371 // Owner and current can't be stopped, but count as running. 18372 i++; 18373 continue; 18374 } 18375 // This is a user to be stopped. 18376 stopUserLocked(oldUserId, null); 18377 num--; 18378 i++; 18379 } 18380 } 18381 } 18382 18383 @Override 18384 public int stopUser(final int userId, final IStopUserCallback callback) { 18385 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18386 != PackageManager.PERMISSION_GRANTED) { 18387 String msg = "Permission Denial: switchUser() from pid=" 18388 + Binder.getCallingPid() 18389 + ", uid=" + Binder.getCallingUid() 18390 + " requires " + INTERACT_ACROSS_USERS_FULL; 18391 Slog.w(TAG, msg); 18392 throw new SecurityException(msg); 18393 } 18394 if (userId <= 0) { 18395 throw new IllegalArgumentException("Can't stop primary user " + userId); 18396 } 18397 synchronized (this) { 18398 return stopUserLocked(userId, callback); 18399 } 18400 } 18401 18402 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18403 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18404 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18405 return ActivityManager.USER_OP_IS_CURRENT; 18406 } 18407 18408 final UserStartedState uss = mStartedUsers.get(userId); 18409 if (uss == null) { 18410 // User is not started, nothing to do... but we do need to 18411 // callback if requested. 18412 if (callback != null) { 18413 mHandler.post(new Runnable() { 18414 @Override 18415 public void run() { 18416 try { 18417 callback.userStopped(userId); 18418 } catch (RemoteException e) { 18419 } 18420 } 18421 }); 18422 } 18423 return ActivityManager.USER_OP_SUCCESS; 18424 } 18425 18426 if (callback != null) { 18427 uss.mStopCallbacks.add(callback); 18428 } 18429 18430 if (uss.mState != UserStartedState.STATE_STOPPING 18431 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18432 uss.mState = UserStartedState.STATE_STOPPING; 18433 updateStartedUserArrayLocked(); 18434 18435 long ident = Binder.clearCallingIdentity(); 18436 try { 18437 // We are going to broadcast ACTION_USER_STOPPING and then 18438 // once that is done send a final ACTION_SHUTDOWN and then 18439 // stop the user. 18440 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18441 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18442 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18443 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18444 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18445 // This is the result receiver for the final shutdown broadcast. 18446 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18447 @Override 18448 public void performReceive(Intent intent, int resultCode, String data, 18449 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18450 finishUserStop(uss); 18451 } 18452 }; 18453 // This is the result receiver for the initial stopping broadcast. 18454 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18455 @Override 18456 public void performReceive(Intent intent, int resultCode, String data, 18457 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18458 // On to the next. 18459 synchronized (ActivityManagerService.this) { 18460 if (uss.mState != UserStartedState.STATE_STOPPING) { 18461 // Whoops, we are being started back up. Abort, abort! 18462 return; 18463 } 18464 uss.mState = UserStartedState.STATE_SHUTDOWN; 18465 } 18466 mBatteryStatsService.noteEvent( 18467 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18468 Integer.toString(userId), userId); 18469 mSystemServiceManager.stopUser(userId); 18470 broadcastIntentLocked(null, null, shutdownIntent, 18471 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18472 true, false, MY_PID, Process.SYSTEM_UID, userId); 18473 } 18474 }; 18475 // Kick things off. 18476 broadcastIntentLocked(null, null, stoppingIntent, 18477 null, stoppingReceiver, 0, null, null, 18478 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18479 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18480 } finally { 18481 Binder.restoreCallingIdentity(ident); 18482 } 18483 } 18484 18485 return ActivityManager.USER_OP_SUCCESS; 18486 } 18487 18488 void finishUserStop(UserStartedState uss) { 18489 final int userId = uss.mHandle.getIdentifier(); 18490 boolean stopped; 18491 ArrayList<IStopUserCallback> callbacks; 18492 synchronized (this) { 18493 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18494 if (mStartedUsers.get(userId) != uss) { 18495 stopped = false; 18496 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18497 stopped = false; 18498 } else { 18499 stopped = true; 18500 // User can no longer run. 18501 mStartedUsers.remove(userId); 18502 mUserLru.remove(Integer.valueOf(userId)); 18503 updateStartedUserArrayLocked(); 18504 18505 // Clean up all state and processes associated with the user. 18506 // Kill all the processes for the user. 18507 forceStopUserLocked(userId, "finish user"); 18508 } 18509 18510 // Explicitly remove the old information in mRecentTasks. 18511 removeRecentTasksForUserLocked(userId); 18512 } 18513 18514 for (int i=0; i<callbacks.size(); i++) { 18515 try { 18516 if (stopped) callbacks.get(i).userStopped(userId); 18517 else callbacks.get(i).userStopAborted(userId); 18518 } catch (RemoteException e) { 18519 } 18520 } 18521 18522 if (stopped) { 18523 mSystemServiceManager.cleanupUser(userId); 18524 synchronized (this) { 18525 mStackSupervisor.removeUserLocked(userId); 18526 } 18527 } 18528 } 18529 18530 @Override 18531 public UserInfo getCurrentUser() { 18532 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18533 != PackageManager.PERMISSION_GRANTED) && ( 18534 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18535 != PackageManager.PERMISSION_GRANTED)) { 18536 String msg = "Permission Denial: getCurrentUser() from pid=" 18537 + Binder.getCallingPid() 18538 + ", uid=" + Binder.getCallingUid() 18539 + " requires " + INTERACT_ACROSS_USERS; 18540 Slog.w(TAG, msg); 18541 throw new SecurityException(msg); 18542 } 18543 synchronized (this) { 18544 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18545 return getUserManagerLocked().getUserInfo(userId); 18546 } 18547 } 18548 18549 int getCurrentUserIdLocked() { 18550 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18551 } 18552 18553 @Override 18554 public boolean isUserRunning(int userId, boolean orStopped) { 18555 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18556 != PackageManager.PERMISSION_GRANTED) { 18557 String msg = "Permission Denial: isUserRunning() from pid=" 18558 + Binder.getCallingPid() 18559 + ", uid=" + Binder.getCallingUid() 18560 + " requires " + INTERACT_ACROSS_USERS; 18561 Slog.w(TAG, msg); 18562 throw new SecurityException(msg); 18563 } 18564 synchronized (this) { 18565 return isUserRunningLocked(userId, orStopped); 18566 } 18567 } 18568 18569 boolean isUserRunningLocked(int userId, boolean orStopped) { 18570 UserStartedState state = mStartedUsers.get(userId); 18571 if (state == null) { 18572 return false; 18573 } 18574 if (orStopped) { 18575 return true; 18576 } 18577 return state.mState != UserStartedState.STATE_STOPPING 18578 && state.mState != UserStartedState.STATE_SHUTDOWN; 18579 } 18580 18581 @Override 18582 public int[] getRunningUserIds() { 18583 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18584 != PackageManager.PERMISSION_GRANTED) { 18585 String msg = "Permission Denial: isUserRunning() from pid=" 18586 + Binder.getCallingPid() 18587 + ", uid=" + Binder.getCallingUid() 18588 + " requires " + INTERACT_ACROSS_USERS; 18589 Slog.w(TAG, msg); 18590 throw new SecurityException(msg); 18591 } 18592 synchronized (this) { 18593 return mStartedUserArray; 18594 } 18595 } 18596 18597 private void updateStartedUserArrayLocked() { 18598 int num = 0; 18599 for (int i=0; i<mStartedUsers.size(); i++) { 18600 UserStartedState uss = mStartedUsers.valueAt(i); 18601 // This list does not include stopping users. 18602 if (uss.mState != UserStartedState.STATE_STOPPING 18603 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18604 num++; 18605 } 18606 } 18607 mStartedUserArray = new int[num]; 18608 num = 0; 18609 for (int i=0; i<mStartedUsers.size(); i++) { 18610 UserStartedState uss = mStartedUsers.valueAt(i); 18611 if (uss.mState != UserStartedState.STATE_STOPPING 18612 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18613 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18614 num++; 18615 } 18616 } 18617 } 18618 18619 @Override 18620 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18621 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18622 != PackageManager.PERMISSION_GRANTED) { 18623 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18624 + Binder.getCallingPid() 18625 + ", uid=" + Binder.getCallingUid() 18626 + " requires " + INTERACT_ACROSS_USERS_FULL; 18627 Slog.w(TAG, msg); 18628 throw new SecurityException(msg); 18629 } 18630 18631 mUserSwitchObservers.register(observer); 18632 } 18633 18634 @Override 18635 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18636 mUserSwitchObservers.unregister(observer); 18637 } 18638 18639 private boolean userExists(int userId) { 18640 if (userId == 0) { 18641 return true; 18642 } 18643 UserManagerService ums = getUserManagerLocked(); 18644 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18645 } 18646 18647 int[] getUsersLocked() { 18648 UserManagerService ums = getUserManagerLocked(); 18649 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18650 } 18651 18652 UserManagerService getUserManagerLocked() { 18653 if (mUserManager == null) { 18654 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18655 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18656 } 18657 return mUserManager; 18658 } 18659 18660 private int applyUserId(int uid, int userId) { 18661 return UserHandle.getUid(userId, uid); 18662 } 18663 18664 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18665 if (info == null) return null; 18666 ApplicationInfo newInfo = new ApplicationInfo(info); 18667 newInfo.uid = applyUserId(info.uid, userId); 18668 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18669 + info.packageName; 18670 return newInfo; 18671 } 18672 18673 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18674 if (aInfo == null 18675 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18676 return aInfo; 18677 } 18678 18679 ActivityInfo info = new ActivityInfo(aInfo); 18680 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18681 return info; 18682 } 18683 18684 private final class LocalService extends ActivityManagerInternal { 18685 @Override 18686 public void goingToSleep() { 18687 ActivityManagerService.this.goingToSleep(); 18688 } 18689 18690 @Override 18691 public void wakingUp() { 18692 ActivityManagerService.this.wakingUp(); 18693 } 18694 18695 @Override 18696 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18697 String processName, String abiOverride, int uid, Runnable crashHandler) { 18698 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18699 processName, abiOverride, uid, crashHandler); 18700 } 18701 } 18702 18703 /** 18704 * An implementation of IAppTask, that allows an app to manage its own tasks via 18705 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18706 * only the process that calls getAppTasks() can call the AppTask methods. 18707 */ 18708 class AppTaskImpl extends IAppTask.Stub { 18709 private int mTaskId; 18710 private int mCallingUid; 18711 18712 public AppTaskImpl(int taskId, int callingUid) { 18713 mTaskId = taskId; 18714 mCallingUid = callingUid; 18715 } 18716 18717 private void checkCaller() { 18718 if (mCallingUid != Binder.getCallingUid()) { 18719 throw new SecurityException("Caller " + mCallingUid 18720 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18721 } 18722 } 18723 18724 @Override 18725 public void finishAndRemoveTask() { 18726 checkCaller(); 18727 18728 synchronized (ActivityManagerService.this) { 18729 long origId = Binder.clearCallingIdentity(); 18730 try { 18731 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18732 if (tr == null) { 18733 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18734 } 18735 // Only kill the process if we are not a new document 18736 int flags = tr.getBaseIntent().getFlags(); 18737 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18738 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18739 removeTaskByIdLocked(mTaskId, 18740 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18741 } finally { 18742 Binder.restoreCallingIdentity(origId); 18743 } 18744 } 18745 } 18746 18747 @Override 18748 public ActivityManager.RecentTaskInfo getTaskInfo() { 18749 checkCaller(); 18750 18751 synchronized (ActivityManagerService.this) { 18752 long origId = Binder.clearCallingIdentity(); 18753 try { 18754 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18755 if (tr == null) { 18756 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18757 } 18758 return createRecentTaskInfoFromTaskRecord(tr); 18759 } finally { 18760 Binder.restoreCallingIdentity(origId); 18761 } 18762 } 18763 } 18764 18765 @Override 18766 public void moveToFront() { 18767 checkCaller(); 18768 18769 final TaskRecord tr; 18770 synchronized (ActivityManagerService.this) { 18771 tr = recentTaskForIdLocked(mTaskId); 18772 if (tr == null) { 18773 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18774 } 18775 if (tr.getRootActivity() != null) { 18776 long origId = Binder.clearCallingIdentity(); 18777 try { 18778 moveTaskToFrontLocked(tr.taskId, 0, null); 18779 return; 18780 } finally { 18781 Binder.restoreCallingIdentity(origId); 18782 } 18783 } 18784 } 18785 18786 startActivityFromRecentsInner(tr.taskId, null); 18787 } 18788 18789 @Override 18790 public int startActivity(IBinder whoThread, String callingPackage, 18791 Intent intent, String resolvedType, Bundle options) { 18792 checkCaller(); 18793 18794 int callingUser = UserHandle.getCallingUserId(); 18795 TaskRecord tr; 18796 IApplicationThread appThread; 18797 synchronized (ActivityManagerService.this) { 18798 tr = recentTaskForIdLocked(mTaskId); 18799 if (tr == null) { 18800 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18801 } 18802 appThread = ApplicationThreadNative.asInterface(whoThread); 18803 if (appThread == null) { 18804 throw new IllegalArgumentException("Bad app thread " + appThread); 18805 } 18806 } 18807 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18808 resolvedType, null, null, null, null, 0, 0, null, null, 18809 null, options, callingUser, null, tr); 18810 } 18811 18812 @Override 18813 public void setExcludeFromRecents(boolean exclude) { 18814 checkCaller(); 18815 18816 synchronized (ActivityManagerService.this) { 18817 long origId = Binder.clearCallingIdentity(); 18818 try { 18819 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18820 if (tr == null) { 18821 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18822 } 18823 Intent intent = tr.getBaseIntent(); 18824 if (exclude) { 18825 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18826 } else { 18827 intent.setFlags(intent.getFlags() 18828 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18829 } 18830 } finally { 18831 Binder.restoreCallingIdentity(origId); 18832 } 18833 } 18834 } 18835 } 18836} 18837