ActivityManagerService.java revision 852975d5377bfe5f4abc9d2a28e301aa2fa99994
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.admin.DevicePolicyManager; 41import android.app.usage.UsageEvents; 42import android.app.usage.UsageStatsManagerInternal; 43import android.appwidget.AppWidgetManager; 44import android.content.res.Resources; 45import android.graphics.Bitmap; 46import android.graphics.Point; 47import android.graphics.Rect; 48import android.os.BatteryStats; 49import android.os.PersistableBundle; 50import android.service.voice.IVoiceInteractionSession; 51import android.util.ArrayMap; 52import android.util.ArraySet; 53import android.util.SparseIntArray; 54 55import com.android.internal.R; 56import com.android.internal.annotations.GuardedBy; 57import com.android.internal.app.IAppOpsService; 58import com.android.internal.app.IVoiceInteractor; 59import com.android.internal.app.ProcessMap; 60import com.android.internal.app.ProcessStats; 61import com.android.internal.content.PackageMonitor; 62import com.android.internal.os.BackgroundThread; 63import com.android.internal.os.BatteryStatsImpl; 64import com.android.internal.os.ProcessCpuTracker; 65import com.android.internal.os.TransferPipe; 66import com.android.internal.os.Zygote; 67import com.android.internal.util.FastPrintWriter; 68import com.android.internal.util.FastXmlSerializer; 69import com.android.internal.util.MemInfoReader; 70import com.android.internal.util.Preconditions; 71import com.android.server.AppOpsService; 72import com.android.server.AttributeCache; 73import com.android.server.IntentResolver; 74import com.android.server.LocalServices; 75import com.android.server.ServiceThread; 76import com.android.server.SystemService; 77import com.android.server.SystemServiceManager; 78import com.android.server.Watchdog; 79import com.android.server.am.ActivityStack.ActivityState; 80import com.android.server.firewall.IntentFirewall; 81import com.android.server.pm.UserManagerService; 82import com.android.server.wm.AppTransition; 83import com.android.server.wm.WindowManagerService; 84import com.google.android.collect.Lists; 85import com.google.android.collect.Maps; 86 87import libcore.io.IoUtils; 88 89import org.xmlpull.v1.XmlPullParser; 90import org.xmlpull.v1.XmlPullParserException; 91import org.xmlpull.v1.XmlSerializer; 92 93import android.app.Activity; 94import android.app.ActivityManager; 95import android.app.ActivityManager.RunningTaskInfo; 96import android.app.ActivityManager.StackInfo; 97import android.app.ActivityManagerInternal; 98import android.app.ActivityManagerNative; 99import android.app.ActivityOptions; 100import android.app.ActivityThread; 101import android.app.AlertDialog; 102import android.app.AppGlobals; 103import android.app.ApplicationErrorReport; 104import android.app.Dialog; 105import android.app.IActivityController; 106import android.app.IApplicationThread; 107import android.app.IInstrumentationWatcher; 108import android.app.INotificationManager; 109import android.app.IProcessObserver; 110import android.app.IServiceConnection; 111import android.app.IStopUserCallback; 112import android.app.IUiAutomationConnection; 113import android.app.IUserSwitchObserver; 114import android.app.Instrumentation; 115import android.app.Notification; 116import android.app.NotificationManager; 117import android.app.PendingIntent; 118import android.app.backup.IBackupManager; 119import android.content.ActivityNotFoundException; 120import android.content.BroadcastReceiver; 121import android.content.ClipData; 122import android.content.ComponentCallbacks2; 123import android.content.ComponentName; 124import android.content.ContentProvider; 125import android.content.ContentResolver; 126import android.content.Context; 127import android.content.DialogInterface; 128import android.content.IContentProvider; 129import android.content.IIntentReceiver; 130import android.content.IIntentSender; 131import android.content.Intent; 132import android.content.IntentFilter; 133import android.content.IntentSender; 134import android.content.pm.ActivityInfo; 135import android.content.pm.ApplicationInfo; 136import android.content.pm.ConfigurationInfo; 137import android.content.pm.IPackageDataObserver; 138import android.content.pm.IPackageManager; 139import android.content.pm.InstrumentationInfo; 140import android.content.pm.PackageInfo; 141import android.content.pm.PackageManager; 142import android.content.pm.ParceledListSlice; 143import android.content.pm.UserInfo; 144import android.content.pm.PackageManager.NameNotFoundException; 145import android.content.pm.PathPermission; 146import android.content.pm.ProviderInfo; 147import android.content.pm.ResolveInfo; 148import android.content.pm.ServiceInfo; 149import android.content.res.CompatibilityInfo; 150import android.content.res.Configuration; 151import android.net.Proxy; 152import android.net.ProxyInfo; 153import android.net.Uri; 154import android.os.Binder; 155import android.os.Build; 156import android.os.Bundle; 157import android.os.Debug; 158import android.os.DropBoxManager; 159import android.os.Environment; 160import android.os.FactoryTest; 161import android.os.FileObserver; 162import android.os.FileUtils; 163import android.os.Handler; 164import android.os.IBinder; 165import android.os.IPermissionController; 166import android.os.IRemoteCallback; 167import android.os.IUserManager; 168import android.os.Looper; 169import android.os.Message; 170import android.os.Parcel; 171import android.os.ParcelFileDescriptor; 172import android.os.Process; 173import android.os.RemoteCallbackList; 174import android.os.RemoteException; 175import android.os.SELinux; 176import android.os.ServiceManager; 177import android.os.StrictMode; 178import android.os.SystemClock; 179import android.os.SystemProperties; 180import android.os.UpdateLock; 181import android.os.UserHandle; 182import android.provider.Settings; 183import android.text.format.DateUtils; 184import android.text.format.Time; 185import android.util.AtomicFile; 186import android.util.EventLog; 187import android.util.Log; 188import android.util.Pair; 189import android.util.PrintWriterPrinter; 190import android.util.Slog; 191import android.util.SparseArray; 192import android.util.TimeUtils; 193import android.util.Xml; 194import android.view.Gravity; 195import android.view.LayoutInflater; 196import android.view.View; 197import android.view.WindowManager; 198 199import java.io.BufferedInputStream; 200import java.io.BufferedOutputStream; 201import java.io.DataInputStream; 202import java.io.DataOutputStream; 203import java.io.File; 204import java.io.FileDescriptor; 205import java.io.FileInputStream; 206import java.io.FileNotFoundException; 207import java.io.FileOutputStream; 208import java.io.IOException; 209import java.io.InputStreamReader; 210import java.io.PrintWriter; 211import java.io.StringWriter; 212import java.lang.ref.WeakReference; 213import java.util.ArrayList; 214import java.util.Arrays; 215import java.util.Collections; 216import java.util.Comparator; 217import java.util.HashMap; 218import java.util.HashSet; 219import java.util.Iterator; 220import java.util.List; 221import java.util.Locale; 222import java.util.Map; 223import java.util.Set; 224import java.util.concurrent.atomic.AtomicBoolean; 225import java.util.concurrent.atomic.AtomicLong; 226 227public final class ActivityManagerService extends ActivityManagerNative 228 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 229 230 private static final String USER_DATA_DIR = "/data/user/"; 231 // File that stores last updated system version and called preboot receivers 232 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 233 234 static final String TAG = "ActivityManager"; 235 static final String TAG_MU = "ActivityManagerServiceMU"; 236 static final boolean DEBUG = false; 237 static final boolean localLOGV = DEBUG; 238 static final boolean DEBUG_BACKUP = localLOGV || false; 239 static final boolean DEBUG_BROADCAST = localLOGV || false; 240 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 241 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 242 static final boolean DEBUG_CLEANUP = localLOGV || false; 243 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 244 static final boolean DEBUG_FOCUS = false; 245 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 246 static final boolean DEBUG_MU = localLOGV || false; 247 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 248 static final boolean DEBUG_LRU = localLOGV || false; 249 static final boolean DEBUG_PAUSE = localLOGV || false; 250 static final boolean DEBUG_POWER = localLOGV || false; 251 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 252 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 253 static final boolean DEBUG_PROCESSES = localLOGV || false; 254 static final boolean DEBUG_PROVIDER = localLOGV || false; 255 static final boolean DEBUG_RESULTS = localLOGV || false; 256 static final boolean DEBUG_SERVICE = localLOGV || false; 257 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 258 static final boolean DEBUG_STACK = localLOGV || false; 259 static final boolean DEBUG_SWITCH = localLOGV || false; 260 static final boolean DEBUG_TASKS = localLOGV || false; 261 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 262 static final boolean DEBUG_TRANSITION = localLOGV || false; 263 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 264 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 265 static final boolean DEBUG_VISBILITY = localLOGV || false; 266 static final boolean DEBUG_PSS = localLOGV || false; 267 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 268 static final boolean DEBUG_RECENTS = localLOGV || false; 269 static final boolean VALIDATE_TOKENS = false; 270 static final boolean SHOW_ACTIVITY_START_TIME = true; 271 272 // Control over CPU and battery monitoring. 273 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 274 static final boolean MONITOR_CPU_USAGE = true; 275 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 276 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 277 static final boolean MONITOR_THREAD_CPU_USAGE = false; 278 279 // The flags that are set for all calls we make to the package manager. 280 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 281 282 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 283 284 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 285 286 // Maximum number recent bitmaps to keep in memory. 287 static final int MAX_RECENT_BITMAPS = 5; 288 289 // Amount of time after a call to stopAppSwitches() during which we will 290 // prevent further untrusted switches from happening. 291 static final long APP_SWITCH_DELAY_TIME = 5*1000; 292 293 // How long we wait for a launched process to attach to the activity manager 294 // before we decide it's never going to come up for real. 295 static final int PROC_START_TIMEOUT = 10*1000; 296 297 // How long we wait for a launched process to attach to the activity manager 298 // before we decide it's never going to come up for real, when the process was 299 // started with a wrapper for instrumentation (such as Valgrind) because it 300 // could take much longer than usual. 301 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 302 303 // How long to wait after going idle before forcing apps to GC. 304 static final int GC_TIMEOUT = 5*1000; 305 306 // The minimum amount of time between successive GC requests for a process. 307 static final int GC_MIN_INTERVAL = 60*1000; 308 309 // The minimum amount of time between successive PSS requests for a process. 310 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 311 312 // The minimum amount of time between successive PSS requests for a process 313 // when the request is due to the memory state being lowered. 314 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 315 316 // The rate at which we check for apps using excessive power -- 15 mins. 317 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 318 319 // The minimum sample duration we will allow before deciding we have 320 // enough data on wake locks to start killing things. 321 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 322 323 // The minimum sample duration we will allow before deciding we have 324 // enough data on CPU usage to start killing things. 325 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 326 327 // How long we allow a receiver to run before giving up on it. 328 static final int BROADCAST_FG_TIMEOUT = 10*1000; 329 static final int BROADCAST_BG_TIMEOUT = 60*1000; 330 331 // How long we wait until we timeout on key dispatching. 332 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 333 334 // How long we wait until we timeout on key dispatching during instrumentation. 335 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 336 337 // Amount of time we wait for observers to handle a user switch before 338 // giving up on them and unfreezing the screen. 339 static final int USER_SWITCH_TIMEOUT = 2*1000; 340 341 // Maximum number of users we allow to be running at a time. 342 static final int MAX_RUNNING_USERS = 3; 343 344 // How long to wait in getAssistContextExtras for the activity and foreground services 345 // to respond with the result. 346 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 347 348 // Maximum number of persisted Uri grants a package is allowed 349 static final int MAX_PERSISTED_URI_GRANTS = 128; 350 351 static final int MY_PID = Process.myPid(); 352 353 static final String[] EMPTY_STRING_ARRAY = new String[0]; 354 355 // How many bytes to write into the dropbox log before truncating 356 static final int DROPBOX_MAX_SIZE = 256 * 1024; 357 358 // Access modes for handleIncomingUser. 359 static final int ALLOW_NON_FULL = 0; 360 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 361 static final int ALLOW_FULL_ONLY = 2; 362 363 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 364 365 /** All system services */ 366 SystemServiceManager mSystemServiceManager; 367 368 /** Run all ActivityStacks through this */ 369 ActivityStackSupervisor mStackSupervisor; 370 371 public IntentFirewall mIntentFirewall; 372 373 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 374 // default actuion automatically. Important for devices without direct input 375 // devices. 376 private boolean mShowDialogs = true; 377 378 BroadcastQueue mFgBroadcastQueue; 379 BroadcastQueue mBgBroadcastQueue; 380 // Convenient for easy iteration over the queues. Foreground is first 381 // so that dispatch of foreground broadcasts gets precedence. 382 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 383 384 BroadcastQueue broadcastQueueForIntent(Intent intent) { 385 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 386 if (DEBUG_BACKGROUND_BROADCAST) { 387 Slog.i(TAG, "Broadcast intent " + intent + " on " 388 + (isFg ? "foreground" : "background") 389 + " queue"); 390 } 391 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 392 } 393 394 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 395 for (BroadcastQueue queue : mBroadcastQueues) { 396 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 397 if (r != null) { 398 return r; 399 } 400 } 401 return null; 402 } 403 404 /** 405 * Activity we have told the window manager to have key focus. 406 */ 407 ActivityRecord mFocusedActivity = null; 408 409 /** 410 * List of intents that were used to start the most recent tasks. 411 */ 412 ArrayList<TaskRecord> mRecentTasks; 413 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 414 415 /** 416 * For addAppTask: cached of the last activity component that was added. 417 */ 418 ComponentName mLastAddedTaskComponent; 419 420 /** 421 * For addAppTask: cached of the last activity uid that was added. 422 */ 423 int mLastAddedTaskUid; 424 425 /** 426 * For addAppTask: cached of the last ActivityInfo that was added. 427 */ 428 ActivityInfo mLastAddedTaskActivity; 429 430 public class PendingAssistExtras extends Binder implements Runnable { 431 public final ActivityRecord activity; 432 public boolean haveResult = false; 433 public Bundle result = null; 434 public PendingAssistExtras(ActivityRecord _activity) { 435 activity = _activity; 436 } 437 @Override 438 public void run() { 439 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 440 synchronized (this) { 441 haveResult = true; 442 notifyAll(); 443 } 444 } 445 } 446 447 final ArrayList<PendingAssistExtras> mPendingAssistExtras 448 = new ArrayList<PendingAssistExtras>(); 449 450 /** 451 * Process management. 452 */ 453 final ProcessList mProcessList = new ProcessList(); 454 455 /** 456 * All of the applications we currently have running organized by name. 457 * The keys are strings of the application package name (as 458 * returned by the package manager), and the keys are ApplicationRecord 459 * objects. 460 */ 461 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 462 463 /** 464 * Tracking long-term execution of processes to look for abuse and other 465 * bad app behavior. 466 */ 467 final ProcessStatsService mProcessStats; 468 469 /** 470 * The currently running isolated processes. 471 */ 472 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 473 474 /** 475 * Counter for assigning isolated process uids, to avoid frequently reusing the 476 * same ones. 477 */ 478 int mNextIsolatedProcessUid = 0; 479 480 /** 481 * The currently running heavy-weight process, if any. 482 */ 483 ProcessRecord mHeavyWeightProcess = null; 484 485 /** 486 * The last time that various processes have crashed. 487 */ 488 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 489 490 /** 491 * Information about a process that is currently marked as bad. 492 */ 493 static final class BadProcessInfo { 494 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 495 this.time = time; 496 this.shortMsg = shortMsg; 497 this.longMsg = longMsg; 498 this.stack = stack; 499 } 500 501 final long time; 502 final String shortMsg; 503 final String longMsg; 504 final String stack; 505 } 506 507 /** 508 * Set of applications that we consider to be bad, and will reject 509 * incoming broadcasts from (which the user has no control over). 510 * Processes are added to this set when they have crashed twice within 511 * a minimum amount of time; they are removed from it when they are 512 * later restarted (hopefully due to some user action). The value is the 513 * time it was added to the list. 514 */ 515 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 516 517 /** 518 * All of the processes we currently have running organized by pid. 519 * The keys are the pid running the application. 520 * 521 * <p>NOTE: This object is protected by its own lock, NOT the global 522 * activity manager lock! 523 */ 524 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 525 526 /** 527 * All of the processes that have been forced to be foreground. The key 528 * is the pid of the caller who requested it (we hold a death 529 * link on it). 530 */ 531 abstract class ForegroundToken implements IBinder.DeathRecipient { 532 int pid; 533 IBinder token; 534 } 535 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 536 537 /** 538 * List of records for processes that someone had tried to start before the 539 * system was ready. We don't start them at that point, but ensure they 540 * are started by the time booting is complete. 541 */ 542 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 543 544 /** 545 * List of persistent applications that are in the process 546 * of being started. 547 */ 548 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 549 550 /** 551 * Processes that are being forcibly torn down. 552 */ 553 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 554 555 /** 556 * List of running applications, sorted by recent usage. 557 * The first entry in the list is the least recently used. 558 */ 559 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 560 561 /** 562 * Where in mLruProcesses that the processes hosting activities start. 563 */ 564 int mLruProcessActivityStart = 0; 565 566 /** 567 * Where in mLruProcesses that the processes hosting services start. 568 * This is after (lower index) than mLruProcessesActivityStart. 569 */ 570 int mLruProcessServiceStart = 0; 571 572 /** 573 * List of processes that should gc as soon as things are idle. 574 */ 575 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 576 577 /** 578 * Processes we want to collect PSS data from. 579 */ 580 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 581 582 /** 583 * Last time we requested PSS data of all processes. 584 */ 585 long mLastFullPssTime = SystemClock.uptimeMillis(); 586 587 /** 588 * If set, the next time we collect PSS data we should do a full collection 589 * with data from native processes and the kernel. 590 */ 591 boolean mFullPssPending = false; 592 593 /** 594 * This is the process holding what we currently consider to be 595 * the "home" activity. 596 */ 597 ProcessRecord mHomeProcess; 598 599 /** 600 * This is the process holding the activity the user last visited that 601 * is in a different process from the one they are currently in. 602 */ 603 ProcessRecord mPreviousProcess; 604 605 /** 606 * The time at which the previous process was last visible. 607 */ 608 long mPreviousProcessVisibleTime; 609 610 /** 611 * Which uses have been started, so are allowed to run code. 612 */ 613 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 614 615 /** 616 * LRU list of history of current users. Most recently current is at the end. 617 */ 618 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 619 620 /** 621 * Constant array of the users that are currently started. 622 */ 623 int[] mStartedUserArray = new int[] { 0 }; 624 625 /** 626 * Registered observers of the user switching mechanics. 627 */ 628 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 629 = new RemoteCallbackList<IUserSwitchObserver>(); 630 631 /** 632 * Currently active user switch. 633 */ 634 Object mCurUserSwitchCallback; 635 636 /** 637 * Packages that the user has asked to have run in screen size 638 * compatibility mode instead of filling the screen. 639 */ 640 final CompatModePackages mCompatModePackages; 641 642 /** 643 * Set of IntentSenderRecord objects that are currently active. 644 */ 645 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 646 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 647 648 /** 649 * Fingerprints (hashCode()) of stack traces that we've 650 * already logged DropBox entries for. Guarded by itself. If 651 * something (rogue user app) forces this over 652 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 653 */ 654 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 655 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 656 657 /** 658 * Strict Mode background batched logging state. 659 * 660 * The string buffer is guarded by itself, and its lock is also 661 * used to determine if another batched write is already 662 * in-flight. 663 */ 664 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 665 666 /** 667 * Keeps track of all IIntentReceivers that have been registered for 668 * broadcasts. Hash keys are the receiver IBinder, hash value is 669 * a ReceiverList. 670 */ 671 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 672 new HashMap<IBinder, ReceiverList>(); 673 674 /** 675 * Resolver for broadcast intents to registered receivers. 676 * Holds BroadcastFilter (subclass of IntentFilter). 677 */ 678 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 679 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 680 @Override 681 protected boolean allowFilterResult( 682 BroadcastFilter filter, List<BroadcastFilter> dest) { 683 IBinder target = filter.receiverList.receiver.asBinder(); 684 for (int i=dest.size()-1; i>=0; i--) { 685 if (dest.get(i).receiverList.receiver.asBinder() == target) { 686 return false; 687 } 688 } 689 return true; 690 } 691 692 @Override 693 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 694 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 695 || userId == filter.owningUserId) { 696 return super.newResult(filter, match, userId); 697 } 698 return null; 699 } 700 701 @Override 702 protected BroadcastFilter[] newArray(int size) { 703 return new BroadcastFilter[size]; 704 } 705 706 @Override 707 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 708 return packageName.equals(filter.packageName); 709 } 710 }; 711 712 /** 713 * State of all active sticky broadcasts per user. Keys are the action of the 714 * sticky Intent, values are an ArrayList of all broadcasted intents with 715 * that action (which should usually be one). The SparseArray is keyed 716 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 717 * for stickies that are sent to all users. 718 */ 719 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 720 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 721 722 final ActiveServices mServices; 723 724 /** 725 * Backup/restore process management 726 */ 727 String mBackupAppName = null; 728 BackupRecord mBackupTarget = null; 729 730 final ProviderMap mProviderMap; 731 732 /** 733 * List of content providers who have clients waiting for them. The 734 * application is currently being launched and the provider will be 735 * removed from this list once it is published. 736 */ 737 final ArrayList<ContentProviderRecord> mLaunchingProviders 738 = new ArrayList<ContentProviderRecord>(); 739 740 /** 741 * File storing persisted {@link #mGrantedUriPermissions}. 742 */ 743 private final AtomicFile mGrantFile; 744 745 /** XML constants used in {@link #mGrantFile} */ 746 private static final String TAG_URI_GRANTS = "uri-grants"; 747 private static final String TAG_URI_GRANT = "uri-grant"; 748 private static final String ATTR_USER_HANDLE = "userHandle"; 749 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 750 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 751 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 752 private static final String ATTR_TARGET_PKG = "targetPkg"; 753 private static final String ATTR_URI = "uri"; 754 private static final String ATTR_MODE_FLAGS = "modeFlags"; 755 private static final String ATTR_CREATED_TIME = "createdTime"; 756 private static final String ATTR_PREFIX = "prefix"; 757 758 /** 759 * Global set of specific {@link Uri} permissions that have been granted. 760 * This optimized lookup structure maps from {@link UriPermission#targetUid} 761 * to {@link UriPermission#uri} to {@link UriPermission}. 762 */ 763 @GuardedBy("this") 764 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 765 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 766 767 public static class GrantUri { 768 public final int sourceUserId; 769 public final Uri uri; 770 public boolean prefix; 771 772 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 773 this.sourceUserId = sourceUserId; 774 this.uri = uri; 775 this.prefix = prefix; 776 } 777 778 @Override 779 public int hashCode() { 780 return toString().hashCode(); 781 } 782 783 @Override 784 public boolean equals(Object o) { 785 if (o instanceof GrantUri) { 786 GrantUri other = (GrantUri) o; 787 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 788 && prefix == other.prefix; 789 } 790 return false; 791 } 792 793 @Override 794 public String toString() { 795 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 796 if (prefix) result += " [prefix]"; 797 return result; 798 } 799 800 public String toSafeString() { 801 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 802 if (prefix) result += " [prefix]"; 803 return result; 804 } 805 806 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 807 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 808 ContentProvider.getUriWithoutUserId(uri), false); 809 } 810 } 811 812 CoreSettingsObserver mCoreSettingsObserver; 813 814 /** 815 * Thread-local storage used to carry caller permissions over through 816 * indirect content-provider access. 817 */ 818 private class Identity { 819 public int pid; 820 public int uid; 821 822 Identity(int _pid, int _uid) { 823 pid = _pid; 824 uid = _uid; 825 } 826 } 827 828 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 829 830 /** 831 * All information we have collected about the runtime performance of 832 * any user id that can impact battery performance. 833 */ 834 final BatteryStatsService mBatteryStatsService; 835 836 /** 837 * Information about component usage 838 */ 839 UsageStatsManagerInternal mUsageStatsService; 840 841 /** 842 * Information about and control over application operations 843 */ 844 final AppOpsService mAppOpsService; 845 846 /** 847 * Save recent tasks information across reboots. 848 */ 849 final TaskPersister mTaskPersister; 850 851 /** 852 * Current configuration information. HistoryRecord objects are given 853 * a reference to this object to indicate which configuration they are 854 * currently running in, so this object must be kept immutable. 855 */ 856 Configuration mConfiguration = new Configuration(); 857 858 /** 859 * Current sequencing integer of the configuration, for skipping old 860 * configurations. 861 */ 862 int mConfigurationSeq = 0; 863 864 /** 865 * Hardware-reported OpenGLES version. 866 */ 867 final int GL_ES_VERSION; 868 869 /** 870 * List of initialization arguments to pass to all processes when binding applications to them. 871 * For example, references to the commonly used services. 872 */ 873 HashMap<String, IBinder> mAppBindArgs; 874 875 /** 876 * Temporary to avoid allocations. Protected by main lock. 877 */ 878 final StringBuilder mStringBuilder = new StringBuilder(256); 879 880 /** 881 * Used to control how we initialize the service. 882 */ 883 ComponentName mTopComponent; 884 String mTopAction = Intent.ACTION_MAIN; 885 String mTopData; 886 boolean mProcessesReady = false; 887 boolean mSystemReady = false; 888 boolean mBooting = false; 889 boolean mWaitingUpdate = false; 890 boolean mDidUpdate = false; 891 boolean mOnBattery = false; 892 boolean mLaunchWarningShown = false; 893 894 Context mContext; 895 896 int mFactoryTest; 897 898 boolean mCheckedForSetup; 899 900 /** 901 * The time at which we will allow normal application switches again, 902 * after a call to {@link #stopAppSwitches()}. 903 */ 904 long mAppSwitchesAllowedTime; 905 906 /** 907 * This is set to true after the first switch after mAppSwitchesAllowedTime 908 * is set; any switches after that will clear the time. 909 */ 910 boolean mDidAppSwitch; 911 912 /** 913 * Last time (in realtime) at which we checked for power usage. 914 */ 915 long mLastPowerCheckRealtime; 916 917 /** 918 * Last time (in uptime) at which we checked for power usage. 919 */ 920 long mLastPowerCheckUptime; 921 922 /** 923 * Set while we are wanting to sleep, to prevent any 924 * activities from being started/resumed. 925 */ 926 private boolean mSleeping = false; 927 928 /** 929 * Set while we are running a voice interaction. This overrides 930 * sleeping while it is active. 931 */ 932 private boolean mRunningVoice = false; 933 934 /** 935 * State of external calls telling us if the device is asleep. 936 */ 937 private boolean mWentToSleep = false; 938 939 /** 940 * State of external call telling us if the lock screen is shown. 941 */ 942 private boolean mLockScreenShown = false; 943 944 /** 945 * Set if we are shutting down the system, similar to sleeping. 946 */ 947 boolean mShuttingDown = false; 948 949 /** 950 * Current sequence id for oom_adj computation traversal. 951 */ 952 int mAdjSeq = 0; 953 954 /** 955 * Current sequence id for process LRU updating. 956 */ 957 int mLruSeq = 0; 958 959 /** 960 * Keep track of the non-cached/empty process we last found, to help 961 * determine how to distribute cached/empty processes next time. 962 */ 963 int mNumNonCachedProcs = 0; 964 965 /** 966 * Keep track of the number of cached hidden procs, to balance oom adj 967 * distribution between those and empty procs. 968 */ 969 int mNumCachedHiddenProcs = 0; 970 971 /** 972 * Keep track of the number of service processes we last found, to 973 * determine on the next iteration which should be B services. 974 */ 975 int mNumServiceProcs = 0; 976 int mNewNumAServiceProcs = 0; 977 int mNewNumServiceProcs = 0; 978 979 /** 980 * Allow the current computed overall memory level of the system to go down? 981 * This is set to false when we are killing processes for reasons other than 982 * memory management, so that the now smaller process list will not be taken as 983 * an indication that memory is tighter. 984 */ 985 boolean mAllowLowerMemLevel = false; 986 987 /** 988 * The last computed memory level, for holding when we are in a state that 989 * processes are going away for other reasons. 990 */ 991 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 992 993 /** 994 * The last total number of process we have, to determine if changes actually look 995 * like a shrinking number of process due to lower RAM. 996 */ 997 int mLastNumProcesses; 998 999 /** 1000 * The uptime of the last time we performed idle maintenance. 1001 */ 1002 long mLastIdleTime = SystemClock.uptimeMillis(); 1003 1004 /** 1005 * Total time spent with RAM that has been added in the past since the last idle time. 1006 */ 1007 long mLowRamTimeSinceLastIdle = 0; 1008 1009 /** 1010 * If RAM is currently low, when that horrible situation started. 1011 */ 1012 long mLowRamStartTime = 0; 1013 1014 /** 1015 * For reporting to battery stats the current top application. 1016 */ 1017 private String mCurResumedPackage = null; 1018 private int mCurResumedUid = -1; 1019 1020 /** 1021 * For reporting to battery stats the apps currently running foreground 1022 * service. The ProcessMap is package/uid tuples; each of these contain 1023 * an array of the currently foreground processes. 1024 */ 1025 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1026 = new ProcessMap<ArrayList<ProcessRecord>>(); 1027 1028 /** 1029 * This is set if we had to do a delayed dexopt of an app before launching 1030 * it, to increase the ANR timeouts in that case. 1031 */ 1032 boolean mDidDexOpt; 1033 1034 /** 1035 * Set if the systemServer made a call to enterSafeMode. 1036 */ 1037 boolean mSafeMode; 1038 1039 String mDebugApp = null; 1040 boolean mWaitForDebugger = false; 1041 boolean mDebugTransient = false; 1042 String mOrigDebugApp = null; 1043 boolean mOrigWaitForDebugger = false; 1044 boolean mAlwaysFinishActivities = false; 1045 IActivityController mController = null; 1046 String mProfileApp = null; 1047 ProcessRecord mProfileProc = null; 1048 String mProfileFile; 1049 ParcelFileDescriptor mProfileFd; 1050 int mProfileType = 0; 1051 boolean mAutoStopProfiler = false; 1052 String mOpenGlTraceApp = null; 1053 1054 static class ProcessChangeItem { 1055 static final int CHANGE_ACTIVITIES = 1<<0; 1056 static final int CHANGE_PROCESS_STATE = 1<<1; 1057 int changes; 1058 int uid; 1059 int pid; 1060 int processState; 1061 boolean foregroundActivities; 1062 } 1063 1064 final RemoteCallbackList<IProcessObserver> mProcessObservers 1065 = new RemoteCallbackList<IProcessObserver>(); 1066 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1067 1068 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1069 = new ArrayList<ProcessChangeItem>(); 1070 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 1073 /** 1074 * Runtime CPU use collection thread. This object's lock is used to 1075 * protect all related state. 1076 */ 1077 final Thread mProcessCpuThread; 1078 1079 /** 1080 * Used to collect process stats when showing not responding dialog. 1081 * Protected by mProcessCpuThread. 1082 */ 1083 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1084 MONITOR_THREAD_CPU_USAGE); 1085 final AtomicLong mLastCpuTime = new AtomicLong(0); 1086 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1087 1088 long mLastWriteTime = 0; 1089 1090 /** 1091 * Used to retain an update lock when the foreground activity is in 1092 * immersive mode. 1093 */ 1094 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1095 1096 /** 1097 * Set to true after the system has finished booting. 1098 */ 1099 boolean mBooted = false; 1100 1101 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1102 int mProcessLimitOverride = -1; 1103 1104 WindowManagerService mWindowManager; 1105 1106 final ActivityThread mSystemThread; 1107 1108 int mCurrentUserId = 0; 1109 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1110 1111 /** 1112 * Mapping from each known user ID to the profile group ID it is associated with. 1113 */ 1114 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1115 1116 private UserManagerService mUserManager; 1117 1118 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1119 final ProcessRecord mApp; 1120 final int mPid; 1121 final IApplicationThread mAppThread; 1122 1123 AppDeathRecipient(ProcessRecord app, int pid, 1124 IApplicationThread thread) { 1125 if (localLOGV) Slog.v( 1126 TAG, "New death recipient " + this 1127 + " for thread " + thread.asBinder()); 1128 mApp = app; 1129 mPid = pid; 1130 mAppThread = thread; 1131 } 1132 1133 @Override 1134 public void binderDied() { 1135 if (localLOGV) Slog.v( 1136 TAG, "Death received in " + this 1137 + " for thread " + mAppThread.asBinder()); 1138 synchronized(ActivityManagerService.this) { 1139 appDiedLocked(mApp, mPid, mAppThread); 1140 } 1141 } 1142 } 1143 1144 static final int SHOW_ERROR_MSG = 1; 1145 static final int SHOW_NOT_RESPONDING_MSG = 2; 1146 static final int SHOW_FACTORY_ERROR_MSG = 3; 1147 static final int UPDATE_CONFIGURATION_MSG = 4; 1148 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1149 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1150 static final int SERVICE_TIMEOUT_MSG = 12; 1151 static final int UPDATE_TIME_ZONE = 13; 1152 static final int SHOW_UID_ERROR_MSG = 14; 1153 static final int IM_FEELING_LUCKY_MSG = 15; 1154 static final int PROC_START_TIMEOUT_MSG = 20; 1155 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1156 static final int KILL_APPLICATION_MSG = 22; 1157 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1158 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1159 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1160 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1161 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1162 static final int CLEAR_DNS_CACHE_MSG = 28; 1163 static final int UPDATE_HTTP_PROXY_MSG = 29; 1164 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1165 static final int DISPATCH_PROCESSES_CHANGED = 31; 1166 static final int DISPATCH_PROCESS_DIED = 32; 1167 static final int REPORT_MEM_USAGE_MSG = 33; 1168 static final int REPORT_USER_SWITCH_MSG = 34; 1169 static final int CONTINUE_USER_SWITCH_MSG = 35; 1170 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1171 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1172 static final int PERSIST_URI_GRANTS_MSG = 38; 1173 static final int REQUEST_ALL_PSS_MSG = 39; 1174 static final int START_PROFILES_MSG = 40; 1175 static final int UPDATE_TIME = 41; 1176 static final int SYSTEM_USER_START_MSG = 42; 1177 static final int SYSTEM_USER_CURRENT_MSG = 43; 1178 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1179 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1180 static final int START_USER_SWITCH_MSG = 46; 1181 1182 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1183 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1184 static final int FIRST_COMPAT_MODE_MSG = 300; 1185 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1186 1187 AlertDialog mUidAlert; 1188 CompatModeDialog mCompatModeDialog; 1189 long mLastMemUsageReportTime = 0; 1190 1191 private LockToAppRequestDialog mLockToAppRequest; 1192 1193 /** 1194 * Flag whether the current user is a "monkey", i.e. whether 1195 * the UI is driven by a UI automation tool. 1196 */ 1197 private boolean mUserIsMonkey; 1198 1199 /** Flag whether the device has a recents UI */ 1200 final boolean mHasRecents; 1201 1202 final int mThumbnailWidth; 1203 final int mThumbnailHeight; 1204 1205 final ServiceThread mHandlerThread; 1206 final MainHandler mHandler; 1207 1208 final class MainHandler extends Handler { 1209 public MainHandler(Looper looper) { 1210 super(looper, null, true); 1211 } 1212 1213 @Override 1214 public void handleMessage(Message msg) { 1215 switch (msg.what) { 1216 case SHOW_ERROR_MSG: { 1217 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1218 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1219 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1220 synchronized (ActivityManagerService.this) { 1221 ProcessRecord proc = (ProcessRecord)data.get("app"); 1222 AppErrorResult res = (AppErrorResult) data.get("result"); 1223 if (proc != null && proc.crashDialog != null) { 1224 Slog.e(TAG, "App already has crash dialog: " + proc); 1225 if (res != null) { 1226 res.set(0); 1227 } 1228 return; 1229 } 1230 boolean isBackground = (UserHandle.getAppId(proc.uid) 1231 >= Process.FIRST_APPLICATION_UID 1232 && proc.pid != MY_PID); 1233 for (int userId : mCurrentProfileIds) { 1234 isBackground &= (proc.userId != userId); 1235 } 1236 if (isBackground && !showBackground) { 1237 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1238 if (res != null) { 1239 res.set(0); 1240 } 1241 return; 1242 } 1243 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1244 Dialog d = new AppErrorDialog(mContext, 1245 ActivityManagerService.this, res, proc); 1246 d.show(); 1247 proc.crashDialog = d; 1248 } else { 1249 // The device is asleep, so just pretend that the user 1250 // saw a crash dialog and hit "force quit". 1251 if (res != null) { 1252 res.set(0); 1253 } 1254 } 1255 } 1256 1257 ensureBootCompleted(); 1258 } break; 1259 case SHOW_NOT_RESPONDING_MSG: { 1260 synchronized (ActivityManagerService.this) { 1261 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1262 ProcessRecord proc = (ProcessRecord)data.get("app"); 1263 if (proc != null && proc.anrDialog != null) { 1264 Slog.e(TAG, "App already has anr dialog: " + proc); 1265 return; 1266 } 1267 1268 Intent intent = new Intent("android.intent.action.ANR"); 1269 if (!mProcessesReady) { 1270 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1271 | Intent.FLAG_RECEIVER_FOREGROUND); 1272 } 1273 broadcastIntentLocked(null, null, intent, 1274 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1275 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1276 1277 if (mShowDialogs) { 1278 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1279 mContext, proc, (ActivityRecord)data.get("activity"), 1280 msg.arg1 != 0); 1281 d.show(); 1282 proc.anrDialog = d; 1283 } else { 1284 // Just kill the app if there is no dialog to be shown. 1285 killAppAtUsersRequest(proc, null); 1286 } 1287 } 1288 1289 ensureBootCompleted(); 1290 } break; 1291 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1292 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1293 synchronized (ActivityManagerService.this) { 1294 ProcessRecord proc = (ProcessRecord) data.get("app"); 1295 if (proc == null) { 1296 Slog.e(TAG, "App not found when showing strict mode dialog."); 1297 break; 1298 } 1299 if (proc.crashDialog != null) { 1300 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1301 return; 1302 } 1303 AppErrorResult res = (AppErrorResult) data.get("result"); 1304 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1305 Dialog d = new StrictModeViolationDialog(mContext, 1306 ActivityManagerService.this, res, proc); 1307 d.show(); 1308 proc.crashDialog = d; 1309 } else { 1310 // The device is asleep, so just pretend that the user 1311 // saw a crash dialog and hit "force quit". 1312 res.set(0); 1313 } 1314 } 1315 ensureBootCompleted(); 1316 } break; 1317 case SHOW_FACTORY_ERROR_MSG: { 1318 Dialog d = new FactoryErrorDialog( 1319 mContext, msg.getData().getCharSequence("msg")); 1320 d.show(); 1321 ensureBootCompleted(); 1322 } break; 1323 case UPDATE_CONFIGURATION_MSG: { 1324 final ContentResolver resolver = mContext.getContentResolver(); 1325 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1326 } break; 1327 case GC_BACKGROUND_PROCESSES_MSG: { 1328 synchronized (ActivityManagerService.this) { 1329 performAppGcsIfAppropriateLocked(); 1330 } 1331 } break; 1332 case WAIT_FOR_DEBUGGER_MSG: { 1333 synchronized (ActivityManagerService.this) { 1334 ProcessRecord app = (ProcessRecord)msg.obj; 1335 if (msg.arg1 != 0) { 1336 if (!app.waitedForDebugger) { 1337 Dialog d = new AppWaitingForDebuggerDialog( 1338 ActivityManagerService.this, 1339 mContext, app); 1340 app.waitDialog = d; 1341 app.waitedForDebugger = true; 1342 d.show(); 1343 } 1344 } else { 1345 if (app.waitDialog != null) { 1346 app.waitDialog.dismiss(); 1347 app.waitDialog = null; 1348 } 1349 } 1350 } 1351 } break; 1352 case SERVICE_TIMEOUT_MSG: { 1353 if (mDidDexOpt) { 1354 mDidDexOpt = false; 1355 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1356 nmsg.obj = msg.obj; 1357 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1358 return; 1359 } 1360 mServices.serviceTimeout((ProcessRecord)msg.obj); 1361 } break; 1362 case UPDATE_TIME_ZONE: { 1363 synchronized (ActivityManagerService.this) { 1364 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1365 ProcessRecord r = mLruProcesses.get(i); 1366 if (r.thread != null) { 1367 try { 1368 r.thread.updateTimeZone(); 1369 } catch (RemoteException ex) { 1370 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1371 } 1372 } 1373 } 1374 } 1375 } break; 1376 case CLEAR_DNS_CACHE_MSG: { 1377 synchronized (ActivityManagerService.this) { 1378 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1379 ProcessRecord r = mLruProcesses.get(i); 1380 if (r.thread != null) { 1381 try { 1382 r.thread.clearDnsCache(); 1383 } catch (RemoteException ex) { 1384 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1385 } 1386 } 1387 } 1388 } 1389 } break; 1390 case UPDATE_HTTP_PROXY_MSG: { 1391 ProxyInfo proxy = (ProxyInfo)msg.obj; 1392 String host = ""; 1393 String port = ""; 1394 String exclList = ""; 1395 Uri pacFileUrl = Uri.EMPTY; 1396 if (proxy != null) { 1397 host = proxy.getHost(); 1398 port = Integer.toString(proxy.getPort()); 1399 exclList = proxy.getExclusionListAsString(); 1400 pacFileUrl = proxy.getPacFileUrl(); 1401 } 1402 synchronized (ActivityManagerService.this) { 1403 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1404 ProcessRecord r = mLruProcesses.get(i); 1405 if (r.thread != null) { 1406 try { 1407 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1408 } catch (RemoteException ex) { 1409 Slog.w(TAG, "Failed to update http proxy for: " + 1410 r.info.processName); 1411 } 1412 } 1413 } 1414 } 1415 } break; 1416 case SHOW_UID_ERROR_MSG: { 1417 String title = "System UIDs Inconsistent"; 1418 String text = "UIDs on the system are inconsistent, you need to wipe your" 1419 + " data partition or your device will be unstable."; 1420 Log.e(TAG, title + ": " + text); 1421 if (mShowDialogs) { 1422 // XXX This is a temporary dialog, no need to localize. 1423 AlertDialog d = new BaseErrorDialog(mContext); 1424 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1425 d.setCancelable(false); 1426 d.setTitle(title); 1427 d.setMessage(text); 1428 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1429 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1430 mUidAlert = d; 1431 d.show(); 1432 } 1433 } break; 1434 case IM_FEELING_LUCKY_MSG: { 1435 if (mUidAlert != null) { 1436 mUidAlert.dismiss(); 1437 mUidAlert = null; 1438 } 1439 } break; 1440 case PROC_START_TIMEOUT_MSG: { 1441 if (mDidDexOpt) { 1442 mDidDexOpt = false; 1443 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1444 nmsg.obj = msg.obj; 1445 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1446 return; 1447 } 1448 ProcessRecord app = (ProcessRecord)msg.obj; 1449 synchronized (ActivityManagerService.this) { 1450 processStartTimedOutLocked(app); 1451 } 1452 } break; 1453 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1454 synchronized (ActivityManagerService.this) { 1455 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1456 } 1457 } break; 1458 case KILL_APPLICATION_MSG: { 1459 synchronized (ActivityManagerService.this) { 1460 int appid = msg.arg1; 1461 boolean restart = (msg.arg2 == 1); 1462 Bundle bundle = (Bundle)msg.obj; 1463 String pkg = bundle.getString("pkg"); 1464 String reason = bundle.getString("reason"); 1465 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1466 false, UserHandle.USER_ALL, reason); 1467 } 1468 } break; 1469 case FINALIZE_PENDING_INTENT_MSG: { 1470 ((PendingIntentRecord)msg.obj).completeFinalize(); 1471 } break; 1472 case POST_HEAVY_NOTIFICATION_MSG: { 1473 INotificationManager inm = NotificationManager.getService(); 1474 if (inm == null) { 1475 return; 1476 } 1477 1478 ActivityRecord root = (ActivityRecord)msg.obj; 1479 ProcessRecord process = root.app; 1480 if (process == null) { 1481 return; 1482 } 1483 1484 try { 1485 Context context = mContext.createPackageContext(process.info.packageName, 0); 1486 String text = mContext.getString(R.string.heavy_weight_notification, 1487 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1488 Notification notification = new Notification(); 1489 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1490 notification.when = 0; 1491 notification.flags = Notification.FLAG_ONGOING_EVENT; 1492 notification.tickerText = text; 1493 notification.defaults = 0; // please be quiet 1494 notification.sound = null; 1495 notification.vibrate = null; 1496 notification.color = mContext.getResources().getColor( 1497 com.android.internal.R.color.system_notification_accent_color); 1498 notification.setLatestEventInfo(context, text, 1499 mContext.getText(R.string.heavy_weight_notification_detail), 1500 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1501 PendingIntent.FLAG_CANCEL_CURRENT, null, 1502 new UserHandle(root.userId))); 1503 1504 try { 1505 int[] outId = new int[1]; 1506 inm.enqueueNotificationWithTag("android", "android", null, 1507 R.string.heavy_weight_notification, 1508 notification, outId, root.userId); 1509 } catch (RuntimeException e) { 1510 Slog.w(ActivityManagerService.TAG, 1511 "Error showing notification for heavy-weight app", e); 1512 } catch (RemoteException e) { 1513 } 1514 } catch (NameNotFoundException e) { 1515 Slog.w(TAG, "Unable to create context for heavy notification", e); 1516 } 1517 } break; 1518 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1519 INotificationManager inm = NotificationManager.getService(); 1520 if (inm == null) { 1521 return; 1522 } 1523 try { 1524 inm.cancelNotificationWithTag("android", null, 1525 R.string.heavy_weight_notification, msg.arg1); 1526 } catch (RuntimeException e) { 1527 Slog.w(ActivityManagerService.TAG, 1528 "Error canceling notification for service", e); 1529 } catch (RemoteException e) { 1530 } 1531 } break; 1532 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1533 synchronized (ActivityManagerService.this) { 1534 checkExcessivePowerUsageLocked(true); 1535 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1536 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1537 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1538 } 1539 } break; 1540 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1541 synchronized (ActivityManagerService.this) { 1542 ActivityRecord ar = (ActivityRecord)msg.obj; 1543 if (mCompatModeDialog != null) { 1544 if (mCompatModeDialog.mAppInfo.packageName.equals( 1545 ar.info.applicationInfo.packageName)) { 1546 return; 1547 } 1548 mCompatModeDialog.dismiss(); 1549 mCompatModeDialog = null; 1550 } 1551 if (ar != null && false) { 1552 if (mCompatModePackages.getPackageAskCompatModeLocked( 1553 ar.packageName)) { 1554 int mode = mCompatModePackages.computeCompatModeLocked( 1555 ar.info.applicationInfo); 1556 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1557 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1558 mCompatModeDialog = new CompatModeDialog( 1559 ActivityManagerService.this, mContext, 1560 ar.info.applicationInfo); 1561 mCompatModeDialog.show(); 1562 } 1563 } 1564 } 1565 } 1566 break; 1567 } 1568 case DISPATCH_PROCESSES_CHANGED: { 1569 dispatchProcessesChanged(); 1570 break; 1571 } 1572 case DISPATCH_PROCESS_DIED: { 1573 final int pid = msg.arg1; 1574 final int uid = msg.arg2; 1575 dispatchProcessDied(pid, uid); 1576 break; 1577 } 1578 case REPORT_MEM_USAGE_MSG: { 1579 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1580 Thread thread = new Thread() { 1581 @Override public void run() { 1582 final SparseArray<ProcessMemInfo> infoMap 1583 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1584 for (int i=0, N=memInfos.size(); i<N; i++) { 1585 ProcessMemInfo mi = memInfos.get(i); 1586 infoMap.put(mi.pid, mi); 1587 } 1588 updateCpuStatsNow(); 1589 synchronized (mProcessCpuThread) { 1590 final int N = mProcessCpuTracker.countStats(); 1591 for (int i=0; i<N; i++) { 1592 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1593 if (st.vsize > 0) { 1594 long pss = Debug.getPss(st.pid, null); 1595 if (pss > 0) { 1596 if (infoMap.indexOfKey(st.pid) < 0) { 1597 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1598 ProcessList.NATIVE_ADJ, -1, "native", null); 1599 mi.pss = pss; 1600 memInfos.add(mi); 1601 } 1602 } 1603 } 1604 } 1605 } 1606 1607 long totalPss = 0; 1608 for (int i=0, N=memInfos.size(); i<N; i++) { 1609 ProcessMemInfo mi = memInfos.get(i); 1610 if (mi.pss == 0) { 1611 mi.pss = Debug.getPss(mi.pid, null); 1612 } 1613 totalPss += mi.pss; 1614 } 1615 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1616 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1617 if (lhs.oomAdj != rhs.oomAdj) { 1618 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1619 } 1620 if (lhs.pss != rhs.pss) { 1621 return lhs.pss < rhs.pss ? 1 : -1; 1622 } 1623 return 0; 1624 } 1625 }); 1626 1627 StringBuilder tag = new StringBuilder(128); 1628 StringBuilder stack = new StringBuilder(128); 1629 tag.append("Low on memory -- "); 1630 appendMemBucket(tag, totalPss, "total", false); 1631 appendMemBucket(stack, totalPss, "total", true); 1632 1633 StringBuilder logBuilder = new StringBuilder(1024); 1634 logBuilder.append("Low on memory:\n"); 1635 1636 boolean firstLine = true; 1637 int lastOomAdj = Integer.MIN_VALUE; 1638 for (int i=0, N=memInfos.size(); i<N; i++) { 1639 ProcessMemInfo mi = memInfos.get(i); 1640 1641 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1642 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1643 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1644 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1645 if (lastOomAdj != mi.oomAdj) { 1646 lastOomAdj = mi.oomAdj; 1647 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1648 tag.append(" / "); 1649 } 1650 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1651 if (firstLine) { 1652 stack.append(":"); 1653 firstLine = false; 1654 } 1655 stack.append("\n\t at "); 1656 } else { 1657 stack.append("$"); 1658 } 1659 } else { 1660 tag.append(" "); 1661 stack.append("$"); 1662 } 1663 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1664 appendMemBucket(tag, mi.pss, mi.name, false); 1665 } 1666 appendMemBucket(stack, mi.pss, mi.name, true); 1667 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1668 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1669 stack.append("("); 1670 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1671 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1672 stack.append(DUMP_MEM_OOM_LABEL[k]); 1673 stack.append(":"); 1674 stack.append(DUMP_MEM_OOM_ADJ[k]); 1675 } 1676 } 1677 stack.append(")"); 1678 } 1679 } 1680 1681 logBuilder.append(" "); 1682 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1683 logBuilder.append(' '); 1684 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1685 logBuilder.append(' '); 1686 ProcessList.appendRamKb(logBuilder, mi.pss); 1687 logBuilder.append(" kB: "); 1688 logBuilder.append(mi.name); 1689 logBuilder.append(" ("); 1690 logBuilder.append(mi.pid); 1691 logBuilder.append(") "); 1692 logBuilder.append(mi.adjType); 1693 logBuilder.append('\n'); 1694 if (mi.adjReason != null) { 1695 logBuilder.append(" "); 1696 logBuilder.append(mi.adjReason); 1697 logBuilder.append('\n'); 1698 } 1699 } 1700 1701 logBuilder.append(" "); 1702 ProcessList.appendRamKb(logBuilder, totalPss); 1703 logBuilder.append(" kB: TOTAL\n"); 1704 1705 long[] infos = new long[Debug.MEMINFO_COUNT]; 1706 Debug.getMemInfo(infos); 1707 logBuilder.append(" MemInfo: "); 1708 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1709 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1710 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1711 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1712 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1713 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1714 logBuilder.append(" ZRAM: "); 1715 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1716 logBuilder.append(" kB RAM, "); 1717 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1718 logBuilder.append(" kB swap total, "); 1719 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1720 logBuilder.append(" kB swap free\n"); 1721 } 1722 Slog.i(TAG, logBuilder.toString()); 1723 1724 StringBuilder dropBuilder = new StringBuilder(1024); 1725 /* 1726 StringWriter oomSw = new StringWriter(); 1727 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1728 StringWriter catSw = new StringWriter(); 1729 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1730 String[] emptyArgs = new String[] { }; 1731 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1732 oomPw.flush(); 1733 String oomString = oomSw.toString(); 1734 */ 1735 dropBuilder.append(stack); 1736 dropBuilder.append('\n'); 1737 dropBuilder.append('\n'); 1738 dropBuilder.append(logBuilder); 1739 dropBuilder.append('\n'); 1740 /* 1741 dropBuilder.append(oomString); 1742 dropBuilder.append('\n'); 1743 */ 1744 StringWriter catSw = new StringWriter(); 1745 synchronized (ActivityManagerService.this) { 1746 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1747 String[] emptyArgs = new String[] { }; 1748 catPw.println(); 1749 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1750 catPw.println(); 1751 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1752 false, false, null); 1753 catPw.println(); 1754 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1755 catPw.flush(); 1756 } 1757 dropBuilder.append(catSw.toString()); 1758 addErrorToDropBox("lowmem", null, "system_server", null, 1759 null, tag.toString(), dropBuilder.toString(), null, null); 1760 //Slog.i(TAG, "Sent to dropbox:"); 1761 //Slog.i(TAG, dropBuilder.toString()); 1762 synchronized (ActivityManagerService.this) { 1763 long now = SystemClock.uptimeMillis(); 1764 if (mLastMemUsageReportTime < now) { 1765 mLastMemUsageReportTime = now; 1766 } 1767 } 1768 } 1769 }; 1770 thread.start(); 1771 break; 1772 } 1773 case START_USER_SWITCH_MSG: { 1774 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1775 break; 1776 } 1777 case REPORT_USER_SWITCH_MSG: { 1778 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1779 break; 1780 } 1781 case CONTINUE_USER_SWITCH_MSG: { 1782 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1783 break; 1784 } 1785 case USER_SWITCH_TIMEOUT_MSG: { 1786 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1787 break; 1788 } 1789 case IMMERSIVE_MODE_LOCK_MSG: { 1790 final boolean nextState = (msg.arg1 != 0); 1791 if (mUpdateLock.isHeld() != nextState) { 1792 if (DEBUG_IMMERSIVE) { 1793 final ActivityRecord r = (ActivityRecord) msg.obj; 1794 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1795 } 1796 if (nextState) { 1797 mUpdateLock.acquire(); 1798 } else { 1799 mUpdateLock.release(); 1800 } 1801 } 1802 break; 1803 } 1804 case PERSIST_URI_GRANTS_MSG: { 1805 writeGrantedUriPermissions(); 1806 break; 1807 } 1808 case REQUEST_ALL_PSS_MSG: { 1809 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1810 break; 1811 } 1812 case START_PROFILES_MSG: { 1813 synchronized (ActivityManagerService.this) { 1814 startProfilesLocked(); 1815 } 1816 break; 1817 } 1818 case UPDATE_TIME: { 1819 synchronized (ActivityManagerService.this) { 1820 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1821 ProcessRecord r = mLruProcesses.get(i); 1822 if (r.thread != null) { 1823 try { 1824 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1825 } catch (RemoteException ex) { 1826 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1827 } 1828 } 1829 } 1830 } 1831 break; 1832 } 1833 case SYSTEM_USER_START_MSG: { 1834 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1835 Integer.toString(msg.arg1), msg.arg1); 1836 mSystemServiceManager.startUser(msg.arg1); 1837 break; 1838 } 1839 case SYSTEM_USER_CURRENT_MSG: { 1840 mBatteryStatsService.noteEvent( 1841 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1842 Integer.toString(msg.arg2), msg.arg2); 1843 mBatteryStatsService.noteEvent( 1844 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1845 Integer.toString(msg.arg1), msg.arg1); 1846 mSystemServiceManager.switchUser(msg.arg1); 1847 mLockToAppRequest.clearPrompt(); 1848 break; 1849 } 1850 case ENTER_ANIMATION_COMPLETE_MSG: { 1851 synchronized (ActivityManagerService.this) { 1852 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1853 if (r != null && r.app != null && r.app.thread != null) { 1854 try { 1855 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1856 } catch (RemoteException e) { 1857 } 1858 } 1859 } 1860 break; 1861 } 1862 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1863 enableScreenAfterBoot(); 1864 break; 1865 } 1866 } 1867 } 1868 }; 1869 1870 static final int COLLECT_PSS_BG_MSG = 1; 1871 1872 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1873 @Override 1874 public void handleMessage(Message msg) { 1875 switch (msg.what) { 1876 case COLLECT_PSS_BG_MSG: { 1877 long start = SystemClock.uptimeMillis(); 1878 MemInfoReader memInfo = null; 1879 synchronized (ActivityManagerService.this) { 1880 if (mFullPssPending) { 1881 mFullPssPending = false; 1882 memInfo = new MemInfoReader(); 1883 } 1884 } 1885 if (memInfo != null) { 1886 updateCpuStatsNow(); 1887 long nativeTotalPss = 0; 1888 synchronized (mProcessCpuThread) { 1889 final int N = mProcessCpuTracker.countStats(); 1890 for (int j=0; j<N; j++) { 1891 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1892 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1893 // This is definitely an application process; skip it. 1894 continue; 1895 } 1896 synchronized (mPidsSelfLocked) { 1897 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1898 // This is one of our own processes; skip it. 1899 continue; 1900 } 1901 } 1902 nativeTotalPss += Debug.getPss(st.pid, null); 1903 } 1904 } 1905 memInfo.readMemInfo(); 1906 synchronized (this) { 1907 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1908 + (SystemClock.uptimeMillis()-start) + "ms"); 1909 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1910 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1911 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1912 +memInfo.getSlabSizeKb(), 1913 nativeTotalPss); 1914 } 1915 } 1916 1917 int i=0, num=0; 1918 long[] tmp = new long[1]; 1919 do { 1920 ProcessRecord proc; 1921 int procState; 1922 int pid; 1923 synchronized (ActivityManagerService.this) { 1924 if (i >= mPendingPssProcesses.size()) { 1925 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1926 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1927 mPendingPssProcesses.clear(); 1928 return; 1929 } 1930 proc = mPendingPssProcesses.get(i); 1931 procState = proc.pssProcState; 1932 if (proc.thread != null && procState == proc.setProcState) { 1933 pid = proc.pid; 1934 } else { 1935 proc = null; 1936 pid = 0; 1937 } 1938 i++; 1939 } 1940 if (proc != null) { 1941 long pss = Debug.getPss(pid, tmp); 1942 synchronized (ActivityManagerService.this) { 1943 if (proc.thread != null && proc.setProcState == procState 1944 && proc.pid == pid) { 1945 num++; 1946 proc.lastPssTime = SystemClock.uptimeMillis(); 1947 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1948 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1949 + ": " + pss + " lastPss=" + proc.lastPss 1950 + " state=" + ProcessList.makeProcStateString(procState)); 1951 if (proc.initialIdlePss == 0) { 1952 proc.initialIdlePss = pss; 1953 } 1954 proc.lastPss = pss; 1955 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1956 proc.lastCachedPss = pss; 1957 } 1958 } 1959 } 1960 } 1961 } while (true); 1962 } 1963 } 1964 } 1965 }; 1966 1967 /** 1968 * Monitor for package changes and update our internal state. 1969 */ 1970 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1971 @Override 1972 public void onPackageRemoved(String packageName, int uid) { 1973 // Remove all tasks with activities in the specified package from the list of recent tasks 1974 synchronized (ActivityManagerService.this) { 1975 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1976 TaskRecord tr = mRecentTasks.get(i); 1977 ComponentName cn = tr.intent.getComponent(); 1978 if (cn != null && cn.getPackageName().equals(packageName)) { 1979 // If the package name matches, remove the task and kill the process 1980 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1981 } 1982 } 1983 } 1984 } 1985 1986 @Override 1987 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1988 onPackageModified(packageName); 1989 return true; 1990 } 1991 1992 @Override 1993 public void onPackageModified(String packageName) { 1994 final PackageManager pm = mContext.getPackageManager(); 1995 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1996 new ArrayList<Pair<Intent, Integer>>(); 1997 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1998 // Copy the list of recent tasks so that we don't hold onto the lock on 1999 // ActivityManagerService for long periods while checking if components exist. 2000 synchronized (ActivityManagerService.this) { 2001 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2002 TaskRecord tr = mRecentTasks.get(i); 2003 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2004 } 2005 } 2006 // Check the recent tasks and filter out all tasks with components that no longer exist. 2007 Intent tmpI = new Intent(); 2008 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2009 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2010 ComponentName cn = p.first.getComponent(); 2011 if (cn != null && cn.getPackageName().equals(packageName)) { 2012 try { 2013 // Add the task to the list to remove if the component no longer exists 2014 tmpI.setComponent(cn); 2015 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2016 tasksToRemove.add(p.second); 2017 } 2018 } catch (Exception e) {} 2019 } 2020 } 2021 // Prune all the tasks with removed components from the list of recent tasks 2022 synchronized (ActivityManagerService.this) { 2023 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2024 // Remove the task but don't kill the process (since other components in that 2025 // package may still be running and in the background) 2026 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2027 } 2028 } 2029 } 2030 2031 @Override 2032 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2033 // Force stop the specified packages 2034 if (packages != null) { 2035 for (String pkg : packages) { 2036 synchronized (ActivityManagerService.this) { 2037 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2038 "finished booting")) { 2039 return true; 2040 } 2041 } 2042 } 2043 } 2044 return false; 2045 } 2046 }; 2047 2048 public void setSystemProcess() { 2049 try { 2050 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2051 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2052 ServiceManager.addService("meminfo", new MemBinder(this)); 2053 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2054 ServiceManager.addService("dbinfo", new DbBinder(this)); 2055 if (MONITOR_CPU_USAGE) { 2056 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2057 } 2058 ServiceManager.addService("permission", new PermissionController(this)); 2059 2060 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2061 "android", STOCK_PM_FLAGS); 2062 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2063 2064 synchronized (this) { 2065 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2066 app.persistent = true; 2067 app.pid = MY_PID; 2068 app.maxAdj = ProcessList.SYSTEM_ADJ; 2069 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2070 mProcessNames.put(app.processName, app.uid, app); 2071 synchronized (mPidsSelfLocked) { 2072 mPidsSelfLocked.put(app.pid, app); 2073 } 2074 updateLruProcessLocked(app, false, null); 2075 updateOomAdjLocked(); 2076 } 2077 } catch (PackageManager.NameNotFoundException e) { 2078 throw new RuntimeException( 2079 "Unable to find android system package", e); 2080 } 2081 } 2082 2083 public void setWindowManager(WindowManagerService wm) { 2084 mWindowManager = wm; 2085 mStackSupervisor.setWindowManager(wm); 2086 } 2087 2088 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2089 mUsageStatsService = usageStatsManager; 2090 } 2091 2092 public void startObservingNativeCrashes() { 2093 final NativeCrashListener ncl = new NativeCrashListener(this); 2094 ncl.start(); 2095 } 2096 2097 public IAppOpsService getAppOpsService() { 2098 return mAppOpsService; 2099 } 2100 2101 static class MemBinder extends Binder { 2102 ActivityManagerService mActivityManagerService; 2103 MemBinder(ActivityManagerService activityManagerService) { 2104 mActivityManagerService = activityManagerService; 2105 } 2106 2107 @Override 2108 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2109 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2110 != PackageManager.PERMISSION_GRANTED) { 2111 pw.println("Permission Denial: can't dump meminfo from from pid=" 2112 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2113 + " without permission " + android.Manifest.permission.DUMP); 2114 return; 2115 } 2116 2117 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2118 } 2119 } 2120 2121 static class GraphicsBinder extends Binder { 2122 ActivityManagerService mActivityManagerService; 2123 GraphicsBinder(ActivityManagerService activityManagerService) { 2124 mActivityManagerService = activityManagerService; 2125 } 2126 2127 @Override 2128 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2129 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2130 != PackageManager.PERMISSION_GRANTED) { 2131 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2132 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2133 + " without permission " + android.Manifest.permission.DUMP); 2134 return; 2135 } 2136 2137 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2138 } 2139 } 2140 2141 static class DbBinder extends Binder { 2142 ActivityManagerService mActivityManagerService; 2143 DbBinder(ActivityManagerService activityManagerService) { 2144 mActivityManagerService = activityManagerService; 2145 } 2146 2147 @Override 2148 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2149 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2150 != PackageManager.PERMISSION_GRANTED) { 2151 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2152 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2153 + " without permission " + android.Manifest.permission.DUMP); 2154 return; 2155 } 2156 2157 mActivityManagerService.dumpDbInfo(fd, pw, args); 2158 } 2159 } 2160 2161 static class CpuBinder extends Binder { 2162 ActivityManagerService mActivityManagerService; 2163 CpuBinder(ActivityManagerService activityManagerService) { 2164 mActivityManagerService = activityManagerService; 2165 } 2166 2167 @Override 2168 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2169 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2170 != PackageManager.PERMISSION_GRANTED) { 2171 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2172 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2173 + " without permission " + android.Manifest.permission.DUMP); 2174 return; 2175 } 2176 2177 synchronized (mActivityManagerService.mProcessCpuThread) { 2178 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2179 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2180 SystemClock.uptimeMillis())); 2181 } 2182 } 2183 } 2184 2185 public static final class Lifecycle extends SystemService { 2186 private final ActivityManagerService mService; 2187 2188 public Lifecycle(Context context) { 2189 super(context); 2190 mService = new ActivityManagerService(context); 2191 } 2192 2193 @Override 2194 public void onStart() { 2195 mService.start(); 2196 } 2197 2198 public ActivityManagerService getService() { 2199 return mService; 2200 } 2201 } 2202 2203 // Note: This method is invoked on the main thread but may need to attach various 2204 // handlers to other threads. So take care to be explicit about the looper. 2205 public ActivityManagerService(Context systemContext) { 2206 mContext = systemContext; 2207 mFactoryTest = FactoryTest.getMode(); 2208 mSystemThread = ActivityThread.currentActivityThread(); 2209 2210 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2211 2212 mHandlerThread = new ServiceThread(TAG, 2213 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2214 mHandlerThread.start(); 2215 mHandler = new MainHandler(mHandlerThread.getLooper()); 2216 2217 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2218 "foreground", BROADCAST_FG_TIMEOUT, false); 2219 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2220 "background", BROADCAST_BG_TIMEOUT, true); 2221 mBroadcastQueues[0] = mFgBroadcastQueue; 2222 mBroadcastQueues[1] = mBgBroadcastQueue; 2223 2224 mServices = new ActiveServices(this); 2225 mProviderMap = new ProviderMap(this); 2226 2227 // TODO: Move creation of battery stats service outside of activity manager service. 2228 File dataDir = Environment.getDataDirectory(); 2229 File systemDir = new File(dataDir, "system"); 2230 systemDir.mkdirs(); 2231 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2232 mBatteryStatsService.getActiveStatistics().readLocked(); 2233 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2234 mOnBattery = DEBUG_POWER ? true 2235 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2236 mBatteryStatsService.getActiveStatistics().setCallback(this); 2237 2238 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2239 2240 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2241 2242 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2243 2244 // User 0 is the first and only user that runs at boot. 2245 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2246 mUserLru.add(Integer.valueOf(0)); 2247 updateStartedUserArrayLocked(); 2248 2249 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2250 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2251 2252 mConfiguration.setToDefaults(); 2253 mConfiguration.setLocale(Locale.getDefault()); 2254 2255 mConfigurationSeq = mConfiguration.seq = 1; 2256 mProcessCpuTracker.init(); 2257 2258 final Resources res = mContext.getResources(); 2259 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 2260 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 2261 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 2262 2263 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2264 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2265 mStackSupervisor = new ActivityStackSupervisor(this); 2266 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2267 2268 mProcessCpuThread = new Thread("CpuTracker") { 2269 @Override 2270 public void run() { 2271 while (true) { 2272 try { 2273 try { 2274 synchronized(this) { 2275 final long now = SystemClock.uptimeMillis(); 2276 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2277 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2278 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2279 // + ", write delay=" + nextWriteDelay); 2280 if (nextWriteDelay < nextCpuDelay) { 2281 nextCpuDelay = nextWriteDelay; 2282 } 2283 if (nextCpuDelay > 0) { 2284 mProcessCpuMutexFree.set(true); 2285 this.wait(nextCpuDelay); 2286 } 2287 } 2288 } catch (InterruptedException e) { 2289 } 2290 updateCpuStatsNow(); 2291 } catch (Exception e) { 2292 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2293 } 2294 } 2295 } 2296 }; 2297 2298 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2299 2300 Watchdog.getInstance().addMonitor(this); 2301 Watchdog.getInstance().addThread(mHandler); 2302 } 2303 2304 public void setSystemServiceManager(SystemServiceManager mgr) { 2305 mSystemServiceManager = mgr; 2306 } 2307 2308 private void start() { 2309 Process.removeAllProcessGroups(); 2310 mProcessCpuThread.start(); 2311 2312 mBatteryStatsService.publish(mContext); 2313 mAppOpsService.publish(mContext); 2314 Slog.d("AppOps", "AppOpsService published"); 2315 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2316 } 2317 2318 public void initPowerManagement() { 2319 mStackSupervisor.initPowerManagement(); 2320 mBatteryStatsService.initPowerManagement(); 2321 } 2322 2323 @Override 2324 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2325 throws RemoteException { 2326 if (code == SYSPROPS_TRANSACTION) { 2327 // We need to tell all apps about the system property change. 2328 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2329 synchronized(this) { 2330 final int NP = mProcessNames.getMap().size(); 2331 for (int ip=0; ip<NP; ip++) { 2332 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2333 final int NA = apps.size(); 2334 for (int ia=0; ia<NA; ia++) { 2335 ProcessRecord app = apps.valueAt(ia); 2336 if (app.thread != null) { 2337 procs.add(app.thread.asBinder()); 2338 } 2339 } 2340 } 2341 } 2342 2343 int N = procs.size(); 2344 for (int i=0; i<N; i++) { 2345 Parcel data2 = Parcel.obtain(); 2346 try { 2347 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2348 } catch (RemoteException e) { 2349 } 2350 data2.recycle(); 2351 } 2352 } 2353 try { 2354 return super.onTransact(code, data, reply, flags); 2355 } catch (RuntimeException e) { 2356 // The activity manager only throws security exceptions, so let's 2357 // log all others. 2358 if (!(e instanceof SecurityException)) { 2359 Slog.wtf(TAG, "Activity Manager Crash", e); 2360 } 2361 throw e; 2362 } 2363 } 2364 2365 void updateCpuStats() { 2366 final long now = SystemClock.uptimeMillis(); 2367 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2368 return; 2369 } 2370 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2371 synchronized (mProcessCpuThread) { 2372 mProcessCpuThread.notify(); 2373 } 2374 } 2375 } 2376 2377 void updateCpuStatsNow() { 2378 synchronized (mProcessCpuThread) { 2379 mProcessCpuMutexFree.set(false); 2380 final long now = SystemClock.uptimeMillis(); 2381 boolean haveNewCpuStats = false; 2382 2383 if (MONITOR_CPU_USAGE && 2384 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2385 mLastCpuTime.set(now); 2386 haveNewCpuStats = true; 2387 mProcessCpuTracker.update(); 2388 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2389 //Slog.i(TAG, "Total CPU usage: " 2390 // + mProcessCpu.getTotalCpuPercent() + "%"); 2391 2392 // Slog the cpu usage if the property is set. 2393 if ("true".equals(SystemProperties.get("events.cpu"))) { 2394 int user = mProcessCpuTracker.getLastUserTime(); 2395 int system = mProcessCpuTracker.getLastSystemTime(); 2396 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2397 int irq = mProcessCpuTracker.getLastIrqTime(); 2398 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2399 int idle = mProcessCpuTracker.getLastIdleTime(); 2400 2401 int total = user + system + iowait + irq + softIrq + idle; 2402 if (total == 0) total = 1; 2403 2404 EventLog.writeEvent(EventLogTags.CPU, 2405 ((user+system+iowait+irq+softIrq) * 100) / total, 2406 (user * 100) / total, 2407 (system * 100) / total, 2408 (iowait * 100) / total, 2409 (irq * 100) / total, 2410 (softIrq * 100) / total); 2411 } 2412 } 2413 2414 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2415 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2416 synchronized(bstats) { 2417 synchronized(mPidsSelfLocked) { 2418 if (haveNewCpuStats) { 2419 if (mOnBattery) { 2420 int perc = bstats.startAddingCpuLocked(); 2421 int totalUTime = 0; 2422 int totalSTime = 0; 2423 final int N = mProcessCpuTracker.countStats(); 2424 for (int i=0; i<N; i++) { 2425 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2426 if (!st.working) { 2427 continue; 2428 } 2429 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2430 int otherUTime = (st.rel_utime*perc)/100; 2431 int otherSTime = (st.rel_stime*perc)/100; 2432 totalUTime += otherUTime; 2433 totalSTime += otherSTime; 2434 if (pr != null) { 2435 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2436 if (ps == null || !ps.isActive()) { 2437 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2438 pr.info.uid, pr.processName); 2439 } 2440 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2441 st.rel_stime-otherSTime); 2442 ps.addSpeedStepTimes(cpuSpeedTimes); 2443 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2444 } else { 2445 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2446 if (ps == null || !ps.isActive()) { 2447 st.batteryStats = ps = bstats.getProcessStatsLocked( 2448 bstats.mapUid(st.uid), st.name); 2449 } 2450 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2451 st.rel_stime-otherSTime); 2452 ps.addSpeedStepTimes(cpuSpeedTimes); 2453 } 2454 } 2455 bstats.finishAddingCpuLocked(perc, totalUTime, 2456 totalSTime, cpuSpeedTimes); 2457 } 2458 } 2459 } 2460 2461 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2462 mLastWriteTime = now; 2463 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2464 } 2465 } 2466 } 2467 } 2468 2469 @Override 2470 public void batteryNeedsCpuUpdate() { 2471 updateCpuStatsNow(); 2472 } 2473 2474 @Override 2475 public void batteryPowerChanged(boolean onBattery) { 2476 // When plugging in, update the CPU stats first before changing 2477 // the plug state. 2478 updateCpuStatsNow(); 2479 synchronized (this) { 2480 synchronized(mPidsSelfLocked) { 2481 mOnBattery = DEBUG_POWER ? true : onBattery; 2482 } 2483 } 2484 } 2485 2486 /** 2487 * Initialize the application bind args. These are passed to each 2488 * process when the bindApplication() IPC is sent to the process. They're 2489 * lazily setup to make sure the services are running when they're asked for. 2490 */ 2491 private HashMap<String, IBinder> getCommonServicesLocked() { 2492 if (mAppBindArgs == null) { 2493 mAppBindArgs = new HashMap<String, IBinder>(); 2494 2495 // Setup the application init args 2496 mAppBindArgs.put("package", ServiceManager.getService("package")); 2497 mAppBindArgs.put("window", ServiceManager.getService("window")); 2498 mAppBindArgs.put(Context.ALARM_SERVICE, 2499 ServiceManager.getService(Context.ALARM_SERVICE)); 2500 } 2501 return mAppBindArgs; 2502 } 2503 2504 final void setFocusedActivityLocked(ActivityRecord r) { 2505 if (mFocusedActivity != r) { 2506 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2507 mFocusedActivity = r; 2508 if (r.task != null && r.task.voiceInteractor != null) { 2509 startRunningVoiceLocked(); 2510 } else { 2511 finishRunningVoiceLocked(); 2512 } 2513 mStackSupervisor.setFocusedStack(r); 2514 if (r != null) { 2515 mWindowManager.setFocusedApp(r.appToken, true); 2516 } 2517 applyUpdateLockStateLocked(r); 2518 } 2519 } 2520 2521 final void clearFocusedActivity(ActivityRecord r) { 2522 if (mFocusedActivity == r) { 2523 mFocusedActivity = null; 2524 } 2525 } 2526 2527 @Override 2528 public void setFocusedStack(int stackId) { 2529 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2530 synchronized (ActivityManagerService.this) { 2531 ActivityStack stack = mStackSupervisor.getStack(stackId); 2532 if (stack != null) { 2533 ActivityRecord r = stack.topRunningActivityLocked(null); 2534 if (r != null) { 2535 setFocusedActivityLocked(r); 2536 } 2537 } 2538 } 2539 } 2540 2541 @Override 2542 public void notifyActivityDrawn(IBinder token) { 2543 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2544 synchronized (this) { 2545 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2546 if (r != null) { 2547 r.task.stack.notifyActivityDrawnLocked(r); 2548 } 2549 } 2550 } 2551 2552 final void applyUpdateLockStateLocked(ActivityRecord r) { 2553 // Modifications to the UpdateLock state are done on our handler, outside 2554 // the activity manager's locks. The new state is determined based on the 2555 // state *now* of the relevant activity record. The object is passed to 2556 // the handler solely for logging detail, not to be consulted/modified. 2557 final boolean nextState = r != null && r.immersive; 2558 mHandler.sendMessage( 2559 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2560 } 2561 2562 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2563 Message msg = Message.obtain(); 2564 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2565 msg.obj = r.task.askedCompatMode ? null : r; 2566 mHandler.sendMessage(msg); 2567 } 2568 2569 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2570 String what, Object obj, ProcessRecord srcApp) { 2571 app.lastActivityTime = now; 2572 2573 if (app.activities.size() > 0) { 2574 // Don't want to touch dependent processes that are hosting activities. 2575 return index; 2576 } 2577 2578 int lrui = mLruProcesses.lastIndexOf(app); 2579 if (lrui < 0) { 2580 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2581 + what + " " + obj + " from " + srcApp); 2582 return index; 2583 } 2584 2585 if (lrui >= index) { 2586 // Don't want to cause this to move dependent processes *back* in the 2587 // list as if they were less frequently used. 2588 return index; 2589 } 2590 2591 if (lrui >= mLruProcessActivityStart) { 2592 // Don't want to touch dependent processes that are hosting activities. 2593 return index; 2594 } 2595 2596 mLruProcesses.remove(lrui); 2597 if (index > 0) { 2598 index--; 2599 } 2600 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2601 + " in LRU list: " + app); 2602 mLruProcesses.add(index, app); 2603 return index; 2604 } 2605 2606 final void removeLruProcessLocked(ProcessRecord app) { 2607 int lrui = mLruProcesses.lastIndexOf(app); 2608 if (lrui >= 0) { 2609 if (lrui <= mLruProcessActivityStart) { 2610 mLruProcessActivityStart--; 2611 } 2612 if (lrui <= mLruProcessServiceStart) { 2613 mLruProcessServiceStart--; 2614 } 2615 mLruProcesses.remove(lrui); 2616 } 2617 } 2618 2619 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2620 ProcessRecord client) { 2621 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2622 || app.treatLikeActivity; 2623 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2624 if (!activityChange && hasActivity) { 2625 // The process has activities, so we are only allowing activity-based adjustments 2626 // to move it. It should be kept in the front of the list with other 2627 // processes that have activities, and we don't want those to change their 2628 // order except due to activity operations. 2629 return; 2630 } 2631 2632 mLruSeq++; 2633 final long now = SystemClock.uptimeMillis(); 2634 app.lastActivityTime = now; 2635 2636 // First a quick reject: if the app is already at the position we will 2637 // put it, then there is nothing to do. 2638 if (hasActivity) { 2639 final int N = mLruProcesses.size(); 2640 if (N > 0 && mLruProcesses.get(N-1) == app) { 2641 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2642 return; 2643 } 2644 } else { 2645 if (mLruProcessServiceStart > 0 2646 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2647 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2648 return; 2649 } 2650 } 2651 2652 int lrui = mLruProcesses.lastIndexOf(app); 2653 2654 if (app.persistent && lrui >= 0) { 2655 // We don't care about the position of persistent processes, as long as 2656 // they are in the list. 2657 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2658 return; 2659 } 2660 2661 /* In progress: compute new position first, so we can avoid doing work 2662 if the process is not actually going to move. Not yet working. 2663 int addIndex; 2664 int nextIndex; 2665 boolean inActivity = false, inService = false; 2666 if (hasActivity) { 2667 // Process has activities, put it at the very tipsy-top. 2668 addIndex = mLruProcesses.size(); 2669 nextIndex = mLruProcessServiceStart; 2670 inActivity = true; 2671 } else if (hasService) { 2672 // Process has services, put it at the top of the service list. 2673 addIndex = mLruProcessActivityStart; 2674 nextIndex = mLruProcessServiceStart; 2675 inActivity = true; 2676 inService = true; 2677 } else { 2678 // Process not otherwise of interest, it goes to the top of the non-service area. 2679 addIndex = mLruProcessServiceStart; 2680 if (client != null) { 2681 int clientIndex = mLruProcesses.lastIndexOf(client); 2682 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2683 + app); 2684 if (clientIndex >= 0 && addIndex > clientIndex) { 2685 addIndex = clientIndex; 2686 } 2687 } 2688 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2689 } 2690 2691 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2692 + mLruProcessActivityStart + "): " + app); 2693 */ 2694 2695 if (lrui >= 0) { 2696 if (lrui < mLruProcessActivityStart) { 2697 mLruProcessActivityStart--; 2698 } 2699 if (lrui < mLruProcessServiceStart) { 2700 mLruProcessServiceStart--; 2701 } 2702 /* 2703 if (addIndex > lrui) { 2704 addIndex--; 2705 } 2706 if (nextIndex > lrui) { 2707 nextIndex--; 2708 } 2709 */ 2710 mLruProcesses.remove(lrui); 2711 } 2712 2713 /* 2714 mLruProcesses.add(addIndex, app); 2715 if (inActivity) { 2716 mLruProcessActivityStart++; 2717 } 2718 if (inService) { 2719 mLruProcessActivityStart++; 2720 } 2721 */ 2722 2723 int nextIndex; 2724 if (hasActivity) { 2725 final int N = mLruProcesses.size(); 2726 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2727 // Process doesn't have activities, but has clients with 2728 // activities... move it up, but one below the top (the top 2729 // should always have a real activity). 2730 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2731 mLruProcesses.add(N-1, app); 2732 // To keep it from spamming the LRU list (by making a bunch of clients), 2733 // we will push down any other entries owned by the app. 2734 final int uid = app.info.uid; 2735 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2736 ProcessRecord subProc = mLruProcesses.get(i); 2737 if (subProc.info.uid == uid) { 2738 // We want to push this one down the list. If the process after 2739 // it is for the same uid, however, don't do so, because we don't 2740 // want them internally to be re-ordered. 2741 if (mLruProcesses.get(i-1).info.uid != uid) { 2742 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2743 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2744 ProcessRecord tmp = mLruProcesses.get(i); 2745 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2746 mLruProcesses.set(i-1, tmp); 2747 i--; 2748 } 2749 } else { 2750 // A gap, we can stop here. 2751 break; 2752 } 2753 } 2754 } else { 2755 // Process has activities, put it at the very tipsy-top. 2756 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2757 mLruProcesses.add(app); 2758 } 2759 nextIndex = mLruProcessServiceStart; 2760 } else if (hasService) { 2761 // Process has services, put it at the top of the service list. 2762 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2763 mLruProcesses.add(mLruProcessActivityStart, app); 2764 nextIndex = mLruProcessServiceStart; 2765 mLruProcessActivityStart++; 2766 } else { 2767 // Process not otherwise of interest, it goes to the top of the non-service area. 2768 int index = mLruProcessServiceStart; 2769 if (client != null) { 2770 // If there is a client, don't allow the process to be moved up higher 2771 // in the list than that client. 2772 int clientIndex = mLruProcesses.lastIndexOf(client); 2773 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2774 + " when updating " + app); 2775 if (clientIndex <= lrui) { 2776 // Don't allow the client index restriction to push it down farther in the 2777 // list than it already is. 2778 clientIndex = lrui; 2779 } 2780 if (clientIndex >= 0 && index > clientIndex) { 2781 index = clientIndex; 2782 } 2783 } 2784 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2785 mLruProcesses.add(index, app); 2786 nextIndex = index-1; 2787 mLruProcessActivityStart++; 2788 mLruProcessServiceStart++; 2789 } 2790 2791 // If the app is currently using a content provider or service, 2792 // bump those processes as well. 2793 for (int j=app.connections.size()-1; j>=0; j--) { 2794 ConnectionRecord cr = app.connections.valueAt(j); 2795 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2796 && cr.binding.service.app != null 2797 && cr.binding.service.app.lruSeq != mLruSeq 2798 && !cr.binding.service.app.persistent) { 2799 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2800 "service connection", cr, app); 2801 } 2802 } 2803 for (int j=app.conProviders.size()-1; j>=0; j--) { 2804 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2805 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2806 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2807 "provider reference", cpr, app); 2808 } 2809 } 2810 } 2811 2812 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2813 if (uid == Process.SYSTEM_UID) { 2814 // The system gets to run in any process. If there are multiple 2815 // processes with the same uid, just pick the first (this 2816 // should never happen). 2817 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2818 if (procs == null) return null; 2819 final int N = procs.size(); 2820 for (int i = 0; i < N; i++) { 2821 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2822 } 2823 } 2824 ProcessRecord proc = mProcessNames.get(processName, uid); 2825 if (false && proc != null && !keepIfLarge 2826 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2827 && proc.lastCachedPss >= 4000) { 2828 // Turn this condition on to cause killing to happen regularly, for testing. 2829 if (proc.baseProcessTracker != null) { 2830 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2831 } 2832 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2833 } else if (proc != null && !keepIfLarge 2834 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2835 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2836 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2837 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2838 if (proc.baseProcessTracker != null) { 2839 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2840 } 2841 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2842 } 2843 } 2844 return proc; 2845 } 2846 2847 void ensurePackageDexOpt(String packageName) { 2848 IPackageManager pm = AppGlobals.getPackageManager(); 2849 try { 2850 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2851 mDidDexOpt = true; 2852 } 2853 } catch (RemoteException e) { 2854 } 2855 } 2856 2857 boolean isNextTransitionForward() { 2858 int transit = mWindowManager.getPendingAppTransition(); 2859 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2860 || transit == AppTransition.TRANSIT_TASK_OPEN 2861 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2862 } 2863 2864 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2865 String processName, String abiOverride, int uid, Runnable crashHandler) { 2866 synchronized(this) { 2867 ApplicationInfo info = new ApplicationInfo(); 2868 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2869 // For isolated processes, the former contains the parent's uid and the latter the 2870 // actual uid of the isolated process. 2871 // In the special case introduced by this method (which is, starting an isolated 2872 // process directly from the SystemServer without an actual parent app process) the 2873 // closest thing to a parent's uid is SYSTEM_UID. 2874 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2875 // the |isolated| logic in the ProcessRecord constructor. 2876 info.uid = Process.SYSTEM_UID; 2877 info.processName = processName; 2878 info.className = entryPoint; 2879 info.packageName = "android"; 2880 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2881 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2882 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2883 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2884 crashHandler); 2885 return proc != null ? proc.pid : 0; 2886 } 2887 } 2888 2889 final ProcessRecord startProcessLocked(String processName, 2890 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2891 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2892 boolean isolated, boolean keepIfLarge) { 2893 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2894 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2895 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2896 null /* crashHandler */); 2897 } 2898 2899 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2900 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2901 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2902 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2903 ProcessRecord app; 2904 if (!isolated) { 2905 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2906 } else { 2907 // If this is an isolated process, it can't re-use an existing process. 2908 app = null; 2909 } 2910 // We don't have to do anything more if: 2911 // (1) There is an existing application record; and 2912 // (2) The caller doesn't think it is dead, OR there is no thread 2913 // object attached to it so we know it couldn't have crashed; and 2914 // (3) There is a pid assigned to it, so it is either starting or 2915 // already running. 2916 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2917 + " app=" + app + " knownToBeDead=" + knownToBeDead 2918 + " thread=" + (app != null ? app.thread : null) 2919 + " pid=" + (app != null ? app.pid : -1)); 2920 if (app != null && app.pid > 0) { 2921 if (!knownToBeDead || app.thread == null) { 2922 // We already have the app running, or are waiting for it to 2923 // come up (we have a pid but not yet its thread), so keep it. 2924 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2925 // If this is a new package in the process, add the package to the list 2926 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2927 return app; 2928 } 2929 2930 // An application record is attached to a previous process, 2931 // clean it up now. 2932 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2933 Process.killProcessGroup(app.info.uid, app.pid); 2934 handleAppDiedLocked(app, true, true); 2935 } 2936 2937 String hostingNameStr = hostingName != null 2938 ? hostingName.flattenToShortString() : null; 2939 2940 if (!isolated) { 2941 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2942 // If we are in the background, then check to see if this process 2943 // is bad. If so, we will just silently fail. 2944 if (mBadProcesses.get(info.processName, info.uid) != null) { 2945 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2946 + "/" + info.processName); 2947 return null; 2948 } 2949 } else { 2950 // When the user is explicitly starting a process, then clear its 2951 // crash count so that we won't make it bad until they see at 2952 // least one crash dialog again, and make the process good again 2953 // if it had been bad. 2954 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2955 + "/" + info.processName); 2956 mProcessCrashTimes.remove(info.processName, info.uid); 2957 if (mBadProcesses.get(info.processName, info.uid) != null) { 2958 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2959 UserHandle.getUserId(info.uid), info.uid, 2960 info.processName); 2961 mBadProcesses.remove(info.processName, info.uid); 2962 if (app != null) { 2963 app.bad = false; 2964 } 2965 } 2966 } 2967 } 2968 2969 if (app == null) { 2970 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2971 app.crashHandler = crashHandler; 2972 if (app == null) { 2973 Slog.w(TAG, "Failed making new process record for " 2974 + processName + "/" + info.uid + " isolated=" + isolated); 2975 return null; 2976 } 2977 mProcessNames.put(processName, app.uid, app); 2978 if (isolated) { 2979 mIsolatedProcesses.put(app.uid, app); 2980 } 2981 } else { 2982 // If this is a new package in the process, add the package to the list 2983 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2984 } 2985 2986 // If the system is not ready yet, then hold off on starting this 2987 // process until it is. 2988 if (!mProcessesReady 2989 && !isAllowedWhileBooting(info) 2990 && !allowWhileBooting) { 2991 if (!mProcessesOnHold.contains(app)) { 2992 mProcessesOnHold.add(app); 2993 } 2994 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2995 return app; 2996 } 2997 2998 startProcessLocked( 2999 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3000 return (app.pid != 0) ? app : null; 3001 } 3002 3003 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3004 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3005 } 3006 3007 private final void startProcessLocked(ProcessRecord app, 3008 String hostingType, String hostingNameStr) { 3009 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3010 null /* entryPoint */, null /* entryPointArgs */); 3011 } 3012 3013 private final void startProcessLocked(ProcessRecord app, String hostingType, 3014 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3015 if (app.pid > 0 && app.pid != MY_PID) { 3016 synchronized (mPidsSelfLocked) { 3017 mPidsSelfLocked.remove(app.pid); 3018 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3019 } 3020 app.setPid(0); 3021 } 3022 3023 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3024 "startProcessLocked removing on hold: " + app); 3025 mProcessesOnHold.remove(app); 3026 3027 updateCpuStats(); 3028 3029 try { 3030 int uid = app.uid; 3031 3032 int[] gids = null; 3033 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3034 if (!app.isolated) { 3035 int[] permGids = null; 3036 try { 3037 final PackageManager pm = mContext.getPackageManager(); 3038 permGids = pm.getPackageGids(app.info.packageName); 3039 3040 if (Environment.isExternalStorageEmulated()) { 3041 if (pm.checkPermission( 3042 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3043 app.info.packageName) == PERMISSION_GRANTED) { 3044 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3045 } else { 3046 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3047 } 3048 } 3049 } catch (PackageManager.NameNotFoundException e) { 3050 Slog.w(TAG, "Unable to retrieve gids", e); 3051 } 3052 3053 /* 3054 * Add shared application and profile GIDs so applications can share some 3055 * resources like shared libraries and access user-wide resources 3056 */ 3057 if (permGids == null) { 3058 gids = new int[2]; 3059 } else { 3060 gids = new int[permGids.length + 2]; 3061 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3062 } 3063 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3064 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3065 } 3066 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3067 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3068 && mTopComponent != null 3069 && app.processName.equals(mTopComponent.getPackageName())) { 3070 uid = 0; 3071 } 3072 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3073 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3074 uid = 0; 3075 } 3076 } 3077 int debugFlags = 0; 3078 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3079 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3080 // Also turn on CheckJNI for debuggable apps. It's quite 3081 // awkward to turn on otherwise. 3082 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3083 } 3084 // Run the app in safe mode if its manifest requests so or the 3085 // system is booted in safe mode. 3086 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3087 mSafeMode == true) { 3088 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3089 } 3090 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3091 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3092 } 3093 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3094 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3095 } 3096 if ("1".equals(SystemProperties.get("debug.assert"))) { 3097 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3098 } 3099 3100 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3101 if (requiredAbi == null) { 3102 requiredAbi = Build.SUPPORTED_ABIS[0]; 3103 } 3104 3105 // Start the process. It will either succeed and return a result containing 3106 // the PID of the new process, or else throw a RuntimeException. 3107 boolean isActivityProcess = (entryPoint == null); 3108 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3109 Process.ProcessStartResult startResult = Process.start(entryPoint, 3110 app.processName, uid, uid, gids, debugFlags, mountExternal, 3111 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3112 3113 if (app.isolated) { 3114 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3115 } 3116 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3117 3118 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3119 UserHandle.getUserId(uid), startResult.pid, uid, 3120 app.processName, hostingType, 3121 hostingNameStr != null ? hostingNameStr : ""); 3122 3123 if (app.persistent) { 3124 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3125 } 3126 3127 StringBuilder buf = mStringBuilder; 3128 buf.setLength(0); 3129 buf.append("Start proc "); 3130 buf.append(app.processName); 3131 if (!isActivityProcess) { 3132 buf.append(" ["); 3133 buf.append(entryPoint); 3134 buf.append("]"); 3135 } 3136 buf.append(" for "); 3137 buf.append(hostingType); 3138 if (hostingNameStr != null) { 3139 buf.append(" "); 3140 buf.append(hostingNameStr); 3141 } 3142 buf.append(": pid="); 3143 buf.append(startResult.pid); 3144 buf.append(" uid="); 3145 buf.append(uid); 3146 buf.append(" gids={"); 3147 if (gids != null) { 3148 for (int gi=0; gi<gids.length; gi++) { 3149 if (gi != 0) buf.append(", "); 3150 buf.append(gids[gi]); 3151 3152 } 3153 } 3154 buf.append("}"); 3155 if (requiredAbi != null) { 3156 buf.append(" abi="); 3157 buf.append(requiredAbi); 3158 } 3159 Slog.i(TAG, buf.toString()); 3160 app.setPid(startResult.pid); 3161 app.usingWrapper = startResult.usingWrapper; 3162 app.removed = false; 3163 app.killedByAm = false; 3164 synchronized (mPidsSelfLocked) { 3165 this.mPidsSelfLocked.put(startResult.pid, app); 3166 if (isActivityProcess) { 3167 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3168 msg.obj = app; 3169 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3170 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3171 } 3172 } 3173 } catch (RuntimeException e) { 3174 // XXX do better error recovery. 3175 app.setPid(0); 3176 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3177 if (app.isolated) { 3178 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3179 } 3180 Slog.e(TAG, "Failure starting process " + app.processName, e); 3181 } 3182 } 3183 3184 void updateUsageStats(ActivityRecord component, boolean resumed) { 3185 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3186 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3187 if (resumed) { 3188 if (mUsageStatsService != null) { 3189 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3190 System.currentTimeMillis(), 3191 UsageEvents.Event.MOVE_TO_FOREGROUND); 3192 } 3193 synchronized (stats) { 3194 stats.noteActivityResumedLocked(component.app.uid); 3195 } 3196 } else { 3197 if (mUsageStatsService != null) { 3198 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3199 System.currentTimeMillis(), 3200 UsageEvents.Event.MOVE_TO_BACKGROUND); 3201 } 3202 synchronized (stats) { 3203 stats.noteActivityPausedLocked(component.app.uid); 3204 } 3205 } 3206 } 3207 3208 Intent getHomeIntent() { 3209 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3210 intent.setComponent(mTopComponent); 3211 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3212 intent.addCategory(Intent.CATEGORY_HOME); 3213 } 3214 return intent; 3215 } 3216 3217 boolean startHomeActivityLocked(int userId) { 3218 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3219 && mTopAction == null) { 3220 // We are running in factory test mode, but unable to find 3221 // the factory test app, so just sit around displaying the 3222 // error message and don't try to start anything. 3223 return false; 3224 } 3225 Intent intent = getHomeIntent(); 3226 ActivityInfo aInfo = 3227 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3228 if (aInfo != null) { 3229 intent.setComponent(new ComponentName( 3230 aInfo.applicationInfo.packageName, aInfo.name)); 3231 // Don't do this if the home app is currently being 3232 // instrumented. 3233 aInfo = new ActivityInfo(aInfo); 3234 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3235 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3236 aInfo.applicationInfo.uid, true); 3237 if (app == null || app.instrumentationClass == null) { 3238 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3239 mStackSupervisor.startHomeActivity(intent, aInfo); 3240 } 3241 } 3242 3243 return true; 3244 } 3245 3246 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3247 ActivityInfo ai = null; 3248 ComponentName comp = intent.getComponent(); 3249 try { 3250 if (comp != null) { 3251 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3252 } else { 3253 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3254 intent, 3255 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3256 flags, userId); 3257 3258 if (info != null) { 3259 ai = info.activityInfo; 3260 } 3261 } 3262 } catch (RemoteException e) { 3263 // ignore 3264 } 3265 3266 return ai; 3267 } 3268 3269 /** 3270 * Starts the "new version setup screen" if appropriate. 3271 */ 3272 void startSetupActivityLocked() { 3273 // Only do this once per boot. 3274 if (mCheckedForSetup) { 3275 return; 3276 } 3277 3278 // We will show this screen if the current one is a different 3279 // version than the last one shown, and we are not running in 3280 // low-level factory test mode. 3281 final ContentResolver resolver = mContext.getContentResolver(); 3282 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3283 Settings.Global.getInt(resolver, 3284 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3285 mCheckedForSetup = true; 3286 3287 // See if we should be showing the platform update setup UI. 3288 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3289 List<ResolveInfo> ris = mContext.getPackageManager() 3290 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3291 3292 // We don't allow third party apps to replace this. 3293 ResolveInfo ri = null; 3294 for (int i=0; ris != null && i<ris.size(); i++) { 3295 if ((ris.get(i).activityInfo.applicationInfo.flags 3296 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3297 ri = ris.get(i); 3298 break; 3299 } 3300 } 3301 3302 if (ri != null) { 3303 String vers = ri.activityInfo.metaData != null 3304 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3305 : null; 3306 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3307 vers = ri.activityInfo.applicationInfo.metaData.getString( 3308 Intent.METADATA_SETUP_VERSION); 3309 } 3310 String lastVers = Settings.Secure.getString( 3311 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3312 if (vers != null && !vers.equals(lastVers)) { 3313 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3314 intent.setComponent(new ComponentName( 3315 ri.activityInfo.packageName, ri.activityInfo.name)); 3316 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3317 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3318 null); 3319 } 3320 } 3321 } 3322 } 3323 3324 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3325 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3326 } 3327 3328 void enforceNotIsolatedCaller(String caller) { 3329 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3330 throw new SecurityException("Isolated process not allowed to call " + caller); 3331 } 3332 } 3333 3334 @Override 3335 public int getFrontActivityScreenCompatMode() { 3336 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3337 synchronized (this) { 3338 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3339 } 3340 } 3341 3342 @Override 3343 public void setFrontActivityScreenCompatMode(int mode) { 3344 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3345 "setFrontActivityScreenCompatMode"); 3346 synchronized (this) { 3347 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3348 } 3349 } 3350 3351 @Override 3352 public int getPackageScreenCompatMode(String packageName) { 3353 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3354 synchronized (this) { 3355 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3356 } 3357 } 3358 3359 @Override 3360 public void setPackageScreenCompatMode(String packageName, int mode) { 3361 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3362 "setPackageScreenCompatMode"); 3363 synchronized (this) { 3364 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3365 } 3366 } 3367 3368 @Override 3369 public boolean getPackageAskScreenCompat(String packageName) { 3370 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3371 synchronized (this) { 3372 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3373 } 3374 } 3375 3376 @Override 3377 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3378 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3379 "setPackageAskScreenCompat"); 3380 synchronized (this) { 3381 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3382 } 3383 } 3384 3385 private void dispatchProcessesChanged() { 3386 int N; 3387 synchronized (this) { 3388 N = mPendingProcessChanges.size(); 3389 if (mActiveProcessChanges.length < N) { 3390 mActiveProcessChanges = new ProcessChangeItem[N]; 3391 } 3392 mPendingProcessChanges.toArray(mActiveProcessChanges); 3393 mAvailProcessChanges.addAll(mPendingProcessChanges); 3394 mPendingProcessChanges.clear(); 3395 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3396 } 3397 3398 int i = mProcessObservers.beginBroadcast(); 3399 while (i > 0) { 3400 i--; 3401 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3402 if (observer != null) { 3403 try { 3404 for (int j=0; j<N; j++) { 3405 ProcessChangeItem item = mActiveProcessChanges[j]; 3406 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3407 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3408 + item.pid + " uid=" + item.uid + ": " 3409 + item.foregroundActivities); 3410 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3411 item.foregroundActivities); 3412 } 3413 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3414 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3415 + item.pid + " uid=" + item.uid + ": " + item.processState); 3416 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3417 } 3418 } 3419 } catch (RemoteException e) { 3420 } 3421 } 3422 } 3423 mProcessObservers.finishBroadcast(); 3424 } 3425 3426 private void dispatchProcessDied(int pid, int uid) { 3427 int i = mProcessObservers.beginBroadcast(); 3428 while (i > 0) { 3429 i--; 3430 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3431 if (observer != null) { 3432 try { 3433 observer.onProcessDied(pid, uid); 3434 } catch (RemoteException e) { 3435 } 3436 } 3437 } 3438 mProcessObservers.finishBroadcast(); 3439 } 3440 3441 @Override 3442 public final int startActivity(IApplicationThread caller, String callingPackage, 3443 Intent intent, String resolvedType, IBinder resultTo, 3444 String resultWho, int requestCode, int startFlags, 3445 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3446 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3447 resultWho, requestCode, 3448 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3449 } 3450 3451 @Override 3452 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3453 Intent intent, String resolvedType, IBinder resultTo, 3454 String resultWho, int requestCode, int startFlags, 3455 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3456 enforceNotIsolatedCaller("startActivity"); 3457 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3458 false, ALLOW_FULL_ONLY, "startActivity", null); 3459 // TODO: Switch to user app stacks here. 3460 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3461 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3462 null, null, options, userId, null, null); 3463 } 3464 3465 @Override 3466 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3467 Intent intent, String resolvedType, IBinder resultTo, 3468 String resultWho, int requestCode, int startFlags, 3469 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3470 3471 // This is very dangerous -- it allows you to perform a start activity (including 3472 // permission grants) as any app that may launch one of your own activities. So 3473 // we will only allow this to be done from activities that are part of the core framework, 3474 // and then only when they are running as the system. 3475 final ActivityRecord sourceRecord; 3476 final int targetUid; 3477 final String targetPackage; 3478 synchronized (this) { 3479 if (resultTo == null) { 3480 throw new SecurityException("Must be called from an activity"); 3481 } 3482 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3483 if (sourceRecord == null) { 3484 throw new SecurityException("Called with bad activity token: " + resultTo); 3485 } 3486 if (!sourceRecord.info.packageName.equals("android")) { 3487 throw new SecurityException( 3488 "Must be called from an activity that is declared in the android package"); 3489 } 3490 if (sourceRecord.app == null) { 3491 throw new SecurityException("Called without a process attached to activity"); 3492 } 3493 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3494 // This is still okay, as long as this activity is running under the 3495 // uid of the original calling activity. 3496 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3497 throw new SecurityException( 3498 "Calling activity in uid " + sourceRecord.app.uid 3499 + " must be system uid or original calling uid " 3500 + sourceRecord.launchedFromUid); 3501 } 3502 } 3503 targetUid = sourceRecord.launchedFromUid; 3504 targetPackage = sourceRecord.launchedFromPackage; 3505 } 3506 3507 // TODO: Switch to user app stacks here. 3508 try { 3509 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3510 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3511 null, null, null, null, options, UserHandle.getUserId(sourceRecord.app.uid), 3512 null, null); 3513 return ret; 3514 } catch (SecurityException e) { 3515 // XXX need to figure out how to propagate to original app. 3516 // A SecurityException here is generally actually a fault of the original 3517 // calling activity (such as a fairly granting permissions), so propagate it 3518 // back to them. 3519 /* 3520 StringBuilder msg = new StringBuilder(); 3521 msg.append("While launching"); 3522 msg.append(intent.toString()); 3523 msg.append(": "); 3524 msg.append(e.getMessage()); 3525 */ 3526 throw e; 3527 } 3528 } 3529 3530 @Override 3531 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3532 Intent intent, String resolvedType, IBinder resultTo, 3533 String resultWho, int requestCode, int startFlags, String profileFile, 3534 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3535 enforceNotIsolatedCaller("startActivityAndWait"); 3536 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3537 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3538 WaitResult res = new WaitResult(); 3539 // TODO: Switch to user app stacks here. 3540 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3541 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3542 res, null, options, userId, null, null); 3543 return res; 3544 } 3545 3546 @Override 3547 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3548 Intent intent, String resolvedType, IBinder resultTo, 3549 String resultWho, int requestCode, int startFlags, Configuration config, 3550 Bundle options, int userId) { 3551 enforceNotIsolatedCaller("startActivityWithConfig"); 3552 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3553 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3554 // TODO: Switch to user app stacks here. 3555 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3556 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3557 null, null, null, config, options, userId, null, null); 3558 return ret; 3559 } 3560 3561 @Override 3562 public int startActivityIntentSender(IApplicationThread caller, 3563 IntentSender intent, Intent fillInIntent, String resolvedType, 3564 IBinder resultTo, String resultWho, int requestCode, 3565 int flagsMask, int flagsValues, Bundle options) { 3566 enforceNotIsolatedCaller("startActivityIntentSender"); 3567 // Refuse possible leaked file descriptors 3568 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3569 throw new IllegalArgumentException("File descriptors passed in Intent"); 3570 } 3571 3572 IIntentSender sender = intent.getTarget(); 3573 if (!(sender instanceof PendingIntentRecord)) { 3574 throw new IllegalArgumentException("Bad PendingIntent object"); 3575 } 3576 3577 PendingIntentRecord pir = (PendingIntentRecord)sender; 3578 3579 synchronized (this) { 3580 // If this is coming from the currently resumed activity, it is 3581 // effectively saying that app switches are allowed at this point. 3582 final ActivityStack stack = getFocusedStack(); 3583 if (stack.mResumedActivity != null && 3584 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3585 mAppSwitchesAllowedTime = 0; 3586 } 3587 } 3588 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3589 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3590 return ret; 3591 } 3592 3593 @Override 3594 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3595 Intent intent, String resolvedType, IVoiceInteractionSession session, 3596 IVoiceInteractor interactor, int startFlags, String profileFile, 3597 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3598 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3599 != PackageManager.PERMISSION_GRANTED) { 3600 String msg = "Permission Denial: startVoiceActivity() from pid=" 3601 + Binder.getCallingPid() 3602 + ", uid=" + Binder.getCallingUid() 3603 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3604 Slog.w(TAG, msg); 3605 throw new SecurityException(msg); 3606 } 3607 if (session == null || interactor == null) { 3608 throw new NullPointerException("null session or interactor"); 3609 } 3610 userId = handleIncomingUser(callingPid, callingUid, userId, 3611 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3612 // TODO: Switch to user app stacks here. 3613 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3614 resolvedType, session, interactor, null, null, 0, startFlags, 3615 profileFile, profileFd, null, null, options, userId, null, null); 3616 } 3617 3618 @Override 3619 public boolean startNextMatchingActivity(IBinder callingActivity, 3620 Intent intent, Bundle options) { 3621 // Refuse possible leaked file descriptors 3622 if (intent != null && intent.hasFileDescriptors() == true) { 3623 throw new IllegalArgumentException("File descriptors passed in Intent"); 3624 } 3625 3626 synchronized (this) { 3627 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3628 if (r == null) { 3629 ActivityOptions.abort(options); 3630 return false; 3631 } 3632 if (r.app == null || r.app.thread == null) { 3633 // The caller is not running... d'oh! 3634 ActivityOptions.abort(options); 3635 return false; 3636 } 3637 intent = new Intent(intent); 3638 // The caller is not allowed to change the data. 3639 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3640 // And we are resetting to find the next component... 3641 intent.setComponent(null); 3642 3643 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3644 3645 ActivityInfo aInfo = null; 3646 try { 3647 List<ResolveInfo> resolves = 3648 AppGlobals.getPackageManager().queryIntentActivities( 3649 intent, r.resolvedType, 3650 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3651 UserHandle.getCallingUserId()); 3652 3653 // Look for the original activity in the list... 3654 final int N = resolves != null ? resolves.size() : 0; 3655 for (int i=0; i<N; i++) { 3656 ResolveInfo rInfo = resolves.get(i); 3657 if (rInfo.activityInfo.packageName.equals(r.packageName) 3658 && rInfo.activityInfo.name.equals(r.info.name)) { 3659 // We found the current one... the next matching is 3660 // after it. 3661 i++; 3662 if (i<N) { 3663 aInfo = resolves.get(i).activityInfo; 3664 } 3665 if (debug) { 3666 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3667 + "/" + r.info.name); 3668 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3669 + "/" + aInfo.name); 3670 } 3671 break; 3672 } 3673 } 3674 } catch (RemoteException e) { 3675 } 3676 3677 if (aInfo == null) { 3678 // Nobody who is next! 3679 ActivityOptions.abort(options); 3680 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3681 return false; 3682 } 3683 3684 intent.setComponent(new ComponentName( 3685 aInfo.applicationInfo.packageName, aInfo.name)); 3686 intent.setFlags(intent.getFlags()&~( 3687 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3688 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3689 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3690 Intent.FLAG_ACTIVITY_NEW_TASK)); 3691 3692 // Okay now we need to start the new activity, replacing the 3693 // currently running activity. This is a little tricky because 3694 // we want to start the new one as if the current one is finished, 3695 // but not finish the current one first so that there is no flicker. 3696 // And thus... 3697 final boolean wasFinishing = r.finishing; 3698 r.finishing = true; 3699 3700 // Propagate reply information over to the new activity. 3701 final ActivityRecord resultTo = r.resultTo; 3702 final String resultWho = r.resultWho; 3703 final int requestCode = r.requestCode; 3704 r.resultTo = null; 3705 if (resultTo != null) { 3706 resultTo.removeResultsLocked(r, resultWho, requestCode); 3707 } 3708 3709 final long origId = Binder.clearCallingIdentity(); 3710 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3711 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3712 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3713 options, false, null, null, null); 3714 Binder.restoreCallingIdentity(origId); 3715 3716 r.finishing = wasFinishing; 3717 if (res != ActivityManager.START_SUCCESS) { 3718 return false; 3719 } 3720 return true; 3721 } 3722 } 3723 3724 @Override 3725 public final int startActivityFromRecents(int taskId, Bundle options) { 3726 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3727 String msg = "Permission Denial: startActivityFromRecents called without " + 3728 START_TASKS_FROM_RECENTS; 3729 Slog.w(TAG, msg); 3730 throw new SecurityException(msg); 3731 } 3732 return startActivityFromRecentsInner(taskId, options); 3733 } 3734 3735 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3736 final TaskRecord task; 3737 final int callingUid; 3738 final String callingPackage; 3739 final Intent intent; 3740 final int userId; 3741 synchronized (this) { 3742 task = recentTaskForIdLocked(taskId); 3743 if (task == null) { 3744 throw new IllegalArgumentException("Task " + taskId + " not found."); 3745 } 3746 callingUid = task.mCallingUid; 3747 callingPackage = task.mCallingPackage; 3748 intent = task.intent; 3749 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3750 userId = task.userId; 3751 } 3752 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3753 options, userId, null, task); 3754 } 3755 3756 final int startActivityInPackage(int uid, String callingPackage, 3757 Intent intent, String resolvedType, IBinder resultTo, 3758 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3759 IActivityContainer container, TaskRecord inTask) { 3760 3761 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3762 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3763 3764 // TODO: Switch to user app stacks here. 3765 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3766 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3767 null, null, null, null, options, userId, container, inTask); 3768 return ret; 3769 } 3770 3771 @Override 3772 public final int startActivities(IApplicationThread caller, String callingPackage, 3773 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3774 int userId) { 3775 enforceNotIsolatedCaller("startActivities"); 3776 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3777 false, ALLOW_FULL_ONLY, "startActivity", null); 3778 // TODO: Switch to user app stacks here. 3779 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3780 resolvedTypes, resultTo, options, userId); 3781 return ret; 3782 } 3783 3784 final int startActivitiesInPackage(int uid, String callingPackage, 3785 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3786 Bundle options, int userId) { 3787 3788 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3789 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3790 // TODO: Switch to user app stacks here. 3791 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3792 resultTo, options, userId); 3793 return ret; 3794 } 3795 3796 //explicitly remove thd old information in mRecentTasks when removing existing user. 3797 private void removeRecentTasksForUserLocked(int userId) { 3798 if(userId <= 0) { 3799 Slog.i(TAG, "Can't remove recent task on user " + userId); 3800 return; 3801 } 3802 3803 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3804 TaskRecord tr = mRecentTasks.get(i); 3805 if (tr.userId == userId) { 3806 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3807 + " when finishing user" + userId); 3808 mRecentTasks.remove(i); 3809 tr.removedFromRecents(mTaskPersister); 3810 } 3811 } 3812 3813 // Remove tasks from persistent storage. 3814 mTaskPersister.wakeup(null, true); 3815 } 3816 3817 /** 3818 * Update the recent tasks lists: make sure tasks should still be here (their 3819 * applications / activities still exist), update their availability, fixup ordering 3820 * of affiliations. 3821 */ 3822 void cleanupRecentTasksLocked(int userId) { 3823 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3824 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3825 final IPackageManager pm = AppGlobals.getPackageManager(); 3826 final ActivityInfo dummyAct = new ActivityInfo(); 3827 final ApplicationInfo dummyApp = new ApplicationInfo(); 3828 3829 int N = mRecentTasks.size(); 3830 3831 int[] users = userId == UserHandle.USER_ALL 3832 ? getUsersLocked() : new int[] { userId }; 3833 for (int user : users) { 3834 for (int i = 0; i < N; i++) { 3835 TaskRecord task = mRecentTasks.get(i); 3836 if (task.userId != user) { 3837 // Only look at tasks for the user ID of interest. 3838 continue; 3839 } 3840 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3841 // This situation is broken, and we should just get rid of it now. 3842 mRecentTasks.remove(i); 3843 task.removedFromRecents(mTaskPersister); 3844 i--; 3845 N--; 3846 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3847 continue; 3848 } 3849 // Check whether this activity is currently available. 3850 if (task.realActivity != null) { 3851 ActivityInfo ai = availActCache.get(task.realActivity); 3852 if (ai == null) { 3853 try { 3854 ai = pm.getActivityInfo(task.realActivity, 3855 PackageManager.GET_UNINSTALLED_PACKAGES 3856 | PackageManager.GET_DISABLED_COMPONENTS, user); 3857 } catch (RemoteException e) { 3858 // Will never happen. 3859 continue; 3860 } 3861 if (ai == null) { 3862 ai = dummyAct; 3863 } 3864 availActCache.put(task.realActivity, ai); 3865 } 3866 if (ai == dummyAct) { 3867 // This could be either because the activity no longer exists, or the 3868 // app is temporarily gone. For the former we want to remove the recents 3869 // entry; for the latter we want to mark it as unavailable. 3870 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3871 if (app == null) { 3872 try { 3873 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3874 PackageManager.GET_UNINSTALLED_PACKAGES 3875 | PackageManager.GET_DISABLED_COMPONENTS, user); 3876 } catch (RemoteException e) { 3877 // Will never happen. 3878 continue; 3879 } 3880 if (app == null) { 3881 app = dummyApp; 3882 } 3883 availAppCache.put(task.realActivity.getPackageName(), app); 3884 } 3885 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3886 // Doesn't exist any more! Good-bye. 3887 mRecentTasks.remove(i); 3888 task.removedFromRecents(mTaskPersister); 3889 i--; 3890 N--; 3891 Slog.w(TAG, "Removing no longer valid recent: " + task); 3892 continue; 3893 } else { 3894 // Otherwise just not available for now. 3895 if (task.isAvailable) { 3896 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3897 + task); 3898 } 3899 task.isAvailable = false; 3900 } 3901 } else { 3902 if (!ai.enabled || !ai.applicationInfo.enabled 3903 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3904 if (task.isAvailable) { 3905 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3906 + task + " (enabled=" + ai.enabled + "/" 3907 + ai.applicationInfo.enabled + " flags=" 3908 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3909 } 3910 task.isAvailable = false; 3911 } else { 3912 if (!task.isAvailable) { 3913 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3914 + task); 3915 } 3916 task.isAvailable = true; 3917 } 3918 } 3919 } 3920 } 3921 } 3922 3923 // Verify the affiliate chain for each task. 3924 for (int i = 0; i < N; ) { 3925 TaskRecord task = mRecentTasks.remove(i); 3926 if (mTmpRecents.contains(task)) { 3927 continue; 3928 } 3929 int affiliatedTaskId = task.mAffiliatedTaskId; 3930 while (true) { 3931 TaskRecord next = task.mNextAffiliate; 3932 if (next == null) { 3933 break; 3934 } 3935 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3936 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3937 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3938 task.setNextAffiliate(null); 3939 if (next.mPrevAffiliate == task) { 3940 next.setPrevAffiliate(null); 3941 } 3942 break; 3943 } 3944 if (next.mPrevAffiliate != task) { 3945 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3946 next.mPrevAffiliate + " task=" + task); 3947 next.setPrevAffiliate(null); 3948 task.setNextAffiliate(null); 3949 break; 3950 } 3951 if (!mRecentTasks.contains(next)) { 3952 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3953 task.setNextAffiliate(null); 3954 // We know that next.mPrevAffiliate is always task, from above, so clear 3955 // its previous affiliate. 3956 next.setPrevAffiliate(null); 3957 break; 3958 } 3959 task = next; 3960 } 3961 // task is now the end of the list 3962 do { 3963 mRecentTasks.remove(task); 3964 mRecentTasks.add(i++, task); 3965 mTmpRecents.add(task); 3966 task.inRecents = true; 3967 } while ((task = task.mPrevAffiliate) != null); 3968 } 3969 mTmpRecents.clear(); 3970 // mRecentTasks is now in sorted, affiliated order. 3971 } 3972 3973 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3974 int N = mRecentTasks.size(); 3975 TaskRecord top = task; 3976 int topIndex = taskIndex; 3977 while (top.mNextAffiliate != null && topIndex > 0) { 3978 top = top.mNextAffiliate; 3979 topIndex--; 3980 } 3981 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3982 + topIndex + " from intial " + taskIndex); 3983 // Find the end of the chain, doing a sanity check along the way. 3984 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3985 int endIndex = topIndex; 3986 TaskRecord prev = top; 3987 while (endIndex < N) { 3988 TaskRecord cur = mRecentTasks.get(endIndex); 3989 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3990 + endIndex + " " + cur); 3991 if (cur == top) { 3992 // Verify start of the chain. 3993 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3994 Slog.wtf(TAG, "Bad chain @" + endIndex 3995 + ": first task has next affiliate: " + prev); 3996 sane = false; 3997 break; 3998 } 3999 } else { 4000 // Verify middle of the chain's next points back to the one before. 4001 if (cur.mNextAffiliate != prev 4002 || cur.mNextAffiliateTaskId != prev.taskId) { 4003 Slog.wtf(TAG, "Bad chain @" + endIndex 4004 + ": middle task " + cur + " @" + endIndex 4005 + " has bad next affiliate " 4006 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4007 + ", expected " + prev); 4008 sane = false; 4009 break; 4010 } 4011 } 4012 if (cur.mPrevAffiliateTaskId == -1) { 4013 // Chain ends here. 4014 if (cur.mPrevAffiliate != null) { 4015 Slog.wtf(TAG, "Bad chain @" + endIndex 4016 + ": last task " + cur + " has previous affiliate " 4017 + cur.mPrevAffiliate); 4018 sane = false; 4019 } 4020 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4021 break; 4022 } else { 4023 // Verify middle of the chain's prev points to a valid item. 4024 if (cur.mPrevAffiliate == null) { 4025 Slog.wtf(TAG, "Bad chain @" + endIndex 4026 + ": task " + cur + " has previous affiliate " 4027 + cur.mPrevAffiliate + " but should be id " 4028 + cur.mPrevAffiliate); 4029 sane = false; 4030 break; 4031 } 4032 } 4033 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4034 Slog.wtf(TAG, "Bad chain @" + endIndex 4035 + ": task " + cur + " has affiliated id " 4036 + cur.mAffiliatedTaskId + " but should be " 4037 + task.mAffiliatedTaskId); 4038 sane = false; 4039 break; 4040 } 4041 prev = cur; 4042 endIndex++; 4043 if (endIndex >= N) { 4044 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4045 + ": last task " + prev); 4046 sane = false; 4047 break; 4048 } 4049 } 4050 if (sane) { 4051 if (endIndex < taskIndex) { 4052 Slog.wtf(TAG, "Bad chain @" + endIndex 4053 + ": did not extend to task " + task + " @" + taskIndex); 4054 sane = false; 4055 } 4056 } 4057 if (sane) { 4058 // All looks good, we can just move all of the affiliated tasks 4059 // to the top. 4060 for (int i=topIndex; i<=endIndex; i++) { 4061 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4062 + " from " + i + " to " + (i-topIndex)); 4063 TaskRecord cur = mRecentTasks.remove(i); 4064 mRecentTasks.add(i-topIndex, cur); 4065 } 4066 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4067 + " to " + endIndex); 4068 return true; 4069 } 4070 4071 // Whoops, couldn't do it. 4072 return false; 4073 } 4074 4075 final void addRecentTaskLocked(TaskRecord task) { 4076 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4077 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4078 4079 int N = mRecentTasks.size(); 4080 // Quick case: check if the top-most recent task is the same. 4081 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4082 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4083 return; 4084 } 4085 // Another quick case: check if this is part of a set of affiliated 4086 // tasks that are at the top. 4087 if (isAffiliated && N > 0 && task.inRecents 4088 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4089 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4090 + " at top when adding " + task); 4091 return; 4092 } 4093 // Another quick case: never add voice sessions. 4094 if (task.voiceSession != null) { 4095 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4096 return; 4097 } 4098 4099 boolean needAffiliationFix = false; 4100 4101 // Slightly less quick case: the task is already in recents, so all we need 4102 // to do is move it. 4103 if (task.inRecents) { 4104 int taskIndex = mRecentTasks.indexOf(task); 4105 if (taskIndex >= 0) { 4106 if (!isAffiliated) { 4107 // Simple case: this is not an affiliated task, so we just move it to the front. 4108 mRecentTasks.remove(taskIndex); 4109 mRecentTasks.add(0, task); 4110 notifyTaskPersisterLocked(task, false); 4111 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4112 + " from " + taskIndex); 4113 return; 4114 } else { 4115 // More complicated: need to keep all affiliated tasks together. 4116 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4117 // All went well. 4118 return; 4119 } 4120 4121 // Uh oh... something bad in the affiliation chain, try to rebuild 4122 // everything and then go through our general path of adding a new task. 4123 needAffiliationFix = true; 4124 } 4125 } else { 4126 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4127 needAffiliationFix = true; 4128 } 4129 } 4130 4131 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4132 trimRecentsForTask(task, true); 4133 4134 N = mRecentTasks.size(); 4135 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4136 final TaskRecord tr = mRecentTasks.remove(N - 1); 4137 tr.removedFromRecents(mTaskPersister); 4138 N--; 4139 } 4140 task.inRecents = true; 4141 if (!isAffiliated || needAffiliationFix) { 4142 // If this is a simple non-affiliated task, or we had some failure trying to 4143 // handle it as part of an affilated task, then just place it at the top. 4144 mRecentTasks.add(0, task); 4145 } else if (isAffiliated) { 4146 // If this is a new affiliated task, then move all of the affiliated tasks 4147 // to the front and insert this new one. 4148 TaskRecord other = task.mNextAffiliate; 4149 if (other == null) { 4150 other = task.mPrevAffiliate; 4151 } 4152 if (other != null) { 4153 int otherIndex = mRecentTasks.indexOf(other); 4154 if (otherIndex >= 0) { 4155 // Insert new task at appropriate location. 4156 int taskIndex; 4157 if (other == task.mNextAffiliate) { 4158 // We found the index of our next affiliation, which is who is 4159 // before us in the list, so add after that point. 4160 taskIndex = otherIndex+1; 4161 } else { 4162 // We found the index of our previous affiliation, which is who is 4163 // after us in the list, so add at their position. 4164 taskIndex = otherIndex; 4165 } 4166 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4167 + taskIndex + ": " + task); 4168 mRecentTasks.add(taskIndex, task); 4169 4170 // Now move everything to the front. 4171 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4172 // All went well. 4173 return; 4174 } 4175 4176 // Uh oh... something bad in the affiliation chain, try to rebuild 4177 // everything and then go through our general path of adding a new task. 4178 needAffiliationFix = true; 4179 } else { 4180 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4181 + other); 4182 needAffiliationFix = true; 4183 } 4184 } else { 4185 if (DEBUG_RECENTS) Slog.d(TAG, 4186 "addRecent: adding affiliated task without next/prev:" + task); 4187 needAffiliationFix = true; 4188 } 4189 } 4190 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4191 4192 if (needAffiliationFix) { 4193 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4194 cleanupRecentTasksLocked(task.userId); 4195 } 4196 } 4197 4198 /** 4199 * If needed, remove oldest existing entries in recents that are for the same kind 4200 * of task as the given one. 4201 */ 4202 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4203 int N = mRecentTasks.size(); 4204 final Intent intent = task.intent; 4205 final boolean document = intent != null && intent.isDocument(); 4206 4207 int maxRecents = task.maxRecents - 1; 4208 for (int i=0; i<N; i++) { 4209 final TaskRecord tr = mRecentTasks.get(i); 4210 if (task != tr) { 4211 if (task.userId != tr.userId) { 4212 continue; 4213 } 4214 if (i > MAX_RECENT_BITMAPS) { 4215 tr.freeLastThumbnail(); 4216 } 4217 final Intent trIntent = tr.intent; 4218 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4219 (intent == null || !intent.filterEquals(trIntent))) { 4220 continue; 4221 } 4222 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4223 if (document && trIsDocument) { 4224 // These are the same document activity (not necessarily the same doc). 4225 if (maxRecents > 0) { 4226 --maxRecents; 4227 continue; 4228 } 4229 // Hit the maximum number of documents for this task. Fall through 4230 // and remove this document from recents. 4231 } else if (document || trIsDocument) { 4232 // Only one of these is a document. Not the droid we're looking for. 4233 continue; 4234 } 4235 } 4236 4237 if (!doTrim) { 4238 // If the caller is not actually asking for a trim, just tell them we reached 4239 // a point where the trim would happen. 4240 return i; 4241 } 4242 4243 // Either task and tr are the same or, their affinities match or their intents match 4244 // and neither of them is a document, or they are documents using the same activity 4245 // and their maxRecents has been reached. 4246 tr.disposeThumbnail(); 4247 mRecentTasks.remove(i); 4248 if (task != tr) { 4249 tr.removedFromRecents(mTaskPersister); 4250 } 4251 i--; 4252 N--; 4253 if (task.intent == null) { 4254 // If the new recent task we are adding is not fully 4255 // specified, then replace it with the existing recent task. 4256 task = tr; 4257 } 4258 notifyTaskPersisterLocked(tr, false); 4259 } 4260 4261 return -1; 4262 } 4263 4264 @Override 4265 public void reportActivityFullyDrawn(IBinder token) { 4266 synchronized (this) { 4267 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4268 if (r == null) { 4269 return; 4270 } 4271 r.reportFullyDrawnLocked(); 4272 } 4273 } 4274 4275 @Override 4276 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4277 synchronized (this) { 4278 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4279 if (r == null) { 4280 return; 4281 } 4282 final long origId = Binder.clearCallingIdentity(); 4283 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4284 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4285 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4286 if (config != null) { 4287 r.frozenBeforeDestroy = true; 4288 if (!updateConfigurationLocked(config, r, false, false)) { 4289 mStackSupervisor.resumeTopActivitiesLocked(); 4290 } 4291 } 4292 Binder.restoreCallingIdentity(origId); 4293 } 4294 } 4295 4296 @Override 4297 public int getRequestedOrientation(IBinder token) { 4298 synchronized (this) { 4299 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4300 if (r == null) { 4301 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4302 } 4303 return mWindowManager.getAppOrientation(r.appToken); 4304 } 4305 } 4306 4307 /** 4308 * This is the internal entry point for handling Activity.finish(). 4309 * 4310 * @param token The Binder token referencing the Activity we want to finish. 4311 * @param resultCode Result code, if any, from this Activity. 4312 * @param resultData Result data (Intent), if any, from this Activity. 4313 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4314 * the root Activity in the task. 4315 * 4316 * @return Returns true if the activity successfully finished, or false if it is still running. 4317 */ 4318 @Override 4319 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4320 boolean finishTask) { 4321 // Refuse possible leaked file descriptors 4322 if (resultData != null && resultData.hasFileDescriptors() == true) { 4323 throw new IllegalArgumentException("File descriptors passed in Intent"); 4324 } 4325 4326 synchronized(this) { 4327 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4328 if (r == null) { 4329 return true; 4330 } 4331 // Keep track of the root activity of the task before we finish it 4332 TaskRecord tr = r.task; 4333 ActivityRecord rootR = tr.getRootActivity(); 4334 // Do not allow task to finish in Lock Task mode. 4335 if (tr == mStackSupervisor.mLockTaskModeTask) { 4336 if (rootR == r) { 4337 mStackSupervisor.showLockTaskToast(); 4338 return false; 4339 } 4340 } 4341 if (mController != null) { 4342 // Find the first activity that is not finishing. 4343 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4344 if (next != null) { 4345 // ask watcher if this is allowed 4346 boolean resumeOK = true; 4347 try { 4348 resumeOK = mController.activityResuming(next.packageName); 4349 } catch (RemoteException e) { 4350 mController = null; 4351 Watchdog.getInstance().setActivityController(null); 4352 } 4353 4354 if (!resumeOK) { 4355 return false; 4356 } 4357 } 4358 } 4359 final long origId = Binder.clearCallingIdentity(); 4360 try { 4361 boolean res; 4362 if (finishTask && r == rootR) { 4363 // If requested, remove the task that is associated to this activity only if it 4364 // was the root activity in the task. The result code and data is ignored because 4365 // we don't support returning them across task boundaries. 4366 res = removeTaskByIdLocked(tr.taskId, 0); 4367 } else { 4368 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4369 resultData, "app-request", true); 4370 } 4371 return res; 4372 } finally { 4373 Binder.restoreCallingIdentity(origId); 4374 } 4375 } 4376 } 4377 4378 @Override 4379 public final void finishHeavyWeightApp() { 4380 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4381 != PackageManager.PERMISSION_GRANTED) { 4382 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4383 + Binder.getCallingPid() 4384 + ", uid=" + Binder.getCallingUid() 4385 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4386 Slog.w(TAG, msg); 4387 throw new SecurityException(msg); 4388 } 4389 4390 synchronized(this) { 4391 if (mHeavyWeightProcess == null) { 4392 return; 4393 } 4394 4395 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4396 mHeavyWeightProcess.activities); 4397 for (int i=0; i<activities.size(); i++) { 4398 ActivityRecord r = activities.get(i); 4399 if (!r.finishing) { 4400 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4401 null, "finish-heavy", true); 4402 } 4403 } 4404 4405 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4406 mHeavyWeightProcess.userId, 0)); 4407 mHeavyWeightProcess = null; 4408 } 4409 } 4410 4411 @Override 4412 public void crashApplication(int uid, int initialPid, String packageName, 4413 String message) { 4414 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4415 != PackageManager.PERMISSION_GRANTED) { 4416 String msg = "Permission Denial: crashApplication() from pid=" 4417 + Binder.getCallingPid() 4418 + ", uid=" + Binder.getCallingUid() 4419 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4420 Slog.w(TAG, msg); 4421 throw new SecurityException(msg); 4422 } 4423 4424 synchronized(this) { 4425 ProcessRecord proc = null; 4426 4427 // Figure out which process to kill. We don't trust that initialPid 4428 // still has any relation to current pids, so must scan through the 4429 // list. 4430 synchronized (mPidsSelfLocked) { 4431 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4432 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4433 if (p.uid != uid) { 4434 continue; 4435 } 4436 if (p.pid == initialPid) { 4437 proc = p; 4438 break; 4439 } 4440 if (p.pkgList.containsKey(packageName)) { 4441 proc = p; 4442 } 4443 } 4444 } 4445 4446 if (proc == null) { 4447 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4448 + " initialPid=" + initialPid 4449 + " packageName=" + packageName); 4450 return; 4451 } 4452 4453 if (proc.thread != null) { 4454 if (proc.pid == Process.myPid()) { 4455 Log.w(TAG, "crashApplication: trying to crash self!"); 4456 return; 4457 } 4458 long ident = Binder.clearCallingIdentity(); 4459 try { 4460 proc.thread.scheduleCrash(message); 4461 } catch (RemoteException e) { 4462 } 4463 Binder.restoreCallingIdentity(ident); 4464 } 4465 } 4466 } 4467 4468 @Override 4469 public final void finishSubActivity(IBinder token, String resultWho, 4470 int requestCode) { 4471 synchronized(this) { 4472 final long origId = Binder.clearCallingIdentity(); 4473 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4474 if (r != null) { 4475 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4476 } 4477 Binder.restoreCallingIdentity(origId); 4478 } 4479 } 4480 4481 @Override 4482 public boolean finishActivityAffinity(IBinder token) { 4483 synchronized(this) { 4484 final long origId = Binder.clearCallingIdentity(); 4485 try { 4486 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4487 4488 ActivityRecord rootR = r.task.getRootActivity(); 4489 // Do not allow task to finish in Lock Task mode. 4490 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4491 if (rootR == r) { 4492 mStackSupervisor.showLockTaskToast(); 4493 return false; 4494 } 4495 } 4496 boolean res = false; 4497 if (r != null) { 4498 res = r.task.stack.finishActivityAffinityLocked(r); 4499 } 4500 return res; 4501 } finally { 4502 Binder.restoreCallingIdentity(origId); 4503 } 4504 } 4505 } 4506 4507 @Override 4508 public void finishVoiceTask(IVoiceInteractionSession session) { 4509 synchronized(this) { 4510 final long origId = Binder.clearCallingIdentity(); 4511 try { 4512 mStackSupervisor.finishVoiceTask(session); 4513 } finally { 4514 Binder.restoreCallingIdentity(origId); 4515 } 4516 } 4517 4518 } 4519 4520 @Override 4521 public boolean releaseActivityInstance(IBinder token) { 4522 synchronized(this) { 4523 final long origId = Binder.clearCallingIdentity(); 4524 try { 4525 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4526 if (r.task == null || r.task.stack == null) { 4527 return false; 4528 } 4529 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4530 } finally { 4531 Binder.restoreCallingIdentity(origId); 4532 } 4533 } 4534 } 4535 4536 @Override 4537 public void releaseSomeActivities(IApplicationThread appInt) { 4538 synchronized(this) { 4539 final long origId = Binder.clearCallingIdentity(); 4540 try { 4541 ProcessRecord app = getRecordForAppLocked(appInt); 4542 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4543 } finally { 4544 Binder.restoreCallingIdentity(origId); 4545 } 4546 } 4547 } 4548 4549 @Override 4550 public boolean willActivityBeVisible(IBinder token) { 4551 synchronized(this) { 4552 ActivityStack stack = ActivityRecord.getStackLocked(token); 4553 if (stack != null) { 4554 return stack.willActivityBeVisibleLocked(token); 4555 } 4556 return false; 4557 } 4558 } 4559 4560 @Override 4561 public void overridePendingTransition(IBinder token, String packageName, 4562 int enterAnim, int exitAnim) { 4563 synchronized(this) { 4564 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4565 if (self == null) { 4566 return; 4567 } 4568 4569 final long origId = Binder.clearCallingIdentity(); 4570 4571 if (self.state == ActivityState.RESUMED 4572 || self.state == ActivityState.PAUSING) { 4573 mWindowManager.overridePendingAppTransition(packageName, 4574 enterAnim, exitAnim, null); 4575 } 4576 4577 Binder.restoreCallingIdentity(origId); 4578 } 4579 } 4580 4581 /** 4582 * Main function for removing an existing process from the activity manager 4583 * as a result of that process going away. Clears out all connections 4584 * to the process. 4585 */ 4586 private final void handleAppDiedLocked(ProcessRecord app, 4587 boolean restarting, boolean allowRestart) { 4588 int pid = app.pid; 4589 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4590 if (!restarting) { 4591 removeLruProcessLocked(app); 4592 if (pid > 0) { 4593 ProcessList.remove(pid); 4594 } 4595 } 4596 4597 if (mProfileProc == app) { 4598 clearProfilerLocked(); 4599 } 4600 4601 // Remove this application's activities from active lists. 4602 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4603 4604 app.activities.clear(); 4605 4606 if (app.instrumentationClass != null) { 4607 Slog.w(TAG, "Crash of app " + app.processName 4608 + " running instrumentation " + app.instrumentationClass); 4609 Bundle info = new Bundle(); 4610 info.putString("shortMsg", "Process crashed."); 4611 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4612 } 4613 4614 if (!restarting) { 4615 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4616 // If there was nothing to resume, and we are not already 4617 // restarting this process, but there is a visible activity that 4618 // is hosted by the process... then make sure all visible 4619 // activities are running, taking care of restarting this 4620 // process. 4621 if (hasVisibleActivities) { 4622 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4623 } 4624 } 4625 } 4626 } 4627 4628 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4629 IBinder threadBinder = thread.asBinder(); 4630 // Find the application record. 4631 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4632 ProcessRecord rec = mLruProcesses.get(i); 4633 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4634 return i; 4635 } 4636 } 4637 return -1; 4638 } 4639 4640 final ProcessRecord getRecordForAppLocked( 4641 IApplicationThread thread) { 4642 if (thread == null) { 4643 return null; 4644 } 4645 4646 int appIndex = getLRURecordIndexForAppLocked(thread); 4647 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4648 } 4649 4650 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4651 // If there are no longer any background processes running, 4652 // and the app that died was not running instrumentation, 4653 // then tell everyone we are now low on memory. 4654 boolean haveBg = false; 4655 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4656 ProcessRecord rec = mLruProcesses.get(i); 4657 if (rec.thread != null 4658 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4659 haveBg = true; 4660 break; 4661 } 4662 } 4663 4664 if (!haveBg) { 4665 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4666 if (doReport) { 4667 long now = SystemClock.uptimeMillis(); 4668 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4669 doReport = false; 4670 } else { 4671 mLastMemUsageReportTime = now; 4672 } 4673 } 4674 final ArrayList<ProcessMemInfo> memInfos 4675 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4676 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4677 long now = SystemClock.uptimeMillis(); 4678 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4679 ProcessRecord rec = mLruProcesses.get(i); 4680 if (rec == dyingProc || rec.thread == null) { 4681 continue; 4682 } 4683 if (doReport) { 4684 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4685 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4686 } 4687 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4688 // The low memory report is overriding any current 4689 // state for a GC request. Make sure to do 4690 // heavy/important/visible/foreground processes first. 4691 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4692 rec.lastRequestedGc = 0; 4693 } else { 4694 rec.lastRequestedGc = rec.lastLowMemory; 4695 } 4696 rec.reportLowMemory = true; 4697 rec.lastLowMemory = now; 4698 mProcessesToGc.remove(rec); 4699 addProcessToGcListLocked(rec); 4700 } 4701 } 4702 if (doReport) { 4703 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4704 mHandler.sendMessage(msg); 4705 } 4706 scheduleAppGcsLocked(); 4707 } 4708 } 4709 4710 final void appDiedLocked(ProcessRecord app) { 4711 appDiedLocked(app, app.pid, app.thread); 4712 } 4713 4714 final void appDiedLocked(ProcessRecord app, int pid, 4715 IApplicationThread thread) { 4716 4717 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4718 synchronized (stats) { 4719 stats.noteProcessDiedLocked(app.info.uid, pid); 4720 } 4721 4722 Process.killProcessGroup(app.info.uid, pid); 4723 4724 // Clean up already done if the process has been re-started. 4725 if (app.pid == pid && app.thread != null && 4726 app.thread.asBinder() == thread.asBinder()) { 4727 boolean doLowMem = app.instrumentationClass == null; 4728 boolean doOomAdj = doLowMem; 4729 if (!app.killedByAm) { 4730 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4731 + ") has died."); 4732 mAllowLowerMemLevel = true; 4733 } else { 4734 // Note that we always want to do oom adj to update our state with the 4735 // new number of procs. 4736 mAllowLowerMemLevel = false; 4737 doLowMem = false; 4738 } 4739 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4740 if (DEBUG_CLEANUP) Slog.v( 4741 TAG, "Dying app: " + app + ", pid: " + pid 4742 + ", thread: " + thread.asBinder()); 4743 handleAppDiedLocked(app, false, true); 4744 4745 if (doOomAdj) { 4746 updateOomAdjLocked(); 4747 } 4748 if (doLowMem) { 4749 doLowMemReportIfNeededLocked(app); 4750 } 4751 } else if (app.pid != pid) { 4752 // A new process has already been started. 4753 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4754 + ") has died and restarted (pid " + app.pid + ")."); 4755 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4756 } else if (DEBUG_PROCESSES) { 4757 Slog.d(TAG, "Received spurious death notification for thread " 4758 + thread.asBinder()); 4759 } 4760 } 4761 4762 /** 4763 * If a stack trace dump file is configured, dump process stack traces. 4764 * @param clearTraces causes the dump file to be erased prior to the new 4765 * traces being written, if true; when false, the new traces will be 4766 * appended to any existing file content. 4767 * @param firstPids of dalvik VM processes to dump stack traces for first 4768 * @param lastPids of dalvik VM processes to dump stack traces for last 4769 * @param nativeProcs optional list of native process names to dump stack crawls 4770 * @return file containing stack traces, or null if no dump file is configured 4771 */ 4772 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4773 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4774 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4775 if (tracesPath == null || tracesPath.length() == 0) { 4776 return null; 4777 } 4778 4779 File tracesFile = new File(tracesPath); 4780 try { 4781 File tracesDir = tracesFile.getParentFile(); 4782 if (!tracesDir.exists()) { 4783 tracesFile.mkdirs(); 4784 if (!SELinux.restorecon(tracesDir)) { 4785 return null; 4786 } 4787 } 4788 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4789 4790 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4791 tracesFile.createNewFile(); 4792 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4793 } catch (IOException e) { 4794 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4795 return null; 4796 } 4797 4798 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4799 return tracesFile; 4800 } 4801 4802 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4803 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4804 // Use a FileObserver to detect when traces finish writing. 4805 // The order of traces is considered important to maintain for legibility. 4806 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4807 @Override 4808 public synchronized void onEvent(int event, String path) { notify(); } 4809 }; 4810 4811 try { 4812 observer.startWatching(); 4813 4814 // First collect all of the stacks of the most important pids. 4815 if (firstPids != null) { 4816 try { 4817 int num = firstPids.size(); 4818 for (int i = 0; i < num; i++) { 4819 synchronized (observer) { 4820 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4821 observer.wait(200); // Wait for write-close, give up after 200msec 4822 } 4823 } 4824 } catch (InterruptedException e) { 4825 Log.wtf(TAG, e); 4826 } 4827 } 4828 4829 // Next collect the stacks of the native pids 4830 if (nativeProcs != null) { 4831 int[] pids = Process.getPidsForCommands(nativeProcs); 4832 if (pids != null) { 4833 for (int pid : pids) { 4834 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4835 } 4836 } 4837 } 4838 4839 // Lastly, measure CPU usage. 4840 if (processCpuTracker != null) { 4841 processCpuTracker.init(); 4842 System.gc(); 4843 processCpuTracker.update(); 4844 try { 4845 synchronized (processCpuTracker) { 4846 processCpuTracker.wait(500); // measure over 1/2 second. 4847 } 4848 } catch (InterruptedException e) { 4849 } 4850 processCpuTracker.update(); 4851 4852 // We'll take the stack crawls of just the top apps using CPU. 4853 final int N = processCpuTracker.countWorkingStats(); 4854 int numProcs = 0; 4855 for (int i=0; i<N && numProcs<5; i++) { 4856 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4857 if (lastPids.indexOfKey(stats.pid) >= 0) { 4858 numProcs++; 4859 try { 4860 synchronized (observer) { 4861 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4862 observer.wait(200); // Wait for write-close, give up after 200msec 4863 } 4864 } catch (InterruptedException e) { 4865 Log.wtf(TAG, e); 4866 } 4867 4868 } 4869 } 4870 } 4871 } finally { 4872 observer.stopWatching(); 4873 } 4874 } 4875 4876 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4877 if (true || IS_USER_BUILD) { 4878 return; 4879 } 4880 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4881 if (tracesPath == null || tracesPath.length() == 0) { 4882 return; 4883 } 4884 4885 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4886 StrictMode.allowThreadDiskWrites(); 4887 try { 4888 final File tracesFile = new File(tracesPath); 4889 final File tracesDir = tracesFile.getParentFile(); 4890 final File tracesTmp = new File(tracesDir, "__tmp__"); 4891 try { 4892 if (!tracesDir.exists()) { 4893 tracesFile.mkdirs(); 4894 if (!SELinux.restorecon(tracesDir.getPath())) { 4895 return; 4896 } 4897 } 4898 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4899 4900 if (tracesFile.exists()) { 4901 tracesTmp.delete(); 4902 tracesFile.renameTo(tracesTmp); 4903 } 4904 StringBuilder sb = new StringBuilder(); 4905 Time tobj = new Time(); 4906 tobj.set(System.currentTimeMillis()); 4907 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4908 sb.append(": "); 4909 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4910 sb.append(" since "); 4911 sb.append(msg); 4912 FileOutputStream fos = new FileOutputStream(tracesFile); 4913 fos.write(sb.toString().getBytes()); 4914 if (app == null) { 4915 fos.write("\n*** No application process!".getBytes()); 4916 } 4917 fos.close(); 4918 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4919 } catch (IOException e) { 4920 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4921 return; 4922 } 4923 4924 if (app != null) { 4925 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4926 firstPids.add(app.pid); 4927 dumpStackTraces(tracesPath, firstPids, null, null, null); 4928 } 4929 4930 File lastTracesFile = null; 4931 File curTracesFile = null; 4932 for (int i=9; i>=0; i--) { 4933 String name = String.format(Locale.US, "slow%02d.txt", i); 4934 curTracesFile = new File(tracesDir, name); 4935 if (curTracesFile.exists()) { 4936 if (lastTracesFile != null) { 4937 curTracesFile.renameTo(lastTracesFile); 4938 } else { 4939 curTracesFile.delete(); 4940 } 4941 } 4942 lastTracesFile = curTracesFile; 4943 } 4944 tracesFile.renameTo(curTracesFile); 4945 if (tracesTmp.exists()) { 4946 tracesTmp.renameTo(tracesFile); 4947 } 4948 } finally { 4949 StrictMode.setThreadPolicy(oldPolicy); 4950 } 4951 } 4952 4953 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4954 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4955 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4956 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4957 4958 if (mController != null) { 4959 try { 4960 // 0 == continue, -1 = kill process immediately 4961 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4962 if (res < 0 && app.pid != MY_PID) { 4963 app.kill("anr", true); 4964 } 4965 } catch (RemoteException e) { 4966 mController = null; 4967 Watchdog.getInstance().setActivityController(null); 4968 } 4969 } 4970 4971 long anrTime = SystemClock.uptimeMillis(); 4972 if (MONITOR_CPU_USAGE) { 4973 updateCpuStatsNow(); 4974 } 4975 4976 synchronized (this) { 4977 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4978 if (mShuttingDown) { 4979 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4980 return; 4981 } else if (app.notResponding) { 4982 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4983 return; 4984 } else if (app.crashing) { 4985 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4986 return; 4987 } 4988 4989 // In case we come through here for the same app before completing 4990 // this one, mark as anring now so we will bail out. 4991 app.notResponding = true; 4992 4993 // Log the ANR to the event log. 4994 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4995 app.processName, app.info.flags, annotation); 4996 4997 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4998 firstPids.add(app.pid); 4999 5000 int parentPid = app.pid; 5001 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5002 if (parentPid != app.pid) firstPids.add(parentPid); 5003 5004 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5005 5006 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5007 ProcessRecord r = mLruProcesses.get(i); 5008 if (r != null && r.thread != null) { 5009 int pid = r.pid; 5010 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5011 if (r.persistent) { 5012 firstPids.add(pid); 5013 } else { 5014 lastPids.put(pid, Boolean.TRUE); 5015 } 5016 } 5017 } 5018 } 5019 } 5020 5021 // Log the ANR to the main log. 5022 StringBuilder info = new StringBuilder(); 5023 info.setLength(0); 5024 info.append("ANR in ").append(app.processName); 5025 if (activity != null && activity.shortComponentName != null) { 5026 info.append(" (").append(activity.shortComponentName).append(")"); 5027 } 5028 info.append("\n"); 5029 info.append("PID: ").append(app.pid).append("\n"); 5030 if (annotation != null) { 5031 info.append("Reason: ").append(annotation).append("\n"); 5032 } 5033 if (parent != null && parent != activity) { 5034 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5035 } 5036 5037 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5038 5039 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5040 NATIVE_STACKS_OF_INTEREST); 5041 5042 String cpuInfo = null; 5043 if (MONITOR_CPU_USAGE) { 5044 updateCpuStatsNow(); 5045 synchronized (mProcessCpuThread) { 5046 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5047 } 5048 info.append(processCpuTracker.printCurrentLoad()); 5049 info.append(cpuInfo); 5050 } 5051 5052 info.append(processCpuTracker.printCurrentState(anrTime)); 5053 5054 Slog.e(TAG, info.toString()); 5055 if (tracesFile == null) { 5056 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5057 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5058 } 5059 5060 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5061 cpuInfo, tracesFile, null); 5062 5063 if (mController != null) { 5064 try { 5065 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5066 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5067 if (res != 0) { 5068 if (res < 0 && app.pid != MY_PID) { 5069 app.kill("anr", true); 5070 } else { 5071 synchronized (this) { 5072 mServices.scheduleServiceTimeoutLocked(app); 5073 } 5074 } 5075 return; 5076 } 5077 } catch (RemoteException e) { 5078 mController = null; 5079 Watchdog.getInstance().setActivityController(null); 5080 } 5081 } 5082 5083 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5084 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5085 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5086 5087 synchronized (this) { 5088 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5089 app.kill("bg anr", true); 5090 return; 5091 } 5092 5093 // Set the app's notResponding state, and look up the errorReportReceiver 5094 makeAppNotRespondingLocked(app, 5095 activity != null ? activity.shortComponentName : null, 5096 annotation != null ? "ANR " + annotation : "ANR", 5097 info.toString()); 5098 5099 // Bring up the infamous App Not Responding dialog 5100 Message msg = Message.obtain(); 5101 HashMap<String, Object> map = new HashMap<String, Object>(); 5102 msg.what = SHOW_NOT_RESPONDING_MSG; 5103 msg.obj = map; 5104 msg.arg1 = aboveSystem ? 1 : 0; 5105 map.put("app", app); 5106 if (activity != null) { 5107 map.put("activity", activity); 5108 } 5109 5110 mHandler.sendMessage(msg); 5111 } 5112 } 5113 5114 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5115 if (!mLaunchWarningShown) { 5116 mLaunchWarningShown = true; 5117 mHandler.post(new Runnable() { 5118 @Override 5119 public void run() { 5120 synchronized (ActivityManagerService.this) { 5121 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5122 d.show(); 5123 mHandler.postDelayed(new Runnable() { 5124 @Override 5125 public void run() { 5126 synchronized (ActivityManagerService.this) { 5127 d.dismiss(); 5128 mLaunchWarningShown = false; 5129 } 5130 } 5131 }, 4000); 5132 } 5133 } 5134 }); 5135 } 5136 } 5137 5138 @Override 5139 public boolean clearApplicationUserData(final String packageName, 5140 final IPackageDataObserver observer, int userId) { 5141 enforceNotIsolatedCaller("clearApplicationUserData"); 5142 int uid = Binder.getCallingUid(); 5143 int pid = Binder.getCallingPid(); 5144 userId = handleIncomingUser(pid, uid, 5145 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5146 long callingId = Binder.clearCallingIdentity(); 5147 try { 5148 IPackageManager pm = AppGlobals.getPackageManager(); 5149 int pkgUid = -1; 5150 synchronized(this) { 5151 try { 5152 pkgUid = pm.getPackageUid(packageName, userId); 5153 } catch (RemoteException e) { 5154 } 5155 if (pkgUid == -1) { 5156 Slog.w(TAG, "Invalid packageName: " + packageName); 5157 if (observer != null) { 5158 try { 5159 observer.onRemoveCompleted(packageName, false); 5160 } catch (RemoteException e) { 5161 Slog.i(TAG, "Observer no longer exists."); 5162 } 5163 } 5164 return false; 5165 } 5166 if (uid == pkgUid || checkComponentPermission( 5167 android.Manifest.permission.CLEAR_APP_USER_DATA, 5168 pid, uid, -1, true) 5169 == PackageManager.PERMISSION_GRANTED) { 5170 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5171 } else { 5172 throw new SecurityException("PID " + pid + " does not have permission " 5173 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5174 + " of package " + packageName); 5175 } 5176 5177 // Remove all tasks match the cleared application package and user 5178 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5179 final TaskRecord tr = mRecentTasks.get(i); 5180 final String taskPackageName = 5181 tr.getBaseIntent().getComponent().getPackageName(); 5182 if (tr.userId != userId) continue; 5183 if (!taskPackageName.equals(packageName)) continue; 5184 removeTaskByIdLocked(tr.taskId, 0); 5185 } 5186 } 5187 5188 try { 5189 // Clear application user data 5190 pm.clearApplicationUserData(packageName, observer, userId); 5191 5192 synchronized(this) { 5193 // Remove all permissions granted from/to this package 5194 removeUriPermissionsForPackageLocked(packageName, userId, true); 5195 } 5196 5197 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5198 Uri.fromParts("package", packageName, null)); 5199 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5200 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5201 null, null, 0, null, null, null, false, false, userId); 5202 } catch (RemoteException e) { 5203 } 5204 } finally { 5205 Binder.restoreCallingIdentity(callingId); 5206 } 5207 return true; 5208 } 5209 5210 @Override 5211 public void killBackgroundProcesses(final String packageName, int userId) { 5212 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5213 != PackageManager.PERMISSION_GRANTED && 5214 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5215 != PackageManager.PERMISSION_GRANTED) { 5216 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5217 + Binder.getCallingPid() 5218 + ", uid=" + Binder.getCallingUid() 5219 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5220 Slog.w(TAG, msg); 5221 throw new SecurityException(msg); 5222 } 5223 5224 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5225 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5226 long callingId = Binder.clearCallingIdentity(); 5227 try { 5228 IPackageManager pm = AppGlobals.getPackageManager(); 5229 synchronized(this) { 5230 int appId = -1; 5231 try { 5232 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5233 } catch (RemoteException e) { 5234 } 5235 if (appId == -1) { 5236 Slog.w(TAG, "Invalid packageName: " + packageName); 5237 return; 5238 } 5239 killPackageProcessesLocked(packageName, appId, userId, 5240 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5241 } 5242 } finally { 5243 Binder.restoreCallingIdentity(callingId); 5244 } 5245 } 5246 5247 @Override 5248 public void killAllBackgroundProcesses() { 5249 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5250 != PackageManager.PERMISSION_GRANTED) { 5251 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5252 + Binder.getCallingPid() 5253 + ", uid=" + Binder.getCallingUid() 5254 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5255 Slog.w(TAG, msg); 5256 throw new SecurityException(msg); 5257 } 5258 5259 long callingId = Binder.clearCallingIdentity(); 5260 try { 5261 synchronized(this) { 5262 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5263 final int NP = mProcessNames.getMap().size(); 5264 for (int ip=0; ip<NP; ip++) { 5265 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5266 final int NA = apps.size(); 5267 for (int ia=0; ia<NA; ia++) { 5268 ProcessRecord app = apps.valueAt(ia); 5269 if (app.persistent) { 5270 // we don't kill persistent processes 5271 continue; 5272 } 5273 if (app.removed) { 5274 procs.add(app); 5275 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5276 app.removed = true; 5277 procs.add(app); 5278 } 5279 } 5280 } 5281 5282 int N = procs.size(); 5283 for (int i=0; i<N; i++) { 5284 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5285 } 5286 mAllowLowerMemLevel = true; 5287 updateOomAdjLocked(); 5288 doLowMemReportIfNeededLocked(null); 5289 } 5290 } finally { 5291 Binder.restoreCallingIdentity(callingId); 5292 } 5293 } 5294 5295 @Override 5296 public void forceStopPackage(final String packageName, int userId) { 5297 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5298 != PackageManager.PERMISSION_GRANTED) { 5299 String msg = "Permission Denial: forceStopPackage() from pid=" 5300 + Binder.getCallingPid() 5301 + ", uid=" + Binder.getCallingUid() 5302 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5303 Slog.w(TAG, msg); 5304 throw new SecurityException(msg); 5305 } 5306 final int callingPid = Binder.getCallingPid(); 5307 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5308 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5309 long callingId = Binder.clearCallingIdentity(); 5310 try { 5311 IPackageManager pm = AppGlobals.getPackageManager(); 5312 synchronized(this) { 5313 int[] users = userId == UserHandle.USER_ALL 5314 ? getUsersLocked() : new int[] { userId }; 5315 for (int user : users) { 5316 int pkgUid = -1; 5317 try { 5318 pkgUid = pm.getPackageUid(packageName, user); 5319 } catch (RemoteException e) { 5320 } 5321 if (pkgUid == -1) { 5322 Slog.w(TAG, "Invalid packageName: " + packageName); 5323 continue; 5324 } 5325 try { 5326 pm.setPackageStoppedState(packageName, true, user); 5327 } catch (RemoteException e) { 5328 } catch (IllegalArgumentException e) { 5329 Slog.w(TAG, "Failed trying to unstop package " 5330 + packageName + ": " + e); 5331 } 5332 if (isUserRunningLocked(user, false)) { 5333 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5334 } 5335 } 5336 } 5337 } finally { 5338 Binder.restoreCallingIdentity(callingId); 5339 } 5340 } 5341 5342 @Override 5343 public void addPackageDependency(String packageName) { 5344 synchronized (this) { 5345 int callingPid = Binder.getCallingPid(); 5346 if (callingPid == Process.myPid()) { 5347 // Yeah, um, no. 5348 Slog.w(TAG, "Can't addPackageDependency on system process"); 5349 return; 5350 } 5351 ProcessRecord proc; 5352 synchronized (mPidsSelfLocked) { 5353 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5354 } 5355 if (proc != null) { 5356 if (proc.pkgDeps == null) { 5357 proc.pkgDeps = new ArraySet<String>(1); 5358 } 5359 proc.pkgDeps.add(packageName); 5360 } 5361 } 5362 } 5363 5364 /* 5365 * The pkg name and app id have to be specified. 5366 */ 5367 @Override 5368 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5369 if (pkg == null) { 5370 return; 5371 } 5372 // Make sure the uid is valid. 5373 if (appid < 0) { 5374 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5375 return; 5376 } 5377 int callerUid = Binder.getCallingUid(); 5378 // Only the system server can kill an application 5379 if (callerUid == Process.SYSTEM_UID) { 5380 // Post an aysnc message to kill the application 5381 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5382 msg.arg1 = appid; 5383 msg.arg2 = 0; 5384 Bundle bundle = new Bundle(); 5385 bundle.putString("pkg", pkg); 5386 bundle.putString("reason", reason); 5387 msg.obj = bundle; 5388 mHandler.sendMessage(msg); 5389 } else { 5390 throw new SecurityException(callerUid + " cannot kill pkg: " + 5391 pkg); 5392 } 5393 } 5394 5395 @Override 5396 public void closeSystemDialogs(String reason) { 5397 enforceNotIsolatedCaller("closeSystemDialogs"); 5398 5399 final int pid = Binder.getCallingPid(); 5400 final int uid = Binder.getCallingUid(); 5401 final long origId = Binder.clearCallingIdentity(); 5402 try { 5403 synchronized (this) { 5404 // Only allow this from foreground processes, so that background 5405 // applications can't abuse it to prevent system UI from being shown. 5406 if (uid >= Process.FIRST_APPLICATION_UID) { 5407 ProcessRecord proc; 5408 synchronized (mPidsSelfLocked) { 5409 proc = mPidsSelfLocked.get(pid); 5410 } 5411 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5412 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5413 + " from background process " + proc); 5414 return; 5415 } 5416 } 5417 closeSystemDialogsLocked(reason); 5418 } 5419 } finally { 5420 Binder.restoreCallingIdentity(origId); 5421 } 5422 } 5423 5424 void closeSystemDialogsLocked(String reason) { 5425 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5426 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5427 | Intent.FLAG_RECEIVER_FOREGROUND); 5428 if (reason != null) { 5429 intent.putExtra("reason", reason); 5430 } 5431 mWindowManager.closeSystemDialogs(reason); 5432 5433 mStackSupervisor.closeSystemDialogsLocked(); 5434 5435 broadcastIntentLocked(null, null, intent, null, 5436 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5437 Process.SYSTEM_UID, UserHandle.USER_ALL); 5438 } 5439 5440 @Override 5441 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5442 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5443 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5444 for (int i=pids.length-1; i>=0; i--) { 5445 ProcessRecord proc; 5446 int oomAdj; 5447 synchronized (this) { 5448 synchronized (mPidsSelfLocked) { 5449 proc = mPidsSelfLocked.get(pids[i]); 5450 oomAdj = proc != null ? proc.setAdj : 0; 5451 } 5452 } 5453 infos[i] = new Debug.MemoryInfo(); 5454 Debug.getMemoryInfo(pids[i], infos[i]); 5455 if (proc != null) { 5456 synchronized (this) { 5457 if (proc.thread != null && proc.setAdj == oomAdj) { 5458 // Record this for posterity if the process has been stable. 5459 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5460 infos[i].getTotalUss(), false, proc.pkgList); 5461 } 5462 } 5463 } 5464 } 5465 return infos; 5466 } 5467 5468 @Override 5469 public long[] getProcessPss(int[] pids) { 5470 enforceNotIsolatedCaller("getProcessPss"); 5471 long[] pss = new long[pids.length]; 5472 for (int i=pids.length-1; i>=0; i--) { 5473 ProcessRecord proc; 5474 int oomAdj; 5475 synchronized (this) { 5476 synchronized (mPidsSelfLocked) { 5477 proc = mPidsSelfLocked.get(pids[i]); 5478 oomAdj = proc != null ? proc.setAdj : 0; 5479 } 5480 } 5481 long[] tmpUss = new long[1]; 5482 pss[i] = Debug.getPss(pids[i], tmpUss); 5483 if (proc != null) { 5484 synchronized (this) { 5485 if (proc.thread != null && proc.setAdj == oomAdj) { 5486 // Record this for posterity if the process has been stable. 5487 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5488 } 5489 } 5490 } 5491 } 5492 return pss; 5493 } 5494 5495 @Override 5496 public void killApplicationProcess(String processName, int uid) { 5497 if (processName == null) { 5498 return; 5499 } 5500 5501 int callerUid = Binder.getCallingUid(); 5502 // Only the system server can kill an application 5503 if (callerUid == Process.SYSTEM_UID) { 5504 synchronized (this) { 5505 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5506 if (app != null && app.thread != null) { 5507 try { 5508 app.thread.scheduleSuicide(); 5509 } catch (RemoteException e) { 5510 // If the other end already died, then our work here is done. 5511 } 5512 } else { 5513 Slog.w(TAG, "Process/uid not found attempting kill of " 5514 + processName + " / " + uid); 5515 } 5516 } 5517 } else { 5518 throw new SecurityException(callerUid + " cannot kill app process: " + 5519 processName); 5520 } 5521 } 5522 5523 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5524 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5525 false, true, false, false, UserHandle.getUserId(uid), reason); 5526 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5527 Uri.fromParts("package", packageName, null)); 5528 if (!mProcessesReady) { 5529 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5530 | Intent.FLAG_RECEIVER_FOREGROUND); 5531 } 5532 intent.putExtra(Intent.EXTRA_UID, uid); 5533 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5534 broadcastIntentLocked(null, null, intent, 5535 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5536 false, false, 5537 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5538 } 5539 5540 private void forceStopUserLocked(int userId, String reason) { 5541 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5542 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5543 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5544 | Intent.FLAG_RECEIVER_FOREGROUND); 5545 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5546 broadcastIntentLocked(null, null, intent, 5547 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5548 false, false, 5549 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5550 } 5551 5552 private final boolean killPackageProcessesLocked(String packageName, int appId, 5553 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5554 boolean doit, boolean evenPersistent, String reason) { 5555 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5556 5557 // Remove all processes this package may have touched: all with the 5558 // same UID (except for the system or root user), and all whose name 5559 // matches the package name. 5560 final int NP = mProcessNames.getMap().size(); 5561 for (int ip=0; ip<NP; ip++) { 5562 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5563 final int NA = apps.size(); 5564 for (int ia=0; ia<NA; ia++) { 5565 ProcessRecord app = apps.valueAt(ia); 5566 if (app.persistent && !evenPersistent) { 5567 // we don't kill persistent processes 5568 continue; 5569 } 5570 if (app.removed) { 5571 if (doit) { 5572 procs.add(app); 5573 } 5574 continue; 5575 } 5576 5577 // Skip process if it doesn't meet our oom adj requirement. 5578 if (app.setAdj < minOomAdj) { 5579 continue; 5580 } 5581 5582 // If no package is specified, we call all processes under the 5583 // give user id. 5584 if (packageName == null) { 5585 if (app.userId != userId) { 5586 continue; 5587 } 5588 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5589 continue; 5590 } 5591 // Package has been specified, we want to hit all processes 5592 // that match it. We need to qualify this by the processes 5593 // that are running under the specified app and user ID. 5594 } else { 5595 final boolean isDep = app.pkgDeps != null 5596 && app.pkgDeps.contains(packageName); 5597 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5598 continue; 5599 } 5600 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5601 continue; 5602 } 5603 if (!app.pkgList.containsKey(packageName) && !isDep) { 5604 continue; 5605 } 5606 } 5607 5608 // Process has passed all conditions, kill it! 5609 if (!doit) { 5610 return true; 5611 } 5612 app.removed = true; 5613 procs.add(app); 5614 } 5615 } 5616 5617 int N = procs.size(); 5618 for (int i=0; i<N; i++) { 5619 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5620 } 5621 updateOomAdjLocked(); 5622 return N > 0; 5623 } 5624 5625 private final boolean forceStopPackageLocked(String name, int appId, 5626 boolean callerWillRestart, boolean purgeCache, boolean doit, 5627 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5628 int i; 5629 int N; 5630 5631 if (userId == UserHandle.USER_ALL && name == null) { 5632 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5633 } 5634 5635 if (appId < 0 && name != null) { 5636 try { 5637 appId = UserHandle.getAppId( 5638 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5639 } catch (RemoteException e) { 5640 } 5641 } 5642 5643 if (doit) { 5644 if (name != null) { 5645 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5646 + " user=" + userId + ": " + reason); 5647 } else { 5648 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5649 } 5650 5651 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5652 for (int ip=pmap.size()-1; ip>=0; ip--) { 5653 SparseArray<Long> ba = pmap.valueAt(ip); 5654 for (i=ba.size()-1; i>=0; i--) { 5655 boolean remove = false; 5656 final int entUid = ba.keyAt(i); 5657 if (name != null) { 5658 if (userId == UserHandle.USER_ALL) { 5659 if (UserHandle.getAppId(entUid) == appId) { 5660 remove = true; 5661 } 5662 } else { 5663 if (entUid == UserHandle.getUid(userId, appId)) { 5664 remove = true; 5665 } 5666 } 5667 } else if (UserHandle.getUserId(entUid) == userId) { 5668 remove = true; 5669 } 5670 if (remove) { 5671 ba.removeAt(i); 5672 } 5673 } 5674 if (ba.size() == 0) { 5675 pmap.removeAt(ip); 5676 } 5677 } 5678 } 5679 5680 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5681 -100, callerWillRestart, true, doit, evenPersistent, 5682 name == null ? ("stop user " + userId) : ("stop " + name)); 5683 5684 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5685 if (!doit) { 5686 return true; 5687 } 5688 didSomething = true; 5689 } 5690 5691 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5692 if (!doit) { 5693 return true; 5694 } 5695 didSomething = true; 5696 } 5697 5698 if (name == null) { 5699 // Remove all sticky broadcasts from this user. 5700 mStickyBroadcasts.remove(userId); 5701 } 5702 5703 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5704 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5705 userId, providers)) { 5706 if (!doit) { 5707 return true; 5708 } 5709 didSomething = true; 5710 } 5711 N = providers.size(); 5712 for (i=0; i<N; i++) { 5713 removeDyingProviderLocked(null, providers.get(i), true); 5714 } 5715 5716 // Remove transient permissions granted from/to this package/user 5717 removeUriPermissionsForPackageLocked(name, userId, false); 5718 5719 if (name == null || uninstalling) { 5720 // Remove pending intents. For now we only do this when force 5721 // stopping users, because we have some problems when doing this 5722 // for packages -- app widgets are not currently cleaned up for 5723 // such packages, so they can be left with bad pending intents. 5724 if (mIntentSenderRecords.size() > 0) { 5725 Iterator<WeakReference<PendingIntentRecord>> it 5726 = mIntentSenderRecords.values().iterator(); 5727 while (it.hasNext()) { 5728 WeakReference<PendingIntentRecord> wpir = it.next(); 5729 if (wpir == null) { 5730 it.remove(); 5731 continue; 5732 } 5733 PendingIntentRecord pir = wpir.get(); 5734 if (pir == null) { 5735 it.remove(); 5736 continue; 5737 } 5738 if (name == null) { 5739 // Stopping user, remove all objects for the user. 5740 if (pir.key.userId != userId) { 5741 // Not the same user, skip it. 5742 continue; 5743 } 5744 } else { 5745 if (UserHandle.getAppId(pir.uid) != appId) { 5746 // Different app id, skip it. 5747 continue; 5748 } 5749 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5750 // Different user, skip it. 5751 continue; 5752 } 5753 if (!pir.key.packageName.equals(name)) { 5754 // Different package, skip it. 5755 continue; 5756 } 5757 } 5758 if (!doit) { 5759 return true; 5760 } 5761 didSomething = true; 5762 it.remove(); 5763 pir.canceled = true; 5764 if (pir.key.activity != null) { 5765 pir.key.activity.pendingResults.remove(pir.ref); 5766 } 5767 } 5768 } 5769 } 5770 5771 if (doit) { 5772 if (purgeCache && name != null) { 5773 AttributeCache ac = AttributeCache.instance(); 5774 if (ac != null) { 5775 ac.removePackage(name); 5776 } 5777 } 5778 if (mBooted) { 5779 mStackSupervisor.resumeTopActivitiesLocked(); 5780 mStackSupervisor.scheduleIdleLocked(); 5781 } 5782 } 5783 5784 return didSomething; 5785 } 5786 5787 private final boolean removeProcessLocked(ProcessRecord app, 5788 boolean callerWillRestart, boolean allowRestart, String reason) { 5789 final String name = app.processName; 5790 final int uid = app.uid; 5791 if (DEBUG_PROCESSES) Slog.d( 5792 TAG, "Force removing proc " + app.toShortString() + " (" + name 5793 + "/" + uid + ")"); 5794 5795 mProcessNames.remove(name, uid); 5796 mIsolatedProcesses.remove(app.uid); 5797 if (mHeavyWeightProcess == app) { 5798 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5799 mHeavyWeightProcess.userId, 0)); 5800 mHeavyWeightProcess = null; 5801 } 5802 boolean needRestart = false; 5803 if (app.pid > 0 && app.pid != MY_PID) { 5804 int pid = app.pid; 5805 synchronized (mPidsSelfLocked) { 5806 mPidsSelfLocked.remove(pid); 5807 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5808 } 5809 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5810 if (app.isolated) { 5811 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5812 } 5813 app.kill(reason, true); 5814 handleAppDiedLocked(app, true, allowRestart); 5815 removeLruProcessLocked(app); 5816 5817 if (app.persistent && !app.isolated) { 5818 if (!callerWillRestart) { 5819 addAppLocked(app.info, false, null /* ABI override */); 5820 } else { 5821 needRestart = true; 5822 } 5823 } 5824 } else { 5825 mRemovedProcesses.add(app); 5826 } 5827 5828 return needRestart; 5829 } 5830 5831 private final void processStartTimedOutLocked(ProcessRecord app) { 5832 final int pid = app.pid; 5833 boolean gone = false; 5834 synchronized (mPidsSelfLocked) { 5835 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5836 if (knownApp != null && knownApp.thread == null) { 5837 mPidsSelfLocked.remove(pid); 5838 gone = true; 5839 } 5840 } 5841 5842 if (gone) { 5843 Slog.w(TAG, "Process " + app + " failed to attach"); 5844 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5845 pid, app.uid, app.processName); 5846 mProcessNames.remove(app.processName, app.uid); 5847 mIsolatedProcesses.remove(app.uid); 5848 if (mHeavyWeightProcess == app) { 5849 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5850 mHeavyWeightProcess.userId, 0)); 5851 mHeavyWeightProcess = null; 5852 } 5853 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5854 if (app.isolated) { 5855 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5856 } 5857 // Take care of any launching providers waiting for this process. 5858 checkAppInLaunchingProvidersLocked(app, true); 5859 // Take care of any services that are waiting for the process. 5860 mServices.processStartTimedOutLocked(app); 5861 app.kill("start timeout", true); 5862 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5863 Slog.w(TAG, "Unattached app died before backup, skipping"); 5864 try { 5865 IBackupManager bm = IBackupManager.Stub.asInterface( 5866 ServiceManager.getService(Context.BACKUP_SERVICE)); 5867 bm.agentDisconnected(app.info.packageName); 5868 } catch (RemoteException e) { 5869 // Can't happen; the backup manager is local 5870 } 5871 } 5872 if (isPendingBroadcastProcessLocked(pid)) { 5873 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5874 skipPendingBroadcastLocked(pid); 5875 } 5876 } else { 5877 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5878 } 5879 } 5880 5881 private final boolean attachApplicationLocked(IApplicationThread thread, 5882 int pid) { 5883 5884 // Find the application record that is being attached... either via 5885 // the pid if we are running in multiple processes, or just pull the 5886 // next app record if we are emulating process with anonymous threads. 5887 ProcessRecord app; 5888 if (pid != MY_PID && pid >= 0) { 5889 synchronized (mPidsSelfLocked) { 5890 app = mPidsSelfLocked.get(pid); 5891 } 5892 } else { 5893 app = null; 5894 } 5895 5896 if (app == null) { 5897 Slog.w(TAG, "No pending application record for pid " + pid 5898 + " (IApplicationThread " + thread + "); dropping process"); 5899 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5900 if (pid > 0 && pid != MY_PID) { 5901 Process.killProcessQuiet(pid); 5902 //TODO: Process.killProcessGroup(app.info.uid, pid); 5903 } else { 5904 try { 5905 thread.scheduleExit(); 5906 } catch (Exception e) { 5907 // Ignore exceptions. 5908 } 5909 } 5910 return false; 5911 } 5912 5913 // If this application record is still attached to a previous 5914 // process, clean it up now. 5915 if (app.thread != null) { 5916 handleAppDiedLocked(app, true, true); 5917 } 5918 5919 // Tell the process all about itself. 5920 5921 if (localLOGV) Slog.v( 5922 TAG, "Binding process pid " + pid + " to record " + app); 5923 5924 final String processName = app.processName; 5925 try { 5926 AppDeathRecipient adr = new AppDeathRecipient( 5927 app, pid, thread); 5928 thread.asBinder().linkToDeath(adr, 0); 5929 app.deathRecipient = adr; 5930 } catch (RemoteException e) { 5931 app.resetPackageList(mProcessStats); 5932 startProcessLocked(app, "link fail", processName); 5933 return false; 5934 } 5935 5936 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5937 5938 app.makeActive(thread, mProcessStats); 5939 app.curAdj = app.setAdj = -100; 5940 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5941 app.forcingToForeground = null; 5942 updateProcessForegroundLocked(app, false, false); 5943 app.hasShownUi = false; 5944 app.debugging = false; 5945 app.cached = false; 5946 5947 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5948 5949 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5950 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5951 5952 if (!normalMode) { 5953 Slog.i(TAG, "Launching preboot mode app: " + app); 5954 } 5955 5956 if (localLOGV) Slog.v( 5957 TAG, "New app record " + app 5958 + " thread=" + thread.asBinder() + " pid=" + pid); 5959 try { 5960 int testMode = IApplicationThread.DEBUG_OFF; 5961 if (mDebugApp != null && mDebugApp.equals(processName)) { 5962 testMode = mWaitForDebugger 5963 ? IApplicationThread.DEBUG_WAIT 5964 : IApplicationThread.DEBUG_ON; 5965 app.debugging = true; 5966 if (mDebugTransient) { 5967 mDebugApp = mOrigDebugApp; 5968 mWaitForDebugger = mOrigWaitForDebugger; 5969 } 5970 } 5971 String profileFile = app.instrumentationProfileFile; 5972 ParcelFileDescriptor profileFd = null; 5973 boolean profileAutoStop = false; 5974 if (mProfileApp != null && mProfileApp.equals(processName)) { 5975 mProfileProc = app; 5976 profileFile = mProfileFile; 5977 profileFd = mProfileFd; 5978 profileAutoStop = mAutoStopProfiler; 5979 } 5980 boolean enableOpenGlTrace = false; 5981 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5982 enableOpenGlTrace = true; 5983 mOpenGlTraceApp = null; 5984 } 5985 5986 // If the app is being launched for restore or full backup, set it up specially 5987 boolean isRestrictedBackupMode = false; 5988 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5989 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5990 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5991 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5992 } 5993 5994 ensurePackageDexOpt(app.instrumentationInfo != null 5995 ? app.instrumentationInfo.packageName 5996 : app.info.packageName); 5997 if (app.instrumentationClass != null) { 5998 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5999 } 6000 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6001 + processName + " with config " + mConfiguration); 6002 ApplicationInfo appInfo = app.instrumentationInfo != null 6003 ? app.instrumentationInfo : app.info; 6004 app.compat = compatibilityInfoForPackageLocked(appInfo); 6005 if (profileFd != null) { 6006 profileFd = profileFd.dup(); 6007 } 6008 thread.bindApplication(processName, appInfo, providers, 6009 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 6010 app.instrumentationArguments, app.instrumentationWatcher, 6011 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6012 isRestrictedBackupMode || !normalMode, app.persistent, 6013 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6014 mCoreSettingsObserver.getCoreSettingsLocked()); 6015 updateLruProcessLocked(app, false, null); 6016 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6017 } catch (Exception e) { 6018 // todo: Yikes! What should we do? For now we will try to 6019 // start another process, but that could easily get us in 6020 // an infinite loop of restarting processes... 6021 Slog.w(TAG, "Exception thrown during bind!", e); 6022 6023 app.resetPackageList(mProcessStats); 6024 app.unlinkDeathRecipient(); 6025 startProcessLocked(app, "bind fail", processName); 6026 return false; 6027 } 6028 6029 // Remove this record from the list of starting applications. 6030 mPersistentStartingProcesses.remove(app); 6031 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6032 "Attach application locked removing on hold: " + app); 6033 mProcessesOnHold.remove(app); 6034 6035 boolean badApp = false; 6036 boolean didSomething = false; 6037 6038 // See if the top visible activity is waiting to run in this process... 6039 if (normalMode) { 6040 try { 6041 if (mStackSupervisor.attachApplicationLocked(app)) { 6042 didSomething = true; 6043 } 6044 } catch (Exception e) { 6045 badApp = true; 6046 } 6047 } 6048 6049 // Find any services that should be running in this process... 6050 if (!badApp) { 6051 try { 6052 didSomething |= mServices.attachApplicationLocked(app, processName); 6053 } catch (Exception e) { 6054 badApp = true; 6055 } 6056 } 6057 6058 // Check if a next-broadcast receiver is in this process... 6059 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6060 try { 6061 didSomething |= sendPendingBroadcastsLocked(app); 6062 } catch (Exception e) { 6063 // If the app died trying to launch the receiver we declare it 'bad' 6064 badApp = true; 6065 } 6066 } 6067 6068 // Check whether the next backup agent is in this process... 6069 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6070 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6071 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6072 try { 6073 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6074 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6075 mBackupTarget.backupMode); 6076 } catch (Exception e) { 6077 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6078 e.printStackTrace(); 6079 } 6080 } 6081 6082 if (badApp) { 6083 // todo: Also need to kill application to deal with all 6084 // kinds of exceptions. 6085 handleAppDiedLocked(app, false, true); 6086 return false; 6087 } 6088 6089 if (!didSomething) { 6090 updateOomAdjLocked(); 6091 } 6092 6093 return true; 6094 } 6095 6096 @Override 6097 public final void attachApplication(IApplicationThread thread) { 6098 synchronized (this) { 6099 int callingPid = Binder.getCallingPid(); 6100 final long origId = Binder.clearCallingIdentity(); 6101 attachApplicationLocked(thread, callingPid); 6102 Binder.restoreCallingIdentity(origId); 6103 } 6104 } 6105 6106 @Override 6107 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6108 final long origId = Binder.clearCallingIdentity(); 6109 synchronized (this) { 6110 ActivityStack stack = ActivityRecord.getStackLocked(token); 6111 if (stack != null) { 6112 ActivityRecord r = 6113 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6114 if (stopProfiling) { 6115 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6116 try { 6117 mProfileFd.close(); 6118 } catch (IOException e) { 6119 } 6120 clearProfilerLocked(); 6121 } 6122 } 6123 } 6124 } 6125 Binder.restoreCallingIdentity(origId); 6126 } 6127 6128 void postEnableScreenAfterBootLocked() { 6129 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6130 } 6131 6132 void enableScreenAfterBoot() { 6133 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6134 SystemClock.uptimeMillis()); 6135 mWindowManager.enableScreenAfterBoot(); 6136 6137 synchronized (this) { 6138 updateEventDispatchingLocked(); 6139 } 6140 } 6141 6142 @Override 6143 public void showBootMessage(final CharSequence msg, final boolean always) { 6144 enforceNotIsolatedCaller("showBootMessage"); 6145 mWindowManager.showBootMessage(msg, always); 6146 } 6147 6148 @Override 6149 public void keyguardWaitingForActivityDrawn() { 6150 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6151 final long token = Binder.clearCallingIdentity(); 6152 try { 6153 synchronized (this) { 6154 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6155 mWindowManager.keyguardWaitingForActivityDrawn(); 6156 } 6157 } finally { 6158 Binder.restoreCallingIdentity(token); 6159 } 6160 } 6161 6162 final void finishBooting() { 6163 // Register receivers to handle package update events 6164 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6165 6166 // Let system services know. 6167 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6168 6169 synchronized (this) { 6170 // Ensure that any processes we had put on hold are now started 6171 // up. 6172 final int NP = mProcessesOnHold.size(); 6173 if (NP > 0) { 6174 ArrayList<ProcessRecord> procs = 6175 new ArrayList<ProcessRecord>(mProcessesOnHold); 6176 for (int ip=0; ip<NP; ip++) { 6177 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6178 + procs.get(ip)); 6179 startProcessLocked(procs.get(ip), "on-hold", null); 6180 } 6181 } 6182 6183 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6184 // Start looking for apps that are abusing wake locks. 6185 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6186 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6187 // Tell anyone interested that we are done booting! 6188 SystemProperties.set("sys.boot_completed", "1"); 6189 SystemProperties.set("dev.bootcomplete", "1"); 6190 for (int i=0; i<mStartedUsers.size(); i++) { 6191 UserStartedState uss = mStartedUsers.valueAt(i); 6192 if (uss.mState == UserStartedState.STATE_BOOTING) { 6193 uss.mState = UserStartedState.STATE_RUNNING; 6194 final int userId = mStartedUsers.keyAt(i); 6195 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6196 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6197 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6198 broadcastIntentLocked(null, null, intent, null, 6199 new IIntentReceiver.Stub() { 6200 @Override 6201 public void performReceive(Intent intent, int resultCode, 6202 String data, Bundle extras, boolean ordered, 6203 boolean sticky, int sendingUser) { 6204 synchronized (ActivityManagerService.this) { 6205 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6206 true, false); 6207 } 6208 } 6209 }, 6210 0, null, null, 6211 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6212 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6213 userId); 6214 } 6215 } 6216 scheduleStartProfilesLocked(); 6217 } 6218 } 6219 } 6220 6221 final void ensureBootCompleted() { 6222 boolean booting; 6223 boolean enableScreen; 6224 synchronized (this) { 6225 booting = mBooting; 6226 mBooting = false; 6227 enableScreen = !mBooted; 6228 mBooted = true; 6229 } 6230 6231 if (booting) { 6232 finishBooting(); 6233 } 6234 6235 if (enableScreen) { 6236 enableScreenAfterBoot(); 6237 } 6238 } 6239 6240 @Override 6241 public final void activityResumed(IBinder token) { 6242 final long origId = Binder.clearCallingIdentity(); 6243 synchronized(this) { 6244 ActivityStack stack = ActivityRecord.getStackLocked(token); 6245 if (stack != null) { 6246 ActivityRecord.activityResumedLocked(token); 6247 } 6248 } 6249 Binder.restoreCallingIdentity(origId); 6250 } 6251 6252 @Override 6253 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6254 final long origId = Binder.clearCallingIdentity(); 6255 synchronized(this) { 6256 ActivityStack stack = ActivityRecord.getStackLocked(token); 6257 if (stack != null) { 6258 stack.activityPausedLocked(token, false, persistentState); 6259 } 6260 } 6261 Binder.restoreCallingIdentity(origId); 6262 } 6263 6264 @Override 6265 public final void activityStopped(IBinder token, Bundle icicle, 6266 PersistableBundle persistentState, CharSequence description) { 6267 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6268 6269 // Refuse possible leaked file descriptors 6270 if (icicle != null && icicle.hasFileDescriptors()) { 6271 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6272 } 6273 6274 final long origId = Binder.clearCallingIdentity(); 6275 6276 synchronized (this) { 6277 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6278 if (r != null) { 6279 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6280 } 6281 } 6282 6283 trimApplications(); 6284 6285 Binder.restoreCallingIdentity(origId); 6286 } 6287 6288 @Override 6289 public final void activityDestroyed(IBinder token) { 6290 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6291 synchronized (this) { 6292 ActivityStack stack = ActivityRecord.getStackLocked(token); 6293 if (stack != null) { 6294 stack.activityDestroyedLocked(token); 6295 } 6296 } 6297 } 6298 6299 @Override 6300 public final void backgroundResourcesReleased(IBinder token) { 6301 final long origId = Binder.clearCallingIdentity(); 6302 try { 6303 synchronized (this) { 6304 ActivityStack stack = ActivityRecord.getStackLocked(token); 6305 if (stack != null) { 6306 stack.backgroundResourcesReleased(token); 6307 } 6308 } 6309 } finally { 6310 Binder.restoreCallingIdentity(origId); 6311 } 6312 } 6313 6314 @Override 6315 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6316 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6317 } 6318 6319 @Override 6320 public final void notifyEnterAnimationComplete(IBinder token) { 6321 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6322 } 6323 6324 @Override 6325 public String getCallingPackage(IBinder token) { 6326 synchronized (this) { 6327 ActivityRecord r = getCallingRecordLocked(token); 6328 return r != null ? r.info.packageName : null; 6329 } 6330 } 6331 6332 @Override 6333 public ComponentName getCallingActivity(IBinder token) { 6334 synchronized (this) { 6335 ActivityRecord r = getCallingRecordLocked(token); 6336 return r != null ? r.intent.getComponent() : null; 6337 } 6338 } 6339 6340 private ActivityRecord getCallingRecordLocked(IBinder token) { 6341 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6342 if (r == null) { 6343 return null; 6344 } 6345 return r.resultTo; 6346 } 6347 6348 @Override 6349 public ComponentName getActivityClassForToken(IBinder token) { 6350 synchronized(this) { 6351 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6352 if (r == null) { 6353 return null; 6354 } 6355 return r.intent.getComponent(); 6356 } 6357 } 6358 6359 @Override 6360 public String getPackageForToken(IBinder token) { 6361 synchronized(this) { 6362 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6363 if (r == null) { 6364 return null; 6365 } 6366 return r.packageName; 6367 } 6368 } 6369 6370 @Override 6371 public IIntentSender getIntentSender(int type, 6372 String packageName, IBinder token, String resultWho, 6373 int requestCode, Intent[] intents, String[] resolvedTypes, 6374 int flags, Bundle options, int userId) { 6375 enforceNotIsolatedCaller("getIntentSender"); 6376 // Refuse possible leaked file descriptors 6377 if (intents != null) { 6378 if (intents.length < 1) { 6379 throw new IllegalArgumentException("Intents array length must be >= 1"); 6380 } 6381 for (int i=0; i<intents.length; i++) { 6382 Intent intent = intents[i]; 6383 if (intent != null) { 6384 if (intent.hasFileDescriptors()) { 6385 throw new IllegalArgumentException("File descriptors passed in Intent"); 6386 } 6387 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6388 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6389 throw new IllegalArgumentException( 6390 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6391 } 6392 intents[i] = new Intent(intent); 6393 } 6394 } 6395 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6396 throw new IllegalArgumentException( 6397 "Intent array length does not match resolvedTypes length"); 6398 } 6399 } 6400 if (options != null) { 6401 if (options.hasFileDescriptors()) { 6402 throw new IllegalArgumentException("File descriptors passed in options"); 6403 } 6404 } 6405 6406 synchronized(this) { 6407 int callingUid = Binder.getCallingUid(); 6408 int origUserId = userId; 6409 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6410 type == ActivityManager.INTENT_SENDER_BROADCAST, 6411 ALLOW_NON_FULL, "getIntentSender", null); 6412 if (origUserId == UserHandle.USER_CURRENT) { 6413 // We don't want to evaluate this until the pending intent is 6414 // actually executed. However, we do want to always do the 6415 // security checking for it above. 6416 userId = UserHandle.USER_CURRENT; 6417 } 6418 try { 6419 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6420 int uid = AppGlobals.getPackageManager() 6421 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6422 if (!UserHandle.isSameApp(callingUid, uid)) { 6423 String msg = "Permission Denial: getIntentSender() from pid=" 6424 + Binder.getCallingPid() 6425 + ", uid=" + Binder.getCallingUid() 6426 + ", (need uid=" + uid + ")" 6427 + " is not allowed to send as package " + packageName; 6428 Slog.w(TAG, msg); 6429 throw new SecurityException(msg); 6430 } 6431 } 6432 6433 return getIntentSenderLocked(type, packageName, callingUid, userId, 6434 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6435 6436 } catch (RemoteException e) { 6437 throw new SecurityException(e); 6438 } 6439 } 6440 } 6441 6442 IIntentSender getIntentSenderLocked(int type, String packageName, 6443 int callingUid, int userId, IBinder token, String resultWho, 6444 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6445 Bundle options) { 6446 if (DEBUG_MU) 6447 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6448 ActivityRecord activity = null; 6449 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6450 activity = ActivityRecord.isInStackLocked(token); 6451 if (activity == null) { 6452 return null; 6453 } 6454 if (activity.finishing) { 6455 return null; 6456 } 6457 } 6458 6459 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6460 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6461 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6462 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6463 |PendingIntent.FLAG_UPDATE_CURRENT); 6464 6465 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6466 type, packageName, activity, resultWho, 6467 requestCode, intents, resolvedTypes, flags, options, userId); 6468 WeakReference<PendingIntentRecord> ref; 6469 ref = mIntentSenderRecords.get(key); 6470 PendingIntentRecord rec = ref != null ? ref.get() : null; 6471 if (rec != null) { 6472 if (!cancelCurrent) { 6473 if (updateCurrent) { 6474 if (rec.key.requestIntent != null) { 6475 rec.key.requestIntent.replaceExtras(intents != null ? 6476 intents[intents.length - 1] : null); 6477 } 6478 if (intents != null) { 6479 intents[intents.length-1] = rec.key.requestIntent; 6480 rec.key.allIntents = intents; 6481 rec.key.allResolvedTypes = resolvedTypes; 6482 } else { 6483 rec.key.allIntents = null; 6484 rec.key.allResolvedTypes = null; 6485 } 6486 } 6487 return rec; 6488 } 6489 rec.canceled = true; 6490 mIntentSenderRecords.remove(key); 6491 } 6492 if (noCreate) { 6493 return rec; 6494 } 6495 rec = new PendingIntentRecord(this, key, callingUid); 6496 mIntentSenderRecords.put(key, rec.ref); 6497 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6498 if (activity.pendingResults == null) { 6499 activity.pendingResults 6500 = new HashSet<WeakReference<PendingIntentRecord>>(); 6501 } 6502 activity.pendingResults.add(rec.ref); 6503 } 6504 return rec; 6505 } 6506 6507 @Override 6508 public void cancelIntentSender(IIntentSender sender) { 6509 if (!(sender instanceof PendingIntentRecord)) { 6510 return; 6511 } 6512 synchronized(this) { 6513 PendingIntentRecord rec = (PendingIntentRecord)sender; 6514 try { 6515 int uid = AppGlobals.getPackageManager() 6516 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6517 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6518 String msg = "Permission Denial: cancelIntentSender() from pid=" 6519 + Binder.getCallingPid() 6520 + ", uid=" + Binder.getCallingUid() 6521 + " is not allowed to cancel packges " 6522 + rec.key.packageName; 6523 Slog.w(TAG, msg); 6524 throw new SecurityException(msg); 6525 } 6526 } catch (RemoteException e) { 6527 throw new SecurityException(e); 6528 } 6529 cancelIntentSenderLocked(rec, true); 6530 } 6531 } 6532 6533 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6534 rec.canceled = true; 6535 mIntentSenderRecords.remove(rec.key); 6536 if (cleanActivity && rec.key.activity != null) { 6537 rec.key.activity.pendingResults.remove(rec.ref); 6538 } 6539 } 6540 6541 @Override 6542 public String getPackageForIntentSender(IIntentSender pendingResult) { 6543 if (!(pendingResult instanceof PendingIntentRecord)) { 6544 return null; 6545 } 6546 try { 6547 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6548 return res.key.packageName; 6549 } catch (ClassCastException e) { 6550 } 6551 return null; 6552 } 6553 6554 @Override 6555 public int getUidForIntentSender(IIntentSender sender) { 6556 if (sender instanceof PendingIntentRecord) { 6557 try { 6558 PendingIntentRecord res = (PendingIntentRecord)sender; 6559 return res.uid; 6560 } catch (ClassCastException e) { 6561 } 6562 } 6563 return -1; 6564 } 6565 6566 @Override 6567 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6568 if (!(pendingResult instanceof PendingIntentRecord)) { 6569 return false; 6570 } 6571 try { 6572 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6573 if (res.key.allIntents == null) { 6574 return false; 6575 } 6576 for (int i=0; i<res.key.allIntents.length; i++) { 6577 Intent intent = res.key.allIntents[i]; 6578 if (intent.getPackage() != null && intent.getComponent() != null) { 6579 return false; 6580 } 6581 } 6582 return true; 6583 } catch (ClassCastException e) { 6584 } 6585 return false; 6586 } 6587 6588 @Override 6589 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6590 if (!(pendingResult instanceof PendingIntentRecord)) { 6591 return false; 6592 } 6593 try { 6594 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6595 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6596 return true; 6597 } 6598 return false; 6599 } catch (ClassCastException e) { 6600 } 6601 return false; 6602 } 6603 6604 @Override 6605 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6606 if (!(pendingResult instanceof PendingIntentRecord)) { 6607 return null; 6608 } 6609 try { 6610 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6611 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6612 } catch (ClassCastException e) { 6613 } 6614 return null; 6615 } 6616 6617 @Override 6618 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6619 if (!(pendingResult instanceof PendingIntentRecord)) { 6620 return null; 6621 } 6622 try { 6623 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6624 Intent intent = res.key.requestIntent; 6625 if (intent != null) { 6626 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6627 || res.lastTagPrefix.equals(prefix))) { 6628 return res.lastTag; 6629 } 6630 res.lastTagPrefix = prefix; 6631 StringBuilder sb = new StringBuilder(128); 6632 if (prefix != null) { 6633 sb.append(prefix); 6634 } 6635 if (intent.getAction() != null) { 6636 sb.append(intent.getAction()); 6637 } else if (intent.getComponent() != null) { 6638 intent.getComponent().appendShortString(sb); 6639 } else { 6640 sb.append("?"); 6641 } 6642 return res.lastTag = sb.toString(); 6643 } 6644 } catch (ClassCastException e) { 6645 } 6646 return null; 6647 } 6648 6649 @Override 6650 public void setProcessLimit(int max) { 6651 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6652 "setProcessLimit()"); 6653 synchronized (this) { 6654 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6655 mProcessLimitOverride = max; 6656 } 6657 trimApplications(); 6658 } 6659 6660 @Override 6661 public int getProcessLimit() { 6662 synchronized (this) { 6663 return mProcessLimitOverride; 6664 } 6665 } 6666 6667 void foregroundTokenDied(ForegroundToken token) { 6668 synchronized (ActivityManagerService.this) { 6669 synchronized (mPidsSelfLocked) { 6670 ForegroundToken cur 6671 = mForegroundProcesses.get(token.pid); 6672 if (cur != token) { 6673 return; 6674 } 6675 mForegroundProcesses.remove(token.pid); 6676 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6677 if (pr == null) { 6678 return; 6679 } 6680 pr.forcingToForeground = null; 6681 updateProcessForegroundLocked(pr, false, false); 6682 } 6683 updateOomAdjLocked(); 6684 } 6685 } 6686 6687 @Override 6688 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6689 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6690 "setProcessForeground()"); 6691 synchronized(this) { 6692 boolean changed = false; 6693 6694 synchronized (mPidsSelfLocked) { 6695 ProcessRecord pr = mPidsSelfLocked.get(pid); 6696 if (pr == null && isForeground) { 6697 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6698 return; 6699 } 6700 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6701 if (oldToken != null) { 6702 oldToken.token.unlinkToDeath(oldToken, 0); 6703 mForegroundProcesses.remove(pid); 6704 if (pr != null) { 6705 pr.forcingToForeground = null; 6706 } 6707 changed = true; 6708 } 6709 if (isForeground && token != null) { 6710 ForegroundToken newToken = new ForegroundToken() { 6711 @Override 6712 public void binderDied() { 6713 foregroundTokenDied(this); 6714 } 6715 }; 6716 newToken.pid = pid; 6717 newToken.token = token; 6718 try { 6719 token.linkToDeath(newToken, 0); 6720 mForegroundProcesses.put(pid, newToken); 6721 pr.forcingToForeground = token; 6722 changed = true; 6723 } catch (RemoteException e) { 6724 // If the process died while doing this, we will later 6725 // do the cleanup with the process death link. 6726 } 6727 } 6728 } 6729 6730 if (changed) { 6731 updateOomAdjLocked(); 6732 } 6733 } 6734 } 6735 6736 // ========================================================= 6737 // PERMISSIONS 6738 // ========================================================= 6739 6740 static class PermissionController extends IPermissionController.Stub { 6741 ActivityManagerService mActivityManagerService; 6742 PermissionController(ActivityManagerService activityManagerService) { 6743 mActivityManagerService = activityManagerService; 6744 } 6745 6746 @Override 6747 public boolean checkPermission(String permission, int pid, int uid) { 6748 return mActivityManagerService.checkPermission(permission, pid, 6749 uid) == PackageManager.PERMISSION_GRANTED; 6750 } 6751 } 6752 6753 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6754 @Override 6755 public int checkComponentPermission(String permission, int pid, int uid, 6756 int owningUid, boolean exported) { 6757 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6758 owningUid, exported); 6759 } 6760 6761 @Override 6762 public Object getAMSLock() { 6763 return ActivityManagerService.this; 6764 } 6765 } 6766 6767 /** 6768 * This can be called with or without the global lock held. 6769 */ 6770 int checkComponentPermission(String permission, int pid, int uid, 6771 int owningUid, boolean exported) { 6772 // We might be performing an operation on behalf of an indirect binder 6773 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6774 // client identity accordingly before proceeding. 6775 Identity tlsIdentity = sCallerIdentity.get(); 6776 if (tlsIdentity != null) { 6777 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6778 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6779 uid = tlsIdentity.uid; 6780 pid = tlsIdentity.pid; 6781 } 6782 6783 if (pid == MY_PID) { 6784 return PackageManager.PERMISSION_GRANTED; 6785 } 6786 6787 return ActivityManager.checkComponentPermission(permission, uid, 6788 owningUid, exported); 6789 } 6790 6791 /** 6792 * As the only public entry point for permissions checking, this method 6793 * can enforce the semantic that requesting a check on a null global 6794 * permission is automatically denied. (Internally a null permission 6795 * string is used when calling {@link #checkComponentPermission} in cases 6796 * when only uid-based security is needed.) 6797 * 6798 * This can be called with or without the global lock held. 6799 */ 6800 @Override 6801 public int checkPermission(String permission, int pid, int uid) { 6802 if (permission == null) { 6803 return PackageManager.PERMISSION_DENIED; 6804 } 6805 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6806 } 6807 6808 /** 6809 * Binder IPC calls go through the public entry point. 6810 * This can be called with or without the global lock held. 6811 */ 6812 int checkCallingPermission(String permission) { 6813 return checkPermission(permission, 6814 Binder.getCallingPid(), 6815 UserHandle.getAppId(Binder.getCallingUid())); 6816 } 6817 6818 /** 6819 * This can be called with or without the global lock held. 6820 */ 6821 void enforceCallingPermission(String permission, String func) { 6822 if (checkCallingPermission(permission) 6823 == PackageManager.PERMISSION_GRANTED) { 6824 return; 6825 } 6826 6827 String msg = "Permission Denial: " + func + " from pid=" 6828 + Binder.getCallingPid() 6829 + ", uid=" + Binder.getCallingUid() 6830 + " requires " + permission; 6831 Slog.w(TAG, msg); 6832 throw new SecurityException(msg); 6833 } 6834 6835 /** 6836 * Determine if UID is holding permissions required to access {@link Uri} in 6837 * the given {@link ProviderInfo}. Final permission checking is always done 6838 * in {@link ContentProvider}. 6839 */ 6840 private final boolean checkHoldingPermissionsLocked( 6841 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6842 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6843 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6844 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6845 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6846 != PERMISSION_GRANTED) { 6847 return false; 6848 } 6849 } 6850 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6851 } 6852 6853 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6854 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6855 if (pi.applicationInfo.uid == uid) { 6856 return true; 6857 } else if (!pi.exported) { 6858 return false; 6859 } 6860 6861 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6862 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6863 try { 6864 // check if target holds top-level <provider> permissions 6865 if (!readMet && pi.readPermission != null && considerUidPermissions 6866 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6867 readMet = true; 6868 } 6869 if (!writeMet && pi.writePermission != null && considerUidPermissions 6870 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6871 writeMet = true; 6872 } 6873 6874 // track if unprotected read/write is allowed; any denied 6875 // <path-permission> below removes this ability 6876 boolean allowDefaultRead = pi.readPermission == null; 6877 boolean allowDefaultWrite = pi.writePermission == null; 6878 6879 // check if target holds any <path-permission> that match uri 6880 final PathPermission[] pps = pi.pathPermissions; 6881 if (pps != null) { 6882 final String path = grantUri.uri.getPath(); 6883 int i = pps.length; 6884 while (i > 0 && (!readMet || !writeMet)) { 6885 i--; 6886 PathPermission pp = pps[i]; 6887 if (pp.match(path)) { 6888 if (!readMet) { 6889 final String pprperm = pp.getReadPermission(); 6890 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6891 + pprperm + " for " + pp.getPath() 6892 + ": match=" + pp.match(path) 6893 + " check=" + pm.checkUidPermission(pprperm, uid)); 6894 if (pprperm != null) { 6895 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6896 == PERMISSION_GRANTED) { 6897 readMet = true; 6898 } else { 6899 allowDefaultRead = false; 6900 } 6901 } 6902 } 6903 if (!writeMet) { 6904 final String ppwperm = pp.getWritePermission(); 6905 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6906 + ppwperm + " for " + pp.getPath() 6907 + ": match=" + pp.match(path) 6908 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6909 if (ppwperm != null) { 6910 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6911 == PERMISSION_GRANTED) { 6912 writeMet = true; 6913 } else { 6914 allowDefaultWrite = false; 6915 } 6916 } 6917 } 6918 } 6919 } 6920 } 6921 6922 // grant unprotected <provider> read/write, if not blocked by 6923 // <path-permission> above 6924 if (allowDefaultRead) readMet = true; 6925 if (allowDefaultWrite) writeMet = true; 6926 6927 } catch (RemoteException e) { 6928 return false; 6929 } 6930 6931 return readMet && writeMet; 6932 } 6933 6934 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6935 ProviderInfo pi = null; 6936 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6937 if (cpr != null) { 6938 pi = cpr.info; 6939 } else { 6940 try { 6941 pi = AppGlobals.getPackageManager().resolveContentProvider( 6942 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6943 } catch (RemoteException ex) { 6944 } 6945 } 6946 return pi; 6947 } 6948 6949 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6950 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6951 if (targetUris != null) { 6952 return targetUris.get(grantUri); 6953 } 6954 return null; 6955 } 6956 6957 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6958 String targetPkg, int targetUid, GrantUri grantUri) { 6959 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6960 if (targetUris == null) { 6961 targetUris = Maps.newArrayMap(); 6962 mGrantedUriPermissions.put(targetUid, targetUris); 6963 } 6964 6965 UriPermission perm = targetUris.get(grantUri); 6966 if (perm == null) { 6967 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6968 targetUris.put(grantUri, perm); 6969 } 6970 6971 return perm; 6972 } 6973 6974 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6975 final int modeFlags) { 6976 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6977 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6978 : UriPermission.STRENGTH_OWNED; 6979 6980 // Root gets to do everything. 6981 if (uid == 0) { 6982 return true; 6983 } 6984 6985 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6986 if (perms == null) return false; 6987 6988 // First look for exact match 6989 final UriPermission exactPerm = perms.get(grantUri); 6990 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6991 return true; 6992 } 6993 6994 // No exact match, look for prefixes 6995 final int N = perms.size(); 6996 for (int i = 0; i < N; i++) { 6997 final UriPermission perm = perms.valueAt(i); 6998 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6999 && perm.getStrength(modeFlags) >= minStrength) { 7000 return true; 7001 } 7002 } 7003 7004 return false; 7005 } 7006 7007 /** 7008 * @param uri This uri must NOT contain an embedded userId. 7009 * @param userId The userId in which the uri is to be resolved. 7010 */ 7011 @Override 7012 public int checkUriPermission(Uri uri, int pid, int uid, 7013 final int modeFlags, int userId) { 7014 enforceNotIsolatedCaller("checkUriPermission"); 7015 7016 // Another redirected-binder-call permissions check as in 7017 // {@link checkComponentPermission}. 7018 Identity tlsIdentity = sCallerIdentity.get(); 7019 if (tlsIdentity != null) { 7020 uid = tlsIdentity.uid; 7021 pid = tlsIdentity.pid; 7022 } 7023 7024 // Our own process gets to do everything. 7025 if (pid == MY_PID) { 7026 return PackageManager.PERMISSION_GRANTED; 7027 } 7028 synchronized (this) { 7029 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7030 ? PackageManager.PERMISSION_GRANTED 7031 : PackageManager.PERMISSION_DENIED; 7032 } 7033 } 7034 7035 /** 7036 * Check if the targetPkg can be granted permission to access uri by 7037 * the callingUid using the given modeFlags. Throws a security exception 7038 * if callingUid is not allowed to do this. Returns the uid of the target 7039 * if the URI permission grant should be performed; returns -1 if it is not 7040 * needed (for example targetPkg already has permission to access the URI). 7041 * If you already know the uid of the target, you can supply it in 7042 * lastTargetUid else set that to -1. 7043 */ 7044 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7045 final int modeFlags, int lastTargetUid) { 7046 if (!Intent.isAccessUriMode(modeFlags)) { 7047 return -1; 7048 } 7049 7050 if (targetPkg != null) { 7051 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7052 "Checking grant " + targetPkg + " permission to " + grantUri); 7053 } 7054 7055 final IPackageManager pm = AppGlobals.getPackageManager(); 7056 7057 // If this is not a content: uri, we can't do anything with it. 7058 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7059 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7060 "Can't grant URI permission for non-content URI: " + grantUri); 7061 return -1; 7062 } 7063 7064 final String authority = grantUri.uri.getAuthority(); 7065 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7066 if (pi == null) { 7067 Slog.w(TAG, "No content provider found for permission check: " + 7068 grantUri.uri.toSafeString()); 7069 return -1; 7070 } 7071 7072 int targetUid = lastTargetUid; 7073 if (targetUid < 0 && targetPkg != null) { 7074 try { 7075 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7076 if (targetUid < 0) { 7077 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7078 "Can't grant URI permission no uid for: " + targetPkg); 7079 return -1; 7080 } 7081 } catch (RemoteException ex) { 7082 return -1; 7083 } 7084 } 7085 7086 if (targetUid >= 0) { 7087 // First... does the target actually need this permission? 7088 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7089 // No need to grant the target this permission. 7090 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7091 "Target " + targetPkg + " already has full permission to " + grantUri); 7092 return -1; 7093 } 7094 } else { 7095 // First... there is no target package, so can anyone access it? 7096 boolean allowed = pi.exported; 7097 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7098 if (pi.readPermission != null) { 7099 allowed = false; 7100 } 7101 } 7102 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7103 if (pi.writePermission != null) { 7104 allowed = false; 7105 } 7106 } 7107 if (allowed) { 7108 return -1; 7109 } 7110 } 7111 7112 /* There is a special cross user grant if: 7113 * - The target is on another user. 7114 * - Apps on the current user can access the uri without any uid permissions. 7115 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7116 * grant uri permissions. 7117 */ 7118 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7119 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7120 modeFlags, false /*without considering the uid permissions*/); 7121 7122 // Second... is the provider allowing granting of URI permissions? 7123 if (!specialCrossUserGrant) { 7124 if (!pi.grantUriPermissions) { 7125 throw new SecurityException("Provider " + pi.packageName 7126 + "/" + pi.name 7127 + " does not allow granting of Uri permissions (uri " 7128 + grantUri + ")"); 7129 } 7130 if (pi.uriPermissionPatterns != null) { 7131 final int N = pi.uriPermissionPatterns.length; 7132 boolean allowed = false; 7133 for (int i=0; i<N; i++) { 7134 if (pi.uriPermissionPatterns[i] != null 7135 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7136 allowed = true; 7137 break; 7138 } 7139 } 7140 if (!allowed) { 7141 throw new SecurityException("Provider " + pi.packageName 7142 + "/" + pi.name 7143 + " does not allow granting of permission to path of Uri " 7144 + grantUri); 7145 } 7146 } 7147 } 7148 7149 // Third... does the caller itself have permission to access 7150 // this uri? 7151 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7152 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7153 // Require they hold a strong enough Uri permission 7154 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7155 throw new SecurityException("Uid " + callingUid 7156 + " does not have permission to uri " + grantUri); 7157 } 7158 } 7159 } 7160 return targetUid; 7161 } 7162 7163 /** 7164 * @param uri This uri must NOT contain an embedded userId. 7165 * @param userId The userId in which the uri is to be resolved. 7166 */ 7167 @Override 7168 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7169 final int modeFlags, int userId) { 7170 enforceNotIsolatedCaller("checkGrantUriPermission"); 7171 synchronized(this) { 7172 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7173 new GrantUri(userId, uri, false), modeFlags, -1); 7174 } 7175 } 7176 7177 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7178 final int modeFlags, UriPermissionOwner owner) { 7179 if (!Intent.isAccessUriMode(modeFlags)) { 7180 return; 7181 } 7182 7183 // So here we are: the caller has the assumed permission 7184 // to the uri, and the target doesn't. Let's now give this to 7185 // the target. 7186 7187 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7188 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7189 7190 final String authority = grantUri.uri.getAuthority(); 7191 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7192 if (pi == null) { 7193 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7194 return; 7195 } 7196 7197 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7198 grantUri.prefix = true; 7199 } 7200 final UriPermission perm = findOrCreateUriPermissionLocked( 7201 pi.packageName, targetPkg, targetUid, grantUri); 7202 perm.grantModes(modeFlags, owner); 7203 } 7204 7205 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7206 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7207 if (targetPkg == null) { 7208 throw new NullPointerException("targetPkg"); 7209 } 7210 int targetUid; 7211 final IPackageManager pm = AppGlobals.getPackageManager(); 7212 try { 7213 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7214 } catch (RemoteException ex) { 7215 return; 7216 } 7217 7218 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7219 targetUid); 7220 if (targetUid < 0) { 7221 return; 7222 } 7223 7224 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7225 owner); 7226 } 7227 7228 static class NeededUriGrants extends ArrayList<GrantUri> { 7229 final String targetPkg; 7230 final int targetUid; 7231 final int flags; 7232 7233 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7234 this.targetPkg = targetPkg; 7235 this.targetUid = targetUid; 7236 this.flags = flags; 7237 } 7238 } 7239 7240 /** 7241 * Like checkGrantUriPermissionLocked, but takes an Intent. 7242 */ 7243 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7244 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7245 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7246 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7247 + " clip=" + (intent != null ? intent.getClipData() : null) 7248 + " from " + intent + "; flags=0x" 7249 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7250 7251 if (targetPkg == null) { 7252 throw new NullPointerException("targetPkg"); 7253 } 7254 7255 if (intent == null) { 7256 return null; 7257 } 7258 Uri data = intent.getData(); 7259 ClipData clip = intent.getClipData(); 7260 if (data == null && clip == null) { 7261 return null; 7262 } 7263 // Default userId for uris in the intent (if they don't specify it themselves) 7264 int contentUserHint = intent.getContentUserHint(); 7265 if (contentUserHint == UserHandle.USER_CURRENT) { 7266 contentUserHint = UserHandle.getUserId(callingUid); 7267 } 7268 final IPackageManager pm = AppGlobals.getPackageManager(); 7269 int targetUid; 7270 if (needed != null) { 7271 targetUid = needed.targetUid; 7272 } else { 7273 try { 7274 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7275 } catch (RemoteException ex) { 7276 return null; 7277 } 7278 if (targetUid < 0) { 7279 if (DEBUG_URI_PERMISSION) { 7280 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7281 + " on user " + targetUserId); 7282 } 7283 return null; 7284 } 7285 } 7286 if (data != null) { 7287 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7288 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7289 targetUid); 7290 if (targetUid > 0) { 7291 if (needed == null) { 7292 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7293 } 7294 needed.add(grantUri); 7295 } 7296 } 7297 if (clip != null) { 7298 for (int i=0; i<clip.getItemCount(); i++) { 7299 Uri uri = clip.getItemAt(i).getUri(); 7300 if (uri != null) { 7301 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7302 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7303 targetUid); 7304 if (targetUid > 0) { 7305 if (needed == null) { 7306 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7307 } 7308 needed.add(grantUri); 7309 } 7310 } else { 7311 Intent clipIntent = clip.getItemAt(i).getIntent(); 7312 if (clipIntent != null) { 7313 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7314 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7315 if (newNeeded != null) { 7316 needed = newNeeded; 7317 } 7318 } 7319 } 7320 } 7321 } 7322 7323 return needed; 7324 } 7325 7326 /** 7327 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7328 */ 7329 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7330 UriPermissionOwner owner) { 7331 if (needed != null) { 7332 for (int i=0; i<needed.size(); i++) { 7333 GrantUri grantUri = needed.get(i); 7334 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7335 grantUri, needed.flags, owner); 7336 } 7337 } 7338 } 7339 7340 void grantUriPermissionFromIntentLocked(int callingUid, 7341 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7342 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7343 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7344 if (needed == null) { 7345 return; 7346 } 7347 7348 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7349 } 7350 7351 /** 7352 * @param uri This uri must NOT contain an embedded userId. 7353 * @param userId The userId in which the uri is to be resolved. 7354 */ 7355 @Override 7356 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7357 final int modeFlags, int userId) { 7358 enforceNotIsolatedCaller("grantUriPermission"); 7359 GrantUri grantUri = new GrantUri(userId, uri, false); 7360 synchronized(this) { 7361 final ProcessRecord r = getRecordForAppLocked(caller); 7362 if (r == null) { 7363 throw new SecurityException("Unable to find app for caller " 7364 + caller 7365 + " when granting permission to uri " + grantUri); 7366 } 7367 if (targetPkg == null) { 7368 throw new IllegalArgumentException("null target"); 7369 } 7370 if (grantUri == null) { 7371 throw new IllegalArgumentException("null uri"); 7372 } 7373 7374 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7375 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7376 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7377 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7378 7379 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7380 UserHandle.getUserId(r.uid)); 7381 } 7382 } 7383 7384 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7385 if (perm.modeFlags == 0) { 7386 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7387 perm.targetUid); 7388 if (perms != null) { 7389 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7390 "Removing " + perm.targetUid + " permission to " + perm.uri); 7391 7392 perms.remove(perm.uri); 7393 if (perms.isEmpty()) { 7394 mGrantedUriPermissions.remove(perm.targetUid); 7395 } 7396 } 7397 } 7398 } 7399 7400 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7401 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7402 7403 final IPackageManager pm = AppGlobals.getPackageManager(); 7404 final String authority = grantUri.uri.getAuthority(); 7405 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7406 if (pi == null) { 7407 Slog.w(TAG, "No content provider found for permission revoke: " 7408 + grantUri.toSafeString()); 7409 return; 7410 } 7411 7412 // Does the caller have this permission on the URI? 7413 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7414 // Right now, if you are not the original owner of the permission, 7415 // you are not allowed to revoke it. 7416 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7417 throw new SecurityException("Uid " + callingUid 7418 + " does not have permission to uri " + grantUri); 7419 //} 7420 } 7421 7422 boolean persistChanged = false; 7423 7424 // Go through all of the permissions and remove any that match. 7425 int N = mGrantedUriPermissions.size(); 7426 for (int i = 0; i < N; i++) { 7427 final int targetUid = mGrantedUriPermissions.keyAt(i); 7428 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7429 7430 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7431 final UriPermission perm = it.next(); 7432 if (perm.uri.sourceUserId == grantUri.sourceUserId 7433 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7434 if (DEBUG_URI_PERMISSION) 7435 Slog.v(TAG, 7436 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7437 persistChanged |= perm.revokeModes( 7438 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7439 if (perm.modeFlags == 0) { 7440 it.remove(); 7441 } 7442 } 7443 } 7444 7445 if (perms.isEmpty()) { 7446 mGrantedUriPermissions.remove(targetUid); 7447 N--; 7448 i--; 7449 } 7450 } 7451 7452 if (persistChanged) { 7453 schedulePersistUriGrants(); 7454 } 7455 } 7456 7457 /** 7458 * @param uri This uri must NOT contain an embedded userId. 7459 * @param userId The userId in which the uri is to be resolved. 7460 */ 7461 @Override 7462 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7463 int userId) { 7464 enforceNotIsolatedCaller("revokeUriPermission"); 7465 synchronized(this) { 7466 final ProcessRecord r = getRecordForAppLocked(caller); 7467 if (r == null) { 7468 throw new SecurityException("Unable to find app for caller " 7469 + caller 7470 + " when revoking permission to uri " + uri); 7471 } 7472 if (uri == null) { 7473 Slog.w(TAG, "revokeUriPermission: null uri"); 7474 return; 7475 } 7476 7477 if (!Intent.isAccessUriMode(modeFlags)) { 7478 return; 7479 } 7480 7481 final IPackageManager pm = AppGlobals.getPackageManager(); 7482 final String authority = uri.getAuthority(); 7483 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7484 if (pi == null) { 7485 Slog.w(TAG, "No content provider found for permission revoke: " 7486 + uri.toSafeString()); 7487 return; 7488 } 7489 7490 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7491 } 7492 } 7493 7494 /** 7495 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7496 * given package. 7497 * 7498 * @param packageName Package name to match, or {@code null} to apply to all 7499 * packages. 7500 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7501 * to all users. 7502 * @param persistable If persistable grants should be removed. 7503 */ 7504 private void removeUriPermissionsForPackageLocked( 7505 String packageName, int userHandle, boolean persistable) { 7506 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7507 throw new IllegalArgumentException("Must narrow by either package or user"); 7508 } 7509 7510 boolean persistChanged = false; 7511 7512 int N = mGrantedUriPermissions.size(); 7513 for (int i = 0; i < N; i++) { 7514 final int targetUid = mGrantedUriPermissions.keyAt(i); 7515 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7516 7517 // Only inspect grants matching user 7518 if (userHandle == UserHandle.USER_ALL 7519 || userHandle == UserHandle.getUserId(targetUid)) { 7520 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7521 final UriPermission perm = it.next(); 7522 7523 // Only inspect grants matching package 7524 if (packageName == null || perm.sourcePkg.equals(packageName) 7525 || perm.targetPkg.equals(packageName)) { 7526 persistChanged |= perm.revokeModes( 7527 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7528 7529 // Only remove when no modes remain; any persisted grants 7530 // will keep this alive. 7531 if (perm.modeFlags == 0) { 7532 it.remove(); 7533 } 7534 } 7535 } 7536 7537 if (perms.isEmpty()) { 7538 mGrantedUriPermissions.remove(targetUid); 7539 N--; 7540 i--; 7541 } 7542 } 7543 } 7544 7545 if (persistChanged) { 7546 schedulePersistUriGrants(); 7547 } 7548 } 7549 7550 @Override 7551 public IBinder newUriPermissionOwner(String name) { 7552 enforceNotIsolatedCaller("newUriPermissionOwner"); 7553 synchronized(this) { 7554 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7555 return owner.getExternalTokenLocked(); 7556 } 7557 } 7558 7559 /** 7560 * @param uri This uri must NOT contain an embedded userId. 7561 * @param sourceUserId The userId in which the uri is to be resolved. 7562 * @param targetUserId The userId of the app that receives the grant. 7563 */ 7564 @Override 7565 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7566 final int modeFlags, int sourceUserId, int targetUserId) { 7567 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7568 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7569 synchronized(this) { 7570 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7571 if (owner == null) { 7572 throw new IllegalArgumentException("Unknown owner: " + token); 7573 } 7574 if (fromUid != Binder.getCallingUid()) { 7575 if (Binder.getCallingUid() != Process.myUid()) { 7576 // Only system code can grant URI permissions on behalf 7577 // of other users. 7578 throw new SecurityException("nice try"); 7579 } 7580 } 7581 if (targetPkg == null) { 7582 throw new IllegalArgumentException("null target"); 7583 } 7584 if (uri == null) { 7585 throw new IllegalArgumentException("null uri"); 7586 } 7587 7588 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7589 modeFlags, owner, targetUserId); 7590 } 7591 } 7592 7593 /** 7594 * @param uri This uri must NOT contain an embedded userId. 7595 * @param userId The userId in which the uri is to be resolved. 7596 */ 7597 @Override 7598 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7599 synchronized(this) { 7600 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7601 if (owner == null) { 7602 throw new IllegalArgumentException("Unknown owner: " + token); 7603 } 7604 7605 if (uri == null) { 7606 owner.removeUriPermissionsLocked(mode); 7607 } else { 7608 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7609 } 7610 } 7611 } 7612 7613 private void schedulePersistUriGrants() { 7614 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7615 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7616 10 * DateUtils.SECOND_IN_MILLIS); 7617 } 7618 } 7619 7620 private void writeGrantedUriPermissions() { 7621 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7622 7623 // Snapshot permissions so we can persist without lock 7624 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7625 synchronized (this) { 7626 final int size = mGrantedUriPermissions.size(); 7627 for (int i = 0; i < size; i++) { 7628 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7629 for (UriPermission perm : perms.values()) { 7630 if (perm.persistedModeFlags != 0) { 7631 persist.add(perm.snapshot()); 7632 } 7633 } 7634 } 7635 } 7636 7637 FileOutputStream fos = null; 7638 try { 7639 fos = mGrantFile.startWrite(); 7640 7641 XmlSerializer out = new FastXmlSerializer(); 7642 out.setOutput(fos, "utf-8"); 7643 out.startDocument(null, true); 7644 out.startTag(null, TAG_URI_GRANTS); 7645 for (UriPermission.Snapshot perm : persist) { 7646 out.startTag(null, TAG_URI_GRANT); 7647 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7648 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7649 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7650 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7651 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7652 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7653 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7654 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7655 out.endTag(null, TAG_URI_GRANT); 7656 } 7657 out.endTag(null, TAG_URI_GRANTS); 7658 out.endDocument(); 7659 7660 mGrantFile.finishWrite(fos); 7661 } catch (IOException e) { 7662 if (fos != null) { 7663 mGrantFile.failWrite(fos); 7664 } 7665 } 7666 } 7667 7668 private void readGrantedUriPermissionsLocked() { 7669 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7670 7671 final long now = System.currentTimeMillis(); 7672 7673 FileInputStream fis = null; 7674 try { 7675 fis = mGrantFile.openRead(); 7676 final XmlPullParser in = Xml.newPullParser(); 7677 in.setInput(fis, null); 7678 7679 int type; 7680 while ((type = in.next()) != END_DOCUMENT) { 7681 final String tag = in.getName(); 7682 if (type == START_TAG) { 7683 if (TAG_URI_GRANT.equals(tag)) { 7684 final int sourceUserId; 7685 final int targetUserId; 7686 final int userHandle = readIntAttribute(in, 7687 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7688 if (userHandle != UserHandle.USER_NULL) { 7689 // For backwards compatibility. 7690 sourceUserId = userHandle; 7691 targetUserId = userHandle; 7692 } else { 7693 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7694 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7695 } 7696 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7697 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7698 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7699 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7700 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7701 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7702 7703 // Sanity check that provider still belongs to source package 7704 final ProviderInfo pi = getProviderInfoLocked( 7705 uri.getAuthority(), sourceUserId); 7706 if (pi != null && sourcePkg.equals(pi.packageName)) { 7707 int targetUid = -1; 7708 try { 7709 targetUid = AppGlobals.getPackageManager() 7710 .getPackageUid(targetPkg, targetUserId); 7711 } catch (RemoteException e) { 7712 } 7713 if (targetUid != -1) { 7714 final UriPermission perm = findOrCreateUriPermissionLocked( 7715 sourcePkg, targetPkg, targetUid, 7716 new GrantUri(sourceUserId, uri, prefix)); 7717 perm.initPersistedModes(modeFlags, createdTime); 7718 } 7719 } else { 7720 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7721 + " but instead found " + pi); 7722 } 7723 } 7724 } 7725 } 7726 } catch (FileNotFoundException e) { 7727 // Missing grants is okay 7728 } catch (IOException e) { 7729 Log.wtf(TAG, "Failed reading Uri grants", e); 7730 } catch (XmlPullParserException e) { 7731 Log.wtf(TAG, "Failed reading Uri grants", e); 7732 } finally { 7733 IoUtils.closeQuietly(fis); 7734 } 7735 } 7736 7737 /** 7738 * @param uri This uri must NOT contain an embedded userId. 7739 * @param userId The userId in which the uri is to be resolved. 7740 */ 7741 @Override 7742 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7743 enforceNotIsolatedCaller("takePersistableUriPermission"); 7744 7745 Preconditions.checkFlagsArgument(modeFlags, 7746 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7747 7748 synchronized (this) { 7749 final int callingUid = Binder.getCallingUid(); 7750 boolean persistChanged = false; 7751 GrantUri grantUri = new GrantUri(userId, uri, false); 7752 7753 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7754 new GrantUri(userId, uri, false)); 7755 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7756 new GrantUri(userId, uri, true)); 7757 7758 final boolean exactValid = (exactPerm != null) 7759 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7760 final boolean prefixValid = (prefixPerm != null) 7761 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7762 7763 if (!(exactValid || prefixValid)) { 7764 throw new SecurityException("No persistable permission grants found for UID " 7765 + callingUid + " and Uri " + grantUri.toSafeString()); 7766 } 7767 7768 if (exactValid) { 7769 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7770 } 7771 if (prefixValid) { 7772 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7773 } 7774 7775 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7776 7777 if (persistChanged) { 7778 schedulePersistUriGrants(); 7779 } 7780 } 7781 } 7782 7783 /** 7784 * @param uri This uri must NOT contain an embedded userId. 7785 * @param userId The userId in which the uri is to be resolved. 7786 */ 7787 @Override 7788 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7789 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7790 7791 Preconditions.checkFlagsArgument(modeFlags, 7792 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7793 7794 synchronized (this) { 7795 final int callingUid = Binder.getCallingUid(); 7796 boolean persistChanged = false; 7797 7798 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7799 new GrantUri(userId, uri, false)); 7800 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7801 new GrantUri(userId, uri, true)); 7802 if (exactPerm == null && prefixPerm == null) { 7803 throw new SecurityException("No permission grants found for UID " + callingUid 7804 + " and Uri " + uri.toSafeString()); 7805 } 7806 7807 if (exactPerm != null) { 7808 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7809 removeUriPermissionIfNeededLocked(exactPerm); 7810 } 7811 if (prefixPerm != null) { 7812 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7813 removeUriPermissionIfNeededLocked(prefixPerm); 7814 } 7815 7816 if (persistChanged) { 7817 schedulePersistUriGrants(); 7818 } 7819 } 7820 } 7821 7822 /** 7823 * Prune any older {@link UriPermission} for the given UID until outstanding 7824 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7825 * 7826 * @return if any mutations occured that require persisting. 7827 */ 7828 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7829 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7830 if (perms == null) return false; 7831 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7832 7833 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7834 for (UriPermission perm : perms.values()) { 7835 if (perm.persistedModeFlags != 0) { 7836 persisted.add(perm); 7837 } 7838 } 7839 7840 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7841 if (trimCount <= 0) return false; 7842 7843 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7844 for (int i = 0; i < trimCount; i++) { 7845 final UriPermission perm = persisted.get(i); 7846 7847 if (DEBUG_URI_PERMISSION) { 7848 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7849 } 7850 7851 perm.releasePersistableModes(~0); 7852 removeUriPermissionIfNeededLocked(perm); 7853 } 7854 7855 return true; 7856 } 7857 7858 @Override 7859 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7860 String packageName, boolean incoming) { 7861 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7862 Preconditions.checkNotNull(packageName, "packageName"); 7863 7864 final int callingUid = Binder.getCallingUid(); 7865 final IPackageManager pm = AppGlobals.getPackageManager(); 7866 try { 7867 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7868 if (packageUid != callingUid) { 7869 throw new SecurityException( 7870 "Package " + packageName + " does not belong to calling UID " + callingUid); 7871 } 7872 } catch (RemoteException e) { 7873 throw new SecurityException("Failed to verify package name ownership"); 7874 } 7875 7876 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7877 synchronized (this) { 7878 if (incoming) { 7879 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7880 callingUid); 7881 if (perms == null) { 7882 Slog.w(TAG, "No permission grants found for " + packageName); 7883 } else { 7884 for (UriPermission perm : perms.values()) { 7885 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7886 result.add(perm.buildPersistedPublicApiObject()); 7887 } 7888 } 7889 } 7890 } else { 7891 final int size = mGrantedUriPermissions.size(); 7892 for (int i = 0; i < size; i++) { 7893 final ArrayMap<GrantUri, UriPermission> perms = 7894 mGrantedUriPermissions.valueAt(i); 7895 for (UriPermission perm : perms.values()) { 7896 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7897 result.add(perm.buildPersistedPublicApiObject()); 7898 } 7899 } 7900 } 7901 } 7902 } 7903 return new ParceledListSlice<android.content.UriPermission>(result); 7904 } 7905 7906 @Override 7907 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7908 synchronized (this) { 7909 ProcessRecord app = 7910 who != null ? getRecordForAppLocked(who) : null; 7911 if (app == null) return; 7912 7913 Message msg = Message.obtain(); 7914 msg.what = WAIT_FOR_DEBUGGER_MSG; 7915 msg.obj = app; 7916 msg.arg1 = waiting ? 1 : 0; 7917 mHandler.sendMessage(msg); 7918 } 7919 } 7920 7921 @Override 7922 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7923 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7924 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7925 outInfo.availMem = Process.getFreeMemory(); 7926 outInfo.totalMem = Process.getTotalMemory(); 7927 outInfo.threshold = homeAppMem; 7928 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7929 outInfo.hiddenAppThreshold = cachedAppMem; 7930 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7931 ProcessList.SERVICE_ADJ); 7932 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7933 ProcessList.VISIBLE_APP_ADJ); 7934 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7935 ProcessList.FOREGROUND_APP_ADJ); 7936 } 7937 7938 // ========================================================= 7939 // TASK MANAGEMENT 7940 // ========================================================= 7941 7942 @Override 7943 public List<IAppTask> getAppTasks(String callingPackage) { 7944 int callingUid = Binder.getCallingUid(); 7945 long ident = Binder.clearCallingIdentity(); 7946 7947 synchronized(this) { 7948 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7949 try { 7950 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7951 7952 final int N = mRecentTasks.size(); 7953 for (int i = 0; i < N; i++) { 7954 TaskRecord tr = mRecentTasks.get(i); 7955 // Skip tasks that do not match the caller. We don't need to verify 7956 // callingPackage, because we are also limiting to callingUid and know 7957 // that will limit to the correct security sandbox. 7958 if (tr.effectiveUid != callingUid) { 7959 continue; 7960 } 7961 Intent intent = tr.getBaseIntent(); 7962 if (intent == null || 7963 !callingPackage.equals(intent.getComponent().getPackageName())) { 7964 continue; 7965 } 7966 ActivityManager.RecentTaskInfo taskInfo = 7967 createRecentTaskInfoFromTaskRecord(tr); 7968 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7969 list.add(taskImpl); 7970 } 7971 } finally { 7972 Binder.restoreCallingIdentity(ident); 7973 } 7974 return list; 7975 } 7976 } 7977 7978 @Override 7979 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7980 final int callingUid = Binder.getCallingUid(); 7981 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7982 7983 synchronized(this) { 7984 if (localLOGV) Slog.v( 7985 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7986 7987 final boolean allowed = checkCallingPermission( 7988 android.Manifest.permission.GET_TASKS) 7989 == PackageManager.PERMISSION_GRANTED; 7990 if (!allowed) { 7991 Slog.w(TAG, "getTasks: caller " + callingUid 7992 + " does not hold GET_TASKS; limiting output"); 7993 } 7994 7995 // TODO: Improve with MRU list from all ActivityStacks. 7996 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7997 } 7998 7999 return list; 8000 } 8001 8002 TaskRecord getMostRecentTask() { 8003 return mRecentTasks.get(0); 8004 } 8005 8006 /** 8007 * Creates a new RecentTaskInfo from a TaskRecord. 8008 */ 8009 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8010 // Update the task description to reflect any changes in the task stack 8011 tr.updateTaskDescription(); 8012 8013 // Compose the recent task info 8014 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8015 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8016 rti.persistentId = tr.taskId; 8017 rti.baseIntent = new Intent(tr.getBaseIntent()); 8018 rti.origActivity = tr.origActivity; 8019 rti.description = tr.lastDescription; 8020 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8021 rti.userId = tr.userId; 8022 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8023 rti.firstActiveTime = tr.firstActiveTime; 8024 rti.lastActiveTime = tr.lastActiveTime; 8025 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8026 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8027 return rti; 8028 } 8029 8030 @Override 8031 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8032 final int callingUid = Binder.getCallingUid(); 8033 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8034 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8035 8036 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8037 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8038 synchronized (this) { 8039 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8040 == PackageManager.PERMISSION_GRANTED; 8041 if (!allowed) { 8042 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8043 + " does not hold GET_TASKS; limiting output"); 8044 } 8045 final boolean detailed = checkCallingPermission( 8046 android.Manifest.permission.GET_DETAILED_TASKS) 8047 == PackageManager.PERMISSION_GRANTED; 8048 8049 final int N = mRecentTasks.size(); 8050 ArrayList<ActivityManager.RecentTaskInfo> res 8051 = new ArrayList<ActivityManager.RecentTaskInfo>( 8052 maxNum < N ? maxNum : N); 8053 8054 final Set<Integer> includedUsers; 8055 if (includeProfiles) { 8056 includedUsers = getProfileIdsLocked(userId); 8057 } else { 8058 includedUsers = new HashSet<Integer>(); 8059 } 8060 includedUsers.add(Integer.valueOf(userId)); 8061 8062 for (int i=0; i<N && maxNum > 0; i++) { 8063 TaskRecord tr = mRecentTasks.get(i); 8064 // Only add calling user or related users recent tasks 8065 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8066 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8067 continue; 8068 } 8069 8070 // Return the entry if desired by the caller. We always return 8071 // the first entry, because callers always expect this to be the 8072 // foreground app. We may filter others if the caller has 8073 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8074 // we should exclude the entry. 8075 8076 if (i == 0 8077 || withExcluded 8078 || (tr.intent == null) 8079 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8080 == 0)) { 8081 if (!allowed) { 8082 // If the caller doesn't have the GET_TASKS permission, then only 8083 // allow them to see a small subset of tasks -- their own and home. 8084 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8085 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8086 continue; 8087 } 8088 } 8089 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8090 if (tr.stack != null && tr.stack.isHomeStack()) { 8091 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8092 continue; 8093 } 8094 } 8095 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8096 // Don't include auto remove tasks that are finished or finishing. 8097 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8098 + tr); 8099 continue; 8100 } 8101 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8102 && !tr.isAvailable) { 8103 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8104 continue; 8105 } 8106 8107 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8108 if (!detailed) { 8109 rti.baseIntent.replaceExtras((Bundle)null); 8110 } 8111 8112 res.add(rti); 8113 maxNum--; 8114 } 8115 } 8116 return res; 8117 } 8118 } 8119 8120 private TaskRecord recentTaskForIdLocked(int id) { 8121 final int N = mRecentTasks.size(); 8122 for (int i=0; i<N; i++) { 8123 TaskRecord tr = mRecentTasks.get(i); 8124 if (tr.taskId == id) { 8125 return tr; 8126 } 8127 } 8128 return null; 8129 } 8130 8131 @Override 8132 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8133 synchronized (this) { 8134 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8135 "getTaskThumbnail()"); 8136 TaskRecord tr = recentTaskForIdLocked(id); 8137 if (tr != null) { 8138 return tr.getTaskThumbnailLocked(); 8139 } 8140 } 8141 return null; 8142 } 8143 8144 @Override 8145 public int addAppTask(IBinder activityToken, Intent intent, 8146 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8147 final int callingUid = Binder.getCallingUid(); 8148 final long callingIdent = Binder.clearCallingIdentity(); 8149 8150 try { 8151 synchronized (this) { 8152 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8153 if (r == null) { 8154 throw new IllegalArgumentException("Activity does not exist; token=" 8155 + activityToken); 8156 } 8157 ComponentName comp = intent.getComponent(); 8158 if (comp == null) { 8159 throw new IllegalArgumentException("Intent " + intent 8160 + " must specify explicit component"); 8161 } 8162 if (thumbnail.getWidth() != mThumbnailWidth 8163 || thumbnail.getHeight() != mThumbnailHeight) { 8164 throw new IllegalArgumentException("Bad thumbnail size: got " 8165 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8166 + mThumbnailWidth + "x" + mThumbnailHeight); 8167 } 8168 if (intent.getSelector() != null) { 8169 intent.setSelector(null); 8170 } 8171 if (intent.getSourceBounds() != null) { 8172 intent.setSourceBounds(null); 8173 } 8174 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8175 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8176 // The caller has added this as an auto-remove task... that makes no 8177 // sense, so turn off auto-remove. 8178 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8179 } 8180 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8181 // Must be a new task. 8182 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8183 } 8184 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8185 mLastAddedTaskActivity = null; 8186 } 8187 ActivityInfo ainfo = mLastAddedTaskActivity; 8188 if (ainfo == null) { 8189 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8190 comp, 0, UserHandle.getUserId(callingUid)); 8191 if (ainfo.applicationInfo.uid != callingUid) { 8192 throw new SecurityException( 8193 "Can't add task for another application: target uid=" 8194 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8195 } 8196 } 8197 8198 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8199 intent, description); 8200 8201 int trimIdx = trimRecentsForTask(task, false); 8202 if (trimIdx >= 0) { 8203 // If this would have caused a trim, then we'll abort because that 8204 // means it would be added at the end of the list but then just removed. 8205 return -1; 8206 } 8207 8208 final int N = mRecentTasks.size(); 8209 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8210 final TaskRecord tr = mRecentTasks.remove(N - 1); 8211 tr.removedFromRecents(mTaskPersister); 8212 } 8213 8214 task.inRecents = true; 8215 mRecentTasks.add(task); 8216 r.task.stack.addTask(task, false, false); 8217 8218 task.setLastThumbnail(thumbnail); 8219 task.freeLastThumbnail(); 8220 8221 return task.taskId; 8222 } 8223 } finally { 8224 Binder.restoreCallingIdentity(callingIdent); 8225 } 8226 } 8227 8228 @Override 8229 public Point getAppTaskThumbnailSize() { 8230 synchronized (this) { 8231 return new Point(mThumbnailWidth, mThumbnailHeight); 8232 } 8233 } 8234 8235 @Override 8236 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8237 synchronized (this) { 8238 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8239 if (r != null) { 8240 r.taskDescription = td; 8241 r.task.updateTaskDescription(); 8242 } 8243 } 8244 } 8245 8246 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8247 mRecentTasks.remove(tr); 8248 tr.removedFromRecents(mTaskPersister); 8249 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8250 Intent baseIntent = new Intent( 8251 tr.intent != null ? tr.intent : tr.affinityIntent); 8252 ComponentName component = baseIntent.getComponent(); 8253 if (component == null) { 8254 Slog.w(TAG, "Now component for base intent of task: " + tr); 8255 return; 8256 } 8257 8258 // Find any running services associated with this app. 8259 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8260 8261 if (killProcesses) { 8262 // Find any running processes associated with this app. 8263 final String pkg = component.getPackageName(); 8264 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8265 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8266 for (int i=0; i<pmap.size(); i++) { 8267 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8268 for (int j=0; j<uids.size(); j++) { 8269 ProcessRecord proc = uids.valueAt(j); 8270 if (proc.userId != tr.userId) { 8271 continue; 8272 } 8273 if (!proc.pkgList.containsKey(pkg)) { 8274 continue; 8275 } 8276 procs.add(proc); 8277 } 8278 } 8279 8280 // Kill the running processes. 8281 for (int i=0; i<procs.size(); i++) { 8282 ProcessRecord pr = procs.get(i); 8283 if (pr == mHomeProcess) { 8284 // Don't kill the home process along with tasks from the same package. 8285 continue; 8286 } 8287 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8288 pr.kill("remove task", true); 8289 } else { 8290 pr.waitingToKill = "remove task"; 8291 } 8292 } 8293 } 8294 } 8295 8296 /** 8297 * Removes the task with the specified task id. 8298 * 8299 * @param taskId Identifier of the task to be removed. 8300 * @param flags Additional operational flags. May be 0 or 8301 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8302 * @return Returns true if the given task was found and removed. 8303 */ 8304 private boolean removeTaskByIdLocked(int taskId, int flags) { 8305 TaskRecord tr = recentTaskForIdLocked(taskId); 8306 if (tr != null) { 8307 tr.removeTaskActivitiesLocked(); 8308 cleanUpRemovedTaskLocked(tr, flags); 8309 if (tr.isPersistable) { 8310 notifyTaskPersisterLocked(null, true); 8311 } 8312 return true; 8313 } 8314 return false; 8315 } 8316 8317 @Override 8318 public boolean removeTask(int taskId, int flags) { 8319 synchronized (this) { 8320 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8321 "removeTask()"); 8322 long ident = Binder.clearCallingIdentity(); 8323 try { 8324 return removeTaskByIdLocked(taskId, flags); 8325 } finally { 8326 Binder.restoreCallingIdentity(ident); 8327 } 8328 } 8329 } 8330 8331 /** 8332 * TODO: Add mController hook 8333 */ 8334 @Override 8335 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8336 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8337 "moveTaskToFront()"); 8338 8339 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8340 synchronized(this) { 8341 moveTaskToFrontLocked(taskId, flags, options); 8342 } 8343 } 8344 8345 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8346 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8347 Binder.getCallingUid(), "Task to front")) { 8348 ActivityOptions.abort(options); 8349 return; 8350 } 8351 final long origId = Binder.clearCallingIdentity(); 8352 try { 8353 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8354 if (task == null) { 8355 return; 8356 } 8357 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8358 mStackSupervisor.showLockTaskToast(); 8359 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8360 return; 8361 } 8362 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8363 if (prev != null && prev.isRecentsActivity()) { 8364 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8365 } 8366 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8367 } finally { 8368 Binder.restoreCallingIdentity(origId); 8369 } 8370 ActivityOptions.abort(options); 8371 } 8372 8373 @Override 8374 public void moveTaskToBack(int taskId) { 8375 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8376 "moveTaskToBack()"); 8377 8378 synchronized(this) { 8379 TaskRecord tr = recentTaskForIdLocked(taskId); 8380 if (tr != null) { 8381 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8382 ActivityStack stack = tr.stack; 8383 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8384 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8385 Binder.getCallingUid(), "Task to back")) { 8386 return; 8387 } 8388 } 8389 final long origId = Binder.clearCallingIdentity(); 8390 try { 8391 stack.moveTaskToBackLocked(taskId, null); 8392 } finally { 8393 Binder.restoreCallingIdentity(origId); 8394 } 8395 } 8396 } 8397 } 8398 8399 /** 8400 * Moves an activity, and all of the other activities within the same task, to the bottom 8401 * of the history stack. The activity's order within the task is unchanged. 8402 * 8403 * @param token A reference to the activity we wish to move 8404 * @param nonRoot If false then this only works if the activity is the root 8405 * of a task; if true it will work for any activity in a task. 8406 * @return Returns true if the move completed, false if not. 8407 */ 8408 @Override 8409 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8410 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8411 synchronized(this) { 8412 final long origId = Binder.clearCallingIdentity(); 8413 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8414 if (taskId >= 0) { 8415 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8416 } 8417 Binder.restoreCallingIdentity(origId); 8418 } 8419 return false; 8420 } 8421 8422 @Override 8423 public void moveTaskBackwards(int task) { 8424 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8425 "moveTaskBackwards()"); 8426 8427 synchronized(this) { 8428 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8429 Binder.getCallingUid(), "Task backwards")) { 8430 return; 8431 } 8432 final long origId = Binder.clearCallingIdentity(); 8433 moveTaskBackwardsLocked(task); 8434 Binder.restoreCallingIdentity(origId); 8435 } 8436 } 8437 8438 private final void moveTaskBackwardsLocked(int task) { 8439 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8440 } 8441 8442 @Override 8443 public IBinder getHomeActivityToken() throws RemoteException { 8444 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8445 "getHomeActivityToken()"); 8446 synchronized (this) { 8447 return mStackSupervisor.getHomeActivityToken(); 8448 } 8449 } 8450 8451 @Override 8452 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8453 IActivityContainerCallback callback) throws RemoteException { 8454 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8455 "createActivityContainer()"); 8456 synchronized (this) { 8457 if (parentActivityToken == null) { 8458 throw new IllegalArgumentException("parent token must not be null"); 8459 } 8460 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8461 if (r == null) { 8462 return null; 8463 } 8464 if (callback == null) { 8465 throw new IllegalArgumentException("callback must not be null"); 8466 } 8467 return mStackSupervisor.createActivityContainer(r, callback); 8468 } 8469 } 8470 8471 @Override 8472 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8473 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8474 "deleteActivityContainer()"); 8475 synchronized (this) { 8476 mStackSupervisor.deleteActivityContainer(container); 8477 } 8478 } 8479 8480 @Override 8481 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8482 throws RemoteException { 8483 synchronized (this) { 8484 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8485 if (stack != null) { 8486 return stack.mActivityContainer; 8487 } 8488 return null; 8489 } 8490 } 8491 8492 @Override 8493 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8494 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8495 "moveTaskToStack()"); 8496 if (stackId == HOME_STACK_ID) { 8497 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8498 new RuntimeException("here").fillInStackTrace()); 8499 } 8500 synchronized (this) { 8501 long ident = Binder.clearCallingIdentity(); 8502 try { 8503 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8504 + stackId + " toTop=" + toTop); 8505 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8506 } finally { 8507 Binder.restoreCallingIdentity(ident); 8508 } 8509 } 8510 } 8511 8512 @Override 8513 public void resizeStack(int stackBoxId, Rect bounds) { 8514 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8515 "resizeStackBox()"); 8516 long ident = Binder.clearCallingIdentity(); 8517 try { 8518 mWindowManager.resizeStack(stackBoxId, bounds); 8519 } finally { 8520 Binder.restoreCallingIdentity(ident); 8521 } 8522 } 8523 8524 @Override 8525 public List<StackInfo> getAllStackInfos() { 8526 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8527 "getAllStackInfos()"); 8528 long ident = Binder.clearCallingIdentity(); 8529 try { 8530 synchronized (this) { 8531 return mStackSupervisor.getAllStackInfosLocked(); 8532 } 8533 } finally { 8534 Binder.restoreCallingIdentity(ident); 8535 } 8536 } 8537 8538 @Override 8539 public StackInfo getStackInfo(int stackId) { 8540 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8541 "getStackInfo()"); 8542 long ident = Binder.clearCallingIdentity(); 8543 try { 8544 synchronized (this) { 8545 return mStackSupervisor.getStackInfoLocked(stackId); 8546 } 8547 } finally { 8548 Binder.restoreCallingIdentity(ident); 8549 } 8550 } 8551 8552 @Override 8553 public boolean isInHomeStack(int taskId) { 8554 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8555 "getStackInfo()"); 8556 long ident = Binder.clearCallingIdentity(); 8557 try { 8558 synchronized (this) { 8559 TaskRecord tr = recentTaskForIdLocked(taskId); 8560 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8561 } 8562 } finally { 8563 Binder.restoreCallingIdentity(ident); 8564 } 8565 } 8566 8567 @Override 8568 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8569 synchronized(this) { 8570 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8571 } 8572 } 8573 8574 private boolean isLockTaskAuthorized(String pkg) { 8575 final DevicePolicyManager dpm = (DevicePolicyManager) 8576 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8577 try { 8578 int uid = mContext.getPackageManager().getPackageUid(pkg, 8579 Binder.getCallingUserHandle().getIdentifier()); 8580 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8581 } catch (NameNotFoundException e) { 8582 return false; 8583 } 8584 } 8585 8586 void startLockTaskMode(TaskRecord task) { 8587 final String pkg; 8588 synchronized (this) { 8589 pkg = task.intent.getComponent().getPackageName(); 8590 } 8591 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8592 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8593 final TaskRecord taskRecord = task; 8594 mHandler.post(new Runnable() { 8595 @Override 8596 public void run() { 8597 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8598 } 8599 }); 8600 return; 8601 } 8602 long ident = Binder.clearCallingIdentity(); 8603 try { 8604 synchronized (this) { 8605 // Since we lost lock on task, make sure it is still there. 8606 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8607 if (task != null) { 8608 if (!isSystemInitiated 8609 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8610 throw new IllegalArgumentException("Invalid task, not in foreground"); 8611 } 8612 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8613 } 8614 } 8615 } finally { 8616 Binder.restoreCallingIdentity(ident); 8617 } 8618 } 8619 8620 @Override 8621 public void startLockTaskMode(int taskId) { 8622 final TaskRecord task; 8623 long ident = Binder.clearCallingIdentity(); 8624 try { 8625 synchronized (this) { 8626 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8627 } 8628 } finally { 8629 Binder.restoreCallingIdentity(ident); 8630 } 8631 if (task != null) { 8632 startLockTaskMode(task); 8633 } 8634 } 8635 8636 @Override 8637 public void startLockTaskMode(IBinder token) { 8638 final TaskRecord task; 8639 long ident = Binder.clearCallingIdentity(); 8640 try { 8641 synchronized (this) { 8642 final ActivityRecord r = ActivityRecord.forToken(token); 8643 if (r == null) { 8644 return; 8645 } 8646 task = r.task; 8647 } 8648 } finally { 8649 Binder.restoreCallingIdentity(ident); 8650 } 8651 if (task != null) { 8652 startLockTaskMode(task); 8653 } 8654 } 8655 8656 @Override 8657 public void startLockTaskModeOnCurrent() throws RemoteException { 8658 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8659 ActivityRecord r = null; 8660 synchronized (this) { 8661 r = mStackSupervisor.topRunningActivityLocked(); 8662 } 8663 startLockTaskMode(r.task); 8664 } 8665 8666 @Override 8667 public void stopLockTaskMode() { 8668 // Verify that the user matches the package of the intent for the TaskRecord 8669 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8670 // and stopLockTaskMode. 8671 final int callingUid = Binder.getCallingUid(); 8672 if (callingUid != Process.SYSTEM_UID) { 8673 try { 8674 String pkg = 8675 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8676 int uid = mContext.getPackageManager().getPackageUid(pkg, 8677 Binder.getCallingUserHandle().getIdentifier()); 8678 if (uid != callingUid) { 8679 throw new SecurityException("Invalid uid, expected " + uid); 8680 } 8681 } catch (NameNotFoundException e) { 8682 Log.d(TAG, "stopLockTaskMode " + e); 8683 return; 8684 } 8685 } 8686 long ident = Binder.clearCallingIdentity(); 8687 try { 8688 Log.d(TAG, "stopLockTaskMode"); 8689 // Stop lock task 8690 synchronized (this) { 8691 mStackSupervisor.setLockTaskModeLocked(null, false); 8692 } 8693 } finally { 8694 Binder.restoreCallingIdentity(ident); 8695 } 8696 } 8697 8698 @Override 8699 public void stopLockTaskModeOnCurrent() throws RemoteException { 8700 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8701 long ident = Binder.clearCallingIdentity(); 8702 try { 8703 stopLockTaskMode(); 8704 } finally { 8705 Binder.restoreCallingIdentity(ident); 8706 } 8707 } 8708 8709 @Override 8710 public boolean isInLockTaskMode() { 8711 synchronized (this) { 8712 return mStackSupervisor.isInLockTaskMode(); 8713 } 8714 } 8715 8716 // ========================================================= 8717 // CONTENT PROVIDERS 8718 // ========================================================= 8719 8720 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8721 List<ProviderInfo> providers = null; 8722 try { 8723 providers = AppGlobals.getPackageManager(). 8724 queryContentProviders(app.processName, app.uid, 8725 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8726 } catch (RemoteException ex) { 8727 } 8728 if (DEBUG_MU) 8729 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8730 int userId = app.userId; 8731 if (providers != null) { 8732 int N = providers.size(); 8733 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8734 for (int i=0; i<N; i++) { 8735 ProviderInfo cpi = 8736 (ProviderInfo)providers.get(i); 8737 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8738 cpi.name, cpi.flags); 8739 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8740 // This is a singleton provider, but a user besides the 8741 // default user is asking to initialize a process it runs 8742 // in... well, no, it doesn't actually run in this process, 8743 // it runs in the process of the default user. Get rid of it. 8744 providers.remove(i); 8745 N--; 8746 i--; 8747 continue; 8748 } 8749 8750 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8751 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8752 if (cpr == null) { 8753 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8754 mProviderMap.putProviderByClass(comp, cpr); 8755 } 8756 if (DEBUG_MU) 8757 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8758 app.pubProviders.put(cpi.name, cpr); 8759 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8760 // Don't add this if it is a platform component that is marked 8761 // to run in multiple processes, because this is actually 8762 // part of the framework so doesn't make sense to track as a 8763 // separate apk in the process. 8764 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8765 mProcessStats); 8766 } 8767 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8768 } 8769 } 8770 return providers; 8771 } 8772 8773 /** 8774 * Check if {@link ProcessRecord} has a possible chance at accessing the 8775 * given {@link ProviderInfo}. Final permission checking is always done 8776 * in {@link ContentProvider}. 8777 */ 8778 private final String checkContentProviderPermissionLocked( 8779 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8780 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8781 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8782 boolean checkedGrants = false; 8783 if (checkUser) { 8784 // Looking for cross-user grants before enforcing the typical cross-users permissions 8785 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8786 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8787 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8788 return null; 8789 } 8790 checkedGrants = true; 8791 } 8792 userId = handleIncomingUser(callingPid, callingUid, userId, 8793 false, ALLOW_NON_FULL, 8794 "checkContentProviderPermissionLocked " + cpi.authority, null); 8795 if (userId != tmpTargetUserId) { 8796 // When we actually went to determine the final targer user ID, this ended 8797 // up different than our initial check for the authority. This is because 8798 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8799 // SELF. So we need to re-check the grants again. 8800 checkedGrants = false; 8801 } 8802 } 8803 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8804 cpi.applicationInfo.uid, cpi.exported) 8805 == PackageManager.PERMISSION_GRANTED) { 8806 return null; 8807 } 8808 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8809 cpi.applicationInfo.uid, cpi.exported) 8810 == PackageManager.PERMISSION_GRANTED) { 8811 return null; 8812 } 8813 8814 PathPermission[] pps = cpi.pathPermissions; 8815 if (pps != null) { 8816 int i = pps.length; 8817 while (i > 0) { 8818 i--; 8819 PathPermission pp = pps[i]; 8820 String pprperm = pp.getReadPermission(); 8821 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8822 cpi.applicationInfo.uid, cpi.exported) 8823 == PackageManager.PERMISSION_GRANTED) { 8824 return null; 8825 } 8826 String ppwperm = pp.getWritePermission(); 8827 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8828 cpi.applicationInfo.uid, cpi.exported) 8829 == PackageManager.PERMISSION_GRANTED) { 8830 return null; 8831 } 8832 } 8833 } 8834 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8835 return null; 8836 } 8837 8838 String msg; 8839 if (!cpi.exported) { 8840 msg = "Permission Denial: opening provider " + cpi.name 8841 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8842 + ", uid=" + callingUid + ") that is not exported from uid " 8843 + cpi.applicationInfo.uid; 8844 } else { 8845 msg = "Permission Denial: opening provider " + cpi.name 8846 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8847 + ", uid=" + callingUid + ") requires " 8848 + cpi.readPermission + " or " + cpi.writePermission; 8849 } 8850 Slog.w(TAG, msg); 8851 return msg; 8852 } 8853 8854 /** 8855 * Returns if the ContentProvider has granted a uri to callingUid 8856 */ 8857 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8858 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8859 if (perms != null) { 8860 for (int i=perms.size()-1; i>=0; i--) { 8861 GrantUri grantUri = perms.keyAt(i); 8862 if (grantUri.sourceUserId == userId || !checkUser) { 8863 if (matchesProvider(grantUri.uri, cpi)) { 8864 return true; 8865 } 8866 } 8867 } 8868 } 8869 return false; 8870 } 8871 8872 /** 8873 * Returns true if the uri authority is one of the authorities specified in the provider. 8874 */ 8875 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8876 String uriAuth = uri.getAuthority(); 8877 String cpiAuth = cpi.authority; 8878 if (cpiAuth.indexOf(';') == -1) { 8879 return cpiAuth.equals(uriAuth); 8880 } 8881 String[] cpiAuths = cpiAuth.split(";"); 8882 int length = cpiAuths.length; 8883 for (int i = 0; i < length; i++) { 8884 if (cpiAuths[i].equals(uriAuth)) return true; 8885 } 8886 return false; 8887 } 8888 8889 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8890 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8891 if (r != null) { 8892 for (int i=0; i<r.conProviders.size(); i++) { 8893 ContentProviderConnection conn = r.conProviders.get(i); 8894 if (conn.provider == cpr) { 8895 if (DEBUG_PROVIDER) Slog.v(TAG, 8896 "Adding provider requested by " 8897 + r.processName + " from process " 8898 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8899 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8900 if (stable) { 8901 conn.stableCount++; 8902 conn.numStableIncs++; 8903 } else { 8904 conn.unstableCount++; 8905 conn.numUnstableIncs++; 8906 } 8907 return conn; 8908 } 8909 } 8910 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8911 if (stable) { 8912 conn.stableCount = 1; 8913 conn.numStableIncs = 1; 8914 } else { 8915 conn.unstableCount = 1; 8916 conn.numUnstableIncs = 1; 8917 } 8918 cpr.connections.add(conn); 8919 r.conProviders.add(conn); 8920 return conn; 8921 } 8922 cpr.addExternalProcessHandleLocked(externalProcessToken); 8923 return null; 8924 } 8925 8926 boolean decProviderCountLocked(ContentProviderConnection conn, 8927 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8928 if (conn != null) { 8929 cpr = conn.provider; 8930 if (DEBUG_PROVIDER) Slog.v(TAG, 8931 "Removing provider requested by " 8932 + conn.client.processName + " from process " 8933 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8934 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8935 if (stable) { 8936 conn.stableCount--; 8937 } else { 8938 conn.unstableCount--; 8939 } 8940 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8941 cpr.connections.remove(conn); 8942 conn.client.conProviders.remove(conn); 8943 return true; 8944 } 8945 return false; 8946 } 8947 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8948 return false; 8949 } 8950 8951 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8952 String name, IBinder token, boolean stable, int userId) { 8953 ContentProviderRecord cpr; 8954 ContentProviderConnection conn = null; 8955 ProviderInfo cpi = null; 8956 8957 synchronized(this) { 8958 ProcessRecord r = null; 8959 if (caller != null) { 8960 r = getRecordForAppLocked(caller); 8961 if (r == null) { 8962 throw new SecurityException( 8963 "Unable to find app for caller " + caller 8964 + " (pid=" + Binder.getCallingPid() 8965 + ") when getting content provider " + name); 8966 } 8967 } 8968 8969 boolean checkCrossUser = true; 8970 8971 // First check if this content provider has been published... 8972 cpr = mProviderMap.getProviderByName(name, userId); 8973 // If that didn't work, check if it exists for user 0 and then 8974 // verify that it's a singleton provider before using it. 8975 if (cpr == null && userId != UserHandle.USER_OWNER) { 8976 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8977 if (cpr != null) { 8978 cpi = cpr.info; 8979 if (isSingleton(cpi.processName, cpi.applicationInfo, 8980 cpi.name, cpi.flags) 8981 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8982 userId = UserHandle.USER_OWNER; 8983 checkCrossUser = false; 8984 } else { 8985 cpr = null; 8986 cpi = null; 8987 } 8988 } 8989 } 8990 8991 boolean providerRunning = cpr != null; 8992 if (providerRunning) { 8993 cpi = cpr.info; 8994 String msg; 8995 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8996 != null) { 8997 throw new SecurityException(msg); 8998 } 8999 9000 if (r != null && cpr.canRunHere(r)) { 9001 // This provider has been published or is in the process 9002 // of being published... but it is also allowed to run 9003 // in the caller's process, so don't make a connection 9004 // and just let the caller instantiate its own instance. 9005 ContentProviderHolder holder = cpr.newHolder(null); 9006 // don't give caller the provider object, it needs 9007 // to make its own. 9008 holder.provider = null; 9009 return holder; 9010 } 9011 9012 final long origId = Binder.clearCallingIdentity(); 9013 9014 // In this case the provider instance already exists, so we can 9015 // return it right away. 9016 conn = incProviderCountLocked(r, cpr, token, stable); 9017 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9018 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9019 // If this is a perceptible app accessing the provider, 9020 // make sure to count it as being accessed and thus 9021 // back up on the LRU list. This is good because 9022 // content providers are often expensive to start. 9023 updateLruProcessLocked(cpr.proc, false, null); 9024 } 9025 } 9026 9027 if (cpr.proc != null) { 9028 if (false) { 9029 if (cpr.name.flattenToShortString().equals( 9030 "com.android.providers.calendar/.CalendarProvider2")) { 9031 Slog.v(TAG, "****************** KILLING " 9032 + cpr.name.flattenToShortString()); 9033 Process.killProcess(cpr.proc.pid); 9034 } 9035 } 9036 boolean success = updateOomAdjLocked(cpr.proc); 9037 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9038 // NOTE: there is still a race here where a signal could be 9039 // pending on the process even though we managed to update its 9040 // adj level. Not sure what to do about this, but at least 9041 // the race is now smaller. 9042 if (!success) { 9043 // Uh oh... it looks like the provider's process 9044 // has been killed on us. We need to wait for a new 9045 // process to be started, and make sure its death 9046 // doesn't kill our process. 9047 Slog.i(TAG, 9048 "Existing provider " + cpr.name.flattenToShortString() 9049 + " is crashing; detaching " + r); 9050 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9051 appDiedLocked(cpr.proc); 9052 if (!lastRef) { 9053 // This wasn't the last ref our process had on 9054 // the provider... we have now been killed, bail. 9055 return null; 9056 } 9057 providerRunning = false; 9058 conn = null; 9059 } 9060 } 9061 9062 Binder.restoreCallingIdentity(origId); 9063 } 9064 9065 boolean singleton; 9066 if (!providerRunning) { 9067 try { 9068 cpi = AppGlobals.getPackageManager(). 9069 resolveContentProvider(name, 9070 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9071 } catch (RemoteException ex) { 9072 } 9073 if (cpi == null) { 9074 return null; 9075 } 9076 // If the provider is a singleton AND 9077 // (it's a call within the same user || the provider is a 9078 // privileged app) 9079 // Then allow connecting to the singleton provider 9080 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9081 cpi.name, cpi.flags) 9082 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9083 if (singleton) { 9084 userId = UserHandle.USER_OWNER; 9085 } 9086 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9087 9088 String msg; 9089 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9090 != null) { 9091 throw new SecurityException(msg); 9092 } 9093 9094 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9095 && !cpi.processName.equals("system")) { 9096 // If this content provider does not run in the system 9097 // process, and the system is not yet ready to run other 9098 // processes, then fail fast instead of hanging. 9099 throw new IllegalArgumentException( 9100 "Attempt to launch content provider before system ready"); 9101 } 9102 9103 // Make sure that the user who owns this provider is started. If not, 9104 // we don't want to allow it to run. 9105 if (mStartedUsers.get(userId) == null) { 9106 Slog.w(TAG, "Unable to launch app " 9107 + cpi.applicationInfo.packageName + "/" 9108 + cpi.applicationInfo.uid + " for provider " 9109 + name + ": user " + userId + " is stopped"); 9110 return null; 9111 } 9112 9113 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9114 cpr = mProviderMap.getProviderByClass(comp, userId); 9115 final boolean firstClass = cpr == null; 9116 if (firstClass) { 9117 try { 9118 ApplicationInfo ai = 9119 AppGlobals.getPackageManager(). 9120 getApplicationInfo( 9121 cpi.applicationInfo.packageName, 9122 STOCK_PM_FLAGS, userId); 9123 if (ai == null) { 9124 Slog.w(TAG, "No package info for content provider " 9125 + cpi.name); 9126 return null; 9127 } 9128 ai = getAppInfoForUser(ai, userId); 9129 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9130 } catch (RemoteException ex) { 9131 // pm is in same process, this will never happen. 9132 } 9133 } 9134 9135 if (r != null && cpr.canRunHere(r)) { 9136 // If this is a multiprocess provider, then just return its 9137 // info and allow the caller to instantiate it. Only do 9138 // this if the provider is the same user as the caller's 9139 // process, or can run as root (so can be in any process). 9140 return cpr.newHolder(null); 9141 } 9142 9143 if (DEBUG_PROVIDER) { 9144 RuntimeException e = new RuntimeException("here"); 9145 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9146 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9147 } 9148 9149 // This is single process, and our app is now connecting to it. 9150 // See if we are already in the process of launching this 9151 // provider. 9152 final int N = mLaunchingProviders.size(); 9153 int i; 9154 for (i=0; i<N; i++) { 9155 if (mLaunchingProviders.get(i) == cpr) { 9156 break; 9157 } 9158 } 9159 9160 // If the provider is not already being launched, then get it 9161 // started. 9162 if (i >= N) { 9163 final long origId = Binder.clearCallingIdentity(); 9164 9165 try { 9166 // Content provider is now in use, its package can't be stopped. 9167 try { 9168 AppGlobals.getPackageManager().setPackageStoppedState( 9169 cpr.appInfo.packageName, false, userId); 9170 } catch (RemoteException e) { 9171 } catch (IllegalArgumentException e) { 9172 Slog.w(TAG, "Failed trying to unstop package " 9173 + cpr.appInfo.packageName + ": " + e); 9174 } 9175 9176 // Use existing process if already started 9177 ProcessRecord proc = getProcessRecordLocked( 9178 cpi.processName, cpr.appInfo.uid, false); 9179 if (proc != null && proc.thread != null) { 9180 if (DEBUG_PROVIDER) { 9181 Slog.d(TAG, "Installing in existing process " + proc); 9182 } 9183 proc.pubProviders.put(cpi.name, cpr); 9184 try { 9185 proc.thread.scheduleInstallProvider(cpi); 9186 } catch (RemoteException e) { 9187 } 9188 } else { 9189 proc = startProcessLocked(cpi.processName, 9190 cpr.appInfo, false, 0, "content provider", 9191 new ComponentName(cpi.applicationInfo.packageName, 9192 cpi.name), false, false, false); 9193 if (proc == null) { 9194 Slog.w(TAG, "Unable to launch app " 9195 + cpi.applicationInfo.packageName + "/" 9196 + cpi.applicationInfo.uid + " for provider " 9197 + name + ": process is bad"); 9198 return null; 9199 } 9200 } 9201 cpr.launchingApp = proc; 9202 mLaunchingProviders.add(cpr); 9203 } finally { 9204 Binder.restoreCallingIdentity(origId); 9205 } 9206 } 9207 9208 // Make sure the provider is published (the same provider class 9209 // may be published under multiple names). 9210 if (firstClass) { 9211 mProviderMap.putProviderByClass(comp, cpr); 9212 } 9213 9214 mProviderMap.putProviderByName(name, cpr); 9215 conn = incProviderCountLocked(r, cpr, token, stable); 9216 if (conn != null) { 9217 conn.waiting = true; 9218 } 9219 } 9220 } 9221 9222 // Wait for the provider to be published... 9223 synchronized (cpr) { 9224 while (cpr.provider == null) { 9225 if (cpr.launchingApp == null) { 9226 Slog.w(TAG, "Unable to launch app " 9227 + cpi.applicationInfo.packageName + "/" 9228 + cpi.applicationInfo.uid + " for provider " 9229 + name + ": launching app became null"); 9230 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9231 UserHandle.getUserId(cpi.applicationInfo.uid), 9232 cpi.applicationInfo.packageName, 9233 cpi.applicationInfo.uid, name); 9234 return null; 9235 } 9236 try { 9237 if (DEBUG_MU) { 9238 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9239 + cpr.launchingApp); 9240 } 9241 if (conn != null) { 9242 conn.waiting = true; 9243 } 9244 cpr.wait(); 9245 } catch (InterruptedException ex) { 9246 } finally { 9247 if (conn != null) { 9248 conn.waiting = false; 9249 } 9250 } 9251 } 9252 } 9253 return cpr != null ? cpr.newHolder(conn) : null; 9254 } 9255 9256 @Override 9257 public final ContentProviderHolder getContentProvider( 9258 IApplicationThread caller, String name, int userId, boolean stable) { 9259 enforceNotIsolatedCaller("getContentProvider"); 9260 if (caller == null) { 9261 String msg = "null IApplicationThread when getting content provider " 9262 + name; 9263 Slog.w(TAG, msg); 9264 throw new SecurityException(msg); 9265 } 9266 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9267 // with cross-user grant. 9268 return getContentProviderImpl(caller, name, null, stable, userId); 9269 } 9270 9271 public ContentProviderHolder getContentProviderExternal( 9272 String name, int userId, IBinder token) { 9273 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9274 "Do not have permission in call getContentProviderExternal()"); 9275 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9276 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9277 return getContentProviderExternalUnchecked(name, token, userId); 9278 } 9279 9280 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9281 IBinder token, int userId) { 9282 return getContentProviderImpl(null, name, token, true, userId); 9283 } 9284 9285 /** 9286 * Drop a content provider from a ProcessRecord's bookkeeping 9287 */ 9288 public void removeContentProvider(IBinder connection, boolean stable) { 9289 enforceNotIsolatedCaller("removeContentProvider"); 9290 long ident = Binder.clearCallingIdentity(); 9291 try { 9292 synchronized (this) { 9293 ContentProviderConnection conn; 9294 try { 9295 conn = (ContentProviderConnection)connection; 9296 } catch (ClassCastException e) { 9297 String msg ="removeContentProvider: " + connection 9298 + " not a ContentProviderConnection"; 9299 Slog.w(TAG, msg); 9300 throw new IllegalArgumentException(msg); 9301 } 9302 if (conn == null) { 9303 throw new NullPointerException("connection is null"); 9304 } 9305 if (decProviderCountLocked(conn, null, null, stable)) { 9306 updateOomAdjLocked(); 9307 } 9308 } 9309 } finally { 9310 Binder.restoreCallingIdentity(ident); 9311 } 9312 } 9313 9314 public void removeContentProviderExternal(String name, IBinder token) { 9315 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9316 "Do not have permission in call removeContentProviderExternal()"); 9317 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9318 } 9319 9320 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9321 synchronized (this) { 9322 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9323 if(cpr == null) { 9324 //remove from mProvidersByClass 9325 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9326 return; 9327 } 9328 9329 //update content provider record entry info 9330 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9331 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9332 if (localCpr.hasExternalProcessHandles()) { 9333 if (localCpr.removeExternalProcessHandleLocked(token)) { 9334 updateOomAdjLocked(); 9335 } else { 9336 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9337 + " with no external reference for token: " 9338 + token + "."); 9339 } 9340 } else { 9341 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9342 + " with no external references."); 9343 } 9344 } 9345 } 9346 9347 public final void publishContentProviders(IApplicationThread caller, 9348 List<ContentProviderHolder> providers) { 9349 if (providers == null) { 9350 return; 9351 } 9352 9353 enforceNotIsolatedCaller("publishContentProviders"); 9354 synchronized (this) { 9355 final ProcessRecord r = getRecordForAppLocked(caller); 9356 if (DEBUG_MU) 9357 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9358 if (r == null) { 9359 throw new SecurityException( 9360 "Unable to find app for caller " + caller 9361 + " (pid=" + Binder.getCallingPid() 9362 + ") when publishing content providers"); 9363 } 9364 9365 final long origId = Binder.clearCallingIdentity(); 9366 9367 final int N = providers.size(); 9368 for (int i=0; i<N; i++) { 9369 ContentProviderHolder src = providers.get(i); 9370 if (src == null || src.info == null || src.provider == null) { 9371 continue; 9372 } 9373 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9374 if (DEBUG_MU) 9375 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9376 if (dst != null) { 9377 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9378 mProviderMap.putProviderByClass(comp, dst); 9379 String names[] = dst.info.authority.split(";"); 9380 for (int j = 0; j < names.length; j++) { 9381 mProviderMap.putProviderByName(names[j], dst); 9382 } 9383 9384 int NL = mLaunchingProviders.size(); 9385 int j; 9386 for (j=0; j<NL; j++) { 9387 if (mLaunchingProviders.get(j) == dst) { 9388 mLaunchingProviders.remove(j); 9389 j--; 9390 NL--; 9391 } 9392 } 9393 synchronized (dst) { 9394 dst.provider = src.provider; 9395 dst.proc = r; 9396 dst.notifyAll(); 9397 } 9398 updateOomAdjLocked(r); 9399 } 9400 } 9401 9402 Binder.restoreCallingIdentity(origId); 9403 } 9404 } 9405 9406 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9407 ContentProviderConnection conn; 9408 try { 9409 conn = (ContentProviderConnection)connection; 9410 } catch (ClassCastException e) { 9411 String msg ="refContentProvider: " + connection 9412 + " not a ContentProviderConnection"; 9413 Slog.w(TAG, msg); 9414 throw new IllegalArgumentException(msg); 9415 } 9416 if (conn == null) { 9417 throw new NullPointerException("connection is null"); 9418 } 9419 9420 synchronized (this) { 9421 if (stable > 0) { 9422 conn.numStableIncs += stable; 9423 } 9424 stable = conn.stableCount + stable; 9425 if (stable < 0) { 9426 throw new IllegalStateException("stableCount < 0: " + stable); 9427 } 9428 9429 if (unstable > 0) { 9430 conn.numUnstableIncs += unstable; 9431 } 9432 unstable = conn.unstableCount + unstable; 9433 if (unstable < 0) { 9434 throw new IllegalStateException("unstableCount < 0: " + unstable); 9435 } 9436 9437 if ((stable+unstable) <= 0) { 9438 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9439 + stable + " unstable=" + unstable); 9440 } 9441 conn.stableCount = stable; 9442 conn.unstableCount = unstable; 9443 return !conn.dead; 9444 } 9445 } 9446 9447 public void unstableProviderDied(IBinder connection) { 9448 ContentProviderConnection conn; 9449 try { 9450 conn = (ContentProviderConnection)connection; 9451 } catch (ClassCastException e) { 9452 String msg ="refContentProvider: " + connection 9453 + " not a ContentProviderConnection"; 9454 Slog.w(TAG, msg); 9455 throw new IllegalArgumentException(msg); 9456 } 9457 if (conn == null) { 9458 throw new NullPointerException("connection is null"); 9459 } 9460 9461 // Safely retrieve the content provider associated with the connection. 9462 IContentProvider provider; 9463 synchronized (this) { 9464 provider = conn.provider.provider; 9465 } 9466 9467 if (provider == null) { 9468 // Um, yeah, we're way ahead of you. 9469 return; 9470 } 9471 9472 // Make sure the caller is being honest with us. 9473 if (provider.asBinder().pingBinder()) { 9474 // Er, no, still looks good to us. 9475 synchronized (this) { 9476 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9477 + " says " + conn + " died, but we don't agree"); 9478 return; 9479 } 9480 } 9481 9482 // Well look at that! It's dead! 9483 synchronized (this) { 9484 if (conn.provider.provider != provider) { 9485 // But something changed... good enough. 9486 return; 9487 } 9488 9489 ProcessRecord proc = conn.provider.proc; 9490 if (proc == null || proc.thread == null) { 9491 // Seems like the process is already cleaned up. 9492 return; 9493 } 9494 9495 // As far as we're concerned, this is just like receiving a 9496 // death notification... just a bit prematurely. 9497 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9498 + ") early provider death"); 9499 final long ident = Binder.clearCallingIdentity(); 9500 try { 9501 appDiedLocked(proc); 9502 } finally { 9503 Binder.restoreCallingIdentity(ident); 9504 } 9505 } 9506 } 9507 9508 @Override 9509 public void appNotRespondingViaProvider(IBinder connection) { 9510 enforceCallingPermission( 9511 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9512 9513 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9514 if (conn == null) { 9515 Slog.w(TAG, "ContentProviderConnection is null"); 9516 return; 9517 } 9518 9519 final ProcessRecord host = conn.provider.proc; 9520 if (host == null) { 9521 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9522 return; 9523 } 9524 9525 final long token = Binder.clearCallingIdentity(); 9526 try { 9527 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9528 } finally { 9529 Binder.restoreCallingIdentity(token); 9530 } 9531 } 9532 9533 public final void installSystemProviders() { 9534 List<ProviderInfo> providers; 9535 synchronized (this) { 9536 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9537 providers = generateApplicationProvidersLocked(app); 9538 if (providers != null) { 9539 for (int i=providers.size()-1; i>=0; i--) { 9540 ProviderInfo pi = (ProviderInfo)providers.get(i); 9541 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9542 Slog.w(TAG, "Not installing system proc provider " + pi.name 9543 + ": not system .apk"); 9544 providers.remove(i); 9545 } 9546 } 9547 } 9548 } 9549 if (providers != null) { 9550 mSystemThread.installSystemProviders(providers); 9551 } 9552 9553 mCoreSettingsObserver = new CoreSettingsObserver(this); 9554 9555 //mUsageStatsService.monitorPackages(); 9556 } 9557 9558 /** 9559 * Allows apps to retrieve the MIME type of a URI. 9560 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9561 * users, then it does not need permission to access the ContentProvider. 9562 * Either, it needs cross-user uri grants. 9563 * 9564 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9565 * 9566 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9567 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9568 */ 9569 public String getProviderMimeType(Uri uri, int userId) { 9570 enforceNotIsolatedCaller("getProviderMimeType"); 9571 final String name = uri.getAuthority(); 9572 int callingUid = Binder.getCallingUid(); 9573 int callingPid = Binder.getCallingPid(); 9574 long ident = 0; 9575 boolean clearedIdentity = false; 9576 userId = unsafeConvertIncomingUser(userId); 9577 if (UserHandle.getUserId(callingUid) != userId) { 9578 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9579 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9580 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9581 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9582 clearedIdentity = true; 9583 ident = Binder.clearCallingIdentity(); 9584 } 9585 } 9586 ContentProviderHolder holder = null; 9587 try { 9588 holder = getContentProviderExternalUnchecked(name, null, userId); 9589 if (holder != null) { 9590 return holder.provider.getType(uri); 9591 } 9592 } catch (RemoteException e) { 9593 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9594 return null; 9595 } finally { 9596 // We need to clear the identity to call removeContentProviderExternalUnchecked 9597 if (!clearedIdentity) { 9598 ident = Binder.clearCallingIdentity(); 9599 } 9600 try { 9601 if (holder != null) { 9602 removeContentProviderExternalUnchecked(name, null, userId); 9603 } 9604 } finally { 9605 Binder.restoreCallingIdentity(ident); 9606 } 9607 } 9608 9609 return null; 9610 } 9611 9612 // ========================================================= 9613 // GLOBAL MANAGEMENT 9614 // ========================================================= 9615 9616 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9617 boolean isolated, int isolatedUid) { 9618 String proc = customProcess != null ? customProcess : info.processName; 9619 BatteryStatsImpl.Uid.Proc ps = null; 9620 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9621 int uid = info.uid; 9622 if (isolated) { 9623 if (isolatedUid == 0) { 9624 int userId = UserHandle.getUserId(uid); 9625 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9626 while (true) { 9627 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9628 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9629 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9630 } 9631 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9632 mNextIsolatedProcessUid++; 9633 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9634 // No process for this uid, use it. 9635 break; 9636 } 9637 stepsLeft--; 9638 if (stepsLeft <= 0) { 9639 return null; 9640 } 9641 } 9642 } else { 9643 // Special case for startIsolatedProcess (internal only), where 9644 // the uid of the isolated process is specified by the caller. 9645 uid = isolatedUid; 9646 } 9647 } 9648 return new ProcessRecord(stats, info, proc, uid); 9649 } 9650 9651 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9652 String abiOverride) { 9653 ProcessRecord app; 9654 if (!isolated) { 9655 app = getProcessRecordLocked(info.processName, info.uid, true); 9656 } else { 9657 app = null; 9658 } 9659 9660 if (app == null) { 9661 app = newProcessRecordLocked(info, null, isolated, 0); 9662 mProcessNames.put(info.processName, app.uid, app); 9663 if (isolated) { 9664 mIsolatedProcesses.put(app.uid, app); 9665 } 9666 updateLruProcessLocked(app, false, null); 9667 updateOomAdjLocked(); 9668 } 9669 9670 // This package really, really can not be stopped. 9671 try { 9672 AppGlobals.getPackageManager().setPackageStoppedState( 9673 info.packageName, false, UserHandle.getUserId(app.uid)); 9674 } catch (RemoteException e) { 9675 } catch (IllegalArgumentException e) { 9676 Slog.w(TAG, "Failed trying to unstop package " 9677 + info.packageName + ": " + e); 9678 } 9679 9680 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9681 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9682 app.persistent = true; 9683 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9684 } 9685 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9686 mPersistentStartingProcesses.add(app); 9687 startProcessLocked(app, "added application", app.processName, abiOverride, 9688 null /* entryPoint */, null /* entryPointArgs */); 9689 } 9690 9691 return app; 9692 } 9693 9694 public void unhandledBack() { 9695 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9696 "unhandledBack()"); 9697 9698 synchronized(this) { 9699 final long origId = Binder.clearCallingIdentity(); 9700 try { 9701 getFocusedStack().unhandledBackLocked(); 9702 } finally { 9703 Binder.restoreCallingIdentity(origId); 9704 } 9705 } 9706 } 9707 9708 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9709 enforceNotIsolatedCaller("openContentUri"); 9710 final int userId = UserHandle.getCallingUserId(); 9711 String name = uri.getAuthority(); 9712 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9713 ParcelFileDescriptor pfd = null; 9714 if (cph != null) { 9715 // We record the binder invoker's uid in thread-local storage before 9716 // going to the content provider to open the file. Later, in the code 9717 // that handles all permissions checks, we look for this uid and use 9718 // that rather than the Activity Manager's own uid. The effect is that 9719 // we do the check against the caller's permissions even though it looks 9720 // to the content provider like the Activity Manager itself is making 9721 // the request. 9722 sCallerIdentity.set(new Identity( 9723 Binder.getCallingPid(), Binder.getCallingUid())); 9724 try { 9725 pfd = cph.provider.openFile(null, uri, "r", null); 9726 } catch (FileNotFoundException e) { 9727 // do nothing; pfd will be returned null 9728 } finally { 9729 // Ensure that whatever happens, we clean up the identity state 9730 sCallerIdentity.remove(); 9731 } 9732 9733 // We've got the fd now, so we're done with the provider. 9734 removeContentProviderExternalUnchecked(name, null, userId); 9735 } else { 9736 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9737 } 9738 return pfd; 9739 } 9740 9741 // Actually is sleeping or shutting down or whatever else in the future 9742 // is an inactive state. 9743 public boolean isSleepingOrShuttingDown() { 9744 return mSleeping || mShuttingDown; 9745 } 9746 9747 public boolean isSleeping() { 9748 return mSleeping; 9749 } 9750 9751 void goingToSleep() { 9752 synchronized(this) { 9753 mWentToSleep = true; 9754 updateEventDispatchingLocked(); 9755 goToSleepIfNeededLocked(); 9756 } 9757 } 9758 9759 void finishRunningVoiceLocked() { 9760 if (mRunningVoice) { 9761 mRunningVoice = false; 9762 goToSleepIfNeededLocked(); 9763 } 9764 } 9765 9766 void goToSleepIfNeededLocked() { 9767 if (mWentToSleep && !mRunningVoice) { 9768 if (!mSleeping) { 9769 mSleeping = true; 9770 mStackSupervisor.goingToSleepLocked(); 9771 9772 // Initialize the wake times of all processes. 9773 checkExcessivePowerUsageLocked(false); 9774 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9775 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9776 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9777 } 9778 } 9779 } 9780 9781 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9782 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9783 // Never persist the home stack. 9784 return; 9785 } 9786 mTaskPersister.wakeup(task, flush); 9787 } 9788 9789 @Override 9790 public boolean shutdown(int timeout) { 9791 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9792 != PackageManager.PERMISSION_GRANTED) { 9793 throw new SecurityException("Requires permission " 9794 + android.Manifest.permission.SHUTDOWN); 9795 } 9796 9797 boolean timedout = false; 9798 9799 synchronized(this) { 9800 mShuttingDown = true; 9801 updateEventDispatchingLocked(); 9802 timedout = mStackSupervisor.shutdownLocked(timeout); 9803 } 9804 9805 mAppOpsService.shutdown(); 9806 if (mUsageStatsService != null) { 9807 mUsageStatsService.prepareShutdown(); 9808 } 9809 mBatteryStatsService.shutdown(); 9810 synchronized (this) { 9811 mProcessStats.shutdownLocked(); 9812 } 9813 notifyTaskPersisterLocked(null, true); 9814 9815 return timedout; 9816 } 9817 9818 public final void activitySlept(IBinder token) { 9819 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9820 9821 final long origId = Binder.clearCallingIdentity(); 9822 9823 synchronized (this) { 9824 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9825 if (r != null) { 9826 mStackSupervisor.activitySleptLocked(r); 9827 } 9828 } 9829 9830 Binder.restoreCallingIdentity(origId); 9831 } 9832 9833 void logLockScreen(String msg) { 9834 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9835 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9836 mWentToSleep + " mSleeping=" + mSleeping); 9837 } 9838 9839 private void comeOutOfSleepIfNeededLocked() { 9840 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9841 if (mSleeping) { 9842 mSleeping = false; 9843 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9844 } 9845 } 9846 } 9847 9848 void wakingUp() { 9849 synchronized(this) { 9850 mWentToSleep = false; 9851 updateEventDispatchingLocked(); 9852 comeOutOfSleepIfNeededLocked(); 9853 } 9854 } 9855 9856 void startRunningVoiceLocked() { 9857 if (!mRunningVoice) { 9858 mRunningVoice = true; 9859 comeOutOfSleepIfNeededLocked(); 9860 } 9861 } 9862 9863 private void updateEventDispatchingLocked() { 9864 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9865 } 9866 9867 public void setLockScreenShown(boolean shown) { 9868 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9869 != PackageManager.PERMISSION_GRANTED) { 9870 throw new SecurityException("Requires permission " 9871 + android.Manifest.permission.DEVICE_POWER); 9872 } 9873 9874 synchronized(this) { 9875 long ident = Binder.clearCallingIdentity(); 9876 try { 9877 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9878 mLockScreenShown = shown; 9879 comeOutOfSleepIfNeededLocked(); 9880 } finally { 9881 Binder.restoreCallingIdentity(ident); 9882 } 9883 } 9884 } 9885 9886 @Override 9887 public void stopAppSwitches() { 9888 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9889 != PackageManager.PERMISSION_GRANTED) { 9890 throw new SecurityException("Requires permission " 9891 + android.Manifest.permission.STOP_APP_SWITCHES); 9892 } 9893 9894 synchronized(this) { 9895 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9896 + APP_SWITCH_DELAY_TIME; 9897 mDidAppSwitch = false; 9898 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9899 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9900 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9901 } 9902 } 9903 9904 public void resumeAppSwitches() { 9905 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9906 != PackageManager.PERMISSION_GRANTED) { 9907 throw new SecurityException("Requires permission " 9908 + android.Manifest.permission.STOP_APP_SWITCHES); 9909 } 9910 9911 synchronized(this) { 9912 // Note that we don't execute any pending app switches... we will 9913 // let those wait until either the timeout, or the next start 9914 // activity request. 9915 mAppSwitchesAllowedTime = 0; 9916 } 9917 } 9918 9919 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9920 String name) { 9921 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9922 return true; 9923 } 9924 9925 final int perm = checkComponentPermission( 9926 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9927 callingUid, -1, true); 9928 if (perm == PackageManager.PERMISSION_GRANTED) { 9929 return true; 9930 } 9931 9932 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9933 return false; 9934 } 9935 9936 public void setDebugApp(String packageName, boolean waitForDebugger, 9937 boolean persistent) { 9938 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9939 "setDebugApp()"); 9940 9941 long ident = Binder.clearCallingIdentity(); 9942 try { 9943 // Note that this is not really thread safe if there are multiple 9944 // callers into it at the same time, but that's not a situation we 9945 // care about. 9946 if (persistent) { 9947 final ContentResolver resolver = mContext.getContentResolver(); 9948 Settings.Global.putString( 9949 resolver, Settings.Global.DEBUG_APP, 9950 packageName); 9951 Settings.Global.putInt( 9952 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9953 waitForDebugger ? 1 : 0); 9954 } 9955 9956 synchronized (this) { 9957 if (!persistent) { 9958 mOrigDebugApp = mDebugApp; 9959 mOrigWaitForDebugger = mWaitForDebugger; 9960 } 9961 mDebugApp = packageName; 9962 mWaitForDebugger = waitForDebugger; 9963 mDebugTransient = !persistent; 9964 if (packageName != null) { 9965 forceStopPackageLocked(packageName, -1, false, false, true, true, 9966 false, UserHandle.USER_ALL, "set debug app"); 9967 } 9968 } 9969 } finally { 9970 Binder.restoreCallingIdentity(ident); 9971 } 9972 } 9973 9974 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9975 synchronized (this) { 9976 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9977 if (!isDebuggable) { 9978 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9979 throw new SecurityException("Process not debuggable: " + app.packageName); 9980 } 9981 } 9982 9983 mOpenGlTraceApp = processName; 9984 } 9985 } 9986 9987 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9988 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9989 synchronized (this) { 9990 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9991 if (!isDebuggable) { 9992 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9993 throw new SecurityException("Process not debuggable: " + app.packageName); 9994 } 9995 } 9996 mProfileApp = processName; 9997 mProfileFile = profileFile; 9998 if (mProfileFd != null) { 9999 try { 10000 mProfileFd.close(); 10001 } catch (IOException e) { 10002 } 10003 mProfileFd = null; 10004 } 10005 mProfileFd = profileFd; 10006 mProfileType = 0; 10007 mAutoStopProfiler = autoStopProfiler; 10008 } 10009 } 10010 10011 @Override 10012 public void setAlwaysFinish(boolean enabled) { 10013 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10014 "setAlwaysFinish()"); 10015 10016 Settings.Global.putInt( 10017 mContext.getContentResolver(), 10018 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10019 10020 synchronized (this) { 10021 mAlwaysFinishActivities = enabled; 10022 } 10023 } 10024 10025 @Override 10026 public void setActivityController(IActivityController controller) { 10027 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10028 "setActivityController()"); 10029 synchronized (this) { 10030 mController = controller; 10031 Watchdog.getInstance().setActivityController(controller); 10032 } 10033 } 10034 10035 @Override 10036 public void setUserIsMonkey(boolean userIsMonkey) { 10037 synchronized (this) { 10038 synchronized (mPidsSelfLocked) { 10039 final int callingPid = Binder.getCallingPid(); 10040 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10041 if (precessRecord == null) { 10042 throw new SecurityException("Unknown process: " + callingPid); 10043 } 10044 if (precessRecord.instrumentationUiAutomationConnection == null) { 10045 throw new SecurityException("Only an instrumentation process " 10046 + "with a UiAutomation can call setUserIsMonkey"); 10047 } 10048 } 10049 mUserIsMonkey = userIsMonkey; 10050 } 10051 } 10052 10053 @Override 10054 public boolean isUserAMonkey() { 10055 synchronized (this) { 10056 // If there is a controller also implies the user is a monkey. 10057 return (mUserIsMonkey || mController != null); 10058 } 10059 } 10060 10061 public void requestBugReport() { 10062 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10063 SystemProperties.set("ctl.start", "bugreport"); 10064 } 10065 10066 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10067 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10068 } 10069 10070 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10071 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10072 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10073 } 10074 return KEY_DISPATCHING_TIMEOUT; 10075 } 10076 10077 @Override 10078 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10079 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10080 != PackageManager.PERMISSION_GRANTED) { 10081 throw new SecurityException("Requires permission " 10082 + android.Manifest.permission.FILTER_EVENTS); 10083 } 10084 ProcessRecord proc; 10085 long timeout; 10086 synchronized (this) { 10087 synchronized (mPidsSelfLocked) { 10088 proc = mPidsSelfLocked.get(pid); 10089 } 10090 timeout = getInputDispatchingTimeoutLocked(proc); 10091 } 10092 10093 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10094 return -1; 10095 } 10096 10097 return timeout; 10098 } 10099 10100 /** 10101 * Handle input dispatching timeouts. 10102 * Returns whether input dispatching should be aborted or not. 10103 */ 10104 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10105 final ActivityRecord activity, final ActivityRecord parent, 10106 final boolean aboveSystem, String reason) { 10107 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10108 != PackageManager.PERMISSION_GRANTED) { 10109 throw new SecurityException("Requires permission " 10110 + android.Manifest.permission.FILTER_EVENTS); 10111 } 10112 10113 final String annotation; 10114 if (reason == null) { 10115 annotation = "Input dispatching timed out"; 10116 } else { 10117 annotation = "Input dispatching timed out (" + reason + ")"; 10118 } 10119 10120 if (proc != null) { 10121 synchronized (this) { 10122 if (proc.debugging) { 10123 return false; 10124 } 10125 10126 if (mDidDexOpt) { 10127 // Give more time since we were dexopting. 10128 mDidDexOpt = false; 10129 return false; 10130 } 10131 10132 if (proc.instrumentationClass != null) { 10133 Bundle info = new Bundle(); 10134 info.putString("shortMsg", "keyDispatchingTimedOut"); 10135 info.putString("longMsg", annotation); 10136 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10137 return true; 10138 } 10139 } 10140 mHandler.post(new Runnable() { 10141 @Override 10142 public void run() { 10143 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10144 } 10145 }); 10146 } 10147 10148 return true; 10149 } 10150 10151 public Bundle getAssistContextExtras(int requestType) { 10152 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10153 "getAssistContextExtras()"); 10154 PendingAssistExtras pae; 10155 Bundle extras = new Bundle(); 10156 synchronized (this) { 10157 ActivityRecord activity = getFocusedStack().mResumedActivity; 10158 if (activity == null) { 10159 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10160 return null; 10161 } 10162 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10163 if (activity.app == null || activity.app.thread == null) { 10164 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10165 return extras; 10166 } 10167 if (activity.app.pid == Binder.getCallingPid()) { 10168 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10169 return extras; 10170 } 10171 pae = new PendingAssistExtras(activity); 10172 try { 10173 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10174 requestType); 10175 mPendingAssistExtras.add(pae); 10176 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10177 } catch (RemoteException e) { 10178 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10179 return extras; 10180 } 10181 } 10182 synchronized (pae) { 10183 while (!pae.haveResult) { 10184 try { 10185 pae.wait(); 10186 } catch (InterruptedException e) { 10187 } 10188 } 10189 if (pae.result != null) { 10190 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10191 } 10192 } 10193 synchronized (this) { 10194 mPendingAssistExtras.remove(pae); 10195 mHandler.removeCallbacks(pae); 10196 } 10197 return extras; 10198 } 10199 10200 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10201 PendingAssistExtras pae = (PendingAssistExtras)token; 10202 synchronized (pae) { 10203 pae.result = extras; 10204 pae.haveResult = true; 10205 pae.notifyAll(); 10206 } 10207 } 10208 10209 public void registerProcessObserver(IProcessObserver observer) { 10210 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10211 "registerProcessObserver()"); 10212 synchronized (this) { 10213 mProcessObservers.register(observer); 10214 } 10215 } 10216 10217 @Override 10218 public void unregisterProcessObserver(IProcessObserver observer) { 10219 synchronized (this) { 10220 mProcessObservers.unregister(observer); 10221 } 10222 } 10223 10224 @Override 10225 public boolean convertFromTranslucent(IBinder token) { 10226 final long origId = Binder.clearCallingIdentity(); 10227 try { 10228 synchronized (this) { 10229 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10230 if (r == null) { 10231 return false; 10232 } 10233 if (r.changeWindowTranslucency(true)) { 10234 mWindowManager.setAppFullscreen(token, true); 10235 r.task.stack.releaseBackgroundResources(); 10236 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10237 return true; 10238 } 10239 return false; 10240 } 10241 } finally { 10242 Binder.restoreCallingIdentity(origId); 10243 } 10244 } 10245 10246 @Override 10247 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10248 final long origId = Binder.clearCallingIdentity(); 10249 try { 10250 synchronized (this) { 10251 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10252 if (r == null) { 10253 return false; 10254 } 10255 int index = r.task.mActivities.lastIndexOf(r); 10256 if (index > 0) { 10257 ActivityRecord under = r.task.mActivities.get(index - 1); 10258 under.returningOptions = options; 10259 } 10260 if (r.changeWindowTranslucency(false)) { 10261 r.task.stack.convertToTranslucent(r); 10262 mWindowManager.setAppFullscreen(token, false); 10263 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10264 return true; 10265 } else { 10266 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10267 return false; 10268 } 10269 } 10270 } finally { 10271 Binder.restoreCallingIdentity(origId); 10272 } 10273 } 10274 10275 @Override 10276 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10277 final long origId = Binder.clearCallingIdentity(); 10278 try { 10279 synchronized (this) { 10280 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10281 if (r != null) { 10282 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10283 } 10284 } 10285 return false; 10286 } finally { 10287 Binder.restoreCallingIdentity(origId); 10288 } 10289 } 10290 10291 @Override 10292 public boolean isBackgroundVisibleBehind(IBinder token) { 10293 final long origId = Binder.clearCallingIdentity(); 10294 try { 10295 synchronized (this) { 10296 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10297 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10298 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10299 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10300 return visible; 10301 } 10302 } finally { 10303 Binder.restoreCallingIdentity(origId); 10304 } 10305 } 10306 10307 @Override 10308 public ActivityOptions getActivityOptions(IBinder token) { 10309 final long origId = Binder.clearCallingIdentity(); 10310 try { 10311 synchronized (this) { 10312 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10313 if (r != null) { 10314 final ActivityOptions activityOptions = r.pendingOptions; 10315 r.pendingOptions = null; 10316 return activityOptions; 10317 } 10318 return null; 10319 } 10320 } finally { 10321 Binder.restoreCallingIdentity(origId); 10322 } 10323 } 10324 10325 @Override 10326 public void setImmersive(IBinder token, boolean immersive) { 10327 synchronized(this) { 10328 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10329 if (r == null) { 10330 throw new IllegalArgumentException(); 10331 } 10332 r.immersive = immersive; 10333 10334 // update associated state if we're frontmost 10335 if (r == mFocusedActivity) { 10336 if (DEBUG_IMMERSIVE) { 10337 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10338 } 10339 applyUpdateLockStateLocked(r); 10340 } 10341 } 10342 } 10343 10344 @Override 10345 public boolean isImmersive(IBinder token) { 10346 synchronized (this) { 10347 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10348 if (r == null) { 10349 throw new IllegalArgumentException(); 10350 } 10351 return r.immersive; 10352 } 10353 } 10354 10355 public boolean isTopActivityImmersive() { 10356 enforceNotIsolatedCaller("startActivity"); 10357 synchronized (this) { 10358 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10359 return (r != null) ? r.immersive : false; 10360 } 10361 } 10362 10363 @Override 10364 public boolean isTopOfTask(IBinder token) { 10365 synchronized (this) { 10366 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10367 if (r == null) { 10368 throw new IllegalArgumentException(); 10369 } 10370 return r.task.getTopActivity() == r; 10371 } 10372 } 10373 10374 public final void enterSafeMode() { 10375 synchronized(this) { 10376 // It only makes sense to do this before the system is ready 10377 // and started launching other packages. 10378 if (!mSystemReady) { 10379 try { 10380 AppGlobals.getPackageManager().enterSafeMode(); 10381 } catch (RemoteException e) { 10382 } 10383 } 10384 10385 mSafeMode = true; 10386 } 10387 } 10388 10389 public final void showSafeModeOverlay() { 10390 View v = LayoutInflater.from(mContext).inflate( 10391 com.android.internal.R.layout.safe_mode, null); 10392 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10393 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10394 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10395 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10396 lp.gravity = Gravity.BOTTOM | Gravity.START; 10397 lp.format = v.getBackground().getOpacity(); 10398 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10399 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10400 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10401 ((WindowManager)mContext.getSystemService( 10402 Context.WINDOW_SERVICE)).addView(v, lp); 10403 } 10404 10405 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10406 if (!(sender instanceof PendingIntentRecord)) { 10407 return; 10408 } 10409 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10410 synchronized (stats) { 10411 if (mBatteryStatsService.isOnBattery()) { 10412 mBatteryStatsService.enforceCallingPermission(); 10413 PendingIntentRecord rec = (PendingIntentRecord)sender; 10414 int MY_UID = Binder.getCallingUid(); 10415 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10416 BatteryStatsImpl.Uid.Pkg pkg = 10417 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10418 sourcePkg != null ? sourcePkg : rec.key.packageName); 10419 pkg.incWakeupsLocked(); 10420 } 10421 } 10422 } 10423 10424 public boolean killPids(int[] pids, String pReason, boolean secure) { 10425 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10426 throw new SecurityException("killPids only available to the system"); 10427 } 10428 String reason = (pReason == null) ? "Unknown" : pReason; 10429 // XXX Note: don't acquire main activity lock here, because the window 10430 // manager calls in with its locks held. 10431 10432 boolean killed = false; 10433 synchronized (mPidsSelfLocked) { 10434 int[] types = new int[pids.length]; 10435 int worstType = 0; 10436 for (int i=0; i<pids.length; i++) { 10437 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10438 if (proc != null) { 10439 int type = proc.setAdj; 10440 types[i] = type; 10441 if (type > worstType) { 10442 worstType = type; 10443 } 10444 } 10445 } 10446 10447 // If the worst oom_adj is somewhere in the cached proc LRU range, 10448 // then constrain it so we will kill all cached procs. 10449 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10450 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10451 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10452 } 10453 10454 // If this is not a secure call, don't let it kill processes that 10455 // are important. 10456 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10457 worstType = ProcessList.SERVICE_ADJ; 10458 } 10459 10460 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10461 for (int i=0; i<pids.length; i++) { 10462 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10463 if (proc == null) { 10464 continue; 10465 } 10466 int adj = proc.setAdj; 10467 if (adj >= worstType && !proc.killedByAm) { 10468 proc.kill(reason, true); 10469 killed = true; 10470 } 10471 } 10472 } 10473 return killed; 10474 } 10475 10476 @Override 10477 public void killUid(int uid, String reason) { 10478 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10479 throw new SecurityException("killUid only available to the system"); 10480 } 10481 synchronized (this) { 10482 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10483 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10484 reason != null ? reason : "kill uid"); 10485 } 10486 } 10487 10488 @Override 10489 public boolean killProcessesBelowForeground(String reason) { 10490 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10491 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10492 } 10493 10494 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10495 } 10496 10497 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10498 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10499 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10500 } 10501 10502 boolean killed = false; 10503 synchronized (mPidsSelfLocked) { 10504 final int size = mPidsSelfLocked.size(); 10505 for (int i = 0; i < size; i++) { 10506 final int pid = mPidsSelfLocked.keyAt(i); 10507 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10508 if (proc == null) continue; 10509 10510 final int adj = proc.setAdj; 10511 if (adj > belowAdj && !proc.killedByAm) { 10512 proc.kill(reason, true); 10513 killed = true; 10514 } 10515 } 10516 } 10517 return killed; 10518 } 10519 10520 @Override 10521 public void hang(final IBinder who, boolean allowRestart) { 10522 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10523 != PackageManager.PERMISSION_GRANTED) { 10524 throw new SecurityException("Requires permission " 10525 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10526 } 10527 10528 final IBinder.DeathRecipient death = new DeathRecipient() { 10529 @Override 10530 public void binderDied() { 10531 synchronized (this) { 10532 notifyAll(); 10533 } 10534 } 10535 }; 10536 10537 try { 10538 who.linkToDeath(death, 0); 10539 } catch (RemoteException e) { 10540 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10541 return; 10542 } 10543 10544 synchronized (this) { 10545 Watchdog.getInstance().setAllowRestart(allowRestart); 10546 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10547 synchronized (death) { 10548 while (who.isBinderAlive()) { 10549 try { 10550 death.wait(); 10551 } catch (InterruptedException e) { 10552 } 10553 } 10554 } 10555 Watchdog.getInstance().setAllowRestart(true); 10556 } 10557 } 10558 10559 @Override 10560 public void restart() { 10561 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10562 != PackageManager.PERMISSION_GRANTED) { 10563 throw new SecurityException("Requires permission " 10564 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10565 } 10566 10567 Log.i(TAG, "Sending shutdown broadcast..."); 10568 10569 BroadcastReceiver br = new BroadcastReceiver() { 10570 @Override public void onReceive(Context context, Intent intent) { 10571 // Now the broadcast is done, finish up the low-level shutdown. 10572 Log.i(TAG, "Shutting down activity manager..."); 10573 shutdown(10000); 10574 Log.i(TAG, "Shutdown complete, restarting!"); 10575 Process.killProcess(Process.myPid()); 10576 System.exit(10); 10577 } 10578 }; 10579 10580 // First send the high-level shut down broadcast. 10581 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10582 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10583 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10584 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10585 mContext.sendOrderedBroadcastAsUser(intent, 10586 UserHandle.ALL, null, br, mHandler, 0, null, null); 10587 */ 10588 br.onReceive(mContext, intent); 10589 } 10590 10591 private long getLowRamTimeSinceIdle(long now) { 10592 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10593 } 10594 10595 @Override 10596 public void performIdleMaintenance() { 10597 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10598 != PackageManager.PERMISSION_GRANTED) { 10599 throw new SecurityException("Requires permission " 10600 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10601 } 10602 10603 synchronized (this) { 10604 final long now = SystemClock.uptimeMillis(); 10605 final long timeSinceLastIdle = now - mLastIdleTime; 10606 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10607 mLastIdleTime = now; 10608 mLowRamTimeSinceLastIdle = 0; 10609 if (mLowRamStartTime != 0) { 10610 mLowRamStartTime = now; 10611 } 10612 10613 StringBuilder sb = new StringBuilder(128); 10614 sb.append("Idle maintenance over "); 10615 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10616 sb.append(" low RAM for "); 10617 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10618 Slog.i(TAG, sb.toString()); 10619 10620 // If at least 1/3 of our time since the last idle period has been spent 10621 // with RAM low, then we want to kill processes. 10622 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10623 10624 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10625 ProcessRecord proc = mLruProcesses.get(i); 10626 if (proc.notCachedSinceIdle) { 10627 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10628 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10629 if (doKilling && proc.initialIdlePss != 0 10630 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10631 proc.kill("idle maint (pss " + proc.lastPss 10632 + " from " + proc.initialIdlePss + ")", true); 10633 } 10634 } 10635 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10636 proc.notCachedSinceIdle = true; 10637 proc.initialIdlePss = 0; 10638 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10639 isSleeping(), now); 10640 } 10641 } 10642 10643 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10644 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10645 } 10646 } 10647 10648 private void retrieveSettings() { 10649 final ContentResolver resolver = mContext.getContentResolver(); 10650 String debugApp = Settings.Global.getString( 10651 resolver, Settings.Global.DEBUG_APP); 10652 boolean waitForDebugger = Settings.Global.getInt( 10653 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10654 boolean alwaysFinishActivities = Settings.Global.getInt( 10655 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10656 boolean forceRtl = Settings.Global.getInt( 10657 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10658 // Transfer any global setting for forcing RTL layout, into a System Property 10659 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10660 10661 Configuration configuration = new Configuration(); 10662 Settings.System.getConfiguration(resolver, configuration); 10663 if (forceRtl) { 10664 // This will take care of setting the correct layout direction flags 10665 configuration.setLayoutDirection(configuration.locale); 10666 } 10667 10668 synchronized (this) { 10669 mDebugApp = mOrigDebugApp = debugApp; 10670 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10671 mAlwaysFinishActivities = alwaysFinishActivities; 10672 // This happens before any activities are started, so we can 10673 // change mConfiguration in-place. 10674 updateConfigurationLocked(configuration, null, false, true); 10675 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10676 } 10677 } 10678 10679 public boolean testIsSystemReady() { 10680 // no need to synchronize(this) just to read & return the value 10681 return mSystemReady; 10682 } 10683 10684 private static File getCalledPreBootReceiversFile() { 10685 File dataDir = Environment.getDataDirectory(); 10686 File systemDir = new File(dataDir, "system"); 10687 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10688 return fname; 10689 } 10690 10691 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10692 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10693 File file = getCalledPreBootReceiversFile(); 10694 FileInputStream fis = null; 10695 try { 10696 fis = new FileInputStream(file); 10697 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10698 int fvers = dis.readInt(); 10699 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10700 String vers = dis.readUTF(); 10701 String codename = dis.readUTF(); 10702 String build = dis.readUTF(); 10703 if (android.os.Build.VERSION.RELEASE.equals(vers) 10704 && android.os.Build.VERSION.CODENAME.equals(codename) 10705 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10706 int num = dis.readInt(); 10707 while (num > 0) { 10708 num--; 10709 String pkg = dis.readUTF(); 10710 String cls = dis.readUTF(); 10711 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10712 } 10713 } 10714 } 10715 } catch (FileNotFoundException e) { 10716 } catch (IOException e) { 10717 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10718 } finally { 10719 if (fis != null) { 10720 try { 10721 fis.close(); 10722 } catch (IOException e) { 10723 } 10724 } 10725 } 10726 return lastDoneReceivers; 10727 } 10728 10729 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10730 File file = getCalledPreBootReceiversFile(); 10731 FileOutputStream fos = null; 10732 DataOutputStream dos = null; 10733 try { 10734 fos = new FileOutputStream(file); 10735 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10736 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10737 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10738 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10739 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10740 dos.writeInt(list.size()); 10741 for (int i=0; i<list.size(); i++) { 10742 dos.writeUTF(list.get(i).getPackageName()); 10743 dos.writeUTF(list.get(i).getClassName()); 10744 } 10745 } catch (IOException e) { 10746 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10747 file.delete(); 10748 } finally { 10749 FileUtils.sync(fos); 10750 if (dos != null) { 10751 try { 10752 dos.close(); 10753 } catch (IOException e) { 10754 // TODO Auto-generated catch block 10755 e.printStackTrace(); 10756 } 10757 } 10758 } 10759 } 10760 10761 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10762 ArrayList<ComponentName> doneReceivers, int userId) { 10763 boolean waitingUpdate = false; 10764 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10765 List<ResolveInfo> ris = null; 10766 try { 10767 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10768 intent, null, 0, userId); 10769 } catch (RemoteException e) { 10770 } 10771 if (ris != null) { 10772 for (int i=ris.size()-1; i>=0; i--) { 10773 if ((ris.get(i).activityInfo.applicationInfo.flags 10774 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10775 ris.remove(i); 10776 } 10777 } 10778 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10779 10780 // For User 0, load the version number. When delivering to a new user, deliver 10781 // to all receivers. 10782 if (userId == UserHandle.USER_OWNER) { 10783 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10784 for (int i=0; i<ris.size(); i++) { 10785 ActivityInfo ai = ris.get(i).activityInfo; 10786 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10787 if (lastDoneReceivers.contains(comp)) { 10788 // We already did the pre boot receiver for this app with the current 10789 // platform version, so don't do it again... 10790 ris.remove(i); 10791 i--; 10792 // ...however, do keep it as one that has been done, so we don't 10793 // forget about it when rewriting the file of last done receivers. 10794 doneReceivers.add(comp); 10795 } 10796 } 10797 } 10798 10799 // If primary user, send broadcast to all available users, else just to userId 10800 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10801 : new int[] { userId }; 10802 for (int i = 0; i < ris.size(); i++) { 10803 ActivityInfo ai = ris.get(i).activityInfo; 10804 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10805 doneReceivers.add(comp); 10806 intent.setComponent(comp); 10807 for (int j=0; j<users.length; j++) { 10808 IIntentReceiver finisher = null; 10809 // On last receiver and user, set up a completion callback 10810 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10811 finisher = new IIntentReceiver.Stub() { 10812 public void performReceive(Intent intent, int resultCode, 10813 String data, Bundle extras, boolean ordered, 10814 boolean sticky, int sendingUser) { 10815 // The raw IIntentReceiver interface is called 10816 // with the AM lock held, so redispatch to 10817 // execute our code without the lock. 10818 mHandler.post(onFinishCallback); 10819 } 10820 }; 10821 } 10822 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10823 + " for user " + users[j]); 10824 broadcastIntentLocked(null, null, intent, null, finisher, 10825 0, null, null, null, AppOpsManager.OP_NONE, 10826 true, false, MY_PID, Process.SYSTEM_UID, 10827 users[j]); 10828 if (finisher != null) { 10829 waitingUpdate = true; 10830 } 10831 } 10832 } 10833 } 10834 10835 return waitingUpdate; 10836 } 10837 10838 public void systemReady(final Runnable goingCallback) { 10839 synchronized(this) { 10840 if (mSystemReady) { 10841 // If we're done calling all the receivers, run the next "boot phase" passed in 10842 // by the SystemServer 10843 if (goingCallback != null) { 10844 goingCallback.run(); 10845 } 10846 return; 10847 } 10848 10849 // Make sure we have the current profile info, since it is needed for 10850 // security checks. 10851 updateCurrentProfileIdsLocked(); 10852 10853 if (mRecentTasks == null) { 10854 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10855 if (!mRecentTasks.isEmpty()) { 10856 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10857 } 10858 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10859 mTaskPersister.startPersisting(); 10860 } 10861 10862 // Check to see if there are any update receivers to run. 10863 if (!mDidUpdate) { 10864 if (mWaitingUpdate) { 10865 return; 10866 } 10867 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10868 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10869 public void run() { 10870 synchronized (ActivityManagerService.this) { 10871 mDidUpdate = true; 10872 } 10873 writeLastDonePreBootReceivers(doneReceivers); 10874 showBootMessage(mContext.getText( 10875 R.string.android_upgrading_complete), 10876 false); 10877 systemReady(goingCallback); 10878 } 10879 }, doneReceivers, UserHandle.USER_OWNER); 10880 10881 if (mWaitingUpdate) { 10882 return; 10883 } 10884 mDidUpdate = true; 10885 } 10886 10887 mAppOpsService.systemReady(); 10888 mSystemReady = true; 10889 } 10890 10891 ArrayList<ProcessRecord> procsToKill = null; 10892 synchronized(mPidsSelfLocked) { 10893 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10894 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10895 if (!isAllowedWhileBooting(proc.info)){ 10896 if (procsToKill == null) { 10897 procsToKill = new ArrayList<ProcessRecord>(); 10898 } 10899 procsToKill.add(proc); 10900 } 10901 } 10902 } 10903 10904 synchronized(this) { 10905 if (procsToKill != null) { 10906 for (int i=procsToKill.size()-1; i>=0; i--) { 10907 ProcessRecord proc = procsToKill.get(i); 10908 Slog.i(TAG, "Removing system update proc: " + proc); 10909 removeProcessLocked(proc, true, false, "system update done"); 10910 } 10911 } 10912 10913 // Now that we have cleaned up any update processes, we 10914 // are ready to start launching real processes and know that 10915 // we won't trample on them any more. 10916 mProcessesReady = true; 10917 } 10918 10919 Slog.i(TAG, "System now ready"); 10920 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10921 SystemClock.uptimeMillis()); 10922 10923 synchronized(this) { 10924 // Make sure we have no pre-ready processes sitting around. 10925 10926 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10927 ResolveInfo ri = mContext.getPackageManager() 10928 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10929 STOCK_PM_FLAGS); 10930 CharSequence errorMsg = null; 10931 if (ri != null) { 10932 ActivityInfo ai = ri.activityInfo; 10933 ApplicationInfo app = ai.applicationInfo; 10934 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10935 mTopAction = Intent.ACTION_FACTORY_TEST; 10936 mTopData = null; 10937 mTopComponent = new ComponentName(app.packageName, 10938 ai.name); 10939 } else { 10940 errorMsg = mContext.getResources().getText( 10941 com.android.internal.R.string.factorytest_not_system); 10942 } 10943 } else { 10944 errorMsg = mContext.getResources().getText( 10945 com.android.internal.R.string.factorytest_no_action); 10946 } 10947 if (errorMsg != null) { 10948 mTopAction = null; 10949 mTopData = null; 10950 mTopComponent = null; 10951 Message msg = Message.obtain(); 10952 msg.what = SHOW_FACTORY_ERROR_MSG; 10953 msg.getData().putCharSequence("msg", errorMsg); 10954 mHandler.sendMessage(msg); 10955 } 10956 } 10957 } 10958 10959 retrieveSettings(); 10960 10961 synchronized (this) { 10962 readGrantedUriPermissionsLocked(); 10963 } 10964 10965 if (goingCallback != null) goingCallback.run(); 10966 10967 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10968 Integer.toString(mCurrentUserId), mCurrentUserId); 10969 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10970 Integer.toString(mCurrentUserId), mCurrentUserId); 10971 mSystemServiceManager.startUser(mCurrentUserId); 10972 10973 synchronized (this) { 10974 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10975 try { 10976 List apps = AppGlobals.getPackageManager(). 10977 getPersistentApplications(STOCK_PM_FLAGS); 10978 if (apps != null) { 10979 int N = apps.size(); 10980 int i; 10981 for (i=0; i<N; i++) { 10982 ApplicationInfo info 10983 = (ApplicationInfo)apps.get(i); 10984 if (info != null && 10985 !info.packageName.equals("android")) { 10986 addAppLocked(info, false, null /* ABI override */); 10987 } 10988 } 10989 } 10990 } catch (RemoteException ex) { 10991 // pm is in same process, this will never happen. 10992 } 10993 } 10994 10995 // Start up initial activity. 10996 mBooting = true; 10997 10998 try { 10999 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11000 Message msg = Message.obtain(); 11001 msg.what = SHOW_UID_ERROR_MSG; 11002 mHandler.sendMessage(msg); 11003 } 11004 } catch (RemoteException e) { 11005 } 11006 11007 long ident = Binder.clearCallingIdentity(); 11008 try { 11009 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11010 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11011 | Intent.FLAG_RECEIVER_FOREGROUND); 11012 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11013 broadcastIntentLocked(null, null, intent, 11014 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11015 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11016 intent = new Intent(Intent.ACTION_USER_STARTING); 11017 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11018 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11019 broadcastIntentLocked(null, null, intent, 11020 null, new IIntentReceiver.Stub() { 11021 @Override 11022 public void performReceive(Intent intent, int resultCode, String data, 11023 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11024 throws RemoteException { 11025 } 11026 }, 0, null, null, 11027 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11028 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11029 } catch (Throwable t) { 11030 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11031 } finally { 11032 Binder.restoreCallingIdentity(ident); 11033 } 11034 mStackSupervisor.resumeTopActivitiesLocked(); 11035 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11036 } 11037 } 11038 11039 private boolean makeAppCrashingLocked(ProcessRecord app, 11040 String shortMsg, String longMsg, String stackTrace) { 11041 app.crashing = true; 11042 app.crashingReport = generateProcessError(app, 11043 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11044 startAppProblemLocked(app); 11045 app.stopFreezingAllLocked(); 11046 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11047 } 11048 11049 private void makeAppNotRespondingLocked(ProcessRecord app, 11050 String activity, String shortMsg, String longMsg) { 11051 app.notResponding = true; 11052 app.notRespondingReport = generateProcessError(app, 11053 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11054 activity, shortMsg, longMsg, null); 11055 startAppProblemLocked(app); 11056 app.stopFreezingAllLocked(); 11057 } 11058 11059 /** 11060 * Generate a process error record, suitable for attachment to a ProcessRecord. 11061 * 11062 * @param app The ProcessRecord in which the error occurred. 11063 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11064 * ActivityManager.AppErrorStateInfo 11065 * @param activity The activity associated with the crash, if known. 11066 * @param shortMsg Short message describing the crash. 11067 * @param longMsg Long message describing the crash. 11068 * @param stackTrace Full crash stack trace, may be null. 11069 * 11070 * @return Returns a fully-formed AppErrorStateInfo record. 11071 */ 11072 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11073 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11074 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11075 11076 report.condition = condition; 11077 report.processName = app.processName; 11078 report.pid = app.pid; 11079 report.uid = app.info.uid; 11080 report.tag = activity; 11081 report.shortMsg = shortMsg; 11082 report.longMsg = longMsg; 11083 report.stackTrace = stackTrace; 11084 11085 return report; 11086 } 11087 11088 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11089 synchronized (this) { 11090 app.crashing = false; 11091 app.crashingReport = null; 11092 app.notResponding = false; 11093 app.notRespondingReport = null; 11094 if (app.anrDialog == fromDialog) { 11095 app.anrDialog = null; 11096 } 11097 if (app.waitDialog == fromDialog) { 11098 app.waitDialog = null; 11099 } 11100 if (app.pid > 0 && app.pid != MY_PID) { 11101 handleAppCrashLocked(app, null, null, null); 11102 app.kill("user request after error", true); 11103 } 11104 } 11105 } 11106 11107 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11108 String stackTrace) { 11109 long now = SystemClock.uptimeMillis(); 11110 11111 Long crashTime; 11112 if (!app.isolated) { 11113 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11114 } else { 11115 crashTime = null; 11116 } 11117 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11118 // This process loses! 11119 Slog.w(TAG, "Process " + app.info.processName 11120 + " has crashed too many times: killing!"); 11121 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11122 app.userId, app.info.processName, app.uid); 11123 mStackSupervisor.handleAppCrashLocked(app); 11124 if (!app.persistent) { 11125 // We don't want to start this process again until the user 11126 // explicitly does so... but for persistent process, we really 11127 // need to keep it running. If a persistent process is actually 11128 // repeatedly crashing, then badness for everyone. 11129 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11130 app.info.processName); 11131 if (!app.isolated) { 11132 // XXX We don't have a way to mark isolated processes 11133 // as bad, since they don't have a peristent identity. 11134 mBadProcesses.put(app.info.processName, app.uid, 11135 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11136 mProcessCrashTimes.remove(app.info.processName, app.uid); 11137 } 11138 app.bad = true; 11139 app.removed = true; 11140 // Don't let services in this process be restarted and potentially 11141 // annoy the user repeatedly. Unless it is persistent, since those 11142 // processes run critical code. 11143 removeProcessLocked(app, false, false, "crash"); 11144 mStackSupervisor.resumeTopActivitiesLocked(); 11145 return false; 11146 } 11147 mStackSupervisor.resumeTopActivitiesLocked(); 11148 } else { 11149 mStackSupervisor.finishTopRunningActivityLocked(app); 11150 } 11151 11152 // Bump up the crash count of any services currently running in the proc. 11153 for (int i=app.services.size()-1; i>=0; i--) { 11154 // Any services running in the application need to be placed 11155 // back in the pending list. 11156 ServiceRecord sr = app.services.valueAt(i); 11157 sr.crashCount++; 11158 } 11159 11160 // If the crashing process is what we consider to be the "home process" and it has been 11161 // replaced by a third-party app, clear the package preferred activities from packages 11162 // with a home activity running in the process to prevent a repeatedly crashing app 11163 // from blocking the user to manually clear the list. 11164 final ArrayList<ActivityRecord> activities = app.activities; 11165 if (app == mHomeProcess && activities.size() > 0 11166 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11167 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11168 final ActivityRecord r = activities.get(activityNdx); 11169 if (r.isHomeActivity()) { 11170 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11171 try { 11172 ActivityThread.getPackageManager() 11173 .clearPackagePreferredActivities(r.packageName); 11174 } catch (RemoteException c) { 11175 // pm is in same process, this will never happen. 11176 } 11177 } 11178 } 11179 } 11180 11181 if (!app.isolated) { 11182 // XXX Can't keep track of crash times for isolated processes, 11183 // because they don't have a perisistent identity. 11184 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11185 } 11186 11187 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11188 return true; 11189 } 11190 11191 void startAppProblemLocked(ProcessRecord app) { 11192 // If this app is not running under the current user, then we 11193 // can't give it a report button because that would require 11194 // launching the report UI under a different user. 11195 app.errorReportReceiver = null; 11196 11197 for (int userId : mCurrentProfileIds) { 11198 if (app.userId == userId) { 11199 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11200 mContext, app.info.packageName, app.info.flags); 11201 } 11202 } 11203 skipCurrentReceiverLocked(app); 11204 } 11205 11206 void skipCurrentReceiverLocked(ProcessRecord app) { 11207 for (BroadcastQueue queue : mBroadcastQueues) { 11208 queue.skipCurrentReceiverLocked(app); 11209 } 11210 } 11211 11212 /** 11213 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11214 * The application process will exit immediately after this call returns. 11215 * @param app object of the crashing app, null for the system server 11216 * @param crashInfo describing the exception 11217 */ 11218 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11219 ProcessRecord r = findAppProcess(app, "Crash"); 11220 final String processName = app == null ? "system_server" 11221 : (r == null ? "unknown" : r.processName); 11222 11223 handleApplicationCrashInner("crash", r, processName, crashInfo); 11224 } 11225 11226 /* Native crash reporting uses this inner version because it needs to be somewhat 11227 * decoupled from the AM-managed cleanup lifecycle 11228 */ 11229 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11230 ApplicationErrorReport.CrashInfo crashInfo) { 11231 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11232 UserHandle.getUserId(Binder.getCallingUid()), processName, 11233 r == null ? -1 : r.info.flags, 11234 crashInfo.exceptionClassName, 11235 crashInfo.exceptionMessage, 11236 crashInfo.throwFileName, 11237 crashInfo.throwLineNumber); 11238 11239 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11240 11241 crashApplication(r, crashInfo); 11242 } 11243 11244 public void handleApplicationStrictModeViolation( 11245 IBinder app, 11246 int violationMask, 11247 StrictMode.ViolationInfo info) { 11248 ProcessRecord r = findAppProcess(app, "StrictMode"); 11249 if (r == null) { 11250 return; 11251 } 11252 11253 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11254 Integer stackFingerprint = info.hashCode(); 11255 boolean logIt = true; 11256 synchronized (mAlreadyLoggedViolatedStacks) { 11257 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11258 logIt = false; 11259 // TODO: sub-sample into EventLog for these, with 11260 // the info.durationMillis? Then we'd get 11261 // the relative pain numbers, without logging all 11262 // the stack traces repeatedly. We'd want to do 11263 // likewise in the client code, which also does 11264 // dup suppression, before the Binder call. 11265 } else { 11266 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11267 mAlreadyLoggedViolatedStacks.clear(); 11268 } 11269 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11270 } 11271 } 11272 if (logIt) { 11273 logStrictModeViolationToDropBox(r, info); 11274 } 11275 } 11276 11277 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11278 AppErrorResult result = new AppErrorResult(); 11279 synchronized (this) { 11280 final long origId = Binder.clearCallingIdentity(); 11281 11282 Message msg = Message.obtain(); 11283 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11284 HashMap<String, Object> data = new HashMap<String, Object>(); 11285 data.put("result", result); 11286 data.put("app", r); 11287 data.put("violationMask", violationMask); 11288 data.put("info", info); 11289 msg.obj = data; 11290 mHandler.sendMessage(msg); 11291 11292 Binder.restoreCallingIdentity(origId); 11293 } 11294 int res = result.get(); 11295 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11296 } 11297 } 11298 11299 // Depending on the policy in effect, there could be a bunch of 11300 // these in quick succession so we try to batch these together to 11301 // minimize disk writes, number of dropbox entries, and maximize 11302 // compression, by having more fewer, larger records. 11303 private void logStrictModeViolationToDropBox( 11304 ProcessRecord process, 11305 StrictMode.ViolationInfo info) { 11306 if (info == null) { 11307 return; 11308 } 11309 final boolean isSystemApp = process == null || 11310 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11311 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11312 final String processName = process == null ? "unknown" : process.processName; 11313 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11314 final DropBoxManager dbox = (DropBoxManager) 11315 mContext.getSystemService(Context.DROPBOX_SERVICE); 11316 11317 // Exit early if the dropbox isn't configured to accept this report type. 11318 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11319 11320 boolean bufferWasEmpty; 11321 boolean needsFlush; 11322 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11323 synchronized (sb) { 11324 bufferWasEmpty = sb.length() == 0; 11325 appendDropBoxProcessHeaders(process, processName, sb); 11326 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11327 sb.append("System-App: ").append(isSystemApp).append("\n"); 11328 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11329 if (info.violationNumThisLoop != 0) { 11330 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11331 } 11332 if (info.numAnimationsRunning != 0) { 11333 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11334 } 11335 if (info.broadcastIntentAction != null) { 11336 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11337 } 11338 if (info.durationMillis != -1) { 11339 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11340 } 11341 if (info.numInstances != -1) { 11342 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11343 } 11344 if (info.tags != null) { 11345 for (String tag : info.tags) { 11346 sb.append("Span-Tag: ").append(tag).append("\n"); 11347 } 11348 } 11349 sb.append("\n"); 11350 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11351 sb.append(info.crashInfo.stackTrace); 11352 } 11353 sb.append("\n"); 11354 11355 // Only buffer up to ~64k. Various logging bits truncate 11356 // things at 128k. 11357 needsFlush = (sb.length() > 64 * 1024); 11358 } 11359 11360 // Flush immediately if the buffer's grown too large, or this 11361 // is a non-system app. Non-system apps are isolated with a 11362 // different tag & policy and not batched. 11363 // 11364 // Batching is useful during internal testing with 11365 // StrictMode settings turned up high. Without batching, 11366 // thousands of separate files could be created on boot. 11367 if (!isSystemApp || needsFlush) { 11368 new Thread("Error dump: " + dropboxTag) { 11369 @Override 11370 public void run() { 11371 String report; 11372 synchronized (sb) { 11373 report = sb.toString(); 11374 sb.delete(0, sb.length()); 11375 sb.trimToSize(); 11376 } 11377 if (report.length() != 0) { 11378 dbox.addText(dropboxTag, report); 11379 } 11380 } 11381 }.start(); 11382 return; 11383 } 11384 11385 // System app batching: 11386 if (!bufferWasEmpty) { 11387 // An existing dropbox-writing thread is outstanding, so 11388 // we don't need to start it up. The existing thread will 11389 // catch the buffer appends we just did. 11390 return; 11391 } 11392 11393 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11394 // (After this point, we shouldn't access AMS internal data structures.) 11395 new Thread("Error dump: " + dropboxTag) { 11396 @Override 11397 public void run() { 11398 // 5 second sleep to let stacks arrive and be batched together 11399 try { 11400 Thread.sleep(5000); // 5 seconds 11401 } catch (InterruptedException e) {} 11402 11403 String errorReport; 11404 synchronized (mStrictModeBuffer) { 11405 errorReport = mStrictModeBuffer.toString(); 11406 if (errorReport.length() == 0) { 11407 return; 11408 } 11409 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11410 mStrictModeBuffer.trimToSize(); 11411 } 11412 dbox.addText(dropboxTag, errorReport); 11413 } 11414 }.start(); 11415 } 11416 11417 /** 11418 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11419 * @param app object of the crashing app, null for the system server 11420 * @param tag reported by the caller 11421 * @param crashInfo describing the context of the error 11422 * @return true if the process should exit immediately (WTF is fatal) 11423 */ 11424 public boolean handleApplicationWtf(IBinder app, String tag, 11425 ApplicationErrorReport.CrashInfo crashInfo) { 11426 ProcessRecord r = findAppProcess(app, "WTF"); 11427 final String processName = app == null ? "system_server" 11428 : (r == null ? "unknown" : r.processName); 11429 11430 EventLog.writeEvent(EventLogTags.AM_WTF, 11431 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11432 processName, 11433 r == null ? -1 : r.info.flags, 11434 tag, crashInfo.exceptionMessage); 11435 11436 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11437 11438 if (r != null && r.pid != Process.myPid() && 11439 Settings.Global.getInt(mContext.getContentResolver(), 11440 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11441 crashApplication(r, crashInfo); 11442 return true; 11443 } else { 11444 return false; 11445 } 11446 } 11447 11448 /** 11449 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11450 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11451 */ 11452 private ProcessRecord findAppProcess(IBinder app, String reason) { 11453 if (app == null) { 11454 return null; 11455 } 11456 11457 synchronized (this) { 11458 final int NP = mProcessNames.getMap().size(); 11459 for (int ip=0; ip<NP; ip++) { 11460 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11461 final int NA = apps.size(); 11462 for (int ia=0; ia<NA; ia++) { 11463 ProcessRecord p = apps.valueAt(ia); 11464 if (p.thread != null && p.thread.asBinder() == app) { 11465 return p; 11466 } 11467 } 11468 } 11469 11470 Slog.w(TAG, "Can't find mystery application for " + reason 11471 + " from pid=" + Binder.getCallingPid() 11472 + " uid=" + Binder.getCallingUid() + ": " + app); 11473 return null; 11474 } 11475 } 11476 11477 /** 11478 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11479 * to append various headers to the dropbox log text. 11480 */ 11481 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11482 StringBuilder sb) { 11483 // Watchdog thread ends up invoking this function (with 11484 // a null ProcessRecord) to add the stack file to dropbox. 11485 // Do not acquire a lock on this (am) in such cases, as it 11486 // could cause a potential deadlock, if and when watchdog 11487 // is invoked due to unavailability of lock on am and it 11488 // would prevent watchdog from killing system_server. 11489 if (process == null) { 11490 sb.append("Process: ").append(processName).append("\n"); 11491 return; 11492 } 11493 // Note: ProcessRecord 'process' is guarded by the service 11494 // instance. (notably process.pkgList, which could otherwise change 11495 // concurrently during execution of this method) 11496 synchronized (this) { 11497 sb.append("Process: ").append(processName).append("\n"); 11498 int flags = process.info.flags; 11499 IPackageManager pm = AppGlobals.getPackageManager(); 11500 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11501 for (int ip=0; ip<process.pkgList.size(); ip++) { 11502 String pkg = process.pkgList.keyAt(ip); 11503 sb.append("Package: ").append(pkg); 11504 try { 11505 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11506 if (pi != null) { 11507 sb.append(" v").append(pi.versionCode); 11508 if (pi.versionName != null) { 11509 sb.append(" (").append(pi.versionName).append(")"); 11510 } 11511 } 11512 } catch (RemoteException e) { 11513 Slog.e(TAG, "Error getting package info: " + pkg, e); 11514 } 11515 sb.append("\n"); 11516 } 11517 } 11518 } 11519 11520 private static String processClass(ProcessRecord process) { 11521 if (process == null || process.pid == MY_PID) { 11522 return "system_server"; 11523 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11524 return "system_app"; 11525 } else { 11526 return "data_app"; 11527 } 11528 } 11529 11530 /** 11531 * Write a description of an error (crash, WTF, ANR) to the drop box. 11532 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11533 * @param process which caused the error, null means the system server 11534 * @param activity which triggered the error, null if unknown 11535 * @param parent activity related to the error, null if unknown 11536 * @param subject line related to the error, null if absent 11537 * @param report in long form describing the error, null if absent 11538 * @param logFile to include in the report, null if none 11539 * @param crashInfo giving an application stack trace, null if absent 11540 */ 11541 public void addErrorToDropBox(String eventType, 11542 ProcessRecord process, String processName, ActivityRecord activity, 11543 ActivityRecord parent, String subject, 11544 final String report, final File logFile, 11545 final ApplicationErrorReport.CrashInfo crashInfo) { 11546 // NOTE -- this must never acquire the ActivityManagerService lock, 11547 // otherwise the watchdog may be prevented from resetting the system. 11548 11549 final String dropboxTag = processClass(process) + "_" + eventType; 11550 final DropBoxManager dbox = (DropBoxManager) 11551 mContext.getSystemService(Context.DROPBOX_SERVICE); 11552 11553 // Exit early if the dropbox isn't configured to accept this report type. 11554 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11555 11556 final StringBuilder sb = new StringBuilder(1024); 11557 appendDropBoxProcessHeaders(process, processName, sb); 11558 if (activity != null) { 11559 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11560 } 11561 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11562 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11563 } 11564 if (parent != null && parent != activity) { 11565 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11566 } 11567 if (subject != null) { 11568 sb.append("Subject: ").append(subject).append("\n"); 11569 } 11570 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11571 if (Debug.isDebuggerConnected()) { 11572 sb.append("Debugger: Connected\n"); 11573 } 11574 sb.append("\n"); 11575 11576 // Do the rest in a worker thread to avoid blocking the caller on I/O 11577 // (After this point, we shouldn't access AMS internal data structures.) 11578 Thread worker = new Thread("Error dump: " + dropboxTag) { 11579 @Override 11580 public void run() { 11581 if (report != null) { 11582 sb.append(report); 11583 } 11584 if (logFile != null) { 11585 try { 11586 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11587 "\n\n[[TRUNCATED]]")); 11588 } catch (IOException e) { 11589 Slog.e(TAG, "Error reading " + logFile, e); 11590 } 11591 } 11592 if (crashInfo != null && crashInfo.stackTrace != null) { 11593 sb.append(crashInfo.stackTrace); 11594 } 11595 11596 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11597 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11598 if (lines > 0) { 11599 sb.append("\n"); 11600 11601 // Merge several logcat streams, and take the last N lines 11602 InputStreamReader input = null; 11603 try { 11604 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11605 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11606 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11607 11608 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11609 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11610 input = new InputStreamReader(logcat.getInputStream()); 11611 11612 int num; 11613 char[] buf = new char[8192]; 11614 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11615 } catch (IOException e) { 11616 Slog.e(TAG, "Error running logcat", e); 11617 } finally { 11618 if (input != null) try { input.close(); } catch (IOException e) {} 11619 } 11620 } 11621 11622 dbox.addText(dropboxTag, sb.toString()); 11623 } 11624 }; 11625 11626 if (process == null) { 11627 // If process is null, we are being called from some internal code 11628 // and may be about to die -- run this synchronously. 11629 worker.run(); 11630 } else { 11631 worker.start(); 11632 } 11633 } 11634 11635 /** 11636 * Bring up the "unexpected error" dialog box for a crashing app. 11637 * Deal with edge cases (intercepts from instrumented applications, 11638 * ActivityController, error intent receivers, that sort of thing). 11639 * @param r the application crashing 11640 * @param crashInfo describing the failure 11641 */ 11642 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11643 long timeMillis = System.currentTimeMillis(); 11644 String shortMsg = crashInfo.exceptionClassName; 11645 String longMsg = crashInfo.exceptionMessage; 11646 String stackTrace = crashInfo.stackTrace; 11647 if (shortMsg != null && longMsg != null) { 11648 longMsg = shortMsg + ": " + longMsg; 11649 } else if (shortMsg != null) { 11650 longMsg = shortMsg; 11651 } 11652 11653 AppErrorResult result = new AppErrorResult(); 11654 synchronized (this) { 11655 if (mController != null) { 11656 try { 11657 String name = r != null ? r.processName : null; 11658 int pid = r != null ? r.pid : Binder.getCallingPid(); 11659 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11660 if (!mController.appCrashed(name, pid, 11661 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11662 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11663 && "Native crash".equals(crashInfo.exceptionClassName)) { 11664 Slog.w(TAG, "Skip killing native crashed app " + name 11665 + "(" + pid + ") during testing"); 11666 } else { 11667 Slog.w(TAG, "Force-killing crashed app " + name 11668 + " at watcher's request"); 11669 if (r != null) { 11670 r.kill("crash", true); 11671 } else { 11672 // Huh. 11673 Process.killProcess(pid); 11674 Process.killProcessGroup(uid, pid); 11675 } 11676 } 11677 return; 11678 } 11679 } catch (RemoteException e) { 11680 mController = null; 11681 Watchdog.getInstance().setActivityController(null); 11682 } 11683 } 11684 11685 final long origId = Binder.clearCallingIdentity(); 11686 11687 // If this process is running instrumentation, finish it. 11688 if (r != null && r.instrumentationClass != null) { 11689 Slog.w(TAG, "Error in app " + r.processName 11690 + " running instrumentation " + r.instrumentationClass + ":"); 11691 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11692 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11693 Bundle info = new Bundle(); 11694 info.putString("shortMsg", shortMsg); 11695 info.putString("longMsg", longMsg); 11696 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11697 Binder.restoreCallingIdentity(origId); 11698 return; 11699 } 11700 11701 // If we can't identify the process or it's already exceeded its crash quota, 11702 // quit right away without showing a crash dialog. 11703 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11704 Binder.restoreCallingIdentity(origId); 11705 return; 11706 } 11707 11708 Message msg = Message.obtain(); 11709 msg.what = SHOW_ERROR_MSG; 11710 HashMap data = new HashMap(); 11711 data.put("result", result); 11712 data.put("app", r); 11713 msg.obj = data; 11714 mHandler.sendMessage(msg); 11715 11716 Binder.restoreCallingIdentity(origId); 11717 } 11718 11719 int res = result.get(); 11720 11721 Intent appErrorIntent = null; 11722 synchronized (this) { 11723 if (r != null && !r.isolated) { 11724 // XXX Can't keep track of crash time for isolated processes, 11725 // since they don't have a persistent identity. 11726 mProcessCrashTimes.put(r.info.processName, r.uid, 11727 SystemClock.uptimeMillis()); 11728 } 11729 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11730 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11731 } 11732 } 11733 11734 if (appErrorIntent != null) { 11735 try { 11736 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11737 } catch (ActivityNotFoundException e) { 11738 Slog.w(TAG, "bug report receiver dissappeared", e); 11739 } 11740 } 11741 } 11742 11743 Intent createAppErrorIntentLocked(ProcessRecord r, 11744 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11745 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11746 if (report == null) { 11747 return null; 11748 } 11749 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11750 result.setComponent(r.errorReportReceiver); 11751 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11752 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11753 return result; 11754 } 11755 11756 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11757 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11758 if (r.errorReportReceiver == null) { 11759 return null; 11760 } 11761 11762 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11763 return null; 11764 } 11765 11766 ApplicationErrorReport report = new ApplicationErrorReport(); 11767 report.packageName = r.info.packageName; 11768 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11769 report.processName = r.processName; 11770 report.time = timeMillis; 11771 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11772 11773 if (r.crashing || r.forceCrashReport) { 11774 report.type = ApplicationErrorReport.TYPE_CRASH; 11775 report.crashInfo = crashInfo; 11776 } else if (r.notResponding) { 11777 report.type = ApplicationErrorReport.TYPE_ANR; 11778 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11779 11780 report.anrInfo.activity = r.notRespondingReport.tag; 11781 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11782 report.anrInfo.info = r.notRespondingReport.longMsg; 11783 } 11784 11785 return report; 11786 } 11787 11788 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11789 enforceNotIsolatedCaller("getProcessesInErrorState"); 11790 // assume our apps are happy - lazy create the list 11791 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11792 11793 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11794 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11795 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11796 11797 synchronized (this) { 11798 11799 // iterate across all processes 11800 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11801 ProcessRecord app = mLruProcesses.get(i); 11802 if (!allUsers && app.userId != userId) { 11803 continue; 11804 } 11805 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11806 // This one's in trouble, so we'll generate a report for it 11807 // crashes are higher priority (in case there's a crash *and* an anr) 11808 ActivityManager.ProcessErrorStateInfo report = null; 11809 if (app.crashing) { 11810 report = app.crashingReport; 11811 } else if (app.notResponding) { 11812 report = app.notRespondingReport; 11813 } 11814 11815 if (report != null) { 11816 if (errList == null) { 11817 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11818 } 11819 errList.add(report); 11820 } else { 11821 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11822 " crashing = " + app.crashing + 11823 " notResponding = " + app.notResponding); 11824 } 11825 } 11826 } 11827 } 11828 11829 return errList; 11830 } 11831 11832 static int procStateToImportance(int procState, int memAdj, 11833 ActivityManager.RunningAppProcessInfo currApp) { 11834 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11835 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11836 currApp.lru = memAdj; 11837 } else { 11838 currApp.lru = 0; 11839 } 11840 return imp; 11841 } 11842 11843 private void fillInProcMemInfo(ProcessRecord app, 11844 ActivityManager.RunningAppProcessInfo outInfo) { 11845 outInfo.pid = app.pid; 11846 outInfo.uid = app.info.uid; 11847 if (mHeavyWeightProcess == app) { 11848 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11849 } 11850 if (app.persistent) { 11851 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11852 } 11853 if (app.activities.size() > 0) { 11854 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11855 } 11856 outInfo.lastTrimLevel = app.trimMemoryLevel; 11857 int adj = app.curAdj; 11858 int procState = app.curProcState; 11859 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11860 outInfo.importanceReasonCode = app.adjTypeCode; 11861 outInfo.processState = app.curProcState; 11862 } 11863 11864 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11865 enforceNotIsolatedCaller("getRunningAppProcesses"); 11866 // Lazy instantiation of list 11867 List<ActivityManager.RunningAppProcessInfo> runList = null; 11868 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11869 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11870 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11871 synchronized (this) { 11872 // Iterate across all processes 11873 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11874 ProcessRecord app = mLruProcesses.get(i); 11875 if (!allUsers && app.userId != userId) { 11876 continue; 11877 } 11878 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11879 // Generate process state info for running application 11880 ActivityManager.RunningAppProcessInfo currApp = 11881 new ActivityManager.RunningAppProcessInfo(app.processName, 11882 app.pid, app.getPackageList()); 11883 fillInProcMemInfo(app, currApp); 11884 if (app.adjSource instanceof ProcessRecord) { 11885 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11886 currApp.importanceReasonImportance = 11887 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11888 app.adjSourceProcState); 11889 } else if (app.adjSource instanceof ActivityRecord) { 11890 ActivityRecord r = (ActivityRecord)app.adjSource; 11891 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11892 } 11893 if (app.adjTarget instanceof ComponentName) { 11894 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11895 } 11896 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11897 // + " lru=" + currApp.lru); 11898 if (runList == null) { 11899 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11900 } 11901 runList.add(currApp); 11902 } 11903 } 11904 } 11905 return runList; 11906 } 11907 11908 public List<ApplicationInfo> getRunningExternalApplications() { 11909 enforceNotIsolatedCaller("getRunningExternalApplications"); 11910 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11911 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11912 if (runningApps != null && runningApps.size() > 0) { 11913 Set<String> extList = new HashSet<String>(); 11914 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11915 if (app.pkgList != null) { 11916 for (String pkg : app.pkgList) { 11917 extList.add(pkg); 11918 } 11919 } 11920 } 11921 IPackageManager pm = AppGlobals.getPackageManager(); 11922 for (String pkg : extList) { 11923 try { 11924 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11925 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11926 retList.add(info); 11927 } 11928 } catch (RemoteException e) { 11929 } 11930 } 11931 } 11932 return retList; 11933 } 11934 11935 @Override 11936 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11937 enforceNotIsolatedCaller("getMyMemoryState"); 11938 synchronized (this) { 11939 ProcessRecord proc; 11940 synchronized (mPidsSelfLocked) { 11941 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11942 } 11943 fillInProcMemInfo(proc, outInfo); 11944 } 11945 } 11946 11947 @Override 11948 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11949 if (checkCallingPermission(android.Manifest.permission.DUMP) 11950 != PackageManager.PERMISSION_GRANTED) { 11951 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11952 + Binder.getCallingPid() 11953 + ", uid=" + Binder.getCallingUid() 11954 + " without permission " 11955 + android.Manifest.permission.DUMP); 11956 return; 11957 } 11958 11959 boolean dumpAll = false; 11960 boolean dumpClient = false; 11961 String dumpPackage = null; 11962 11963 int opti = 0; 11964 while (opti < args.length) { 11965 String opt = args[opti]; 11966 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11967 break; 11968 } 11969 opti++; 11970 if ("-a".equals(opt)) { 11971 dumpAll = true; 11972 } else if ("-c".equals(opt)) { 11973 dumpClient = true; 11974 } else if ("-h".equals(opt)) { 11975 pw.println("Activity manager dump options:"); 11976 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11977 pw.println(" cmd may be one of:"); 11978 pw.println(" a[ctivities]: activity stack state"); 11979 pw.println(" r[recents]: recent activities state"); 11980 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11981 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11982 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11983 pw.println(" o[om]: out of memory management"); 11984 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11985 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11986 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11987 pw.println(" service [COMP_SPEC]: service client-side state"); 11988 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11989 pw.println(" all: dump all activities"); 11990 pw.println(" top: dump the top activity"); 11991 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11992 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11993 pw.println(" a partial substring in a component name, a"); 11994 pw.println(" hex object identifier."); 11995 pw.println(" -a: include all available server state."); 11996 pw.println(" -c: include client state."); 11997 return; 11998 } else { 11999 pw.println("Unknown argument: " + opt + "; use -h for help"); 12000 } 12001 } 12002 12003 long origId = Binder.clearCallingIdentity(); 12004 boolean more = false; 12005 // Is the caller requesting to dump a particular piece of data? 12006 if (opti < args.length) { 12007 String cmd = args[opti]; 12008 opti++; 12009 if ("activities".equals(cmd) || "a".equals(cmd)) { 12010 synchronized (this) { 12011 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12012 } 12013 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12014 synchronized (this) { 12015 dumpRecentsLocked(fd, pw, args, opti, true, null); 12016 } 12017 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12018 String[] newArgs; 12019 String name; 12020 if (opti >= args.length) { 12021 name = null; 12022 newArgs = EMPTY_STRING_ARRAY; 12023 } else { 12024 name = args[opti]; 12025 opti++; 12026 newArgs = new String[args.length - opti]; 12027 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12028 args.length - opti); 12029 } 12030 synchronized (this) { 12031 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12032 } 12033 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12034 String[] newArgs; 12035 String name; 12036 if (opti >= args.length) { 12037 name = null; 12038 newArgs = EMPTY_STRING_ARRAY; 12039 } else { 12040 name = args[opti]; 12041 opti++; 12042 newArgs = new String[args.length - opti]; 12043 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12044 args.length - opti); 12045 } 12046 synchronized (this) { 12047 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12048 } 12049 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12050 String[] newArgs; 12051 String name; 12052 if (opti >= args.length) { 12053 name = null; 12054 newArgs = EMPTY_STRING_ARRAY; 12055 } else { 12056 name = args[opti]; 12057 opti++; 12058 newArgs = new String[args.length - opti]; 12059 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12060 args.length - opti); 12061 } 12062 synchronized (this) { 12063 dumpProcessesLocked(fd, pw, args, opti, true, name); 12064 } 12065 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12066 synchronized (this) { 12067 dumpOomLocked(fd, pw, args, opti, true); 12068 } 12069 } else if ("provider".equals(cmd)) { 12070 String[] newArgs; 12071 String name; 12072 if (opti >= args.length) { 12073 name = null; 12074 newArgs = EMPTY_STRING_ARRAY; 12075 } else { 12076 name = args[opti]; 12077 opti++; 12078 newArgs = new String[args.length - opti]; 12079 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12080 } 12081 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12082 pw.println("No providers match: " + name); 12083 pw.println("Use -h for help."); 12084 } 12085 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12086 synchronized (this) { 12087 dumpProvidersLocked(fd, pw, args, opti, true, null); 12088 } 12089 } else if ("service".equals(cmd)) { 12090 String[] newArgs; 12091 String name; 12092 if (opti >= args.length) { 12093 name = null; 12094 newArgs = EMPTY_STRING_ARRAY; 12095 } else { 12096 name = args[opti]; 12097 opti++; 12098 newArgs = new String[args.length - opti]; 12099 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12100 args.length - opti); 12101 } 12102 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12103 pw.println("No services match: " + name); 12104 pw.println("Use -h for help."); 12105 } 12106 } else if ("package".equals(cmd)) { 12107 String[] newArgs; 12108 if (opti >= args.length) { 12109 pw.println("package: no package name specified"); 12110 pw.println("Use -h for help."); 12111 } else { 12112 dumpPackage = args[opti]; 12113 opti++; 12114 newArgs = new String[args.length - opti]; 12115 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12116 args.length - opti); 12117 args = newArgs; 12118 opti = 0; 12119 more = true; 12120 } 12121 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12122 synchronized (this) { 12123 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12124 } 12125 } else { 12126 // Dumping a single activity? 12127 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12128 pw.println("Bad activity command, or no activities match: " + cmd); 12129 pw.println("Use -h for help."); 12130 } 12131 } 12132 if (!more) { 12133 Binder.restoreCallingIdentity(origId); 12134 return; 12135 } 12136 } 12137 12138 // No piece of data specified, dump everything. 12139 synchronized (this) { 12140 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12141 pw.println(); 12142 if (dumpAll) { 12143 pw.println("-------------------------------------------------------------------------------"); 12144 } 12145 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12146 pw.println(); 12147 if (dumpAll) { 12148 pw.println("-------------------------------------------------------------------------------"); 12149 } 12150 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12151 pw.println(); 12152 if (dumpAll) { 12153 pw.println("-------------------------------------------------------------------------------"); 12154 } 12155 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12156 pw.println(); 12157 if (dumpAll) { 12158 pw.println("-------------------------------------------------------------------------------"); 12159 } 12160 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12161 pw.println(); 12162 if (dumpAll) { 12163 pw.println("-------------------------------------------------------------------------------"); 12164 } 12165 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12166 pw.println(); 12167 if (dumpAll) { 12168 pw.println("-------------------------------------------------------------------------------"); 12169 } 12170 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12171 } 12172 Binder.restoreCallingIdentity(origId); 12173 } 12174 12175 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12176 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12177 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12178 12179 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12180 dumpPackage); 12181 boolean needSep = printedAnything; 12182 12183 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12184 dumpPackage, needSep, " mFocusedActivity: "); 12185 if (printed) { 12186 printedAnything = true; 12187 needSep = false; 12188 } 12189 12190 if (dumpPackage == null) { 12191 if (needSep) { 12192 pw.println(); 12193 } 12194 needSep = true; 12195 printedAnything = true; 12196 mStackSupervisor.dump(pw, " "); 12197 } 12198 12199 if (!printedAnything) { 12200 pw.println(" (nothing)"); 12201 } 12202 } 12203 12204 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12205 int opti, boolean dumpAll, String dumpPackage) { 12206 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12207 12208 boolean printedAnything = false; 12209 12210 if (mRecentTasks.size() > 0) { 12211 boolean printedHeader = false; 12212 12213 final int N = mRecentTasks.size(); 12214 for (int i=0; i<N; i++) { 12215 TaskRecord tr = mRecentTasks.get(i); 12216 if (dumpPackage != null) { 12217 if (tr.realActivity == null || 12218 !dumpPackage.equals(tr.realActivity)) { 12219 continue; 12220 } 12221 } 12222 if (!printedHeader) { 12223 pw.println(" Recent tasks:"); 12224 printedHeader = true; 12225 printedAnything = true; 12226 } 12227 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12228 pw.println(tr); 12229 if (dumpAll) { 12230 mRecentTasks.get(i).dump(pw, " "); 12231 } 12232 } 12233 } 12234 12235 if (!printedAnything) { 12236 pw.println(" (nothing)"); 12237 } 12238 } 12239 12240 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12241 int opti, boolean dumpAll, String dumpPackage) { 12242 boolean needSep = false; 12243 boolean printedAnything = false; 12244 int numPers = 0; 12245 12246 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12247 12248 if (dumpAll) { 12249 final int NP = mProcessNames.getMap().size(); 12250 for (int ip=0; ip<NP; ip++) { 12251 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12252 final int NA = procs.size(); 12253 for (int ia=0; ia<NA; ia++) { 12254 ProcessRecord r = procs.valueAt(ia); 12255 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12256 continue; 12257 } 12258 if (!needSep) { 12259 pw.println(" All known processes:"); 12260 needSep = true; 12261 printedAnything = true; 12262 } 12263 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12264 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12265 pw.print(" "); pw.println(r); 12266 r.dump(pw, " "); 12267 if (r.persistent) { 12268 numPers++; 12269 } 12270 } 12271 } 12272 } 12273 12274 if (mIsolatedProcesses.size() > 0) { 12275 boolean printed = false; 12276 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12277 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12278 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12279 continue; 12280 } 12281 if (!printed) { 12282 if (needSep) { 12283 pw.println(); 12284 } 12285 pw.println(" Isolated process list (sorted by uid):"); 12286 printedAnything = true; 12287 printed = true; 12288 needSep = true; 12289 } 12290 pw.println(String.format("%sIsolated #%2d: %s", 12291 " ", i, r.toString())); 12292 } 12293 } 12294 12295 if (mLruProcesses.size() > 0) { 12296 if (needSep) { 12297 pw.println(); 12298 } 12299 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12300 pw.print(" total, non-act at "); 12301 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12302 pw.print(", non-svc at "); 12303 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12304 pw.println("):"); 12305 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12306 needSep = true; 12307 printedAnything = true; 12308 } 12309 12310 if (dumpAll || dumpPackage != null) { 12311 synchronized (mPidsSelfLocked) { 12312 boolean printed = false; 12313 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12314 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12315 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12316 continue; 12317 } 12318 if (!printed) { 12319 if (needSep) pw.println(); 12320 needSep = true; 12321 pw.println(" PID mappings:"); 12322 printed = true; 12323 printedAnything = true; 12324 } 12325 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12326 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12327 } 12328 } 12329 } 12330 12331 if (mForegroundProcesses.size() > 0) { 12332 synchronized (mPidsSelfLocked) { 12333 boolean printed = false; 12334 for (int i=0; i<mForegroundProcesses.size(); i++) { 12335 ProcessRecord r = mPidsSelfLocked.get( 12336 mForegroundProcesses.valueAt(i).pid); 12337 if (dumpPackage != null && (r == null 12338 || !r.pkgList.containsKey(dumpPackage))) { 12339 continue; 12340 } 12341 if (!printed) { 12342 if (needSep) pw.println(); 12343 needSep = true; 12344 pw.println(" Foreground Processes:"); 12345 printed = true; 12346 printedAnything = true; 12347 } 12348 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12349 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12350 } 12351 } 12352 } 12353 12354 if (mPersistentStartingProcesses.size() > 0) { 12355 if (needSep) pw.println(); 12356 needSep = true; 12357 printedAnything = true; 12358 pw.println(" Persisent processes that are starting:"); 12359 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12360 "Starting Norm", "Restarting PERS", dumpPackage); 12361 } 12362 12363 if (mRemovedProcesses.size() > 0) { 12364 if (needSep) pw.println(); 12365 needSep = true; 12366 printedAnything = true; 12367 pw.println(" Processes that are being removed:"); 12368 dumpProcessList(pw, this, mRemovedProcesses, " ", 12369 "Removed Norm", "Removed PERS", dumpPackage); 12370 } 12371 12372 if (mProcessesOnHold.size() > 0) { 12373 if (needSep) pw.println(); 12374 needSep = true; 12375 printedAnything = true; 12376 pw.println(" Processes that are on old until the system is ready:"); 12377 dumpProcessList(pw, this, mProcessesOnHold, " ", 12378 "OnHold Norm", "OnHold PERS", dumpPackage); 12379 } 12380 12381 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12382 12383 if (mProcessCrashTimes.getMap().size() > 0) { 12384 boolean printed = false; 12385 long now = SystemClock.uptimeMillis(); 12386 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12387 final int NP = pmap.size(); 12388 for (int ip=0; ip<NP; ip++) { 12389 String pname = pmap.keyAt(ip); 12390 SparseArray<Long> uids = pmap.valueAt(ip); 12391 final int N = uids.size(); 12392 for (int i=0; i<N; i++) { 12393 int puid = uids.keyAt(i); 12394 ProcessRecord r = mProcessNames.get(pname, puid); 12395 if (dumpPackage != null && (r == null 12396 || !r.pkgList.containsKey(dumpPackage))) { 12397 continue; 12398 } 12399 if (!printed) { 12400 if (needSep) pw.println(); 12401 needSep = true; 12402 pw.println(" Time since processes crashed:"); 12403 printed = true; 12404 printedAnything = true; 12405 } 12406 pw.print(" Process "); pw.print(pname); 12407 pw.print(" uid "); pw.print(puid); 12408 pw.print(": last crashed "); 12409 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12410 pw.println(" ago"); 12411 } 12412 } 12413 } 12414 12415 if (mBadProcesses.getMap().size() > 0) { 12416 boolean printed = false; 12417 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12418 final int NP = pmap.size(); 12419 for (int ip=0; ip<NP; ip++) { 12420 String pname = pmap.keyAt(ip); 12421 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12422 final int N = uids.size(); 12423 for (int i=0; i<N; i++) { 12424 int puid = uids.keyAt(i); 12425 ProcessRecord r = mProcessNames.get(pname, puid); 12426 if (dumpPackage != null && (r == null 12427 || !r.pkgList.containsKey(dumpPackage))) { 12428 continue; 12429 } 12430 if (!printed) { 12431 if (needSep) pw.println(); 12432 needSep = true; 12433 pw.println(" Bad processes:"); 12434 printedAnything = true; 12435 } 12436 BadProcessInfo info = uids.valueAt(i); 12437 pw.print(" Bad process "); pw.print(pname); 12438 pw.print(" uid "); pw.print(puid); 12439 pw.print(": crashed at time "); pw.println(info.time); 12440 if (info.shortMsg != null) { 12441 pw.print(" Short msg: "); pw.println(info.shortMsg); 12442 } 12443 if (info.longMsg != null) { 12444 pw.print(" Long msg: "); pw.println(info.longMsg); 12445 } 12446 if (info.stack != null) { 12447 pw.println(" Stack:"); 12448 int lastPos = 0; 12449 for (int pos=0; pos<info.stack.length(); pos++) { 12450 if (info.stack.charAt(pos) == '\n') { 12451 pw.print(" "); 12452 pw.write(info.stack, lastPos, pos-lastPos); 12453 pw.println(); 12454 lastPos = pos+1; 12455 } 12456 } 12457 if (lastPos < info.stack.length()) { 12458 pw.print(" "); 12459 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12460 pw.println(); 12461 } 12462 } 12463 } 12464 } 12465 } 12466 12467 if (dumpPackage == null) { 12468 pw.println(); 12469 needSep = false; 12470 pw.println(" mStartedUsers:"); 12471 for (int i=0; i<mStartedUsers.size(); i++) { 12472 UserStartedState uss = mStartedUsers.valueAt(i); 12473 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12474 pw.print(": "); uss.dump("", pw); 12475 } 12476 pw.print(" mStartedUserArray: ["); 12477 for (int i=0; i<mStartedUserArray.length; i++) { 12478 if (i > 0) pw.print(", "); 12479 pw.print(mStartedUserArray[i]); 12480 } 12481 pw.println("]"); 12482 pw.print(" mUserLru: ["); 12483 for (int i=0; i<mUserLru.size(); i++) { 12484 if (i > 0) pw.print(", "); 12485 pw.print(mUserLru.get(i)); 12486 } 12487 pw.println("]"); 12488 if (dumpAll) { 12489 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12490 } 12491 synchronized (mUserProfileGroupIdsSelfLocked) { 12492 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12493 pw.println(" mUserProfileGroupIds:"); 12494 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12495 pw.print(" User #"); 12496 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12497 pw.print(" -> profile #"); 12498 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12499 } 12500 } 12501 } 12502 } 12503 if (mHomeProcess != null && (dumpPackage == null 12504 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12505 if (needSep) { 12506 pw.println(); 12507 needSep = false; 12508 } 12509 pw.println(" mHomeProcess: " + mHomeProcess); 12510 } 12511 if (mPreviousProcess != null && (dumpPackage == null 12512 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12513 if (needSep) { 12514 pw.println(); 12515 needSep = false; 12516 } 12517 pw.println(" mPreviousProcess: " + mPreviousProcess); 12518 } 12519 if (dumpAll) { 12520 StringBuilder sb = new StringBuilder(128); 12521 sb.append(" mPreviousProcessVisibleTime: "); 12522 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12523 pw.println(sb); 12524 } 12525 if (mHeavyWeightProcess != null && (dumpPackage == null 12526 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12527 if (needSep) { 12528 pw.println(); 12529 needSep = false; 12530 } 12531 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12532 } 12533 if (dumpPackage == null) { 12534 pw.println(" mConfiguration: " + mConfiguration); 12535 } 12536 if (dumpAll) { 12537 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12538 if (mCompatModePackages.getPackages().size() > 0) { 12539 boolean printed = false; 12540 for (Map.Entry<String, Integer> entry 12541 : mCompatModePackages.getPackages().entrySet()) { 12542 String pkg = entry.getKey(); 12543 int mode = entry.getValue(); 12544 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12545 continue; 12546 } 12547 if (!printed) { 12548 pw.println(" mScreenCompatPackages:"); 12549 printed = true; 12550 } 12551 pw.print(" "); pw.print(pkg); pw.print(": "); 12552 pw.print(mode); pw.println(); 12553 } 12554 } 12555 } 12556 if (dumpPackage == null) { 12557 if (mSleeping || mWentToSleep || mLockScreenShown) { 12558 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12559 + " mLockScreenShown " + mLockScreenShown); 12560 } 12561 if (mShuttingDown || mRunningVoice) { 12562 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12563 } 12564 } 12565 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12566 || mOrigWaitForDebugger) { 12567 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12568 || dumpPackage.equals(mOrigDebugApp)) { 12569 if (needSep) { 12570 pw.println(); 12571 needSep = false; 12572 } 12573 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12574 + " mDebugTransient=" + mDebugTransient 12575 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12576 } 12577 } 12578 if (mOpenGlTraceApp != null) { 12579 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12580 if (needSep) { 12581 pw.println(); 12582 needSep = false; 12583 } 12584 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12585 } 12586 } 12587 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12588 || mProfileFd != null) { 12589 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12590 if (needSep) { 12591 pw.println(); 12592 needSep = false; 12593 } 12594 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12595 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12596 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 12597 + mAutoStopProfiler); 12598 } 12599 } 12600 if (dumpPackage == null) { 12601 if (mAlwaysFinishActivities || mController != null) { 12602 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12603 + " mController=" + mController); 12604 } 12605 if (dumpAll) { 12606 pw.println(" Total persistent processes: " + numPers); 12607 pw.println(" mProcessesReady=" + mProcessesReady 12608 + " mSystemReady=" + mSystemReady); 12609 pw.println(" mBooting=" + mBooting 12610 + " mBooted=" + mBooted 12611 + " mFactoryTest=" + mFactoryTest); 12612 pw.print(" mLastPowerCheckRealtime="); 12613 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12614 pw.println(""); 12615 pw.print(" mLastPowerCheckUptime="); 12616 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12617 pw.println(""); 12618 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12619 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12620 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12621 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12622 + " (" + mLruProcesses.size() + " total)" 12623 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12624 + " mNumServiceProcs=" + mNumServiceProcs 12625 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12626 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12627 + " mLastMemoryLevel" + mLastMemoryLevel 12628 + " mLastNumProcesses" + mLastNumProcesses); 12629 long now = SystemClock.uptimeMillis(); 12630 pw.print(" mLastIdleTime="); 12631 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12632 pw.print(" mLowRamSinceLastIdle="); 12633 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12634 pw.println(); 12635 } 12636 } 12637 12638 if (!printedAnything) { 12639 pw.println(" (nothing)"); 12640 } 12641 } 12642 12643 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12644 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12645 if (mProcessesToGc.size() > 0) { 12646 boolean printed = false; 12647 long now = SystemClock.uptimeMillis(); 12648 for (int i=0; i<mProcessesToGc.size(); i++) { 12649 ProcessRecord proc = mProcessesToGc.get(i); 12650 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12651 continue; 12652 } 12653 if (!printed) { 12654 if (needSep) pw.println(); 12655 needSep = true; 12656 pw.println(" Processes that are waiting to GC:"); 12657 printed = true; 12658 } 12659 pw.print(" Process "); pw.println(proc); 12660 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12661 pw.print(", last gced="); 12662 pw.print(now-proc.lastRequestedGc); 12663 pw.print(" ms ago, last lowMem="); 12664 pw.print(now-proc.lastLowMemory); 12665 pw.println(" ms ago"); 12666 12667 } 12668 } 12669 return needSep; 12670 } 12671 12672 void printOomLevel(PrintWriter pw, String name, int adj) { 12673 pw.print(" "); 12674 if (adj >= 0) { 12675 pw.print(' '); 12676 if (adj < 10) pw.print(' '); 12677 } else { 12678 if (adj > -10) pw.print(' '); 12679 } 12680 pw.print(adj); 12681 pw.print(": "); 12682 pw.print(name); 12683 pw.print(" ("); 12684 pw.print(mProcessList.getMemLevel(adj)/1024); 12685 pw.println(" kB)"); 12686 } 12687 12688 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12689 int opti, boolean dumpAll) { 12690 boolean needSep = false; 12691 12692 if (mLruProcesses.size() > 0) { 12693 if (needSep) pw.println(); 12694 needSep = true; 12695 pw.println(" OOM levels:"); 12696 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12697 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12698 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12699 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12700 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12701 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12702 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12703 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12704 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12705 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12706 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12707 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12708 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12709 12710 if (needSep) pw.println(); 12711 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12712 pw.print(" total, non-act at "); 12713 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12714 pw.print(", non-svc at "); 12715 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12716 pw.println("):"); 12717 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12718 needSep = true; 12719 } 12720 12721 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12722 12723 pw.println(); 12724 pw.println(" mHomeProcess: " + mHomeProcess); 12725 pw.println(" mPreviousProcess: " + mPreviousProcess); 12726 if (mHeavyWeightProcess != null) { 12727 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12728 } 12729 12730 return true; 12731 } 12732 12733 /** 12734 * There are three ways to call this: 12735 * - no provider specified: dump all the providers 12736 * - a flattened component name that matched an existing provider was specified as the 12737 * first arg: dump that one provider 12738 * - the first arg isn't the flattened component name of an existing provider: 12739 * dump all providers whose component contains the first arg as a substring 12740 */ 12741 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12742 int opti, boolean dumpAll) { 12743 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12744 } 12745 12746 static class ItemMatcher { 12747 ArrayList<ComponentName> components; 12748 ArrayList<String> strings; 12749 ArrayList<Integer> objects; 12750 boolean all; 12751 12752 ItemMatcher() { 12753 all = true; 12754 } 12755 12756 void build(String name) { 12757 ComponentName componentName = ComponentName.unflattenFromString(name); 12758 if (componentName != null) { 12759 if (components == null) { 12760 components = new ArrayList<ComponentName>(); 12761 } 12762 components.add(componentName); 12763 all = false; 12764 } else { 12765 int objectId = 0; 12766 // Not a '/' separated full component name; maybe an object ID? 12767 try { 12768 objectId = Integer.parseInt(name, 16); 12769 if (objects == null) { 12770 objects = new ArrayList<Integer>(); 12771 } 12772 objects.add(objectId); 12773 all = false; 12774 } catch (RuntimeException e) { 12775 // Not an integer; just do string match. 12776 if (strings == null) { 12777 strings = new ArrayList<String>(); 12778 } 12779 strings.add(name); 12780 all = false; 12781 } 12782 } 12783 } 12784 12785 int build(String[] args, int opti) { 12786 for (; opti<args.length; opti++) { 12787 String name = args[opti]; 12788 if ("--".equals(name)) { 12789 return opti+1; 12790 } 12791 build(name); 12792 } 12793 return opti; 12794 } 12795 12796 boolean match(Object object, ComponentName comp) { 12797 if (all) { 12798 return true; 12799 } 12800 if (components != null) { 12801 for (int i=0; i<components.size(); i++) { 12802 if (components.get(i).equals(comp)) { 12803 return true; 12804 } 12805 } 12806 } 12807 if (objects != null) { 12808 for (int i=0; i<objects.size(); i++) { 12809 if (System.identityHashCode(object) == objects.get(i)) { 12810 return true; 12811 } 12812 } 12813 } 12814 if (strings != null) { 12815 String flat = comp.flattenToString(); 12816 for (int i=0; i<strings.size(); i++) { 12817 if (flat.contains(strings.get(i))) { 12818 return true; 12819 } 12820 } 12821 } 12822 return false; 12823 } 12824 } 12825 12826 /** 12827 * There are three things that cmd can be: 12828 * - a flattened component name that matches an existing activity 12829 * - the cmd arg isn't the flattened component name of an existing activity: 12830 * dump all activity whose component contains the cmd as a substring 12831 * - A hex number of the ActivityRecord object instance. 12832 */ 12833 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12834 int opti, boolean dumpAll) { 12835 ArrayList<ActivityRecord> activities; 12836 12837 synchronized (this) { 12838 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12839 } 12840 12841 if (activities.size() <= 0) { 12842 return false; 12843 } 12844 12845 String[] newArgs = new String[args.length - opti]; 12846 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12847 12848 TaskRecord lastTask = null; 12849 boolean needSep = false; 12850 for (int i=activities.size()-1; i>=0; i--) { 12851 ActivityRecord r = activities.get(i); 12852 if (needSep) { 12853 pw.println(); 12854 } 12855 needSep = true; 12856 synchronized (this) { 12857 if (lastTask != r.task) { 12858 lastTask = r.task; 12859 pw.print("TASK "); pw.print(lastTask.affinity); 12860 pw.print(" id="); pw.println(lastTask.taskId); 12861 if (dumpAll) { 12862 lastTask.dump(pw, " "); 12863 } 12864 } 12865 } 12866 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12867 } 12868 return true; 12869 } 12870 12871 /** 12872 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12873 * there is a thread associated with the activity. 12874 */ 12875 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12876 final ActivityRecord r, String[] args, boolean dumpAll) { 12877 String innerPrefix = prefix + " "; 12878 synchronized (this) { 12879 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12880 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12881 pw.print(" pid="); 12882 if (r.app != null) pw.println(r.app.pid); 12883 else pw.println("(not running)"); 12884 if (dumpAll) { 12885 r.dump(pw, innerPrefix); 12886 } 12887 } 12888 if (r.app != null && r.app.thread != null) { 12889 // flush anything that is already in the PrintWriter since the thread is going 12890 // to write to the file descriptor directly 12891 pw.flush(); 12892 try { 12893 TransferPipe tp = new TransferPipe(); 12894 try { 12895 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12896 r.appToken, innerPrefix, args); 12897 tp.go(fd); 12898 } finally { 12899 tp.kill(); 12900 } 12901 } catch (IOException e) { 12902 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12903 } catch (RemoteException e) { 12904 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12905 } 12906 } 12907 } 12908 12909 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12910 int opti, boolean dumpAll, String dumpPackage) { 12911 boolean needSep = false; 12912 boolean onlyHistory = false; 12913 boolean printedAnything = false; 12914 12915 if ("history".equals(dumpPackage)) { 12916 if (opti < args.length && "-s".equals(args[opti])) { 12917 dumpAll = false; 12918 } 12919 onlyHistory = true; 12920 dumpPackage = null; 12921 } 12922 12923 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12924 if (!onlyHistory && dumpAll) { 12925 if (mRegisteredReceivers.size() > 0) { 12926 boolean printed = false; 12927 Iterator it = mRegisteredReceivers.values().iterator(); 12928 while (it.hasNext()) { 12929 ReceiverList r = (ReceiverList)it.next(); 12930 if (dumpPackage != null && (r.app == null || 12931 !dumpPackage.equals(r.app.info.packageName))) { 12932 continue; 12933 } 12934 if (!printed) { 12935 pw.println(" Registered Receivers:"); 12936 needSep = true; 12937 printed = true; 12938 printedAnything = true; 12939 } 12940 pw.print(" * "); pw.println(r); 12941 r.dump(pw, " "); 12942 } 12943 } 12944 12945 if (mReceiverResolver.dump(pw, needSep ? 12946 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12947 " ", dumpPackage, false)) { 12948 needSep = true; 12949 printedAnything = true; 12950 } 12951 } 12952 12953 for (BroadcastQueue q : mBroadcastQueues) { 12954 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12955 printedAnything |= needSep; 12956 } 12957 12958 needSep = true; 12959 12960 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12961 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12962 if (needSep) { 12963 pw.println(); 12964 } 12965 needSep = true; 12966 printedAnything = true; 12967 pw.print(" Sticky broadcasts for user "); 12968 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12969 StringBuilder sb = new StringBuilder(128); 12970 for (Map.Entry<String, ArrayList<Intent>> ent 12971 : mStickyBroadcasts.valueAt(user).entrySet()) { 12972 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12973 if (dumpAll) { 12974 pw.println(":"); 12975 ArrayList<Intent> intents = ent.getValue(); 12976 final int N = intents.size(); 12977 for (int i=0; i<N; i++) { 12978 sb.setLength(0); 12979 sb.append(" Intent: "); 12980 intents.get(i).toShortString(sb, false, true, false, false); 12981 pw.println(sb.toString()); 12982 Bundle bundle = intents.get(i).getExtras(); 12983 if (bundle != null) { 12984 pw.print(" "); 12985 pw.println(bundle.toString()); 12986 } 12987 } 12988 } else { 12989 pw.println(""); 12990 } 12991 } 12992 } 12993 } 12994 12995 if (!onlyHistory && dumpAll) { 12996 pw.println(); 12997 for (BroadcastQueue queue : mBroadcastQueues) { 12998 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12999 + queue.mBroadcastsScheduled); 13000 } 13001 pw.println(" mHandler:"); 13002 mHandler.dump(new PrintWriterPrinter(pw), " "); 13003 needSep = true; 13004 printedAnything = true; 13005 } 13006 13007 if (!printedAnything) { 13008 pw.println(" (nothing)"); 13009 } 13010 } 13011 13012 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13013 int opti, boolean dumpAll, String dumpPackage) { 13014 boolean needSep; 13015 boolean printedAnything = false; 13016 13017 ItemMatcher matcher = new ItemMatcher(); 13018 matcher.build(args, opti); 13019 13020 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13021 13022 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13023 printedAnything |= needSep; 13024 13025 if (mLaunchingProviders.size() > 0) { 13026 boolean printed = false; 13027 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13028 ContentProviderRecord r = mLaunchingProviders.get(i); 13029 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13030 continue; 13031 } 13032 if (!printed) { 13033 if (needSep) pw.println(); 13034 needSep = true; 13035 pw.println(" Launching content providers:"); 13036 printed = true; 13037 printedAnything = true; 13038 } 13039 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13040 pw.println(r); 13041 } 13042 } 13043 13044 if (mGrantedUriPermissions.size() > 0) { 13045 boolean printed = false; 13046 int dumpUid = -2; 13047 if (dumpPackage != null) { 13048 try { 13049 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13050 } catch (NameNotFoundException e) { 13051 dumpUid = -1; 13052 } 13053 } 13054 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13055 int uid = mGrantedUriPermissions.keyAt(i); 13056 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13057 continue; 13058 } 13059 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13060 if (!printed) { 13061 if (needSep) pw.println(); 13062 needSep = true; 13063 pw.println(" Granted Uri Permissions:"); 13064 printed = true; 13065 printedAnything = true; 13066 } 13067 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13068 for (UriPermission perm : perms.values()) { 13069 pw.print(" "); pw.println(perm); 13070 if (dumpAll) { 13071 perm.dump(pw, " "); 13072 } 13073 } 13074 } 13075 } 13076 13077 if (!printedAnything) { 13078 pw.println(" (nothing)"); 13079 } 13080 } 13081 13082 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13083 int opti, boolean dumpAll, String dumpPackage) { 13084 boolean printed = false; 13085 13086 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13087 13088 if (mIntentSenderRecords.size() > 0) { 13089 Iterator<WeakReference<PendingIntentRecord>> it 13090 = mIntentSenderRecords.values().iterator(); 13091 while (it.hasNext()) { 13092 WeakReference<PendingIntentRecord> ref = it.next(); 13093 PendingIntentRecord rec = ref != null ? ref.get(): null; 13094 if (dumpPackage != null && (rec == null 13095 || !dumpPackage.equals(rec.key.packageName))) { 13096 continue; 13097 } 13098 printed = true; 13099 if (rec != null) { 13100 pw.print(" * "); pw.println(rec); 13101 if (dumpAll) { 13102 rec.dump(pw, " "); 13103 } 13104 } else { 13105 pw.print(" * "); pw.println(ref); 13106 } 13107 } 13108 } 13109 13110 if (!printed) { 13111 pw.println(" (nothing)"); 13112 } 13113 } 13114 13115 private static final int dumpProcessList(PrintWriter pw, 13116 ActivityManagerService service, List list, 13117 String prefix, String normalLabel, String persistentLabel, 13118 String dumpPackage) { 13119 int numPers = 0; 13120 final int N = list.size()-1; 13121 for (int i=N; i>=0; i--) { 13122 ProcessRecord r = (ProcessRecord)list.get(i); 13123 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13124 continue; 13125 } 13126 pw.println(String.format("%s%s #%2d: %s", 13127 prefix, (r.persistent ? persistentLabel : normalLabel), 13128 i, r.toString())); 13129 if (r.persistent) { 13130 numPers++; 13131 } 13132 } 13133 return numPers; 13134 } 13135 13136 private static final boolean dumpProcessOomList(PrintWriter pw, 13137 ActivityManagerService service, List<ProcessRecord> origList, 13138 String prefix, String normalLabel, String persistentLabel, 13139 boolean inclDetails, String dumpPackage) { 13140 13141 ArrayList<Pair<ProcessRecord, Integer>> list 13142 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13143 for (int i=0; i<origList.size(); i++) { 13144 ProcessRecord r = origList.get(i); 13145 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13146 continue; 13147 } 13148 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13149 } 13150 13151 if (list.size() <= 0) { 13152 return false; 13153 } 13154 13155 Comparator<Pair<ProcessRecord, Integer>> comparator 13156 = new Comparator<Pair<ProcessRecord, Integer>>() { 13157 @Override 13158 public int compare(Pair<ProcessRecord, Integer> object1, 13159 Pair<ProcessRecord, Integer> object2) { 13160 if (object1.first.setAdj != object2.first.setAdj) { 13161 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13162 } 13163 if (object1.second.intValue() != object2.second.intValue()) { 13164 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13165 } 13166 return 0; 13167 } 13168 }; 13169 13170 Collections.sort(list, comparator); 13171 13172 final long curRealtime = SystemClock.elapsedRealtime(); 13173 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13174 final long curUptime = SystemClock.uptimeMillis(); 13175 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13176 13177 for (int i=list.size()-1; i>=0; i--) { 13178 ProcessRecord r = list.get(i).first; 13179 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13180 char schedGroup; 13181 switch (r.setSchedGroup) { 13182 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13183 schedGroup = 'B'; 13184 break; 13185 case Process.THREAD_GROUP_DEFAULT: 13186 schedGroup = 'F'; 13187 break; 13188 default: 13189 schedGroup = '?'; 13190 break; 13191 } 13192 char foreground; 13193 if (r.foregroundActivities) { 13194 foreground = 'A'; 13195 } else if (r.foregroundServices) { 13196 foreground = 'S'; 13197 } else { 13198 foreground = ' '; 13199 } 13200 String procState = ProcessList.makeProcStateString(r.curProcState); 13201 pw.print(prefix); 13202 pw.print(r.persistent ? persistentLabel : normalLabel); 13203 pw.print(" #"); 13204 int num = (origList.size()-1)-list.get(i).second; 13205 if (num < 10) pw.print(' '); 13206 pw.print(num); 13207 pw.print(": "); 13208 pw.print(oomAdj); 13209 pw.print(' '); 13210 pw.print(schedGroup); 13211 pw.print('/'); 13212 pw.print(foreground); 13213 pw.print('/'); 13214 pw.print(procState); 13215 pw.print(" trm:"); 13216 if (r.trimMemoryLevel < 10) pw.print(' '); 13217 pw.print(r.trimMemoryLevel); 13218 pw.print(' '); 13219 pw.print(r.toShortString()); 13220 pw.print(" ("); 13221 pw.print(r.adjType); 13222 pw.println(')'); 13223 if (r.adjSource != null || r.adjTarget != null) { 13224 pw.print(prefix); 13225 pw.print(" "); 13226 if (r.adjTarget instanceof ComponentName) { 13227 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13228 } else if (r.adjTarget != null) { 13229 pw.print(r.adjTarget.toString()); 13230 } else { 13231 pw.print("{null}"); 13232 } 13233 pw.print("<="); 13234 if (r.adjSource instanceof ProcessRecord) { 13235 pw.print("Proc{"); 13236 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13237 pw.println("}"); 13238 } else if (r.adjSource != null) { 13239 pw.println(r.adjSource.toString()); 13240 } else { 13241 pw.println("{null}"); 13242 } 13243 } 13244 if (inclDetails) { 13245 pw.print(prefix); 13246 pw.print(" "); 13247 pw.print("oom: max="); pw.print(r.maxAdj); 13248 pw.print(" curRaw="); pw.print(r.curRawAdj); 13249 pw.print(" setRaw="); pw.print(r.setRawAdj); 13250 pw.print(" cur="); pw.print(r.curAdj); 13251 pw.print(" set="); pw.println(r.setAdj); 13252 pw.print(prefix); 13253 pw.print(" "); 13254 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13255 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13256 pw.print(" lastPss="); pw.print(r.lastPss); 13257 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13258 pw.print(prefix); 13259 pw.print(" "); 13260 pw.print("cached="); pw.print(r.cached); 13261 pw.print(" empty="); pw.print(r.empty); 13262 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13263 13264 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13265 if (r.lastWakeTime != 0) { 13266 long wtime; 13267 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13268 synchronized (stats) { 13269 wtime = stats.getProcessWakeTime(r.info.uid, 13270 r.pid, curRealtime); 13271 } 13272 long timeUsed = wtime - r.lastWakeTime; 13273 pw.print(prefix); 13274 pw.print(" "); 13275 pw.print("keep awake over "); 13276 TimeUtils.formatDuration(realtimeSince, pw); 13277 pw.print(" used "); 13278 TimeUtils.formatDuration(timeUsed, pw); 13279 pw.print(" ("); 13280 pw.print((timeUsed*100)/realtimeSince); 13281 pw.println("%)"); 13282 } 13283 if (r.lastCpuTime != 0) { 13284 long timeUsed = r.curCpuTime - r.lastCpuTime; 13285 pw.print(prefix); 13286 pw.print(" "); 13287 pw.print("run cpu over "); 13288 TimeUtils.formatDuration(uptimeSince, pw); 13289 pw.print(" used "); 13290 TimeUtils.formatDuration(timeUsed, pw); 13291 pw.print(" ("); 13292 pw.print((timeUsed*100)/uptimeSince); 13293 pw.println("%)"); 13294 } 13295 } 13296 } 13297 } 13298 return true; 13299 } 13300 13301 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13302 ArrayList<ProcessRecord> procs; 13303 synchronized (this) { 13304 if (args != null && args.length > start 13305 && args[start].charAt(0) != '-') { 13306 procs = new ArrayList<ProcessRecord>(); 13307 int pid = -1; 13308 try { 13309 pid = Integer.parseInt(args[start]); 13310 } catch (NumberFormatException e) { 13311 } 13312 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13313 ProcessRecord proc = mLruProcesses.get(i); 13314 if (proc.pid == pid) { 13315 procs.add(proc); 13316 } else if (proc.processName.equals(args[start])) { 13317 procs.add(proc); 13318 } 13319 } 13320 if (procs.size() <= 0) { 13321 return null; 13322 } 13323 } else { 13324 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13325 } 13326 } 13327 return procs; 13328 } 13329 13330 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13331 PrintWriter pw, String[] args) { 13332 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13333 if (procs == null) { 13334 pw.println("No process found for: " + args[0]); 13335 return; 13336 } 13337 13338 long uptime = SystemClock.uptimeMillis(); 13339 long realtime = SystemClock.elapsedRealtime(); 13340 pw.println("Applications Graphics Acceleration Info:"); 13341 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13342 13343 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13344 ProcessRecord r = procs.get(i); 13345 if (r.thread != null) { 13346 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13347 pw.flush(); 13348 try { 13349 TransferPipe tp = new TransferPipe(); 13350 try { 13351 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13352 tp.go(fd); 13353 } finally { 13354 tp.kill(); 13355 } 13356 } catch (IOException e) { 13357 pw.println("Failure while dumping the app: " + r); 13358 pw.flush(); 13359 } catch (RemoteException e) { 13360 pw.println("Got a RemoteException while dumping the app " + r); 13361 pw.flush(); 13362 } 13363 } 13364 } 13365 } 13366 13367 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13368 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13369 if (procs == null) { 13370 pw.println("No process found for: " + args[0]); 13371 return; 13372 } 13373 13374 pw.println("Applications Database Info:"); 13375 13376 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13377 ProcessRecord r = procs.get(i); 13378 if (r.thread != null) { 13379 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13380 pw.flush(); 13381 try { 13382 TransferPipe tp = new TransferPipe(); 13383 try { 13384 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13385 tp.go(fd); 13386 } finally { 13387 tp.kill(); 13388 } 13389 } catch (IOException e) { 13390 pw.println("Failure while dumping the app: " + r); 13391 pw.flush(); 13392 } catch (RemoteException e) { 13393 pw.println("Got a RemoteException while dumping the app " + r); 13394 pw.flush(); 13395 } 13396 } 13397 } 13398 } 13399 13400 final static class MemItem { 13401 final boolean isProc; 13402 final String label; 13403 final String shortLabel; 13404 final long pss; 13405 final int id; 13406 final boolean hasActivities; 13407 ArrayList<MemItem> subitems; 13408 13409 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13410 boolean _hasActivities) { 13411 isProc = true; 13412 label = _label; 13413 shortLabel = _shortLabel; 13414 pss = _pss; 13415 id = _id; 13416 hasActivities = _hasActivities; 13417 } 13418 13419 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13420 isProc = false; 13421 label = _label; 13422 shortLabel = _shortLabel; 13423 pss = _pss; 13424 id = _id; 13425 hasActivities = false; 13426 } 13427 } 13428 13429 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13430 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13431 if (sort && !isCompact) { 13432 Collections.sort(items, new Comparator<MemItem>() { 13433 @Override 13434 public int compare(MemItem lhs, MemItem rhs) { 13435 if (lhs.pss < rhs.pss) { 13436 return 1; 13437 } else if (lhs.pss > rhs.pss) { 13438 return -1; 13439 } 13440 return 0; 13441 } 13442 }); 13443 } 13444 13445 for (int i=0; i<items.size(); i++) { 13446 MemItem mi = items.get(i); 13447 if (!isCompact) { 13448 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13449 } else if (mi.isProc) { 13450 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13451 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13452 pw.println(mi.hasActivities ? ",a" : ",e"); 13453 } else { 13454 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13455 pw.println(mi.pss); 13456 } 13457 if (mi.subitems != null) { 13458 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13459 true, isCompact); 13460 } 13461 } 13462 } 13463 13464 // These are in KB. 13465 static final long[] DUMP_MEM_BUCKETS = new long[] { 13466 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13467 120*1024, 160*1024, 200*1024, 13468 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13469 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13470 }; 13471 13472 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13473 boolean stackLike) { 13474 int start = label.lastIndexOf('.'); 13475 if (start >= 0) start++; 13476 else start = 0; 13477 int end = label.length(); 13478 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13479 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13480 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13481 out.append(bucket); 13482 out.append(stackLike ? "MB." : "MB "); 13483 out.append(label, start, end); 13484 return; 13485 } 13486 } 13487 out.append(memKB/1024); 13488 out.append(stackLike ? "MB." : "MB "); 13489 out.append(label, start, end); 13490 } 13491 13492 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13493 ProcessList.NATIVE_ADJ, 13494 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13495 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13496 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13497 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13498 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13499 }; 13500 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13501 "Native", 13502 "System", "Persistent", "Foreground", 13503 "Visible", "Perceptible", 13504 "Heavy Weight", "Backup", 13505 "A Services", "Home", 13506 "Previous", "B Services", "Cached" 13507 }; 13508 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13509 "native", 13510 "sys", "pers", "fore", 13511 "vis", "percept", 13512 "heavy", "backup", 13513 "servicea", "home", 13514 "prev", "serviceb", "cached" 13515 }; 13516 13517 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13518 long realtime, boolean isCheckinRequest, boolean isCompact) { 13519 if (isCheckinRequest || isCompact) { 13520 // short checkin version 13521 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13522 } else { 13523 pw.println("Applications Memory Usage (kB):"); 13524 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13525 } 13526 } 13527 13528 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13529 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13530 boolean dumpDetails = false; 13531 boolean dumpFullDetails = false; 13532 boolean dumpDalvik = false; 13533 boolean oomOnly = false; 13534 boolean isCompact = false; 13535 boolean localOnly = false; 13536 13537 int opti = 0; 13538 while (opti < args.length) { 13539 String opt = args[opti]; 13540 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13541 break; 13542 } 13543 opti++; 13544 if ("-a".equals(opt)) { 13545 dumpDetails = true; 13546 dumpFullDetails = true; 13547 dumpDalvik = true; 13548 } else if ("-d".equals(opt)) { 13549 dumpDalvik = true; 13550 } else if ("-c".equals(opt)) { 13551 isCompact = true; 13552 } else if ("--oom".equals(opt)) { 13553 oomOnly = true; 13554 } else if ("--local".equals(opt)) { 13555 localOnly = true; 13556 } else if ("-h".equals(opt)) { 13557 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13558 pw.println(" -a: include all available information for each process."); 13559 pw.println(" -d: include dalvik details when dumping process details."); 13560 pw.println(" -c: dump in a compact machine-parseable representation."); 13561 pw.println(" --oom: only show processes organized by oom adj."); 13562 pw.println(" --local: only collect details locally, don't call process."); 13563 pw.println("If [process] is specified it can be the name or "); 13564 pw.println("pid of a specific process to dump."); 13565 return; 13566 } else { 13567 pw.println("Unknown argument: " + opt + "; use -h for help"); 13568 } 13569 } 13570 13571 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13572 long uptime = SystemClock.uptimeMillis(); 13573 long realtime = SystemClock.elapsedRealtime(); 13574 final long[] tmpLong = new long[1]; 13575 13576 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13577 if (procs == null) { 13578 // No Java processes. Maybe they want to print a native process. 13579 if (args != null && args.length > opti 13580 && args[opti].charAt(0) != '-') { 13581 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13582 = new ArrayList<ProcessCpuTracker.Stats>(); 13583 updateCpuStatsNow(); 13584 int findPid = -1; 13585 try { 13586 findPid = Integer.parseInt(args[opti]); 13587 } catch (NumberFormatException e) { 13588 } 13589 synchronized (mProcessCpuThread) { 13590 final int N = mProcessCpuTracker.countStats(); 13591 for (int i=0; i<N; i++) { 13592 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13593 if (st.pid == findPid || (st.baseName != null 13594 && st.baseName.equals(args[opti]))) { 13595 nativeProcs.add(st); 13596 } 13597 } 13598 } 13599 if (nativeProcs.size() > 0) { 13600 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13601 isCompact); 13602 Debug.MemoryInfo mi = null; 13603 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13604 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13605 final int pid = r.pid; 13606 if (!isCheckinRequest && dumpDetails) { 13607 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13608 } 13609 if (mi == null) { 13610 mi = new Debug.MemoryInfo(); 13611 } 13612 if (dumpDetails || (!brief && !oomOnly)) { 13613 Debug.getMemoryInfo(pid, mi); 13614 } else { 13615 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13616 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13617 } 13618 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13619 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13620 if (isCheckinRequest) { 13621 pw.println(); 13622 } 13623 } 13624 return; 13625 } 13626 } 13627 pw.println("No process found for: " + args[opti]); 13628 return; 13629 } 13630 13631 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13632 dumpDetails = true; 13633 } 13634 13635 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13636 13637 String[] innerArgs = new String[args.length-opti]; 13638 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13639 13640 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13641 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13642 long nativePss=0, dalvikPss=0, otherPss=0; 13643 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13644 13645 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13646 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13647 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13648 13649 long totalPss = 0; 13650 long cachedPss = 0; 13651 13652 Debug.MemoryInfo mi = null; 13653 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13654 final ProcessRecord r = procs.get(i); 13655 final IApplicationThread thread; 13656 final int pid; 13657 final int oomAdj; 13658 final boolean hasActivities; 13659 synchronized (this) { 13660 thread = r.thread; 13661 pid = r.pid; 13662 oomAdj = r.getSetAdjWithServices(); 13663 hasActivities = r.activities.size() > 0; 13664 } 13665 if (thread != null) { 13666 if (!isCheckinRequest && dumpDetails) { 13667 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13668 } 13669 if (mi == null) { 13670 mi = new Debug.MemoryInfo(); 13671 } 13672 if (dumpDetails || (!brief && !oomOnly)) { 13673 Debug.getMemoryInfo(pid, mi); 13674 } else { 13675 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13676 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13677 } 13678 if (dumpDetails) { 13679 if (localOnly) { 13680 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13681 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13682 if (isCheckinRequest) { 13683 pw.println(); 13684 } 13685 } else { 13686 try { 13687 pw.flush(); 13688 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13689 dumpDalvik, innerArgs); 13690 } catch (RemoteException e) { 13691 if (!isCheckinRequest) { 13692 pw.println("Got RemoteException!"); 13693 pw.flush(); 13694 } 13695 } 13696 } 13697 } 13698 13699 final long myTotalPss = mi.getTotalPss(); 13700 final long myTotalUss = mi.getTotalUss(); 13701 13702 synchronized (this) { 13703 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13704 // Record this for posterity if the process has been stable. 13705 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13706 } 13707 } 13708 13709 if (!isCheckinRequest && mi != null) { 13710 totalPss += myTotalPss; 13711 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13712 (hasActivities ? " / activities)" : ")"), 13713 r.processName, myTotalPss, pid, hasActivities); 13714 procMems.add(pssItem); 13715 procMemsMap.put(pid, pssItem); 13716 13717 nativePss += mi.nativePss; 13718 dalvikPss += mi.dalvikPss; 13719 otherPss += mi.otherPss; 13720 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13721 long mem = mi.getOtherPss(j); 13722 miscPss[j] += mem; 13723 otherPss -= mem; 13724 } 13725 13726 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13727 cachedPss += myTotalPss; 13728 } 13729 13730 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13731 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13732 || oomIndex == (oomPss.length-1)) { 13733 oomPss[oomIndex] += myTotalPss; 13734 if (oomProcs[oomIndex] == null) { 13735 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13736 } 13737 oomProcs[oomIndex].add(pssItem); 13738 break; 13739 } 13740 } 13741 } 13742 } 13743 } 13744 13745 long nativeProcTotalPss = 0; 13746 13747 if (!isCheckinRequest && procs.size() > 1) { 13748 // If we are showing aggregations, also look for native processes to 13749 // include so that our aggregations are more accurate. 13750 updateCpuStatsNow(); 13751 synchronized (mProcessCpuThread) { 13752 final int N = mProcessCpuTracker.countStats(); 13753 for (int i=0; i<N; i++) { 13754 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13755 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13756 if (mi == null) { 13757 mi = new Debug.MemoryInfo(); 13758 } 13759 if (!brief && !oomOnly) { 13760 Debug.getMemoryInfo(st.pid, mi); 13761 } else { 13762 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13763 mi.nativePrivateDirty = (int)tmpLong[0]; 13764 } 13765 13766 final long myTotalPss = mi.getTotalPss(); 13767 totalPss += myTotalPss; 13768 nativeProcTotalPss += myTotalPss; 13769 13770 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13771 st.name, myTotalPss, st.pid, false); 13772 procMems.add(pssItem); 13773 13774 nativePss += mi.nativePss; 13775 dalvikPss += mi.dalvikPss; 13776 otherPss += mi.otherPss; 13777 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13778 long mem = mi.getOtherPss(j); 13779 miscPss[j] += mem; 13780 otherPss -= mem; 13781 } 13782 oomPss[0] += myTotalPss; 13783 if (oomProcs[0] == null) { 13784 oomProcs[0] = new ArrayList<MemItem>(); 13785 } 13786 oomProcs[0].add(pssItem); 13787 } 13788 } 13789 } 13790 13791 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13792 13793 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13794 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13795 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13796 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13797 String label = Debug.MemoryInfo.getOtherLabel(j); 13798 catMems.add(new MemItem(label, label, miscPss[j], j)); 13799 } 13800 13801 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13802 for (int j=0; j<oomPss.length; j++) { 13803 if (oomPss[j] != 0) { 13804 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13805 : DUMP_MEM_OOM_LABEL[j]; 13806 MemItem item = new MemItem(label, label, oomPss[j], 13807 DUMP_MEM_OOM_ADJ[j]); 13808 item.subitems = oomProcs[j]; 13809 oomMems.add(item); 13810 } 13811 } 13812 13813 if (!brief && !oomOnly && !isCompact) { 13814 pw.println(); 13815 pw.println("Total PSS by process:"); 13816 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13817 pw.println(); 13818 } 13819 if (!isCompact) { 13820 pw.println("Total PSS by OOM adjustment:"); 13821 } 13822 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13823 if (!brief && !oomOnly) { 13824 PrintWriter out = categoryPw != null ? categoryPw : pw; 13825 if (!isCompact) { 13826 out.println(); 13827 out.println("Total PSS by category:"); 13828 } 13829 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13830 } 13831 if (!isCompact) { 13832 pw.println(); 13833 } 13834 MemInfoReader memInfo = new MemInfoReader(); 13835 memInfo.readMemInfo(); 13836 if (nativeProcTotalPss > 0) { 13837 synchronized (this) { 13838 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13839 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13840 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13841 nativeProcTotalPss); 13842 } 13843 } 13844 if (!brief) { 13845 if (!isCompact) { 13846 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13847 pw.print(" kB (status "); 13848 switch (mLastMemoryLevel) { 13849 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13850 pw.println("normal)"); 13851 break; 13852 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13853 pw.println("moderate)"); 13854 break; 13855 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13856 pw.println("low)"); 13857 break; 13858 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13859 pw.println("critical)"); 13860 break; 13861 default: 13862 pw.print(mLastMemoryLevel); 13863 pw.println(")"); 13864 break; 13865 } 13866 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13867 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13868 pw.print(cachedPss); pw.print(" cached pss + "); 13869 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13870 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13871 } else { 13872 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13873 pw.print(cachedPss + memInfo.getCachedSizeKb() 13874 + memInfo.getFreeSizeKb()); pw.print(","); 13875 pw.println(totalPss - cachedPss); 13876 } 13877 } 13878 if (!isCompact) { 13879 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13880 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13881 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13882 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13883 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13884 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13885 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13886 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13887 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13888 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13889 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13890 } 13891 if (!brief) { 13892 if (memInfo.getZramTotalSizeKb() != 0) { 13893 if (!isCompact) { 13894 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13895 pw.print(" kB physical used for "); 13896 pw.print(memInfo.getSwapTotalSizeKb() 13897 - memInfo.getSwapFreeSizeKb()); 13898 pw.print(" kB in swap ("); 13899 pw.print(memInfo.getSwapTotalSizeKb()); 13900 pw.println(" kB total swap)"); 13901 } else { 13902 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13903 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13904 pw.println(memInfo.getSwapFreeSizeKb()); 13905 } 13906 } 13907 final int[] SINGLE_LONG_FORMAT = new int[] { 13908 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13909 }; 13910 long[] longOut = new long[1]; 13911 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13912 SINGLE_LONG_FORMAT, null, longOut, null); 13913 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13914 longOut[0] = 0; 13915 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13916 SINGLE_LONG_FORMAT, null, longOut, null); 13917 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13918 longOut[0] = 0; 13919 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13920 SINGLE_LONG_FORMAT, null, longOut, null); 13921 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13922 longOut[0] = 0; 13923 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13924 SINGLE_LONG_FORMAT, null, longOut, null); 13925 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13926 if (!isCompact) { 13927 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13928 pw.print(" KSM: "); pw.print(sharing); 13929 pw.print(" kB saved from shared "); 13930 pw.print(shared); pw.println(" kB"); 13931 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13932 pw.print(voltile); pw.println(" kB volatile"); 13933 } 13934 pw.print(" Tuning: "); 13935 pw.print(ActivityManager.staticGetMemoryClass()); 13936 pw.print(" (large "); 13937 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13938 pw.print("), oom "); 13939 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13940 pw.print(" kB"); 13941 pw.print(", restore limit "); 13942 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13943 pw.print(" kB"); 13944 if (ActivityManager.isLowRamDeviceStatic()) { 13945 pw.print(" (low-ram)"); 13946 } 13947 if (ActivityManager.isHighEndGfx()) { 13948 pw.print(" (high-end-gfx)"); 13949 } 13950 pw.println(); 13951 } else { 13952 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13953 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13954 pw.println(voltile); 13955 pw.print("tuning,"); 13956 pw.print(ActivityManager.staticGetMemoryClass()); 13957 pw.print(','); 13958 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13959 pw.print(','); 13960 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13961 if (ActivityManager.isLowRamDeviceStatic()) { 13962 pw.print(",low-ram"); 13963 } 13964 if (ActivityManager.isHighEndGfx()) { 13965 pw.print(",high-end-gfx"); 13966 } 13967 pw.println(); 13968 } 13969 } 13970 } 13971 } 13972 13973 /** 13974 * Searches array of arguments for the specified string 13975 * @param args array of argument strings 13976 * @param value value to search for 13977 * @return true if the value is contained in the array 13978 */ 13979 private static boolean scanArgs(String[] args, String value) { 13980 if (args != null) { 13981 for (String arg : args) { 13982 if (value.equals(arg)) { 13983 return true; 13984 } 13985 } 13986 } 13987 return false; 13988 } 13989 13990 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13991 ContentProviderRecord cpr, boolean always) { 13992 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13993 13994 if (!inLaunching || always) { 13995 synchronized (cpr) { 13996 cpr.launchingApp = null; 13997 cpr.notifyAll(); 13998 } 13999 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14000 String names[] = cpr.info.authority.split(";"); 14001 for (int j = 0; j < names.length; j++) { 14002 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14003 } 14004 } 14005 14006 for (int i=0; i<cpr.connections.size(); i++) { 14007 ContentProviderConnection conn = cpr.connections.get(i); 14008 if (conn.waiting) { 14009 // If this connection is waiting for the provider, then we don't 14010 // need to mess with its process unless we are always removing 14011 // or for some reason the provider is not currently launching. 14012 if (inLaunching && !always) { 14013 continue; 14014 } 14015 } 14016 ProcessRecord capp = conn.client; 14017 conn.dead = true; 14018 if (conn.stableCount > 0) { 14019 if (!capp.persistent && capp.thread != null 14020 && capp.pid != 0 14021 && capp.pid != MY_PID) { 14022 capp.kill("depends on provider " 14023 + cpr.name.flattenToShortString() 14024 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14025 } 14026 } else if (capp.thread != null && conn.provider.provider != null) { 14027 try { 14028 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14029 } catch (RemoteException e) { 14030 } 14031 // In the protocol here, we don't expect the client to correctly 14032 // clean up this connection, we'll just remove it. 14033 cpr.connections.remove(i); 14034 conn.client.conProviders.remove(conn); 14035 } 14036 } 14037 14038 if (inLaunching && always) { 14039 mLaunchingProviders.remove(cpr); 14040 } 14041 return inLaunching; 14042 } 14043 14044 /** 14045 * Main code for cleaning up a process when it has gone away. This is 14046 * called both as a result of the process dying, or directly when stopping 14047 * a process when running in single process mode. 14048 */ 14049 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14050 boolean restarting, boolean allowRestart, int index) { 14051 if (index >= 0) { 14052 removeLruProcessLocked(app); 14053 ProcessList.remove(app.pid); 14054 } 14055 14056 mProcessesToGc.remove(app); 14057 mPendingPssProcesses.remove(app); 14058 14059 // Dismiss any open dialogs. 14060 if (app.crashDialog != null && !app.forceCrashReport) { 14061 app.crashDialog.dismiss(); 14062 app.crashDialog = null; 14063 } 14064 if (app.anrDialog != null) { 14065 app.anrDialog.dismiss(); 14066 app.anrDialog = null; 14067 } 14068 if (app.waitDialog != null) { 14069 app.waitDialog.dismiss(); 14070 app.waitDialog = null; 14071 } 14072 14073 app.crashing = false; 14074 app.notResponding = false; 14075 14076 app.resetPackageList(mProcessStats); 14077 app.unlinkDeathRecipient(); 14078 app.makeInactive(mProcessStats); 14079 app.waitingToKill = null; 14080 app.forcingToForeground = null; 14081 updateProcessForegroundLocked(app, false, false); 14082 app.foregroundActivities = false; 14083 app.hasShownUi = false; 14084 app.treatLikeActivity = false; 14085 app.hasAboveClient = false; 14086 app.hasClientActivities = false; 14087 14088 mServices.killServicesLocked(app, allowRestart); 14089 14090 boolean restart = false; 14091 14092 // Remove published content providers. 14093 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14094 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14095 final boolean always = app.bad || !allowRestart; 14096 if (removeDyingProviderLocked(app, cpr, always) || always) { 14097 // We left the provider in the launching list, need to 14098 // restart it. 14099 restart = true; 14100 } 14101 14102 cpr.provider = null; 14103 cpr.proc = null; 14104 } 14105 app.pubProviders.clear(); 14106 14107 // Take care of any launching providers waiting for this process. 14108 if (checkAppInLaunchingProvidersLocked(app, false)) { 14109 restart = true; 14110 } 14111 14112 // Unregister from connected content providers. 14113 if (!app.conProviders.isEmpty()) { 14114 for (int i=0; i<app.conProviders.size(); i++) { 14115 ContentProviderConnection conn = app.conProviders.get(i); 14116 conn.provider.connections.remove(conn); 14117 } 14118 app.conProviders.clear(); 14119 } 14120 14121 // At this point there may be remaining entries in mLaunchingProviders 14122 // where we were the only one waiting, so they are no longer of use. 14123 // Look for these and clean up if found. 14124 // XXX Commented out for now. Trying to figure out a way to reproduce 14125 // the actual situation to identify what is actually going on. 14126 if (false) { 14127 for (int i=0; i<mLaunchingProviders.size(); i++) { 14128 ContentProviderRecord cpr = (ContentProviderRecord) 14129 mLaunchingProviders.get(i); 14130 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14131 synchronized (cpr) { 14132 cpr.launchingApp = null; 14133 cpr.notifyAll(); 14134 } 14135 } 14136 } 14137 } 14138 14139 skipCurrentReceiverLocked(app); 14140 14141 // Unregister any receivers. 14142 for (int i=app.receivers.size()-1; i>=0; i--) { 14143 removeReceiverLocked(app.receivers.valueAt(i)); 14144 } 14145 app.receivers.clear(); 14146 14147 // If the app is undergoing backup, tell the backup manager about it 14148 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14149 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14150 + mBackupTarget.appInfo + " died during backup"); 14151 try { 14152 IBackupManager bm = IBackupManager.Stub.asInterface( 14153 ServiceManager.getService(Context.BACKUP_SERVICE)); 14154 bm.agentDisconnected(app.info.packageName); 14155 } catch (RemoteException e) { 14156 // can't happen; backup manager is local 14157 } 14158 } 14159 14160 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14161 ProcessChangeItem item = mPendingProcessChanges.get(i); 14162 if (item.pid == app.pid) { 14163 mPendingProcessChanges.remove(i); 14164 mAvailProcessChanges.add(item); 14165 } 14166 } 14167 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14168 14169 // If the caller is restarting this app, then leave it in its 14170 // current lists and let the caller take care of it. 14171 if (restarting) { 14172 return; 14173 } 14174 14175 if (!app.persistent || app.isolated) { 14176 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14177 "Removing non-persistent process during cleanup: " + app); 14178 mProcessNames.remove(app.processName, app.uid); 14179 mIsolatedProcesses.remove(app.uid); 14180 if (mHeavyWeightProcess == app) { 14181 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14182 mHeavyWeightProcess.userId, 0)); 14183 mHeavyWeightProcess = null; 14184 } 14185 } else if (!app.removed) { 14186 // This app is persistent, so we need to keep its record around. 14187 // If it is not already on the pending app list, add it there 14188 // and start a new process for it. 14189 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14190 mPersistentStartingProcesses.add(app); 14191 restart = true; 14192 } 14193 } 14194 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14195 "Clean-up removing on hold: " + app); 14196 mProcessesOnHold.remove(app); 14197 14198 if (app == mHomeProcess) { 14199 mHomeProcess = null; 14200 } 14201 if (app == mPreviousProcess) { 14202 mPreviousProcess = null; 14203 } 14204 14205 if (restart && !app.isolated) { 14206 // We have components that still need to be running in the 14207 // process, so re-launch it. 14208 mProcessNames.put(app.processName, app.uid, app); 14209 startProcessLocked(app, "restart", app.processName); 14210 } else if (app.pid > 0 && app.pid != MY_PID) { 14211 // Goodbye! 14212 boolean removed; 14213 synchronized (mPidsSelfLocked) { 14214 mPidsSelfLocked.remove(app.pid); 14215 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14216 } 14217 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14218 if (app.isolated) { 14219 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14220 } 14221 app.setPid(0); 14222 } 14223 } 14224 14225 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14226 // Look through the content providers we are waiting to have launched, 14227 // and if any run in this process then either schedule a restart of 14228 // the process or kill the client waiting for it if this process has 14229 // gone bad. 14230 int NL = mLaunchingProviders.size(); 14231 boolean restart = false; 14232 for (int i=0; i<NL; i++) { 14233 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14234 if (cpr.launchingApp == app) { 14235 if (!alwaysBad && !app.bad) { 14236 restart = true; 14237 } else { 14238 removeDyingProviderLocked(app, cpr, true); 14239 // cpr should have been removed from mLaunchingProviders 14240 NL = mLaunchingProviders.size(); 14241 i--; 14242 } 14243 } 14244 } 14245 return restart; 14246 } 14247 14248 // ========================================================= 14249 // SERVICES 14250 // ========================================================= 14251 14252 @Override 14253 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14254 int flags) { 14255 enforceNotIsolatedCaller("getServices"); 14256 synchronized (this) { 14257 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14258 } 14259 } 14260 14261 @Override 14262 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14263 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14264 synchronized (this) { 14265 return mServices.getRunningServiceControlPanelLocked(name); 14266 } 14267 } 14268 14269 @Override 14270 public ComponentName startService(IApplicationThread caller, Intent service, 14271 String resolvedType, int userId) { 14272 enforceNotIsolatedCaller("startService"); 14273 // Refuse possible leaked file descriptors 14274 if (service != null && service.hasFileDescriptors() == true) { 14275 throw new IllegalArgumentException("File descriptors passed in Intent"); 14276 } 14277 14278 if (DEBUG_SERVICE) 14279 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14280 synchronized(this) { 14281 final int callingPid = Binder.getCallingPid(); 14282 final int callingUid = Binder.getCallingUid(); 14283 final long origId = Binder.clearCallingIdentity(); 14284 ComponentName res = mServices.startServiceLocked(caller, service, 14285 resolvedType, callingPid, callingUid, userId); 14286 Binder.restoreCallingIdentity(origId); 14287 return res; 14288 } 14289 } 14290 14291 ComponentName startServiceInPackage(int uid, 14292 Intent service, String resolvedType, int userId) { 14293 synchronized(this) { 14294 if (DEBUG_SERVICE) 14295 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14296 final long origId = Binder.clearCallingIdentity(); 14297 ComponentName res = mServices.startServiceLocked(null, service, 14298 resolvedType, -1, uid, userId); 14299 Binder.restoreCallingIdentity(origId); 14300 return res; 14301 } 14302 } 14303 14304 @Override 14305 public int stopService(IApplicationThread caller, Intent service, 14306 String resolvedType, int userId) { 14307 enforceNotIsolatedCaller("stopService"); 14308 // Refuse possible leaked file descriptors 14309 if (service != null && service.hasFileDescriptors() == true) { 14310 throw new IllegalArgumentException("File descriptors passed in Intent"); 14311 } 14312 14313 synchronized(this) { 14314 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14315 } 14316 } 14317 14318 @Override 14319 public IBinder peekService(Intent service, String resolvedType) { 14320 enforceNotIsolatedCaller("peekService"); 14321 // Refuse possible leaked file descriptors 14322 if (service != null && service.hasFileDescriptors() == true) { 14323 throw new IllegalArgumentException("File descriptors passed in Intent"); 14324 } 14325 synchronized(this) { 14326 return mServices.peekServiceLocked(service, resolvedType); 14327 } 14328 } 14329 14330 @Override 14331 public boolean stopServiceToken(ComponentName className, IBinder token, 14332 int startId) { 14333 synchronized(this) { 14334 return mServices.stopServiceTokenLocked(className, token, startId); 14335 } 14336 } 14337 14338 @Override 14339 public void setServiceForeground(ComponentName className, IBinder token, 14340 int id, Notification notification, boolean removeNotification) { 14341 synchronized(this) { 14342 mServices.setServiceForegroundLocked(className, token, id, notification, 14343 removeNotification); 14344 } 14345 } 14346 14347 @Override 14348 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14349 boolean requireFull, String name, String callerPackage) { 14350 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14351 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14352 } 14353 14354 int unsafeConvertIncomingUser(int userId) { 14355 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14356 ? mCurrentUserId : userId; 14357 } 14358 14359 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14360 int allowMode, String name, String callerPackage) { 14361 final int callingUserId = UserHandle.getUserId(callingUid); 14362 if (callingUserId == userId) { 14363 return userId; 14364 } 14365 14366 // Note that we may be accessing mCurrentUserId outside of a lock... 14367 // shouldn't be a big deal, if this is being called outside 14368 // of a locked context there is intrinsically a race with 14369 // the value the caller will receive and someone else changing it. 14370 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14371 // we will switch to the calling user if access to the current user fails. 14372 int targetUserId = unsafeConvertIncomingUser(userId); 14373 14374 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14375 final boolean allow; 14376 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14377 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14378 // If the caller has this permission, they always pass go. And collect $200. 14379 allow = true; 14380 } else if (allowMode == ALLOW_FULL_ONLY) { 14381 // We require full access, sucks to be you. 14382 allow = false; 14383 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14384 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14385 // If the caller does not have either permission, they are always doomed. 14386 allow = false; 14387 } else if (allowMode == ALLOW_NON_FULL) { 14388 // We are blanket allowing non-full access, you lucky caller! 14389 allow = true; 14390 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14391 // We may or may not allow this depending on whether the two users are 14392 // in the same profile. 14393 synchronized (mUserProfileGroupIdsSelfLocked) { 14394 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14395 UserInfo.NO_PROFILE_GROUP_ID); 14396 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14397 UserInfo.NO_PROFILE_GROUP_ID); 14398 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14399 && callingProfile == targetProfile; 14400 } 14401 } else { 14402 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14403 } 14404 if (!allow) { 14405 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14406 // In this case, they would like to just execute as their 14407 // owner user instead of failing. 14408 targetUserId = callingUserId; 14409 } else { 14410 StringBuilder builder = new StringBuilder(128); 14411 builder.append("Permission Denial: "); 14412 builder.append(name); 14413 if (callerPackage != null) { 14414 builder.append(" from "); 14415 builder.append(callerPackage); 14416 } 14417 builder.append(" asks to run as user "); 14418 builder.append(userId); 14419 builder.append(" but is calling from user "); 14420 builder.append(UserHandle.getUserId(callingUid)); 14421 builder.append("; this requires "); 14422 builder.append(INTERACT_ACROSS_USERS_FULL); 14423 if (allowMode != ALLOW_FULL_ONLY) { 14424 builder.append(" or "); 14425 builder.append(INTERACT_ACROSS_USERS); 14426 } 14427 String msg = builder.toString(); 14428 Slog.w(TAG, msg); 14429 throw new SecurityException(msg); 14430 } 14431 } 14432 } 14433 if (!allowAll && targetUserId < 0) { 14434 throw new IllegalArgumentException( 14435 "Call does not support special user #" + targetUserId); 14436 } 14437 return targetUserId; 14438 } 14439 14440 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14441 String className, int flags) { 14442 boolean result = false; 14443 // For apps that don't have pre-defined UIDs, check for permission 14444 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14445 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14446 if (ActivityManager.checkUidPermission( 14447 INTERACT_ACROSS_USERS, 14448 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14449 ComponentName comp = new ComponentName(aInfo.packageName, className); 14450 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14451 + " requests FLAG_SINGLE_USER, but app does not hold " 14452 + INTERACT_ACROSS_USERS; 14453 Slog.w(TAG, msg); 14454 throw new SecurityException(msg); 14455 } 14456 // Permission passed 14457 result = true; 14458 } 14459 } else if ("system".equals(componentProcessName)) { 14460 result = true; 14461 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14462 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14463 // Phone app is allowed to export singleuser providers. 14464 result = true; 14465 } else { 14466 // App with pre-defined UID, check if it's a persistent app 14467 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14468 } 14469 if (DEBUG_MU) { 14470 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14471 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14472 } 14473 return result; 14474 } 14475 14476 /** 14477 * Checks to see if the caller is in the same app as the singleton 14478 * component, or the component is in a special app. It allows special apps 14479 * to export singleton components but prevents exporting singleton 14480 * components for regular apps. 14481 */ 14482 boolean isValidSingletonCall(int callingUid, int componentUid) { 14483 int componentAppId = UserHandle.getAppId(componentUid); 14484 return UserHandle.isSameApp(callingUid, componentUid) 14485 || componentAppId == Process.SYSTEM_UID 14486 || componentAppId == Process.PHONE_UID 14487 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14488 == PackageManager.PERMISSION_GRANTED; 14489 } 14490 14491 public int bindService(IApplicationThread caller, IBinder token, 14492 Intent service, String resolvedType, 14493 IServiceConnection connection, int flags, int userId) { 14494 enforceNotIsolatedCaller("bindService"); 14495 // Refuse possible leaked file descriptors 14496 if (service != null && service.hasFileDescriptors() == true) { 14497 throw new IllegalArgumentException("File descriptors passed in Intent"); 14498 } 14499 14500 synchronized(this) { 14501 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14502 connection, flags, userId); 14503 } 14504 } 14505 14506 public boolean unbindService(IServiceConnection connection) { 14507 synchronized (this) { 14508 return mServices.unbindServiceLocked(connection); 14509 } 14510 } 14511 14512 public void publishService(IBinder token, Intent intent, IBinder service) { 14513 // Refuse possible leaked file descriptors 14514 if (intent != null && intent.hasFileDescriptors() == true) { 14515 throw new IllegalArgumentException("File descriptors passed in Intent"); 14516 } 14517 14518 synchronized(this) { 14519 if (!(token instanceof ServiceRecord)) { 14520 throw new IllegalArgumentException("Invalid service token"); 14521 } 14522 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14523 } 14524 } 14525 14526 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14527 // Refuse possible leaked file descriptors 14528 if (intent != null && intent.hasFileDescriptors() == true) { 14529 throw new IllegalArgumentException("File descriptors passed in Intent"); 14530 } 14531 14532 synchronized(this) { 14533 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14534 } 14535 } 14536 14537 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14538 synchronized(this) { 14539 if (!(token instanceof ServiceRecord)) { 14540 throw new IllegalArgumentException("Invalid service token"); 14541 } 14542 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14543 } 14544 } 14545 14546 // ========================================================= 14547 // BACKUP AND RESTORE 14548 // ========================================================= 14549 14550 // Cause the target app to be launched if necessary and its backup agent 14551 // instantiated. The backup agent will invoke backupAgentCreated() on the 14552 // activity manager to announce its creation. 14553 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14554 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14555 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14556 14557 synchronized(this) { 14558 // !!! TODO: currently no check here that we're already bound 14559 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14560 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14561 synchronized (stats) { 14562 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14563 } 14564 14565 // Backup agent is now in use, its package can't be stopped. 14566 try { 14567 AppGlobals.getPackageManager().setPackageStoppedState( 14568 app.packageName, false, UserHandle.getUserId(app.uid)); 14569 } catch (RemoteException e) { 14570 } catch (IllegalArgumentException e) { 14571 Slog.w(TAG, "Failed trying to unstop package " 14572 + app.packageName + ": " + e); 14573 } 14574 14575 BackupRecord r = new BackupRecord(ss, app, backupMode); 14576 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14577 ? new ComponentName(app.packageName, app.backupAgentName) 14578 : new ComponentName("android", "FullBackupAgent"); 14579 // startProcessLocked() returns existing proc's record if it's already running 14580 ProcessRecord proc = startProcessLocked(app.processName, app, 14581 false, 0, "backup", hostingName, false, false, false); 14582 if (proc == null) { 14583 Slog.e(TAG, "Unable to start backup agent process " + r); 14584 return false; 14585 } 14586 14587 r.app = proc; 14588 mBackupTarget = r; 14589 mBackupAppName = app.packageName; 14590 14591 // Try not to kill the process during backup 14592 updateOomAdjLocked(proc); 14593 14594 // If the process is already attached, schedule the creation of the backup agent now. 14595 // If it is not yet live, this will be done when it attaches to the framework. 14596 if (proc.thread != null) { 14597 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14598 try { 14599 proc.thread.scheduleCreateBackupAgent(app, 14600 compatibilityInfoForPackageLocked(app), backupMode); 14601 } catch (RemoteException e) { 14602 // Will time out on the backup manager side 14603 } 14604 } else { 14605 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14606 } 14607 // Invariants: at this point, the target app process exists and the application 14608 // is either already running or in the process of coming up. mBackupTarget and 14609 // mBackupAppName describe the app, so that when it binds back to the AM we 14610 // know that it's scheduled for a backup-agent operation. 14611 } 14612 14613 return true; 14614 } 14615 14616 @Override 14617 public void clearPendingBackup() { 14618 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14619 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14620 14621 synchronized (this) { 14622 mBackupTarget = null; 14623 mBackupAppName = null; 14624 } 14625 } 14626 14627 // A backup agent has just come up 14628 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14629 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14630 + " = " + agent); 14631 14632 synchronized(this) { 14633 if (!agentPackageName.equals(mBackupAppName)) { 14634 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14635 return; 14636 } 14637 } 14638 14639 long oldIdent = Binder.clearCallingIdentity(); 14640 try { 14641 IBackupManager bm = IBackupManager.Stub.asInterface( 14642 ServiceManager.getService(Context.BACKUP_SERVICE)); 14643 bm.agentConnected(agentPackageName, agent); 14644 } catch (RemoteException e) { 14645 // can't happen; the backup manager service is local 14646 } catch (Exception e) { 14647 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14648 e.printStackTrace(); 14649 } finally { 14650 Binder.restoreCallingIdentity(oldIdent); 14651 } 14652 } 14653 14654 // done with this agent 14655 public void unbindBackupAgent(ApplicationInfo appInfo) { 14656 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14657 if (appInfo == null) { 14658 Slog.w(TAG, "unbind backup agent for null app"); 14659 return; 14660 } 14661 14662 synchronized(this) { 14663 try { 14664 if (mBackupAppName == null) { 14665 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14666 return; 14667 } 14668 14669 if (!mBackupAppName.equals(appInfo.packageName)) { 14670 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14671 return; 14672 } 14673 14674 // Not backing this app up any more; reset its OOM adjustment 14675 final ProcessRecord proc = mBackupTarget.app; 14676 updateOomAdjLocked(proc); 14677 14678 // If the app crashed during backup, 'thread' will be null here 14679 if (proc.thread != null) { 14680 try { 14681 proc.thread.scheduleDestroyBackupAgent(appInfo, 14682 compatibilityInfoForPackageLocked(appInfo)); 14683 } catch (Exception e) { 14684 Slog.e(TAG, "Exception when unbinding backup agent:"); 14685 e.printStackTrace(); 14686 } 14687 } 14688 } finally { 14689 mBackupTarget = null; 14690 mBackupAppName = null; 14691 } 14692 } 14693 } 14694 // ========================================================= 14695 // BROADCASTS 14696 // ========================================================= 14697 14698 private final List getStickiesLocked(String action, IntentFilter filter, 14699 List cur, int userId) { 14700 final ContentResolver resolver = mContext.getContentResolver(); 14701 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14702 if (stickies == null) { 14703 return cur; 14704 } 14705 final ArrayList<Intent> list = stickies.get(action); 14706 if (list == null) { 14707 return cur; 14708 } 14709 int N = list.size(); 14710 for (int i=0; i<N; i++) { 14711 Intent intent = list.get(i); 14712 if (filter.match(resolver, intent, true, TAG) >= 0) { 14713 if (cur == null) { 14714 cur = new ArrayList<Intent>(); 14715 } 14716 cur.add(intent); 14717 } 14718 } 14719 return cur; 14720 } 14721 14722 boolean isPendingBroadcastProcessLocked(int pid) { 14723 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14724 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14725 } 14726 14727 void skipPendingBroadcastLocked(int pid) { 14728 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14729 for (BroadcastQueue queue : mBroadcastQueues) { 14730 queue.skipPendingBroadcastLocked(pid); 14731 } 14732 } 14733 14734 // The app just attached; send any pending broadcasts that it should receive 14735 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14736 boolean didSomething = false; 14737 for (BroadcastQueue queue : mBroadcastQueues) { 14738 didSomething |= queue.sendPendingBroadcastsLocked(app); 14739 } 14740 return didSomething; 14741 } 14742 14743 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14744 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14745 enforceNotIsolatedCaller("registerReceiver"); 14746 int callingUid; 14747 int callingPid; 14748 synchronized(this) { 14749 ProcessRecord callerApp = null; 14750 if (caller != null) { 14751 callerApp = getRecordForAppLocked(caller); 14752 if (callerApp == null) { 14753 throw new SecurityException( 14754 "Unable to find app for caller " + caller 14755 + " (pid=" + Binder.getCallingPid() 14756 + ") when registering receiver " + receiver); 14757 } 14758 if (callerApp.info.uid != Process.SYSTEM_UID && 14759 !callerApp.pkgList.containsKey(callerPackage) && 14760 !"android".equals(callerPackage)) { 14761 throw new SecurityException("Given caller package " + callerPackage 14762 + " is not running in process " + callerApp); 14763 } 14764 callingUid = callerApp.info.uid; 14765 callingPid = callerApp.pid; 14766 } else { 14767 callerPackage = null; 14768 callingUid = Binder.getCallingUid(); 14769 callingPid = Binder.getCallingPid(); 14770 } 14771 14772 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14773 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14774 14775 List allSticky = null; 14776 14777 // Look for any matching sticky broadcasts... 14778 Iterator actions = filter.actionsIterator(); 14779 if (actions != null) { 14780 while (actions.hasNext()) { 14781 String action = (String)actions.next(); 14782 allSticky = getStickiesLocked(action, filter, allSticky, 14783 UserHandle.USER_ALL); 14784 allSticky = getStickiesLocked(action, filter, allSticky, 14785 UserHandle.getUserId(callingUid)); 14786 } 14787 } else { 14788 allSticky = getStickiesLocked(null, filter, allSticky, 14789 UserHandle.USER_ALL); 14790 allSticky = getStickiesLocked(null, filter, allSticky, 14791 UserHandle.getUserId(callingUid)); 14792 } 14793 14794 // The first sticky in the list is returned directly back to 14795 // the client. 14796 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14797 14798 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14799 + ": " + sticky); 14800 14801 if (receiver == null) { 14802 return sticky; 14803 } 14804 14805 ReceiverList rl 14806 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14807 if (rl == null) { 14808 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14809 userId, receiver); 14810 if (rl.app != null) { 14811 rl.app.receivers.add(rl); 14812 } else { 14813 try { 14814 receiver.asBinder().linkToDeath(rl, 0); 14815 } catch (RemoteException e) { 14816 return sticky; 14817 } 14818 rl.linkedToDeath = true; 14819 } 14820 mRegisteredReceivers.put(receiver.asBinder(), rl); 14821 } else if (rl.uid != callingUid) { 14822 throw new IllegalArgumentException( 14823 "Receiver requested to register for uid " + callingUid 14824 + " was previously registered for uid " + rl.uid); 14825 } else if (rl.pid != callingPid) { 14826 throw new IllegalArgumentException( 14827 "Receiver requested to register for pid " + callingPid 14828 + " was previously registered for pid " + rl.pid); 14829 } else if (rl.userId != userId) { 14830 throw new IllegalArgumentException( 14831 "Receiver requested to register for user " + userId 14832 + " was previously registered for user " + rl.userId); 14833 } 14834 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14835 permission, callingUid, userId); 14836 rl.add(bf); 14837 if (!bf.debugCheck()) { 14838 Slog.w(TAG, "==> For Dynamic broadast"); 14839 } 14840 mReceiverResolver.addFilter(bf); 14841 14842 // Enqueue broadcasts for all existing stickies that match 14843 // this filter. 14844 if (allSticky != null) { 14845 ArrayList receivers = new ArrayList(); 14846 receivers.add(bf); 14847 14848 int N = allSticky.size(); 14849 for (int i=0; i<N; i++) { 14850 Intent intent = (Intent)allSticky.get(i); 14851 BroadcastQueue queue = broadcastQueueForIntent(intent); 14852 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14853 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14854 null, null, false, true, true, -1); 14855 queue.enqueueParallelBroadcastLocked(r); 14856 queue.scheduleBroadcastsLocked(); 14857 } 14858 } 14859 14860 return sticky; 14861 } 14862 } 14863 14864 public void unregisterReceiver(IIntentReceiver receiver) { 14865 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14866 14867 final long origId = Binder.clearCallingIdentity(); 14868 try { 14869 boolean doTrim = false; 14870 14871 synchronized(this) { 14872 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14873 if (rl != null) { 14874 if (rl.curBroadcast != null) { 14875 BroadcastRecord r = rl.curBroadcast; 14876 final boolean doNext = finishReceiverLocked( 14877 receiver.asBinder(), r.resultCode, r.resultData, 14878 r.resultExtras, r.resultAbort); 14879 if (doNext) { 14880 doTrim = true; 14881 r.queue.processNextBroadcast(false); 14882 } 14883 } 14884 14885 if (rl.app != null) { 14886 rl.app.receivers.remove(rl); 14887 } 14888 removeReceiverLocked(rl); 14889 if (rl.linkedToDeath) { 14890 rl.linkedToDeath = false; 14891 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14892 } 14893 } 14894 } 14895 14896 // If we actually concluded any broadcasts, we might now be able 14897 // to trim the recipients' apps from our working set 14898 if (doTrim) { 14899 trimApplications(); 14900 return; 14901 } 14902 14903 } finally { 14904 Binder.restoreCallingIdentity(origId); 14905 } 14906 } 14907 14908 void removeReceiverLocked(ReceiverList rl) { 14909 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14910 int N = rl.size(); 14911 for (int i=0; i<N; i++) { 14912 mReceiverResolver.removeFilter(rl.get(i)); 14913 } 14914 } 14915 14916 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14917 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14918 ProcessRecord r = mLruProcesses.get(i); 14919 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14920 try { 14921 r.thread.dispatchPackageBroadcast(cmd, packages); 14922 } catch (RemoteException ex) { 14923 } 14924 } 14925 } 14926 } 14927 14928 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14929 int[] users) { 14930 List<ResolveInfo> receivers = null; 14931 try { 14932 HashSet<ComponentName> singleUserReceivers = null; 14933 boolean scannedFirstReceivers = false; 14934 for (int user : users) { 14935 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14936 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14937 if (user != 0 && newReceivers != null) { 14938 // If this is not the primary user, we need to check for 14939 // any receivers that should be filtered out. 14940 for (int i=0; i<newReceivers.size(); i++) { 14941 ResolveInfo ri = newReceivers.get(i); 14942 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14943 newReceivers.remove(i); 14944 i--; 14945 } 14946 } 14947 } 14948 if (newReceivers != null && newReceivers.size() == 0) { 14949 newReceivers = null; 14950 } 14951 if (receivers == null) { 14952 receivers = newReceivers; 14953 } else if (newReceivers != null) { 14954 // We need to concatenate the additional receivers 14955 // found with what we have do far. This would be easy, 14956 // but we also need to de-dup any receivers that are 14957 // singleUser. 14958 if (!scannedFirstReceivers) { 14959 // Collect any single user receivers we had already retrieved. 14960 scannedFirstReceivers = true; 14961 for (int i=0; i<receivers.size(); i++) { 14962 ResolveInfo ri = receivers.get(i); 14963 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14964 ComponentName cn = new ComponentName( 14965 ri.activityInfo.packageName, ri.activityInfo.name); 14966 if (singleUserReceivers == null) { 14967 singleUserReceivers = new HashSet<ComponentName>(); 14968 } 14969 singleUserReceivers.add(cn); 14970 } 14971 } 14972 } 14973 // Add the new results to the existing results, tracking 14974 // and de-dupping single user receivers. 14975 for (int i=0; i<newReceivers.size(); i++) { 14976 ResolveInfo ri = newReceivers.get(i); 14977 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14978 ComponentName cn = new ComponentName( 14979 ri.activityInfo.packageName, ri.activityInfo.name); 14980 if (singleUserReceivers == null) { 14981 singleUserReceivers = new HashSet<ComponentName>(); 14982 } 14983 if (!singleUserReceivers.contains(cn)) { 14984 singleUserReceivers.add(cn); 14985 receivers.add(ri); 14986 } 14987 } else { 14988 receivers.add(ri); 14989 } 14990 } 14991 } 14992 } 14993 } catch (RemoteException ex) { 14994 // pm is in same process, this will never happen. 14995 } 14996 return receivers; 14997 } 14998 14999 private final int broadcastIntentLocked(ProcessRecord callerApp, 15000 String callerPackage, Intent intent, String resolvedType, 15001 IIntentReceiver resultTo, int resultCode, String resultData, 15002 Bundle map, String requiredPermission, int appOp, 15003 boolean ordered, boolean sticky, int callingPid, int callingUid, 15004 int userId) { 15005 intent = new Intent(intent); 15006 15007 // By default broadcasts do not go to stopped apps. 15008 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15009 15010 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15011 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15012 + " ordered=" + ordered + " userid=" + userId); 15013 if ((resultTo != null) && !ordered) { 15014 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15015 } 15016 15017 userId = handleIncomingUser(callingPid, callingUid, userId, 15018 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15019 15020 // Make sure that the user who is receiving this broadcast is started. 15021 // If not, we will just skip it. 15022 15023 15024 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15025 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15026 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15027 Slog.w(TAG, "Skipping broadcast of " + intent 15028 + ": user " + userId + " is stopped"); 15029 return ActivityManager.BROADCAST_SUCCESS; 15030 } 15031 } 15032 15033 /* 15034 * Prevent non-system code (defined here to be non-persistent 15035 * processes) from sending protected broadcasts. 15036 */ 15037 int callingAppId = UserHandle.getAppId(callingUid); 15038 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15039 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15040 || callingAppId == Process.NFC_UID || callingUid == 0) { 15041 // Always okay. 15042 } else if (callerApp == null || !callerApp.persistent) { 15043 try { 15044 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15045 intent.getAction())) { 15046 String msg = "Permission Denial: not allowed to send broadcast " 15047 + intent.getAction() + " from pid=" 15048 + callingPid + ", uid=" + callingUid; 15049 Slog.w(TAG, msg); 15050 throw new SecurityException(msg); 15051 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15052 // Special case for compatibility: we don't want apps to send this, 15053 // but historically it has not been protected and apps may be using it 15054 // to poke their own app widget. So, instead of making it protected, 15055 // just limit it to the caller. 15056 if (callerApp == null) { 15057 String msg = "Permission Denial: not allowed to send broadcast " 15058 + intent.getAction() + " from unknown caller."; 15059 Slog.w(TAG, msg); 15060 throw new SecurityException(msg); 15061 } else if (intent.getComponent() != null) { 15062 // They are good enough to send to an explicit component... verify 15063 // it is being sent to the calling app. 15064 if (!intent.getComponent().getPackageName().equals( 15065 callerApp.info.packageName)) { 15066 String msg = "Permission Denial: not allowed to send broadcast " 15067 + intent.getAction() + " to " 15068 + intent.getComponent().getPackageName() + " from " 15069 + callerApp.info.packageName; 15070 Slog.w(TAG, msg); 15071 throw new SecurityException(msg); 15072 } 15073 } else { 15074 // Limit broadcast to their own package. 15075 intent.setPackage(callerApp.info.packageName); 15076 } 15077 } 15078 } catch (RemoteException e) { 15079 Slog.w(TAG, "Remote exception", e); 15080 return ActivityManager.BROADCAST_SUCCESS; 15081 } 15082 } 15083 15084 // Handle special intents: if this broadcast is from the package 15085 // manager about a package being removed, we need to remove all of 15086 // its activities from the history stack. 15087 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15088 intent.getAction()); 15089 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15090 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15091 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15092 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15093 || uidRemoved) { 15094 if (checkComponentPermission( 15095 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15096 callingPid, callingUid, -1, true) 15097 == PackageManager.PERMISSION_GRANTED) { 15098 if (uidRemoved) { 15099 final Bundle intentExtras = intent.getExtras(); 15100 final int uid = intentExtras != null 15101 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15102 if (uid >= 0) { 15103 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15104 synchronized (bs) { 15105 bs.removeUidStatsLocked(uid); 15106 } 15107 mAppOpsService.uidRemoved(uid); 15108 } 15109 } else { 15110 // If resources are unavailable just force stop all 15111 // those packages and flush the attribute cache as well. 15112 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15113 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15114 if (list != null && (list.length > 0)) { 15115 for (String pkg : list) { 15116 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15117 "storage unmount"); 15118 } 15119 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15120 sendPackageBroadcastLocked( 15121 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15122 } 15123 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15124 intent.getAction())) { 15125 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15126 } else { 15127 Uri data = intent.getData(); 15128 String ssp; 15129 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15130 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15131 intent.getAction()); 15132 boolean fullUninstall = removed && 15133 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15134 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15135 forceStopPackageLocked(ssp, UserHandle.getAppId( 15136 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15137 false, fullUninstall, userId, 15138 removed ? "pkg removed" : "pkg changed"); 15139 } 15140 if (removed) { 15141 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15142 new String[] {ssp}, userId); 15143 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15144 mAppOpsService.packageRemoved( 15145 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15146 15147 // Remove all permissions granted from/to this package 15148 removeUriPermissionsForPackageLocked(ssp, userId, true); 15149 } 15150 } 15151 } 15152 } 15153 } 15154 } else { 15155 String msg = "Permission Denial: " + intent.getAction() 15156 + " broadcast from " + callerPackage + " (pid=" + callingPid 15157 + ", uid=" + callingUid + ")" 15158 + " requires " 15159 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15160 Slog.w(TAG, msg); 15161 throw new SecurityException(msg); 15162 } 15163 15164 // Special case for adding a package: by default turn on compatibility 15165 // mode. 15166 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15167 Uri data = intent.getData(); 15168 String ssp; 15169 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15170 mCompatModePackages.handlePackageAddedLocked(ssp, 15171 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15172 } 15173 } 15174 15175 /* 15176 * If this is the time zone changed action, queue up a message that will reset the timezone 15177 * of all currently running processes. This message will get queued up before the broadcast 15178 * happens. 15179 */ 15180 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15181 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15182 } 15183 15184 /* 15185 * If the user set the time, let all running processes know. 15186 */ 15187 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15188 final int is24Hour = intent.getBooleanExtra( 15189 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15190 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15191 } 15192 15193 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15194 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15195 } 15196 15197 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15198 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15199 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15200 } 15201 15202 // Add to the sticky list if requested. 15203 if (sticky) { 15204 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15205 callingPid, callingUid) 15206 != PackageManager.PERMISSION_GRANTED) { 15207 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15208 + callingPid + ", uid=" + callingUid 15209 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15210 Slog.w(TAG, msg); 15211 throw new SecurityException(msg); 15212 } 15213 if (requiredPermission != null) { 15214 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15215 + " and enforce permission " + requiredPermission); 15216 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15217 } 15218 if (intent.getComponent() != null) { 15219 throw new SecurityException( 15220 "Sticky broadcasts can't target a specific component"); 15221 } 15222 // We use userId directly here, since the "all" target is maintained 15223 // as a separate set of sticky broadcasts. 15224 if (userId != UserHandle.USER_ALL) { 15225 // But first, if this is not a broadcast to all users, then 15226 // make sure it doesn't conflict with an existing broadcast to 15227 // all users. 15228 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15229 UserHandle.USER_ALL); 15230 if (stickies != null) { 15231 ArrayList<Intent> list = stickies.get(intent.getAction()); 15232 if (list != null) { 15233 int N = list.size(); 15234 int i; 15235 for (i=0; i<N; i++) { 15236 if (intent.filterEquals(list.get(i))) { 15237 throw new IllegalArgumentException( 15238 "Sticky broadcast " + intent + " for user " 15239 + userId + " conflicts with existing global broadcast"); 15240 } 15241 } 15242 } 15243 } 15244 } 15245 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15246 if (stickies == null) { 15247 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15248 mStickyBroadcasts.put(userId, stickies); 15249 } 15250 ArrayList<Intent> list = stickies.get(intent.getAction()); 15251 if (list == null) { 15252 list = new ArrayList<Intent>(); 15253 stickies.put(intent.getAction(), list); 15254 } 15255 int N = list.size(); 15256 int i; 15257 for (i=0; i<N; i++) { 15258 if (intent.filterEquals(list.get(i))) { 15259 // This sticky already exists, replace it. 15260 list.set(i, new Intent(intent)); 15261 break; 15262 } 15263 } 15264 if (i >= N) { 15265 list.add(new Intent(intent)); 15266 } 15267 } 15268 15269 int[] users; 15270 if (userId == UserHandle.USER_ALL) { 15271 // Caller wants broadcast to go to all started users. 15272 users = mStartedUserArray; 15273 } else { 15274 // Caller wants broadcast to go to one specific user. 15275 users = new int[] {userId}; 15276 } 15277 15278 // Figure out who all will receive this broadcast. 15279 List receivers = null; 15280 List<BroadcastFilter> registeredReceivers = null; 15281 // Need to resolve the intent to interested receivers... 15282 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15283 == 0) { 15284 receivers = collectReceiverComponents(intent, resolvedType, users); 15285 } 15286 if (intent.getComponent() == null) { 15287 registeredReceivers = mReceiverResolver.queryIntent(intent, 15288 resolvedType, false, userId); 15289 } 15290 15291 final boolean replacePending = 15292 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15293 15294 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15295 + " replacePending=" + replacePending); 15296 15297 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15298 if (!ordered && NR > 0) { 15299 // If we are not serializing this broadcast, then send the 15300 // registered receivers separately so they don't wait for the 15301 // components to be launched. 15302 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15303 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15304 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15305 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15306 ordered, sticky, false, userId); 15307 if (DEBUG_BROADCAST) Slog.v( 15308 TAG, "Enqueueing parallel broadcast " + r); 15309 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15310 if (!replaced) { 15311 queue.enqueueParallelBroadcastLocked(r); 15312 queue.scheduleBroadcastsLocked(); 15313 } 15314 registeredReceivers = null; 15315 NR = 0; 15316 } 15317 15318 // Merge into one list. 15319 int ir = 0; 15320 if (receivers != null) { 15321 // A special case for PACKAGE_ADDED: do not allow the package 15322 // being added to see this broadcast. This prevents them from 15323 // using this as a back door to get run as soon as they are 15324 // installed. Maybe in the future we want to have a special install 15325 // broadcast or such for apps, but we'd like to deliberately make 15326 // this decision. 15327 String skipPackages[] = null; 15328 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15329 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15330 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15331 Uri data = intent.getData(); 15332 if (data != null) { 15333 String pkgName = data.getSchemeSpecificPart(); 15334 if (pkgName != null) { 15335 skipPackages = new String[] { pkgName }; 15336 } 15337 } 15338 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15339 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15340 } 15341 if (skipPackages != null && (skipPackages.length > 0)) { 15342 for (String skipPackage : skipPackages) { 15343 if (skipPackage != null) { 15344 int NT = receivers.size(); 15345 for (int it=0; it<NT; it++) { 15346 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15347 if (curt.activityInfo.packageName.equals(skipPackage)) { 15348 receivers.remove(it); 15349 it--; 15350 NT--; 15351 } 15352 } 15353 } 15354 } 15355 } 15356 15357 int NT = receivers != null ? receivers.size() : 0; 15358 int it = 0; 15359 ResolveInfo curt = null; 15360 BroadcastFilter curr = null; 15361 while (it < NT && ir < NR) { 15362 if (curt == null) { 15363 curt = (ResolveInfo)receivers.get(it); 15364 } 15365 if (curr == null) { 15366 curr = registeredReceivers.get(ir); 15367 } 15368 if (curr.getPriority() >= curt.priority) { 15369 // Insert this broadcast record into the final list. 15370 receivers.add(it, curr); 15371 ir++; 15372 curr = null; 15373 it++; 15374 NT++; 15375 } else { 15376 // Skip to the next ResolveInfo in the final list. 15377 it++; 15378 curt = null; 15379 } 15380 } 15381 } 15382 while (ir < NR) { 15383 if (receivers == null) { 15384 receivers = new ArrayList(); 15385 } 15386 receivers.add(registeredReceivers.get(ir)); 15387 ir++; 15388 } 15389 15390 if ((receivers != null && receivers.size() > 0) 15391 || resultTo != null) { 15392 BroadcastQueue queue = broadcastQueueForIntent(intent); 15393 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15394 callerPackage, callingPid, callingUid, resolvedType, 15395 requiredPermission, appOp, receivers, resultTo, resultCode, 15396 resultData, map, ordered, sticky, false, userId); 15397 if (DEBUG_BROADCAST) Slog.v( 15398 TAG, "Enqueueing ordered broadcast " + r 15399 + ": prev had " + queue.mOrderedBroadcasts.size()); 15400 if (DEBUG_BROADCAST) { 15401 int seq = r.intent.getIntExtra("seq", -1); 15402 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15403 } 15404 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15405 if (!replaced) { 15406 queue.enqueueOrderedBroadcastLocked(r); 15407 queue.scheduleBroadcastsLocked(); 15408 } 15409 } 15410 15411 return ActivityManager.BROADCAST_SUCCESS; 15412 } 15413 15414 final Intent verifyBroadcastLocked(Intent intent) { 15415 // Refuse possible leaked file descriptors 15416 if (intent != null && intent.hasFileDescriptors() == true) { 15417 throw new IllegalArgumentException("File descriptors passed in Intent"); 15418 } 15419 15420 int flags = intent.getFlags(); 15421 15422 if (!mProcessesReady) { 15423 // if the caller really truly claims to know what they're doing, go 15424 // ahead and allow the broadcast without launching any receivers 15425 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15426 intent = new Intent(intent); 15427 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15428 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15429 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15430 + " before boot completion"); 15431 throw new IllegalStateException("Cannot broadcast before boot completed"); 15432 } 15433 } 15434 15435 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15436 throw new IllegalArgumentException( 15437 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15438 } 15439 15440 return intent; 15441 } 15442 15443 public final int broadcastIntent(IApplicationThread caller, 15444 Intent intent, String resolvedType, IIntentReceiver resultTo, 15445 int resultCode, String resultData, Bundle map, 15446 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15447 enforceNotIsolatedCaller("broadcastIntent"); 15448 synchronized(this) { 15449 intent = verifyBroadcastLocked(intent); 15450 15451 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15452 final int callingPid = Binder.getCallingPid(); 15453 final int callingUid = Binder.getCallingUid(); 15454 final long origId = Binder.clearCallingIdentity(); 15455 int res = broadcastIntentLocked(callerApp, 15456 callerApp != null ? callerApp.info.packageName : null, 15457 intent, resolvedType, resultTo, 15458 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15459 callingPid, callingUid, userId); 15460 Binder.restoreCallingIdentity(origId); 15461 return res; 15462 } 15463 } 15464 15465 int broadcastIntentInPackage(String packageName, int uid, 15466 Intent intent, String resolvedType, IIntentReceiver resultTo, 15467 int resultCode, String resultData, Bundle map, 15468 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15469 synchronized(this) { 15470 intent = verifyBroadcastLocked(intent); 15471 15472 final long origId = Binder.clearCallingIdentity(); 15473 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15474 resultTo, resultCode, resultData, map, requiredPermission, 15475 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15476 Binder.restoreCallingIdentity(origId); 15477 return res; 15478 } 15479 } 15480 15481 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15482 // Refuse possible leaked file descriptors 15483 if (intent != null && intent.hasFileDescriptors() == true) { 15484 throw new IllegalArgumentException("File descriptors passed in Intent"); 15485 } 15486 15487 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15488 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15489 15490 synchronized(this) { 15491 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15492 != PackageManager.PERMISSION_GRANTED) { 15493 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15494 + Binder.getCallingPid() 15495 + ", uid=" + Binder.getCallingUid() 15496 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15497 Slog.w(TAG, msg); 15498 throw new SecurityException(msg); 15499 } 15500 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15501 if (stickies != null) { 15502 ArrayList<Intent> list = stickies.get(intent.getAction()); 15503 if (list != null) { 15504 int N = list.size(); 15505 int i; 15506 for (i=0; i<N; i++) { 15507 if (intent.filterEquals(list.get(i))) { 15508 list.remove(i); 15509 break; 15510 } 15511 } 15512 if (list.size() <= 0) { 15513 stickies.remove(intent.getAction()); 15514 } 15515 } 15516 if (stickies.size() <= 0) { 15517 mStickyBroadcasts.remove(userId); 15518 } 15519 } 15520 } 15521 } 15522 15523 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15524 String resultData, Bundle resultExtras, boolean resultAbort) { 15525 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15526 if (r == null) { 15527 Slog.w(TAG, "finishReceiver called but not found on queue"); 15528 return false; 15529 } 15530 15531 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15532 } 15533 15534 void backgroundServicesFinishedLocked(int userId) { 15535 for (BroadcastQueue queue : mBroadcastQueues) { 15536 queue.backgroundServicesFinishedLocked(userId); 15537 } 15538 } 15539 15540 public void finishReceiver(IBinder who, int resultCode, String resultData, 15541 Bundle resultExtras, boolean resultAbort) { 15542 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15543 15544 // Refuse possible leaked file descriptors 15545 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15546 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15547 } 15548 15549 final long origId = Binder.clearCallingIdentity(); 15550 try { 15551 boolean doNext = false; 15552 BroadcastRecord r; 15553 15554 synchronized(this) { 15555 r = broadcastRecordForReceiverLocked(who); 15556 if (r != null) { 15557 doNext = r.queue.finishReceiverLocked(r, resultCode, 15558 resultData, resultExtras, resultAbort, true); 15559 } 15560 } 15561 15562 if (doNext) { 15563 r.queue.processNextBroadcast(false); 15564 } 15565 trimApplications(); 15566 } finally { 15567 Binder.restoreCallingIdentity(origId); 15568 } 15569 } 15570 15571 // ========================================================= 15572 // INSTRUMENTATION 15573 // ========================================================= 15574 15575 public boolean startInstrumentation(ComponentName className, 15576 String profileFile, int flags, Bundle arguments, 15577 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15578 int userId, String abiOverride) { 15579 enforceNotIsolatedCaller("startInstrumentation"); 15580 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15581 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15582 // Refuse possible leaked file descriptors 15583 if (arguments != null && arguments.hasFileDescriptors()) { 15584 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15585 } 15586 15587 synchronized(this) { 15588 InstrumentationInfo ii = null; 15589 ApplicationInfo ai = null; 15590 try { 15591 ii = mContext.getPackageManager().getInstrumentationInfo( 15592 className, STOCK_PM_FLAGS); 15593 ai = AppGlobals.getPackageManager().getApplicationInfo( 15594 ii.targetPackage, STOCK_PM_FLAGS, userId); 15595 } catch (PackageManager.NameNotFoundException e) { 15596 } catch (RemoteException e) { 15597 } 15598 if (ii == null) { 15599 reportStartInstrumentationFailure(watcher, className, 15600 "Unable to find instrumentation info for: " + className); 15601 return false; 15602 } 15603 if (ai == null) { 15604 reportStartInstrumentationFailure(watcher, className, 15605 "Unable to find instrumentation target package: " + ii.targetPackage); 15606 return false; 15607 } 15608 15609 int match = mContext.getPackageManager().checkSignatures( 15610 ii.targetPackage, ii.packageName); 15611 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15612 String msg = "Permission Denial: starting instrumentation " 15613 + className + " from pid=" 15614 + Binder.getCallingPid() 15615 + ", uid=" + Binder.getCallingPid() 15616 + " not allowed because package " + ii.packageName 15617 + " does not have a signature matching the target " 15618 + ii.targetPackage; 15619 reportStartInstrumentationFailure(watcher, className, msg); 15620 throw new SecurityException(msg); 15621 } 15622 15623 final long origId = Binder.clearCallingIdentity(); 15624 // Instrumentation can kill and relaunch even persistent processes 15625 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15626 "start instr"); 15627 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15628 app.instrumentationClass = className; 15629 app.instrumentationInfo = ai; 15630 app.instrumentationProfileFile = profileFile; 15631 app.instrumentationArguments = arguments; 15632 app.instrumentationWatcher = watcher; 15633 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15634 app.instrumentationResultClass = className; 15635 Binder.restoreCallingIdentity(origId); 15636 } 15637 15638 return true; 15639 } 15640 15641 /** 15642 * Report errors that occur while attempting to start Instrumentation. Always writes the 15643 * error to the logs, but if somebody is watching, send the report there too. This enables 15644 * the "am" command to report errors with more information. 15645 * 15646 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15647 * @param cn The component name of the instrumentation. 15648 * @param report The error report. 15649 */ 15650 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15651 ComponentName cn, String report) { 15652 Slog.w(TAG, report); 15653 try { 15654 if (watcher != null) { 15655 Bundle results = new Bundle(); 15656 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15657 results.putString("Error", report); 15658 watcher.instrumentationStatus(cn, -1, results); 15659 } 15660 } catch (RemoteException e) { 15661 Slog.w(TAG, e); 15662 } 15663 } 15664 15665 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15666 if (app.instrumentationWatcher != null) { 15667 try { 15668 // NOTE: IInstrumentationWatcher *must* be oneway here 15669 app.instrumentationWatcher.instrumentationFinished( 15670 app.instrumentationClass, 15671 resultCode, 15672 results); 15673 } catch (RemoteException e) { 15674 } 15675 } 15676 if (app.instrumentationUiAutomationConnection != null) { 15677 try { 15678 app.instrumentationUiAutomationConnection.shutdown(); 15679 } catch (RemoteException re) { 15680 /* ignore */ 15681 } 15682 // Only a UiAutomation can set this flag and now that 15683 // it is finished we make sure it is reset to its default. 15684 mUserIsMonkey = false; 15685 } 15686 app.instrumentationWatcher = null; 15687 app.instrumentationUiAutomationConnection = null; 15688 app.instrumentationClass = null; 15689 app.instrumentationInfo = null; 15690 app.instrumentationProfileFile = null; 15691 app.instrumentationArguments = null; 15692 15693 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15694 "finished inst"); 15695 } 15696 15697 public void finishInstrumentation(IApplicationThread target, 15698 int resultCode, Bundle results) { 15699 int userId = UserHandle.getCallingUserId(); 15700 // Refuse possible leaked file descriptors 15701 if (results != null && results.hasFileDescriptors()) { 15702 throw new IllegalArgumentException("File descriptors passed in Intent"); 15703 } 15704 15705 synchronized(this) { 15706 ProcessRecord app = getRecordForAppLocked(target); 15707 if (app == null) { 15708 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15709 return; 15710 } 15711 final long origId = Binder.clearCallingIdentity(); 15712 finishInstrumentationLocked(app, resultCode, results); 15713 Binder.restoreCallingIdentity(origId); 15714 } 15715 } 15716 15717 // ========================================================= 15718 // CONFIGURATION 15719 // ========================================================= 15720 15721 public ConfigurationInfo getDeviceConfigurationInfo() { 15722 ConfigurationInfo config = new ConfigurationInfo(); 15723 synchronized (this) { 15724 config.reqTouchScreen = mConfiguration.touchscreen; 15725 config.reqKeyboardType = mConfiguration.keyboard; 15726 config.reqNavigation = mConfiguration.navigation; 15727 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15728 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15729 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15730 } 15731 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15732 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15733 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15734 } 15735 config.reqGlEsVersion = GL_ES_VERSION; 15736 } 15737 return config; 15738 } 15739 15740 ActivityStack getFocusedStack() { 15741 return mStackSupervisor.getFocusedStack(); 15742 } 15743 15744 public Configuration getConfiguration() { 15745 Configuration ci; 15746 synchronized(this) { 15747 ci = new Configuration(mConfiguration); 15748 } 15749 return ci; 15750 } 15751 15752 public void updatePersistentConfiguration(Configuration values) { 15753 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15754 "updateConfiguration()"); 15755 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15756 "updateConfiguration()"); 15757 if (values == null) { 15758 throw new NullPointerException("Configuration must not be null"); 15759 } 15760 15761 synchronized(this) { 15762 final long origId = Binder.clearCallingIdentity(); 15763 updateConfigurationLocked(values, null, true, false); 15764 Binder.restoreCallingIdentity(origId); 15765 } 15766 } 15767 15768 public void updateConfiguration(Configuration values) { 15769 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15770 "updateConfiguration()"); 15771 15772 synchronized(this) { 15773 if (values == null && mWindowManager != null) { 15774 // sentinel: fetch the current configuration from the window manager 15775 values = mWindowManager.computeNewConfiguration(); 15776 } 15777 15778 if (mWindowManager != null) { 15779 mProcessList.applyDisplaySize(mWindowManager); 15780 } 15781 15782 final long origId = Binder.clearCallingIdentity(); 15783 if (values != null) { 15784 Settings.System.clearConfiguration(values); 15785 } 15786 updateConfigurationLocked(values, null, false, false); 15787 Binder.restoreCallingIdentity(origId); 15788 } 15789 } 15790 15791 /** 15792 * Do either or both things: (1) change the current configuration, and (2) 15793 * make sure the given activity is running with the (now) current 15794 * configuration. Returns true if the activity has been left running, or 15795 * false if <var>starting</var> is being destroyed to match the new 15796 * configuration. 15797 * @param persistent TODO 15798 */ 15799 boolean updateConfigurationLocked(Configuration values, 15800 ActivityRecord starting, boolean persistent, boolean initLocale) { 15801 int changes = 0; 15802 15803 if (values != null) { 15804 Configuration newConfig = new Configuration(mConfiguration); 15805 changes = newConfig.updateFrom(values); 15806 if (changes != 0) { 15807 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15808 Slog.i(TAG, "Updating configuration to: " + values); 15809 } 15810 15811 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15812 15813 if (values.locale != null && !initLocale) { 15814 saveLocaleLocked(values.locale, 15815 !values.locale.equals(mConfiguration.locale), 15816 values.userSetLocale); 15817 } 15818 15819 mConfigurationSeq++; 15820 if (mConfigurationSeq <= 0) { 15821 mConfigurationSeq = 1; 15822 } 15823 newConfig.seq = mConfigurationSeq; 15824 mConfiguration = newConfig; 15825 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15826 //mUsageStatsService.noteStartConfig(newConfig); 15827 15828 final Configuration configCopy = new Configuration(mConfiguration); 15829 15830 // TODO: If our config changes, should we auto dismiss any currently 15831 // showing dialogs? 15832 mShowDialogs = shouldShowDialogs(newConfig); 15833 15834 AttributeCache ac = AttributeCache.instance(); 15835 if (ac != null) { 15836 ac.updateConfiguration(configCopy); 15837 } 15838 15839 // Make sure all resources in our process are updated 15840 // right now, so that anyone who is going to retrieve 15841 // resource values after we return will be sure to get 15842 // the new ones. This is especially important during 15843 // boot, where the first config change needs to guarantee 15844 // all resources have that config before following boot 15845 // code is executed. 15846 mSystemThread.applyConfigurationToResources(configCopy); 15847 15848 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15849 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15850 msg.obj = new Configuration(configCopy); 15851 mHandler.sendMessage(msg); 15852 } 15853 15854 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15855 ProcessRecord app = mLruProcesses.get(i); 15856 try { 15857 if (app.thread != null) { 15858 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15859 + app.processName + " new config " + mConfiguration); 15860 app.thread.scheduleConfigurationChanged(configCopy); 15861 } 15862 } catch (Exception e) { 15863 } 15864 } 15865 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15866 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15867 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15868 | Intent.FLAG_RECEIVER_FOREGROUND); 15869 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15870 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15871 Process.SYSTEM_UID, UserHandle.USER_ALL); 15872 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15873 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15874 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15875 broadcastIntentLocked(null, null, intent, 15876 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15877 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15878 } 15879 } 15880 } 15881 15882 boolean kept = true; 15883 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15884 // mainStack is null during startup. 15885 if (mainStack != null) { 15886 if (changes != 0 && starting == null) { 15887 // If the configuration changed, and the caller is not already 15888 // in the process of starting an activity, then find the top 15889 // activity to check if its configuration needs to change. 15890 starting = mainStack.topRunningActivityLocked(null); 15891 } 15892 15893 if (starting != null) { 15894 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15895 // And we need to make sure at this point that all other activities 15896 // are made visible with the correct configuration. 15897 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15898 } 15899 } 15900 15901 if (values != null && mWindowManager != null) { 15902 mWindowManager.setNewConfiguration(mConfiguration); 15903 } 15904 15905 return kept; 15906 } 15907 15908 /** 15909 * Decide based on the configuration whether we should shouw the ANR, 15910 * crash, etc dialogs. The idea is that if there is no affordnace to 15911 * press the on-screen buttons, we shouldn't show the dialog. 15912 * 15913 * A thought: SystemUI might also want to get told about this, the Power 15914 * dialog / global actions also might want different behaviors. 15915 */ 15916 private static final boolean shouldShowDialogs(Configuration config) { 15917 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15918 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15919 } 15920 15921 /** 15922 * Save the locale. You must be inside a synchronized (this) block. 15923 */ 15924 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15925 if(isDiff) { 15926 SystemProperties.set("user.language", l.getLanguage()); 15927 SystemProperties.set("user.region", l.getCountry()); 15928 } 15929 15930 if(isPersist) { 15931 SystemProperties.set("persist.sys.language", l.getLanguage()); 15932 SystemProperties.set("persist.sys.country", l.getCountry()); 15933 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15934 } 15935 } 15936 15937 @Override 15938 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 15939 synchronized (this) { 15940 ActivityRecord srec = ActivityRecord.forToken(token); 15941 if (srec.task != null && srec.task.stack != null) { 15942 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 15943 } 15944 } 15945 return false; 15946 } 15947 15948 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15949 Intent resultData) { 15950 15951 synchronized (this) { 15952 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15953 if (stack != null) { 15954 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15955 } 15956 return false; 15957 } 15958 } 15959 15960 public int getLaunchedFromUid(IBinder activityToken) { 15961 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15962 if (srec == null) { 15963 return -1; 15964 } 15965 return srec.launchedFromUid; 15966 } 15967 15968 public String getLaunchedFromPackage(IBinder activityToken) { 15969 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15970 if (srec == null) { 15971 return null; 15972 } 15973 return srec.launchedFromPackage; 15974 } 15975 15976 // ========================================================= 15977 // LIFETIME MANAGEMENT 15978 // ========================================================= 15979 15980 // Returns which broadcast queue the app is the current [or imminent] receiver 15981 // on, or 'null' if the app is not an active broadcast recipient. 15982 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 15983 BroadcastRecord r = app.curReceiver; 15984 if (r != null) { 15985 return r.queue; 15986 } 15987 15988 // It's not the current receiver, but it might be starting up to become one 15989 synchronized (this) { 15990 for (BroadcastQueue queue : mBroadcastQueues) { 15991 r = queue.mPendingBroadcast; 15992 if (r != null && r.curApp == app) { 15993 // found it; report which queue it's in 15994 return queue; 15995 } 15996 } 15997 } 15998 15999 return null; 16000 } 16001 16002 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16003 boolean doingAll, long now) { 16004 if (mAdjSeq == app.adjSeq) { 16005 // This adjustment has already been computed. 16006 return app.curRawAdj; 16007 } 16008 16009 if (app.thread == null) { 16010 app.adjSeq = mAdjSeq; 16011 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16012 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16013 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16014 } 16015 16016 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16017 app.adjSource = null; 16018 app.adjTarget = null; 16019 app.empty = false; 16020 app.cached = false; 16021 16022 final int activitiesSize = app.activities.size(); 16023 16024 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16025 // The max adjustment doesn't allow this app to be anything 16026 // below foreground, so it is not worth doing work for it. 16027 app.adjType = "fixed"; 16028 app.adjSeq = mAdjSeq; 16029 app.curRawAdj = app.maxAdj; 16030 app.foregroundActivities = false; 16031 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16032 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16033 // System processes can do UI, and when they do we want to have 16034 // them trim their memory after the user leaves the UI. To 16035 // facilitate this, here we need to determine whether or not it 16036 // is currently showing UI. 16037 app.systemNoUi = true; 16038 if (app == TOP_APP) { 16039 app.systemNoUi = false; 16040 } else if (activitiesSize > 0) { 16041 for (int j = 0; j < activitiesSize; j++) { 16042 final ActivityRecord r = app.activities.get(j); 16043 if (r.visible) { 16044 app.systemNoUi = false; 16045 } 16046 } 16047 } 16048 if (!app.systemNoUi) { 16049 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16050 } 16051 return (app.curAdj=app.maxAdj); 16052 } 16053 16054 app.systemNoUi = false; 16055 16056 // Determine the importance of the process, starting with most 16057 // important to least, and assign an appropriate OOM adjustment. 16058 int adj; 16059 int schedGroup; 16060 int procState; 16061 boolean foregroundActivities = false; 16062 BroadcastQueue queue; 16063 if (app == TOP_APP) { 16064 // The last app on the list is the foreground app. 16065 adj = ProcessList.FOREGROUND_APP_ADJ; 16066 schedGroup = Process.THREAD_GROUP_DEFAULT; 16067 app.adjType = "top-activity"; 16068 foregroundActivities = true; 16069 procState = ActivityManager.PROCESS_STATE_TOP; 16070 } else if (app.instrumentationClass != null) { 16071 // Don't want to kill running instrumentation. 16072 adj = ProcessList.FOREGROUND_APP_ADJ; 16073 schedGroup = Process.THREAD_GROUP_DEFAULT; 16074 app.adjType = "instrumentation"; 16075 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16076 } else if ((queue = isReceivingBroadcast(app)) != null) { 16077 // An app that is currently receiving a broadcast also 16078 // counts as being in the foreground for OOM killer purposes. 16079 // It's placed in a sched group based on the nature of the 16080 // broadcast as reflected by which queue it's active in. 16081 adj = ProcessList.FOREGROUND_APP_ADJ; 16082 schedGroup = (queue == mFgBroadcastQueue) 16083 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16084 app.adjType = "broadcast"; 16085 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16086 } else if (app.executingServices.size() > 0) { 16087 // An app that is currently executing a service callback also 16088 // counts as being in the foreground. 16089 adj = ProcessList.FOREGROUND_APP_ADJ; 16090 schedGroup = app.execServicesFg ? 16091 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16092 app.adjType = "exec-service"; 16093 procState = ActivityManager.PROCESS_STATE_SERVICE; 16094 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16095 } else { 16096 // As far as we know the process is empty. We may change our mind later. 16097 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16098 // At this point we don't actually know the adjustment. Use the cached adj 16099 // value that the caller wants us to. 16100 adj = cachedAdj; 16101 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16102 app.cached = true; 16103 app.empty = true; 16104 app.adjType = "cch-empty"; 16105 } 16106 16107 // Examine all activities if not already foreground. 16108 if (!foregroundActivities && activitiesSize > 0) { 16109 for (int j = 0; j < activitiesSize; j++) { 16110 final ActivityRecord r = app.activities.get(j); 16111 if (r.app != app) { 16112 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16113 + app + "?!?"); 16114 continue; 16115 } 16116 if (r.visible) { 16117 // App has a visible activity; only upgrade adjustment. 16118 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16119 adj = ProcessList.VISIBLE_APP_ADJ; 16120 app.adjType = "visible"; 16121 } 16122 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16123 procState = ActivityManager.PROCESS_STATE_TOP; 16124 } 16125 schedGroup = Process.THREAD_GROUP_DEFAULT; 16126 app.cached = false; 16127 app.empty = false; 16128 foregroundActivities = true; 16129 break; 16130 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16131 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16132 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16133 app.adjType = "pausing"; 16134 } 16135 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16136 procState = ActivityManager.PROCESS_STATE_TOP; 16137 } 16138 schedGroup = Process.THREAD_GROUP_DEFAULT; 16139 app.cached = false; 16140 app.empty = false; 16141 foregroundActivities = true; 16142 } else if (r.state == ActivityState.STOPPING) { 16143 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16144 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16145 app.adjType = "stopping"; 16146 } 16147 // For the process state, we will at this point consider the 16148 // process to be cached. It will be cached either as an activity 16149 // or empty depending on whether the activity is finishing. We do 16150 // this so that we can treat the process as cached for purposes of 16151 // memory trimming (determing current memory level, trim command to 16152 // send to process) since there can be an arbitrary number of stopping 16153 // processes and they should soon all go into the cached state. 16154 if (!r.finishing) { 16155 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16156 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16157 } 16158 } 16159 app.cached = false; 16160 app.empty = false; 16161 foregroundActivities = true; 16162 } else { 16163 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16164 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16165 app.adjType = "cch-act"; 16166 } 16167 } 16168 } 16169 } 16170 16171 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16172 if (app.foregroundServices) { 16173 // The user is aware of this app, so make it visible. 16174 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16175 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16176 app.cached = false; 16177 app.adjType = "fg-service"; 16178 schedGroup = Process.THREAD_GROUP_DEFAULT; 16179 } else if (app.forcingToForeground != null) { 16180 // The user is aware of this app, so make it visible. 16181 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16182 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16183 app.cached = false; 16184 app.adjType = "force-fg"; 16185 app.adjSource = app.forcingToForeground; 16186 schedGroup = Process.THREAD_GROUP_DEFAULT; 16187 } 16188 } 16189 16190 if (app == mHeavyWeightProcess) { 16191 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16192 // We don't want to kill the current heavy-weight process. 16193 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16194 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16195 app.cached = false; 16196 app.adjType = "heavy"; 16197 } 16198 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16199 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16200 } 16201 } 16202 16203 if (app == mHomeProcess) { 16204 if (adj > ProcessList.HOME_APP_ADJ) { 16205 // This process is hosting what we currently consider to be the 16206 // home app, so we don't want to let it go into the background. 16207 adj = ProcessList.HOME_APP_ADJ; 16208 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16209 app.cached = false; 16210 app.adjType = "home"; 16211 } 16212 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16213 procState = ActivityManager.PROCESS_STATE_HOME; 16214 } 16215 } 16216 16217 if (app == mPreviousProcess && app.activities.size() > 0) { 16218 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16219 // This was the previous process that showed UI to the user. 16220 // We want to try to keep it around more aggressively, to give 16221 // a good experience around switching between two apps. 16222 adj = ProcessList.PREVIOUS_APP_ADJ; 16223 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16224 app.cached = false; 16225 app.adjType = "previous"; 16226 } 16227 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16228 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16229 } 16230 } 16231 16232 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16233 + " reason=" + app.adjType); 16234 16235 // By default, we use the computed adjustment. It may be changed if 16236 // there are applications dependent on our services or providers, but 16237 // this gives us a baseline and makes sure we don't get into an 16238 // infinite recursion. 16239 app.adjSeq = mAdjSeq; 16240 app.curRawAdj = adj; 16241 app.hasStartedServices = false; 16242 16243 if (mBackupTarget != null && app == mBackupTarget.app) { 16244 // If possible we want to avoid killing apps while they're being backed up 16245 if (adj > ProcessList.BACKUP_APP_ADJ) { 16246 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16247 adj = ProcessList.BACKUP_APP_ADJ; 16248 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16249 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16250 } 16251 app.adjType = "backup"; 16252 app.cached = false; 16253 } 16254 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16255 procState = ActivityManager.PROCESS_STATE_BACKUP; 16256 } 16257 } 16258 16259 boolean mayBeTop = false; 16260 16261 for (int is = app.services.size()-1; 16262 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16263 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16264 || procState > ActivityManager.PROCESS_STATE_TOP); 16265 is--) { 16266 ServiceRecord s = app.services.valueAt(is); 16267 if (s.startRequested) { 16268 app.hasStartedServices = true; 16269 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16270 procState = ActivityManager.PROCESS_STATE_SERVICE; 16271 } 16272 if (app.hasShownUi && app != mHomeProcess) { 16273 // If this process has shown some UI, let it immediately 16274 // go to the LRU list because it may be pretty heavy with 16275 // UI stuff. We'll tag it with a label just to help 16276 // debug and understand what is going on. 16277 if (adj > ProcessList.SERVICE_ADJ) { 16278 app.adjType = "cch-started-ui-services"; 16279 } 16280 } else { 16281 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16282 // This service has seen some activity within 16283 // recent memory, so we will keep its process ahead 16284 // of the background processes. 16285 if (adj > ProcessList.SERVICE_ADJ) { 16286 adj = ProcessList.SERVICE_ADJ; 16287 app.adjType = "started-services"; 16288 app.cached = false; 16289 } 16290 } 16291 // If we have let the service slide into the background 16292 // state, still have some text describing what it is doing 16293 // even though the service no longer has an impact. 16294 if (adj > ProcessList.SERVICE_ADJ) { 16295 app.adjType = "cch-started-services"; 16296 } 16297 } 16298 } 16299 for (int conni = s.connections.size()-1; 16300 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16301 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16302 || procState > ActivityManager.PROCESS_STATE_TOP); 16303 conni--) { 16304 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16305 for (int i = 0; 16306 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16307 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16308 || procState > ActivityManager.PROCESS_STATE_TOP); 16309 i++) { 16310 // XXX should compute this based on the max of 16311 // all connected clients. 16312 ConnectionRecord cr = clist.get(i); 16313 if (cr.binding.client == app) { 16314 // Binding to ourself is not interesting. 16315 continue; 16316 } 16317 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16318 ProcessRecord client = cr.binding.client; 16319 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16320 TOP_APP, doingAll, now); 16321 int clientProcState = client.curProcState; 16322 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16323 // If the other app is cached for any reason, for purposes here 16324 // we are going to consider it empty. The specific cached state 16325 // doesn't propagate except under certain conditions. 16326 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16327 } 16328 String adjType = null; 16329 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16330 // Not doing bind OOM management, so treat 16331 // this guy more like a started service. 16332 if (app.hasShownUi && app != mHomeProcess) { 16333 // If this process has shown some UI, let it immediately 16334 // go to the LRU list because it may be pretty heavy with 16335 // UI stuff. We'll tag it with a label just to help 16336 // debug and understand what is going on. 16337 if (adj > clientAdj) { 16338 adjType = "cch-bound-ui-services"; 16339 } 16340 app.cached = false; 16341 clientAdj = adj; 16342 clientProcState = procState; 16343 } else { 16344 if (now >= (s.lastActivity 16345 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16346 // This service has not seen activity within 16347 // recent memory, so allow it to drop to the 16348 // LRU list if there is no other reason to keep 16349 // it around. We'll also tag it with a label just 16350 // to help debug and undertand what is going on. 16351 if (adj > clientAdj) { 16352 adjType = "cch-bound-services"; 16353 } 16354 clientAdj = adj; 16355 } 16356 } 16357 } 16358 if (adj > clientAdj) { 16359 // If this process has recently shown UI, and 16360 // the process that is binding to it is less 16361 // important than being visible, then we don't 16362 // care about the binding as much as we care 16363 // about letting this process get into the LRU 16364 // list to be killed and restarted if needed for 16365 // memory. 16366 if (app.hasShownUi && app != mHomeProcess 16367 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16368 adjType = "cch-bound-ui-services"; 16369 } else { 16370 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16371 |Context.BIND_IMPORTANT)) != 0) { 16372 adj = clientAdj; 16373 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16374 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16375 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16376 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16377 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16378 adj = clientAdj; 16379 } else { 16380 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16381 adj = ProcessList.VISIBLE_APP_ADJ; 16382 } 16383 } 16384 if (!client.cached) { 16385 app.cached = false; 16386 } 16387 adjType = "service"; 16388 } 16389 } 16390 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16391 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16392 schedGroup = Process.THREAD_GROUP_DEFAULT; 16393 } 16394 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16395 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16396 // Special handling of clients who are in the top state. 16397 // We *may* want to consider this process to be in the 16398 // top state as well, but only if there is not another 16399 // reason for it to be running. Being on the top is a 16400 // special state, meaning you are specifically running 16401 // for the current top app. If the process is already 16402 // running in the background for some other reason, it 16403 // is more important to continue considering it to be 16404 // in the background state. 16405 mayBeTop = true; 16406 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16407 } else { 16408 // Special handling for above-top states (persistent 16409 // processes). These should not bring the current process 16410 // into the top state, since they are not on top. Instead 16411 // give them the best state after that. 16412 clientProcState = 16413 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16414 } 16415 } 16416 } else { 16417 if (clientProcState < 16418 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16419 clientProcState = 16420 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16421 } 16422 } 16423 if (procState > clientProcState) { 16424 procState = clientProcState; 16425 } 16426 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16427 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16428 app.pendingUiClean = true; 16429 } 16430 if (adjType != null) { 16431 app.adjType = adjType; 16432 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16433 .REASON_SERVICE_IN_USE; 16434 app.adjSource = cr.binding.client; 16435 app.adjSourceProcState = clientProcState; 16436 app.adjTarget = s.name; 16437 } 16438 } 16439 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16440 app.treatLikeActivity = true; 16441 } 16442 final ActivityRecord a = cr.activity; 16443 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16444 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16445 (a.visible || a.state == ActivityState.RESUMED 16446 || a.state == ActivityState.PAUSING)) { 16447 adj = ProcessList.FOREGROUND_APP_ADJ; 16448 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16449 schedGroup = Process.THREAD_GROUP_DEFAULT; 16450 } 16451 app.cached = false; 16452 app.adjType = "service"; 16453 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16454 .REASON_SERVICE_IN_USE; 16455 app.adjSource = a; 16456 app.adjSourceProcState = procState; 16457 app.adjTarget = s.name; 16458 } 16459 } 16460 } 16461 } 16462 } 16463 16464 for (int provi = app.pubProviders.size()-1; 16465 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16466 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16467 || procState > ActivityManager.PROCESS_STATE_TOP); 16468 provi--) { 16469 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16470 for (int i = cpr.connections.size()-1; 16471 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16472 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16473 || procState > ActivityManager.PROCESS_STATE_TOP); 16474 i--) { 16475 ContentProviderConnection conn = cpr.connections.get(i); 16476 ProcessRecord client = conn.client; 16477 if (client == app) { 16478 // Being our own client is not interesting. 16479 continue; 16480 } 16481 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16482 int clientProcState = client.curProcState; 16483 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16484 // If the other app is cached for any reason, for purposes here 16485 // we are going to consider it empty. 16486 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16487 } 16488 if (adj > clientAdj) { 16489 if (app.hasShownUi && app != mHomeProcess 16490 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16491 app.adjType = "cch-ui-provider"; 16492 } else { 16493 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16494 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16495 app.adjType = "provider"; 16496 } 16497 app.cached &= client.cached; 16498 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16499 .REASON_PROVIDER_IN_USE; 16500 app.adjSource = client; 16501 app.adjSourceProcState = clientProcState; 16502 app.adjTarget = cpr.name; 16503 } 16504 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16505 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16506 // Special handling of clients who are in the top state. 16507 // We *may* want to consider this process to be in the 16508 // top state as well, but only if there is not another 16509 // reason for it to be running. Being on the top is a 16510 // special state, meaning you are specifically running 16511 // for the current top app. If the process is already 16512 // running in the background for some other reason, it 16513 // is more important to continue considering it to be 16514 // in the background state. 16515 mayBeTop = true; 16516 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16517 } else { 16518 // Special handling for above-top states (persistent 16519 // processes). These should not bring the current process 16520 // into the top state, since they are not on top. Instead 16521 // give them the best state after that. 16522 clientProcState = 16523 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16524 } 16525 } 16526 if (procState > clientProcState) { 16527 procState = clientProcState; 16528 } 16529 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16530 schedGroup = Process.THREAD_GROUP_DEFAULT; 16531 } 16532 } 16533 // If the provider has external (non-framework) process 16534 // dependencies, ensure that its adjustment is at least 16535 // FOREGROUND_APP_ADJ. 16536 if (cpr.hasExternalProcessHandles()) { 16537 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16538 adj = ProcessList.FOREGROUND_APP_ADJ; 16539 schedGroup = Process.THREAD_GROUP_DEFAULT; 16540 app.cached = false; 16541 app.adjType = "provider"; 16542 app.adjTarget = cpr.name; 16543 } 16544 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16545 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16546 } 16547 } 16548 } 16549 16550 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16551 // A client of one of our services or providers is in the top state. We 16552 // *may* want to be in the top state, but not if we are already running in 16553 // the background for some other reason. For the decision here, we are going 16554 // to pick out a few specific states that we want to remain in when a client 16555 // is top (states that tend to be longer-term) and otherwise allow it to go 16556 // to the top state. 16557 switch (procState) { 16558 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16559 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16560 case ActivityManager.PROCESS_STATE_SERVICE: 16561 // These all are longer-term states, so pull them up to the top 16562 // of the background states, but not all the way to the top state. 16563 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16564 break; 16565 default: 16566 // Otherwise, top is a better choice, so take it. 16567 procState = ActivityManager.PROCESS_STATE_TOP; 16568 break; 16569 } 16570 } 16571 16572 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16573 if (app.hasClientActivities) { 16574 // This is a cached process, but with client activities. Mark it so. 16575 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16576 app.adjType = "cch-client-act"; 16577 } else if (app.treatLikeActivity) { 16578 // This is a cached process, but somebody wants us to treat it like it has 16579 // an activity, okay! 16580 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16581 app.adjType = "cch-as-act"; 16582 } 16583 } 16584 16585 if (adj == ProcessList.SERVICE_ADJ) { 16586 if (doingAll) { 16587 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16588 mNewNumServiceProcs++; 16589 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16590 if (!app.serviceb) { 16591 // This service isn't far enough down on the LRU list to 16592 // normally be a B service, but if we are low on RAM and it 16593 // is large we want to force it down since we would prefer to 16594 // keep launcher over it. 16595 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16596 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16597 app.serviceHighRam = true; 16598 app.serviceb = true; 16599 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16600 } else { 16601 mNewNumAServiceProcs++; 16602 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16603 } 16604 } else { 16605 app.serviceHighRam = false; 16606 } 16607 } 16608 if (app.serviceb) { 16609 adj = ProcessList.SERVICE_B_ADJ; 16610 } 16611 } 16612 16613 app.curRawAdj = adj; 16614 16615 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16616 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16617 if (adj > app.maxAdj) { 16618 adj = app.maxAdj; 16619 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16620 schedGroup = Process.THREAD_GROUP_DEFAULT; 16621 } 16622 } 16623 16624 // Do final modification to adj. Everything we do between here and applying 16625 // the final setAdj must be done in this function, because we will also use 16626 // it when computing the final cached adj later. Note that we don't need to 16627 // worry about this for max adj above, since max adj will always be used to 16628 // keep it out of the cached vaues. 16629 app.curAdj = app.modifyRawOomAdj(adj); 16630 app.curSchedGroup = schedGroup; 16631 app.curProcState = procState; 16632 app.foregroundActivities = foregroundActivities; 16633 16634 return app.curRawAdj; 16635 } 16636 16637 /** 16638 * Schedule PSS collection of a process. 16639 */ 16640 void requestPssLocked(ProcessRecord proc, int procState) { 16641 if (mPendingPssProcesses.contains(proc)) { 16642 return; 16643 } 16644 if (mPendingPssProcesses.size() == 0) { 16645 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16646 } 16647 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16648 proc.pssProcState = procState; 16649 mPendingPssProcesses.add(proc); 16650 } 16651 16652 /** 16653 * Schedule PSS collection of all processes. 16654 */ 16655 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16656 if (!always) { 16657 if (now < (mLastFullPssTime + 16658 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16659 return; 16660 } 16661 } 16662 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16663 mLastFullPssTime = now; 16664 mFullPssPending = true; 16665 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16666 mPendingPssProcesses.clear(); 16667 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16668 ProcessRecord app = mLruProcesses.get(i); 16669 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16670 app.pssProcState = app.setProcState; 16671 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16672 isSleeping(), now); 16673 mPendingPssProcesses.add(app); 16674 } 16675 } 16676 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16677 } 16678 16679 /** 16680 * Ask a given process to GC right now. 16681 */ 16682 final void performAppGcLocked(ProcessRecord app) { 16683 try { 16684 app.lastRequestedGc = SystemClock.uptimeMillis(); 16685 if (app.thread != null) { 16686 if (app.reportLowMemory) { 16687 app.reportLowMemory = false; 16688 app.thread.scheduleLowMemory(); 16689 } else { 16690 app.thread.processInBackground(); 16691 } 16692 } 16693 } catch (Exception e) { 16694 // whatever. 16695 } 16696 } 16697 16698 /** 16699 * Returns true if things are idle enough to perform GCs. 16700 */ 16701 private final boolean canGcNowLocked() { 16702 boolean processingBroadcasts = false; 16703 for (BroadcastQueue q : mBroadcastQueues) { 16704 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16705 processingBroadcasts = true; 16706 } 16707 } 16708 return !processingBroadcasts 16709 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16710 } 16711 16712 /** 16713 * Perform GCs on all processes that are waiting for it, but only 16714 * if things are idle. 16715 */ 16716 final void performAppGcsLocked() { 16717 final int N = mProcessesToGc.size(); 16718 if (N <= 0) { 16719 return; 16720 } 16721 if (canGcNowLocked()) { 16722 while (mProcessesToGc.size() > 0) { 16723 ProcessRecord proc = mProcessesToGc.remove(0); 16724 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16725 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16726 <= SystemClock.uptimeMillis()) { 16727 // To avoid spamming the system, we will GC processes one 16728 // at a time, waiting a few seconds between each. 16729 performAppGcLocked(proc); 16730 scheduleAppGcsLocked(); 16731 return; 16732 } else { 16733 // It hasn't been long enough since we last GCed this 16734 // process... put it in the list to wait for its time. 16735 addProcessToGcListLocked(proc); 16736 break; 16737 } 16738 } 16739 } 16740 16741 scheduleAppGcsLocked(); 16742 } 16743 } 16744 16745 /** 16746 * If all looks good, perform GCs on all processes waiting for them. 16747 */ 16748 final void performAppGcsIfAppropriateLocked() { 16749 if (canGcNowLocked()) { 16750 performAppGcsLocked(); 16751 return; 16752 } 16753 // Still not idle, wait some more. 16754 scheduleAppGcsLocked(); 16755 } 16756 16757 /** 16758 * Schedule the execution of all pending app GCs. 16759 */ 16760 final void scheduleAppGcsLocked() { 16761 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16762 16763 if (mProcessesToGc.size() > 0) { 16764 // Schedule a GC for the time to the next process. 16765 ProcessRecord proc = mProcessesToGc.get(0); 16766 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16767 16768 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16769 long now = SystemClock.uptimeMillis(); 16770 if (when < (now+GC_TIMEOUT)) { 16771 when = now + GC_TIMEOUT; 16772 } 16773 mHandler.sendMessageAtTime(msg, when); 16774 } 16775 } 16776 16777 /** 16778 * Add a process to the array of processes waiting to be GCed. Keeps the 16779 * list in sorted order by the last GC time. The process can't already be 16780 * on the list. 16781 */ 16782 final void addProcessToGcListLocked(ProcessRecord proc) { 16783 boolean added = false; 16784 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16785 if (mProcessesToGc.get(i).lastRequestedGc < 16786 proc.lastRequestedGc) { 16787 added = true; 16788 mProcessesToGc.add(i+1, proc); 16789 break; 16790 } 16791 } 16792 if (!added) { 16793 mProcessesToGc.add(0, proc); 16794 } 16795 } 16796 16797 /** 16798 * Set up to ask a process to GC itself. This will either do it 16799 * immediately, or put it on the list of processes to gc the next 16800 * time things are idle. 16801 */ 16802 final void scheduleAppGcLocked(ProcessRecord app) { 16803 long now = SystemClock.uptimeMillis(); 16804 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16805 return; 16806 } 16807 if (!mProcessesToGc.contains(app)) { 16808 addProcessToGcListLocked(app); 16809 scheduleAppGcsLocked(); 16810 } 16811 } 16812 16813 final void checkExcessivePowerUsageLocked(boolean doKills) { 16814 updateCpuStatsNow(); 16815 16816 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16817 boolean doWakeKills = doKills; 16818 boolean doCpuKills = doKills; 16819 if (mLastPowerCheckRealtime == 0) { 16820 doWakeKills = false; 16821 } 16822 if (mLastPowerCheckUptime == 0) { 16823 doCpuKills = false; 16824 } 16825 if (stats.isScreenOn()) { 16826 doWakeKills = false; 16827 } 16828 final long curRealtime = SystemClock.elapsedRealtime(); 16829 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16830 final long curUptime = SystemClock.uptimeMillis(); 16831 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16832 mLastPowerCheckRealtime = curRealtime; 16833 mLastPowerCheckUptime = curUptime; 16834 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16835 doWakeKills = false; 16836 } 16837 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16838 doCpuKills = false; 16839 } 16840 int i = mLruProcesses.size(); 16841 while (i > 0) { 16842 i--; 16843 ProcessRecord app = mLruProcesses.get(i); 16844 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16845 long wtime; 16846 synchronized (stats) { 16847 wtime = stats.getProcessWakeTime(app.info.uid, 16848 app.pid, curRealtime); 16849 } 16850 long wtimeUsed = wtime - app.lastWakeTime; 16851 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16852 if (DEBUG_POWER) { 16853 StringBuilder sb = new StringBuilder(128); 16854 sb.append("Wake for "); 16855 app.toShortString(sb); 16856 sb.append(": over "); 16857 TimeUtils.formatDuration(realtimeSince, sb); 16858 sb.append(" used "); 16859 TimeUtils.formatDuration(wtimeUsed, sb); 16860 sb.append(" ("); 16861 sb.append((wtimeUsed*100)/realtimeSince); 16862 sb.append("%)"); 16863 Slog.i(TAG, sb.toString()); 16864 sb.setLength(0); 16865 sb.append("CPU for "); 16866 app.toShortString(sb); 16867 sb.append(": over "); 16868 TimeUtils.formatDuration(uptimeSince, sb); 16869 sb.append(" used "); 16870 TimeUtils.formatDuration(cputimeUsed, sb); 16871 sb.append(" ("); 16872 sb.append((cputimeUsed*100)/uptimeSince); 16873 sb.append("%)"); 16874 Slog.i(TAG, sb.toString()); 16875 } 16876 // If a process has held a wake lock for more 16877 // than 50% of the time during this period, 16878 // that sounds bad. Kill! 16879 if (doWakeKills && realtimeSince > 0 16880 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16881 synchronized (stats) { 16882 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16883 realtimeSince, wtimeUsed); 16884 } 16885 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16886 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16887 } else if (doCpuKills && uptimeSince > 0 16888 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16889 synchronized (stats) { 16890 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16891 uptimeSince, cputimeUsed); 16892 } 16893 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 16894 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16895 } else { 16896 app.lastWakeTime = wtime; 16897 app.lastCpuTime = app.curCpuTime; 16898 } 16899 } 16900 } 16901 } 16902 16903 private final boolean applyOomAdjLocked(ProcessRecord app, 16904 ProcessRecord TOP_APP, boolean doingAll, long now) { 16905 boolean success = true; 16906 16907 if (app.curRawAdj != app.setRawAdj) { 16908 app.setRawAdj = app.curRawAdj; 16909 } 16910 16911 int changes = 0; 16912 16913 if (app.curAdj != app.setAdj) { 16914 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16915 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16916 TAG, "Set " + app.pid + " " + app.processName + 16917 " adj " + app.curAdj + ": " + app.adjType); 16918 app.setAdj = app.curAdj; 16919 } 16920 16921 if (app.setSchedGroup != app.curSchedGroup) { 16922 app.setSchedGroup = app.curSchedGroup; 16923 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16924 "Setting process group of " + app.processName 16925 + " to " + app.curSchedGroup); 16926 if (app.waitingToKill != null && 16927 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16928 app.kill(app.waitingToKill, true); 16929 success = false; 16930 } else { 16931 if (true) { 16932 long oldId = Binder.clearCallingIdentity(); 16933 try { 16934 Process.setProcessGroup(app.pid, app.curSchedGroup); 16935 } catch (Exception e) { 16936 Slog.w(TAG, "Failed setting process group of " + app.pid 16937 + " to " + app.curSchedGroup); 16938 e.printStackTrace(); 16939 } finally { 16940 Binder.restoreCallingIdentity(oldId); 16941 } 16942 } else { 16943 if (app.thread != null) { 16944 try { 16945 app.thread.setSchedulingGroup(app.curSchedGroup); 16946 } catch (RemoteException e) { 16947 } 16948 } 16949 } 16950 Process.setSwappiness(app.pid, 16951 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16952 } 16953 } 16954 if (app.repForegroundActivities != app.foregroundActivities) { 16955 app.repForegroundActivities = app.foregroundActivities; 16956 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16957 } 16958 if (app.repProcState != app.curProcState) { 16959 app.repProcState = app.curProcState; 16960 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16961 if (app.thread != null) { 16962 try { 16963 if (false) { 16964 //RuntimeException h = new RuntimeException("here"); 16965 Slog.i(TAG, "Sending new process state " + app.repProcState 16966 + " to " + app /*, h*/); 16967 } 16968 app.thread.setProcessState(app.repProcState); 16969 } catch (RemoteException e) { 16970 } 16971 } 16972 } 16973 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16974 app.setProcState)) { 16975 app.lastStateTime = now; 16976 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16977 isSleeping(), now); 16978 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16979 + ProcessList.makeProcStateString(app.setProcState) + " to " 16980 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16981 + (app.nextPssTime-now) + ": " + app); 16982 } else { 16983 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16984 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16985 requestPssLocked(app, app.setProcState); 16986 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16987 isSleeping(), now); 16988 } else if (false && DEBUG_PSS) { 16989 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16990 } 16991 } 16992 if (app.setProcState != app.curProcState) { 16993 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16994 "Proc state change of " + app.processName 16995 + " to " + app.curProcState); 16996 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 16997 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 16998 if (setImportant && !curImportant) { 16999 // This app is no longer something we consider important enough to allow to 17000 // use arbitrary amounts of battery power. Note 17001 // its current wake lock time to later know to kill it if 17002 // it is not behaving well. 17003 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17004 synchronized (stats) { 17005 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17006 app.pid, SystemClock.elapsedRealtime()); 17007 } 17008 app.lastCpuTime = app.curCpuTime; 17009 17010 } 17011 app.setProcState = app.curProcState; 17012 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17013 app.notCachedSinceIdle = false; 17014 } 17015 if (!doingAll) { 17016 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17017 } else { 17018 app.procStateChanged = true; 17019 } 17020 } 17021 17022 if (changes != 0) { 17023 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17024 int i = mPendingProcessChanges.size()-1; 17025 ProcessChangeItem item = null; 17026 while (i >= 0) { 17027 item = mPendingProcessChanges.get(i); 17028 if (item.pid == app.pid) { 17029 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17030 break; 17031 } 17032 i--; 17033 } 17034 if (i < 0) { 17035 // No existing item in pending changes; need a new one. 17036 final int NA = mAvailProcessChanges.size(); 17037 if (NA > 0) { 17038 item = mAvailProcessChanges.remove(NA-1); 17039 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17040 } else { 17041 item = new ProcessChangeItem(); 17042 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17043 } 17044 item.changes = 0; 17045 item.pid = app.pid; 17046 item.uid = app.info.uid; 17047 if (mPendingProcessChanges.size() == 0) { 17048 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17049 "*** Enqueueing dispatch processes changed!"); 17050 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17051 } 17052 mPendingProcessChanges.add(item); 17053 } 17054 item.changes |= changes; 17055 item.processState = app.repProcState; 17056 item.foregroundActivities = app.repForegroundActivities; 17057 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17058 + Integer.toHexString(System.identityHashCode(item)) 17059 + " " + app.toShortString() + ": changes=" + item.changes 17060 + " procState=" + item.processState 17061 + " foreground=" + item.foregroundActivities 17062 + " type=" + app.adjType + " source=" + app.adjSource 17063 + " target=" + app.adjTarget); 17064 } 17065 17066 return success; 17067 } 17068 17069 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17070 if (proc.thread != null) { 17071 if (proc.baseProcessTracker != null) { 17072 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17073 } 17074 if (proc.repProcState >= 0) { 17075 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17076 proc.repProcState); 17077 } 17078 } 17079 } 17080 17081 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17082 ProcessRecord TOP_APP, boolean doingAll, long now) { 17083 if (app.thread == null) { 17084 return false; 17085 } 17086 17087 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17088 17089 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17090 } 17091 17092 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17093 boolean oomAdj) { 17094 if (isForeground != proc.foregroundServices) { 17095 proc.foregroundServices = isForeground; 17096 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17097 proc.info.uid); 17098 if (isForeground) { 17099 if (curProcs == null) { 17100 curProcs = new ArrayList<ProcessRecord>(); 17101 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17102 } 17103 if (!curProcs.contains(proc)) { 17104 curProcs.add(proc); 17105 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17106 proc.info.packageName, proc.info.uid); 17107 } 17108 } else { 17109 if (curProcs != null) { 17110 if (curProcs.remove(proc)) { 17111 mBatteryStatsService.noteEvent( 17112 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17113 proc.info.packageName, proc.info.uid); 17114 if (curProcs.size() <= 0) { 17115 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17116 } 17117 } 17118 } 17119 } 17120 if (oomAdj) { 17121 updateOomAdjLocked(); 17122 } 17123 } 17124 } 17125 17126 private final ActivityRecord resumedAppLocked() { 17127 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17128 String pkg; 17129 int uid; 17130 if (act != null) { 17131 pkg = act.packageName; 17132 uid = act.info.applicationInfo.uid; 17133 } else { 17134 pkg = null; 17135 uid = -1; 17136 } 17137 // Has the UID or resumed package name changed? 17138 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17139 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17140 if (mCurResumedPackage != null) { 17141 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17142 mCurResumedPackage, mCurResumedUid); 17143 } 17144 mCurResumedPackage = pkg; 17145 mCurResumedUid = uid; 17146 if (mCurResumedPackage != null) { 17147 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17148 mCurResumedPackage, mCurResumedUid); 17149 } 17150 } 17151 return act; 17152 } 17153 17154 final boolean updateOomAdjLocked(ProcessRecord app) { 17155 final ActivityRecord TOP_ACT = resumedAppLocked(); 17156 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17157 final boolean wasCached = app.cached; 17158 17159 mAdjSeq++; 17160 17161 // This is the desired cached adjusment we want to tell it to use. 17162 // If our app is currently cached, we know it, and that is it. Otherwise, 17163 // we don't know it yet, and it needs to now be cached we will then 17164 // need to do a complete oom adj. 17165 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17166 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17167 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17168 SystemClock.uptimeMillis()); 17169 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17170 // Changed to/from cached state, so apps after it in the LRU 17171 // list may also be changed. 17172 updateOomAdjLocked(); 17173 } 17174 return success; 17175 } 17176 17177 final void updateOomAdjLocked() { 17178 final ActivityRecord TOP_ACT = resumedAppLocked(); 17179 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17180 final long now = SystemClock.uptimeMillis(); 17181 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17182 final int N = mLruProcesses.size(); 17183 17184 if (false) { 17185 RuntimeException e = new RuntimeException(); 17186 e.fillInStackTrace(); 17187 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17188 } 17189 17190 mAdjSeq++; 17191 mNewNumServiceProcs = 0; 17192 mNewNumAServiceProcs = 0; 17193 17194 final int emptyProcessLimit; 17195 final int cachedProcessLimit; 17196 if (mProcessLimit <= 0) { 17197 emptyProcessLimit = cachedProcessLimit = 0; 17198 } else if (mProcessLimit == 1) { 17199 emptyProcessLimit = 1; 17200 cachedProcessLimit = 0; 17201 } else { 17202 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17203 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17204 } 17205 17206 // Let's determine how many processes we have running vs. 17207 // how many slots we have for background processes; we may want 17208 // to put multiple processes in a slot of there are enough of 17209 // them. 17210 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17211 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17212 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17213 if (numEmptyProcs > cachedProcessLimit) { 17214 // If there are more empty processes than our limit on cached 17215 // processes, then use the cached process limit for the factor. 17216 // This ensures that the really old empty processes get pushed 17217 // down to the bottom, so if we are running low on memory we will 17218 // have a better chance at keeping around more cached processes 17219 // instead of a gazillion empty processes. 17220 numEmptyProcs = cachedProcessLimit; 17221 } 17222 int emptyFactor = numEmptyProcs/numSlots; 17223 if (emptyFactor < 1) emptyFactor = 1; 17224 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17225 if (cachedFactor < 1) cachedFactor = 1; 17226 int stepCached = 0; 17227 int stepEmpty = 0; 17228 int numCached = 0; 17229 int numEmpty = 0; 17230 int numTrimming = 0; 17231 17232 mNumNonCachedProcs = 0; 17233 mNumCachedHiddenProcs = 0; 17234 17235 // First update the OOM adjustment for each of the 17236 // application processes based on their current state. 17237 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17238 int nextCachedAdj = curCachedAdj+1; 17239 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17240 int nextEmptyAdj = curEmptyAdj+2; 17241 for (int i=N-1; i>=0; i--) { 17242 ProcessRecord app = mLruProcesses.get(i); 17243 if (!app.killedByAm && app.thread != null) { 17244 app.procStateChanged = false; 17245 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17246 17247 // If we haven't yet assigned the final cached adj 17248 // to the process, do that now. 17249 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17250 switch (app.curProcState) { 17251 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17252 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17253 // This process is a cached process holding activities... 17254 // assign it the next cached value for that type, and then 17255 // step that cached level. 17256 app.curRawAdj = curCachedAdj; 17257 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17258 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17259 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17260 + ")"); 17261 if (curCachedAdj != nextCachedAdj) { 17262 stepCached++; 17263 if (stepCached >= cachedFactor) { 17264 stepCached = 0; 17265 curCachedAdj = nextCachedAdj; 17266 nextCachedAdj += 2; 17267 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17268 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17269 } 17270 } 17271 } 17272 break; 17273 default: 17274 // For everything else, assign next empty cached process 17275 // level and bump that up. Note that this means that 17276 // long-running services that have dropped down to the 17277 // cached level will be treated as empty (since their process 17278 // state is still as a service), which is what we want. 17279 app.curRawAdj = curEmptyAdj; 17280 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17281 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17282 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17283 + ")"); 17284 if (curEmptyAdj != nextEmptyAdj) { 17285 stepEmpty++; 17286 if (stepEmpty >= emptyFactor) { 17287 stepEmpty = 0; 17288 curEmptyAdj = nextEmptyAdj; 17289 nextEmptyAdj += 2; 17290 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17291 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17292 } 17293 } 17294 } 17295 break; 17296 } 17297 } 17298 17299 applyOomAdjLocked(app, TOP_APP, true, now); 17300 17301 // Count the number of process types. 17302 switch (app.curProcState) { 17303 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17304 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17305 mNumCachedHiddenProcs++; 17306 numCached++; 17307 if (numCached > cachedProcessLimit) { 17308 app.kill("cached #" + numCached, true); 17309 } 17310 break; 17311 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17312 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17313 && app.lastActivityTime < oldTime) { 17314 app.kill("empty for " 17315 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17316 / 1000) + "s", true); 17317 } else { 17318 numEmpty++; 17319 if (numEmpty > emptyProcessLimit) { 17320 app.kill("empty #" + numEmpty, true); 17321 } 17322 } 17323 break; 17324 default: 17325 mNumNonCachedProcs++; 17326 break; 17327 } 17328 17329 if (app.isolated && app.services.size() <= 0) { 17330 // If this is an isolated process, and there are no 17331 // services running in it, then the process is no longer 17332 // needed. We agressively kill these because we can by 17333 // definition not re-use the same process again, and it is 17334 // good to avoid having whatever code was running in them 17335 // left sitting around after no longer needed. 17336 app.kill("isolated not needed", true); 17337 } 17338 17339 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17340 && !app.killedByAm) { 17341 numTrimming++; 17342 } 17343 } 17344 } 17345 17346 mNumServiceProcs = mNewNumServiceProcs; 17347 17348 // Now determine the memory trimming level of background processes. 17349 // Unfortunately we need to start at the back of the list to do this 17350 // properly. We only do this if the number of background apps we 17351 // are managing to keep around is less than half the maximum we desire; 17352 // if we are keeping a good number around, we'll let them use whatever 17353 // memory they want. 17354 final int numCachedAndEmpty = numCached + numEmpty; 17355 int memFactor; 17356 if (numCached <= ProcessList.TRIM_CACHED_APPS 17357 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17358 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17359 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17360 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17361 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17362 } else { 17363 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17364 } 17365 } else { 17366 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17367 } 17368 // We always allow the memory level to go up (better). We only allow it to go 17369 // down if we are in a state where that is allowed, *and* the total number of processes 17370 // has gone down since last time. 17371 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17372 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17373 + " last=" + mLastNumProcesses); 17374 if (memFactor > mLastMemoryLevel) { 17375 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17376 memFactor = mLastMemoryLevel; 17377 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17378 } 17379 } 17380 mLastMemoryLevel = memFactor; 17381 mLastNumProcesses = mLruProcesses.size(); 17382 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17383 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17384 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17385 if (mLowRamStartTime == 0) { 17386 mLowRamStartTime = now; 17387 } 17388 int step = 0; 17389 int fgTrimLevel; 17390 switch (memFactor) { 17391 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17392 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17393 break; 17394 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17395 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17396 break; 17397 default: 17398 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17399 break; 17400 } 17401 int factor = numTrimming/3; 17402 int minFactor = 2; 17403 if (mHomeProcess != null) minFactor++; 17404 if (mPreviousProcess != null) minFactor++; 17405 if (factor < minFactor) factor = minFactor; 17406 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17407 for (int i=N-1; i>=0; i--) { 17408 ProcessRecord app = mLruProcesses.get(i); 17409 if (allChanged || app.procStateChanged) { 17410 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17411 app.procStateChanged = false; 17412 } 17413 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17414 && !app.killedByAm) { 17415 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17416 try { 17417 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17418 "Trimming memory of " + app.processName 17419 + " to " + curLevel); 17420 app.thread.scheduleTrimMemory(curLevel); 17421 } catch (RemoteException e) { 17422 } 17423 if (false) { 17424 // For now we won't do this; our memory trimming seems 17425 // to be good enough at this point that destroying 17426 // activities causes more harm than good. 17427 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17428 && app != mHomeProcess && app != mPreviousProcess) { 17429 // Need to do this on its own message because the stack may not 17430 // be in a consistent state at this point. 17431 // For these apps we will also finish their activities 17432 // to help them free memory. 17433 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17434 } 17435 } 17436 } 17437 app.trimMemoryLevel = curLevel; 17438 step++; 17439 if (step >= factor) { 17440 step = 0; 17441 switch (curLevel) { 17442 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17443 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17444 break; 17445 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17446 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17447 break; 17448 } 17449 } 17450 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17451 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17452 && app.thread != null) { 17453 try { 17454 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17455 "Trimming memory of heavy-weight " + app.processName 17456 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17457 app.thread.scheduleTrimMemory( 17458 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17459 } catch (RemoteException e) { 17460 } 17461 } 17462 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17463 } else { 17464 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17465 || app.systemNoUi) && app.pendingUiClean) { 17466 // If this application is now in the background and it 17467 // had done UI, then give it the special trim level to 17468 // have it free UI resources. 17469 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17470 if (app.trimMemoryLevel < level && app.thread != null) { 17471 try { 17472 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17473 "Trimming memory of bg-ui " + app.processName 17474 + " to " + level); 17475 app.thread.scheduleTrimMemory(level); 17476 } catch (RemoteException e) { 17477 } 17478 } 17479 app.pendingUiClean = false; 17480 } 17481 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17482 try { 17483 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17484 "Trimming memory of fg " + app.processName 17485 + " to " + fgTrimLevel); 17486 app.thread.scheduleTrimMemory(fgTrimLevel); 17487 } catch (RemoteException e) { 17488 } 17489 } 17490 app.trimMemoryLevel = fgTrimLevel; 17491 } 17492 } 17493 } else { 17494 if (mLowRamStartTime != 0) { 17495 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17496 mLowRamStartTime = 0; 17497 } 17498 for (int i=N-1; i>=0; i--) { 17499 ProcessRecord app = mLruProcesses.get(i); 17500 if (allChanged || app.procStateChanged) { 17501 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17502 app.procStateChanged = false; 17503 } 17504 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17505 || app.systemNoUi) && app.pendingUiClean) { 17506 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17507 && app.thread != null) { 17508 try { 17509 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17510 "Trimming memory of ui hidden " + app.processName 17511 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17512 app.thread.scheduleTrimMemory( 17513 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17514 } catch (RemoteException e) { 17515 } 17516 } 17517 app.pendingUiClean = false; 17518 } 17519 app.trimMemoryLevel = 0; 17520 } 17521 } 17522 17523 if (mAlwaysFinishActivities) { 17524 // Need to do this on its own message because the stack may not 17525 // be in a consistent state at this point. 17526 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17527 } 17528 17529 if (allChanged) { 17530 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17531 } 17532 17533 if (mProcessStats.shouldWriteNowLocked(now)) { 17534 mHandler.post(new Runnable() { 17535 @Override public void run() { 17536 synchronized (ActivityManagerService.this) { 17537 mProcessStats.writeStateAsyncLocked(); 17538 } 17539 } 17540 }); 17541 } 17542 17543 if (DEBUG_OOM_ADJ) { 17544 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17545 } 17546 } 17547 17548 final void trimApplications() { 17549 synchronized (this) { 17550 int i; 17551 17552 // First remove any unused application processes whose package 17553 // has been removed. 17554 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17555 final ProcessRecord app = mRemovedProcesses.get(i); 17556 if (app.activities.size() == 0 17557 && app.curReceiver == null && app.services.size() == 0) { 17558 Slog.i( 17559 TAG, "Exiting empty application process " 17560 + app.processName + " (" 17561 + (app.thread != null ? app.thread.asBinder() : null) 17562 + ")\n"); 17563 if (app.pid > 0 && app.pid != MY_PID) { 17564 app.kill("empty", false); 17565 } else { 17566 try { 17567 app.thread.scheduleExit(); 17568 } catch (Exception e) { 17569 // Ignore exceptions. 17570 } 17571 } 17572 cleanUpApplicationRecordLocked(app, false, true, -1); 17573 mRemovedProcesses.remove(i); 17574 17575 if (app.persistent) { 17576 addAppLocked(app.info, false, null /* ABI override */); 17577 } 17578 } 17579 } 17580 17581 // Now update the oom adj for all processes. 17582 updateOomAdjLocked(); 17583 } 17584 } 17585 17586 /** This method sends the specified signal to each of the persistent apps */ 17587 public void signalPersistentProcesses(int sig) throws RemoteException { 17588 if (sig != Process.SIGNAL_USR1) { 17589 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17590 } 17591 17592 synchronized (this) { 17593 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17594 != PackageManager.PERMISSION_GRANTED) { 17595 throw new SecurityException("Requires permission " 17596 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17597 } 17598 17599 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17600 ProcessRecord r = mLruProcesses.get(i); 17601 if (r.thread != null && r.persistent) { 17602 Process.sendSignal(r.pid, sig); 17603 } 17604 } 17605 } 17606 } 17607 17608 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 17609 if (proc == null || proc == mProfileProc) { 17610 proc = mProfileProc; 17611 path = mProfileFile; 17612 profileType = mProfileType; 17613 clearProfilerLocked(); 17614 } 17615 if (proc == null) { 17616 return; 17617 } 17618 try { 17619 proc.thread.profilerControl(false, path, null, profileType); 17620 } catch (RemoteException e) { 17621 throw new IllegalStateException("Process disappeared"); 17622 } 17623 } 17624 17625 private void clearProfilerLocked() { 17626 if (mProfileFd != null) { 17627 try { 17628 mProfileFd.close(); 17629 } catch (IOException e) { 17630 } 17631 } 17632 mProfileApp = null; 17633 mProfileProc = null; 17634 mProfileFile = null; 17635 mProfileType = 0; 17636 mAutoStopProfiler = false; 17637 } 17638 17639 public boolean profileControl(String process, int userId, boolean start, 17640 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 17641 17642 try { 17643 synchronized (this) { 17644 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17645 // its own permission. 17646 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17647 != PackageManager.PERMISSION_GRANTED) { 17648 throw new SecurityException("Requires permission " 17649 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17650 } 17651 17652 if (start && fd == null) { 17653 throw new IllegalArgumentException("null fd"); 17654 } 17655 17656 ProcessRecord proc = null; 17657 if (process != null) { 17658 proc = findProcessLocked(process, userId, "profileControl"); 17659 } 17660 17661 if (start && (proc == null || proc.thread == null)) { 17662 throw new IllegalArgumentException("Unknown process: " + process); 17663 } 17664 17665 if (start) { 17666 stopProfilerLocked(null, null, 0); 17667 setProfileApp(proc.info, proc.processName, path, fd, false); 17668 mProfileProc = proc; 17669 mProfileType = profileType; 17670 try { 17671 fd = fd.dup(); 17672 } catch (IOException e) { 17673 fd = null; 17674 } 17675 proc.thread.profilerControl(start, path, fd, profileType); 17676 fd = null; 17677 mProfileFd = null; 17678 } else { 17679 stopProfilerLocked(proc, path, profileType); 17680 if (fd != null) { 17681 try { 17682 fd.close(); 17683 } catch (IOException e) { 17684 } 17685 } 17686 } 17687 17688 return true; 17689 } 17690 } catch (RemoteException e) { 17691 throw new IllegalStateException("Process disappeared"); 17692 } finally { 17693 if (fd != null) { 17694 try { 17695 fd.close(); 17696 } catch (IOException e) { 17697 } 17698 } 17699 } 17700 } 17701 17702 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17703 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17704 userId, true, ALLOW_FULL_ONLY, callName, null); 17705 ProcessRecord proc = null; 17706 try { 17707 int pid = Integer.parseInt(process); 17708 synchronized (mPidsSelfLocked) { 17709 proc = mPidsSelfLocked.get(pid); 17710 } 17711 } catch (NumberFormatException e) { 17712 } 17713 17714 if (proc == null) { 17715 ArrayMap<String, SparseArray<ProcessRecord>> all 17716 = mProcessNames.getMap(); 17717 SparseArray<ProcessRecord> procs = all.get(process); 17718 if (procs != null && procs.size() > 0) { 17719 proc = procs.valueAt(0); 17720 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17721 for (int i=1; i<procs.size(); i++) { 17722 ProcessRecord thisProc = procs.valueAt(i); 17723 if (thisProc.userId == userId) { 17724 proc = thisProc; 17725 break; 17726 } 17727 } 17728 } 17729 } 17730 } 17731 17732 return proc; 17733 } 17734 17735 public boolean dumpHeap(String process, int userId, boolean managed, 17736 String path, ParcelFileDescriptor fd) throws RemoteException { 17737 17738 try { 17739 synchronized (this) { 17740 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17741 // its own permission (same as profileControl). 17742 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17743 != PackageManager.PERMISSION_GRANTED) { 17744 throw new SecurityException("Requires permission " 17745 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17746 } 17747 17748 if (fd == null) { 17749 throw new IllegalArgumentException("null fd"); 17750 } 17751 17752 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17753 if (proc == null || proc.thread == null) { 17754 throw new IllegalArgumentException("Unknown process: " + process); 17755 } 17756 17757 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17758 if (!isDebuggable) { 17759 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17760 throw new SecurityException("Process not debuggable: " + proc); 17761 } 17762 } 17763 17764 proc.thread.dumpHeap(managed, path, fd); 17765 fd = null; 17766 return true; 17767 } 17768 } catch (RemoteException e) { 17769 throw new IllegalStateException("Process disappeared"); 17770 } finally { 17771 if (fd != null) { 17772 try { 17773 fd.close(); 17774 } catch (IOException e) { 17775 } 17776 } 17777 } 17778 } 17779 17780 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17781 public void monitor() { 17782 synchronized (this) { } 17783 } 17784 17785 void onCoreSettingsChange(Bundle settings) { 17786 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17787 ProcessRecord processRecord = mLruProcesses.get(i); 17788 try { 17789 if (processRecord.thread != null) { 17790 processRecord.thread.setCoreSettings(settings); 17791 } 17792 } catch (RemoteException re) { 17793 /* ignore */ 17794 } 17795 } 17796 } 17797 17798 // Multi-user methods 17799 17800 /** 17801 * Start user, if its not already running, but don't bring it to foreground. 17802 */ 17803 @Override 17804 public boolean startUserInBackground(final int userId) { 17805 return startUser(userId, /* foreground */ false); 17806 } 17807 17808 /** 17809 * Start user, if its not already running, and bring it to foreground. 17810 */ 17811 boolean startUserInForeground(final int userId, Dialog dlg) { 17812 boolean result = startUser(userId, /* foreground */ true); 17813 dlg.dismiss(); 17814 return result; 17815 } 17816 17817 /** 17818 * Refreshes the list of users related to the current user when either a 17819 * user switch happens or when a new related user is started in the 17820 * background. 17821 */ 17822 private void updateCurrentProfileIdsLocked() { 17823 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17824 mCurrentUserId, false /* enabledOnly */); 17825 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17826 for (int i = 0; i < currentProfileIds.length; i++) { 17827 currentProfileIds[i] = profiles.get(i).id; 17828 } 17829 mCurrentProfileIds = currentProfileIds; 17830 17831 synchronized (mUserProfileGroupIdsSelfLocked) { 17832 mUserProfileGroupIdsSelfLocked.clear(); 17833 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17834 for (int i = 0; i < users.size(); i++) { 17835 UserInfo user = users.get(i); 17836 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17837 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17838 } 17839 } 17840 } 17841 } 17842 17843 private Set getProfileIdsLocked(int userId) { 17844 Set userIds = new HashSet<Integer>(); 17845 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17846 userId, false /* enabledOnly */); 17847 for (UserInfo user : profiles) { 17848 userIds.add(Integer.valueOf(user.id)); 17849 } 17850 return userIds; 17851 } 17852 17853 @Override 17854 public boolean switchUser(final int userId) { 17855 String userName; 17856 synchronized (this) { 17857 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17858 if (userInfo == null) { 17859 Slog.w(TAG, "No user info for user #" + userId); 17860 return false; 17861 } 17862 if (userInfo.isManagedProfile()) { 17863 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17864 return false; 17865 } 17866 userName = userInfo.name; 17867 } 17868 mHandler.removeMessages(START_USER_SWITCH_MSG); 17869 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17870 return true; 17871 } 17872 17873 private void showUserSwitchDialog(int userId, String userName) { 17874 // The dialog will show and then initiate the user switch by calling startUserInForeground 17875 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17876 true /* above system */); 17877 d.show(); 17878 } 17879 17880 private boolean startUser(final int userId, final boolean foreground) { 17881 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17882 != PackageManager.PERMISSION_GRANTED) { 17883 String msg = "Permission Denial: switchUser() from pid=" 17884 + Binder.getCallingPid() 17885 + ", uid=" + Binder.getCallingUid() 17886 + " requires " + INTERACT_ACROSS_USERS_FULL; 17887 Slog.w(TAG, msg); 17888 throw new SecurityException(msg); 17889 } 17890 17891 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17892 17893 final long ident = Binder.clearCallingIdentity(); 17894 try { 17895 synchronized (this) { 17896 final int oldUserId = mCurrentUserId; 17897 if (oldUserId == userId) { 17898 return true; 17899 } 17900 17901 mStackSupervisor.setLockTaskModeLocked(null, false); 17902 17903 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17904 if (userInfo == null) { 17905 Slog.w(TAG, "No user info for user #" + userId); 17906 return false; 17907 } 17908 if (foreground && userInfo.isManagedProfile()) { 17909 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17910 return false; 17911 } 17912 17913 if (foreground) { 17914 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17915 R.anim.screen_user_enter); 17916 } 17917 17918 boolean needStart = false; 17919 17920 // If the user we are switching to is not currently started, then 17921 // we need to start it now. 17922 if (mStartedUsers.get(userId) == null) { 17923 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17924 updateStartedUserArrayLocked(); 17925 needStart = true; 17926 } 17927 17928 final Integer userIdInt = Integer.valueOf(userId); 17929 mUserLru.remove(userIdInt); 17930 mUserLru.add(userIdInt); 17931 17932 if (foreground) { 17933 mCurrentUserId = userId; 17934 updateCurrentProfileIdsLocked(); 17935 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17936 // Once the internal notion of the active user has switched, we lock the device 17937 // with the option to show the user switcher on the keyguard. 17938 mWindowManager.lockNow(null); 17939 } else { 17940 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17941 updateCurrentProfileIdsLocked(); 17942 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17943 mUserLru.remove(currentUserIdInt); 17944 mUserLru.add(currentUserIdInt); 17945 } 17946 17947 final UserStartedState uss = mStartedUsers.get(userId); 17948 17949 // Make sure user is in the started state. If it is currently 17950 // stopping, we need to knock that off. 17951 if (uss.mState == UserStartedState.STATE_STOPPING) { 17952 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17953 // so we can just fairly silently bring the user back from 17954 // the almost-dead. 17955 uss.mState = UserStartedState.STATE_RUNNING; 17956 updateStartedUserArrayLocked(); 17957 needStart = true; 17958 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17959 // This means ACTION_SHUTDOWN has been sent, so we will 17960 // need to treat this as a new boot of the user. 17961 uss.mState = UserStartedState.STATE_BOOTING; 17962 updateStartedUserArrayLocked(); 17963 needStart = true; 17964 } 17965 17966 if (uss.mState == UserStartedState.STATE_BOOTING) { 17967 // Booting up a new user, need to tell system services about it. 17968 // Note that this is on the same handler as scheduling of broadcasts, 17969 // which is important because it needs to go first. 17970 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 17971 } 17972 17973 if (foreground) { 17974 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 17975 oldUserId)); 17976 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17977 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17978 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 17979 oldUserId, userId, uss)); 17980 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 17981 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 17982 } 17983 17984 if (needStart) { 17985 // Send USER_STARTED broadcast 17986 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 17987 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17988 | Intent.FLAG_RECEIVER_FOREGROUND); 17989 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17990 broadcastIntentLocked(null, null, intent, 17991 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17992 false, false, MY_PID, Process.SYSTEM_UID, userId); 17993 } 17994 17995 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 17996 if (userId != UserHandle.USER_OWNER) { 17997 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 17998 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 17999 broadcastIntentLocked(null, null, intent, null, 18000 new IIntentReceiver.Stub() { 18001 public void performReceive(Intent intent, int resultCode, 18002 String data, Bundle extras, boolean ordered, 18003 boolean sticky, int sendingUser) { 18004 onUserInitialized(uss, foreground, oldUserId, userId); 18005 } 18006 }, 0, null, null, null, AppOpsManager.OP_NONE, 18007 true, false, MY_PID, Process.SYSTEM_UID, 18008 userId); 18009 uss.initializing = true; 18010 } else { 18011 getUserManagerLocked().makeInitialized(userInfo.id); 18012 } 18013 } 18014 18015 if (foreground) { 18016 if (!uss.initializing) { 18017 moveUserToForeground(uss, oldUserId, userId); 18018 } 18019 } else { 18020 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18021 } 18022 18023 if (needStart) { 18024 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18025 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18026 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18027 broadcastIntentLocked(null, null, intent, 18028 null, new IIntentReceiver.Stub() { 18029 @Override 18030 public void performReceive(Intent intent, int resultCode, String data, 18031 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18032 throws RemoteException { 18033 } 18034 }, 0, null, null, 18035 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18036 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18037 } 18038 } 18039 } finally { 18040 Binder.restoreCallingIdentity(ident); 18041 } 18042 18043 return true; 18044 } 18045 18046 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18047 long ident = Binder.clearCallingIdentity(); 18048 try { 18049 Intent intent; 18050 if (oldUserId >= 0) { 18051 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18052 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18053 int count = profiles.size(); 18054 for (int i = 0; i < count; i++) { 18055 int profileUserId = profiles.get(i).id; 18056 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18057 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18058 | Intent.FLAG_RECEIVER_FOREGROUND); 18059 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18060 broadcastIntentLocked(null, null, intent, 18061 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18062 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18063 } 18064 } 18065 if (newUserId >= 0) { 18066 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18067 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18068 int count = profiles.size(); 18069 for (int i = 0; i < count; i++) { 18070 int profileUserId = profiles.get(i).id; 18071 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18072 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18073 | Intent.FLAG_RECEIVER_FOREGROUND); 18074 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18075 broadcastIntentLocked(null, null, intent, 18076 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18077 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18078 } 18079 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18080 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18081 | Intent.FLAG_RECEIVER_FOREGROUND); 18082 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18083 broadcastIntentLocked(null, null, intent, 18084 null, null, 0, null, null, 18085 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18086 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18087 } 18088 } finally { 18089 Binder.restoreCallingIdentity(ident); 18090 } 18091 } 18092 18093 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18094 final int newUserId) { 18095 final int N = mUserSwitchObservers.beginBroadcast(); 18096 if (N > 0) { 18097 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18098 int mCount = 0; 18099 @Override 18100 public void sendResult(Bundle data) throws RemoteException { 18101 synchronized (ActivityManagerService.this) { 18102 if (mCurUserSwitchCallback == this) { 18103 mCount++; 18104 if (mCount == N) { 18105 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18106 } 18107 } 18108 } 18109 } 18110 }; 18111 synchronized (this) { 18112 uss.switching = true; 18113 mCurUserSwitchCallback = callback; 18114 } 18115 for (int i=0; i<N; i++) { 18116 try { 18117 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18118 newUserId, callback); 18119 } catch (RemoteException e) { 18120 } 18121 } 18122 } else { 18123 synchronized (this) { 18124 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18125 } 18126 } 18127 mUserSwitchObservers.finishBroadcast(); 18128 } 18129 18130 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18131 synchronized (this) { 18132 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18133 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18134 } 18135 } 18136 18137 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18138 mCurUserSwitchCallback = null; 18139 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18140 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18141 oldUserId, newUserId, uss)); 18142 } 18143 18144 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18145 synchronized (this) { 18146 if (foreground) { 18147 moveUserToForeground(uss, oldUserId, newUserId); 18148 } 18149 } 18150 18151 completeSwitchAndInitalize(uss, newUserId, true, false); 18152 } 18153 18154 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18155 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18156 if (homeInFront) { 18157 startHomeActivityLocked(newUserId); 18158 } else { 18159 mStackSupervisor.resumeTopActivitiesLocked(); 18160 } 18161 EventLogTags.writeAmSwitchUser(newUserId); 18162 getUserManagerLocked().userForeground(newUserId); 18163 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18164 } 18165 18166 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18167 completeSwitchAndInitalize(uss, newUserId, false, true); 18168 } 18169 18170 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18171 boolean clearInitializing, boolean clearSwitching) { 18172 boolean unfrozen = false; 18173 synchronized (this) { 18174 if (clearInitializing) { 18175 uss.initializing = false; 18176 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18177 } 18178 if (clearSwitching) { 18179 uss.switching = false; 18180 } 18181 if (!uss.switching && !uss.initializing) { 18182 mWindowManager.stopFreezingScreen(); 18183 unfrozen = true; 18184 } 18185 } 18186 if (unfrozen) { 18187 final int N = mUserSwitchObservers.beginBroadcast(); 18188 for (int i=0; i<N; i++) { 18189 try { 18190 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18191 } catch (RemoteException e) { 18192 } 18193 } 18194 mUserSwitchObservers.finishBroadcast(); 18195 } 18196 } 18197 18198 void scheduleStartProfilesLocked() { 18199 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18200 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18201 DateUtils.SECOND_IN_MILLIS); 18202 } 18203 } 18204 18205 void startProfilesLocked() { 18206 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18207 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18208 mCurrentUserId, false /* enabledOnly */); 18209 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18210 for (UserInfo user : profiles) { 18211 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18212 && user.id != mCurrentUserId) { 18213 toStart.add(user); 18214 } 18215 } 18216 final int n = toStart.size(); 18217 int i = 0; 18218 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18219 startUserInBackground(toStart.get(i).id); 18220 } 18221 if (i < n) { 18222 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18223 } 18224 } 18225 18226 void finishUserBoot(UserStartedState uss) { 18227 synchronized (this) { 18228 if (uss.mState == UserStartedState.STATE_BOOTING 18229 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18230 uss.mState = UserStartedState.STATE_RUNNING; 18231 final int userId = uss.mHandle.getIdentifier(); 18232 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18233 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18234 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18235 broadcastIntentLocked(null, null, intent, 18236 null, null, 0, null, null, 18237 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18238 true, false, MY_PID, Process.SYSTEM_UID, userId); 18239 } 18240 } 18241 } 18242 18243 void finishUserSwitch(UserStartedState uss) { 18244 synchronized (this) { 18245 finishUserBoot(uss); 18246 18247 startProfilesLocked(); 18248 18249 int num = mUserLru.size(); 18250 int i = 0; 18251 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18252 Integer oldUserId = mUserLru.get(i); 18253 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18254 if (oldUss == null) { 18255 // Shouldn't happen, but be sane if it does. 18256 mUserLru.remove(i); 18257 num--; 18258 continue; 18259 } 18260 if (oldUss.mState == UserStartedState.STATE_STOPPING 18261 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18262 // This user is already stopping, doesn't count. 18263 num--; 18264 i++; 18265 continue; 18266 } 18267 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18268 // Owner and current can't be stopped, but count as running. 18269 i++; 18270 continue; 18271 } 18272 // This is a user to be stopped. 18273 stopUserLocked(oldUserId, null); 18274 num--; 18275 i++; 18276 } 18277 } 18278 } 18279 18280 @Override 18281 public int stopUser(final int userId, final IStopUserCallback callback) { 18282 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18283 != PackageManager.PERMISSION_GRANTED) { 18284 String msg = "Permission Denial: switchUser() from pid=" 18285 + Binder.getCallingPid() 18286 + ", uid=" + Binder.getCallingUid() 18287 + " requires " + INTERACT_ACROSS_USERS_FULL; 18288 Slog.w(TAG, msg); 18289 throw new SecurityException(msg); 18290 } 18291 if (userId <= 0) { 18292 throw new IllegalArgumentException("Can't stop primary user " + userId); 18293 } 18294 synchronized (this) { 18295 return stopUserLocked(userId, callback); 18296 } 18297 } 18298 18299 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18300 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18301 if (mCurrentUserId == userId) { 18302 return ActivityManager.USER_OP_IS_CURRENT; 18303 } 18304 18305 final UserStartedState uss = mStartedUsers.get(userId); 18306 if (uss == null) { 18307 // User is not started, nothing to do... but we do need to 18308 // callback if requested. 18309 if (callback != null) { 18310 mHandler.post(new Runnable() { 18311 @Override 18312 public void run() { 18313 try { 18314 callback.userStopped(userId); 18315 } catch (RemoteException e) { 18316 } 18317 } 18318 }); 18319 } 18320 return ActivityManager.USER_OP_SUCCESS; 18321 } 18322 18323 if (callback != null) { 18324 uss.mStopCallbacks.add(callback); 18325 } 18326 18327 if (uss.mState != UserStartedState.STATE_STOPPING 18328 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18329 uss.mState = UserStartedState.STATE_STOPPING; 18330 updateStartedUserArrayLocked(); 18331 18332 long ident = Binder.clearCallingIdentity(); 18333 try { 18334 // We are going to broadcast ACTION_USER_STOPPING and then 18335 // once that is done send a final ACTION_SHUTDOWN and then 18336 // stop the user. 18337 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18338 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18339 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18340 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18341 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18342 // This is the result receiver for the final shutdown broadcast. 18343 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18344 @Override 18345 public void performReceive(Intent intent, int resultCode, String data, 18346 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18347 finishUserStop(uss); 18348 } 18349 }; 18350 // This is the result receiver for the initial stopping broadcast. 18351 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18352 @Override 18353 public void performReceive(Intent intent, int resultCode, String data, 18354 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18355 // On to the next. 18356 synchronized (ActivityManagerService.this) { 18357 if (uss.mState != UserStartedState.STATE_STOPPING) { 18358 // Whoops, we are being started back up. Abort, abort! 18359 return; 18360 } 18361 uss.mState = UserStartedState.STATE_SHUTDOWN; 18362 } 18363 mBatteryStatsService.noteEvent( 18364 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18365 Integer.toString(userId), userId); 18366 mSystemServiceManager.stopUser(userId); 18367 broadcastIntentLocked(null, null, shutdownIntent, 18368 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18369 true, false, MY_PID, Process.SYSTEM_UID, userId); 18370 } 18371 }; 18372 // Kick things off. 18373 broadcastIntentLocked(null, null, stoppingIntent, 18374 null, stoppingReceiver, 0, null, null, 18375 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18376 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18377 } finally { 18378 Binder.restoreCallingIdentity(ident); 18379 } 18380 } 18381 18382 return ActivityManager.USER_OP_SUCCESS; 18383 } 18384 18385 void finishUserStop(UserStartedState uss) { 18386 final int userId = uss.mHandle.getIdentifier(); 18387 boolean stopped; 18388 ArrayList<IStopUserCallback> callbacks; 18389 synchronized (this) { 18390 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18391 if (mStartedUsers.get(userId) != uss) { 18392 stopped = false; 18393 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18394 stopped = false; 18395 } else { 18396 stopped = true; 18397 // User can no longer run. 18398 mStartedUsers.remove(userId); 18399 mUserLru.remove(Integer.valueOf(userId)); 18400 updateStartedUserArrayLocked(); 18401 18402 // Clean up all state and processes associated with the user. 18403 // Kill all the processes for the user. 18404 forceStopUserLocked(userId, "finish user"); 18405 } 18406 18407 // Explicitly remove the old information in mRecentTasks. 18408 removeRecentTasksForUserLocked(userId); 18409 } 18410 18411 for (int i=0; i<callbacks.size(); i++) { 18412 try { 18413 if (stopped) callbacks.get(i).userStopped(userId); 18414 else callbacks.get(i).userStopAborted(userId); 18415 } catch (RemoteException e) { 18416 } 18417 } 18418 18419 if (stopped) { 18420 mSystemServiceManager.cleanupUser(userId); 18421 synchronized (this) { 18422 mStackSupervisor.removeUserLocked(userId); 18423 } 18424 } 18425 } 18426 18427 @Override 18428 public UserInfo getCurrentUser() { 18429 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18430 != PackageManager.PERMISSION_GRANTED) && ( 18431 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18432 != PackageManager.PERMISSION_GRANTED)) { 18433 String msg = "Permission Denial: getCurrentUser() from pid=" 18434 + Binder.getCallingPid() 18435 + ", uid=" + Binder.getCallingUid() 18436 + " requires " + INTERACT_ACROSS_USERS; 18437 Slog.w(TAG, msg); 18438 throw new SecurityException(msg); 18439 } 18440 synchronized (this) { 18441 return getUserManagerLocked().getUserInfo(mCurrentUserId); 18442 } 18443 } 18444 18445 int getCurrentUserIdLocked() { 18446 return mCurrentUserId; 18447 } 18448 18449 @Override 18450 public boolean isUserRunning(int userId, boolean orStopped) { 18451 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18452 != PackageManager.PERMISSION_GRANTED) { 18453 String msg = "Permission Denial: isUserRunning() from pid=" 18454 + Binder.getCallingPid() 18455 + ", uid=" + Binder.getCallingUid() 18456 + " requires " + INTERACT_ACROSS_USERS; 18457 Slog.w(TAG, msg); 18458 throw new SecurityException(msg); 18459 } 18460 synchronized (this) { 18461 return isUserRunningLocked(userId, orStopped); 18462 } 18463 } 18464 18465 boolean isUserRunningLocked(int userId, boolean orStopped) { 18466 UserStartedState state = mStartedUsers.get(userId); 18467 if (state == null) { 18468 return false; 18469 } 18470 if (orStopped) { 18471 return true; 18472 } 18473 return state.mState != UserStartedState.STATE_STOPPING 18474 && state.mState != UserStartedState.STATE_SHUTDOWN; 18475 } 18476 18477 @Override 18478 public int[] getRunningUserIds() { 18479 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18480 != PackageManager.PERMISSION_GRANTED) { 18481 String msg = "Permission Denial: isUserRunning() from pid=" 18482 + Binder.getCallingPid() 18483 + ", uid=" + Binder.getCallingUid() 18484 + " requires " + INTERACT_ACROSS_USERS; 18485 Slog.w(TAG, msg); 18486 throw new SecurityException(msg); 18487 } 18488 synchronized (this) { 18489 return mStartedUserArray; 18490 } 18491 } 18492 18493 private void updateStartedUserArrayLocked() { 18494 int num = 0; 18495 for (int i=0; i<mStartedUsers.size(); i++) { 18496 UserStartedState uss = mStartedUsers.valueAt(i); 18497 // This list does not include stopping users. 18498 if (uss.mState != UserStartedState.STATE_STOPPING 18499 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18500 num++; 18501 } 18502 } 18503 mStartedUserArray = new int[num]; 18504 num = 0; 18505 for (int i=0; i<mStartedUsers.size(); i++) { 18506 UserStartedState uss = mStartedUsers.valueAt(i); 18507 if (uss.mState != UserStartedState.STATE_STOPPING 18508 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18509 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18510 num++; 18511 } 18512 } 18513 } 18514 18515 @Override 18516 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18517 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18518 != PackageManager.PERMISSION_GRANTED) { 18519 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18520 + Binder.getCallingPid() 18521 + ", uid=" + Binder.getCallingUid() 18522 + " requires " + INTERACT_ACROSS_USERS_FULL; 18523 Slog.w(TAG, msg); 18524 throw new SecurityException(msg); 18525 } 18526 18527 mUserSwitchObservers.register(observer); 18528 } 18529 18530 @Override 18531 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18532 mUserSwitchObservers.unregister(observer); 18533 } 18534 18535 private boolean userExists(int userId) { 18536 if (userId == 0) { 18537 return true; 18538 } 18539 UserManagerService ums = getUserManagerLocked(); 18540 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18541 } 18542 18543 int[] getUsersLocked() { 18544 UserManagerService ums = getUserManagerLocked(); 18545 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18546 } 18547 18548 UserManagerService getUserManagerLocked() { 18549 if (mUserManager == null) { 18550 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18551 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18552 } 18553 return mUserManager; 18554 } 18555 18556 private int applyUserId(int uid, int userId) { 18557 return UserHandle.getUid(userId, uid); 18558 } 18559 18560 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18561 if (info == null) return null; 18562 ApplicationInfo newInfo = new ApplicationInfo(info); 18563 newInfo.uid = applyUserId(info.uid, userId); 18564 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18565 + info.packageName; 18566 return newInfo; 18567 } 18568 18569 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18570 if (aInfo == null 18571 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18572 return aInfo; 18573 } 18574 18575 ActivityInfo info = new ActivityInfo(aInfo); 18576 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18577 return info; 18578 } 18579 18580 private final class LocalService extends ActivityManagerInternal { 18581 @Override 18582 public void goingToSleep() { 18583 ActivityManagerService.this.goingToSleep(); 18584 } 18585 18586 @Override 18587 public void wakingUp() { 18588 ActivityManagerService.this.wakingUp(); 18589 } 18590 18591 @Override 18592 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18593 String processName, String abiOverride, int uid, Runnable crashHandler) { 18594 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18595 processName, abiOverride, uid, crashHandler); 18596 } 18597 } 18598 18599 /** 18600 * An implementation of IAppTask, that allows an app to manage its own tasks via 18601 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18602 * only the process that calls getAppTasks() can call the AppTask methods. 18603 */ 18604 class AppTaskImpl extends IAppTask.Stub { 18605 private int mTaskId; 18606 private int mCallingUid; 18607 18608 public AppTaskImpl(int taskId, int callingUid) { 18609 mTaskId = taskId; 18610 mCallingUid = callingUid; 18611 } 18612 18613 private void checkCaller() { 18614 if (mCallingUid != Binder.getCallingUid()) { 18615 throw new SecurityException("Caller " + mCallingUid 18616 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18617 } 18618 } 18619 18620 @Override 18621 public void finishAndRemoveTask() { 18622 checkCaller(); 18623 18624 synchronized (ActivityManagerService.this) { 18625 long origId = Binder.clearCallingIdentity(); 18626 try { 18627 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18628 if (tr == null) { 18629 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18630 } 18631 // Only kill the process if we are not a new document 18632 int flags = tr.getBaseIntent().getFlags(); 18633 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18634 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18635 removeTaskByIdLocked(mTaskId, 18636 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18637 } finally { 18638 Binder.restoreCallingIdentity(origId); 18639 } 18640 } 18641 } 18642 18643 @Override 18644 public ActivityManager.RecentTaskInfo getTaskInfo() { 18645 checkCaller(); 18646 18647 synchronized (ActivityManagerService.this) { 18648 long origId = Binder.clearCallingIdentity(); 18649 try { 18650 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18651 if (tr == null) { 18652 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18653 } 18654 return createRecentTaskInfoFromTaskRecord(tr); 18655 } finally { 18656 Binder.restoreCallingIdentity(origId); 18657 } 18658 } 18659 } 18660 18661 @Override 18662 public void moveToFront() { 18663 checkCaller(); 18664 18665 final TaskRecord tr; 18666 synchronized (ActivityManagerService.this) { 18667 tr = recentTaskForIdLocked(mTaskId); 18668 if (tr == null) { 18669 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18670 } 18671 if (tr.getRootActivity() != null) { 18672 long origId = Binder.clearCallingIdentity(); 18673 try { 18674 moveTaskToFrontLocked(tr.taskId, 0, null); 18675 return; 18676 } finally { 18677 Binder.restoreCallingIdentity(origId); 18678 } 18679 } 18680 } 18681 18682 startActivityFromRecentsInner(tr.taskId, null); 18683 } 18684 18685 @Override 18686 public int startActivity(IBinder whoThread, String callingPackage, 18687 Intent intent, String resolvedType, Bundle options) { 18688 checkCaller(); 18689 18690 int callingUser = UserHandle.getCallingUserId(); 18691 TaskRecord tr; 18692 IApplicationThread appThread; 18693 synchronized (ActivityManagerService.this) { 18694 tr = recentTaskForIdLocked(mTaskId); 18695 if (tr == null) { 18696 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18697 } 18698 appThread = ApplicationThreadNative.asInterface(whoThread); 18699 if (appThread == null) { 18700 throw new IllegalArgumentException("Bad app thread " + appThread); 18701 } 18702 } 18703 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18704 resolvedType, null, null, null, null, 0, 0, null, null, 18705 null, null, options, callingUser, null, tr); 18706 } 18707 18708 @Override 18709 public void setExcludeFromRecents(boolean exclude) { 18710 checkCaller(); 18711 18712 synchronized (ActivityManagerService.this) { 18713 long origId = Binder.clearCallingIdentity(); 18714 try { 18715 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18716 if (tr == null) { 18717 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18718 } 18719 Intent intent = tr.getBaseIntent(); 18720 if (exclude) { 18721 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18722 } else { 18723 intent.setFlags(intent.getFlags() 18724 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18725 } 18726 } finally { 18727 Binder.restoreCallingIdentity(origId); 18728 } 18729 } 18730 } 18731 } 18732} 18733