ActivityManagerService.java revision 7f61e96db7c90c1f4418359672aa4656aebee500
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199 200import java.io.BufferedInputStream; 201import java.io.BufferedOutputStream; 202import java.io.DataInputStream; 203import java.io.DataOutputStream; 204import java.io.File; 205import java.io.FileDescriptor; 206import java.io.FileInputStream; 207import java.io.FileNotFoundException; 208import java.io.FileOutputStream; 209import java.io.IOException; 210import java.io.InputStreamReader; 211import java.io.PrintWriter; 212import java.io.StringWriter; 213import java.lang.ref.WeakReference; 214import java.util.ArrayList; 215import java.util.Arrays; 216import java.util.Collections; 217import java.util.Comparator; 218import java.util.HashMap; 219import java.util.HashSet; 220import java.util.Iterator; 221import java.util.List; 222import java.util.Locale; 223import java.util.Map; 224import java.util.Set; 225import java.util.concurrent.atomic.AtomicBoolean; 226import java.util.concurrent.atomic.AtomicLong; 227 228public final class ActivityManagerService extends ActivityManagerNative 229 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 230 231 private static final String USER_DATA_DIR = "/data/user/"; 232 // File that stores last updated system version and called preboot receivers 233 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 234 235 static final String TAG = "ActivityManager"; 236 static final String TAG_MU = "ActivityManagerServiceMU"; 237 static final boolean DEBUG = false; 238 static final boolean localLOGV = DEBUG; 239 static final boolean DEBUG_BACKUP = localLOGV || false; 240 static final boolean DEBUG_BROADCAST = localLOGV || false; 241 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 242 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_CLEANUP = localLOGV || false; 244 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 245 static final boolean DEBUG_FOCUS = false; 246 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 247 static final boolean DEBUG_MU = localLOGV || false; 248 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 249 static final boolean DEBUG_LRU = localLOGV || false; 250 static final boolean DEBUG_PAUSE = localLOGV || false; 251 static final boolean DEBUG_POWER = localLOGV || false; 252 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 253 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 254 static final boolean DEBUG_PROCESSES = localLOGV || false; 255 static final boolean DEBUG_PROVIDER = localLOGV || false; 256 static final boolean DEBUG_RESULTS = localLOGV || false; 257 static final boolean DEBUG_SERVICE = localLOGV || false; 258 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 259 static final boolean DEBUG_STACK = localLOGV || false; 260 static final boolean DEBUG_SWITCH = localLOGV || false; 261 static final boolean DEBUG_TASKS = localLOGV || false; 262 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 263 static final boolean DEBUG_TRANSITION = localLOGV || false; 264 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 265 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 266 static final boolean DEBUG_VISBILITY = localLOGV || false; 267 static final boolean DEBUG_PSS = localLOGV || false; 268 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 269 static final boolean DEBUG_RECENTS = localLOGV || false; 270 static final boolean VALIDATE_TOKENS = false; 271 static final boolean SHOW_ACTIVITY_START_TIME = true; 272 273 // Control over CPU and battery monitoring. 274 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 275 static final boolean MONITOR_CPU_USAGE = true; 276 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 277 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 278 static final boolean MONITOR_THREAD_CPU_USAGE = false; 279 280 // The flags that are set for all calls we make to the package manager. 281 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 282 283 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 284 285 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 286 287 // Maximum number recent bitmaps to keep in memory. 288 static final int MAX_RECENT_BITMAPS = 5; 289 290 // Amount of time after a call to stopAppSwitches() during which we will 291 // prevent further untrusted switches from happening. 292 static final long APP_SWITCH_DELAY_TIME = 5*1000; 293 294 // How long we wait for a launched process to attach to the activity manager 295 // before we decide it's never going to come up for real. 296 static final int PROC_START_TIMEOUT = 10*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real, when the process was 300 // started with a wrapper for instrumentation (such as Valgrind) because it 301 // could take much longer than usual. 302 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 303 304 // How long to wait after going idle before forcing apps to GC. 305 static final int GC_TIMEOUT = 5*1000; 306 307 // The minimum amount of time between successive GC requests for a process. 308 static final int GC_MIN_INTERVAL = 60*1000; 309 310 // The minimum amount of time between successive PSS requests for a process. 311 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 312 313 // The minimum amount of time between successive PSS requests for a process 314 // when the request is due to the memory state being lowered. 315 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 316 317 // The rate at which we check for apps using excessive power -- 15 mins. 318 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 319 320 // The minimum sample duration we will allow before deciding we have 321 // enough data on wake locks to start killing things. 322 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on CPU usage to start killing things. 326 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // How long we allow a receiver to run before giving up on it. 329 static final int BROADCAST_FG_TIMEOUT = 10*1000; 330 static final int BROADCAST_BG_TIMEOUT = 60*1000; 331 332 // How long we wait until we timeout on key dispatching. 333 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 334 335 // How long we wait until we timeout on key dispatching during instrumentation. 336 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 337 338 // Amount of time we wait for observers to handle a user switch before 339 // giving up on them and unfreezing the screen. 340 static final int USER_SWITCH_TIMEOUT = 2*1000; 341 342 // Maximum number of users we allow to be running at a time. 343 static final int MAX_RUNNING_USERS = 3; 344 345 // How long to wait in getAssistContextExtras for the activity and foreground services 346 // to respond with the result. 347 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 348 349 // Maximum number of persisted Uri grants a package is allowed 350 static final int MAX_PERSISTED_URI_GRANTS = 128; 351 352 static final int MY_PID = Process.myPid(); 353 354 static final String[] EMPTY_STRING_ARRAY = new String[0]; 355 356 // How many bytes to write into the dropbox log before truncating 357 static final int DROPBOX_MAX_SIZE = 256 * 1024; 358 359 // Access modes for handleIncomingUser. 360 static final int ALLOW_NON_FULL = 0; 361 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 362 static final int ALLOW_FULL_ONLY = 2; 363 364 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 365 366 /** All system services */ 367 SystemServiceManager mSystemServiceManager; 368 369 /** Run all ActivityStacks through this */ 370 ActivityStackSupervisor mStackSupervisor; 371 372 public IntentFirewall mIntentFirewall; 373 374 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 375 // default actuion automatically. Important for devices without direct input 376 // devices. 377 private boolean mShowDialogs = true; 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 415 416 /** 417 * For addAppTask: cached of the last activity component that was added. 418 */ 419 ComponentName mLastAddedTaskComponent; 420 421 /** 422 * For addAppTask: cached of the last activity uid that was added. 423 */ 424 int mLastAddedTaskUid; 425 426 /** 427 * For addAppTask: cached of the last ActivityInfo that was added. 428 */ 429 ActivityInfo mLastAddedTaskActivity; 430 431 public class PendingAssistExtras extends Binder implements Runnable { 432 public final ActivityRecord activity; 433 public boolean haveResult = false; 434 public Bundle result = null; 435 public PendingAssistExtras(ActivityRecord _activity) { 436 activity = _activity; 437 } 438 @Override 439 public void run() { 440 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 441 synchronized (this) { 442 haveResult = true; 443 notifyAll(); 444 } 445 } 446 } 447 448 final ArrayList<PendingAssistExtras> mPendingAssistExtras 449 = new ArrayList<PendingAssistExtras>(); 450 451 /** 452 * Process management. 453 */ 454 final ProcessList mProcessList = new ProcessList(); 455 456 /** 457 * All of the applications we currently have running organized by name. 458 * The keys are strings of the application package name (as 459 * returned by the package manager), and the keys are ApplicationRecord 460 * objects. 461 */ 462 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 463 464 /** 465 * Tracking long-term execution of processes to look for abuse and other 466 * bad app behavior. 467 */ 468 final ProcessStatsService mProcessStats; 469 470 /** 471 * The currently running isolated processes. 472 */ 473 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 474 475 /** 476 * Counter for assigning isolated process uids, to avoid frequently reusing the 477 * same ones. 478 */ 479 int mNextIsolatedProcessUid = 0; 480 481 /** 482 * The currently running heavy-weight process, if any. 483 */ 484 ProcessRecord mHeavyWeightProcess = null; 485 486 /** 487 * The last time that various processes have crashed. 488 */ 489 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 490 491 /** 492 * Information about a process that is currently marked as bad. 493 */ 494 static final class BadProcessInfo { 495 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 496 this.time = time; 497 this.shortMsg = shortMsg; 498 this.longMsg = longMsg; 499 this.stack = stack; 500 } 501 502 final long time; 503 final String shortMsg; 504 final String longMsg; 505 final String stack; 506 } 507 508 /** 509 * Set of applications that we consider to be bad, and will reject 510 * incoming broadcasts from (which the user has no control over). 511 * Processes are added to this set when they have crashed twice within 512 * a minimum amount of time; they are removed from it when they are 513 * later restarted (hopefully due to some user action). The value is the 514 * time it was added to the list. 515 */ 516 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 517 518 /** 519 * All of the processes we currently have running organized by pid. 520 * The keys are the pid running the application. 521 * 522 * <p>NOTE: This object is protected by its own lock, NOT the global 523 * activity manager lock! 524 */ 525 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 526 527 /** 528 * All of the processes that have been forced to be foreground. The key 529 * is the pid of the caller who requested it (we hold a death 530 * link on it). 531 */ 532 abstract class ForegroundToken implements IBinder.DeathRecipient { 533 int pid; 534 IBinder token; 535 } 536 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 537 538 /** 539 * List of records for processes that someone had tried to start before the 540 * system was ready. We don't start them at that point, but ensure they 541 * are started by the time booting is complete. 542 */ 543 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 544 545 /** 546 * List of persistent applications that are in the process 547 * of being started. 548 */ 549 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes that are being forcibly torn down. 553 */ 554 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * List of running applications, sorted by recent usage. 558 * The first entry in the list is the least recently used. 559 */ 560 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Where in mLruProcesses that the processes hosting activities start. 564 */ 565 int mLruProcessActivityStart = 0; 566 567 /** 568 * Where in mLruProcesses that the processes hosting services start. 569 * This is after (lower index) than mLruProcessesActivityStart. 570 */ 571 int mLruProcessServiceStart = 0; 572 573 /** 574 * List of processes that should gc as soon as things are idle. 575 */ 576 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes we want to collect PSS data from. 580 */ 581 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * Last time we requested PSS data of all processes. 585 */ 586 long mLastFullPssTime = SystemClock.uptimeMillis(); 587 588 /** 589 * If set, the next time we collect PSS data we should do a full collection 590 * with data from native processes and the kernel. 591 */ 592 boolean mFullPssPending = false; 593 594 /** 595 * This is the process holding what we currently consider to be 596 * the "home" activity. 597 */ 598 ProcessRecord mHomeProcess; 599 600 /** 601 * This is the process holding the activity the user last visited that 602 * is in a different process from the one they are currently in. 603 */ 604 ProcessRecord mPreviousProcess; 605 606 /** 607 * The time at which the previous process was last visible. 608 */ 609 long mPreviousProcessVisibleTime; 610 611 /** 612 * Which uses have been started, so are allowed to run code. 613 */ 614 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 615 616 /** 617 * LRU list of history of current users. Most recently current is at the end. 618 */ 619 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 620 621 /** 622 * Constant array of the users that are currently started. 623 */ 624 int[] mStartedUserArray = new int[] { 0 }; 625 626 /** 627 * Registered observers of the user switching mechanics. 628 */ 629 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 630 = new RemoteCallbackList<IUserSwitchObserver>(); 631 632 /** 633 * Currently active user switch. 634 */ 635 Object mCurUserSwitchCallback; 636 637 /** 638 * Packages that the user has asked to have run in screen size 639 * compatibility mode instead of filling the screen. 640 */ 641 final CompatModePackages mCompatModePackages; 642 643 /** 644 * Set of IntentSenderRecord objects that are currently active. 645 */ 646 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 647 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 648 649 /** 650 * Fingerprints (hashCode()) of stack traces that we've 651 * already logged DropBox entries for. Guarded by itself. If 652 * something (rogue user app) forces this over 653 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 654 */ 655 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 656 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 657 658 /** 659 * Strict Mode background batched logging state. 660 * 661 * The string buffer is guarded by itself, and its lock is also 662 * used to determine if another batched write is already 663 * in-flight. 664 */ 665 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 666 667 /** 668 * Keeps track of all IIntentReceivers that have been registered for 669 * broadcasts. Hash keys are the receiver IBinder, hash value is 670 * a ReceiverList. 671 */ 672 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 673 new HashMap<IBinder, ReceiverList>(); 674 675 /** 676 * Resolver for broadcast intents to registered receivers. 677 * Holds BroadcastFilter (subclass of IntentFilter). 678 */ 679 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 680 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 681 @Override 682 protected boolean allowFilterResult( 683 BroadcastFilter filter, List<BroadcastFilter> dest) { 684 IBinder target = filter.receiverList.receiver.asBinder(); 685 for (int i=dest.size()-1; i>=0; i--) { 686 if (dest.get(i).receiverList.receiver.asBinder() == target) { 687 return false; 688 } 689 } 690 return true; 691 } 692 693 @Override 694 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 695 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 696 || userId == filter.owningUserId) { 697 return super.newResult(filter, match, userId); 698 } 699 return null; 700 } 701 702 @Override 703 protected BroadcastFilter[] newArray(int size) { 704 return new BroadcastFilter[size]; 705 } 706 707 @Override 708 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 709 return packageName.equals(filter.packageName); 710 } 711 }; 712 713 /** 714 * State of all active sticky broadcasts per user. Keys are the action of the 715 * sticky Intent, values are an ArrayList of all broadcasted intents with 716 * that action (which should usually be one). The SparseArray is keyed 717 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 718 * for stickies that are sent to all users. 719 */ 720 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 721 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 722 723 final ActiveServices mServices; 724 725 /** 726 * Backup/restore process management 727 */ 728 String mBackupAppName = null; 729 BackupRecord mBackupTarget = null; 730 731 final ProviderMap mProviderMap; 732 733 /** 734 * List of content providers who have clients waiting for them. The 735 * application is currently being launched and the provider will be 736 * removed from this list once it is published. 737 */ 738 final ArrayList<ContentProviderRecord> mLaunchingProviders 739 = new ArrayList<ContentProviderRecord>(); 740 741 /** 742 * File storing persisted {@link #mGrantedUriPermissions}. 743 */ 744 private final AtomicFile mGrantFile; 745 746 /** XML constants used in {@link #mGrantFile} */ 747 private static final String TAG_URI_GRANTS = "uri-grants"; 748 private static final String TAG_URI_GRANT = "uri-grant"; 749 private static final String ATTR_USER_HANDLE = "userHandle"; 750 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 751 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 752 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 753 private static final String ATTR_TARGET_PKG = "targetPkg"; 754 private static final String ATTR_URI = "uri"; 755 private static final String ATTR_MODE_FLAGS = "modeFlags"; 756 private static final String ATTR_CREATED_TIME = "createdTime"; 757 private static final String ATTR_PREFIX = "prefix"; 758 759 /** 760 * Global set of specific {@link Uri} permissions that have been granted. 761 * This optimized lookup structure maps from {@link UriPermission#targetUid} 762 * to {@link UriPermission#uri} to {@link UriPermission}. 763 */ 764 @GuardedBy("this") 765 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 766 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 767 768 public static class GrantUri { 769 public final int sourceUserId; 770 public final Uri uri; 771 public boolean prefix; 772 773 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 774 this.sourceUserId = sourceUserId; 775 this.uri = uri; 776 this.prefix = prefix; 777 } 778 779 @Override 780 public int hashCode() { 781 return toString().hashCode(); 782 } 783 784 @Override 785 public boolean equals(Object o) { 786 if (o instanceof GrantUri) { 787 GrantUri other = (GrantUri) o; 788 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 789 && prefix == other.prefix; 790 } 791 return false; 792 } 793 794 @Override 795 public String toString() { 796 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 797 if (prefix) result += " [prefix]"; 798 return result; 799 } 800 801 public String toSafeString() { 802 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 803 if (prefix) result += " [prefix]"; 804 return result; 805 } 806 807 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 808 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 809 ContentProvider.getUriWithoutUserId(uri), false); 810 } 811 } 812 813 CoreSettingsObserver mCoreSettingsObserver; 814 815 /** 816 * Thread-local storage used to carry caller permissions over through 817 * indirect content-provider access. 818 */ 819 private class Identity { 820 public int pid; 821 public int uid; 822 823 Identity(int _pid, int _uid) { 824 pid = _pid; 825 uid = _uid; 826 } 827 } 828 829 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 830 831 /** 832 * All information we have collected about the runtime performance of 833 * any user id that can impact battery performance. 834 */ 835 final BatteryStatsService mBatteryStatsService; 836 837 /** 838 * Information about component usage 839 */ 840 UsageStatsManagerInternal mUsageStatsService; 841 842 /** 843 * Information about and control over application operations 844 */ 845 final AppOpsService mAppOpsService; 846 847 /** 848 * Save recent tasks information across reboots. 849 */ 850 final TaskPersister mTaskPersister; 851 852 /** 853 * Current configuration information. HistoryRecord objects are given 854 * a reference to this object to indicate which configuration they are 855 * currently running in, so this object must be kept immutable. 856 */ 857 Configuration mConfiguration = new Configuration(); 858 859 /** 860 * Current sequencing integer of the configuration, for skipping old 861 * configurations. 862 */ 863 int mConfigurationSeq = 0; 864 865 /** 866 * Hardware-reported OpenGLES version. 867 */ 868 final int GL_ES_VERSION; 869 870 /** 871 * List of initialization arguments to pass to all processes when binding applications to them. 872 * For example, references to the commonly used services. 873 */ 874 HashMap<String, IBinder> mAppBindArgs; 875 876 /** 877 * Temporary to avoid allocations. Protected by main lock. 878 */ 879 final StringBuilder mStringBuilder = new StringBuilder(256); 880 881 /** 882 * Used to control how we initialize the service. 883 */ 884 ComponentName mTopComponent; 885 String mTopAction = Intent.ACTION_MAIN; 886 String mTopData; 887 boolean mProcessesReady = false; 888 boolean mSystemReady = false; 889 boolean mBooting = false; 890 boolean mWaitingUpdate = false; 891 boolean mDidUpdate = false; 892 boolean mOnBattery = false; 893 boolean mLaunchWarningShown = false; 894 895 Context mContext; 896 897 int mFactoryTest; 898 899 boolean mCheckedForSetup; 900 901 /** 902 * The time at which we will allow normal application switches again, 903 * after a call to {@link #stopAppSwitches()}. 904 */ 905 long mAppSwitchesAllowedTime; 906 907 /** 908 * This is set to true after the first switch after mAppSwitchesAllowedTime 909 * is set; any switches after that will clear the time. 910 */ 911 boolean mDidAppSwitch; 912 913 /** 914 * Last time (in realtime) at which we checked for power usage. 915 */ 916 long mLastPowerCheckRealtime; 917 918 /** 919 * Last time (in uptime) at which we checked for power usage. 920 */ 921 long mLastPowerCheckUptime; 922 923 /** 924 * Set while we are wanting to sleep, to prevent any 925 * activities from being started/resumed. 926 */ 927 private boolean mSleeping = false; 928 929 /** 930 * Set while we are running a voice interaction. This overrides 931 * sleeping while it is active. 932 */ 933 private boolean mRunningVoice = false; 934 935 /** 936 * State of external calls telling us if the device is asleep. 937 */ 938 private boolean mWentToSleep = false; 939 940 /** 941 * State of external call telling us if the lock screen is shown. 942 */ 943 private boolean mLockScreenShown = false; 944 945 /** 946 * Set if we are shutting down the system, similar to sleeping. 947 */ 948 boolean mShuttingDown = false; 949 950 /** 951 * Current sequence id for oom_adj computation traversal. 952 */ 953 int mAdjSeq = 0; 954 955 /** 956 * Current sequence id for process LRU updating. 957 */ 958 int mLruSeq = 0; 959 960 /** 961 * Keep track of the non-cached/empty process we last found, to help 962 * determine how to distribute cached/empty processes next time. 963 */ 964 int mNumNonCachedProcs = 0; 965 966 /** 967 * Keep track of the number of cached hidden procs, to balance oom adj 968 * distribution between those and empty procs. 969 */ 970 int mNumCachedHiddenProcs = 0; 971 972 /** 973 * Keep track of the number of service processes we last found, to 974 * determine on the next iteration which should be B services. 975 */ 976 int mNumServiceProcs = 0; 977 int mNewNumAServiceProcs = 0; 978 int mNewNumServiceProcs = 0; 979 980 /** 981 * Allow the current computed overall memory level of the system to go down? 982 * This is set to false when we are killing processes for reasons other than 983 * memory management, so that the now smaller process list will not be taken as 984 * an indication that memory is tighter. 985 */ 986 boolean mAllowLowerMemLevel = false; 987 988 /** 989 * The last computed memory level, for holding when we are in a state that 990 * processes are going away for other reasons. 991 */ 992 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 993 994 /** 995 * The last total number of process we have, to determine if changes actually look 996 * like a shrinking number of process due to lower RAM. 997 */ 998 int mLastNumProcesses; 999 1000 /** 1001 * The uptime of the last time we performed idle maintenance. 1002 */ 1003 long mLastIdleTime = SystemClock.uptimeMillis(); 1004 1005 /** 1006 * Total time spent with RAM that has been added in the past since the last idle time. 1007 */ 1008 long mLowRamTimeSinceLastIdle = 0; 1009 1010 /** 1011 * If RAM is currently low, when that horrible situation started. 1012 */ 1013 long mLowRamStartTime = 0; 1014 1015 /** 1016 * For reporting to battery stats the current top application. 1017 */ 1018 private String mCurResumedPackage = null; 1019 private int mCurResumedUid = -1; 1020 1021 /** 1022 * For reporting to battery stats the apps currently running foreground 1023 * service. The ProcessMap is package/uid tuples; each of these contain 1024 * an array of the currently foreground processes. 1025 */ 1026 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1027 = new ProcessMap<ArrayList<ProcessRecord>>(); 1028 1029 /** 1030 * This is set if we had to do a delayed dexopt of an app before launching 1031 * it, to increase the ANR timeouts in that case. 1032 */ 1033 boolean mDidDexOpt; 1034 1035 /** 1036 * Set if the systemServer made a call to enterSafeMode. 1037 */ 1038 boolean mSafeMode; 1039 1040 String mDebugApp = null; 1041 boolean mWaitForDebugger = false; 1042 boolean mDebugTransient = false; 1043 String mOrigDebugApp = null; 1044 boolean mOrigWaitForDebugger = false; 1045 boolean mAlwaysFinishActivities = false; 1046 IActivityController mController = null; 1047 String mProfileApp = null; 1048 ProcessRecord mProfileProc = null; 1049 String mProfileFile; 1050 ParcelFileDescriptor mProfileFd; 1051 int mSamplingInterval = 0; 1052 boolean mAutoStopProfiler = false; 1053 int mProfileType = 0; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 int mCurrentUserId = 0; 1111 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1112 1113 /** 1114 * Mapping from each known user ID to the profile group ID it is associated with. 1115 */ 1116 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1117 1118 private UserManagerService mUserManager; 1119 1120 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1121 final ProcessRecord mApp; 1122 final int mPid; 1123 final IApplicationThread mAppThread; 1124 1125 AppDeathRecipient(ProcessRecord app, int pid, 1126 IApplicationThread thread) { 1127 if (localLOGV) Slog.v( 1128 TAG, "New death recipient " + this 1129 + " for thread " + thread.asBinder()); 1130 mApp = app; 1131 mPid = pid; 1132 mAppThread = thread; 1133 } 1134 1135 @Override 1136 public void binderDied() { 1137 if (localLOGV) Slog.v( 1138 TAG, "Death received in " + this 1139 + " for thread " + mAppThread.asBinder()); 1140 synchronized(ActivityManagerService.this) { 1141 appDiedLocked(mApp, mPid, mAppThread); 1142 } 1143 } 1144 } 1145 1146 static final int SHOW_ERROR_MSG = 1; 1147 static final int SHOW_NOT_RESPONDING_MSG = 2; 1148 static final int SHOW_FACTORY_ERROR_MSG = 3; 1149 static final int UPDATE_CONFIGURATION_MSG = 4; 1150 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1151 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1152 static final int SERVICE_TIMEOUT_MSG = 12; 1153 static final int UPDATE_TIME_ZONE = 13; 1154 static final int SHOW_UID_ERROR_MSG = 14; 1155 static final int IM_FEELING_LUCKY_MSG = 15; 1156 static final int PROC_START_TIMEOUT_MSG = 20; 1157 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1158 static final int KILL_APPLICATION_MSG = 22; 1159 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1160 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1161 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1162 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1163 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1164 static final int CLEAR_DNS_CACHE_MSG = 28; 1165 static final int UPDATE_HTTP_PROXY_MSG = 29; 1166 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1167 static final int DISPATCH_PROCESSES_CHANGED = 31; 1168 static final int DISPATCH_PROCESS_DIED = 32; 1169 static final int REPORT_MEM_USAGE_MSG = 33; 1170 static final int REPORT_USER_SWITCH_MSG = 34; 1171 static final int CONTINUE_USER_SWITCH_MSG = 35; 1172 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1173 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1174 static final int PERSIST_URI_GRANTS_MSG = 38; 1175 static final int REQUEST_ALL_PSS_MSG = 39; 1176 static final int START_PROFILES_MSG = 40; 1177 static final int UPDATE_TIME = 41; 1178 static final int SYSTEM_USER_START_MSG = 42; 1179 static final int SYSTEM_USER_CURRENT_MSG = 43; 1180 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1181 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1182 static final int START_USER_SWITCH_MSG = 46; 1183 1184 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1185 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1186 static final int FIRST_COMPAT_MODE_MSG = 300; 1187 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1188 1189 AlertDialog mUidAlert; 1190 CompatModeDialog mCompatModeDialog; 1191 long mLastMemUsageReportTime = 0; 1192 1193 private LockToAppRequestDialog mLockToAppRequest; 1194 1195 /** 1196 * Flag whether the current user is a "monkey", i.e. whether 1197 * the UI is driven by a UI automation tool. 1198 */ 1199 private boolean mUserIsMonkey; 1200 1201 /** Flag whether the device has a Recents UI */ 1202 boolean mHasRecents; 1203 1204 /** The dimensions of the thumbnails in the Recents UI. */ 1205 int mThumbnailWidth; 1206 int mThumbnailHeight; 1207 1208 final ServiceThread mHandlerThread; 1209 final MainHandler mHandler; 1210 1211 final class MainHandler extends Handler { 1212 public MainHandler(Looper looper) { 1213 super(looper, null, true); 1214 } 1215 1216 @Override 1217 public void handleMessage(Message msg) { 1218 switch (msg.what) { 1219 case SHOW_ERROR_MSG: { 1220 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1221 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1222 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1223 synchronized (ActivityManagerService.this) { 1224 ProcessRecord proc = (ProcessRecord)data.get("app"); 1225 AppErrorResult res = (AppErrorResult) data.get("result"); 1226 if (proc != null && proc.crashDialog != null) { 1227 Slog.e(TAG, "App already has crash dialog: " + proc); 1228 if (res != null) { 1229 res.set(0); 1230 } 1231 return; 1232 } 1233 boolean isBackground = (UserHandle.getAppId(proc.uid) 1234 >= Process.FIRST_APPLICATION_UID 1235 && proc.pid != MY_PID); 1236 for (int userId : mCurrentProfileIds) { 1237 isBackground &= (proc.userId != userId); 1238 } 1239 if (isBackground && !showBackground) { 1240 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1241 if (res != null) { 1242 res.set(0); 1243 } 1244 return; 1245 } 1246 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1247 Dialog d = new AppErrorDialog(mContext, 1248 ActivityManagerService.this, res, proc); 1249 d.show(); 1250 proc.crashDialog = d; 1251 } else { 1252 // The device is asleep, so just pretend that the user 1253 // saw a crash dialog and hit "force quit". 1254 if (res != null) { 1255 res.set(0); 1256 } 1257 } 1258 } 1259 1260 ensureBootCompleted(); 1261 } break; 1262 case SHOW_NOT_RESPONDING_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1265 ProcessRecord proc = (ProcessRecord)data.get("app"); 1266 if (proc != null && proc.anrDialog != null) { 1267 Slog.e(TAG, "App already has anr dialog: " + proc); 1268 return; 1269 } 1270 1271 Intent intent = new Intent("android.intent.action.ANR"); 1272 if (!mProcessesReady) { 1273 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1274 | Intent.FLAG_RECEIVER_FOREGROUND); 1275 } 1276 broadcastIntentLocked(null, null, intent, 1277 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1278 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1279 1280 if (mShowDialogs) { 1281 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1282 mContext, proc, (ActivityRecord)data.get("activity"), 1283 msg.arg1 != 0); 1284 d.show(); 1285 proc.anrDialog = d; 1286 } else { 1287 // Just kill the app if there is no dialog to be shown. 1288 killAppAtUsersRequest(proc, null); 1289 } 1290 } 1291 1292 ensureBootCompleted(); 1293 } break; 1294 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1295 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1296 synchronized (ActivityManagerService.this) { 1297 ProcessRecord proc = (ProcessRecord) data.get("app"); 1298 if (proc == null) { 1299 Slog.e(TAG, "App not found when showing strict mode dialog."); 1300 break; 1301 } 1302 if (proc.crashDialog != null) { 1303 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1304 return; 1305 } 1306 AppErrorResult res = (AppErrorResult) data.get("result"); 1307 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1308 Dialog d = new StrictModeViolationDialog(mContext, 1309 ActivityManagerService.this, res, proc); 1310 d.show(); 1311 proc.crashDialog = d; 1312 } else { 1313 // The device is asleep, so just pretend that the user 1314 // saw a crash dialog and hit "force quit". 1315 res.set(0); 1316 } 1317 } 1318 ensureBootCompleted(); 1319 } break; 1320 case SHOW_FACTORY_ERROR_MSG: { 1321 Dialog d = new FactoryErrorDialog( 1322 mContext, msg.getData().getCharSequence("msg")); 1323 d.show(); 1324 ensureBootCompleted(); 1325 } break; 1326 case UPDATE_CONFIGURATION_MSG: { 1327 final ContentResolver resolver = mContext.getContentResolver(); 1328 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1329 } break; 1330 case GC_BACKGROUND_PROCESSES_MSG: { 1331 synchronized (ActivityManagerService.this) { 1332 performAppGcsIfAppropriateLocked(); 1333 } 1334 } break; 1335 case WAIT_FOR_DEBUGGER_MSG: { 1336 synchronized (ActivityManagerService.this) { 1337 ProcessRecord app = (ProcessRecord)msg.obj; 1338 if (msg.arg1 != 0) { 1339 if (!app.waitedForDebugger) { 1340 Dialog d = new AppWaitingForDebuggerDialog( 1341 ActivityManagerService.this, 1342 mContext, app); 1343 app.waitDialog = d; 1344 app.waitedForDebugger = true; 1345 d.show(); 1346 } 1347 } else { 1348 if (app.waitDialog != null) { 1349 app.waitDialog.dismiss(); 1350 app.waitDialog = null; 1351 } 1352 } 1353 } 1354 } break; 1355 case SERVICE_TIMEOUT_MSG: { 1356 if (mDidDexOpt) { 1357 mDidDexOpt = false; 1358 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1359 nmsg.obj = msg.obj; 1360 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1361 return; 1362 } 1363 mServices.serviceTimeout((ProcessRecord)msg.obj); 1364 } break; 1365 case UPDATE_TIME_ZONE: { 1366 synchronized (ActivityManagerService.this) { 1367 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1368 ProcessRecord r = mLruProcesses.get(i); 1369 if (r.thread != null) { 1370 try { 1371 r.thread.updateTimeZone(); 1372 } catch (RemoteException ex) { 1373 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1374 } 1375 } 1376 } 1377 } 1378 } break; 1379 case CLEAR_DNS_CACHE_MSG: { 1380 synchronized (ActivityManagerService.this) { 1381 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1382 ProcessRecord r = mLruProcesses.get(i); 1383 if (r.thread != null) { 1384 try { 1385 r.thread.clearDnsCache(); 1386 } catch (RemoteException ex) { 1387 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1388 } 1389 } 1390 } 1391 } 1392 } break; 1393 case UPDATE_HTTP_PROXY_MSG: { 1394 ProxyInfo proxy = (ProxyInfo)msg.obj; 1395 String host = ""; 1396 String port = ""; 1397 String exclList = ""; 1398 Uri pacFileUrl = Uri.EMPTY; 1399 if (proxy != null) { 1400 host = proxy.getHost(); 1401 port = Integer.toString(proxy.getPort()); 1402 exclList = proxy.getExclusionListAsString(); 1403 pacFileUrl = proxy.getPacFileUrl(); 1404 } 1405 synchronized (ActivityManagerService.this) { 1406 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1407 ProcessRecord r = mLruProcesses.get(i); 1408 if (r.thread != null) { 1409 try { 1410 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1411 } catch (RemoteException ex) { 1412 Slog.w(TAG, "Failed to update http proxy for: " + 1413 r.info.processName); 1414 } 1415 } 1416 } 1417 } 1418 } break; 1419 case SHOW_UID_ERROR_MSG: { 1420 String title = "System UIDs Inconsistent"; 1421 String text = "UIDs on the system are inconsistent, you need to wipe your" 1422 + " data partition or your device will be unstable."; 1423 Log.e(TAG, title + ": " + text); 1424 if (mShowDialogs) { 1425 // XXX This is a temporary dialog, no need to localize. 1426 AlertDialog d = new BaseErrorDialog(mContext); 1427 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1428 d.setCancelable(false); 1429 d.setTitle(title); 1430 d.setMessage(text); 1431 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1432 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1433 mUidAlert = d; 1434 d.show(); 1435 } 1436 } break; 1437 case IM_FEELING_LUCKY_MSG: { 1438 if (mUidAlert != null) { 1439 mUidAlert.dismiss(); 1440 mUidAlert = null; 1441 } 1442 } break; 1443 case PROC_START_TIMEOUT_MSG: { 1444 if (mDidDexOpt) { 1445 mDidDexOpt = false; 1446 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1447 nmsg.obj = msg.obj; 1448 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1449 return; 1450 } 1451 ProcessRecord app = (ProcessRecord)msg.obj; 1452 synchronized (ActivityManagerService.this) { 1453 processStartTimedOutLocked(app); 1454 } 1455 } break; 1456 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1457 synchronized (ActivityManagerService.this) { 1458 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1459 } 1460 } break; 1461 case KILL_APPLICATION_MSG: { 1462 synchronized (ActivityManagerService.this) { 1463 int appid = msg.arg1; 1464 boolean restart = (msg.arg2 == 1); 1465 Bundle bundle = (Bundle)msg.obj; 1466 String pkg = bundle.getString("pkg"); 1467 String reason = bundle.getString("reason"); 1468 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1469 false, UserHandle.USER_ALL, reason); 1470 } 1471 } break; 1472 case FINALIZE_PENDING_INTENT_MSG: { 1473 ((PendingIntentRecord)msg.obj).completeFinalize(); 1474 } break; 1475 case POST_HEAVY_NOTIFICATION_MSG: { 1476 INotificationManager inm = NotificationManager.getService(); 1477 if (inm == null) { 1478 return; 1479 } 1480 1481 ActivityRecord root = (ActivityRecord)msg.obj; 1482 ProcessRecord process = root.app; 1483 if (process == null) { 1484 return; 1485 } 1486 1487 try { 1488 Context context = mContext.createPackageContext(process.info.packageName, 0); 1489 String text = mContext.getString(R.string.heavy_weight_notification, 1490 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1491 Notification notification = new Notification(); 1492 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1493 notification.when = 0; 1494 notification.flags = Notification.FLAG_ONGOING_EVENT; 1495 notification.tickerText = text; 1496 notification.defaults = 0; // please be quiet 1497 notification.sound = null; 1498 notification.vibrate = null; 1499 notification.color = mContext.getResources().getColor( 1500 com.android.internal.R.color.system_notification_accent_color); 1501 notification.setLatestEventInfo(context, text, 1502 mContext.getText(R.string.heavy_weight_notification_detail), 1503 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1504 PendingIntent.FLAG_CANCEL_CURRENT, null, 1505 new UserHandle(root.userId))); 1506 1507 try { 1508 int[] outId = new int[1]; 1509 inm.enqueueNotificationWithTag("android", "android", null, 1510 R.string.heavy_weight_notification, 1511 notification, outId, root.userId); 1512 } catch (RuntimeException e) { 1513 Slog.w(ActivityManagerService.TAG, 1514 "Error showing notification for heavy-weight app", e); 1515 } catch (RemoteException e) { 1516 } 1517 } catch (NameNotFoundException e) { 1518 Slog.w(TAG, "Unable to create context for heavy notification", e); 1519 } 1520 } break; 1521 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1522 INotificationManager inm = NotificationManager.getService(); 1523 if (inm == null) { 1524 return; 1525 } 1526 try { 1527 inm.cancelNotificationWithTag("android", null, 1528 R.string.heavy_weight_notification, msg.arg1); 1529 } catch (RuntimeException e) { 1530 Slog.w(ActivityManagerService.TAG, 1531 "Error canceling notification for service", e); 1532 } catch (RemoteException e) { 1533 } 1534 } break; 1535 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1536 synchronized (ActivityManagerService.this) { 1537 checkExcessivePowerUsageLocked(true); 1538 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1539 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1540 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1541 } 1542 } break; 1543 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1544 synchronized (ActivityManagerService.this) { 1545 ActivityRecord ar = (ActivityRecord)msg.obj; 1546 if (mCompatModeDialog != null) { 1547 if (mCompatModeDialog.mAppInfo.packageName.equals( 1548 ar.info.applicationInfo.packageName)) { 1549 return; 1550 } 1551 mCompatModeDialog.dismiss(); 1552 mCompatModeDialog = null; 1553 } 1554 if (ar != null && false) { 1555 if (mCompatModePackages.getPackageAskCompatModeLocked( 1556 ar.packageName)) { 1557 int mode = mCompatModePackages.computeCompatModeLocked( 1558 ar.info.applicationInfo); 1559 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1560 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1561 mCompatModeDialog = new CompatModeDialog( 1562 ActivityManagerService.this, mContext, 1563 ar.info.applicationInfo); 1564 mCompatModeDialog.show(); 1565 } 1566 } 1567 } 1568 } 1569 break; 1570 } 1571 case DISPATCH_PROCESSES_CHANGED: { 1572 dispatchProcessesChanged(); 1573 break; 1574 } 1575 case DISPATCH_PROCESS_DIED: { 1576 final int pid = msg.arg1; 1577 final int uid = msg.arg2; 1578 dispatchProcessDied(pid, uid); 1579 break; 1580 } 1581 case REPORT_MEM_USAGE_MSG: { 1582 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1583 Thread thread = new Thread() { 1584 @Override public void run() { 1585 final SparseArray<ProcessMemInfo> infoMap 1586 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1587 for (int i=0, N=memInfos.size(); i<N; i++) { 1588 ProcessMemInfo mi = memInfos.get(i); 1589 infoMap.put(mi.pid, mi); 1590 } 1591 updateCpuStatsNow(); 1592 synchronized (mProcessCpuThread) { 1593 final int N = mProcessCpuTracker.countStats(); 1594 for (int i=0; i<N; i++) { 1595 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1596 if (st.vsize > 0) { 1597 long pss = Debug.getPss(st.pid, null); 1598 if (pss > 0) { 1599 if (infoMap.indexOfKey(st.pid) < 0) { 1600 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1601 ProcessList.NATIVE_ADJ, -1, "native", null); 1602 mi.pss = pss; 1603 memInfos.add(mi); 1604 } 1605 } 1606 } 1607 } 1608 } 1609 1610 long totalPss = 0; 1611 for (int i=0, N=memInfos.size(); i<N; i++) { 1612 ProcessMemInfo mi = memInfos.get(i); 1613 if (mi.pss == 0) { 1614 mi.pss = Debug.getPss(mi.pid, null); 1615 } 1616 totalPss += mi.pss; 1617 } 1618 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1619 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1620 if (lhs.oomAdj != rhs.oomAdj) { 1621 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1622 } 1623 if (lhs.pss != rhs.pss) { 1624 return lhs.pss < rhs.pss ? 1 : -1; 1625 } 1626 return 0; 1627 } 1628 }); 1629 1630 StringBuilder tag = new StringBuilder(128); 1631 StringBuilder stack = new StringBuilder(128); 1632 tag.append("Low on memory -- "); 1633 appendMemBucket(tag, totalPss, "total", false); 1634 appendMemBucket(stack, totalPss, "total", true); 1635 1636 StringBuilder logBuilder = new StringBuilder(1024); 1637 logBuilder.append("Low on memory:\n"); 1638 1639 boolean firstLine = true; 1640 int lastOomAdj = Integer.MIN_VALUE; 1641 for (int i=0, N=memInfos.size(); i<N; i++) { 1642 ProcessMemInfo mi = memInfos.get(i); 1643 1644 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1645 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1646 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1647 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1648 if (lastOomAdj != mi.oomAdj) { 1649 lastOomAdj = mi.oomAdj; 1650 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1651 tag.append(" / "); 1652 } 1653 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1654 if (firstLine) { 1655 stack.append(":"); 1656 firstLine = false; 1657 } 1658 stack.append("\n\t at "); 1659 } else { 1660 stack.append("$"); 1661 } 1662 } else { 1663 tag.append(" "); 1664 stack.append("$"); 1665 } 1666 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1667 appendMemBucket(tag, mi.pss, mi.name, false); 1668 } 1669 appendMemBucket(stack, mi.pss, mi.name, true); 1670 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1671 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1672 stack.append("("); 1673 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1674 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1675 stack.append(DUMP_MEM_OOM_LABEL[k]); 1676 stack.append(":"); 1677 stack.append(DUMP_MEM_OOM_ADJ[k]); 1678 } 1679 } 1680 stack.append(")"); 1681 } 1682 } 1683 1684 logBuilder.append(" "); 1685 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1686 logBuilder.append(' '); 1687 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1688 logBuilder.append(' '); 1689 ProcessList.appendRamKb(logBuilder, mi.pss); 1690 logBuilder.append(" kB: "); 1691 logBuilder.append(mi.name); 1692 logBuilder.append(" ("); 1693 logBuilder.append(mi.pid); 1694 logBuilder.append(") "); 1695 logBuilder.append(mi.adjType); 1696 logBuilder.append('\n'); 1697 if (mi.adjReason != null) { 1698 logBuilder.append(" "); 1699 logBuilder.append(mi.adjReason); 1700 logBuilder.append('\n'); 1701 } 1702 } 1703 1704 logBuilder.append(" "); 1705 ProcessList.appendRamKb(logBuilder, totalPss); 1706 logBuilder.append(" kB: TOTAL\n"); 1707 1708 long[] infos = new long[Debug.MEMINFO_COUNT]; 1709 Debug.getMemInfo(infos); 1710 logBuilder.append(" MemInfo: "); 1711 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1712 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1713 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1714 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1715 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1716 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1717 logBuilder.append(" ZRAM: "); 1718 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1719 logBuilder.append(" kB RAM, "); 1720 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1721 logBuilder.append(" kB swap total, "); 1722 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1723 logBuilder.append(" kB swap free\n"); 1724 } 1725 Slog.i(TAG, logBuilder.toString()); 1726 1727 StringBuilder dropBuilder = new StringBuilder(1024); 1728 /* 1729 StringWriter oomSw = new StringWriter(); 1730 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1731 StringWriter catSw = new StringWriter(); 1732 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1733 String[] emptyArgs = new String[] { }; 1734 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1735 oomPw.flush(); 1736 String oomString = oomSw.toString(); 1737 */ 1738 dropBuilder.append(stack); 1739 dropBuilder.append('\n'); 1740 dropBuilder.append('\n'); 1741 dropBuilder.append(logBuilder); 1742 dropBuilder.append('\n'); 1743 /* 1744 dropBuilder.append(oomString); 1745 dropBuilder.append('\n'); 1746 */ 1747 StringWriter catSw = new StringWriter(); 1748 synchronized (ActivityManagerService.this) { 1749 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1750 String[] emptyArgs = new String[] { }; 1751 catPw.println(); 1752 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1753 catPw.println(); 1754 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1755 false, false, null); 1756 catPw.println(); 1757 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1758 catPw.flush(); 1759 } 1760 dropBuilder.append(catSw.toString()); 1761 addErrorToDropBox("lowmem", null, "system_server", null, 1762 null, tag.toString(), dropBuilder.toString(), null, null); 1763 //Slog.i(TAG, "Sent to dropbox:"); 1764 //Slog.i(TAG, dropBuilder.toString()); 1765 synchronized (ActivityManagerService.this) { 1766 long now = SystemClock.uptimeMillis(); 1767 if (mLastMemUsageReportTime < now) { 1768 mLastMemUsageReportTime = now; 1769 } 1770 } 1771 } 1772 }; 1773 thread.start(); 1774 break; 1775 } 1776 case START_USER_SWITCH_MSG: { 1777 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1778 break; 1779 } 1780 case REPORT_USER_SWITCH_MSG: { 1781 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1782 break; 1783 } 1784 case CONTINUE_USER_SWITCH_MSG: { 1785 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1786 break; 1787 } 1788 case USER_SWITCH_TIMEOUT_MSG: { 1789 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1790 break; 1791 } 1792 case IMMERSIVE_MODE_LOCK_MSG: { 1793 final boolean nextState = (msg.arg1 != 0); 1794 if (mUpdateLock.isHeld() != nextState) { 1795 if (DEBUG_IMMERSIVE) { 1796 final ActivityRecord r = (ActivityRecord) msg.obj; 1797 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1798 } 1799 if (nextState) { 1800 mUpdateLock.acquire(); 1801 } else { 1802 mUpdateLock.release(); 1803 } 1804 } 1805 break; 1806 } 1807 case PERSIST_URI_GRANTS_MSG: { 1808 writeGrantedUriPermissions(); 1809 break; 1810 } 1811 case REQUEST_ALL_PSS_MSG: { 1812 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1813 break; 1814 } 1815 case START_PROFILES_MSG: { 1816 synchronized (ActivityManagerService.this) { 1817 startProfilesLocked(); 1818 } 1819 break; 1820 } 1821 case UPDATE_TIME: { 1822 synchronized (ActivityManagerService.this) { 1823 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1824 ProcessRecord r = mLruProcesses.get(i); 1825 if (r.thread != null) { 1826 try { 1827 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1828 } catch (RemoteException ex) { 1829 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1830 } 1831 } 1832 } 1833 } 1834 break; 1835 } 1836 case SYSTEM_USER_START_MSG: { 1837 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1838 Integer.toString(msg.arg1), msg.arg1); 1839 mSystemServiceManager.startUser(msg.arg1); 1840 break; 1841 } 1842 case SYSTEM_USER_CURRENT_MSG: { 1843 mBatteryStatsService.noteEvent( 1844 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1845 Integer.toString(msg.arg2), msg.arg2); 1846 mBatteryStatsService.noteEvent( 1847 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1848 Integer.toString(msg.arg1), msg.arg1); 1849 mSystemServiceManager.switchUser(msg.arg1); 1850 mLockToAppRequest.clearPrompt(); 1851 break; 1852 } 1853 case ENTER_ANIMATION_COMPLETE_MSG: { 1854 synchronized (ActivityManagerService.this) { 1855 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1856 if (r != null && r.app != null && r.app.thread != null) { 1857 try { 1858 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1859 } catch (RemoteException e) { 1860 } 1861 } 1862 } 1863 break; 1864 } 1865 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1866 enableScreenAfterBoot(); 1867 break; 1868 } 1869 } 1870 } 1871 }; 1872 1873 static final int COLLECT_PSS_BG_MSG = 1; 1874 1875 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1876 @Override 1877 public void handleMessage(Message msg) { 1878 switch (msg.what) { 1879 case COLLECT_PSS_BG_MSG: { 1880 long start = SystemClock.uptimeMillis(); 1881 MemInfoReader memInfo = null; 1882 synchronized (ActivityManagerService.this) { 1883 if (mFullPssPending) { 1884 mFullPssPending = false; 1885 memInfo = new MemInfoReader(); 1886 } 1887 } 1888 if (memInfo != null) { 1889 updateCpuStatsNow(); 1890 long nativeTotalPss = 0; 1891 synchronized (mProcessCpuThread) { 1892 final int N = mProcessCpuTracker.countStats(); 1893 for (int j=0; j<N; j++) { 1894 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1895 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1896 // This is definitely an application process; skip it. 1897 continue; 1898 } 1899 synchronized (mPidsSelfLocked) { 1900 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1901 // This is one of our own processes; skip it. 1902 continue; 1903 } 1904 } 1905 nativeTotalPss += Debug.getPss(st.pid, null); 1906 } 1907 } 1908 memInfo.readMemInfo(); 1909 synchronized (this) { 1910 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1911 + (SystemClock.uptimeMillis()-start) + "ms"); 1912 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1913 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1914 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1915 +memInfo.getSlabSizeKb(), 1916 nativeTotalPss); 1917 } 1918 } 1919 1920 int i=0, num=0; 1921 long[] tmp = new long[1]; 1922 do { 1923 ProcessRecord proc; 1924 int procState; 1925 int pid; 1926 synchronized (ActivityManagerService.this) { 1927 if (i >= mPendingPssProcesses.size()) { 1928 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1929 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1930 mPendingPssProcesses.clear(); 1931 return; 1932 } 1933 proc = mPendingPssProcesses.get(i); 1934 procState = proc.pssProcState; 1935 if (proc.thread != null && procState == proc.setProcState) { 1936 pid = proc.pid; 1937 } else { 1938 proc = null; 1939 pid = 0; 1940 } 1941 i++; 1942 } 1943 if (proc != null) { 1944 long pss = Debug.getPss(pid, tmp); 1945 synchronized (ActivityManagerService.this) { 1946 if (proc.thread != null && proc.setProcState == procState 1947 && proc.pid == pid) { 1948 num++; 1949 proc.lastPssTime = SystemClock.uptimeMillis(); 1950 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1951 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1952 + ": " + pss + " lastPss=" + proc.lastPss 1953 + " state=" + ProcessList.makeProcStateString(procState)); 1954 if (proc.initialIdlePss == 0) { 1955 proc.initialIdlePss = pss; 1956 } 1957 proc.lastPss = pss; 1958 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1959 proc.lastCachedPss = pss; 1960 } 1961 } 1962 } 1963 } 1964 } while (true); 1965 } 1966 } 1967 } 1968 }; 1969 1970 /** 1971 * Monitor for package changes and update our internal state. 1972 */ 1973 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1974 @Override 1975 public void onPackageRemoved(String packageName, int uid) { 1976 // Remove all tasks with activities in the specified package from the list of recent tasks 1977 synchronized (ActivityManagerService.this) { 1978 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1979 TaskRecord tr = mRecentTasks.get(i); 1980 ComponentName cn = tr.intent.getComponent(); 1981 if (cn != null && cn.getPackageName().equals(packageName)) { 1982 // If the package name matches, remove the task and kill the process 1983 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1984 } 1985 } 1986 } 1987 } 1988 1989 @Override 1990 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1991 onPackageModified(packageName); 1992 return true; 1993 } 1994 1995 @Override 1996 public void onPackageModified(String packageName) { 1997 final PackageManager pm = mContext.getPackageManager(); 1998 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1999 new ArrayList<Pair<Intent, Integer>>(); 2000 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2001 // Copy the list of recent tasks so that we don't hold onto the lock on 2002 // ActivityManagerService for long periods while checking if components exist. 2003 synchronized (ActivityManagerService.this) { 2004 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2005 TaskRecord tr = mRecentTasks.get(i); 2006 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2007 } 2008 } 2009 // Check the recent tasks and filter out all tasks with components that no longer exist. 2010 Intent tmpI = new Intent(); 2011 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2012 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2013 ComponentName cn = p.first.getComponent(); 2014 if (cn != null && cn.getPackageName().equals(packageName)) { 2015 try { 2016 // Add the task to the list to remove if the component no longer exists 2017 tmpI.setComponent(cn); 2018 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2019 tasksToRemove.add(p.second); 2020 } 2021 } catch (Exception e) {} 2022 } 2023 } 2024 // Prune all the tasks with removed components from the list of recent tasks 2025 synchronized (ActivityManagerService.this) { 2026 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2027 // Remove the task but don't kill the process (since other components in that 2028 // package may still be running and in the background) 2029 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2030 } 2031 } 2032 } 2033 2034 @Override 2035 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2036 // Force stop the specified packages 2037 if (packages != null) { 2038 for (String pkg : packages) { 2039 synchronized (ActivityManagerService.this) { 2040 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2041 "finished booting")) { 2042 return true; 2043 } 2044 } 2045 } 2046 } 2047 return false; 2048 } 2049 }; 2050 2051 public void setSystemProcess() { 2052 try { 2053 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2054 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2055 ServiceManager.addService("meminfo", new MemBinder(this)); 2056 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2057 ServiceManager.addService("dbinfo", new DbBinder(this)); 2058 if (MONITOR_CPU_USAGE) { 2059 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2060 } 2061 ServiceManager.addService("permission", new PermissionController(this)); 2062 2063 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2064 "android", STOCK_PM_FLAGS); 2065 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2066 2067 synchronized (this) { 2068 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2069 app.persistent = true; 2070 app.pid = MY_PID; 2071 app.maxAdj = ProcessList.SYSTEM_ADJ; 2072 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2073 mProcessNames.put(app.processName, app.uid, app); 2074 synchronized (mPidsSelfLocked) { 2075 mPidsSelfLocked.put(app.pid, app); 2076 } 2077 updateLruProcessLocked(app, false, null); 2078 updateOomAdjLocked(); 2079 } 2080 } catch (PackageManager.NameNotFoundException e) { 2081 throw new RuntimeException( 2082 "Unable to find android system package", e); 2083 } 2084 } 2085 2086 public void setWindowManager(WindowManagerService wm) { 2087 mWindowManager = wm; 2088 mStackSupervisor.setWindowManager(wm); 2089 } 2090 2091 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2092 mUsageStatsService = usageStatsManager; 2093 } 2094 2095 public void startObservingNativeCrashes() { 2096 final NativeCrashListener ncl = new NativeCrashListener(this); 2097 ncl.start(); 2098 } 2099 2100 public IAppOpsService getAppOpsService() { 2101 return mAppOpsService; 2102 } 2103 2104 static class MemBinder extends Binder { 2105 ActivityManagerService mActivityManagerService; 2106 MemBinder(ActivityManagerService activityManagerService) { 2107 mActivityManagerService = activityManagerService; 2108 } 2109 2110 @Override 2111 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2112 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2113 != PackageManager.PERMISSION_GRANTED) { 2114 pw.println("Permission Denial: can't dump meminfo from from pid=" 2115 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2116 + " without permission " + android.Manifest.permission.DUMP); 2117 return; 2118 } 2119 2120 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2121 } 2122 } 2123 2124 static class GraphicsBinder extends Binder { 2125 ActivityManagerService mActivityManagerService; 2126 GraphicsBinder(ActivityManagerService activityManagerService) { 2127 mActivityManagerService = activityManagerService; 2128 } 2129 2130 @Override 2131 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2132 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2133 != PackageManager.PERMISSION_GRANTED) { 2134 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2135 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2136 + " without permission " + android.Manifest.permission.DUMP); 2137 return; 2138 } 2139 2140 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2141 } 2142 } 2143 2144 static class DbBinder extends Binder { 2145 ActivityManagerService mActivityManagerService; 2146 DbBinder(ActivityManagerService activityManagerService) { 2147 mActivityManagerService = activityManagerService; 2148 } 2149 2150 @Override 2151 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2152 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2153 != PackageManager.PERMISSION_GRANTED) { 2154 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2155 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2156 + " without permission " + android.Manifest.permission.DUMP); 2157 return; 2158 } 2159 2160 mActivityManagerService.dumpDbInfo(fd, pw, args); 2161 } 2162 } 2163 2164 static class CpuBinder extends Binder { 2165 ActivityManagerService mActivityManagerService; 2166 CpuBinder(ActivityManagerService activityManagerService) { 2167 mActivityManagerService = activityManagerService; 2168 } 2169 2170 @Override 2171 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2172 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2173 != PackageManager.PERMISSION_GRANTED) { 2174 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2175 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2176 + " without permission " + android.Manifest.permission.DUMP); 2177 return; 2178 } 2179 2180 synchronized (mActivityManagerService.mProcessCpuThread) { 2181 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2182 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2183 SystemClock.uptimeMillis())); 2184 } 2185 } 2186 } 2187 2188 public static final class Lifecycle extends SystemService { 2189 private final ActivityManagerService mService; 2190 2191 public Lifecycle(Context context) { 2192 super(context); 2193 mService = new ActivityManagerService(context); 2194 } 2195 2196 @Override 2197 public void onStart() { 2198 mService.start(); 2199 } 2200 2201 public ActivityManagerService getService() { 2202 return mService; 2203 } 2204 } 2205 2206 // Note: This method is invoked on the main thread but may need to attach various 2207 // handlers to other threads. So take care to be explicit about the looper. 2208 public ActivityManagerService(Context systemContext) { 2209 mContext = systemContext; 2210 mFactoryTest = FactoryTest.getMode(); 2211 mSystemThread = ActivityThread.currentActivityThread(); 2212 2213 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2214 2215 mHandlerThread = new ServiceThread(TAG, 2216 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2217 mHandlerThread.start(); 2218 mHandler = new MainHandler(mHandlerThread.getLooper()); 2219 2220 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2221 "foreground", BROADCAST_FG_TIMEOUT, false); 2222 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2223 "background", BROADCAST_BG_TIMEOUT, true); 2224 mBroadcastQueues[0] = mFgBroadcastQueue; 2225 mBroadcastQueues[1] = mBgBroadcastQueue; 2226 2227 mServices = new ActiveServices(this); 2228 mProviderMap = new ProviderMap(this); 2229 2230 // TODO: Move creation of battery stats service outside of activity manager service. 2231 File dataDir = Environment.getDataDirectory(); 2232 File systemDir = new File(dataDir, "system"); 2233 systemDir.mkdirs(); 2234 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2235 mBatteryStatsService.getActiveStatistics().readLocked(); 2236 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2237 mOnBattery = DEBUG_POWER ? true 2238 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2239 mBatteryStatsService.getActiveStatistics().setCallback(this); 2240 2241 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2242 2243 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2244 2245 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2246 2247 // User 0 is the first and only user that runs at boot. 2248 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2249 mUserLru.add(Integer.valueOf(0)); 2250 updateStartedUserArrayLocked(); 2251 2252 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2253 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2254 2255 mConfiguration.setToDefaults(); 2256 mConfiguration.setLocale(Locale.getDefault()); 2257 2258 mConfigurationSeq = mConfiguration.seq = 1; 2259 mProcessCpuTracker.init(); 2260 2261 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2262 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2263 mStackSupervisor = new ActivityStackSupervisor(this); 2264 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2265 2266 mProcessCpuThread = new Thread("CpuTracker") { 2267 @Override 2268 public void run() { 2269 while (true) { 2270 try { 2271 try { 2272 synchronized(this) { 2273 final long now = SystemClock.uptimeMillis(); 2274 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2275 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2276 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2277 // + ", write delay=" + nextWriteDelay); 2278 if (nextWriteDelay < nextCpuDelay) { 2279 nextCpuDelay = nextWriteDelay; 2280 } 2281 if (nextCpuDelay > 0) { 2282 mProcessCpuMutexFree.set(true); 2283 this.wait(nextCpuDelay); 2284 } 2285 } 2286 } catch (InterruptedException e) { 2287 } 2288 updateCpuStatsNow(); 2289 } catch (Exception e) { 2290 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2291 } 2292 } 2293 } 2294 }; 2295 2296 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2297 2298 Watchdog.getInstance().addMonitor(this); 2299 Watchdog.getInstance().addThread(mHandler); 2300 } 2301 2302 public void setSystemServiceManager(SystemServiceManager mgr) { 2303 mSystemServiceManager = mgr; 2304 } 2305 2306 private void start() { 2307 Process.removeAllProcessGroups(); 2308 mProcessCpuThread.start(); 2309 2310 mBatteryStatsService.publish(mContext); 2311 mAppOpsService.publish(mContext); 2312 Slog.d("AppOps", "AppOpsService published"); 2313 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2314 } 2315 2316 public void initPowerManagement() { 2317 mStackSupervisor.initPowerManagement(); 2318 mBatteryStatsService.initPowerManagement(); 2319 } 2320 2321 @Override 2322 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2323 throws RemoteException { 2324 if (code == SYSPROPS_TRANSACTION) { 2325 // We need to tell all apps about the system property change. 2326 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2327 synchronized(this) { 2328 final int NP = mProcessNames.getMap().size(); 2329 for (int ip=0; ip<NP; ip++) { 2330 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2331 final int NA = apps.size(); 2332 for (int ia=0; ia<NA; ia++) { 2333 ProcessRecord app = apps.valueAt(ia); 2334 if (app.thread != null) { 2335 procs.add(app.thread.asBinder()); 2336 } 2337 } 2338 } 2339 } 2340 2341 int N = procs.size(); 2342 for (int i=0; i<N; i++) { 2343 Parcel data2 = Parcel.obtain(); 2344 try { 2345 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2346 } catch (RemoteException e) { 2347 } 2348 data2.recycle(); 2349 } 2350 } 2351 try { 2352 return super.onTransact(code, data, reply, flags); 2353 } catch (RuntimeException e) { 2354 // The activity manager only throws security exceptions, so let's 2355 // log all others. 2356 if (!(e instanceof SecurityException)) { 2357 Slog.wtf(TAG, "Activity Manager Crash", e); 2358 } 2359 throw e; 2360 } 2361 } 2362 2363 void updateCpuStats() { 2364 final long now = SystemClock.uptimeMillis(); 2365 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2366 return; 2367 } 2368 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2369 synchronized (mProcessCpuThread) { 2370 mProcessCpuThread.notify(); 2371 } 2372 } 2373 } 2374 2375 void updateCpuStatsNow() { 2376 synchronized (mProcessCpuThread) { 2377 mProcessCpuMutexFree.set(false); 2378 final long now = SystemClock.uptimeMillis(); 2379 boolean haveNewCpuStats = false; 2380 2381 if (MONITOR_CPU_USAGE && 2382 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2383 mLastCpuTime.set(now); 2384 haveNewCpuStats = true; 2385 mProcessCpuTracker.update(); 2386 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2387 //Slog.i(TAG, "Total CPU usage: " 2388 // + mProcessCpu.getTotalCpuPercent() + "%"); 2389 2390 // Slog the cpu usage if the property is set. 2391 if ("true".equals(SystemProperties.get("events.cpu"))) { 2392 int user = mProcessCpuTracker.getLastUserTime(); 2393 int system = mProcessCpuTracker.getLastSystemTime(); 2394 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2395 int irq = mProcessCpuTracker.getLastIrqTime(); 2396 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2397 int idle = mProcessCpuTracker.getLastIdleTime(); 2398 2399 int total = user + system + iowait + irq + softIrq + idle; 2400 if (total == 0) total = 1; 2401 2402 EventLog.writeEvent(EventLogTags.CPU, 2403 ((user+system+iowait+irq+softIrq) * 100) / total, 2404 (user * 100) / total, 2405 (system * 100) / total, 2406 (iowait * 100) / total, 2407 (irq * 100) / total, 2408 (softIrq * 100) / total); 2409 } 2410 } 2411 2412 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2413 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2414 synchronized(bstats) { 2415 synchronized(mPidsSelfLocked) { 2416 if (haveNewCpuStats) { 2417 if (mOnBattery) { 2418 int perc = bstats.startAddingCpuLocked(); 2419 int totalUTime = 0; 2420 int totalSTime = 0; 2421 final int N = mProcessCpuTracker.countStats(); 2422 for (int i=0; i<N; i++) { 2423 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2424 if (!st.working) { 2425 continue; 2426 } 2427 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2428 int otherUTime = (st.rel_utime*perc)/100; 2429 int otherSTime = (st.rel_stime*perc)/100; 2430 totalUTime += otherUTime; 2431 totalSTime += otherSTime; 2432 if (pr != null) { 2433 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2434 if (ps == null || !ps.isActive()) { 2435 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2436 pr.info.uid, pr.processName); 2437 } 2438 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2439 st.rel_stime-otherSTime); 2440 ps.addSpeedStepTimes(cpuSpeedTimes); 2441 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2442 } else { 2443 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2444 if (ps == null || !ps.isActive()) { 2445 st.batteryStats = ps = bstats.getProcessStatsLocked( 2446 bstats.mapUid(st.uid), st.name); 2447 } 2448 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2449 st.rel_stime-otherSTime); 2450 ps.addSpeedStepTimes(cpuSpeedTimes); 2451 } 2452 } 2453 bstats.finishAddingCpuLocked(perc, totalUTime, 2454 totalSTime, cpuSpeedTimes); 2455 } 2456 } 2457 } 2458 2459 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2460 mLastWriteTime = now; 2461 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2462 } 2463 } 2464 } 2465 } 2466 2467 @Override 2468 public void batteryNeedsCpuUpdate() { 2469 updateCpuStatsNow(); 2470 } 2471 2472 @Override 2473 public void batteryPowerChanged(boolean onBattery) { 2474 // When plugging in, update the CPU stats first before changing 2475 // the plug state. 2476 updateCpuStatsNow(); 2477 synchronized (this) { 2478 synchronized(mPidsSelfLocked) { 2479 mOnBattery = DEBUG_POWER ? true : onBattery; 2480 } 2481 } 2482 } 2483 2484 /** 2485 * Initialize the application bind args. These are passed to each 2486 * process when the bindApplication() IPC is sent to the process. They're 2487 * lazily setup to make sure the services are running when they're asked for. 2488 */ 2489 private HashMap<String, IBinder> getCommonServicesLocked() { 2490 if (mAppBindArgs == null) { 2491 mAppBindArgs = new HashMap<String, IBinder>(); 2492 2493 // Setup the application init args 2494 mAppBindArgs.put("package", ServiceManager.getService("package")); 2495 mAppBindArgs.put("window", ServiceManager.getService("window")); 2496 mAppBindArgs.put(Context.ALARM_SERVICE, 2497 ServiceManager.getService(Context.ALARM_SERVICE)); 2498 } 2499 return mAppBindArgs; 2500 } 2501 2502 final void setFocusedActivityLocked(ActivityRecord r) { 2503 if (mFocusedActivity != r) { 2504 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2505 mFocusedActivity = r; 2506 if (r.task != null && r.task.voiceInteractor != null) { 2507 startRunningVoiceLocked(); 2508 } else { 2509 finishRunningVoiceLocked(); 2510 } 2511 mStackSupervisor.setFocusedStack(r); 2512 if (r != null) { 2513 mWindowManager.setFocusedApp(r.appToken, true); 2514 } 2515 applyUpdateLockStateLocked(r); 2516 } 2517 } 2518 2519 final void clearFocusedActivity(ActivityRecord r) { 2520 if (mFocusedActivity == r) { 2521 mFocusedActivity = null; 2522 } 2523 } 2524 2525 @Override 2526 public void setFocusedStack(int stackId) { 2527 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2528 synchronized (ActivityManagerService.this) { 2529 ActivityStack stack = mStackSupervisor.getStack(stackId); 2530 if (stack != null) { 2531 ActivityRecord r = stack.topRunningActivityLocked(null); 2532 if (r != null) { 2533 setFocusedActivityLocked(r); 2534 } 2535 } 2536 } 2537 } 2538 2539 @Override 2540 public void notifyActivityDrawn(IBinder token) { 2541 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2542 synchronized (this) { 2543 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2544 if (r != null) { 2545 r.task.stack.notifyActivityDrawnLocked(r); 2546 } 2547 } 2548 } 2549 2550 final void applyUpdateLockStateLocked(ActivityRecord r) { 2551 // Modifications to the UpdateLock state are done on our handler, outside 2552 // the activity manager's locks. The new state is determined based on the 2553 // state *now* of the relevant activity record. The object is passed to 2554 // the handler solely for logging detail, not to be consulted/modified. 2555 final boolean nextState = r != null && r.immersive; 2556 mHandler.sendMessage( 2557 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2558 } 2559 2560 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2561 Message msg = Message.obtain(); 2562 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2563 msg.obj = r.task.askedCompatMode ? null : r; 2564 mHandler.sendMessage(msg); 2565 } 2566 2567 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2568 String what, Object obj, ProcessRecord srcApp) { 2569 app.lastActivityTime = now; 2570 2571 if (app.activities.size() > 0) { 2572 // Don't want to touch dependent processes that are hosting activities. 2573 return index; 2574 } 2575 2576 int lrui = mLruProcesses.lastIndexOf(app); 2577 if (lrui < 0) { 2578 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2579 + what + " " + obj + " from " + srcApp); 2580 return index; 2581 } 2582 2583 if (lrui >= index) { 2584 // Don't want to cause this to move dependent processes *back* in the 2585 // list as if they were less frequently used. 2586 return index; 2587 } 2588 2589 if (lrui >= mLruProcessActivityStart) { 2590 // Don't want to touch dependent processes that are hosting activities. 2591 return index; 2592 } 2593 2594 mLruProcesses.remove(lrui); 2595 if (index > 0) { 2596 index--; 2597 } 2598 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2599 + " in LRU list: " + app); 2600 mLruProcesses.add(index, app); 2601 return index; 2602 } 2603 2604 final void removeLruProcessLocked(ProcessRecord app) { 2605 int lrui = mLruProcesses.lastIndexOf(app); 2606 if (lrui >= 0) { 2607 if (lrui <= mLruProcessActivityStart) { 2608 mLruProcessActivityStart--; 2609 } 2610 if (lrui <= mLruProcessServiceStart) { 2611 mLruProcessServiceStart--; 2612 } 2613 mLruProcesses.remove(lrui); 2614 } 2615 } 2616 2617 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2618 ProcessRecord client) { 2619 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2620 || app.treatLikeActivity; 2621 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2622 if (!activityChange && hasActivity) { 2623 // The process has activities, so we are only allowing activity-based adjustments 2624 // to move it. It should be kept in the front of the list with other 2625 // processes that have activities, and we don't want those to change their 2626 // order except due to activity operations. 2627 return; 2628 } 2629 2630 mLruSeq++; 2631 final long now = SystemClock.uptimeMillis(); 2632 app.lastActivityTime = now; 2633 2634 // First a quick reject: if the app is already at the position we will 2635 // put it, then there is nothing to do. 2636 if (hasActivity) { 2637 final int N = mLruProcesses.size(); 2638 if (N > 0 && mLruProcesses.get(N-1) == app) { 2639 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2640 return; 2641 } 2642 } else { 2643 if (mLruProcessServiceStart > 0 2644 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2645 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2646 return; 2647 } 2648 } 2649 2650 int lrui = mLruProcesses.lastIndexOf(app); 2651 2652 if (app.persistent && lrui >= 0) { 2653 // We don't care about the position of persistent processes, as long as 2654 // they are in the list. 2655 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2656 return; 2657 } 2658 2659 /* In progress: compute new position first, so we can avoid doing work 2660 if the process is not actually going to move. Not yet working. 2661 int addIndex; 2662 int nextIndex; 2663 boolean inActivity = false, inService = false; 2664 if (hasActivity) { 2665 // Process has activities, put it at the very tipsy-top. 2666 addIndex = mLruProcesses.size(); 2667 nextIndex = mLruProcessServiceStart; 2668 inActivity = true; 2669 } else if (hasService) { 2670 // Process has services, put it at the top of the service list. 2671 addIndex = mLruProcessActivityStart; 2672 nextIndex = mLruProcessServiceStart; 2673 inActivity = true; 2674 inService = true; 2675 } else { 2676 // Process not otherwise of interest, it goes to the top of the non-service area. 2677 addIndex = mLruProcessServiceStart; 2678 if (client != null) { 2679 int clientIndex = mLruProcesses.lastIndexOf(client); 2680 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2681 + app); 2682 if (clientIndex >= 0 && addIndex > clientIndex) { 2683 addIndex = clientIndex; 2684 } 2685 } 2686 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2687 } 2688 2689 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2690 + mLruProcessActivityStart + "): " + app); 2691 */ 2692 2693 if (lrui >= 0) { 2694 if (lrui < mLruProcessActivityStart) { 2695 mLruProcessActivityStart--; 2696 } 2697 if (lrui < mLruProcessServiceStart) { 2698 mLruProcessServiceStart--; 2699 } 2700 /* 2701 if (addIndex > lrui) { 2702 addIndex--; 2703 } 2704 if (nextIndex > lrui) { 2705 nextIndex--; 2706 } 2707 */ 2708 mLruProcesses.remove(lrui); 2709 } 2710 2711 /* 2712 mLruProcesses.add(addIndex, app); 2713 if (inActivity) { 2714 mLruProcessActivityStart++; 2715 } 2716 if (inService) { 2717 mLruProcessActivityStart++; 2718 } 2719 */ 2720 2721 int nextIndex; 2722 if (hasActivity) { 2723 final int N = mLruProcesses.size(); 2724 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2725 // Process doesn't have activities, but has clients with 2726 // activities... move it up, but one below the top (the top 2727 // should always have a real activity). 2728 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2729 mLruProcesses.add(N-1, app); 2730 // To keep it from spamming the LRU list (by making a bunch of clients), 2731 // we will push down any other entries owned by the app. 2732 final int uid = app.info.uid; 2733 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2734 ProcessRecord subProc = mLruProcesses.get(i); 2735 if (subProc.info.uid == uid) { 2736 // We want to push this one down the list. If the process after 2737 // it is for the same uid, however, don't do so, because we don't 2738 // want them internally to be re-ordered. 2739 if (mLruProcesses.get(i-1).info.uid != uid) { 2740 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2741 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2742 ProcessRecord tmp = mLruProcesses.get(i); 2743 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2744 mLruProcesses.set(i-1, tmp); 2745 i--; 2746 } 2747 } else { 2748 // A gap, we can stop here. 2749 break; 2750 } 2751 } 2752 } else { 2753 // Process has activities, put it at the very tipsy-top. 2754 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2755 mLruProcesses.add(app); 2756 } 2757 nextIndex = mLruProcessServiceStart; 2758 } else if (hasService) { 2759 // Process has services, put it at the top of the service list. 2760 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2761 mLruProcesses.add(mLruProcessActivityStart, app); 2762 nextIndex = mLruProcessServiceStart; 2763 mLruProcessActivityStart++; 2764 } else { 2765 // Process not otherwise of interest, it goes to the top of the non-service area. 2766 int index = mLruProcessServiceStart; 2767 if (client != null) { 2768 // If there is a client, don't allow the process to be moved up higher 2769 // in the list than that client. 2770 int clientIndex = mLruProcesses.lastIndexOf(client); 2771 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2772 + " when updating " + app); 2773 if (clientIndex <= lrui) { 2774 // Don't allow the client index restriction to push it down farther in the 2775 // list than it already is. 2776 clientIndex = lrui; 2777 } 2778 if (clientIndex >= 0 && index > clientIndex) { 2779 index = clientIndex; 2780 } 2781 } 2782 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2783 mLruProcesses.add(index, app); 2784 nextIndex = index-1; 2785 mLruProcessActivityStart++; 2786 mLruProcessServiceStart++; 2787 } 2788 2789 // If the app is currently using a content provider or service, 2790 // bump those processes as well. 2791 for (int j=app.connections.size()-1; j>=0; j--) { 2792 ConnectionRecord cr = app.connections.valueAt(j); 2793 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2794 && cr.binding.service.app != null 2795 && cr.binding.service.app.lruSeq != mLruSeq 2796 && !cr.binding.service.app.persistent) { 2797 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2798 "service connection", cr, app); 2799 } 2800 } 2801 for (int j=app.conProviders.size()-1; j>=0; j--) { 2802 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2803 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2804 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2805 "provider reference", cpr, app); 2806 } 2807 } 2808 } 2809 2810 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2811 if (uid == Process.SYSTEM_UID) { 2812 // The system gets to run in any process. If there are multiple 2813 // processes with the same uid, just pick the first (this 2814 // should never happen). 2815 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2816 if (procs == null) return null; 2817 final int N = procs.size(); 2818 for (int i = 0; i < N; i++) { 2819 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2820 } 2821 } 2822 ProcessRecord proc = mProcessNames.get(processName, uid); 2823 if (false && proc != null && !keepIfLarge 2824 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2825 && proc.lastCachedPss >= 4000) { 2826 // Turn this condition on to cause killing to happen regularly, for testing. 2827 if (proc.baseProcessTracker != null) { 2828 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2829 } 2830 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2831 } else if (proc != null && !keepIfLarge 2832 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2833 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2834 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2835 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2836 if (proc.baseProcessTracker != null) { 2837 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2838 } 2839 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2840 } 2841 } 2842 return proc; 2843 } 2844 2845 void ensurePackageDexOpt(String packageName) { 2846 IPackageManager pm = AppGlobals.getPackageManager(); 2847 try { 2848 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2849 mDidDexOpt = true; 2850 } 2851 } catch (RemoteException e) { 2852 } 2853 } 2854 2855 boolean isNextTransitionForward() { 2856 int transit = mWindowManager.getPendingAppTransition(); 2857 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2858 || transit == AppTransition.TRANSIT_TASK_OPEN 2859 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2860 } 2861 2862 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2863 String processName, String abiOverride, int uid, Runnable crashHandler) { 2864 synchronized(this) { 2865 ApplicationInfo info = new ApplicationInfo(); 2866 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2867 // For isolated processes, the former contains the parent's uid and the latter the 2868 // actual uid of the isolated process. 2869 // In the special case introduced by this method (which is, starting an isolated 2870 // process directly from the SystemServer without an actual parent app process) the 2871 // closest thing to a parent's uid is SYSTEM_UID. 2872 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2873 // the |isolated| logic in the ProcessRecord constructor. 2874 info.uid = Process.SYSTEM_UID; 2875 info.processName = processName; 2876 info.className = entryPoint; 2877 info.packageName = "android"; 2878 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2879 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2880 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2881 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2882 crashHandler); 2883 return proc != null ? proc.pid : 0; 2884 } 2885 } 2886 2887 final ProcessRecord startProcessLocked(String processName, 2888 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2889 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2890 boolean isolated, boolean keepIfLarge) { 2891 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2892 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2893 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2894 null /* crashHandler */); 2895 } 2896 2897 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2898 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2899 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2900 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2901 long startTime = SystemClock.elapsedRealtime(); 2902 ProcessRecord app; 2903 if (!isolated) { 2904 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2905 checkTime(startTime, "startProcess: after getProcessRecord"); 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 checkTime(startTime, "startProcess: done, added package to proc"); 2928 return app; 2929 } 2930 2931 // An application record is attached to a previous process, 2932 // clean it up now. 2933 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2934 checkTime(startTime, "startProcess: bad proc running, killing"); 2935 Process.killProcessGroup(app.info.uid, app.pid); 2936 handleAppDiedLocked(app, true, true); 2937 checkTime(startTime, "startProcess: done killing old proc"); 2938 } 2939 2940 String hostingNameStr = hostingName != null 2941 ? hostingName.flattenToShortString() : null; 2942 2943 if (!isolated) { 2944 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2945 // If we are in the background, then check to see if this process 2946 // is bad. If so, we will just silently fail. 2947 if (mBadProcesses.get(info.processName, info.uid) != null) { 2948 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2949 + "/" + info.processName); 2950 return null; 2951 } 2952 } else { 2953 // When the user is explicitly starting a process, then clear its 2954 // crash count so that we won't make it bad until they see at 2955 // least one crash dialog again, and make the process good again 2956 // if it had been bad. 2957 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2958 + "/" + info.processName); 2959 mProcessCrashTimes.remove(info.processName, info.uid); 2960 if (mBadProcesses.get(info.processName, info.uid) != null) { 2961 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2962 UserHandle.getUserId(info.uid), info.uid, 2963 info.processName); 2964 mBadProcesses.remove(info.processName, info.uid); 2965 if (app != null) { 2966 app.bad = false; 2967 } 2968 } 2969 } 2970 } 2971 2972 if (app == null) { 2973 checkTime(startTime, "startProcess: creating new process record"); 2974 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2975 app.crashHandler = crashHandler; 2976 if (app == null) { 2977 Slog.w(TAG, "Failed making new process record for " 2978 + processName + "/" + info.uid + " isolated=" + isolated); 2979 return null; 2980 } 2981 mProcessNames.put(processName, app.uid, app); 2982 if (isolated) { 2983 mIsolatedProcesses.put(app.uid, app); 2984 } 2985 checkTime(startTime, "startProcess: done creating new process record"); 2986 } else { 2987 // If this is a new package in the process, add the package to the list 2988 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2989 checkTime(startTime, "startProcess: added package to existing proc"); 2990 } 2991 2992 // If the system is not ready yet, then hold off on starting this 2993 // process until it is. 2994 if (!mProcessesReady 2995 && !isAllowedWhileBooting(info) 2996 && !allowWhileBooting) { 2997 if (!mProcessesOnHold.contains(app)) { 2998 mProcessesOnHold.add(app); 2999 } 3000 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3001 return app; 3002 } 3003 3004 startProcessLocked( 3005 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3006 checkTime(startTime, "startProcess: done starting proc!"); 3007 return (app.pid != 0) ? app : null; 3008 } 3009 3010 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3011 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3012 } 3013 3014 private final void startProcessLocked(ProcessRecord app, 3015 String hostingType, String hostingNameStr) { 3016 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3017 null /* entryPoint */, null /* entryPointArgs */); 3018 } 3019 3020 private final void startProcessLocked(ProcessRecord app, String hostingType, 3021 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3022 long startTime = SystemClock.elapsedRealtime(); 3023 if (app.pid > 0 && app.pid != MY_PID) { 3024 checkTime(startTime, "startProcess: removing from pids map"); 3025 synchronized (mPidsSelfLocked) { 3026 mPidsSelfLocked.remove(app.pid); 3027 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3028 } 3029 checkTime(startTime, "startProcess: done removing from pids map"); 3030 app.setPid(0); 3031 } 3032 3033 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3034 "startProcessLocked removing on hold: " + app); 3035 mProcessesOnHold.remove(app); 3036 3037 checkTime(startTime, "startProcess: starting to update cpu stats"); 3038 updateCpuStats(); 3039 checkTime(startTime, "startProcess: done updating cpu stats"); 3040 3041 try { 3042 int uid = app.uid; 3043 3044 int[] gids = null; 3045 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3046 if (!app.isolated) { 3047 int[] permGids = null; 3048 try { 3049 checkTime(startTime, "startProcess: getting gids from package manager"); 3050 final PackageManager pm = mContext.getPackageManager(); 3051 permGids = pm.getPackageGids(app.info.packageName); 3052 3053 if (Environment.isExternalStorageEmulated()) { 3054 checkTime(startTime, "startProcess: checking external storage perm"); 3055 if (pm.checkPermission( 3056 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3057 app.info.packageName) == PERMISSION_GRANTED) { 3058 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3059 } else { 3060 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3061 } 3062 } 3063 } catch (PackageManager.NameNotFoundException e) { 3064 Slog.w(TAG, "Unable to retrieve gids", e); 3065 } 3066 3067 /* 3068 * Add shared application and profile GIDs so applications can share some 3069 * resources like shared libraries and access user-wide resources 3070 */ 3071 if (permGids == null) { 3072 gids = new int[2]; 3073 } else { 3074 gids = new int[permGids.length + 2]; 3075 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3076 } 3077 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3078 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3079 } 3080 checkTime(startTime, "startProcess: building args"); 3081 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3082 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3083 && mTopComponent != null 3084 && app.processName.equals(mTopComponent.getPackageName())) { 3085 uid = 0; 3086 } 3087 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3088 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3089 uid = 0; 3090 } 3091 } 3092 int debugFlags = 0; 3093 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3094 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3095 // Also turn on CheckJNI for debuggable apps. It's quite 3096 // awkward to turn on otherwise. 3097 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3098 } 3099 // Run the app in safe mode if its manifest requests so or the 3100 // system is booted in safe mode. 3101 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3102 mSafeMode == true) { 3103 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3104 } 3105 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3106 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3107 } 3108 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3109 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3110 } 3111 if ("1".equals(SystemProperties.get("debug.assert"))) { 3112 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3113 } 3114 3115 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3116 if (requiredAbi == null) { 3117 requiredAbi = Build.SUPPORTED_ABIS[0]; 3118 } 3119 3120 // Start the process. It will either succeed and return a result containing 3121 // the PID of the new process, or else throw a RuntimeException. 3122 boolean isActivityProcess = (entryPoint == null); 3123 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3124 checkTime(startTime, "startProcess: asking zygote to start proc"); 3125 Process.ProcessStartResult startResult = Process.start(entryPoint, 3126 app.processName, uid, uid, gids, debugFlags, mountExternal, 3127 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3128 checkTime(startTime, "startProcess: returned from zygote!"); 3129 3130 checkTime(startTime, "startProcess: noting battery stats update"); 3131 if (app.isolated) { 3132 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3133 } 3134 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3135 checkTime(startTime, "startProcess: done updating battery stats"); 3136 3137 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3138 UserHandle.getUserId(uid), startResult.pid, uid, 3139 app.processName, hostingType, 3140 hostingNameStr != null ? hostingNameStr : ""); 3141 3142 if (app.persistent) { 3143 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3144 } 3145 3146 checkTime(startTime, "startProcess: building log message"); 3147 StringBuilder buf = mStringBuilder; 3148 buf.setLength(0); 3149 buf.append("Start proc "); 3150 buf.append(app.processName); 3151 if (!isActivityProcess) { 3152 buf.append(" ["); 3153 buf.append(entryPoint); 3154 buf.append("]"); 3155 } 3156 buf.append(" for "); 3157 buf.append(hostingType); 3158 if (hostingNameStr != null) { 3159 buf.append(" "); 3160 buf.append(hostingNameStr); 3161 } 3162 buf.append(": pid="); 3163 buf.append(startResult.pid); 3164 buf.append(" uid="); 3165 buf.append(uid); 3166 buf.append(" gids={"); 3167 if (gids != null) { 3168 for (int gi=0; gi<gids.length; gi++) { 3169 if (gi != 0) buf.append(", "); 3170 buf.append(gids[gi]); 3171 3172 } 3173 } 3174 buf.append("}"); 3175 if (requiredAbi != null) { 3176 buf.append(" abi="); 3177 buf.append(requiredAbi); 3178 } 3179 Slog.i(TAG, buf.toString()); 3180 app.setPid(startResult.pid); 3181 app.usingWrapper = startResult.usingWrapper; 3182 app.removed = false; 3183 app.killedByAm = false; 3184 checkTime(startTime, "startProcess: starting to update pids map"); 3185 synchronized (mPidsSelfLocked) { 3186 this.mPidsSelfLocked.put(startResult.pid, app); 3187 if (isActivityProcess) { 3188 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3189 msg.obj = app; 3190 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3191 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3192 } 3193 } 3194 checkTime(startTime, "startProcess: done updating pids map"); 3195 } catch (RuntimeException e) { 3196 // XXX do better error recovery. 3197 app.setPid(0); 3198 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3199 if (app.isolated) { 3200 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3201 } 3202 Slog.e(TAG, "Failure starting process " + app.processName, e); 3203 } 3204 } 3205 3206 void updateUsageStats(ActivityRecord component, boolean resumed) { 3207 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3208 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3209 if (resumed) { 3210 if (mUsageStatsService != null) { 3211 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3212 UsageEvents.Event.MOVE_TO_FOREGROUND); 3213 } 3214 synchronized (stats) { 3215 stats.noteActivityResumedLocked(component.app.uid); 3216 } 3217 } else { 3218 if (mUsageStatsService != null) { 3219 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3220 UsageEvents.Event.MOVE_TO_BACKGROUND); 3221 } 3222 synchronized (stats) { 3223 stats.noteActivityPausedLocked(component.app.uid); 3224 } 3225 } 3226 } 3227 3228 Intent getHomeIntent() { 3229 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3230 intent.setComponent(mTopComponent); 3231 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3232 intent.addCategory(Intent.CATEGORY_HOME); 3233 } 3234 return intent; 3235 } 3236 3237 boolean startHomeActivityLocked(int userId) { 3238 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3239 && mTopAction == null) { 3240 // We are running in factory test mode, but unable to find 3241 // the factory test app, so just sit around displaying the 3242 // error message and don't try to start anything. 3243 return false; 3244 } 3245 Intent intent = getHomeIntent(); 3246 ActivityInfo aInfo = 3247 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3248 if (aInfo != null) { 3249 intent.setComponent(new ComponentName( 3250 aInfo.applicationInfo.packageName, aInfo.name)); 3251 // Don't do this if the home app is currently being 3252 // instrumented. 3253 aInfo = new ActivityInfo(aInfo); 3254 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3255 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3256 aInfo.applicationInfo.uid, true); 3257 if (app == null || app.instrumentationClass == null) { 3258 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3259 mStackSupervisor.startHomeActivity(intent, aInfo); 3260 } 3261 } 3262 3263 return true; 3264 } 3265 3266 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3267 ActivityInfo ai = null; 3268 ComponentName comp = intent.getComponent(); 3269 try { 3270 if (comp != null) { 3271 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3272 } else { 3273 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3274 intent, 3275 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3276 flags, userId); 3277 3278 if (info != null) { 3279 ai = info.activityInfo; 3280 } 3281 } 3282 } catch (RemoteException e) { 3283 // ignore 3284 } 3285 3286 return ai; 3287 } 3288 3289 /** 3290 * Starts the "new version setup screen" if appropriate. 3291 */ 3292 void startSetupActivityLocked() { 3293 // Only do this once per boot. 3294 if (mCheckedForSetup) { 3295 return; 3296 } 3297 3298 // We will show this screen if the current one is a different 3299 // version than the last one shown, and we are not running in 3300 // low-level factory test mode. 3301 final ContentResolver resolver = mContext.getContentResolver(); 3302 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3303 Settings.Global.getInt(resolver, 3304 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3305 mCheckedForSetup = true; 3306 3307 // See if we should be showing the platform update setup UI. 3308 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3309 List<ResolveInfo> ris = mContext.getPackageManager() 3310 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3311 3312 // We don't allow third party apps to replace this. 3313 ResolveInfo ri = null; 3314 for (int i=0; ris != null && i<ris.size(); i++) { 3315 if ((ris.get(i).activityInfo.applicationInfo.flags 3316 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3317 ri = ris.get(i); 3318 break; 3319 } 3320 } 3321 3322 if (ri != null) { 3323 String vers = ri.activityInfo.metaData != null 3324 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3325 : null; 3326 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3327 vers = ri.activityInfo.applicationInfo.metaData.getString( 3328 Intent.METADATA_SETUP_VERSION); 3329 } 3330 String lastVers = Settings.Secure.getString( 3331 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3332 if (vers != null && !vers.equals(lastVers)) { 3333 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3334 intent.setComponent(new ComponentName( 3335 ri.activityInfo.packageName, ri.activityInfo.name)); 3336 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3337 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3338 null); 3339 } 3340 } 3341 } 3342 } 3343 3344 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3345 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3346 } 3347 3348 void enforceNotIsolatedCaller(String caller) { 3349 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3350 throw new SecurityException("Isolated process not allowed to call " + caller); 3351 } 3352 } 3353 3354 @Override 3355 public int getFrontActivityScreenCompatMode() { 3356 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3357 synchronized (this) { 3358 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3359 } 3360 } 3361 3362 @Override 3363 public void setFrontActivityScreenCompatMode(int mode) { 3364 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3365 "setFrontActivityScreenCompatMode"); 3366 synchronized (this) { 3367 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3368 } 3369 } 3370 3371 @Override 3372 public int getPackageScreenCompatMode(String packageName) { 3373 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3374 synchronized (this) { 3375 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3376 } 3377 } 3378 3379 @Override 3380 public void setPackageScreenCompatMode(String packageName, int mode) { 3381 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3382 "setPackageScreenCompatMode"); 3383 synchronized (this) { 3384 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3385 } 3386 } 3387 3388 @Override 3389 public boolean getPackageAskScreenCompat(String packageName) { 3390 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3391 synchronized (this) { 3392 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3393 } 3394 } 3395 3396 @Override 3397 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3398 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3399 "setPackageAskScreenCompat"); 3400 synchronized (this) { 3401 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3402 } 3403 } 3404 3405 private void dispatchProcessesChanged() { 3406 int N; 3407 synchronized (this) { 3408 N = mPendingProcessChanges.size(); 3409 if (mActiveProcessChanges.length < N) { 3410 mActiveProcessChanges = new ProcessChangeItem[N]; 3411 } 3412 mPendingProcessChanges.toArray(mActiveProcessChanges); 3413 mAvailProcessChanges.addAll(mPendingProcessChanges); 3414 mPendingProcessChanges.clear(); 3415 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3416 } 3417 3418 int i = mProcessObservers.beginBroadcast(); 3419 while (i > 0) { 3420 i--; 3421 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3422 if (observer != null) { 3423 try { 3424 for (int j=0; j<N; j++) { 3425 ProcessChangeItem item = mActiveProcessChanges[j]; 3426 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3427 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3428 + item.pid + " uid=" + item.uid + ": " 3429 + item.foregroundActivities); 3430 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3431 item.foregroundActivities); 3432 } 3433 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3434 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3435 + item.pid + " uid=" + item.uid + ": " + item.processState); 3436 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3437 } 3438 } 3439 } catch (RemoteException e) { 3440 } 3441 } 3442 } 3443 mProcessObservers.finishBroadcast(); 3444 } 3445 3446 private void dispatchProcessDied(int pid, int uid) { 3447 int i = mProcessObservers.beginBroadcast(); 3448 while (i > 0) { 3449 i--; 3450 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3451 if (observer != null) { 3452 try { 3453 observer.onProcessDied(pid, uid); 3454 } catch (RemoteException e) { 3455 } 3456 } 3457 } 3458 mProcessObservers.finishBroadcast(); 3459 } 3460 3461 @Override 3462 public final int startActivity(IApplicationThread caller, String callingPackage, 3463 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3464 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3465 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3466 resultWho, requestCode, startFlags, profilerInfo, options, 3467 UserHandle.getCallingUserId()); 3468 } 3469 3470 @Override 3471 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3472 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3473 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3474 enforceNotIsolatedCaller("startActivity"); 3475 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3476 false, ALLOW_FULL_ONLY, "startActivity", null); 3477 // TODO: Switch to user app stacks here. 3478 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3479 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3480 profilerInfo, null, null, options, userId, null, null); 3481 } 3482 3483 @Override 3484 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3485 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3486 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3487 3488 // This is very dangerous -- it allows you to perform a start activity (including 3489 // permission grants) as any app that may launch one of your own activities. So 3490 // we will only allow this to be done from activities that are part of the core framework, 3491 // and then only when they are running as the system. 3492 final ActivityRecord sourceRecord; 3493 final int targetUid; 3494 final String targetPackage; 3495 synchronized (this) { 3496 if (resultTo == null) { 3497 throw new SecurityException("Must be called from an activity"); 3498 } 3499 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3500 if (sourceRecord == null) { 3501 throw new SecurityException("Called with bad activity token: " + resultTo); 3502 } 3503 if (!sourceRecord.info.packageName.equals("android")) { 3504 throw new SecurityException( 3505 "Must be called from an activity that is declared in the android package"); 3506 } 3507 if (sourceRecord.app == null) { 3508 throw new SecurityException("Called without a process attached to activity"); 3509 } 3510 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3511 // This is still okay, as long as this activity is running under the 3512 // uid of the original calling activity. 3513 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3514 throw new SecurityException( 3515 "Calling activity in uid " + sourceRecord.app.uid 3516 + " must be system uid or original calling uid " 3517 + sourceRecord.launchedFromUid); 3518 } 3519 } 3520 targetUid = sourceRecord.launchedFromUid; 3521 targetPackage = sourceRecord.launchedFromPackage; 3522 } 3523 3524 // TODO: Switch to user app stacks here. 3525 try { 3526 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3527 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3528 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3529 return ret; 3530 } catch (SecurityException e) { 3531 // XXX need to figure out how to propagate to original app. 3532 // A SecurityException here is generally actually a fault of the original 3533 // calling activity (such as a fairly granting permissions), so propagate it 3534 // back to them. 3535 /* 3536 StringBuilder msg = new StringBuilder(); 3537 msg.append("While launching"); 3538 msg.append(intent.toString()); 3539 msg.append(": "); 3540 msg.append(e.getMessage()); 3541 */ 3542 throw e; 3543 } 3544 } 3545 3546 @Override 3547 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3548 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3549 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3550 enforceNotIsolatedCaller("startActivityAndWait"); 3551 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3552 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3553 WaitResult res = new WaitResult(); 3554 // TODO: Switch to user app stacks here. 3555 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3556 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3557 options, userId, null, null); 3558 return res; 3559 } 3560 3561 @Override 3562 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3563 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3564 int startFlags, Configuration config, Bundle options, int userId) { 3565 enforceNotIsolatedCaller("startActivityWithConfig"); 3566 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3567 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3568 // TODO: Switch to user app stacks here. 3569 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3570 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3571 null, null, config, options, userId, null, null); 3572 return ret; 3573 } 3574 3575 @Override 3576 public int startActivityIntentSender(IApplicationThread caller, 3577 IntentSender intent, Intent fillInIntent, String resolvedType, 3578 IBinder resultTo, String resultWho, int requestCode, 3579 int flagsMask, int flagsValues, Bundle options) { 3580 enforceNotIsolatedCaller("startActivityIntentSender"); 3581 // Refuse possible leaked file descriptors 3582 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3583 throw new IllegalArgumentException("File descriptors passed in Intent"); 3584 } 3585 3586 IIntentSender sender = intent.getTarget(); 3587 if (!(sender instanceof PendingIntentRecord)) { 3588 throw new IllegalArgumentException("Bad PendingIntent object"); 3589 } 3590 3591 PendingIntentRecord pir = (PendingIntentRecord)sender; 3592 3593 synchronized (this) { 3594 // If this is coming from the currently resumed activity, it is 3595 // effectively saying that app switches are allowed at this point. 3596 final ActivityStack stack = getFocusedStack(); 3597 if (stack.mResumedActivity != null && 3598 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3599 mAppSwitchesAllowedTime = 0; 3600 } 3601 } 3602 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3603 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3604 return ret; 3605 } 3606 3607 @Override 3608 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3609 Intent intent, String resolvedType, IVoiceInteractionSession session, 3610 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3611 Bundle options, int userId) { 3612 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3613 != PackageManager.PERMISSION_GRANTED) { 3614 String msg = "Permission Denial: startVoiceActivity() from pid=" 3615 + Binder.getCallingPid() 3616 + ", uid=" + Binder.getCallingUid() 3617 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3618 Slog.w(TAG, msg); 3619 throw new SecurityException(msg); 3620 } 3621 if (session == null || interactor == null) { 3622 throw new NullPointerException("null session or interactor"); 3623 } 3624 userId = handleIncomingUser(callingPid, callingUid, userId, 3625 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3626 // TODO: Switch to user app stacks here. 3627 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3628 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3629 null, options, userId, null, null); 3630 } 3631 3632 @Override 3633 public boolean startNextMatchingActivity(IBinder callingActivity, 3634 Intent intent, Bundle options) { 3635 // Refuse possible leaked file descriptors 3636 if (intent != null && intent.hasFileDescriptors() == true) { 3637 throw new IllegalArgumentException("File descriptors passed in Intent"); 3638 } 3639 3640 synchronized (this) { 3641 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3642 if (r == null) { 3643 ActivityOptions.abort(options); 3644 return false; 3645 } 3646 if (r.app == null || r.app.thread == null) { 3647 // The caller is not running... d'oh! 3648 ActivityOptions.abort(options); 3649 return false; 3650 } 3651 intent = new Intent(intent); 3652 // The caller is not allowed to change the data. 3653 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3654 // And we are resetting to find the next component... 3655 intent.setComponent(null); 3656 3657 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3658 3659 ActivityInfo aInfo = null; 3660 try { 3661 List<ResolveInfo> resolves = 3662 AppGlobals.getPackageManager().queryIntentActivities( 3663 intent, r.resolvedType, 3664 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3665 UserHandle.getCallingUserId()); 3666 3667 // Look for the original activity in the list... 3668 final int N = resolves != null ? resolves.size() : 0; 3669 for (int i=0; i<N; i++) { 3670 ResolveInfo rInfo = resolves.get(i); 3671 if (rInfo.activityInfo.packageName.equals(r.packageName) 3672 && rInfo.activityInfo.name.equals(r.info.name)) { 3673 // We found the current one... the next matching is 3674 // after it. 3675 i++; 3676 if (i<N) { 3677 aInfo = resolves.get(i).activityInfo; 3678 } 3679 if (debug) { 3680 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3681 + "/" + r.info.name); 3682 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3683 + "/" + aInfo.name); 3684 } 3685 break; 3686 } 3687 } 3688 } catch (RemoteException e) { 3689 } 3690 3691 if (aInfo == null) { 3692 // Nobody who is next! 3693 ActivityOptions.abort(options); 3694 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3695 return false; 3696 } 3697 3698 intent.setComponent(new ComponentName( 3699 aInfo.applicationInfo.packageName, aInfo.name)); 3700 intent.setFlags(intent.getFlags()&~( 3701 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3702 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3703 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3704 Intent.FLAG_ACTIVITY_NEW_TASK)); 3705 3706 // Okay now we need to start the new activity, replacing the 3707 // currently running activity. This is a little tricky because 3708 // we want to start the new one as if the current one is finished, 3709 // but not finish the current one first so that there is no flicker. 3710 // And thus... 3711 final boolean wasFinishing = r.finishing; 3712 r.finishing = true; 3713 3714 // Propagate reply information over to the new activity. 3715 final ActivityRecord resultTo = r.resultTo; 3716 final String resultWho = r.resultWho; 3717 final int requestCode = r.requestCode; 3718 r.resultTo = null; 3719 if (resultTo != null) { 3720 resultTo.removeResultsLocked(r, resultWho, requestCode); 3721 } 3722 3723 final long origId = Binder.clearCallingIdentity(); 3724 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3725 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3726 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3727 options, false, null, null, null); 3728 Binder.restoreCallingIdentity(origId); 3729 3730 r.finishing = wasFinishing; 3731 if (res != ActivityManager.START_SUCCESS) { 3732 return false; 3733 } 3734 return true; 3735 } 3736 } 3737 3738 @Override 3739 public final int startActivityFromRecents(int taskId, Bundle options) { 3740 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3741 String msg = "Permission Denial: startActivityFromRecents called without " + 3742 START_TASKS_FROM_RECENTS; 3743 Slog.w(TAG, msg); 3744 throw new SecurityException(msg); 3745 } 3746 return startActivityFromRecentsInner(taskId, options); 3747 } 3748 3749 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3750 final TaskRecord task; 3751 final int callingUid; 3752 final String callingPackage; 3753 final Intent intent; 3754 final int userId; 3755 synchronized (this) { 3756 task = recentTaskForIdLocked(taskId); 3757 if (task == null) { 3758 throw new IllegalArgumentException("Task " + taskId + " not found."); 3759 } 3760 callingUid = task.mCallingUid; 3761 callingPackage = task.mCallingPackage; 3762 intent = task.intent; 3763 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3764 userId = task.userId; 3765 } 3766 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3767 options, userId, null, task); 3768 } 3769 3770 final int startActivityInPackage(int uid, String callingPackage, 3771 Intent intent, String resolvedType, IBinder resultTo, 3772 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3773 IActivityContainer container, TaskRecord inTask) { 3774 3775 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3776 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3777 3778 // TODO: Switch to user app stacks here. 3779 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3780 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3781 null, null, null, options, userId, container, inTask); 3782 return ret; 3783 } 3784 3785 @Override 3786 public final int startActivities(IApplicationThread caller, String callingPackage, 3787 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3788 int userId) { 3789 enforceNotIsolatedCaller("startActivities"); 3790 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3791 false, ALLOW_FULL_ONLY, "startActivity", null); 3792 // TODO: Switch to user app stacks here. 3793 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3794 resolvedTypes, resultTo, options, userId); 3795 return ret; 3796 } 3797 3798 final int startActivitiesInPackage(int uid, String callingPackage, 3799 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3800 Bundle options, int userId) { 3801 3802 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3803 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3804 // TODO: Switch to user app stacks here. 3805 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3806 resultTo, options, userId); 3807 return ret; 3808 } 3809 3810 //explicitly remove thd old information in mRecentTasks when removing existing user. 3811 private void removeRecentTasksForUserLocked(int userId) { 3812 if(userId <= 0) { 3813 Slog.i(TAG, "Can't remove recent task on user " + userId); 3814 return; 3815 } 3816 3817 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3818 TaskRecord tr = mRecentTasks.get(i); 3819 if (tr.userId == userId) { 3820 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3821 + " when finishing user" + userId); 3822 mRecentTasks.remove(i); 3823 tr.removedFromRecents(mTaskPersister); 3824 } 3825 } 3826 3827 // Remove tasks from persistent storage. 3828 mTaskPersister.wakeup(null, true); 3829 } 3830 3831 /** 3832 * Update the recent tasks lists: make sure tasks should still be here (their 3833 * applications / activities still exist), update their availability, fixup ordering 3834 * of affiliations. 3835 */ 3836 void cleanupRecentTasksLocked(int userId) { 3837 if (mRecentTasks == null) { 3838 // Happens when called from the packagemanager broadcast before boot. 3839 return; 3840 } 3841 3842 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3843 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3844 final IPackageManager pm = AppGlobals.getPackageManager(); 3845 final ActivityInfo dummyAct = new ActivityInfo(); 3846 final ApplicationInfo dummyApp = new ApplicationInfo(); 3847 3848 int N = mRecentTasks.size(); 3849 3850 int[] users = userId == UserHandle.USER_ALL 3851 ? getUsersLocked() : new int[] { userId }; 3852 for (int user : users) { 3853 for (int i = 0; i < N; i++) { 3854 TaskRecord task = mRecentTasks.get(i); 3855 if (task.userId != user) { 3856 // Only look at tasks for the user ID of interest. 3857 continue; 3858 } 3859 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3860 // This situation is broken, and we should just get rid of it now. 3861 mRecentTasks.remove(i); 3862 task.removedFromRecents(mTaskPersister); 3863 i--; 3864 N--; 3865 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3866 continue; 3867 } 3868 // Check whether this activity is currently available. 3869 if (task.realActivity != null) { 3870 ActivityInfo ai = availActCache.get(task.realActivity); 3871 if (ai == null) { 3872 try { 3873 ai = pm.getActivityInfo(task.realActivity, 3874 PackageManager.GET_UNINSTALLED_PACKAGES 3875 | PackageManager.GET_DISABLED_COMPONENTS, user); 3876 } catch (RemoteException e) { 3877 // Will never happen. 3878 continue; 3879 } 3880 if (ai == null) { 3881 ai = dummyAct; 3882 } 3883 availActCache.put(task.realActivity, ai); 3884 } 3885 if (ai == dummyAct) { 3886 // This could be either because the activity no longer exists, or the 3887 // app is temporarily gone. For the former we want to remove the recents 3888 // entry; for the latter we want to mark it as unavailable. 3889 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3890 if (app == null) { 3891 try { 3892 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3893 PackageManager.GET_UNINSTALLED_PACKAGES 3894 | PackageManager.GET_DISABLED_COMPONENTS, user); 3895 } catch (RemoteException e) { 3896 // Will never happen. 3897 continue; 3898 } 3899 if (app == null) { 3900 app = dummyApp; 3901 } 3902 availAppCache.put(task.realActivity.getPackageName(), app); 3903 } 3904 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3905 // Doesn't exist any more! Good-bye. 3906 mRecentTasks.remove(i); 3907 task.removedFromRecents(mTaskPersister); 3908 i--; 3909 N--; 3910 Slog.w(TAG, "Removing no longer valid recent: " + task); 3911 continue; 3912 } else { 3913 // Otherwise just not available for now. 3914 if (task.isAvailable) { 3915 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3916 + task); 3917 } 3918 task.isAvailable = false; 3919 } 3920 } else { 3921 if (!ai.enabled || !ai.applicationInfo.enabled 3922 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3923 if (task.isAvailable) { 3924 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3925 + task + " (enabled=" + ai.enabled + "/" 3926 + ai.applicationInfo.enabled + " flags=" 3927 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3928 } 3929 task.isAvailable = false; 3930 } else { 3931 if (!task.isAvailable) { 3932 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3933 + task); 3934 } 3935 task.isAvailable = true; 3936 } 3937 } 3938 } 3939 } 3940 } 3941 3942 // Verify the affiliate chain for each task. 3943 for (int i = 0; i < N; ) { 3944 TaskRecord task = mRecentTasks.remove(i); 3945 if (mTmpRecents.contains(task)) { 3946 continue; 3947 } 3948 int affiliatedTaskId = task.mAffiliatedTaskId; 3949 while (true) { 3950 TaskRecord next = task.mNextAffiliate; 3951 if (next == null) { 3952 break; 3953 } 3954 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3955 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3956 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3957 task.setNextAffiliate(null); 3958 if (next.mPrevAffiliate == task) { 3959 next.setPrevAffiliate(null); 3960 } 3961 break; 3962 } 3963 if (next.mPrevAffiliate != task) { 3964 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3965 next.mPrevAffiliate + " task=" + task); 3966 next.setPrevAffiliate(null); 3967 task.setNextAffiliate(null); 3968 break; 3969 } 3970 if (!mRecentTasks.contains(next)) { 3971 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3972 task.setNextAffiliate(null); 3973 // We know that next.mPrevAffiliate is always task, from above, so clear 3974 // its previous affiliate. 3975 next.setPrevAffiliate(null); 3976 break; 3977 } 3978 task = next; 3979 } 3980 // task is now the end of the list 3981 do { 3982 mRecentTasks.remove(task); 3983 mRecentTasks.add(i++, task); 3984 mTmpRecents.add(task); 3985 task.inRecents = true; 3986 } while ((task = task.mPrevAffiliate) != null); 3987 } 3988 mTmpRecents.clear(); 3989 // mRecentTasks is now in sorted, affiliated order. 3990 } 3991 3992 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3993 int N = mRecentTasks.size(); 3994 TaskRecord top = task; 3995 int topIndex = taskIndex; 3996 while (top.mNextAffiliate != null && topIndex > 0) { 3997 top = top.mNextAffiliate; 3998 topIndex--; 3999 } 4000 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4001 + topIndex + " from intial " + taskIndex); 4002 // Find the end of the chain, doing a sanity check along the way. 4003 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4004 int endIndex = topIndex; 4005 TaskRecord prev = top; 4006 while (endIndex < N) { 4007 TaskRecord cur = mRecentTasks.get(endIndex); 4008 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4009 + endIndex + " " + cur); 4010 if (cur == top) { 4011 // Verify start of the chain. 4012 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4013 Slog.wtf(TAG, "Bad chain @" + endIndex 4014 + ": first task has next affiliate: " + prev); 4015 sane = false; 4016 break; 4017 } 4018 } else { 4019 // Verify middle of the chain's next points back to the one before. 4020 if (cur.mNextAffiliate != prev 4021 || cur.mNextAffiliateTaskId != prev.taskId) { 4022 Slog.wtf(TAG, "Bad chain @" + endIndex 4023 + ": middle task " + cur + " @" + endIndex 4024 + " has bad next affiliate " 4025 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4026 + ", expected " + prev); 4027 sane = false; 4028 break; 4029 } 4030 } 4031 if (cur.mPrevAffiliateTaskId == -1) { 4032 // Chain ends here. 4033 if (cur.mPrevAffiliate != null) { 4034 Slog.wtf(TAG, "Bad chain @" + endIndex 4035 + ": last task " + cur + " has previous affiliate " 4036 + cur.mPrevAffiliate); 4037 sane = false; 4038 } 4039 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4040 break; 4041 } else { 4042 // Verify middle of the chain's prev points to a valid item. 4043 if (cur.mPrevAffiliate == null) { 4044 Slog.wtf(TAG, "Bad chain @" + endIndex 4045 + ": task " + cur + " has previous affiliate " 4046 + cur.mPrevAffiliate + " but should be id " 4047 + cur.mPrevAffiliate); 4048 sane = false; 4049 break; 4050 } 4051 } 4052 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4053 Slog.wtf(TAG, "Bad chain @" + endIndex 4054 + ": task " + cur + " has affiliated id " 4055 + cur.mAffiliatedTaskId + " but should be " 4056 + task.mAffiliatedTaskId); 4057 sane = false; 4058 break; 4059 } 4060 prev = cur; 4061 endIndex++; 4062 if (endIndex >= N) { 4063 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4064 + ": last task " + prev); 4065 sane = false; 4066 break; 4067 } 4068 } 4069 if (sane) { 4070 if (endIndex < taskIndex) { 4071 Slog.wtf(TAG, "Bad chain @" + endIndex 4072 + ": did not extend to task " + task + " @" + taskIndex); 4073 sane = false; 4074 } 4075 } 4076 if (sane) { 4077 // All looks good, we can just move all of the affiliated tasks 4078 // to the top. 4079 for (int i=topIndex; i<=endIndex; i++) { 4080 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4081 + " from " + i + " to " + (i-topIndex)); 4082 TaskRecord cur = mRecentTasks.remove(i); 4083 mRecentTasks.add(i-topIndex, cur); 4084 } 4085 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4086 + " to " + endIndex); 4087 return true; 4088 } 4089 4090 // Whoops, couldn't do it. 4091 return false; 4092 } 4093 4094 final void addRecentTaskLocked(TaskRecord task) { 4095 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4096 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4097 4098 int N = mRecentTasks.size(); 4099 // Quick case: check if the top-most recent task is the same. 4100 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4101 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4102 return; 4103 } 4104 // Another quick case: check if this is part of a set of affiliated 4105 // tasks that are at the top. 4106 if (isAffiliated && N > 0 && task.inRecents 4107 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4108 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4109 + " at top when adding " + task); 4110 return; 4111 } 4112 // Another quick case: never add voice sessions. 4113 if (task.voiceSession != null) { 4114 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4115 return; 4116 } 4117 4118 boolean needAffiliationFix = false; 4119 4120 // Slightly less quick case: the task is already in recents, so all we need 4121 // to do is move it. 4122 if (task.inRecents) { 4123 int taskIndex = mRecentTasks.indexOf(task); 4124 if (taskIndex >= 0) { 4125 if (!isAffiliated) { 4126 // Simple case: this is not an affiliated task, so we just move it to the front. 4127 mRecentTasks.remove(taskIndex); 4128 mRecentTasks.add(0, task); 4129 notifyTaskPersisterLocked(task, false); 4130 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4131 + " from " + taskIndex); 4132 return; 4133 } else { 4134 // More complicated: need to keep all affiliated tasks together. 4135 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4136 // All went well. 4137 return; 4138 } 4139 4140 // Uh oh... something bad in the affiliation chain, try to rebuild 4141 // everything and then go through our general path of adding a new task. 4142 needAffiliationFix = true; 4143 } 4144 } else { 4145 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4146 needAffiliationFix = true; 4147 } 4148 } 4149 4150 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4151 trimRecentsForTask(task, true); 4152 4153 N = mRecentTasks.size(); 4154 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4155 final TaskRecord tr = mRecentTasks.remove(N - 1); 4156 tr.removedFromRecents(mTaskPersister); 4157 N--; 4158 } 4159 task.inRecents = true; 4160 if (!isAffiliated || needAffiliationFix) { 4161 // If this is a simple non-affiliated task, or we had some failure trying to 4162 // handle it as part of an affilated task, then just place it at the top. 4163 mRecentTasks.add(0, task); 4164 } else if (isAffiliated) { 4165 // If this is a new affiliated task, then move all of the affiliated tasks 4166 // to the front and insert this new one. 4167 TaskRecord other = task.mNextAffiliate; 4168 if (other == null) { 4169 other = task.mPrevAffiliate; 4170 } 4171 if (other != null) { 4172 int otherIndex = mRecentTasks.indexOf(other); 4173 if (otherIndex >= 0) { 4174 // Insert new task at appropriate location. 4175 int taskIndex; 4176 if (other == task.mNextAffiliate) { 4177 // We found the index of our next affiliation, which is who is 4178 // before us in the list, so add after that point. 4179 taskIndex = otherIndex+1; 4180 } else { 4181 // We found the index of our previous affiliation, which is who is 4182 // after us in the list, so add at their position. 4183 taskIndex = otherIndex; 4184 } 4185 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4186 + taskIndex + ": " + task); 4187 mRecentTasks.add(taskIndex, task); 4188 4189 // Now move everything to the front. 4190 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4191 // All went well. 4192 return; 4193 } 4194 4195 // Uh oh... something bad in the affiliation chain, try to rebuild 4196 // everything and then go through our general path of adding a new task. 4197 needAffiliationFix = true; 4198 } else { 4199 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4200 + other); 4201 needAffiliationFix = true; 4202 } 4203 } else { 4204 if (DEBUG_RECENTS) Slog.d(TAG, 4205 "addRecent: adding affiliated task without next/prev:" + task); 4206 needAffiliationFix = true; 4207 } 4208 } 4209 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4210 4211 if (needAffiliationFix) { 4212 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4213 cleanupRecentTasksLocked(task.userId); 4214 } 4215 } 4216 4217 /** 4218 * If needed, remove oldest existing entries in recents that are for the same kind 4219 * of task as the given one. 4220 */ 4221 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4222 int N = mRecentTasks.size(); 4223 final Intent intent = task.intent; 4224 final boolean document = intent != null && intent.isDocument(); 4225 4226 int maxRecents = task.maxRecents - 1; 4227 for (int i=0; i<N; i++) { 4228 final TaskRecord tr = mRecentTasks.get(i); 4229 if (task != tr) { 4230 if (task.userId != tr.userId) { 4231 continue; 4232 } 4233 if (i > MAX_RECENT_BITMAPS) { 4234 tr.freeLastThumbnail(); 4235 } 4236 final Intent trIntent = tr.intent; 4237 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4238 (intent == null || !intent.filterEquals(trIntent))) { 4239 continue; 4240 } 4241 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4242 if (document && trIsDocument) { 4243 // These are the same document activity (not necessarily the same doc). 4244 if (maxRecents > 0) { 4245 --maxRecents; 4246 continue; 4247 } 4248 // Hit the maximum number of documents for this task. Fall through 4249 // and remove this document from recents. 4250 } else if (document || trIsDocument) { 4251 // Only one of these is a document. Not the droid we're looking for. 4252 continue; 4253 } 4254 } 4255 4256 if (!doTrim) { 4257 // If the caller is not actually asking for a trim, just tell them we reached 4258 // a point where the trim would happen. 4259 return i; 4260 } 4261 4262 // Either task and tr are the same or, their affinities match or their intents match 4263 // and neither of them is a document, or they are documents using the same activity 4264 // and their maxRecents has been reached. 4265 tr.disposeThumbnail(); 4266 mRecentTasks.remove(i); 4267 if (task != tr) { 4268 tr.removedFromRecents(mTaskPersister); 4269 } 4270 i--; 4271 N--; 4272 if (task.intent == null) { 4273 // If the new recent task we are adding is not fully 4274 // specified, then replace it with the existing recent task. 4275 task = tr; 4276 } 4277 notifyTaskPersisterLocked(tr, false); 4278 } 4279 4280 return -1; 4281 } 4282 4283 @Override 4284 public void reportActivityFullyDrawn(IBinder token) { 4285 synchronized (this) { 4286 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4287 if (r == null) { 4288 return; 4289 } 4290 r.reportFullyDrawnLocked(); 4291 } 4292 } 4293 4294 @Override 4295 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4296 synchronized (this) { 4297 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4298 if (r == null) { 4299 return; 4300 } 4301 final long origId = Binder.clearCallingIdentity(); 4302 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4303 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4304 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4305 if (config != null) { 4306 r.frozenBeforeDestroy = true; 4307 if (!updateConfigurationLocked(config, r, false, false)) { 4308 mStackSupervisor.resumeTopActivitiesLocked(); 4309 } 4310 } 4311 Binder.restoreCallingIdentity(origId); 4312 } 4313 } 4314 4315 @Override 4316 public int getRequestedOrientation(IBinder token) { 4317 synchronized (this) { 4318 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4319 if (r == null) { 4320 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4321 } 4322 return mWindowManager.getAppOrientation(r.appToken); 4323 } 4324 } 4325 4326 /** 4327 * This is the internal entry point for handling Activity.finish(). 4328 * 4329 * @param token The Binder token referencing the Activity we want to finish. 4330 * @param resultCode Result code, if any, from this Activity. 4331 * @param resultData Result data (Intent), if any, from this Activity. 4332 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4333 * the root Activity in the task. 4334 * 4335 * @return Returns true if the activity successfully finished, or false if it is still running. 4336 */ 4337 @Override 4338 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4339 boolean finishTask) { 4340 // Refuse possible leaked file descriptors 4341 if (resultData != null && resultData.hasFileDescriptors() == true) { 4342 throw new IllegalArgumentException("File descriptors passed in Intent"); 4343 } 4344 4345 synchronized(this) { 4346 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4347 if (r == null) { 4348 return true; 4349 } 4350 // Keep track of the root activity of the task before we finish it 4351 TaskRecord tr = r.task; 4352 ActivityRecord rootR = tr.getRootActivity(); 4353 // Do not allow task to finish in Lock Task mode. 4354 if (tr == mStackSupervisor.mLockTaskModeTask) { 4355 if (rootR == r) { 4356 mStackSupervisor.showLockTaskToast(); 4357 return false; 4358 } 4359 } 4360 if (mController != null) { 4361 // Find the first activity that is not finishing. 4362 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4363 if (next != null) { 4364 // ask watcher if this is allowed 4365 boolean resumeOK = true; 4366 try { 4367 resumeOK = mController.activityResuming(next.packageName); 4368 } catch (RemoteException e) { 4369 mController = null; 4370 Watchdog.getInstance().setActivityController(null); 4371 } 4372 4373 if (!resumeOK) { 4374 return false; 4375 } 4376 } 4377 } 4378 final long origId = Binder.clearCallingIdentity(); 4379 try { 4380 boolean res; 4381 if (finishTask && r == rootR) { 4382 // If requested, remove the task that is associated to this activity only if it 4383 // was the root activity in the task. The result code and data is ignored because 4384 // we don't support returning them across task boundaries. 4385 res = removeTaskByIdLocked(tr.taskId, 0); 4386 } else { 4387 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4388 resultData, "app-request", true); 4389 } 4390 return res; 4391 } finally { 4392 Binder.restoreCallingIdentity(origId); 4393 } 4394 } 4395 } 4396 4397 @Override 4398 public final void finishHeavyWeightApp() { 4399 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4400 != PackageManager.PERMISSION_GRANTED) { 4401 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4402 + Binder.getCallingPid() 4403 + ", uid=" + Binder.getCallingUid() 4404 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4405 Slog.w(TAG, msg); 4406 throw new SecurityException(msg); 4407 } 4408 4409 synchronized(this) { 4410 if (mHeavyWeightProcess == null) { 4411 return; 4412 } 4413 4414 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4415 mHeavyWeightProcess.activities); 4416 for (int i=0; i<activities.size(); i++) { 4417 ActivityRecord r = activities.get(i); 4418 if (!r.finishing) { 4419 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4420 null, "finish-heavy", true); 4421 } 4422 } 4423 4424 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4425 mHeavyWeightProcess.userId, 0)); 4426 mHeavyWeightProcess = null; 4427 } 4428 } 4429 4430 @Override 4431 public void crashApplication(int uid, int initialPid, String packageName, 4432 String message) { 4433 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4434 != PackageManager.PERMISSION_GRANTED) { 4435 String msg = "Permission Denial: crashApplication() from pid=" 4436 + Binder.getCallingPid() 4437 + ", uid=" + Binder.getCallingUid() 4438 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4439 Slog.w(TAG, msg); 4440 throw new SecurityException(msg); 4441 } 4442 4443 synchronized(this) { 4444 ProcessRecord proc = null; 4445 4446 // Figure out which process to kill. We don't trust that initialPid 4447 // still has any relation to current pids, so must scan through the 4448 // list. 4449 synchronized (mPidsSelfLocked) { 4450 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4451 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4452 if (p.uid != uid) { 4453 continue; 4454 } 4455 if (p.pid == initialPid) { 4456 proc = p; 4457 break; 4458 } 4459 if (p.pkgList.containsKey(packageName)) { 4460 proc = p; 4461 } 4462 } 4463 } 4464 4465 if (proc == null) { 4466 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4467 + " initialPid=" + initialPid 4468 + " packageName=" + packageName); 4469 return; 4470 } 4471 4472 if (proc.thread != null) { 4473 if (proc.pid == Process.myPid()) { 4474 Log.w(TAG, "crashApplication: trying to crash self!"); 4475 return; 4476 } 4477 long ident = Binder.clearCallingIdentity(); 4478 try { 4479 proc.thread.scheduleCrash(message); 4480 } catch (RemoteException e) { 4481 } 4482 Binder.restoreCallingIdentity(ident); 4483 } 4484 } 4485 } 4486 4487 @Override 4488 public final void finishSubActivity(IBinder token, String resultWho, 4489 int requestCode) { 4490 synchronized(this) { 4491 final long origId = Binder.clearCallingIdentity(); 4492 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4493 if (r != null) { 4494 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4495 } 4496 Binder.restoreCallingIdentity(origId); 4497 } 4498 } 4499 4500 @Override 4501 public boolean finishActivityAffinity(IBinder token) { 4502 synchronized(this) { 4503 final long origId = Binder.clearCallingIdentity(); 4504 try { 4505 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4506 4507 ActivityRecord rootR = r.task.getRootActivity(); 4508 // Do not allow task to finish in Lock Task mode. 4509 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4510 if (rootR == r) { 4511 mStackSupervisor.showLockTaskToast(); 4512 return false; 4513 } 4514 } 4515 boolean res = false; 4516 if (r != null) { 4517 res = r.task.stack.finishActivityAffinityLocked(r); 4518 } 4519 return res; 4520 } finally { 4521 Binder.restoreCallingIdentity(origId); 4522 } 4523 } 4524 } 4525 4526 @Override 4527 public void finishVoiceTask(IVoiceInteractionSession session) { 4528 synchronized(this) { 4529 final long origId = Binder.clearCallingIdentity(); 4530 try { 4531 mStackSupervisor.finishVoiceTask(session); 4532 } finally { 4533 Binder.restoreCallingIdentity(origId); 4534 } 4535 } 4536 4537 } 4538 4539 @Override 4540 public boolean releaseActivityInstance(IBinder token) { 4541 synchronized(this) { 4542 final long origId = Binder.clearCallingIdentity(); 4543 try { 4544 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4545 if (r.task == null || r.task.stack == null) { 4546 return false; 4547 } 4548 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4549 } finally { 4550 Binder.restoreCallingIdentity(origId); 4551 } 4552 } 4553 } 4554 4555 @Override 4556 public void releaseSomeActivities(IApplicationThread appInt) { 4557 synchronized(this) { 4558 final long origId = Binder.clearCallingIdentity(); 4559 try { 4560 ProcessRecord app = getRecordForAppLocked(appInt); 4561 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4562 } finally { 4563 Binder.restoreCallingIdentity(origId); 4564 } 4565 } 4566 } 4567 4568 @Override 4569 public boolean willActivityBeVisible(IBinder token) { 4570 synchronized(this) { 4571 ActivityStack stack = ActivityRecord.getStackLocked(token); 4572 if (stack != null) { 4573 return stack.willActivityBeVisibleLocked(token); 4574 } 4575 return false; 4576 } 4577 } 4578 4579 @Override 4580 public void overridePendingTransition(IBinder token, String packageName, 4581 int enterAnim, int exitAnim) { 4582 synchronized(this) { 4583 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4584 if (self == null) { 4585 return; 4586 } 4587 4588 final long origId = Binder.clearCallingIdentity(); 4589 4590 if (self.state == ActivityState.RESUMED 4591 || self.state == ActivityState.PAUSING) { 4592 mWindowManager.overridePendingAppTransition(packageName, 4593 enterAnim, exitAnim, null); 4594 } 4595 4596 Binder.restoreCallingIdentity(origId); 4597 } 4598 } 4599 4600 /** 4601 * Main function for removing an existing process from the activity manager 4602 * as a result of that process going away. Clears out all connections 4603 * to the process. 4604 */ 4605 private final void handleAppDiedLocked(ProcessRecord app, 4606 boolean restarting, boolean allowRestart) { 4607 int pid = app.pid; 4608 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4609 if (!restarting) { 4610 removeLruProcessLocked(app); 4611 if (pid > 0) { 4612 ProcessList.remove(pid); 4613 } 4614 } 4615 4616 if (mProfileProc == app) { 4617 clearProfilerLocked(); 4618 } 4619 4620 // Remove this application's activities from active lists. 4621 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4622 4623 app.activities.clear(); 4624 4625 if (app.instrumentationClass != null) { 4626 Slog.w(TAG, "Crash of app " + app.processName 4627 + " running instrumentation " + app.instrumentationClass); 4628 Bundle info = new Bundle(); 4629 info.putString("shortMsg", "Process crashed."); 4630 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4631 } 4632 4633 if (!restarting) { 4634 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4635 // If there was nothing to resume, and we are not already 4636 // restarting this process, but there is a visible activity that 4637 // is hosted by the process... then make sure all visible 4638 // activities are running, taking care of restarting this 4639 // process. 4640 if (hasVisibleActivities) { 4641 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4642 } 4643 } 4644 } 4645 } 4646 4647 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4648 IBinder threadBinder = thread.asBinder(); 4649 // Find the application record. 4650 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4651 ProcessRecord rec = mLruProcesses.get(i); 4652 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4653 return i; 4654 } 4655 } 4656 return -1; 4657 } 4658 4659 final ProcessRecord getRecordForAppLocked( 4660 IApplicationThread thread) { 4661 if (thread == null) { 4662 return null; 4663 } 4664 4665 int appIndex = getLRURecordIndexForAppLocked(thread); 4666 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4667 } 4668 4669 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4670 // If there are no longer any background processes running, 4671 // and the app that died was not running instrumentation, 4672 // then tell everyone we are now low on memory. 4673 boolean haveBg = false; 4674 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4675 ProcessRecord rec = mLruProcesses.get(i); 4676 if (rec.thread != null 4677 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4678 haveBg = true; 4679 break; 4680 } 4681 } 4682 4683 if (!haveBg) { 4684 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4685 if (doReport) { 4686 long now = SystemClock.uptimeMillis(); 4687 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4688 doReport = false; 4689 } else { 4690 mLastMemUsageReportTime = now; 4691 } 4692 } 4693 final ArrayList<ProcessMemInfo> memInfos 4694 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4695 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4696 long now = SystemClock.uptimeMillis(); 4697 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4698 ProcessRecord rec = mLruProcesses.get(i); 4699 if (rec == dyingProc || rec.thread == null) { 4700 continue; 4701 } 4702 if (doReport) { 4703 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4704 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4705 } 4706 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4707 // The low memory report is overriding any current 4708 // state for a GC request. Make sure to do 4709 // heavy/important/visible/foreground processes first. 4710 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4711 rec.lastRequestedGc = 0; 4712 } else { 4713 rec.lastRequestedGc = rec.lastLowMemory; 4714 } 4715 rec.reportLowMemory = true; 4716 rec.lastLowMemory = now; 4717 mProcessesToGc.remove(rec); 4718 addProcessToGcListLocked(rec); 4719 } 4720 } 4721 if (doReport) { 4722 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4723 mHandler.sendMessage(msg); 4724 } 4725 scheduleAppGcsLocked(); 4726 } 4727 } 4728 4729 final void appDiedLocked(ProcessRecord app) { 4730 appDiedLocked(app, app.pid, app.thread); 4731 } 4732 4733 final void appDiedLocked(ProcessRecord app, int pid, 4734 IApplicationThread thread) { 4735 4736 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4737 synchronized (stats) { 4738 stats.noteProcessDiedLocked(app.info.uid, pid); 4739 } 4740 4741 Process.killProcessGroup(app.info.uid, pid); 4742 4743 // Clean up already done if the process has been re-started. 4744 if (app.pid == pid && app.thread != null && 4745 app.thread.asBinder() == thread.asBinder()) { 4746 boolean doLowMem = app.instrumentationClass == null; 4747 boolean doOomAdj = doLowMem; 4748 if (!app.killedByAm) { 4749 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4750 + ") has died."); 4751 mAllowLowerMemLevel = true; 4752 } else { 4753 // Note that we always want to do oom adj to update our state with the 4754 // new number of procs. 4755 mAllowLowerMemLevel = false; 4756 doLowMem = false; 4757 } 4758 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4759 if (DEBUG_CLEANUP) Slog.v( 4760 TAG, "Dying app: " + app + ", pid: " + pid 4761 + ", thread: " + thread.asBinder()); 4762 handleAppDiedLocked(app, false, true); 4763 4764 if (doOomAdj) { 4765 updateOomAdjLocked(); 4766 } 4767 if (doLowMem) { 4768 doLowMemReportIfNeededLocked(app); 4769 } 4770 } else if (app.pid != pid) { 4771 // A new process has already been started. 4772 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4773 + ") has died and restarted (pid " + app.pid + ")."); 4774 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4775 } else if (DEBUG_PROCESSES) { 4776 Slog.d(TAG, "Received spurious death notification for thread " 4777 + thread.asBinder()); 4778 } 4779 } 4780 4781 /** 4782 * If a stack trace dump file is configured, dump process stack traces. 4783 * @param clearTraces causes the dump file to be erased prior to the new 4784 * traces being written, if true; when false, the new traces will be 4785 * appended to any existing file content. 4786 * @param firstPids of dalvik VM processes to dump stack traces for first 4787 * @param lastPids of dalvik VM processes to dump stack traces for last 4788 * @param nativeProcs optional list of native process names to dump stack crawls 4789 * @return file containing stack traces, or null if no dump file is configured 4790 */ 4791 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4792 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4793 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4794 if (tracesPath == null || tracesPath.length() == 0) { 4795 return null; 4796 } 4797 4798 File tracesFile = new File(tracesPath); 4799 try { 4800 File tracesDir = tracesFile.getParentFile(); 4801 if (!tracesDir.exists()) { 4802 tracesFile.mkdirs(); 4803 if (!SELinux.restorecon(tracesDir)) { 4804 return null; 4805 } 4806 } 4807 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4808 4809 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4810 tracesFile.createNewFile(); 4811 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4812 } catch (IOException e) { 4813 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4814 return null; 4815 } 4816 4817 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4818 return tracesFile; 4819 } 4820 4821 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4822 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4823 // Use a FileObserver to detect when traces finish writing. 4824 // The order of traces is considered important to maintain for legibility. 4825 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4826 @Override 4827 public synchronized void onEvent(int event, String path) { notify(); } 4828 }; 4829 4830 try { 4831 observer.startWatching(); 4832 4833 // First collect all of the stacks of the most important pids. 4834 if (firstPids != null) { 4835 try { 4836 int num = firstPids.size(); 4837 for (int i = 0; i < num; i++) { 4838 synchronized (observer) { 4839 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4840 observer.wait(200); // Wait for write-close, give up after 200msec 4841 } 4842 } 4843 } catch (InterruptedException e) { 4844 Log.wtf(TAG, e); 4845 } 4846 } 4847 4848 // Next collect the stacks of the native pids 4849 if (nativeProcs != null) { 4850 int[] pids = Process.getPidsForCommands(nativeProcs); 4851 if (pids != null) { 4852 for (int pid : pids) { 4853 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4854 } 4855 } 4856 } 4857 4858 // Lastly, measure CPU usage. 4859 if (processCpuTracker != null) { 4860 processCpuTracker.init(); 4861 System.gc(); 4862 processCpuTracker.update(); 4863 try { 4864 synchronized (processCpuTracker) { 4865 processCpuTracker.wait(500); // measure over 1/2 second. 4866 } 4867 } catch (InterruptedException e) { 4868 } 4869 processCpuTracker.update(); 4870 4871 // We'll take the stack crawls of just the top apps using CPU. 4872 final int N = processCpuTracker.countWorkingStats(); 4873 int numProcs = 0; 4874 for (int i=0; i<N && numProcs<5; i++) { 4875 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4876 if (lastPids.indexOfKey(stats.pid) >= 0) { 4877 numProcs++; 4878 try { 4879 synchronized (observer) { 4880 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4881 observer.wait(200); // Wait for write-close, give up after 200msec 4882 } 4883 } catch (InterruptedException e) { 4884 Log.wtf(TAG, e); 4885 } 4886 4887 } 4888 } 4889 } 4890 } finally { 4891 observer.stopWatching(); 4892 } 4893 } 4894 4895 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4896 if (true || IS_USER_BUILD) { 4897 return; 4898 } 4899 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4900 if (tracesPath == null || tracesPath.length() == 0) { 4901 return; 4902 } 4903 4904 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4905 StrictMode.allowThreadDiskWrites(); 4906 try { 4907 final File tracesFile = new File(tracesPath); 4908 final File tracesDir = tracesFile.getParentFile(); 4909 final File tracesTmp = new File(tracesDir, "__tmp__"); 4910 try { 4911 if (!tracesDir.exists()) { 4912 tracesFile.mkdirs(); 4913 if (!SELinux.restorecon(tracesDir.getPath())) { 4914 return; 4915 } 4916 } 4917 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4918 4919 if (tracesFile.exists()) { 4920 tracesTmp.delete(); 4921 tracesFile.renameTo(tracesTmp); 4922 } 4923 StringBuilder sb = new StringBuilder(); 4924 Time tobj = new Time(); 4925 tobj.set(System.currentTimeMillis()); 4926 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4927 sb.append(": "); 4928 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4929 sb.append(" since "); 4930 sb.append(msg); 4931 FileOutputStream fos = new FileOutputStream(tracesFile); 4932 fos.write(sb.toString().getBytes()); 4933 if (app == null) { 4934 fos.write("\n*** No application process!".getBytes()); 4935 } 4936 fos.close(); 4937 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4938 } catch (IOException e) { 4939 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4940 return; 4941 } 4942 4943 if (app != null) { 4944 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4945 firstPids.add(app.pid); 4946 dumpStackTraces(tracesPath, firstPids, null, null, null); 4947 } 4948 4949 File lastTracesFile = null; 4950 File curTracesFile = null; 4951 for (int i=9; i>=0; i--) { 4952 String name = String.format(Locale.US, "slow%02d.txt", i); 4953 curTracesFile = new File(tracesDir, name); 4954 if (curTracesFile.exists()) { 4955 if (lastTracesFile != null) { 4956 curTracesFile.renameTo(lastTracesFile); 4957 } else { 4958 curTracesFile.delete(); 4959 } 4960 } 4961 lastTracesFile = curTracesFile; 4962 } 4963 tracesFile.renameTo(curTracesFile); 4964 if (tracesTmp.exists()) { 4965 tracesTmp.renameTo(tracesFile); 4966 } 4967 } finally { 4968 StrictMode.setThreadPolicy(oldPolicy); 4969 } 4970 } 4971 4972 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4973 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4974 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4975 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4976 4977 if (mController != null) { 4978 try { 4979 // 0 == continue, -1 = kill process immediately 4980 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4981 if (res < 0 && app.pid != MY_PID) { 4982 app.kill("anr", true); 4983 } 4984 } catch (RemoteException e) { 4985 mController = null; 4986 Watchdog.getInstance().setActivityController(null); 4987 } 4988 } 4989 4990 long anrTime = SystemClock.uptimeMillis(); 4991 if (MONITOR_CPU_USAGE) { 4992 updateCpuStatsNow(); 4993 } 4994 4995 synchronized (this) { 4996 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4997 if (mShuttingDown) { 4998 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4999 return; 5000 } else if (app.notResponding) { 5001 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5002 return; 5003 } else if (app.crashing) { 5004 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5005 return; 5006 } 5007 5008 // In case we come through here for the same app before completing 5009 // this one, mark as anring now so we will bail out. 5010 app.notResponding = true; 5011 5012 // Log the ANR to the event log. 5013 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5014 app.processName, app.info.flags, annotation); 5015 5016 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5017 firstPids.add(app.pid); 5018 5019 int parentPid = app.pid; 5020 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5021 if (parentPid != app.pid) firstPids.add(parentPid); 5022 5023 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5024 5025 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5026 ProcessRecord r = mLruProcesses.get(i); 5027 if (r != null && r.thread != null) { 5028 int pid = r.pid; 5029 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5030 if (r.persistent) { 5031 firstPids.add(pid); 5032 } else { 5033 lastPids.put(pid, Boolean.TRUE); 5034 } 5035 } 5036 } 5037 } 5038 } 5039 5040 // Log the ANR to the main log. 5041 StringBuilder info = new StringBuilder(); 5042 info.setLength(0); 5043 info.append("ANR in ").append(app.processName); 5044 if (activity != null && activity.shortComponentName != null) { 5045 info.append(" (").append(activity.shortComponentName).append(")"); 5046 } 5047 info.append("\n"); 5048 info.append("PID: ").append(app.pid).append("\n"); 5049 if (annotation != null) { 5050 info.append("Reason: ").append(annotation).append("\n"); 5051 } 5052 if (parent != null && parent != activity) { 5053 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5054 } 5055 5056 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5057 5058 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5059 NATIVE_STACKS_OF_INTEREST); 5060 5061 String cpuInfo = null; 5062 if (MONITOR_CPU_USAGE) { 5063 updateCpuStatsNow(); 5064 synchronized (mProcessCpuThread) { 5065 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5066 } 5067 info.append(processCpuTracker.printCurrentLoad()); 5068 info.append(cpuInfo); 5069 } 5070 5071 info.append(processCpuTracker.printCurrentState(anrTime)); 5072 5073 Slog.e(TAG, info.toString()); 5074 if (tracesFile == null) { 5075 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5076 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5077 } 5078 5079 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5080 cpuInfo, tracesFile, null); 5081 5082 if (mController != null) { 5083 try { 5084 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5085 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5086 if (res != 0) { 5087 if (res < 0 && app.pid != MY_PID) { 5088 app.kill("anr", true); 5089 } else { 5090 synchronized (this) { 5091 mServices.scheduleServiceTimeoutLocked(app); 5092 } 5093 } 5094 return; 5095 } 5096 } catch (RemoteException e) { 5097 mController = null; 5098 Watchdog.getInstance().setActivityController(null); 5099 } 5100 } 5101 5102 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5103 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5104 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5105 5106 synchronized (this) { 5107 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5108 app.kill("bg anr", true); 5109 return; 5110 } 5111 5112 // Set the app's notResponding state, and look up the errorReportReceiver 5113 makeAppNotRespondingLocked(app, 5114 activity != null ? activity.shortComponentName : null, 5115 annotation != null ? "ANR " + annotation : "ANR", 5116 info.toString()); 5117 5118 // Bring up the infamous App Not Responding dialog 5119 Message msg = Message.obtain(); 5120 HashMap<String, Object> map = new HashMap<String, Object>(); 5121 msg.what = SHOW_NOT_RESPONDING_MSG; 5122 msg.obj = map; 5123 msg.arg1 = aboveSystem ? 1 : 0; 5124 map.put("app", app); 5125 if (activity != null) { 5126 map.put("activity", activity); 5127 } 5128 5129 mHandler.sendMessage(msg); 5130 } 5131 } 5132 5133 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5134 if (!mLaunchWarningShown) { 5135 mLaunchWarningShown = true; 5136 mHandler.post(new Runnable() { 5137 @Override 5138 public void run() { 5139 synchronized (ActivityManagerService.this) { 5140 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5141 d.show(); 5142 mHandler.postDelayed(new Runnable() { 5143 @Override 5144 public void run() { 5145 synchronized (ActivityManagerService.this) { 5146 d.dismiss(); 5147 mLaunchWarningShown = false; 5148 } 5149 } 5150 }, 4000); 5151 } 5152 } 5153 }); 5154 } 5155 } 5156 5157 @Override 5158 public boolean clearApplicationUserData(final String packageName, 5159 final IPackageDataObserver observer, int userId) { 5160 enforceNotIsolatedCaller("clearApplicationUserData"); 5161 int uid = Binder.getCallingUid(); 5162 int pid = Binder.getCallingPid(); 5163 userId = handleIncomingUser(pid, uid, 5164 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5165 long callingId = Binder.clearCallingIdentity(); 5166 try { 5167 IPackageManager pm = AppGlobals.getPackageManager(); 5168 int pkgUid = -1; 5169 synchronized(this) { 5170 try { 5171 pkgUid = pm.getPackageUid(packageName, userId); 5172 } catch (RemoteException e) { 5173 } 5174 if (pkgUid == -1) { 5175 Slog.w(TAG, "Invalid packageName: " + packageName); 5176 if (observer != null) { 5177 try { 5178 observer.onRemoveCompleted(packageName, false); 5179 } catch (RemoteException e) { 5180 Slog.i(TAG, "Observer no longer exists."); 5181 } 5182 } 5183 return false; 5184 } 5185 if (uid == pkgUid || checkComponentPermission( 5186 android.Manifest.permission.CLEAR_APP_USER_DATA, 5187 pid, uid, -1, true) 5188 == PackageManager.PERMISSION_GRANTED) { 5189 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5190 } else { 5191 throw new SecurityException("PID " + pid + " does not have permission " 5192 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5193 + " of package " + packageName); 5194 } 5195 5196 // Remove all tasks match the cleared application package and user 5197 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5198 final TaskRecord tr = mRecentTasks.get(i); 5199 final String taskPackageName = 5200 tr.getBaseIntent().getComponent().getPackageName(); 5201 if (tr.userId != userId) continue; 5202 if (!taskPackageName.equals(packageName)) continue; 5203 removeTaskByIdLocked(tr.taskId, 0); 5204 } 5205 } 5206 5207 try { 5208 // Clear application user data 5209 pm.clearApplicationUserData(packageName, observer, userId); 5210 5211 synchronized(this) { 5212 // Remove all permissions granted from/to this package 5213 removeUriPermissionsForPackageLocked(packageName, userId, true); 5214 } 5215 5216 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5217 Uri.fromParts("package", packageName, null)); 5218 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5219 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5220 null, null, 0, null, null, null, false, false, userId); 5221 } catch (RemoteException e) { 5222 } 5223 } finally { 5224 Binder.restoreCallingIdentity(callingId); 5225 } 5226 return true; 5227 } 5228 5229 @Override 5230 public void killBackgroundProcesses(final String packageName, int userId) { 5231 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5232 != PackageManager.PERMISSION_GRANTED && 5233 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5234 != PackageManager.PERMISSION_GRANTED) { 5235 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5236 + Binder.getCallingPid() 5237 + ", uid=" + Binder.getCallingUid() 5238 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5239 Slog.w(TAG, msg); 5240 throw new SecurityException(msg); 5241 } 5242 5243 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5244 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5245 long callingId = Binder.clearCallingIdentity(); 5246 try { 5247 IPackageManager pm = AppGlobals.getPackageManager(); 5248 synchronized(this) { 5249 int appId = -1; 5250 try { 5251 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5252 } catch (RemoteException e) { 5253 } 5254 if (appId == -1) { 5255 Slog.w(TAG, "Invalid packageName: " + packageName); 5256 return; 5257 } 5258 killPackageProcessesLocked(packageName, appId, userId, 5259 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5260 } 5261 } finally { 5262 Binder.restoreCallingIdentity(callingId); 5263 } 5264 } 5265 5266 @Override 5267 public void killAllBackgroundProcesses() { 5268 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5269 != PackageManager.PERMISSION_GRANTED) { 5270 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5271 + Binder.getCallingPid() 5272 + ", uid=" + Binder.getCallingUid() 5273 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5274 Slog.w(TAG, msg); 5275 throw new SecurityException(msg); 5276 } 5277 5278 long callingId = Binder.clearCallingIdentity(); 5279 try { 5280 synchronized(this) { 5281 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5282 final int NP = mProcessNames.getMap().size(); 5283 for (int ip=0; ip<NP; ip++) { 5284 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5285 final int NA = apps.size(); 5286 for (int ia=0; ia<NA; ia++) { 5287 ProcessRecord app = apps.valueAt(ia); 5288 if (app.persistent) { 5289 // we don't kill persistent processes 5290 continue; 5291 } 5292 if (app.removed) { 5293 procs.add(app); 5294 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5295 app.removed = true; 5296 procs.add(app); 5297 } 5298 } 5299 } 5300 5301 int N = procs.size(); 5302 for (int i=0; i<N; i++) { 5303 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5304 } 5305 mAllowLowerMemLevel = true; 5306 updateOomAdjLocked(); 5307 doLowMemReportIfNeededLocked(null); 5308 } 5309 } finally { 5310 Binder.restoreCallingIdentity(callingId); 5311 } 5312 } 5313 5314 @Override 5315 public void forceStopPackage(final String packageName, int userId) { 5316 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5317 != PackageManager.PERMISSION_GRANTED) { 5318 String msg = "Permission Denial: forceStopPackage() from pid=" 5319 + Binder.getCallingPid() 5320 + ", uid=" + Binder.getCallingUid() 5321 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5322 Slog.w(TAG, msg); 5323 throw new SecurityException(msg); 5324 } 5325 final int callingPid = Binder.getCallingPid(); 5326 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5327 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5328 long callingId = Binder.clearCallingIdentity(); 5329 try { 5330 IPackageManager pm = AppGlobals.getPackageManager(); 5331 synchronized(this) { 5332 int[] users = userId == UserHandle.USER_ALL 5333 ? getUsersLocked() : new int[] { userId }; 5334 for (int user : users) { 5335 int pkgUid = -1; 5336 try { 5337 pkgUid = pm.getPackageUid(packageName, user); 5338 } catch (RemoteException e) { 5339 } 5340 if (pkgUid == -1) { 5341 Slog.w(TAG, "Invalid packageName: " + packageName); 5342 continue; 5343 } 5344 try { 5345 pm.setPackageStoppedState(packageName, true, user); 5346 } catch (RemoteException e) { 5347 } catch (IllegalArgumentException e) { 5348 Slog.w(TAG, "Failed trying to unstop package " 5349 + packageName + ": " + e); 5350 } 5351 if (isUserRunningLocked(user, false)) { 5352 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5353 } 5354 } 5355 } 5356 } finally { 5357 Binder.restoreCallingIdentity(callingId); 5358 } 5359 } 5360 5361 @Override 5362 public void addPackageDependency(String packageName) { 5363 synchronized (this) { 5364 int callingPid = Binder.getCallingPid(); 5365 if (callingPid == Process.myPid()) { 5366 // Yeah, um, no. 5367 Slog.w(TAG, "Can't addPackageDependency on system process"); 5368 return; 5369 } 5370 ProcessRecord proc; 5371 synchronized (mPidsSelfLocked) { 5372 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5373 } 5374 if (proc != null) { 5375 if (proc.pkgDeps == null) { 5376 proc.pkgDeps = new ArraySet<String>(1); 5377 } 5378 proc.pkgDeps.add(packageName); 5379 } 5380 } 5381 } 5382 5383 /* 5384 * The pkg name and app id have to be specified. 5385 */ 5386 @Override 5387 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5388 if (pkg == null) { 5389 return; 5390 } 5391 // Make sure the uid is valid. 5392 if (appid < 0) { 5393 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5394 return; 5395 } 5396 int callerUid = Binder.getCallingUid(); 5397 // Only the system server can kill an application 5398 if (callerUid == Process.SYSTEM_UID) { 5399 // Post an aysnc message to kill the application 5400 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5401 msg.arg1 = appid; 5402 msg.arg2 = 0; 5403 Bundle bundle = new Bundle(); 5404 bundle.putString("pkg", pkg); 5405 bundle.putString("reason", reason); 5406 msg.obj = bundle; 5407 mHandler.sendMessage(msg); 5408 } else { 5409 throw new SecurityException(callerUid + " cannot kill pkg: " + 5410 pkg); 5411 } 5412 } 5413 5414 @Override 5415 public void closeSystemDialogs(String reason) { 5416 enforceNotIsolatedCaller("closeSystemDialogs"); 5417 5418 final int pid = Binder.getCallingPid(); 5419 final int uid = Binder.getCallingUid(); 5420 final long origId = Binder.clearCallingIdentity(); 5421 try { 5422 synchronized (this) { 5423 // Only allow this from foreground processes, so that background 5424 // applications can't abuse it to prevent system UI from being shown. 5425 if (uid >= Process.FIRST_APPLICATION_UID) { 5426 ProcessRecord proc; 5427 synchronized (mPidsSelfLocked) { 5428 proc = mPidsSelfLocked.get(pid); 5429 } 5430 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5431 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5432 + " from background process " + proc); 5433 return; 5434 } 5435 } 5436 closeSystemDialogsLocked(reason); 5437 } 5438 } finally { 5439 Binder.restoreCallingIdentity(origId); 5440 } 5441 } 5442 5443 void closeSystemDialogsLocked(String reason) { 5444 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5445 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5446 | Intent.FLAG_RECEIVER_FOREGROUND); 5447 if (reason != null) { 5448 intent.putExtra("reason", reason); 5449 } 5450 mWindowManager.closeSystemDialogs(reason); 5451 5452 mStackSupervisor.closeSystemDialogsLocked(); 5453 5454 broadcastIntentLocked(null, null, intent, null, 5455 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5456 Process.SYSTEM_UID, UserHandle.USER_ALL); 5457 } 5458 5459 @Override 5460 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5461 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5462 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5463 for (int i=pids.length-1; i>=0; i--) { 5464 ProcessRecord proc; 5465 int oomAdj; 5466 synchronized (this) { 5467 synchronized (mPidsSelfLocked) { 5468 proc = mPidsSelfLocked.get(pids[i]); 5469 oomAdj = proc != null ? proc.setAdj : 0; 5470 } 5471 } 5472 infos[i] = new Debug.MemoryInfo(); 5473 Debug.getMemoryInfo(pids[i], infos[i]); 5474 if (proc != null) { 5475 synchronized (this) { 5476 if (proc.thread != null && proc.setAdj == oomAdj) { 5477 // Record this for posterity if the process has been stable. 5478 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5479 infos[i].getTotalUss(), false, proc.pkgList); 5480 } 5481 } 5482 } 5483 } 5484 return infos; 5485 } 5486 5487 @Override 5488 public long[] getProcessPss(int[] pids) { 5489 enforceNotIsolatedCaller("getProcessPss"); 5490 long[] pss = new long[pids.length]; 5491 for (int i=pids.length-1; i>=0; i--) { 5492 ProcessRecord proc; 5493 int oomAdj; 5494 synchronized (this) { 5495 synchronized (mPidsSelfLocked) { 5496 proc = mPidsSelfLocked.get(pids[i]); 5497 oomAdj = proc != null ? proc.setAdj : 0; 5498 } 5499 } 5500 long[] tmpUss = new long[1]; 5501 pss[i] = Debug.getPss(pids[i], tmpUss); 5502 if (proc != null) { 5503 synchronized (this) { 5504 if (proc.thread != null && proc.setAdj == oomAdj) { 5505 // Record this for posterity if the process has been stable. 5506 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5507 } 5508 } 5509 } 5510 } 5511 return pss; 5512 } 5513 5514 @Override 5515 public void killApplicationProcess(String processName, int uid) { 5516 if (processName == null) { 5517 return; 5518 } 5519 5520 int callerUid = Binder.getCallingUid(); 5521 // Only the system server can kill an application 5522 if (callerUid == Process.SYSTEM_UID) { 5523 synchronized (this) { 5524 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5525 if (app != null && app.thread != null) { 5526 try { 5527 app.thread.scheduleSuicide(); 5528 } catch (RemoteException e) { 5529 // If the other end already died, then our work here is done. 5530 } 5531 } else { 5532 Slog.w(TAG, "Process/uid not found attempting kill of " 5533 + processName + " / " + uid); 5534 } 5535 } 5536 } else { 5537 throw new SecurityException(callerUid + " cannot kill app process: " + 5538 processName); 5539 } 5540 } 5541 5542 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5543 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5544 false, true, false, false, UserHandle.getUserId(uid), reason); 5545 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5546 Uri.fromParts("package", packageName, null)); 5547 if (!mProcessesReady) { 5548 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5549 | Intent.FLAG_RECEIVER_FOREGROUND); 5550 } 5551 intent.putExtra(Intent.EXTRA_UID, uid); 5552 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5553 broadcastIntentLocked(null, null, intent, 5554 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5555 false, false, 5556 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5557 } 5558 5559 private void forceStopUserLocked(int userId, String reason) { 5560 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5561 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5562 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5563 | Intent.FLAG_RECEIVER_FOREGROUND); 5564 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5565 broadcastIntentLocked(null, null, intent, 5566 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5567 false, false, 5568 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5569 } 5570 5571 private final boolean killPackageProcessesLocked(String packageName, int appId, 5572 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5573 boolean doit, boolean evenPersistent, String reason) { 5574 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5575 5576 // Remove all processes this package may have touched: all with the 5577 // same UID (except for the system or root user), and all whose name 5578 // matches the package name. 5579 final int NP = mProcessNames.getMap().size(); 5580 for (int ip=0; ip<NP; ip++) { 5581 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5582 final int NA = apps.size(); 5583 for (int ia=0; ia<NA; ia++) { 5584 ProcessRecord app = apps.valueAt(ia); 5585 if (app.persistent && !evenPersistent) { 5586 // we don't kill persistent processes 5587 continue; 5588 } 5589 if (app.removed) { 5590 if (doit) { 5591 procs.add(app); 5592 } 5593 continue; 5594 } 5595 5596 // Skip process if it doesn't meet our oom adj requirement. 5597 if (app.setAdj < minOomAdj) { 5598 continue; 5599 } 5600 5601 // If no package is specified, we call all processes under the 5602 // give user id. 5603 if (packageName == null) { 5604 if (app.userId != userId) { 5605 continue; 5606 } 5607 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5608 continue; 5609 } 5610 // Package has been specified, we want to hit all processes 5611 // that match it. We need to qualify this by the processes 5612 // that are running under the specified app and user ID. 5613 } else { 5614 final boolean isDep = app.pkgDeps != null 5615 && app.pkgDeps.contains(packageName); 5616 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5617 continue; 5618 } 5619 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5620 continue; 5621 } 5622 if (!app.pkgList.containsKey(packageName) && !isDep) { 5623 continue; 5624 } 5625 } 5626 5627 // Process has passed all conditions, kill it! 5628 if (!doit) { 5629 return true; 5630 } 5631 app.removed = true; 5632 procs.add(app); 5633 } 5634 } 5635 5636 int N = procs.size(); 5637 for (int i=0; i<N; i++) { 5638 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5639 } 5640 updateOomAdjLocked(); 5641 return N > 0; 5642 } 5643 5644 private final boolean forceStopPackageLocked(String name, int appId, 5645 boolean callerWillRestart, boolean purgeCache, boolean doit, 5646 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5647 int i; 5648 int N; 5649 5650 if (userId == UserHandle.USER_ALL && name == null) { 5651 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5652 } 5653 5654 if (appId < 0 && name != null) { 5655 try { 5656 appId = UserHandle.getAppId( 5657 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5658 } catch (RemoteException e) { 5659 } 5660 } 5661 5662 if (doit) { 5663 if (name != null) { 5664 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5665 + " user=" + userId + ": " + reason); 5666 } else { 5667 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5668 } 5669 5670 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5671 for (int ip=pmap.size()-1; ip>=0; ip--) { 5672 SparseArray<Long> ba = pmap.valueAt(ip); 5673 for (i=ba.size()-1; i>=0; i--) { 5674 boolean remove = false; 5675 final int entUid = ba.keyAt(i); 5676 if (name != null) { 5677 if (userId == UserHandle.USER_ALL) { 5678 if (UserHandle.getAppId(entUid) == appId) { 5679 remove = true; 5680 } 5681 } else { 5682 if (entUid == UserHandle.getUid(userId, appId)) { 5683 remove = true; 5684 } 5685 } 5686 } else if (UserHandle.getUserId(entUid) == userId) { 5687 remove = true; 5688 } 5689 if (remove) { 5690 ba.removeAt(i); 5691 } 5692 } 5693 if (ba.size() == 0) { 5694 pmap.removeAt(ip); 5695 } 5696 } 5697 } 5698 5699 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5700 -100, callerWillRestart, true, doit, evenPersistent, 5701 name == null ? ("stop user " + userId) : ("stop " + name)); 5702 5703 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5704 if (!doit) { 5705 return true; 5706 } 5707 didSomething = true; 5708 } 5709 5710 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5711 if (!doit) { 5712 return true; 5713 } 5714 didSomething = true; 5715 } 5716 5717 if (name == null) { 5718 // Remove all sticky broadcasts from this user. 5719 mStickyBroadcasts.remove(userId); 5720 } 5721 5722 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5723 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5724 userId, providers)) { 5725 if (!doit) { 5726 return true; 5727 } 5728 didSomething = true; 5729 } 5730 N = providers.size(); 5731 for (i=0; i<N; i++) { 5732 removeDyingProviderLocked(null, providers.get(i), true); 5733 } 5734 5735 // Remove transient permissions granted from/to this package/user 5736 removeUriPermissionsForPackageLocked(name, userId, false); 5737 5738 if (name == null || uninstalling) { 5739 // Remove pending intents. For now we only do this when force 5740 // stopping users, because we have some problems when doing this 5741 // for packages -- app widgets are not currently cleaned up for 5742 // such packages, so they can be left with bad pending intents. 5743 if (mIntentSenderRecords.size() > 0) { 5744 Iterator<WeakReference<PendingIntentRecord>> it 5745 = mIntentSenderRecords.values().iterator(); 5746 while (it.hasNext()) { 5747 WeakReference<PendingIntentRecord> wpir = it.next(); 5748 if (wpir == null) { 5749 it.remove(); 5750 continue; 5751 } 5752 PendingIntentRecord pir = wpir.get(); 5753 if (pir == null) { 5754 it.remove(); 5755 continue; 5756 } 5757 if (name == null) { 5758 // Stopping user, remove all objects for the user. 5759 if (pir.key.userId != userId) { 5760 // Not the same user, skip it. 5761 continue; 5762 } 5763 } else { 5764 if (UserHandle.getAppId(pir.uid) != appId) { 5765 // Different app id, skip it. 5766 continue; 5767 } 5768 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5769 // Different user, skip it. 5770 continue; 5771 } 5772 if (!pir.key.packageName.equals(name)) { 5773 // Different package, skip it. 5774 continue; 5775 } 5776 } 5777 if (!doit) { 5778 return true; 5779 } 5780 didSomething = true; 5781 it.remove(); 5782 pir.canceled = true; 5783 if (pir.key.activity != null) { 5784 pir.key.activity.pendingResults.remove(pir.ref); 5785 } 5786 } 5787 } 5788 } 5789 5790 if (doit) { 5791 if (purgeCache && name != null) { 5792 AttributeCache ac = AttributeCache.instance(); 5793 if (ac != null) { 5794 ac.removePackage(name); 5795 } 5796 } 5797 if (mBooted) { 5798 mStackSupervisor.resumeTopActivitiesLocked(); 5799 mStackSupervisor.scheduleIdleLocked(); 5800 } 5801 } 5802 5803 return didSomething; 5804 } 5805 5806 private final boolean removeProcessLocked(ProcessRecord app, 5807 boolean callerWillRestart, boolean allowRestart, String reason) { 5808 final String name = app.processName; 5809 final int uid = app.uid; 5810 if (DEBUG_PROCESSES) Slog.d( 5811 TAG, "Force removing proc " + app.toShortString() + " (" + name 5812 + "/" + uid + ")"); 5813 5814 mProcessNames.remove(name, uid); 5815 mIsolatedProcesses.remove(app.uid); 5816 if (mHeavyWeightProcess == app) { 5817 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5818 mHeavyWeightProcess.userId, 0)); 5819 mHeavyWeightProcess = null; 5820 } 5821 boolean needRestart = false; 5822 if (app.pid > 0 && app.pid != MY_PID) { 5823 int pid = app.pid; 5824 synchronized (mPidsSelfLocked) { 5825 mPidsSelfLocked.remove(pid); 5826 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5827 } 5828 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5829 if (app.isolated) { 5830 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5831 } 5832 app.kill(reason, true); 5833 handleAppDiedLocked(app, true, allowRestart); 5834 removeLruProcessLocked(app); 5835 5836 if (app.persistent && !app.isolated) { 5837 if (!callerWillRestart) { 5838 addAppLocked(app.info, false, null /* ABI override */); 5839 } else { 5840 needRestart = true; 5841 } 5842 } 5843 } else { 5844 mRemovedProcesses.add(app); 5845 } 5846 5847 return needRestart; 5848 } 5849 5850 private final void processStartTimedOutLocked(ProcessRecord app) { 5851 final int pid = app.pid; 5852 boolean gone = false; 5853 synchronized (mPidsSelfLocked) { 5854 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5855 if (knownApp != null && knownApp.thread == null) { 5856 mPidsSelfLocked.remove(pid); 5857 gone = true; 5858 } 5859 } 5860 5861 if (gone) { 5862 Slog.w(TAG, "Process " + app + " failed to attach"); 5863 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5864 pid, app.uid, app.processName); 5865 mProcessNames.remove(app.processName, app.uid); 5866 mIsolatedProcesses.remove(app.uid); 5867 if (mHeavyWeightProcess == app) { 5868 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5869 mHeavyWeightProcess.userId, 0)); 5870 mHeavyWeightProcess = null; 5871 } 5872 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5873 if (app.isolated) { 5874 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5875 } 5876 // Take care of any launching providers waiting for this process. 5877 checkAppInLaunchingProvidersLocked(app, true); 5878 // Take care of any services that are waiting for the process. 5879 mServices.processStartTimedOutLocked(app); 5880 app.kill("start timeout", true); 5881 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5882 Slog.w(TAG, "Unattached app died before backup, skipping"); 5883 try { 5884 IBackupManager bm = IBackupManager.Stub.asInterface( 5885 ServiceManager.getService(Context.BACKUP_SERVICE)); 5886 bm.agentDisconnected(app.info.packageName); 5887 } catch (RemoteException e) { 5888 // Can't happen; the backup manager is local 5889 } 5890 } 5891 if (isPendingBroadcastProcessLocked(pid)) { 5892 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5893 skipPendingBroadcastLocked(pid); 5894 } 5895 } else { 5896 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5897 } 5898 } 5899 5900 private final boolean attachApplicationLocked(IApplicationThread thread, 5901 int pid) { 5902 5903 // Find the application record that is being attached... either via 5904 // the pid if we are running in multiple processes, or just pull the 5905 // next app record if we are emulating process with anonymous threads. 5906 ProcessRecord app; 5907 if (pid != MY_PID && pid >= 0) { 5908 synchronized (mPidsSelfLocked) { 5909 app = mPidsSelfLocked.get(pid); 5910 } 5911 } else { 5912 app = null; 5913 } 5914 5915 if (app == null) { 5916 Slog.w(TAG, "No pending application record for pid " + pid 5917 + " (IApplicationThread " + thread + "); dropping process"); 5918 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5919 if (pid > 0 && pid != MY_PID) { 5920 Process.killProcessQuiet(pid); 5921 //TODO: Process.killProcessGroup(app.info.uid, pid); 5922 } else { 5923 try { 5924 thread.scheduleExit(); 5925 } catch (Exception e) { 5926 // Ignore exceptions. 5927 } 5928 } 5929 return false; 5930 } 5931 5932 // If this application record is still attached to a previous 5933 // process, clean it up now. 5934 if (app.thread != null) { 5935 handleAppDiedLocked(app, true, true); 5936 } 5937 5938 // Tell the process all about itself. 5939 5940 if (localLOGV) Slog.v( 5941 TAG, "Binding process pid " + pid + " to record " + app); 5942 5943 final String processName = app.processName; 5944 try { 5945 AppDeathRecipient adr = new AppDeathRecipient( 5946 app, pid, thread); 5947 thread.asBinder().linkToDeath(adr, 0); 5948 app.deathRecipient = adr; 5949 } catch (RemoteException e) { 5950 app.resetPackageList(mProcessStats); 5951 startProcessLocked(app, "link fail", processName); 5952 return false; 5953 } 5954 5955 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5956 5957 app.makeActive(thread, mProcessStats); 5958 app.curAdj = app.setAdj = -100; 5959 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5960 app.forcingToForeground = null; 5961 updateProcessForegroundLocked(app, false, false); 5962 app.hasShownUi = false; 5963 app.debugging = false; 5964 app.cached = false; 5965 5966 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5967 5968 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5969 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5970 5971 if (!normalMode) { 5972 Slog.i(TAG, "Launching preboot mode app: " + app); 5973 } 5974 5975 if (localLOGV) Slog.v( 5976 TAG, "New app record " + app 5977 + " thread=" + thread.asBinder() + " pid=" + pid); 5978 try { 5979 int testMode = IApplicationThread.DEBUG_OFF; 5980 if (mDebugApp != null && mDebugApp.equals(processName)) { 5981 testMode = mWaitForDebugger 5982 ? IApplicationThread.DEBUG_WAIT 5983 : IApplicationThread.DEBUG_ON; 5984 app.debugging = true; 5985 if (mDebugTransient) { 5986 mDebugApp = mOrigDebugApp; 5987 mWaitForDebugger = mOrigWaitForDebugger; 5988 } 5989 } 5990 String profileFile = app.instrumentationProfileFile; 5991 ParcelFileDescriptor profileFd = null; 5992 int samplingInterval = 0; 5993 boolean profileAutoStop = false; 5994 if (mProfileApp != null && mProfileApp.equals(processName)) { 5995 mProfileProc = app; 5996 profileFile = mProfileFile; 5997 profileFd = mProfileFd; 5998 samplingInterval = mSamplingInterval; 5999 profileAutoStop = mAutoStopProfiler; 6000 } 6001 boolean enableOpenGlTrace = false; 6002 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6003 enableOpenGlTrace = true; 6004 mOpenGlTraceApp = null; 6005 } 6006 6007 // If the app is being launched for restore or full backup, set it up specially 6008 boolean isRestrictedBackupMode = false; 6009 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6010 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6011 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6012 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6013 } 6014 6015 ensurePackageDexOpt(app.instrumentationInfo != null 6016 ? app.instrumentationInfo.packageName 6017 : app.info.packageName); 6018 if (app.instrumentationClass != null) { 6019 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6020 } 6021 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6022 + processName + " with config " + mConfiguration); 6023 ApplicationInfo appInfo = app.instrumentationInfo != null 6024 ? app.instrumentationInfo : app.info; 6025 app.compat = compatibilityInfoForPackageLocked(appInfo); 6026 if (profileFd != null) { 6027 profileFd = profileFd.dup(); 6028 } 6029 ProfilerInfo profilerInfo = profileFile == null ? null 6030 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6031 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6032 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6033 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6034 isRestrictedBackupMode || !normalMode, app.persistent, 6035 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6036 mCoreSettingsObserver.getCoreSettingsLocked()); 6037 updateLruProcessLocked(app, false, null); 6038 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6039 } catch (Exception e) { 6040 // todo: Yikes! What should we do? For now we will try to 6041 // start another process, but that could easily get us in 6042 // an infinite loop of restarting processes... 6043 Slog.w(TAG, "Exception thrown during bind!", e); 6044 6045 app.resetPackageList(mProcessStats); 6046 app.unlinkDeathRecipient(); 6047 startProcessLocked(app, "bind fail", processName); 6048 return false; 6049 } 6050 6051 // Remove this record from the list of starting applications. 6052 mPersistentStartingProcesses.remove(app); 6053 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6054 "Attach application locked removing on hold: " + app); 6055 mProcessesOnHold.remove(app); 6056 6057 boolean badApp = false; 6058 boolean didSomething = false; 6059 6060 // See if the top visible activity is waiting to run in this process... 6061 if (normalMode) { 6062 try { 6063 if (mStackSupervisor.attachApplicationLocked(app)) { 6064 didSomething = true; 6065 } 6066 } catch (Exception e) { 6067 badApp = true; 6068 } 6069 } 6070 6071 // Find any services that should be running in this process... 6072 if (!badApp) { 6073 try { 6074 didSomething |= mServices.attachApplicationLocked(app, processName); 6075 } catch (Exception e) { 6076 badApp = true; 6077 } 6078 } 6079 6080 // Check if a next-broadcast receiver is in this process... 6081 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6082 try { 6083 didSomething |= sendPendingBroadcastsLocked(app); 6084 } catch (Exception e) { 6085 // If the app died trying to launch the receiver we declare it 'bad' 6086 badApp = true; 6087 } 6088 } 6089 6090 // Check whether the next backup agent is in this process... 6091 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6092 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6093 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6094 try { 6095 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6096 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6097 mBackupTarget.backupMode); 6098 } catch (Exception e) { 6099 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6100 e.printStackTrace(); 6101 } 6102 } 6103 6104 if (badApp) { 6105 // todo: Also need to kill application to deal with all 6106 // kinds of exceptions. 6107 handleAppDiedLocked(app, false, true); 6108 return false; 6109 } 6110 6111 if (!didSomething) { 6112 updateOomAdjLocked(); 6113 } 6114 6115 return true; 6116 } 6117 6118 @Override 6119 public final void attachApplication(IApplicationThread thread) { 6120 synchronized (this) { 6121 int callingPid = Binder.getCallingPid(); 6122 final long origId = Binder.clearCallingIdentity(); 6123 attachApplicationLocked(thread, callingPid); 6124 Binder.restoreCallingIdentity(origId); 6125 } 6126 } 6127 6128 @Override 6129 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6130 final long origId = Binder.clearCallingIdentity(); 6131 synchronized (this) { 6132 ActivityStack stack = ActivityRecord.getStackLocked(token); 6133 if (stack != null) { 6134 ActivityRecord r = 6135 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6136 if (stopProfiling) { 6137 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6138 try { 6139 mProfileFd.close(); 6140 } catch (IOException e) { 6141 } 6142 clearProfilerLocked(); 6143 } 6144 } 6145 } 6146 } 6147 Binder.restoreCallingIdentity(origId); 6148 } 6149 6150 void postEnableScreenAfterBootLocked() { 6151 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6152 } 6153 6154 void enableScreenAfterBoot() { 6155 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6156 SystemClock.uptimeMillis()); 6157 mWindowManager.enableScreenAfterBoot(); 6158 6159 synchronized (this) { 6160 updateEventDispatchingLocked(); 6161 } 6162 } 6163 6164 @Override 6165 public void showBootMessage(final CharSequence msg, final boolean always) { 6166 enforceNotIsolatedCaller("showBootMessage"); 6167 mWindowManager.showBootMessage(msg, always); 6168 } 6169 6170 @Override 6171 public void keyguardWaitingForActivityDrawn() { 6172 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6173 final long token = Binder.clearCallingIdentity(); 6174 try { 6175 synchronized (this) { 6176 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6177 mWindowManager.keyguardWaitingForActivityDrawn(); 6178 } 6179 } finally { 6180 Binder.restoreCallingIdentity(token); 6181 } 6182 } 6183 6184 final void finishBooting() { 6185 // Register receivers to handle package update events 6186 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6187 6188 // Let system services know. 6189 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6190 6191 synchronized (this) { 6192 // Ensure that any processes we had put on hold are now started 6193 // up. 6194 final int NP = mProcessesOnHold.size(); 6195 if (NP > 0) { 6196 ArrayList<ProcessRecord> procs = 6197 new ArrayList<ProcessRecord>(mProcessesOnHold); 6198 for (int ip=0; ip<NP; ip++) { 6199 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6200 + procs.get(ip)); 6201 startProcessLocked(procs.get(ip), "on-hold", null); 6202 } 6203 } 6204 6205 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6206 // Start looking for apps that are abusing wake locks. 6207 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6208 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6209 // Tell anyone interested that we are done booting! 6210 SystemProperties.set("sys.boot_completed", "1"); 6211 SystemProperties.set("dev.bootcomplete", "1"); 6212 for (int i=0; i<mStartedUsers.size(); i++) { 6213 UserStartedState uss = mStartedUsers.valueAt(i); 6214 if (uss.mState == UserStartedState.STATE_BOOTING) { 6215 uss.mState = UserStartedState.STATE_RUNNING; 6216 final int userId = mStartedUsers.keyAt(i); 6217 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6218 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6219 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6220 broadcastIntentLocked(null, null, intent, null, 6221 new IIntentReceiver.Stub() { 6222 @Override 6223 public void performReceive(Intent intent, int resultCode, 6224 String data, Bundle extras, boolean ordered, 6225 boolean sticky, int sendingUser) { 6226 synchronized (ActivityManagerService.this) { 6227 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6228 true, false); 6229 } 6230 } 6231 }, 6232 0, null, null, 6233 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6234 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6235 userId); 6236 } 6237 } 6238 scheduleStartProfilesLocked(); 6239 } 6240 } 6241 } 6242 6243 final void ensureBootCompleted() { 6244 boolean booting; 6245 boolean enableScreen; 6246 synchronized (this) { 6247 booting = mBooting; 6248 mBooting = false; 6249 enableScreen = !mBooted; 6250 mBooted = true; 6251 } 6252 6253 if (booting) { 6254 finishBooting(); 6255 } 6256 6257 if (enableScreen) { 6258 enableScreenAfterBoot(); 6259 } 6260 } 6261 6262 @Override 6263 public final void activityResumed(IBinder token) { 6264 final long origId = Binder.clearCallingIdentity(); 6265 synchronized(this) { 6266 ActivityStack stack = ActivityRecord.getStackLocked(token); 6267 if (stack != null) { 6268 ActivityRecord.activityResumedLocked(token); 6269 } 6270 } 6271 Binder.restoreCallingIdentity(origId); 6272 } 6273 6274 @Override 6275 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6276 final long origId = Binder.clearCallingIdentity(); 6277 synchronized(this) { 6278 ActivityStack stack = ActivityRecord.getStackLocked(token); 6279 if (stack != null) { 6280 stack.activityPausedLocked(token, false, persistentState); 6281 } 6282 } 6283 Binder.restoreCallingIdentity(origId); 6284 } 6285 6286 @Override 6287 public final void activityStopped(IBinder token, Bundle icicle, 6288 PersistableBundle persistentState, CharSequence description) { 6289 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6290 6291 // Refuse possible leaked file descriptors 6292 if (icicle != null && icicle.hasFileDescriptors()) { 6293 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6294 } 6295 6296 final long origId = Binder.clearCallingIdentity(); 6297 6298 synchronized (this) { 6299 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6300 if (r != null) { 6301 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6302 } 6303 } 6304 6305 trimApplications(); 6306 6307 Binder.restoreCallingIdentity(origId); 6308 } 6309 6310 @Override 6311 public final void activityDestroyed(IBinder token) { 6312 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6313 synchronized (this) { 6314 ActivityStack stack = ActivityRecord.getStackLocked(token); 6315 if (stack != null) { 6316 stack.activityDestroyedLocked(token); 6317 } 6318 } 6319 } 6320 6321 @Override 6322 public final void backgroundResourcesReleased(IBinder token) { 6323 final long origId = Binder.clearCallingIdentity(); 6324 try { 6325 synchronized (this) { 6326 ActivityStack stack = ActivityRecord.getStackLocked(token); 6327 if (stack != null) { 6328 stack.backgroundResourcesReleased(token); 6329 } 6330 } 6331 } finally { 6332 Binder.restoreCallingIdentity(origId); 6333 } 6334 } 6335 6336 @Override 6337 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6338 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6339 } 6340 6341 @Override 6342 public final void notifyEnterAnimationComplete(IBinder token) { 6343 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6344 } 6345 6346 @Override 6347 public String getCallingPackage(IBinder token) { 6348 synchronized (this) { 6349 ActivityRecord r = getCallingRecordLocked(token); 6350 return r != null ? r.info.packageName : null; 6351 } 6352 } 6353 6354 @Override 6355 public ComponentName getCallingActivity(IBinder token) { 6356 synchronized (this) { 6357 ActivityRecord r = getCallingRecordLocked(token); 6358 return r != null ? r.intent.getComponent() : null; 6359 } 6360 } 6361 6362 private ActivityRecord getCallingRecordLocked(IBinder token) { 6363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6364 if (r == null) { 6365 return null; 6366 } 6367 return r.resultTo; 6368 } 6369 6370 @Override 6371 public ComponentName getActivityClassForToken(IBinder token) { 6372 synchronized(this) { 6373 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6374 if (r == null) { 6375 return null; 6376 } 6377 return r.intent.getComponent(); 6378 } 6379 } 6380 6381 @Override 6382 public String getPackageForToken(IBinder token) { 6383 synchronized(this) { 6384 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6385 if (r == null) { 6386 return null; 6387 } 6388 return r.packageName; 6389 } 6390 } 6391 6392 @Override 6393 public IIntentSender getIntentSender(int type, 6394 String packageName, IBinder token, String resultWho, 6395 int requestCode, Intent[] intents, String[] resolvedTypes, 6396 int flags, Bundle options, int userId) { 6397 enforceNotIsolatedCaller("getIntentSender"); 6398 // Refuse possible leaked file descriptors 6399 if (intents != null) { 6400 if (intents.length < 1) { 6401 throw new IllegalArgumentException("Intents array length must be >= 1"); 6402 } 6403 for (int i=0; i<intents.length; i++) { 6404 Intent intent = intents[i]; 6405 if (intent != null) { 6406 if (intent.hasFileDescriptors()) { 6407 throw new IllegalArgumentException("File descriptors passed in Intent"); 6408 } 6409 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6410 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6411 throw new IllegalArgumentException( 6412 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6413 } 6414 intents[i] = new Intent(intent); 6415 } 6416 } 6417 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6418 throw new IllegalArgumentException( 6419 "Intent array length does not match resolvedTypes length"); 6420 } 6421 } 6422 if (options != null) { 6423 if (options.hasFileDescriptors()) { 6424 throw new IllegalArgumentException("File descriptors passed in options"); 6425 } 6426 } 6427 6428 synchronized(this) { 6429 int callingUid = Binder.getCallingUid(); 6430 int origUserId = userId; 6431 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6432 type == ActivityManager.INTENT_SENDER_BROADCAST, 6433 ALLOW_NON_FULL, "getIntentSender", null); 6434 if (origUserId == UserHandle.USER_CURRENT) { 6435 // We don't want to evaluate this until the pending intent is 6436 // actually executed. However, we do want to always do the 6437 // security checking for it above. 6438 userId = UserHandle.USER_CURRENT; 6439 } 6440 try { 6441 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6442 int uid = AppGlobals.getPackageManager() 6443 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6444 if (!UserHandle.isSameApp(callingUid, uid)) { 6445 String msg = "Permission Denial: getIntentSender() from pid=" 6446 + Binder.getCallingPid() 6447 + ", uid=" + Binder.getCallingUid() 6448 + ", (need uid=" + uid + ")" 6449 + " is not allowed to send as package " + packageName; 6450 Slog.w(TAG, msg); 6451 throw new SecurityException(msg); 6452 } 6453 } 6454 6455 return getIntentSenderLocked(type, packageName, callingUid, userId, 6456 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6457 6458 } catch (RemoteException e) { 6459 throw new SecurityException(e); 6460 } 6461 } 6462 } 6463 6464 IIntentSender getIntentSenderLocked(int type, String packageName, 6465 int callingUid, int userId, IBinder token, String resultWho, 6466 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6467 Bundle options) { 6468 if (DEBUG_MU) 6469 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6470 ActivityRecord activity = null; 6471 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6472 activity = ActivityRecord.isInStackLocked(token); 6473 if (activity == null) { 6474 return null; 6475 } 6476 if (activity.finishing) { 6477 return null; 6478 } 6479 } 6480 6481 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6482 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6483 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6484 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6485 |PendingIntent.FLAG_UPDATE_CURRENT); 6486 6487 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6488 type, packageName, activity, resultWho, 6489 requestCode, intents, resolvedTypes, flags, options, userId); 6490 WeakReference<PendingIntentRecord> ref; 6491 ref = mIntentSenderRecords.get(key); 6492 PendingIntentRecord rec = ref != null ? ref.get() : null; 6493 if (rec != null) { 6494 if (!cancelCurrent) { 6495 if (updateCurrent) { 6496 if (rec.key.requestIntent != null) { 6497 rec.key.requestIntent.replaceExtras(intents != null ? 6498 intents[intents.length - 1] : null); 6499 } 6500 if (intents != null) { 6501 intents[intents.length-1] = rec.key.requestIntent; 6502 rec.key.allIntents = intents; 6503 rec.key.allResolvedTypes = resolvedTypes; 6504 } else { 6505 rec.key.allIntents = null; 6506 rec.key.allResolvedTypes = null; 6507 } 6508 } 6509 return rec; 6510 } 6511 rec.canceled = true; 6512 mIntentSenderRecords.remove(key); 6513 } 6514 if (noCreate) { 6515 return rec; 6516 } 6517 rec = new PendingIntentRecord(this, key, callingUid); 6518 mIntentSenderRecords.put(key, rec.ref); 6519 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6520 if (activity.pendingResults == null) { 6521 activity.pendingResults 6522 = new HashSet<WeakReference<PendingIntentRecord>>(); 6523 } 6524 activity.pendingResults.add(rec.ref); 6525 } 6526 return rec; 6527 } 6528 6529 @Override 6530 public void cancelIntentSender(IIntentSender sender) { 6531 if (!(sender instanceof PendingIntentRecord)) { 6532 return; 6533 } 6534 synchronized(this) { 6535 PendingIntentRecord rec = (PendingIntentRecord)sender; 6536 try { 6537 int uid = AppGlobals.getPackageManager() 6538 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6539 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6540 String msg = "Permission Denial: cancelIntentSender() from pid=" 6541 + Binder.getCallingPid() 6542 + ", uid=" + Binder.getCallingUid() 6543 + " is not allowed to cancel packges " 6544 + rec.key.packageName; 6545 Slog.w(TAG, msg); 6546 throw new SecurityException(msg); 6547 } 6548 } catch (RemoteException e) { 6549 throw new SecurityException(e); 6550 } 6551 cancelIntentSenderLocked(rec, true); 6552 } 6553 } 6554 6555 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6556 rec.canceled = true; 6557 mIntentSenderRecords.remove(rec.key); 6558 if (cleanActivity && rec.key.activity != null) { 6559 rec.key.activity.pendingResults.remove(rec.ref); 6560 } 6561 } 6562 6563 @Override 6564 public String getPackageForIntentSender(IIntentSender pendingResult) { 6565 if (!(pendingResult instanceof PendingIntentRecord)) { 6566 return null; 6567 } 6568 try { 6569 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6570 return res.key.packageName; 6571 } catch (ClassCastException e) { 6572 } 6573 return null; 6574 } 6575 6576 @Override 6577 public int getUidForIntentSender(IIntentSender sender) { 6578 if (sender instanceof PendingIntentRecord) { 6579 try { 6580 PendingIntentRecord res = (PendingIntentRecord)sender; 6581 return res.uid; 6582 } catch (ClassCastException e) { 6583 } 6584 } 6585 return -1; 6586 } 6587 6588 @Override 6589 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6590 if (!(pendingResult instanceof PendingIntentRecord)) { 6591 return false; 6592 } 6593 try { 6594 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6595 if (res.key.allIntents == null) { 6596 return false; 6597 } 6598 for (int i=0; i<res.key.allIntents.length; i++) { 6599 Intent intent = res.key.allIntents[i]; 6600 if (intent.getPackage() != null && intent.getComponent() != null) { 6601 return false; 6602 } 6603 } 6604 return true; 6605 } catch (ClassCastException e) { 6606 } 6607 return false; 6608 } 6609 6610 @Override 6611 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6612 if (!(pendingResult instanceof PendingIntentRecord)) { 6613 return false; 6614 } 6615 try { 6616 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6617 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6618 return true; 6619 } 6620 return false; 6621 } catch (ClassCastException e) { 6622 } 6623 return false; 6624 } 6625 6626 @Override 6627 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6628 if (!(pendingResult instanceof PendingIntentRecord)) { 6629 return null; 6630 } 6631 try { 6632 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6633 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6634 } catch (ClassCastException e) { 6635 } 6636 return null; 6637 } 6638 6639 @Override 6640 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6641 if (!(pendingResult instanceof PendingIntentRecord)) { 6642 return null; 6643 } 6644 try { 6645 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6646 Intent intent = res.key.requestIntent; 6647 if (intent != null) { 6648 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6649 || res.lastTagPrefix.equals(prefix))) { 6650 return res.lastTag; 6651 } 6652 res.lastTagPrefix = prefix; 6653 StringBuilder sb = new StringBuilder(128); 6654 if (prefix != null) { 6655 sb.append(prefix); 6656 } 6657 if (intent.getAction() != null) { 6658 sb.append(intent.getAction()); 6659 } else if (intent.getComponent() != null) { 6660 intent.getComponent().appendShortString(sb); 6661 } else { 6662 sb.append("?"); 6663 } 6664 return res.lastTag = sb.toString(); 6665 } 6666 } catch (ClassCastException e) { 6667 } 6668 return null; 6669 } 6670 6671 @Override 6672 public void setProcessLimit(int max) { 6673 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6674 "setProcessLimit()"); 6675 synchronized (this) { 6676 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6677 mProcessLimitOverride = max; 6678 } 6679 trimApplications(); 6680 } 6681 6682 @Override 6683 public int getProcessLimit() { 6684 synchronized (this) { 6685 return mProcessLimitOverride; 6686 } 6687 } 6688 6689 void foregroundTokenDied(ForegroundToken token) { 6690 synchronized (ActivityManagerService.this) { 6691 synchronized (mPidsSelfLocked) { 6692 ForegroundToken cur 6693 = mForegroundProcesses.get(token.pid); 6694 if (cur != token) { 6695 return; 6696 } 6697 mForegroundProcesses.remove(token.pid); 6698 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6699 if (pr == null) { 6700 return; 6701 } 6702 pr.forcingToForeground = null; 6703 updateProcessForegroundLocked(pr, false, false); 6704 } 6705 updateOomAdjLocked(); 6706 } 6707 } 6708 6709 @Override 6710 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6711 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6712 "setProcessForeground()"); 6713 synchronized(this) { 6714 boolean changed = false; 6715 6716 synchronized (mPidsSelfLocked) { 6717 ProcessRecord pr = mPidsSelfLocked.get(pid); 6718 if (pr == null && isForeground) { 6719 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6720 return; 6721 } 6722 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6723 if (oldToken != null) { 6724 oldToken.token.unlinkToDeath(oldToken, 0); 6725 mForegroundProcesses.remove(pid); 6726 if (pr != null) { 6727 pr.forcingToForeground = null; 6728 } 6729 changed = true; 6730 } 6731 if (isForeground && token != null) { 6732 ForegroundToken newToken = new ForegroundToken() { 6733 @Override 6734 public void binderDied() { 6735 foregroundTokenDied(this); 6736 } 6737 }; 6738 newToken.pid = pid; 6739 newToken.token = token; 6740 try { 6741 token.linkToDeath(newToken, 0); 6742 mForegroundProcesses.put(pid, newToken); 6743 pr.forcingToForeground = token; 6744 changed = true; 6745 } catch (RemoteException e) { 6746 // If the process died while doing this, we will later 6747 // do the cleanup with the process death link. 6748 } 6749 } 6750 } 6751 6752 if (changed) { 6753 updateOomAdjLocked(); 6754 } 6755 } 6756 } 6757 6758 // ========================================================= 6759 // PERMISSIONS 6760 // ========================================================= 6761 6762 static class PermissionController extends IPermissionController.Stub { 6763 ActivityManagerService mActivityManagerService; 6764 PermissionController(ActivityManagerService activityManagerService) { 6765 mActivityManagerService = activityManagerService; 6766 } 6767 6768 @Override 6769 public boolean checkPermission(String permission, int pid, int uid) { 6770 return mActivityManagerService.checkPermission(permission, pid, 6771 uid) == PackageManager.PERMISSION_GRANTED; 6772 } 6773 } 6774 6775 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6776 @Override 6777 public int checkComponentPermission(String permission, int pid, int uid, 6778 int owningUid, boolean exported) { 6779 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6780 owningUid, exported); 6781 } 6782 6783 @Override 6784 public Object getAMSLock() { 6785 return ActivityManagerService.this; 6786 } 6787 } 6788 6789 /** 6790 * This can be called with or without the global lock held. 6791 */ 6792 int checkComponentPermission(String permission, int pid, int uid, 6793 int owningUid, boolean exported) { 6794 // We might be performing an operation on behalf of an indirect binder 6795 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6796 // client identity accordingly before proceeding. 6797 Identity tlsIdentity = sCallerIdentity.get(); 6798 if (tlsIdentity != null) { 6799 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6800 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6801 uid = tlsIdentity.uid; 6802 pid = tlsIdentity.pid; 6803 } 6804 6805 if (pid == MY_PID) { 6806 return PackageManager.PERMISSION_GRANTED; 6807 } 6808 6809 return ActivityManager.checkComponentPermission(permission, uid, 6810 owningUid, exported); 6811 } 6812 6813 /** 6814 * As the only public entry point for permissions checking, this method 6815 * can enforce the semantic that requesting a check on a null global 6816 * permission is automatically denied. (Internally a null permission 6817 * string is used when calling {@link #checkComponentPermission} in cases 6818 * when only uid-based security is needed.) 6819 * 6820 * This can be called with or without the global lock held. 6821 */ 6822 @Override 6823 public int checkPermission(String permission, int pid, int uid) { 6824 if (permission == null) { 6825 return PackageManager.PERMISSION_DENIED; 6826 } 6827 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6828 } 6829 6830 /** 6831 * Binder IPC calls go through the public entry point. 6832 * This can be called with or without the global lock held. 6833 */ 6834 int checkCallingPermission(String permission) { 6835 return checkPermission(permission, 6836 Binder.getCallingPid(), 6837 UserHandle.getAppId(Binder.getCallingUid())); 6838 } 6839 6840 /** 6841 * This can be called with or without the global lock held. 6842 */ 6843 void enforceCallingPermission(String permission, String func) { 6844 if (checkCallingPermission(permission) 6845 == PackageManager.PERMISSION_GRANTED) { 6846 return; 6847 } 6848 6849 String msg = "Permission Denial: " + func + " from pid=" 6850 + Binder.getCallingPid() 6851 + ", uid=" + Binder.getCallingUid() 6852 + " requires " + permission; 6853 Slog.w(TAG, msg); 6854 throw new SecurityException(msg); 6855 } 6856 6857 /** 6858 * Determine if UID is holding permissions required to access {@link Uri} in 6859 * the given {@link ProviderInfo}. Final permission checking is always done 6860 * in {@link ContentProvider}. 6861 */ 6862 private final boolean checkHoldingPermissionsLocked( 6863 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6864 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6865 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6866 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6867 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6868 != PERMISSION_GRANTED) { 6869 return false; 6870 } 6871 } 6872 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6873 } 6874 6875 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6876 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6877 if (pi.applicationInfo.uid == uid) { 6878 return true; 6879 } else if (!pi.exported) { 6880 return false; 6881 } 6882 6883 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6884 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6885 try { 6886 // check if target holds top-level <provider> permissions 6887 if (!readMet && pi.readPermission != null && considerUidPermissions 6888 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6889 readMet = true; 6890 } 6891 if (!writeMet && pi.writePermission != null && considerUidPermissions 6892 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6893 writeMet = true; 6894 } 6895 6896 // track if unprotected read/write is allowed; any denied 6897 // <path-permission> below removes this ability 6898 boolean allowDefaultRead = pi.readPermission == null; 6899 boolean allowDefaultWrite = pi.writePermission == null; 6900 6901 // check if target holds any <path-permission> that match uri 6902 final PathPermission[] pps = pi.pathPermissions; 6903 if (pps != null) { 6904 final String path = grantUri.uri.getPath(); 6905 int i = pps.length; 6906 while (i > 0 && (!readMet || !writeMet)) { 6907 i--; 6908 PathPermission pp = pps[i]; 6909 if (pp.match(path)) { 6910 if (!readMet) { 6911 final String pprperm = pp.getReadPermission(); 6912 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6913 + pprperm + " for " + pp.getPath() 6914 + ": match=" + pp.match(path) 6915 + " check=" + pm.checkUidPermission(pprperm, uid)); 6916 if (pprperm != null) { 6917 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6918 == PERMISSION_GRANTED) { 6919 readMet = true; 6920 } else { 6921 allowDefaultRead = false; 6922 } 6923 } 6924 } 6925 if (!writeMet) { 6926 final String ppwperm = pp.getWritePermission(); 6927 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6928 + ppwperm + " for " + pp.getPath() 6929 + ": match=" + pp.match(path) 6930 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6931 if (ppwperm != null) { 6932 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6933 == PERMISSION_GRANTED) { 6934 writeMet = true; 6935 } else { 6936 allowDefaultWrite = false; 6937 } 6938 } 6939 } 6940 } 6941 } 6942 } 6943 6944 // grant unprotected <provider> read/write, if not blocked by 6945 // <path-permission> above 6946 if (allowDefaultRead) readMet = true; 6947 if (allowDefaultWrite) writeMet = true; 6948 6949 } catch (RemoteException e) { 6950 return false; 6951 } 6952 6953 return readMet && writeMet; 6954 } 6955 6956 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6957 ProviderInfo pi = null; 6958 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6959 if (cpr != null) { 6960 pi = cpr.info; 6961 } else { 6962 try { 6963 pi = AppGlobals.getPackageManager().resolveContentProvider( 6964 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6965 } catch (RemoteException ex) { 6966 } 6967 } 6968 return pi; 6969 } 6970 6971 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6972 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6973 if (targetUris != null) { 6974 return targetUris.get(grantUri); 6975 } 6976 return null; 6977 } 6978 6979 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6980 String targetPkg, int targetUid, GrantUri grantUri) { 6981 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6982 if (targetUris == null) { 6983 targetUris = Maps.newArrayMap(); 6984 mGrantedUriPermissions.put(targetUid, targetUris); 6985 } 6986 6987 UriPermission perm = targetUris.get(grantUri); 6988 if (perm == null) { 6989 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6990 targetUris.put(grantUri, perm); 6991 } 6992 6993 return perm; 6994 } 6995 6996 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6997 final int modeFlags) { 6998 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6999 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7000 : UriPermission.STRENGTH_OWNED; 7001 7002 // Root gets to do everything. 7003 if (uid == 0) { 7004 return true; 7005 } 7006 7007 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7008 if (perms == null) return false; 7009 7010 // First look for exact match 7011 final UriPermission exactPerm = perms.get(grantUri); 7012 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7013 return true; 7014 } 7015 7016 // No exact match, look for prefixes 7017 final int N = perms.size(); 7018 for (int i = 0; i < N; i++) { 7019 final UriPermission perm = perms.valueAt(i); 7020 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7021 && perm.getStrength(modeFlags) >= minStrength) { 7022 return true; 7023 } 7024 } 7025 7026 return false; 7027 } 7028 7029 /** 7030 * @param uri This uri must NOT contain an embedded userId. 7031 * @param userId The userId in which the uri is to be resolved. 7032 */ 7033 @Override 7034 public int checkUriPermission(Uri uri, int pid, int uid, 7035 final int modeFlags, int userId) { 7036 enforceNotIsolatedCaller("checkUriPermission"); 7037 7038 // Another redirected-binder-call permissions check as in 7039 // {@link checkComponentPermission}. 7040 Identity tlsIdentity = sCallerIdentity.get(); 7041 if (tlsIdentity != null) { 7042 uid = tlsIdentity.uid; 7043 pid = tlsIdentity.pid; 7044 } 7045 7046 // Our own process gets to do everything. 7047 if (pid == MY_PID) { 7048 return PackageManager.PERMISSION_GRANTED; 7049 } 7050 synchronized (this) { 7051 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7052 ? PackageManager.PERMISSION_GRANTED 7053 : PackageManager.PERMISSION_DENIED; 7054 } 7055 } 7056 7057 /** 7058 * Check if the targetPkg can be granted permission to access uri by 7059 * the callingUid using the given modeFlags. Throws a security exception 7060 * if callingUid is not allowed to do this. Returns the uid of the target 7061 * if the URI permission grant should be performed; returns -1 if it is not 7062 * needed (for example targetPkg already has permission to access the URI). 7063 * If you already know the uid of the target, you can supply it in 7064 * lastTargetUid else set that to -1. 7065 */ 7066 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7067 final int modeFlags, int lastTargetUid) { 7068 if (!Intent.isAccessUriMode(modeFlags)) { 7069 return -1; 7070 } 7071 7072 if (targetPkg != null) { 7073 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7074 "Checking grant " + targetPkg + " permission to " + grantUri); 7075 } 7076 7077 final IPackageManager pm = AppGlobals.getPackageManager(); 7078 7079 // If this is not a content: uri, we can't do anything with it. 7080 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7081 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7082 "Can't grant URI permission for non-content URI: " + grantUri); 7083 return -1; 7084 } 7085 7086 final String authority = grantUri.uri.getAuthority(); 7087 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7088 if (pi == null) { 7089 Slog.w(TAG, "No content provider found for permission check: " + 7090 grantUri.uri.toSafeString()); 7091 return -1; 7092 } 7093 7094 int targetUid = lastTargetUid; 7095 if (targetUid < 0 && targetPkg != null) { 7096 try { 7097 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7098 if (targetUid < 0) { 7099 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7100 "Can't grant URI permission no uid for: " + targetPkg); 7101 return -1; 7102 } 7103 } catch (RemoteException ex) { 7104 return -1; 7105 } 7106 } 7107 7108 if (targetUid >= 0) { 7109 // First... does the target actually need this permission? 7110 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7111 // No need to grant the target this permission. 7112 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7113 "Target " + targetPkg + " already has full permission to " + grantUri); 7114 return -1; 7115 } 7116 } else { 7117 // First... there is no target package, so can anyone access it? 7118 boolean allowed = pi.exported; 7119 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7120 if (pi.readPermission != null) { 7121 allowed = false; 7122 } 7123 } 7124 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7125 if (pi.writePermission != null) { 7126 allowed = false; 7127 } 7128 } 7129 if (allowed) { 7130 return -1; 7131 } 7132 } 7133 7134 /* There is a special cross user grant if: 7135 * - The target is on another user. 7136 * - Apps on the current user can access the uri without any uid permissions. 7137 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7138 * grant uri permissions. 7139 */ 7140 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7141 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7142 modeFlags, false /*without considering the uid permissions*/); 7143 7144 // Second... is the provider allowing granting of URI permissions? 7145 if (!specialCrossUserGrant) { 7146 if (!pi.grantUriPermissions) { 7147 throw new SecurityException("Provider " + pi.packageName 7148 + "/" + pi.name 7149 + " does not allow granting of Uri permissions (uri " 7150 + grantUri + ")"); 7151 } 7152 if (pi.uriPermissionPatterns != null) { 7153 final int N = pi.uriPermissionPatterns.length; 7154 boolean allowed = false; 7155 for (int i=0; i<N; i++) { 7156 if (pi.uriPermissionPatterns[i] != null 7157 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7158 allowed = true; 7159 break; 7160 } 7161 } 7162 if (!allowed) { 7163 throw new SecurityException("Provider " + pi.packageName 7164 + "/" + pi.name 7165 + " does not allow granting of permission to path of Uri " 7166 + grantUri); 7167 } 7168 } 7169 } 7170 7171 // Third... does the caller itself have permission to access 7172 // this uri? 7173 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7174 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7175 // Require they hold a strong enough Uri permission 7176 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7177 throw new SecurityException("Uid " + callingUid 7178 + " does not have permission to uri " + grantUri); 7179 } 7180 } 7181 } 7182 return targetUid; 7183 } 7184 7185 /** 7186 * @param uri This uri must NOT contain an embedded userId. 7187 * @param userId The userId in which the uri is to be resolved. 7188 */ 7189 @Override 7190 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7191 final int modeFlags, int userId) { 7192 enforceNotIsolatedCaller("checkGrantUriPermission"); 7193 synchronized(this) { 7194 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7195 new GrantUri(userId, uri, false), modeFlags, -1); 7196 } 7197 } 7198 7199 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7200 final int modeFlags, UriPermissionOwner owner) { 7201 if (!Intent.isAccessUriMode(modeFlags)) { 7202 return; 7203 } 7204 7205 // So here we are: the caller has the assumed permission 7206 // to the uri, and the target doesn't. Let's now give this to 7207 // the target. 7208 7209 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7210 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7211 7212 final String authority = grantUri.uri.getAuthority(); 7213 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7214 if (pi == null) { 7215 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7216 return; 7217 } 7218 7219 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7220 grantUri.prefix = true; 7221 } 7222 final UriPermission perm = findOrCreateUriPermissionLocked( 7223 pi.packageName, targetPkg, targetUid, grantUri); 7224 perm.grantModes(modeFlags, owner); 7225 } 7226 7227 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7228 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7229 if (targetPkg == null) { 7230 throw new NullPointerException("targetPkg"); 7231 } 7232 int targetUid; 7233 final IPackageManager pm = AppGlobals.getPackageManager(); 7234 try { 7235 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7236 } catch (RemoteException ex) { 7237 return; 7238 } 7239 7240 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7241 targetUid); 7242 if (targetUid < 0) { 7243 return; 7244 } 7245 7246 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7247 owner); 7248 } 7249 7250 static class NeededUriGrants extends ArrayList<GrantUri> { 7251 final String targetPkg; 7252 final int targetUid; 7253 final int flags; 7254 7255 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7256 this.targetPkg = targetPkg; 7257 this.targetUid = targetUid; 7258 this.flags = flags; 7259 } 7260 } 7261 7262 /** 7263 * Like checkGrantUriPermissionLocked, but takes an Intent. 7264 */ 7265 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7266 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7267 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7268 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7269 + " clip=" + (intent != null ? intent.getClipData() : null) 7270 + " from " + intent + "; flags=0x" 7271 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7272 7273 if (targetPkg == null) { 7274 throw new NullPointerException("targetPkg"); 7275 } 7276 7277 if (intent == null) { 7278 return null; 7279 } 7280 Uri data = intent.getData(); 7281 ClipData clip = intent.getClipData(); 7282 if (data == null && clip == null) { 7283 return null; 7284 } 7285 // Default userId for uris in the intent (if they don't specify it themselves) 7286 int contentUserHint = intent.getContentUserHint(); 7287 if (contentUserHint == UserHandle.USER_CURRENT) { 7288 contentUserHint = UserHandle.getUserId(callingUid); 7289 } 7290 final IPackageManager pm = AppGlobals.getPackageManager(); 7291 int targetUid; 7292 if (needed != null) { 7293 targetUid = needed.targetUid; 7294 } else { 7295 try { 7296 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7297 } catch (RemoteException ex) { 7298 return null; 7299 } 7300 if (targetUid < 0) { 7301 if (DEBUG_URI_PERMISSION) { 7302 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7303 + " on user " + targetUserId); 7304 } 7305 return null; 7306 } 7307 } 7308 if (data != null) { 7309 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7310 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7311 targetUid); 7312 if (targetUid > 0) { 7313 if (needed == null) { 7314 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7315 } 7316 needed.add(grantUri); 7317 } 7318 } 7319 if (clip != null) { 7320 for (int i=0; i<clip.getItemCount(); i++) { 7321 Uri uri = clip.getItemAt(i).getUri(); 7322 if (uri != null) { 7323 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7324 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7325 targetUid); 7326 if (targetUid > 0) { 7327 if (needed == null) { 7328 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7329 } 7330 needed.add(grantUri); 7331 } 7332 } else { 7333 Intent clipIntent = clip.getItemAt(i).getIntent(); 7334 if (clipIntent != null) { 7335 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7336 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7337 if (newNeeded != null) { 7338 needed = newNeeded; 7339 } 7340 } 7341 } 7342 } 7343 } 7344 7345 return needed; 7346 } 7347 7348 /** 7349 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7350 */ 7351 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7352 UriPermissionOwner owner) { 7353 if (needed != null) { 7354 for (int i=0; i<needed.size(); i++) { 7355 GrantUri grantUri = needed.get(i); 7356 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7357 grantUri, needed.flags, owner); 7358 } 7359 } 7360 } 7361 7362 void grantUriPermissionFromIntentLocked(int callingUid, 7363 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7364 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7365 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7366 if (needed == null) { 7367 return; 7368 } 7369 7370 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7371 } 7372 7373 /** 7374 * @param uri This uri must NOT contain an embedded userId. 7375 * @param userId The userId in which the uri is to be resolved. 7376 */ 7377 @Override 7378 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7379 final int modeFlags, int userId) { 7380 enforceNotIsolatedCaller("grantUriPermission"); 7381 GrantUri grantUri = new GrantUri(userId, uri, false); 7382 synchronized(this) { 7383 final ProcessRecord r = getRecordForAppLocked(caller); 7384 if (r == null) { 7385 throw new SecurityException("Unable to find app for caller " 7386 + caller 7387 + " when granting permission to uri " + grantUri); 7388 } 7389 if (targetPkg == null) { 7390 throw new IllegalArgumentException("null target"); 7391 } 7392 if (grantUri == null) { 7393 throw new IllegalArgumentException("null uri"); 7394 } 7395 7396 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7397 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7398 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7399 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7400 7401 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7402 UserHandle.getUserId(r.uid)); 7403 } 7404 } 7405 7406 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7407 if (perm.modeFlags == 0) { 7408 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7409 perm.targetUid); 7410 if (perms != null) { 7411 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7412 "Removing " + perm.targetUid + " permission to " + perm.uri); 7413 7414 perms.remove(perm.uri); 7415 if (perms.isEmpty()) { 7416 mGrantedUriPermissions.remove(perm.targetUid); 7417 } 7418 } 7419 } 7420 } 7421 7422 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7423 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7424 7425 final IPackageManager pm = AppGlobals.getPackageManager(); 7426 final String authority = grantUri.uri.getAuthority(); 7427 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7428 if (pi == null) { 7429 Slog.w(TAG, "No content provider found for permission revoke: " 7430 + grantUri.toSafeString()); 7431 return; 7432 } 7433 7434 // Does the caller have this permission on the URI? 7435 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7436 // Right now, if you are not the original owner of the permission, 7437 // you are not allowed to revoke it. 7438 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7439 throw new SecurityException("Uid " + callingUid 7440 + " does not have permission to uri " + grantUri); 7441 //} 7442 } 7443 7444 boolean persistChanged = false; 7445 7446 // Go through all of the permissions and remove any that match. 7447 int N = mGrantedUriPermissions.size(); 7448 for (int i = 0; i < N; i++) { 7449 final int targetUid = mGrantedUriPermissions.keyAt(i); 7450 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7451 7452 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7453 final UriPermission perm = it.next(); 7454 if (perm.uri.sourceUserId == grantUri.sourceUserId 7455 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7456 if (DEBUG_URI_PERMISSION) 7457 Slog.v(TAG, 7458 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7459 persistChanged |= perm.revokeModes( 7460 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7461 if (perm.modeFlags == 0) { 7462 it.remove(); 7463 } 7464 } 7465 } 7466 7467 if (perms.isEmpty()) { 7468 mGrantedUriPermissions.remove(targetUid); 7469 N--; 7470 i--; 7471 } 7472 } 7473 7474 if (persistChanged) { 7475 schedulePersistUriGrants(); 7476 } 7477 } 7478 7479 /** 7480 * @param uri This uri must NOT contain an embedded userId. 7481 * @param userId The userId in which the uri is to be resolved. 7482 */ 7483 @Override 7484 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7485 int userId) { 7486 enforceNotIsolatedCaller("revokeUriPermission"); 7487 synchronized(this) { 7488 final ProcessRecord r = getRecordForAppLocked(caller); 7489 if (r == null) { 7490 throw new SecurityException("Unable to find app for caller " 7491 + caller 7492 + " when revoking permission to uri " + uri); 7493 } 7494 if (uri == null) { 7495 Slog.w(TAG, "revokeUriPermission: null uri"); 7496 return; 7497 } 7498 7499 if (!Intent.isAccessUriMode(modeFlags)) { 7500 return; 7501 } 7502 7503 final IPackageManager pm = AppGlobals.getPackageManager(); 7504 final String authority = uri.getAuthority(); 7505 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7506 if (pi == null) { 7507 Slog.w(TAG, "No content provider found for permission revoke: " 7508 + uri.toSafeString()); 7509 return; 7510 } 7511 7512 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7513 } 7514 } 7515 7516 /** 7517 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7518 * given package. 7519 * 7520 * @param packageName Package name to match, or {@code null} to apply to all 7521 * packages. 7522 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7523 * to all users. 7524 * @param persistable If persistable grants should be removed. 7525 */ 7526 private void removeUriPermissionsForPackageLocked( 7527 String packageName, int userHandle, boolean persistable) { 7528 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7529 throw new IllegalArgumentException("Must narrow by either package or user"); 7530 } 7531 7532 boolean persistChanged = false; 7533 7534 int N = mGrantedUriPermissions.size(); 7535 for (int i = 0; i < N; i++) { 7536 final int targetUid = mGrantedUriPermissions.keyAt(i); 7537 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7538 7539 // Only inspect grants matching user 7540 if (userHandle == UserHandle.USER_ALL 7541 || userHandle == UserHandle.getUserId(targetUid)) { 7542 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7543 final UriPermission perm = it.next(); 7544 7545 // Only inspect grants matching package 7546 if (packageName == null || perm.sourcePkg.equals(packageName) 7547 || perm.targetPkg.equals(packageName)) { 7548 persistChanged |= perm.revokeModes( 7549 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7550 7551 // Only remove when no modes remain; any persisted grants 7552 // will keep this alive. 7553 if (perm.modeFlags == 0) { 7554 it.remove(); 7555 } 7556 } 7557 } 7558 7559 if (perms.isEmpty()) { 7560 mGrantedUriPermissions.remove(targetUid); 7561 N--; 7562 i--; 7563 } 7564 } 7565 } 7566 7567 if (persistChanged) { 7568 schedulePersistUriGrants(); 7569 } 7570 } 7571 7572 @Override 7573 public IBinder newUriPermissionOwner(String name) { 7574 enforceNotIsolatedCaller("newUriPermissionOwner"); 7575 synchronized(this) { 7576 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7577 return owner.getExternalTokenLocked(); 7578 } 7579 } 7580 7581 /** 7582 * @param uri This uri must NOT contain an embedded userId. 7583 * @param sourceUserId The userId in which the uri is to be resolved. 7584 * @param targetUserId The userId of the app that receives the grant. 7585 */ 7586 @Override 7587 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7588 final int modeFlags, int sourceUserId, int targetUserId) { 7589 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7590 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7591 synchronized(this) { 7592 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7593 if (owner == null) { 7594 throw new IllegalArgumentException("Unknown owner: " + token); 7595 } 7596 if (fromUid != Binder.getCallingUid()) { 7597 if (Binder.getCallingUid() != Process.myUid()) { 7598 // Only system code can grant URI permissions on behalf 7599 // of other users. 7600 throw new SecurityException("nice try"); 7601 } 7602 } 7603 if (targetPkg == null) { 7604 throw new IllegalArgumentException("null target"); 7605 } 7606 if (uri == null) { 7607 throw new IllegalArgumentException("null uri"); 7608 } 7609 7610 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7611 modeFlags, owner, targetUserId); 7612 } 7613 } 7614 7615 /** 7616 * @param uri This uri must NOT contain an embedded userId. 7617 * @param userId The userId in which the uri is to be resolved. 7618 */ 7619 @Override 7620 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7621 synchronized(this) { 7622 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7623 if (owner == null) { 7624 throw new IllegalArgumentException("Unknown owner: " + token); 7625 } 7626 7627 if (uri == null) { 7628 owner.removeUriPermissionsLocked(mode); 7629 } else { 7630 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7631 } 7632 } 7633 } 7634 7635 private void schedulePersistUriGrants() { 7636 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7637 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7638 10 * DateUtils.SECOND_IN_MILLIS); 7639 } 7640 } 7641 7642 private void writeGrantedUriPermissions() { 7643 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7644 7645 // Snapshot permissions so we can persist without lock 7646 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7647 synchronized (this) { 7648 final int size = mGrantedUriPermissions.size(); 7649 for (int i = 0; i < size; i++) { 7650 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7651 for (UriPermission perm : perms.values()) { 7652 if (perm.persistedModeFlags != 0) { 7653 persist.add(perm.snapshot()); 7654 } 7655 } 7656 } 7657 } 7658 7659 FileOutputStream fos = null; 7660 try { 7661 fos = mGrantFile.startWrite(); 7662 7663 XmlSerializer out = new FastXmlSerializer(); 7664 out.setOutput(fos, "utf-8"); 7665 out.startDocument(null, true); 7666 out.startTag(null, TAG_URI_GRANTS); 7667 for (UriPermission.Snapshot perm : persist) { 7668 out.startTag(null, TAG_URI_GRANT); 7669 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7670 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7671 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7672 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7673 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7674 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7675 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7676 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7677 out.endTag(null, TAG_URI_GRANT); 7678 } 7679 out.endTag(null, TAG_URI_GRANTS); 7680 out.endDocument(); 7681 7682 mGrantFile.finishWrite(fos); 7683 } catch (IOException e) { 7684 if (fos != null) { 7685 mGrantFile.failWrite(fos); 7686 } 7687 } 7688 } 7689 7690 private void readGrantedUriPermissionsLocked() { 7691 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7692 7693 final long now = System.currentTimeMillis(); 7694 7695 FileInputStream fis = null; 7696 try { 7697 fis = mGrantFile.openRead(); 7698 final XmlPullParser in = Xml.newPullParser(); 7699 in.setInput(fis, null); 7700 7701 int type; 7702 while ((type = in.next()) != END_DOCUMENT) { 7703 final String tag = in.getName(); 7704 if (type == START_TAG) { 7705 if (TAG_URI_GRANT.equals(tag)) { 7706 final int sourceUserId; 7707 final int targetUserId; 7708 final int userHandle = readIntAttribute(in, 7709 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7710 if (userHandle != UserHandle.USER_NULL) { 7711 // For backwards compatibility. 7712 sourceUserId = userHandle; 7713 targetUserId = userHandle; 7714 } else { 7715 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7716 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7717 } 7718 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7719 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7720 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7721 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7722 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7723 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7724 7725 // Sanity check that provider still belongs to source package 7726 final ProviderInfo pi = getProviderInfoLocked( 7727 uri.getAuthority(), sourceUserId); 7728 if (pi != null && sourcePkg.equals(pi.packageName)) { 7729 int targetUid = -1; 7730 try { 7731 targetUid = AppGlobals.getPackageManager() 7732 .getPackageUid(targetPkg, targetUserId); 7733 } catch (RemoteException e) { 7734 } 7735 if (targetUid != -1) { 7736 final UriPermission perm = findOrCreateUriPermissionLocked( 7737 sourcePkg, targetPkg, targetUid, 7738 new GrantUri(sourceUserId, uri, prefix)); 7739 perm.initPersistedModes(modeFlags, createdTime); 7740 } 7741 } else { 7742 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7743 + " but instead found " + pi); 7744 } 7745 } 7746 } 7747 } 7748 } catch (FileNotFoundException e) { 7749 // Missing grants is okay 7750 } catch (IOException e) { 7751 Log.wtf(TAG, "Failed reading Uri grants", e); 7752 } catch (XmlPullParserException e) { 7753 Log.wtf(TAG, "Failed reading Uri grants", e); 7754 } finally { 7755 IoUtils.closeQuietly(fis); 7756 } 7757 } 7758 7759 /** 7760 * @param uri This uri must NOT contain an embedded userId. 7761 * @param userId The userId in which the uri is to be resolved. 7762 */ 7763 @Override 7764 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7765 enforceNotIsolatedCaller("takePersistableUriPermission"); 7766 7767 Preconditions.checkFlagsArgument(modeFlags, 7768 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7769 7770 synchronized (this) { 7771 final int callingUid = Binder.getCallingUid(); 7772 boolean persistChanged = false; 7773 GrantUri grantUri = new GrantUri(userId, uri, false); 7774 7775 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7776 new GrantUri(userId, uri, false)); 7777 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7778 new GrantUri(userId, uri, true)); 7779 7780 final boolean exactValid = (exactPerm != null) 7781 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7782 final boolean prefixValid = (prefixPerm != null) 7783 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7784 7785 if (!(exactValid || prefixValid)) { 7786 throw new SecurityException("No persistable permission grants found for UID " 7787 + callingUid + " and Uri " + grantUri.toSafeString()); 7788 } 7789 7790 if (exactValid) { 7791 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7792 } 7793 if (prefixValid) { 7794 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7795 } 7796 7797 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7798 7799 if (persistChanged) { 7800 schedulePersistUriGrants(); 7801 } 7802 } 7803 } 7804 7805 /** 7806 * @param uri This uri must NOT contain an embedded userId. 7807 * @param userId The userId in which the uri is to be resolved. 7808 */ 7809 @Override 7810 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7811 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7812 7813 Preconditions.checkFlagsArgument(modeFlags, 7814 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7815 7816 synchronized (this) { 7817 final int callingUid = Binder.getCallingUid(); 7818 boolean persistChanged = false; 7819 7820 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7821 new GrantUri(userId, uri, false)); 7822 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7823 new GrantUri(userId, uri, true)); 7824 if (exactPerm == null && prefixPerm == null) { 7825 throw new SecurityException("No permission grants found for UID " + callingUid 7826 + " and Uri " + uri.toSafeString()); 7827 } 7828 7829 if (exactPerm != null) { 7830 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7831 removeUriPermissionIfNeededLocked(exactPerm); 7832 } 7833 if (prefixPerm != null) { 7834 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7835 removeUriPermissionIfNeededLocked(prefixPerm); 7836 } 7837 7838 if (persistChanged) { 7839 schedulePersistUriGrants(); 7840 } 7841 } 7842 } 7843 7844 /** 7845 * Prune any older {@link UriPermission} for the given UID until outstanding 7846 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7847 * 7848 * @return if any mutations occured that require persisting. 7849 */ 7850 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7851 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7852 if (perms == null) return false; 7853 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7854 7855 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7856 for (UriPermission perm : perms.values()) { 7857 if (perm.persistedModeFlags != 0) { 7858 persisted.add(perm); 7859 } 7860 } 7861 7862 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7863 if (trimCount <= 0) return false; 7864 7865 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7866 for (int i = 0; i < trimCount; i++) { 7867 final UriPermission perm = persisted.get(i); 7868 7869 if (DEBUG_URI_PERMISSION) { 7870 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7871 } 7872 7873 perm.releasePersistableModes(~0); 7874 removeUriPermissionIfNeededLocked(perm); 7875 } 7876 7877 return true; 7878 } 7879 7880 @Override 7881 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7882 String packageName, boolean incoming) { 7883 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7884 Preconditions.checkNotNull(packageName, "packageName"); 7885 7886 final int callingUid = Binder.getCallingUid(); 7887 final IPackageManager pm = AppGlobals.getPackageManager(); 7888 try { 7889 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7890 if (packageUid != callingUid) { 7891 throw new SecurityException( 7892 "Package " + packageName + " does not belong to calling UID " + callingUid); 7893 } 7894 } catch (RemoteException e) { 7895 throw new SecurityException("Failed to verify package name ownership"); 7896 } 7897 7898 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7899 synchronized (this) { 7900 if (incoming) { 7901 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7902 callingUid); 7903 if (perms == null) { 7904 Slog.w(TAG, "No permission grants found for " + packageName); 7905 } else { 7906 for (UriPermission perm : perms.values()) { 7907 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7908 result.add(perm.buildPersistedPublicApiObject()); 7909 } 7910 } 7911 } 7912 } else { 7913 final int size = mGrantedUriPermissions.size(); 7914 for (int i = 0; i < size; i++) { 7915 final ArrayMap<GrantUri, UriPermission> perms = 7916 mGrantedUriPermissions.valueAt(i); 7917 for (UriPermission perm : perms.values()) { 7918 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7919 result.add(perm.buildPersistedPublicApiObject()); 7920 } 7921 } 7922 } 7923 } 7924 } 7925 return new ParceledListSlice<android.content.UriPermission>(result); 7926 } 7927 7928 @Override 7929 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7930 synchronized (this) { 7931 ProcessRecord app = 7932 who != null ? getRecordForAppLocked(who) : null; 7933 if (app == null) return; 7934 7935 Message msg = Message.obtain(); 7936 msg.what = WAIT_FOR_DEBUGGER_MSG; 7937 msg.obj = app; 7938 msg.arg1 = waiting ? 1 : 0; 7939 mHandler.sendMessage(msg); 7940 } 7941 } 7942 7943 @Override 7944 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7945 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7946 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7947 outInfo.availMem = Process.getFreeMemory(); 7948 outInfo.totalMem = Process.getTotalMemory(); 7949 outInfo.threshold = homeAppMem; 7950 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7951 outInfo.hiddenAppThreshold = cachedAppMem; 7952 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7953 ProcessList.SERVICE_ADJ); 7954 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7955 ProcessList.VISIBLE_APP_ADJ); 7956 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7957 ProcessList.FOREGROUND_APP_ADJ); 7958 } 7959 7960 // ========================================================= 7961 // TASK MANAGEMENT 7962 // ========================================================= 7963 7964 @Override 7965 public List<IAppTask> getAppTasks(String callingPackage) { 7966 int callingUid = Binder.getCallingUid(); 7967 long ident = Binder.clearCallingIdentity(); 7968 7969 synchronized(this) { 7970 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7971 try { 7972 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7973 7974 final int N = mRecentTasks.size(); 7975 for (int i = 0; i < N; i++) { 7976 TaskRecord tr = mRecentTasks.get(i); 7977 // Skip tasks that do not match the caller. We don't need to verify 7978 // callingPackage, because we are also limiting to callingUid and know 7979 // that will limit to the correct security sandbox. 7980 if (tr.effectiveUid != callingUid) { 7981 continue; 7982 } 7983 Intent intent = tr.getBaseIntent(); 7984 if (intent == null || 7985 !callingPackage.equals(intent.getComponent().getPackageName())) { 7986 continue; 7987 } 7988 ActivityManager.RecentTaskInfo taskInfo = 7989 createRecentTaskInfoFromTaskRecord(tr); 7990 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7991 list.add(taskImpl); 7992 } 7993 } finally { 7994 Binder.restoreCallingIdentity(ident); 7995 } 7996 return list; 7997 } 7998 } 7999 8000 @Override 8001 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8002 final int callingUid = Binder.getCallingUid(); 8003 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8004 8005 synchronized(this) { 8006 if (localLOGV) Slog.v( 8007 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8008 8009 final boolean allowed = checkCallingPermission( 8010 android.Manifest.permission.GET_TASKS) 8011 == PackageManager.PERMISSION_GRANTED; 8012 if (!allowed) { 8013 Slog.w(TAG, "getTasks: caller " + callingUid 8014 + " does not hold GET_TASKS; limiting output"); 8015 } 8016 8017 // TODO: Improve with MRU list from all ActivityStacks. 8018 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8019 } 8020 8021 return list; 8022 } 8023 8024 TaskRecord getMostRecentTask() { 8025 return mRecentTasks.get(0); 8026 } 8027 8028 /** 8029 * Creates a new RecentTaskInfo from a TaskRecord. 8030 */ 8031 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8032 // Update the task description to reflect any changes in the task stack 8033 tr.updateTaskDescription(); 8034 8035 // Compose the recent task info 8036 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8037 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8038 rti.persistentId = tr.taskId; 8039 rti.baseIntent = new Intent(tr.getBaseIntent()); 8040 rti.origActivity = tr.origActivity; 8041 rti.description = tr.lastDescription; 8042 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8043 rti.userId = tr.userId; 8044 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8045 rti.firstActiveTime = tr.firstActiveTime; 8046 rti.lastActiveTime = tr.lastActiveTime; 8047 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8048 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8049 return rti; 8050 } 8051 8052 @Override 8053 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8054 final int callingUid = Binder.getCallingUid(); 8055 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8056 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8057 8058 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8059 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8060 synchronized (this) { 8061 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8062 == PackageManager.PERMISSION_GRANTED; 8063 if (!allowed) { 8064 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8065 + " does not hold GET_TASKS; limiting output"); 8066 } 8067 final boolean detailed = checkCallingPermission( 8068 android.Manifest.permission.GET_DETAILED_TASKS) 8069 == PackageManager.PERMISSION_GRANTED; 8070 8071 final int N = mRecentTasks.size(); 8072 ArrayList<ActivityManager.RecentTaskInfo> res 8073 = new ArrayList<ActivityManager.RecentTaskInfo>( 8074 maxNum < N ? maxNum : N); 8075 8076 final Set<Integer> includedUsers; 8077 if (includeProfiles) { 8078 includedUsers = getProfileIdsLocked(userId); 8079 } else { 8080 includedUsers = new HashSet<Integer>(); 8081 } 8082 includedUsers.add(Integer.valueOf(userId)); 8083 8084 for (int i=0; i<N && maxNum > 0; i++) { 8085 TaskRecord tr = mRecentTasks.get(i); 8086 // Only add calling user or related users recent tasks 8087 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8088 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8089 continue; 8090 } 8091 8092 // Return the entry if desired by the caller. We always return 8093 // the first entry, because callers always expect this to be the 8094 // foreground app. We may filter others if the caller has 8095 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8096 // we should exclude the entry. 8097 8098 if (i == 0 8099 || withExcluded 8100 || (tr.intent == null) 8101 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8102 == 0)) { 8103 if (!allowed) { 8104 // If the caller doesn't have the GET_TASKS permission, then only 8105 // allow them to see a small subset of tasks -- their own and home. 8106 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8107 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8108 continue; 8109 } 8110 } 8111 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8112 if (tr.stack != null && tr.stack.isHomeStack()) { 8113 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8114 continue; 8115 } 8116 } 8117 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8118 // Don't include auto remove tasks that are finished or finishing. 8119 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8120 + tr); 8121 continue; 8122 } 8123 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8124 && !tr.isAvailable) { 8125 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8126 continue; 8127 } 8128 8129 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8130 if (!detailed) { 8131 rti.baseIntent.replaceExtras((Bundle)null); 8132 } 8133 8134 res.add(rti); 8135 maxNum--; 8136 } 8137 } 8138 return res; 8139 } 8140 } 8141 8142 private TaskRecord recentTaskForIdLocked(int id) { 8143 final int N = mRecentTasks.size(); 8144 for (int i=0; i<N; i++) { 8145 TaskRecord tr = mRecentTasks.get(i); 8146 if (tr.taskId == id) { 8147 return tr; 8148 } 8149 } 8150 return null; 8151 } 8152 8153 @Override 8154 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8155 synchronized (this) { 8156 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8157 "getTaskThumbnail()"); 8158 TaskRecord tr = recentTaskForIdLocked(id); 8159 if (tr != null) { 8160 return tr.getTaskThumbnailLocked(); 8161 } 8162 } 8163 return null; 8164 } 8165 8166 @Override 8167 public int addAppTask(IBinder activityToken, Intent intent, 8168 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8169 final int callingUid = Binder.getCallingUid(); 8170 final long callingIdent = Binder.clearCallingIdentity(); 8171 8172 try { 8173 synchronized (this) { 8174 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8175 if (r == null) { 8176 throw new IllegalArgumentException("Activity does not exist; token=" 8177 + activityToken); 8178 } 8179 ComponentName comp = intent.getComponent(); 8180 if (comp == null) { 8181 throw new IllegalArgumentException("Intent " + intent 8182 + " must specify explicit component"); 8183 } 8184 if (thumbnail.getWidth() != mThumbnailWidth 8185 || thumbnail.getHeight() != mThumbnailHeight) { 8186 throw new IllegalArgumentException("Bad thumbnail size: got " 8187 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8188 + mThumbnailWidth + "x" + mThumbnailHeight); 8189 } 8190 if (intent.getSelector() != null) { 8191 intent.setSelector(null); 8192 } 8193 if (intent.getSourceBounds() != null) { 8194 intent.setSourceBounds(null); 8195 } 8196 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8197 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8198 // The caller has added this as an auto-remove task... that makes no 8199 // sense, so turn off auto-remove. 8200 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8201 } 8202 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8203 // Must be a new task. 8204 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8205 } 8206 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8207 mLastAddedTaskActivity = null; 8208 } 8209 ActivityInfo ainfo = mLastAddedTaskActivity; 8210 if (ainfo == null) { 8211 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8212 comp, 0, UserHandle.getUserId(callingUid)); 8213 if (ainfo.applicationInfo.uid != callingUid) { 8214 throw new SecurityException( 8215 "Can't add task for another application: target uid=" 8216 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8217 } 8218 } 8219 8220 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8221 intent, description); 8222 8223 int trimIdx = trimRecentsForTask(task, false); 8224 if (trimIdx >= 0) { 8225 // If this would have caused a trim, then we'll abort because that 8226 // means it would be added at the end of the list but then just removed. 8227 return -1; 8228 } 8229 8230 final int N = mRecentTasks.size(); 8231 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8232 final TaskRecord tr = mRecentTasks.remove(N - 1); 8233 tr.removedFromRecents(mTaskPersister); 8234 } 8235 8236 task.inRecents = true; 8237 mRecentTasks.add(task); 8238 r.task.stack.addTask(task, false, false); 8239 8240 task.setLastThumbnail(thumbnail); 8241 task.freeLastThumbnail(); 8242 8243 return task.taskId; 8244 } 8245 } finally { 8246 Binder.restoreCallingIdentity(callingIdent); 8247 } 8248 } 8249 8250 @Override 8251 public Point getAppTaskThumbnailSize() { 8252 synchronized (this) { 8253 return new Point(mThumbnailWidth, mThumbnailHeight); 8254 } 8255 } 8256 8257 @Override 8258 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8259 synchronized (this) { 8260 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8261 if (r != null) { 8262 r.taskDescription = td; 8263 r.task.updateTaskDescription(); 8264 } 8265 } 8266 } 8267 8268 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8269 mRecentTasks.remove(tr); 8270 tr.removedFromRecents(mTaskPersister); 8271 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8272 Intent baseIntent = new Intent( 8273 tr.intent != null ? tr.intent : tr.affinityIntent); 8274 ComponentName component = baseIntent.getComponent(); 8275 if (component == null) { 8276 Slog.w(TAG, "Now component for base intent of task: " + tr); 8277 return; 8278 } 8279 8280 // Find any running services associated with this app. 8281 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8282 8283 if (killProcesses) { 8284 // Find any running processes associated with this app. 8285 final String pkg = component.getPackageName(); 8286 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8287 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8288 for (int i=0; i<pmap.size(); i++) { 8289 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8290 for (int j=0; j<uids.size(); j++) { 8291 ProcessRecord proc = uids.valueAt(j); 8292 if (proc.userId != tr.userId) { 8293 continue; 8294 } 8295 if (!proc.pkgList.containsKey(pkg)) { 8296 continue; 8297 } 8298 procs.add(proc); 8299 } 8300 } 8301 8302 // Kill the running processes. 8303 for (int i=0; i<procs.size(); i++) { 8304 ProcessRecord pr = procs.get(i); 8305 if (pr == mHomeProcess) { 8306 // Don't kill the home process along with tasks from the same package. 8307 continue; 8308 } 8309 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8310 pr.kill("remove task", true); 8311 } else { 8312 pr.waitingToKill = "remove task"; 8313 } 8314 } 8315 } 8316 } 8317 8318 /** 8319 * Removes the task with the specified task id. 8320 * 8321 * @param taskId Identifier of the task to be removed. 8322 * @param flags Additional operational flags. May be 0 or 8323 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8324 * @return Returns true if the given task was found and removed. 8325 */ 8326 private boolean removeTaskByIdLocked(int taskId, int flags) { 8327 TaskRecord tr = recentTaskForIdLocked(taskId); 8328 if (tr != null) { 8329 tr.removeTaskActivitiesLocked(); 8330 cleanUpRemovedTaskLocked(tr, flags); 8331 if (tr.isPersistable) { 8332 notifyTaskPersisterLocked(null, true); 8333 } 8334 return true; 8335 } 8336 return false; 8337 } 8338 8339 @Override 8340 public boolean removeTask(int taskId, int flags) { 8341 synchronized (this) { 8342 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8343 "removeTask()"); 8344 long ident = Binder.clearCallingIdentity(); 8345 try { 8346 return removeTaskByIdLocked(taskId, flags); 8347 } finally { 8348 Binder.restoreCallingIdentity(ident); 8349 } 8350 } 8351 } 8352 8353 /** 8354 * TODO: Add mController hook 8355 */ 8356 @Override 8357 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8358 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8359 "moveTaskToFront()"); 8360 8361 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8362 synchronized(this) { 8363 moveTaskToFrontLocked(taskId, flags, options); 8364 } 8365 } 8366 8367 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8368 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8369 Binder.getCallingUid(), "Task to front")) { 8370 ActivityOptions.abort(options); 8371 return; 8372 } 8373 final long origId = Binder.clearCallingIdentity(); 8374 try { 8375 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8376 if (task == null) { 8377 return; 8378 } 8379 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8380 mStackSupervisor.showLockTaskToast(); 8381 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8382 return; 8383 } 8384 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8385 if (prev != null && prev.isRecentsActivity()) { 8386 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8387 } 8388 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8389 } finally { 8390 Binder.restoreCallingIdentity(origId); 8391 } 8392 ActivityOptions.abort(options); 8393 } 8394 8395 @Override 8396 public void moveTaskToBack(int taskId) { 8397 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8398 "moveTaskToBack()"); 8399 8400 synchronized(this) { 8401 TaskRecord tr = recentTaskForIdLocked(taskId); 8402 if (tr != null) { 8403 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8404 ActivityStack stack = tr.stack; 8405 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8406 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8407 Binder.getCallingUid(), "Task to back")) { 8408 return; 8409 } 8410 } 8411 final long origId = Binder.clearCallingIdentity(); 8412 try { 8413 stack.moveTaskToBackLocked(taskId, null); 8414 } finally { 8415 Binder.restoreCallingIdentity(origId); 8416 } 8417 } 8418 } 8419 } 8420 8421 /** 8422 * Moves an activity, and all of the other activities within the same task, to the bottom 8423 * of the history stack. The activity's order within the task is unchanged. 8424 * 8425 * @param token A reference to the activity we wish to move 8426 * @param nonRoot If false then this only works if the activity is the root 8427 * of a task; if true it will work for any activity in a task. 8428 * @return Returns true if the move completed, false if not. 8429 */ 8430 @Override 8431 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8432 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8433 synchronized(this) { 8434 final long origId = Binder.clearCallingIdentity(); 8435 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8436 if (taskId >= 0) { 8437 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8438 } 8439 Binder.restoreCallingIdentity(origId); 8440 } 8441 return false; 8442 } 8443 8444 @Override 8445 public void moveTaskBackwards(int task) { 8446 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8447 "moveTaskBackwards()"); 8448 8449 synchronized(this) { 8450 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8451 Binder.getCallingUid(), "Task backwards")) { 8452 return; 8453 } 8454 final long origId = Binder.clearCallingIdentity(); 8455 moveTaskBackwardsLocked(task); 8456 Binder.restoreCallingIdentity(origId); 8457 } 8458 } 8459 8460 private final void moveTaskBackwardsLocked(int task) { 8461 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8462 } 8463 8464 @Override 8465 public IBinder getHomeActivityToken() throws RemoteException { 8466 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8467 "getHomeActivityToken()"); 8468 synchronized (this) { 8469 return mStackSupervisor.getHomeActivityToken(); 8470 } 8471 } 8472 8473 @Override 8474 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8475 IActivityContainerCallback callback) throws RemoteException { 8476 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8477 "createActivityContainer()"); 8478 synchronized (this) { 8479 if (parentActivityToken == null) { 8480 throw new IllegalArgumentException("parent token must not be null"); 8481 } 8482 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8483 if (r == null) { 8484 return null; 8485 } 8486 if (callback == null) { 8487 throw new IllegalArgumentException("callback must not be null"); 8488 } 8489 return mStackSupervisor.createActivityContainer(r, callback); 8490 } 8491 } 8492 8493 @Override 8494 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8495 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8496 "deleteActivityContainer()"); 8497 synchronized (this) { 8498 mStackSupervisor.deleteActivityContainer(container); 8499 } 8500 } 8501 8502 @Override 8503 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8504 throws RemoteException { 8505 synchronized (this) { 8506 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8507 if (stack != null) { 8508 return stack.mActivityContainer; 8509 } 8510 return null; 8511 } 8512 } 8513 8514 @Override 8515 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8516 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8517 "moveTaskToStack()"); 8518 if (stackId == HOME_STACK_ID) { 8519 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8520 new RuntimeException("here").fillInStackTrace()); 8521 } 8522 synchronized (this) { 8523 long ident = Binder.clearCallingIdentity(); 8524 try { 8525 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8526 + stackId + " toTop=" + toTop); 8527 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8528 } finally { 8529 Binder.restoreCallingIdentity(ident); 8530 } 8531 } 8532 } 8533 8534 @Override 8535 public void resizeStack(int stackBoxId, Rect bounds) { 8536 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8537 "resizeStackBox()"); 8538 long ident = Binder.clearCallingIdentity(); 8539 try { 8540 mWindowManager.resizeStack(stackBoxId, bounds); 8541 } finally { 8542 Binder.restoreCallingIdentity(ident); 8543 } 8544 } 8545 8546 @Override 8547 public List<StackInfo> getAllStackInfos() { 8548 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8549 "getAllStackInfos()"); 8550 long ident = Binder.clearCallingIdentity(); 8551 try { 8552 synchronized (this) { 8553 return mStackSupervisor.getAllStackInfosLocked(); 8554 } 8555 } finally { 8556 Binder.restoreCallingIdentity(ident); 8557 } 8558 } 8559 8560 @Override 8561 public StackInfo getStackInfo(int stackId) { 8562 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8563 "getStackInfo()"); 8564 long ident = Binder.clearCallingIdentity(); 8565 try { 8566 synchronized (this) { 8567 return mStackSupervisor.getStackInfoLocked(stackId); 8568 } 8569 } finally { 8570 Binder.restoreCallingIdentity(ident); 8571 } 8572 } 8573 8574 @Override 8575 public boolean isInHomeStack(int taskId) { 8576 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8577 "getStackInfo()"); 8578 long ident = Binder.clearCallingIdentity(); 8579 try { 8580 synchronized (this) { 8581 TaskRecord tr = recentTaskForIdLocked(taskId); 8582 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8583 } 8584 } finally { 8585 Binder.restoreCallingIdentity(ident); 8586 } 8587 } 8588 8589 @Override 8590 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8591 synchronized(this) { 8592 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8593 } 8594 } 8595 8596 private boolean isLockTaskAuthorized(String pkg) { 8597 final DevicePolicyManager dpm = (DevicePolicyManager) 8598 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8599 try { 8600 int uid = mContext.getPackageManager().getPackageUid(pkg, 8601 Binder.getCallingUserHandle().getIdentifier()); 8602 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8603 } catch (NameNotFoundException e) { 8604 return false; 8605 } 8606 } 8607 8608 void startLockTaskMode(TaskRecord task) { 8609 final String pkg; 8610 synchronized (this) { 8611 pkg = task.intent.getComponent().getPackageName(); 8612 } 8613 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8614 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8615 final TaskRecord taskRecord = task; 8616 mHandler.post(new Runnable() { 8617 @Override 8618 public void run() { 8619 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8620 } 8621 }); 8622 return; 8623 } 8624 long ident = Binder.clearCallingIdentity(); 8625 try { 8626 synchronized (this) { 8627 // Since we lost lock on task, make sure it is still there. 8628 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8629 if (task != null) { 8630 if (!isSystemInitiated 8631 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8632 throw new IllegalArgumentException("Invalid task, not in foreground"); 8633 } 8634 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8635 } 8636 } 8637 } finally { 8638 Binder.restoreCallingIdentity(ident); 8639 } 8640 } 8641 8642 @Override 8643 public void startLockTaskMode(int taskId) { 8644 final TaskRecord task; 8645 long ident = Binder.clearCallingIdentity(); 8646 try { 8647 synchronized (this) { 8648 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8649 } 8650 } finally { 8651 Binder.restoreCallingIdentity(ident); 8652 } 8653 if (task != null) { 8654 startLockTaskMode(task); 8655 } 8656 } 8657 8658 @Override 8659 public void startLockTaskMode(IBinder token) { 8660 final TaskRecord task; 8661 long ident = Binder.clearCallingIdentity(); 8662 try { 8663 synchronized (this) { 8664 final ActivityRecord r = ActivityRecord.forToken(token); 8665 if (r == null) { 8666 return; 8667 } 8668 task = r.task; 8669 } 8670 } finally { 8671 Binder.restoreCallingIdentity(ident); 8672 } 8673 if (task != null) { 8674 startLockTaskMode(task); 8675 } 8676 } 8677 8678 @Override 8679 public void startLockTaskModeOnCurrent() throws RemoteException { 8680 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8681 ActivityRecord r = null; 8682 synchronized (this) { 8683 r = mStackSupervisor.topRunningActivityLocked(); 8684 } 8685 startLockTaskMode(r.task); 8686 } 8687 8688 @Override 8689 public void stopLockTaskMode() { 8690 // Verify that the user matches the package of the intent for the TaskRecord 8691 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8692 // and stopLockTaskMode. 8693 final int callingUid = Binder.getCallingUid(); 8694 if (callingUid != Process.SYSTEM_UID) { 8695 try { 8696 String pkg = 8697 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8698 int uid = mContext.getPackageManager().getPackageUid(pkg, 8699 Binder.getCallingUserHandle().getIdentifier()); 8700 if (uid != callingUid) { 8701 throw new SecurityException("Invalid uid, expected " + uid); 8702 } 8703 } catch (NameNotFoundException e) { 8704 Log.d(TAG, "stopLockTaskMode " + e); 8705 return; 8706 } 8707 } 8708 long ident = Binder.clearCallingIdentity(); 8709 try { 8710 Log.d(TAG, "stopLockTaskMode"); 8711 // Stop lock task 8712 synchronized (this) { 8713 mStackSupervisor.setLockTaskModeLocked(null, false); 8714 } 8715 } finally { 8716 Binder.restoreCallingIdentity(ident); 8717 } 8718 } 8719 8720 @Override 8721 public void stopLockTaskModeOnCurrent() throws RemoteException { 8722 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8723 long ident = Binder.clearCallingIdentity(); 8724 try { 8725 stopLockTaskMode(); 8726 } finally { 8727 Binder.restoreCallingIdentity(ident); 8728 } 8729 } 8730 8731 @Override 8732 public boolean isInLockTaskMode() { 8733 synchronized (this) { 8734 return mStackSupervisor.isInLockTaskMode(); 8735 } 8736 } 8737 8738 // ========================================================= 8739 // CONTENT PROVIDERS 8740 // ========================================================= 8741 8742 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8743 List<ProviderInfo> providers = null; 8744 try { 8745 providers = AppGlobals.getPackageManager(). 8746 queryContentProviders(app.processName, app.uid, 8747 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8748 } catch (RemoteException ex) { 8749 } 8750 if (DEBUG_MU) 8751 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8752 int userId = app.userId; 8753 if (providers != null) { 8754 int N = providers.size(); 8755 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8756 for (int i=0; i<N; i++) { 8757 ProviderInfo cpi = 8758 (ProviderInfo)providers.get(i); 8759 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8760 cpi.name, cpi.flags); 8761 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8762 // This is a singleton provider, but a user besides the 8763 // default user is asking to initialize a process it runs 8764 // in... well, no, it doesn't actually run in this process, 8765 // it runs in the process of the default user. Get rid of it. 8766 providers.remove(i); 8767 N--; 8768 i--; 8769 continue; 8770 } 8771 8772 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8773 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8774 if (cpr == null) { 8775 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8776 mProviderMap.putProviderByClass(comp, cpr); 8777 } 8778 if (DEBUG_MU) 8779 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8780 app.pubProviders.put(cpi.name, cpr); 8781 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8782 // Don't add this if it is a platform component that is marked 8783 // to run in multiple processes, because this is actually 8784 // part of the framework so doesn't make sense to track as a 8785 // separate apk in the process. 8786 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8787 mProcessStats); 8788 } 8789 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8790 } 8791 } 8792 return providers; 8793 } 8794 8795 /** 8796 * Check if {@link ProcessRecord} has a possible chance at accessing the 8797 * given {@link ProviderInfo}. Final permission checking is always done 8798 * in {@link ContentProvider}. 8799 */ 8800 private final String checkContentProviderPermissionLocked( 8801 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8802 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8803 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8804 boolean checkedGrants = false; 8805 if (checkUser) { 8806 // Looking for cross-user grants before enforcing the typical cross-users permissions 8807 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8808 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8809 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8810 return null; 8811 } 8812 checkedGrants = true; 8813 } 8814 userId = handleIncomingUser(callingPid, callingUid, userId, 8815 false, ALLOW_NON_FULL, 8816 "checkContentProviderPermissionLocked " + cpi.authority, null); 8817 if (userId != tmpTargetUserId) { 8818 // When we actually went to determine the final targer user ID, this ended 8819 // up different than our initial check for the authority. This is because 8820 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8821 // SELF. So we need to re-check the grants again. 8822 checkedGrants = false; 8823 } 8824 } 8825 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8826 cpi.applicationInfo.uid, cpi.exported) 8827 == PackageManager.PERMISSION_GRANTED) { 8828 return null; 8829 } 8830 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8831 cpi.applicationInfo.uid, cpi.exported) 8832 == PackageManager.PERMISSION_GRANTED) { 8833 return null; 8834 } 8835 8836 PathPermission[] pps = cpi.pathPermissions; 8837 if (pps != null) { 8838 int i = pps.length; 8839 while (i > 0) { 8840 i--; 8841 PathPermission pp = pps[i]; 8842 String pprperm = pp.getReadPermission(); 8843 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8844 cpi.applicationInfo.uid, cpi.exported) 8845 == PackageManager.PERMISSION_GRANTED) { 8846 return null; 8847 } 8848 String ppwperm = pp.getWritePermission(); 8849 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8850 cpi.applicationInfo.uid, cpi.exported) 8851 == PackageManager.PERMISSION_GRANTED) { 8852 return null; 8853 } 8854 } 8855 } 8856 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8857 return null; 8858 } 8859 8860 String msg; 8861 if (!cpi.exported) { 8862 msg = "Permission Denial: opening provider " + cpi.name 8863 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8864 + ", uid=" + callingUid + ") that is not exported from uid " 8865 + cpi.applicationInfo.uid; 8866 } else { 8867 msg = "Permission Denial: opening provider " + cpi.name 8868 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8869 + ", uid=" + callingUid + ") requires " 8870 + cpi.readPermission + " or " + cpi.writePermission; 8871 } 8872 Slog.w(TAG, msg); 8873 return msg; 8874 } 8875 8876 /** 8877 * Returns if the ContentProvider has granted a uri to callingUid 8878 */ 8879 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8880 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8881 if (perms != null) { 8882 for (int i=perms.size()-1; i>=0; i--) { 8883 GrantUri grantUri = perms.keyAt(i); 8884 if (grantUri.sourceUserId == userId || !checkUser) { 8885 if (matchesProvider(grantUri.uri, cpi)) { 8886 return true; 8887 } 8888 } 8889 } 8890 } 8891 return false; 8892 } 8893 8894 /** 8895 * Returns true if the uri authority is one of the authorities specified in the provider. 8896 */ 8897 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8898 String uriAuth = uri.getAuthority(); 8899 String cpiAuth = cpi.authority; 8900 if (cpiAuth.indexOf(';') == -1) { 8901 return cpiAuth.equals(uriAuth); 8902 } 8903 String[] cpiAuths = cpiAuth.split(";"); 8904 int length = cpiAuths.length; 8905 for (int i = 0; i < length; i++) { 8906 if (cpiAuths[i].equals(uriAuth)) return true; 8907 } 8908 return false; 8909 } 8910 8911 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8912 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8913 if (r != null) { 8914 for (int i=0; i<r.conProviders.size(); i++) { 8915 ContentProviderConnection conn = r.conProviders.get(i); 8916 if (conn.provider == cpr) { 8917 if (DEBUG_PROVIDER) Slog.v(TAG, 8918 "Adding provider requested by " 8919 + r.processName + " from process " 8920 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8921 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8922 if (stable) { 8923 conn.stableCount++; 8924 conn.numStableIncs++; 8925 } else { 8926 conn.unstableCount++; 8927 conn.numUnstableIncs++; 8928 } 8929 return conn; 8930 } 8931 } 8932 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8933 if (stable) { 8934 conn.stableCount = 1; 8935 conn.numStableIncs = 1; 8936 } else { 8937 conn.unstableCount = 1; 8938 conn.numUnstableIncs = 1; 8939 } 8940 cpr.connections.add(conn); 8941 r.conProviders.add(conn); 8942 return conn; 8943 } 8944 cpr.addExternalProcessHandleLocked(externalProcessToken); 8945 return null; 8946 } 8947 8948 boolean decProviderCountLocked(ContentProviderConnection conn, 8949 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8950 if (conn != null) { 8951 cpr = conn.provider; 8952 if (DEBUG_PROVIDER) Slog.v(TAG, 8953 "Removing provider requested by " 8954 + conn.client.processName + " from process " 8955 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8956 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8957 if (stable) { 8958 conn.stableCount--; 8959 } else { 8960 conn.unstableCount--; 8961 } 8962 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8963 cpr.connections.remove(conn); 8964 conn.client.conProviders.remove(conn); 8965 return true; 8966 } 8967 return false; 8968 } 8969 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8970 return false; 8971 } 8972 8973 private void checkTime(long startTime, String where) { 8974 long now = SystemClock.elapsedRealtime(); 8975 if ((now-startTime) > 1000) { 8976 // If we are taking more than a second, log about it. 8977 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 8978 } 8979 } 8980 8981 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8982 String name, IBinder token, boolean stable, int userId) { 8983 ContentProviderRecord cpr; 8984 ContentProviderConnection conn = null; 8985 ProviderInfo cpi = null; 8986 8987 synchronized(this) { 8988 long startTime = SystemClock.elapsedRealtime(); 8989 8990 ProcessRecord r = null; 8991 if (caller != null) { 8992 r = getRecordForAppLocked(caller); 8993 if (r == null) { 8994 throw new SecurityException( 8995 "Unable to find app for caller " + caller 8996 + " (pid=" + Binder.getCallingPid() 8997 + ") when getting content provider " + name); 8998 } 8999 } 9000 9001 boolean checkCrossUser = true; 9002 9003 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9004 9005 // First check if this content provider has been published... 9006 cpr = mProviderMap.getProviderByName(name, userId); 9007 // If that didn't work, check if it exists for user 0 and then 9008 // verify that it's a singleton provider before using it. 9009 if (cpr == null && userId != UserHandle.USER_OWNER) { 9010 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9011 if (cpr != null) { 9012 cpi = cpr.info; 9013 if (isSingleton(cpi.processName, cpi.applicationInfo, 9014 cpi.name, cpi.flags) 9015 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9016 userId = UserHandle.USER_OWNER; 9017 checkCrossUser = false; 9018 } else { 9019 cpr = null; 9020 cpi = null; 9021 } 9022 } 9023 } 9024 9025 boolean providerRunning = cpr != null; 9026 if (providerRunning) { 9027 cpi = cpr.info; 9028 String msg; 9029 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9030 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9031 != null) { 9032 throw new SecurityException(msg); 9033 } 9034 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9035 9036 if (r != null && cpr.canRunHere(r)) { 9037 // This provider has been published or is in the process 9038 // of being published... but it is also allowed to run 9039 // in the caller's process, so don't make a connection 9040 // and just let the caller instantiate its own instance. 9041 ContentProviderHolder holder = cpr.newHolder(null); 9042 // don't give caller the provider object, it needs 9043 // to make its own. 9044 holder.provider = null; 9045 return holder; 9046 } 9047 9048 final long origId = Binder.clearCallingIdentity(); 9049 9050 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9051 9052 // In this case the provider instance already exists, so we can 9053 // return it right away. 9054 conn = incProviderCountLocked(r, cpr, token, stable); 9055 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9056 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9057 // If this is a perceptible app accessing the provider, 9058 // make sure to count it as being accessed and thus 9059 // back up on the LRU list. This is good because 9060 // content providers are often expensive to start. 9061 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9062 updateLruProcessLocked(cpr.proc, false, null); 9063 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9064 } 9065 } 9066 9067 if (cpr.proc != null) { 9068 if (false) { 9069 if (cpr.name.flattenToShortString().equals( 9070 "com.android.providers.calendar/.CalendarProvider2")) { 9071 Slog.v(TAG, "****************** KILLING " 9072 + cpr.name.flattenToShortString()); 9073 Process.killProcess(cpr.proc.pid); 9074 } 9075 } 9076 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9077 boolean success = updateOomAdjLocked(cpr.proc); 9078 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9079 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9080 // NOTE: there is still a race here where a signal could be 9081 // pending on the process even though we managed to update its 9082 // adj level. Not sure what to do about this, but at least 9083 // the race is now smaller. 9084 if (!success) { 9085 // Uh oh... it looks like the provider's process 9086 // has been killed on us. We need to wait for a new 9087 // process to be started, and make sure its death 9088 // doesn't kill our process. 9089 Slog.i(TAG, 9090 "Existing provider " + cpr.name.flattenToShortString() 9091 + " is crashing; detaching " + r); 9092 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9093 checkTime(startTime, "getContentProviderImpl: before appDied"); 9094 appDiedLocked(cpr.proc); 9095 checkTime(startTime, "getContentProviderImpl: after appDied"); 9096 if (!lastRef) { 9097 // This wasn't the last ref our process had on 9098 // the provider... we have now been killed, bail. 9099 return null; 9100 } 9101 providerRunning = false; 9102 conn = null; 9103 } 9104 } 9105 9106 Binder.restoreCallingIdentity(origId); 9107 } 9108 9109 boolean singleton; 9110 if (!providerRunning) { 9111 try { 9112 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9113 cpi = AppGlobals.getPackageManager(). 9114 resolveContentProvider(name, 9115 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9116 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9117 } catch (RemoteException ex) { 9118 } 9119 if (cpi == null) { 9120 return null; 9121 } 9122 // If the provider is a singleton AND 9123 // (it's a call within the same user || the provider is a 9124 // privileged app) 9125 // Then allow connecting to the singleton provider 9126 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9127 cpi.name, cpi.flags) 9128 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9129 if (singleton) { 9130 userId = UserHandle.USER_OWNER; 9131 } 9132 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9133 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9134 9135 String msg; 9136 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9137 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9138 != null) { 9139 throw new SecurityException(msg); 9140 } 9141 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9142 9143 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9144 && !cpi.processName.equals("system")) { 9145 // If this content provider does not run in the system 9146 // process, and the system is not yet ready to run other 9147 // processes, then fail fast instead of hanging. 9148 throw new IllegalArgumentException( 9149 "Attempt to launch content provider before system ready"); 9150 } 9151 9152 // Make sure that the user who owns this provider is started. If not, 9153 // we don't want to allow it to run. 9154 if (mStartedUsers.get(userId) == null) { 9155 Slog.w(TAG, "Unable to launch app " 9156 + cpi.applicationInfo.packageName + "/" 9157 + cpi.applicationInfo.uid + " for provider " 9158 + name + ": user " + userId + " is stopped"); 9159 return null; 9160 } 9161 9162 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9163 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9164 cpr = mProviderMap.getProviderByClass(comp, userId); 9165 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9166 final boolean firstClass = cpr == null; 9167 if (firstClass) { 9168 try { 9169 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9170 ApplicationInfo ai = 9171 AppGlobals.getPackageManager(). 9172 getApplicationInfo( 9173 cpi.applicationInfo.packageName, 9174 STOCK_PM_FLAGS, userId); 9175 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9176 if (ai == null) { 9177 Slog.w(TAG, "No package info for content provider " 9178 + cpi.name); 9179 return null; 9180 } 9181 ai = getAppInfoForUser(ai, userId); 9182 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9183 } catch (RemoteException ex) { 9184 // pm is in same process, this will never happen. 9185 } 9186 } 9187 9188 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9189 9190 if (r != null && cpr.canRunHere(r)) { 9191 // If this is a multiprocess provider, then just return its 9192 // info and allow the caller to instantiate it. Only do 9193 // this if the provider is the same user as the caller's 9194 // process, or can run as root (so can be in any process). 9195 return cpr.newHolder(null); 9196 } 9197 9198 if (DEBUG_PROVIDER) { 9199 RuntimeException e = new RuntimeException("here"); 9200 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9201 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9202 } 9203 9204 // This is single process, and our app is now connecting to it. 9205 // See if we are already in the process of launching this 9206 // provider. 9207 final int N = mLaunchingProviders.size(); 9208 int i; 9209 for (i=0; i<N; i++) { 9210 if (mLaunchingProviders.get(i) == cpr) { 9211 break; 9212 } 9213 } 9214 9215 // If the provider is not already being launched, then get it 9216 // started. 9217 if (i >= N) { 9218 final long origId = Binder.clearCallingIdentity(); 9219 9220 try { 9221 // Content provider is now in use, its package can't be stopped. 9222 try { 9223 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9224 AppGlobals.getPackageManager().setPackageStoppedState( 9225 cpr.appInfo.packageName, false, userId); 9226 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9227 } catch (RemoteException e) { 9228 } catch (IllegalArgumentException e) { 9229 Slog.w(TAG, "Failed trying to unstop package " 9230 + cpr.appInfo.packageName + ": " + e); 9231 } 9232 9233 // Use existing process if already started 9234 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9235 ProcessRecord proc = getProcessRecordLocked( 9236 cpi.processName, cpr.appInfo.uid, false); 9237 if (proc != null && proc.thread != null) { 9238 if (DEBUG_PROVIDER) { 9239 Slog.d(TAG, "Installing in existing process " + proc); 9240 } 9241 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9242 proc.pubProviders.put(cpi.name, cpr); 9243 try { 9244 proc.thread.scheduleInstallProvider(cpi); 9245 } catch (RemoteException e) { 9246 } 9247 } else { 9248 checkTime(startTime, "getContentProviderImpl: before start process"); 9249 proc = startProcessLocked(cpi.processName, 9250 cpr.appInfo, false, 0, "content provider", 9251 new ComponentName(cpi.applicationInfo.packageName, 9252 cpi.name), false, false, false); 9253 checkTime(startTime, "getContentProviderImpl: after start process"); 9254 if (proc == null) { 9255 Slog.w(TAG, "Unable to launch app " 9256 + cpi.applicationInfo.packageName + "/" 9257 + cpi.applicationInfo.uid + " for provider " 9258 + name + ": process is bad"); 9259 return null; 9260 } 9261 } 9262 cpr.launchingApp = proc; 9263 mLaunchingProviders.add(cpr); 9264 } finally { 9265 Binder.restoreCallingIdentity(origId); 9266 } 9267 } 9268 9269 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9270 9271 // Make sure the provider is published (the same provider class 9272 // may be published under multiple names). 9273 if (firstClass) { 9274 mProviderMap.putProviderByClass(comp, cpr); 9275 } 9276 9277 mProviderMap.putProviderByName(name, cpr); 9278 conn = incProviderCountLocked(r, cpr, token, stable); 9279 if (conn != null) { 9280 conn.waiting = true; 9281 } 9282 } 9283 checkTime(startTime, "getContentProviderImpl: done!"); 9284 } 9285 9286 // Wait for the provider to be published... 9287 synchronized (cpr) { 9288 while (cpr.provider == null) { 9289 if (cpr.launchingApp == null) { 9290 Slog.w(TAG, "Unable to launch app " 9291 + cpi.applicationInfo.packageName + "/" 9292 + cpi.applicationInfo.uid + " for provider " 9293 + name + ": launching app became null"); 9294 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9295 UserHandle.getUserId(cpi.applicationInfo.uid), 9296 cpi.applicationInfo.packageName, 9297 cpi.applicationInfo.uid, name); 9298 return null; 9299 } 9300 try { 9301 if (DEBUG_MU) { 9302 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9303 + cpr.launchingApp); 9304 } 9305 if (conn != null) { 9306 conn.waiting = true; 9307 } 9308 cpr.wait(); 9309 } catch (InterruptedException ex) { 9310 } finally { 9311 if (conn != null) { 9312 conn.waiting = false; 9313 } 9314 } 9315 } 9316 } 9317 return cpr != null ? cpr.newHolder(conn) : null; 9318 } 9319 9320 @Override 9321 public final ContentProviderHolder getContentProvider( 9322 IApplicationThread caller, String name, int userId, boolean stable) { 9323 enforceNotIsolatedCaller("getContentProvider"); 9324 if (caller == null) { 9325 String msg = "null IApplicationThread when getting content provider " 9326 + name; 9327 Slog.w(TAG, msg); 9328 throw new SecurityException(msg); 9329 } 9330 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9331 // with cross-user grant. 9332 return getContentProviderImpl(caller, name, null, stable, userId); 9333 } 9334 9335 public ContentProviderHolder getContentProviderExternal( 9336 String name, int userId, IBinder token) { 9337 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9338 "Do not have permission in call getContentProviderExternal()"); 9339 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9340 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9341 return getContentProviderExternalUnchecked(name, token, userId); 9342 } 9343 9344 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9345 IBinder token, int userId) { 9346 return getContentProviderImpl(null, name, token, true, userId); 9347 } 9348 9349 /** 9350 * Drop a content provider from a ProcessRecord's bookkeeping 9351 */ 9352 public void removeContentProvider(IBinder connection, boolean stable) { 9353 enforceNotIsolatedCaller("removeContentProvider"); 9354 long ident = Binder.clearCallingIdentity(); 9355 try { 9356 synchronized (this) { 9357 ContentProviderConnection conn; 9358 try { 9359 conn = (ContentProviderConnection)connection; 9360 } catch (ClassCastException e) { 9361 String msg ="removeContentProvider: " + connection 9362 + " not a ContentProviderConnection"; 9363 Slog.w(TAG, msg); 9364 throw new IllegalArgumentException(msg); 9365 } 9366 if (conn == null) { 9367 throw new NullPointerException("connection is null"); 9368 } 9369 if (decProviderCountLocked(conn, null, null, stable)) { 9370 updateOomAdjLocked(); 9371 } 9372 } 9373 } finally { 9374 Binder.restoreCallingIdentity(ident); 9375 } 9376 } 9377 9378 public void removeContentProviderExternal(String name, IBinder token) { 9379 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9380 "Do not have permission in call removeContentProviderExternal()"); 9381 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9382 } 9383 9384 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9385 synchronized (this) { 9386 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9387 if(cpr == null) { 9388 //remove from mProvidersByClass 9389 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9390 return; 9391 } 9392 9393 //update content provider record entry info 9394 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9395 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9396 if (localCpr.hasExternalProcessHandles()) { 9397 if (localCpr.removeExternalProcessHandleLocked(token)) { 9398 updateOomAdjLocked(); 9399 } else { 9400 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9401 + " with no external reference for token: " 9402 + token + "."); 9403 } 9404 } else { 9405 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9406 + " with no external references."); 9407 } 9408 } 9409 } 9410 9411 public final void publishContentProviders(IApplicationThread caller, 9412 List<ContentProviderHolder> providers) { 9413 if (providers == null) { 9414 return; 9415 } 9416 9417 enforceNotIsolatedCaller("publishContentProviders"); 9418 synchronized (this) { 9419 final ProcessRecord r = getRecordForAppLocked(caller); 9420 if (DEBUG_MU) 9421 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9422 if (r == null) { 9423 throw new SecurityException( 9424 "Unable to find app for caller " + caller 9425 + " (pid=" + Binder.getCallingPid() 9426 + ") when publishing content providers"); 9427 } 9428 9429 final long origId = Binder.clearCallingIdentity(); 9430 9431 final int N = providers.size(); 9432 for (int i=0; i<N; i++) { 9433 ContentProviderHolder src = providers.get(i); 9434 if (src == null || src.info == null || src.provider == null) { 9435 continue; 9436 } 9437 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9438 if (DEBUG_MU) 9439 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9440 if (dst != null) { 9441 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9442 mProviderMap.putProviderByClass(comp, dst); 9443 String names[] = dst.info.authority.split(";"); 9444 for (int j = 0; j < names.length; j++) { 9445 mProviderMap.putProviderByName(names[j], dst); 9446 } 9447 9448 int NL = mLaunchingProviders.size(); 9449 int j; 9450 for (j=0; j<NL; j++) { 9451 if (mLaunchingProviders.get(j) == dst) { 9452 mLaunchingProviders.remove(j); 9453 j--; 9454 NL--; 9455 } 9456 } 9457 synchronized (dst) { 9458 dst.provider = src.provider; 9459 dst.proc = r; 9460 dst.notifyAll(); 9461 } 9462 updateOomAdjLocked(r); 9463 } 9464 } 9465 9466 Binder.restoreCallingIdentity(origId); 9467 } 9468 } 9469 9470 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9471 ContentProviderConnection conn; 9472 try { 9473 conn = (ContentProviderConnection)connection; 9474 } catch (ClassCastException e) { 9475 String msg ="refContentProvider: " + connection 9476 + " not a ContentProviderConnection"; 9477 Slog.w(TAG, msg); 9478 throw new IllegalArgumentException(msg); 9479 } 9480 if (conn == null) { 9481 throw new NullPointerException("connection is null"); 9482 } 9483 9484 synchronized (this) { 9485 if (stable > 0) { 9486 conn.numStableIncs += stable; 9487 } 9488 stable = conn.stableCount + stable; 9489 if (stable < 0) { 9490 throw new IllegalStateException("stableCount < 0: " + stable); 9491 } 9492 9493 if (unstable > 0) { 9494 conn.numUnstableIncs += unstable; 9495 } 9496 unstable = conn.unstableCount + unstable; 9497 if (unstable < 0) { 9498 throw new IllegalStateException("unstableCount < 0: " + unstable); 9499 } 9500 9501 if ((stable+unstable) <= 0) { 9502 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9503 + stable + " unstable=" + unstable); 9504 } 9505 conn.stableCount = stable; 9506 conn.unstableCount = unstable; 9507 return !conn.dead; 9508 } 9509 } 9510 9511 public void unstableProviderDied(IBinder connection) { 9512 ContentProviderConnection conn; 9513 try { 9514 conn = (ContentProviderConnection)connection; 9515 } catch (ClassCastException e) { 9516 String msg ="refContentProvider: " + connection 9517 + " not a ContentProviderConnection"; 9518 Slog.w(TAG, msg); 9519 throw new IllegalArgumentException(msg); 9520 } 9521 if (conn == null) { 9522 throw new NullPointerException("connection is null"); 9523 } 9524 9525 // Safely retrieve the content provider associated with the connection. 9526 IContentProvider provider; 9527 synchronized (this) { 9528 provider = conn.provider.provider; 9529 } 9530 9531 if (provider == null) { 9532 // Um, yeah, we're way ahead of you. 9533 return; 9534 } 9535 9536 // Make sure the caller is being honest with us. 9537 if (provider.asBinder().pingBinder()) { 9538 // Er, no, still looks good to us. 9539 synchronized (this) { 9540 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9541 + " says " + conn + " died, but we don't agree"); 9542 return; 9543 } 9544 } 9545 9546 // Well look at that! It's dead! 9547 synchronized (this) { 9548 if (conn.provider.provider != provider) { 9549 // But something changed... good enough. 9550 return; 9551 } 9552 9553 ProcessRecord proc = conn.provider.proc; 9554 if (proc == null || proc.thread == null) { 9555 // Seems like the process is already cleaned up. 9556 return; 9557 } 9558 9559 // As far as we're concerned, this is just like receiving a 9560 // death notification... just a bit prematurely. 9561 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9562 + ") early provider death"); 9563 final long ident = Binder.clearCallingIdentity(); 9564 try { 9565 appDiedLocked(proc); 9566 } finally { 9567 Binder.restoreCallingIdentity(ident); 9568 } 9569 } 9570 } 9571 9572 @Override 9573 public void appNotRespondingViaProvider(IBinder connection) { 9574 enforceCallingPermission( 9575 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9576 9577 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9578 if (conn == null) { 9579 Slog.w(TAG, "ContentProviderConnection is null"); 9580 return; 9581 } 9582 9583 final ProcessRecord host = conn.provider.proc; 9584 if (host == null) { 9585 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9586 return; 9587 } 9588 9589 final long token = Binder.clearCallingIdentity(); 9590 try { 9591 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9592 } finally { 9593 Binder.restoreCallingIdentity(token); 9594 } 9595 } 9596 9597 public final void installSystemProviders() { 9598 List<ProviderInfo> providers; 9599 synchronized (this) { 9600 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9601 providers = generateApplicationProvidersLocked(app); 9602 if (providers != null) { 9603 for (int i=providers.size()-1; i>=0; i--) { 9604 ProviderInfo pi = (ProviderInfo)providers.get(i); 9605 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9606 Slog.w(TAG, "Not installing system proc provider " + pi.name 9607 + ": not system .apk"); 9608 providers.remove(i); 9609 } 9610 } 9611 } 9612 } 9613 if (providers != null) { 9614 mSystemThread.installSystemProviders(providers); 9615 } 9616 9617 mCoreSettingsObserver = new CoreSettingsObserver(this); 9618 9619 //mUsageStatsService.monitorPackages(); 9620 } 9621 9622 /** 9623 * Allows apps to retrieve the MIME type of a URI. 9624 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9625 * users, then it does not need permission to access the ContentProvider. 9626 * Either, it needs cross-user uri grants. 9627 * 9628 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9629 * 9630 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9631 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9632 */ 9633 public String getProviderMimeType(Uri uri, int userId) { 9634 enforceNotIsolatedCaller("getProviderMimeType"); 9635 final String name = uri.getAuthority(); 9636 int callingUid = Binder.getCallingUid(); 9637 int callingPid = Binder.getCallingPid(); 9638 long ident = 0; 9639 boolean clearedIdentity = false; 9640 userId = unsafeConvertIncomingUser(userId); 9641 if (UserHandle.getUserId(callingUid) != userId) { 9642 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9643 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9644 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9645 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9646 clearedIdentity = true; 9647 ident = Binder.clearCallingIdentity(); 9648 } 9649 } 9650 ContentProviderHolder holder = null; 9651 try { 9652 holder = getContentProviderExternalUnchecked(name, null, userId); 9653 if (holder != null) { 9654 return holder.provider.getType(uri); 9655 } 9656 } catch (RemoteException e) { 9657 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9658 return null; 9659 } finally { 9660 // We need to clear the identity to call removeContentProviderExternalUnchecked 9661 if (!clearedIdentity) { 9662 ident = Binder.clearCallingIdentity(); 9663 } 9664 try { 9665 if (holder != null) { 9666 removeContentProviderExternalUnchecked(name, null, userId); 9667 } 9668 } finally { 9669 Binder.restoreCallingIdentity(ident); 9670 } 9671 } 9672 9673 return null; 9674 } 9675 9676 // ========================================================= 9677 // GLOBAL MANAGEMENT 9678 // ========================================================= 9679 9680 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9681 boolean isolated, int isolatedUid) { 9682 String proc = customProcess != null ? customProcess : info.processName; 9683 BatteryStatsImpl.Uid.Proc ps = null; 9684 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9685 int uid = info.uid; 9686 if (isolated) { 9687 if (isolatedUid == 0) { 9688 int userId = UserHandle.getUserId(uid); 9689 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9690 while (true) { 9691 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9692 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9693 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9694 } 9695 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9696 mNextIsolatedProcessUid++; 9697 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9698 // No process for this uid, use it. 9699 break; 9700 } 9701 stepsLeft--; 9702 if (stepsLeft <= 0) { 9703 return null; 9704 } 9705 } 9706 } else { 9707 // Special case for startIsolatedProcess (internal only), where 9708 // the uid of the isolated process is specified by the caller. 9709 uid = isolatedUid; 9710 } 9711 } 9712 return new ProcessRecord(stats, info, proc, uid); 9713 } 9714 9715 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9716 String abiOverride) { 9717 ProcessRecord app; 9718 if (!isolated) { 9719 app = getProcessRecordLocked(info.processName, info.uid, true); 9720 } else { 9721 app = null; 9722 } 9723 9724 if (app == null) { 9725 app = newProcessRecordLocked(info, null, isolated, 0); 9726 mProcessNames.put(info.processName, app.uid, app); 9727 if (isolated) { 9728 mIsolatedProcesses.put(app.uid, app); 9729 } 9730 updateLruProcessLocked(app, false, null); 9731 updateOomAdjLocked(); 9732 } 9733 9734 // This package really, really can not be stopped. 9735 try { 9736 AppGlobals.getPackageManager().setPackageStoppedState( 9737 info.packageName, false, UserHandle.getUserId(app.uid)); 9738 } catch (RemoteException e) { 9739 } catch (IllegalArgumentException e) { 9740 Slog.w(TAG, "Failed trying to unstop package " 9741 + info.packageName + ": " + e); 9742 } 9743 9744 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9745 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9746 app.persistent = true; 9747 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9748 } 9749 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9750 mPersistentStartingProcesses.add(app); 9751 startProcessLocked(app, "added application", app.processName, abiOverride, 9752 null /* entryPoint */, null /* entryPointArgs */); 9753 } 9754 9755 return app; 9756 } 9757 9758 public void unhandledBack() { 9759 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9760 "unhandledBack()"); 9761 9762 synchronized(this) { 9763 final long origId = Binder.clearCallingIdentity(); 9764 try { 9765 getFocusedStack().unhandledBackLocked(); 9766 } finally { 9767 Binder.restoreCallingIdentity(origId); 9768 } 9769 } 9770 } 9771 9772 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9773 enforceNotIsolatedCaller("openContentUri"); 9774 final int userId = UserHandle.getCallingUserId(); 9775 String name = uri.getAuthority(); 9776 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9777 ParcelFileDescriptor pfd = null; 9778 if (cph != null) { 9779 // We record the binder invoker's uid in thread-local storage before 9780 // going to the content provider to open the file. Later, in the code 9781 // that handles all permissions checks, we look for this uid and use 9782 // that rather than the Activity Manager's own uid. The effect is that 9783 // we do the check against the caller's permissions even though it looks 9784 // to the content provider like the Activity Manager itself is making 9785 // the request. 9786 sCallerIdentity.set(new Identity( 9787 Binder.getCallingPid(), Binder.getCallingUid())); 9788 try { 9789 pfd = cph.provider.openFile(null, uri, "r", null); 9790 } catch (FileNotFoundException e) { 9791 // do nothing; pfd will be returned null 9792 } finally { 9793 // Ensure that whatever happens, we clean up the identity state 9794 sCallerIdentity.remove(); 9795 } 9796 9797 // We've got the fd now, so we're done with the provider. 9798 removeContentProviderExternalUnchecked(name, null, userId); 9799 } else { 9800 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9801 } 9802 return pfd; 9803 } 9804 9805 // Actually is sleeping or shutting down or whatever else in the future 9806 // is an inactive state. 9807 public boolean isSleepingOrShuttingDown() { 9808 return mSleeping || mShuttingDown; 9809 } 9810 9811 public boolean isSleeping() { 9812 return mSleeping; 9813 } 9814 9815 void goingToSleep() { 9816 synchronized(this) { 9817 mWentToSleep = true; 9818 updateEventDispatchingLocked(); 9819 goToSleepIfNeededLocked(); 9820 } 9821 } 9822 9823 void finishRunningVoiceLocked() { 9824 if (mRunningVoice) { 9825 mRunningVoice = false; 9826 goToSleepIfNeededLocked(); 9827 } 9828 } 9829 9830 void goToSleepIfNeededLocked() { 9831 if (mWentToSleep && !mRunningVoice) { 9832 if (!mSleeping) { 9833 mSleeping = true; 9834 mStackSupervisor.goingToSleepLocked(); 9835 9836 // Initialize the wake times of all processes. 9837 checkExcessivePowerUsageLocked(false); 9838 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9839 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9840 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9841 } 9842 } 9843 } 9844 9845 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9846 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9847 // Never persist the home stack. 9848 return; 9849 } 9850 mTaskPersister.wakeup(task, flush); 9851 } 9852 9853 @Override 9854 public boolean shutdown(int timeout) { 9855 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9856 != PackageManager.PERMISSION_GRANTED) { 9857 throw new SecurityException("Requires permission " 9858 + android.Manifest.permission.SHUTDOWN); 9859 } 9860 9861 boolean timedout = false; 9862 9863 synchronized(this) { 9864 mShuttingDown = true; 9865 updateEventDispatchingLocked(); 9866 timedout = mStackSupervisor.shutdownLocked(timeout); 9867 } 9868 9869 mAppOpsService.shutdown(); 9870 if (mUsageStatsService != null) { 9871 mUsageStatsService.prepareShutdown(); 9872 } 9873 mBatteryStatsService.shutdown(); 9874 synchronized (this) { 9875 mProcessStats.shutdownLocked(); 9876 } 9877 notifyTaskPersisterLocked(null, true); 9878 9879 return timedout; 9880 } 9881 9882 public final void activitySlept(IBinder token) { 9883 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9884 9885 final long origId = Binder.clearCallingIdentity(); 9886 9887 synchronized (this) { 9888 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9889 if (r != null) { 9890 mStackSupervisor.activitySleptLocked(r); 9891 } 9892 } 9893 9894 Binder.restoreCallingIdentity(origId); 9895 } 9896 9897 void logLockScreen(String msg) { 9898 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9899 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9900 mWentToSleep + " mSleeping=" + mSleeping); 9901 } 9902 9903 private void comeOutOfSleepIfNeededLocked() { 9904 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9905 if (mSleeping) { 9906 mSleeping = false; 9907 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9908 } 9909 } 9910 } 9911 9912 void wakingUp() { 9913 synchronized(this) { 9914 mWentToSleep = false; 9915 updateEventDispatchingLocked(); 9916 comeOutOfSleepIfNeededLocked(); 9917 } 9918 } 9919 9920 void startRunningVoiceLocked() { 9921 if (!mRunningVoice) { 9922 mRunningVoice = true; 9923 comeOutOfSleepIfNeededLocked(); 9924 } 9925 } 9926 9927 private void updateEventDispatchingLocked() { 9928 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9929 } 9930 9931 public void setLockScreenShown(boolean shown) { 9932 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9933 != PackageManager.PERMISSION_GRANTED) { 9934 throw new SecurityException("Requires permission " 9935 + android.Manifest.permission.DEVICE_POWER); 9936 } 9937 9938 synchronized(this) { 9939 long ident = Binder.clearCallingIdentity(); 9940 try { 9941 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9942 mLockScreenShown = shown; 9943 comeOutOfSleepIfNeededLocked(); 9944 } finally { 9945 Binder.restoreCallingIdentity(ident); 9946 } 9947 } 9948 } 9949 9950 @Override 9951 public void stopAppSwitches() { 9952 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9953 != PackageManager.PERMISSION_GRANTED) { 9954 throw new SecurityException("Requires permission " 9955 + android.Manifest.permission.STOP_APP_SWITCHES); 9956 } 9957 9958 synchronized(this) { 9959 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9960 + APP_SWITCH_DELAY_TIME; 9961 mDidAppSwitch = false; 9962 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9963 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9964 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9965 } 9966 } 9967 9968 public void resumeAppSwitches() { 9969 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9970 != PackageManager.PERMISSION_GRANTED) { 9971 throw new SecurityException("Requires permission " 9972 + android.Manifest.permission.STOP_APP_SWITCHES); 9973 } 9974 9975 synchronized(this) { 9976 // Note that we don't execute any pending app switches... we will 9977 // let those wait until either the timeout, or the next start 9978 // activity request. 9979 mAppSwitchesAllowedTime = 0; 9980 } 9981 } 9982 9983 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9984 String name) { 9985 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9986 return true; 9987 } 9988 9989 final int perm = checkComponentPermission( 9990 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9991 callingUid, -1, true); 9992 if (perm == PackageManager.PERMISSION_GRANTED) { 9993 return true; 9994 } 9995 9996 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9997 return false; 9998 } 9999 10000 public void setDebugApp(String packageName, boolean waitForDebugger, 10001 boolean persistent) { 10002 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10003 "setDebugApp()"); 10004 10005 long ident = Binder.clearCallingIdentity(); 10006 try { 10007 // Note that this is not really thread safe if there are multiple 10008 // callers into it at the same time, but that's not a situation we 10009 // care about. 10010 if (persistent) { 10011 final ContentResolver resolver = mContext.getContentResolver(); 10012 Settings.Global.putString( 10013 resolver, Settings.Global.DEBUG_APP, 10014 packageName); 10015 Settings.Global.putInt( 10016 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10017 waitForDebugger ? 1 : 0); 10018 } 10019 10020 synchronized (this) { 10021 if (!persistent) { 10022 mOrigDebugApp = mDebugApp; 10023 mOrigWaitForDebugger = mWaitForDebugger; 10024 } 10025 mDebugApp = packageName; 10026 mWaitForDebugger = waitForDebugger; 10027 mDebugTransient = !persistent; 10028 if (packageName != null) { 10029 forceStopPackageLocked(packageName, -1, false, false, true, true, 10030 false, UserHandle.USER_ALL, "set debug app"); 10031 } 10032 } 10033 } finally { 10034 Binder.restoreCallingIdentity(ident); 10035 } 10036 } 10037 10038 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10039 synchronized (this) { 10040 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10041 if (!isDebuggable) { 10042 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10043 throw new SecurityException("Process not debuggable: " + app.packageName); 10044 } 10045 } 10046 10047 mOpenGlTraceApp = processName; 10048 } 10049 } 10050 10051 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10052 synchronized (this) { 10053 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10054 if (!isDebuggable) { 10055 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10056 throw new SecurityException("Process not debuggable: " + app.packageName); 10057 } 10058 } 10059 mProfileApp = processName; 10060 mProfileFile = profilerInfo.profileFile; 10061 if (mProfileFd != null) { 10062 try { 10063 mProfileFd.close(); 10064 } catch (IOException e) { 10065 } 10066 mProfileFd = null; 10067 } 10068 mProfileFd = profilerInfo.profileFd; 10069 mSamplingInterval = profilerInfo.samplingInterval; 10070 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10071 mProfileType = 0; 10072 } 10073 } 10074 10075 @Override 10076 public void setAlwaysFinish(boolean enabled) { 10077 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10078 "setAlwaysFinish()"); 10079 10080 Settings.Global.putInt( 10081 mContext.getContentResolver(), 10082 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10083 10084 synchronized (this) { 10085 mAlwaysFinishActivities = enabled; 10086 } 10087 } 10088 10089 @Override 10090 public void setActivityController(IActivityController controller) { 10091 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10092 "setActivityController()"); 10093 synchronized (this) { 10094 mController = controller; 10095 Watchdog.getInstance().setActivityController(controller); 10096 } 10097 } 10098 10099 @Override 10100 public void setUserIsMonkey(boolean userIsMonkey) { 10101 synchronized (this) { 10102 synchronized (mPidsSelfLocked) { 10103 final int callingPid = Binder.getCallingPid(); 10104 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10105 if (precessRecord == null) { 10106 throw new SecurityException("Unknown process: " + callingPid); 10107 } 10108 if (precessRecord.instrumentationUiAutomationConnection == null) { 10109 throw new SecurityException("Only an instrumentation process " 10110 + "with a UiAutomation can call setUserIsMonkey"); 10111 } 10112 } 10113 mUserIsMonkey = userIsMonkey; 10114 } 10115 } 10116 10117 @Override 10118 public boolean isUserAMonkey() { 10119 synchronized (this) { 10120 // If there is a controller also implies the user is a monkey. 10121 return (mUserIsMonkey || mController != null); 10122 } 10123 } 10124 10125 public void requestBugReport() { 10126 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10127 SystemProperties.set("ctl.start", "bugreport"); 10128 } 10129 10130 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10131 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10132 } 10133 10134 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10135 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10136 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10137 } 10138 return KEY_DISPATCHING_TIMEOUT; 10139 } 10140 10141 @Override 10142 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10143 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10144 != PackageManager.PERMISSION_GRANTED) { 10145 throw new SecurityException("Requires permission " 10146 + android.Manifest.permission.FILTER_EVENTS); 10147 } 10148 ProcessRecord proc; 10149 long timeout; 10150 synchronized (this) { 10151 synchronized (mPidsSelfLocked) { 10152 proc = mPidsSelfLocked.get(pid); 10153 } 10154 timeout = getInputDispatchingTimeoutLocked(proc); 10155 } 10156 10157 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10158 return -1; 10159 } 10160 10161 return timeout; 10162 } 10163 10164 /** 10165 * Handle input dispatching timeouts. 10166 * Returns whether input dispatching should be aborted or not. 10167 */ 10168 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10169 final ActivityRecord activity, final ActivityRecord parent, 10170 final boolean aboveSystem, String reason) { 10171 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10172 != PackageManager.PERMISSION_GRANTED) { 10173 throw new SecurityException("Requires permission " 10174 + android.Manifest.permission.FILTER_EVENTS); 10175 } 10176 10177 final String annotation; 10178 if (reason == null) { 10179 annotation = "Input dispatching timed out"; 10180 } else { 10181 annotation = "Input dispatching timed out (" + reason + ")"; 10182 } 10183 10184 if (proc != null) { 10185 synchronized (this) { 10186 if (proc.debugging) { 10187 return false; 10188 } 10189 10190 if (mDidDexOpt) { 10191 // Give more time since we were dexopting. 10192 mDidDexOpt = false; 10193 return false; 10194 } 10195 10196 if (proc.instrumentationClass != null) { 10197 Bundle info = new Bundle(); 10198 info.putString("shortMsg", "keyDispatchingTimedOut"); 10199 info.putString("longMsg", annotation); 10200 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10201 return true; 10202 } 10203 } 10204 mHandler.post(new Runnable() { 10205 @Override 10206 public void run() { 10207 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10208 } 10209 }); 10210 } 10211 10212 return true; 10213 } 10214 10215 public Bundle getAssistContextExtras(int requestType) { 10216 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10217 "getAssistContextExtras()"); 10218 PendingAssistExtras pae; 10219 Bundle extras = new Bundle(); 10220 synchronized (this) { 10221 ActivityRecord activity = getFocusedStack().mResumedActivity; 10222 if (activity == null) { 10223 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10224 return null; 10225 } 10226 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10227 if (activity.app == null || activity.app.thread == null) { 10228 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10229 return extras; 10230 } 10231 if (activity.app.pid == Binder.getCallingPid()) { 10232 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10233 return extras; 10234 } 10235 pae = new PendingAssistExtras(activity); 10236 try { 10237 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10238 requestType); 10239 mPendingAssistExtras.add(pae); 10240 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10241 } catch (RemoteException e) { 10242 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10243 return extras; 10244 } 10245 } 10246 synchronized (pae) { 10247 while (!pae.haveResult) { 10248 try { 10249 pae.wait(); 10250 } catch (InterruptedException e) { 10251 } 10252 } 10253 if (pae.result != null) { 10254 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10255 } 10256 } 10257 synchronized (this) { 10258 mPendingAssistExtras.remove(pae); 10259 mHandler.removeCallbacks(pae); 10260 } 10261 return extras; 10262 } 10263 10264 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10265 PendingAssistExtras pae = (PendingAssistExtras)token; 10266 synchronized (pae) { 10267 pae.result = extras; 10268 pae.haveResult = true; 10269 pae.notifyAll(); 10270 } 10271 } 10272 10273 public void registerProcessObserver(IProcessObserver observer) { 10274 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10275 "registerProcessObserver()"); 10276 synchronized (this) { 10277 mProcessObservers.register(observer); 10278 } 10279 } 10280 10281 @Override 10282 public void unregisterProcessObserver(IProcessObserver observer) { 10283 synchronized (this) { 10284 mProcessObservers.unregister(observer); 10285 } 10286 } 10287 10288 @Override 10289 public boolean convertFromTranslucent(IBinder token) { 10290 final long origId = Binder.clearCallingIdentity(); 10291 try { 10292 synchronized (this) { 10293 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10294 if (r == null) { 10295 return false; 10296 } 10297 if (r.changeWindowTranslucency(true)) { 10298 mWindowManager.setAppFullscreen(token, true); 10299 r.task.stack.releaseBackgroundResources(); 10300 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10301 return true; 10302 } 10303 return false; 10304 } 10305 } finally { 10306 Binder.restoreCallingIdentity(origId); 10307 } 10308 } 10309 10310 @Override 10311 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10312 final long origId = Binder.clearCallingIdentity(); 10313 try { 10314 synchronized (this) { 10315 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10316 if (r == null) { 10317 return false; 10318 } 10319 int index = r.task.mActivities.lastIndexOf(r); 10320 if (index > 0) { 10321 ActivityRecord under = r.task.mActivities.get(index - 1); 10322 under.returningOptions = options; 10323 } 10324 if (r.changeWindowTranslucency(false)) { 10325 r.task.stack.convertToTranslucent(r); 10326 mWindowManager.setAppFullscreen(token, false); 10327 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10328 return true; 10329 } else { 10330 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10331 return false; 10332 } 10333 } 10334 } finally { 10335 Binder.restoreCallingIdentity(origId); 10336 } 10337 } 10338 10339 @Override 10340 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10341 final long origId = Binder.clearCallingIdentity(); 10342 try { 10343 synchronized (this) { 10344 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10345 if (r != null) { 10346 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10347 } 10348 } 10349 return false; 10350 } finally { 10351 Binder.restoreCallingIdentity(origId); 10352 } 10353 } 10354 10355 @Override 10356 public boolean isBackgroundVisibleBehind(IBinder token) { 10357 final long origId = Binder.clearCallingIdentity(); 10358 try { 10359 synchronized (this) { 10360 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10361 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10362 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10363 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10364 return visible; 10365 } 10366 } finally { 10367 Binder.restoreCallingIdentity(origId); 10368 } 10369 } 10370 10371 @Override 10372 public ActivityOptions getActivityOptions(IBinder token) { 10373 final long origId = Binder.clearCallingIdentity(); 10374 try { 10375 synchronized (this) { 10376 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10377 if (r != null) { 10378 final ActivityOptions activityOptions = r.pendingOptions; 10379 r.pendingOptions = null; 10380 return activityOptions; 10381 } 10382 return null; 10383 } 10384 } finally { 10385 Binder.restoreCallingIdentity(origId); 10386 } 10387 } 10388 10389 @Override 10390 public void setImmersive(IBinder token, boolean immersive) { 10391 synchronized(this) { 10392 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10393 if (r == null) { 10394 throw new IllegalArgumentException(); 10395 } 10396 r.immersive = immersive; 10397 10398 // update associated state if we're frontmost 10399 if (r == mFocusedActivity) { 10400 if (DEBUG_IMMERSIVE) { 10401 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10402 } 10403 applyUpdateLockStateLocked(r); 10404 } 10405 } 10406 } 10407 10408 @Override 10409 public boolean isImmersive(IBinder token) { 10410 synchronized (this) { 10411 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10412 if (r == null) { 10413 throw new IllegalArgumentException(); 10414 } 10415 return r.immersive; 10416 } 10417 } 10418 10419 public boolean isTopActivityImmersive() { 10420 enforceNotIsolatedCaller("startActivity"); 10421 synchronized (this) { 10422 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10423 return (r != null) ? r.immersive : false; 10424 } 10425 } 10426 10427 @Override 10428 public boolean isTopOfTask(IBinder token) { 10429 synchronized (this) { 10430 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10431 if (r == null) { 10432 throw new IllegalArgumentException(); 10433 } 10434 return r.task.getTopActivity() == r; 10435 } 10436 } 10437 10438 public final void enterSafeMode() { 10439 synchronized(this) { 10440 // It only makes sense to do this before the system is ready 10441 // and started launching other packages. 10442 if (!mSystemReady) { 10443 try { 10444 AppGlobals.getPackageManager().enterSafeMode(); 10445 } catch (RemoteException e) { 10446 } 10447 } 10448 10449 mSafeMode = true; 10450 } 10451 } 10452 10453 public final void showSafeModeOverlay() { 10454 View v = LayoutInflater.from(mContext).inflate( 10455 com.android.internal.R.layout.safe_mode, null); 10456 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10457 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10458 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10459 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10460 lp.gravity = Gravity.BOTTOM | Gravity.START; 10461 lp.format = v.getBackground().getOpacity(); 10462 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10463 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10464 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10465 ((WindowManager)mContext.getSystemService( 10466 Context.WINDOW_SERVICE)).addView(v, lp); 10467 } 10468 10469 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10470 if (!(sender instanceof PendingIntentRecord)) { 10471 return; 10472 } 10473 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10474 synchronized (stats) { 10475 if (mBatteryStatsService.isOnBattery()) { 10476 mBatteryStatsService.enforceCallingPermission(); 10477 PendingIntentRecord rec = (PendingIntentRecord)sender; 10478 int MY_UID = Binder.getCallingUid(); 10479 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10480 BatteryStatsImpl.Uid.Pkg pkg = 10481 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10482 sourcePkg != null ? sourcePkg : rec.key.packageName); 10483 pkg.incWakeupsLocked(); 10484 } 10485 } 10486 } 10487 10488 public boolean killPids(int[] pids, String pReason, boolean secure) { 10489 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10490 throw new SecurityException("killPids only available to the system"); 10491 } 10492 String reason = (pReason == null) ? "Unknown" : pReason; 10493 // XXX Note: don't acquire main activity lock here, because the window 10494 // manager calls in with its locks held. 10495 10496 boolean killed = false; 10497 synchronized (mPidsSelfLocked) { 10498 int[] types = new int[pids.length]; 10499 int worstType = 0; 10500 for (int i=0; i<pids.length; i++) { 10501 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10502 if (proc != null) { 10503 int type = proc.setAdj; 10504 types[i] = type; 10505 if (type > worstType) { 10506 worstType = type; 10507 } 10508 } 10509 } 10510 10511 // If the worst oom_adj is somewhere in the cached proc LRU range, 10512 // then constrain it so we will kill all cached procs. 10513 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10514 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10515 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10516 } 10517 10518 // If this is not a secure call, don't let it kill processes that 10519 // are important. 10520 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10521 worstType = ProcessList.SERVICE_ADJ; 10522 } 10523 10524 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10525 for (int i=0; i<pids.length; i++) { 10526 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10527 if (proc == null) { 10528 continue; 10529 } 10530 int adj = proc.setAdj; 10531 if (adj >= worstType && !proc.killedByAm) { 10532 proc.kill(reason, true); 10533 killed = true; 10534 } 10535 } 10536 } 10537 return killed; 10538 } 10539 10540 @Override 10541 public void killUid(int uid, String reason) { 10542 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10543 throw new SecurityException("killUid only available to the system"); 10544 } 10545 synchronized (this) { 10546 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10547 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10548 reason != null ? reason : "kill uid"); 10549 } 10550 } 10551 10552 @Override 10553 public boolean killProcessesBelowForeground(String reason) { 10554 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10555 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10556 } 10557 10558 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10559 } 10560 10561 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10562 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10563 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10564 } 10565 10566 boolean killed = false; 10567 synchronized (mPidsSelfLocked) { 10568 final int size = mPidsSelfLocked.size(); 10569 for (int i = 0; i < size; i++) { 10570 final int pid = mPidsSelfLocked.keyAt(i); 10571 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10572 if (proc == null) continue; 10573 10574 final int adj = proc.setAdj; 10575 if (adj > belowAdj && !proc.killedByAm) { 10576 proc.kill(reason, true); 10577 killed = true; 10578 } 10579 } 10580 } 10581 return killed; 10582 } 10583 10584 @Override 10585 public void hang(final IBinder who, boolean allowRestart) { 10586 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10587 != PackageManager.PERMISSION_GRANTED) { 10588 throw new SecurityException("Requires permission " 10589 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10590 } 10591 10592 final IBinder.DeathRecipient death = new DeathRecipient() { 10593 @Override 10594 public void binderDied() { 10595 synchronized (this) { 10596 notifyAll(); 10597 } 10598 } 10599 }; 10600 10601 try { 10602 who.linkToDeath(death, 0); 10603 } catch (RemoteException e) { 10604 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10605 return; 10606 } 10607 10608 synchronized (this) { 10609 Watchdog.getInstance().setAllowRestart(allowRestart); 10610 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10611 synchronized (death) { 10612 while (who.isBinderAlive()) { 10613 try { 10614 death.wait(); 10615 } catch (InterruptedException e) { 10616 } 10617 } 10618 } 10619 Watchdog.getInstance().setAllowRestart(true); 10620 } 10621 } 10622 10623 @Override 10624 public void restart() { 10625 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10626 != PackageManager.PERMISSION_GRANTED) { 10627 throw new SecurityException("Requires permission " 10628 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10629 } 10630 10631 Log.i(TAG, "Sending shutdown broadcast..."); 10632 10633 BroadcastReceiver br = new BroadcastReceiver() { 10634 @Override public void onReceive(Context context, Intent intent) { 10635 // Now the broadcast is done, finish up the low-level shutdown. 10636 Log.i(TAG, "Shutting down activity manager..."); 10637 shutdown(10000); 10638 Log.i(TAG, "Shutdown complete, restarting!"); 10639 Process.killProcess(Process.myPid()); 10640 System.exit(10); 10641 } 10642 }; 10643 10644 // First send the high-level shut down broadcast. 10645 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10646 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10647 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10648 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10649 mContext.sendOrderedBroadcastAsUser(intent, 10650 UserHandle.ALL, null, br, mHandler, 0, null, null); 10651 */ 10652 br.onReceive(mContext, intent); 10653 } 10654 10655 private long getLowRamTimeSinceIdle(long now) { 10656 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10657 } 10658 10659 @Override 10660 public void performIdleMaintenance() { 10661 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10662 != PackageManager.PERMISSION_GRANTED) { 10663 throw new SecurityException("Requires permission " 10664 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10665 } 10666 10667 synchronized (this) { 10668 final long now = SystemClock.uptimeMillis(); 10669 final long timeSinceLastIdle = now - mLastIdleTime; 10670 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10671 mLastIdleTime = now; 10672 mLowRamTimeSinceLastIdle = 0; 10673 if (mLowRamStartTime != 0) { 10674 mLowRamStartTime = now; 10675 } 10676 10677 StringBuilder sb = new StringBuilder(128); 10678 sb.append("Idle maintenance over "); 10679 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10680 sb.append(" low RAM for "); 10681 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10682 Slog.i(TAG, sb.toString()); 10683 10684 // If at least 1/3 of our time since the last idle period has been spent 10685 // with RAM low, then we want to kill processes. 10686 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10687 10688 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10689 ProcessRecord proc = mLruProcesses.get(i); 10690 if (proc.notCachedSinceIdle) { 10691 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10692 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10693 if (doKilling && proc.initialIdlePss != 0 10694 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10695 proc.kill("idle maint (pss " + proc.lastPss 10696 + " from " + proc.initialIdlePss + ")", true); 10697 } 10698 } 10699 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10700 proc.notCachedSinceIdle = true; 10701 proc.initialIdlePss = 0; 10702 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10703 isSleeping(), now); 10704 } 10705 } 10706 10707 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10708 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10709 } 10710 } 10711 10712 private void retrieveSettings() { 10713 final ContentResolver resolver = mContext.getContentResolver(); 10714 String debugApp = Settings.Global.getString( 10715 resolver, Settings.Global.DEBUG_APP); 10716 boolean waitForDebugger = Settings.Global.getInt( 10717 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10718 boolean alwaysFinishActivities = Settings.Global.getInt( 10719 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10720 boolean forceRtl = Settings.Global.getInt( 10721 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10722 // Transfer any global setting for forcing RTL layout, into a System Property 10723 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10724 10725 Configuration configuration = new Configuration(); 10726 Settings.System.getConfiguration(resolver, configuration); 10727 if (forceRtl) { 10728 // This will take care of setting the correct layout direction flags 10729 configuration.setLayoutDirection(configuration.locale); 10730 } 10731 10732 synchronized (this) { 10733 mDebugApp = mOrigDebugApp = debugApp; 10734 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10735 mAlwaysFinishActivities = alwaysFinishActivities; 10736 // This happens before any activities are started, so we can 10737 // change mConfiguration in-place. 10738 updateConfigurationLocked(configuration, null, false, true); 10739 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10740 } 10741 } 10742 10743 /** Loads resources after the current configuration has been set. */ 10744 private void loadResourcesOnSystemReady() { 10745 final Resources res = mContext.getResources(); 10746 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10747 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10748 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10749 } 10750 10751 public boolean testIsSystemReady() { 10752 // no need to synchronize(this) just to read & return the value 10753 return mSystemReady; 10754 } 10755 10756 private static File getCalledPreBootReceiversFile() { 10757 File dataDir = Environment.getDataDirectory(); 10758 File systemDir = new File(dataDir, "system"); 10759 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10760 return fname; 10761 } 10762 10763 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10764 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10765 File file = getCalledPreBootReceiversFile(); 10766 FileInputStream fis = null; 10767 try { 10768 fis = new FileInputStream(file); 10769 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10770 int fvers = dis.readInt(); 10771 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10772 String vers = dis.readUTF(); 10773 String codename = dis.readUTF(); 10774 String build = dis.readUTF(); 10775 if (android.os.Build.VERSION.RELEASE.equals(vers) 10776 && android.os.Build.VERSION.CODENAME.equals(codename) 10777 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10778 int num = dis.readInt(); 10779 while (num > 0) { 10780 num--; 10781 String pkg = dis.readUTF(); 10782 String cls = dis.readUTF(); 10783 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10784 } 10785 } 10786 } 10787 } catch (FileNotFoundException e) { 10788 } catch (IOException e) { 10789 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10790 } finally { 10791 if (fis != null) { 10792 try { 10793 fis.close(); 10794 } catch (IOException e) { 10795 } 10796 } 10797 } 10798 return lastDoneReceivers; 10799 } 10800 10801 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10802 File file = getCalledPreBootReceiversFile(); 10803 FileOutputStream fos = null; 10804 DataOutputStream dos = null; 10805 try { 10806 fos = new FileOutputStream(file); 10807 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10808 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10809 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10810 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10811 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10812 dos.writeInt(list.size()); 10813 for (int i=0; i<list.size(); i++) { 10814 dos.writeUTF(list.get(i).getPackageName()); 10815 dos.writeUTF(list.get(i).getClassName()); 10816 } 10817 } catch (IOException e) { 10818 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10819 file.delete(); 10820 } finally { 10821 FileUtils.sync(fos); 10822 if (dos != null) { 10823 try { 10824 dos.close(); 10825 } catch (IOException e) { 10826 // TODO Auto-generated catch block 10827 e.printStackTrace(); 10828 } 10829 } 10830 } 10831 } 10832 10833 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10834 ArrayList<ComponentName> doneReceivers, int userId) { 10835 boolean waitingUpdate = false; 10836 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10837 List<ResolveInfo> ris = null; 10838 try { 10839 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10840 intent, null, 0, userId); 10841 } catch (RemoteException e) { 10842 } 10843 if (ris != null) { 10844 for (int i=ris.size()-1; i>=0; i--) { 10845 if ((ris.get(i).activityInfo.applicationInfo.flags 10846 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10847 ris.remove(i); 10848 } 10849 } 10850 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10851 10852 // For User 0, load the version number. When delivering to a new user, deliver 10853 // to all receivers. 10854 if (userId == UserHandle.USER_OWNER) { 10855 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10856 for (int i=0; i<ris.size(); i++) { 10857 ActivityInfo ai = ris.get(i).activityInfo; 10858 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10859 if (lastDoneReceivers.contains(comp)) { 10860 // We already did the pre boot receiver for this app with the current 10861 // platform version, so don't do it again... 10862 ris.remove(i); 10863 i--; 10864 // ...however, do keep it as one that has been done, so we don't 10865 // forget about it when rewriting the file of last done receivers. 10866 doneReceivers.add(comp); 10867 } 10868 } 10869 } 10870 10871 // If primary user, send broadcast to all available users, else just to userId 10872 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10873 : new int[] { userId }; 10874 for (int i = 0; i < ris.size(); i++) { 10875 ActivityInfo ai = ris.get(i).activityInfo; 10876 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10877 doneReceivers.add(comp); 10878 intent.setComponent(comp); 10879 for (int j=0; j<users.length; j++) { 10880 IIntentReceiver finisher = null; 10881 // On last receiver and user, set up a completion callback 10882 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10883 finisher = new IIntentReceiver.Stub() { 10884 public void performReceive(Intent intent, int resultCode, 10885 String data, Bundle extras, boolean ordered, 10886 boolean sticky, int sendingUser) { 10887 // The raw IIntentReceiver interface is called 10888 // with the AM lock held, so redispatch to 10889 // execute our code without the lock. 10890 mHandler.post(onFinishCallback); 10891 } 10892 }; 10893 } 10894 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10895 + " for user " + users[j]); 10896 broadcastIntentLocked(null, null, intent, null, finisher, 10897 0, null, null, null, AppOpsManager.OP_NONE, 10898 true, false, MY_PID, Process.SYSTEM_UID, 10899 users[j]); 10900 if (finisher != null) { 10901 waitingUpdate = true; 10902 } 10903 } 10904 } 10905 } 10906 10907 return waitingUpdate; 10908 } 10909 10910 public void systemReady(final Runnable goingCallback) { 10911 synchronized(this) { 10912 if (mSystemReady) { 10913 // If we're done calling all the receivers, run the next "boot phase" passed in 10914 // by the SystemServer 10915 if (goingCallback != null) { 10916 goingCallback.run(); 10917 } 10918 return; 10919 } 10920 10921 // Make sure we have the current profile info, since it is needed for 10922 // security checks. 10923 updateCurrentProfileIdsLocked(); 10924 10925 if (mRecentTasks == null) { 10926 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10927 if (!mRecentTasks.isEmpty()) { 10928 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10929 } 10930 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10931 mTaskPersister.startPersisting(); 10932 } 10933 10934 // Check to see if there are any update receivers to run. 10935 if (!mDidUpdate) { 10936 if (mWaitingUpdate) { 10937 return; 10938 } 10939 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10940 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10941 public void run() { 10942 synchronized (ActivityManagerService.this) { 10943 mDidUpdate = true; 10944 } 10945 writeLastDonePreBootReceivers(doneReceivers); 10946 showBootMessage(mContext.getText( 10947 R.string.android_upgrading_complete), 10948 false); 10949 systemReady(goingCallback); 10950 } 10951 }, doneReceivers, UserHandle.USER_OWNER); 10952 10953 if (mWaitingUpdate) { 10954 return; 10955 } 10956 mDidUpdate = true; 10957 } 10958 10959 mAppOpsService.systemReady(); 10960 mSystemReady = true; 10961 } 10962 10963 ArrayList<ProcessRecord> procsToKill = null; 10964 synchronized(mPidsSelfLocked) { 10965 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10966 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10967 if (!isAllowedWhileBooting(proc.info)){ 10968 if (procsToKill == null) { 10969 procsToKill = new ArrayList<ProcessRecord>(); 10970 } 10971 procsToKill.add(proc); 10972 } 10973 } 10974 } 10975 10976 synchronized(this) { 10977 if (procsToKill != null) { 10978 for (int i=procsToKill.size()-1; i>=0; i--) { 10979 ProcessRecord proc = procsToKill.get(i); 10980 Slog.i(TAG, "Removing system update proc: " + proc); 10981 removeProcessLocked(proc, true, false, "system update done"); 10982 } 10983 } 10984 10985 // Now that we have cleaned up any update processes, we 10986 // are ready to start launching real processes and know that 10987 // we won't trample on them any more. 10988 mProcessesReady = true; 10989 } 10990 10991 Slog.i(TAG, "System now ready"); 10992 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10993 SystemClock.uptimeMillis()); 10994 10995 synchronized(this) { 10996 // Make sure we have no pre-ready processes sitting around. 10997 10998 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10999 ResolveInfo ri = mContext.getPackageManager() 11000 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11001 STOCK_PM_FLAGS); 11002 CharSequence errorMsg = null; 11003 if (ri != null) { 11004 ActivityInfo ai = ri.activityInfo; 11005 ApplicationInfo app = ai.applicationInfo; 11006 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11007 mTopAction = Intent.ACTION_FACTORY_TEST; 11008 mTopData = null; 11009 mTopComponent = new ComponentName(app.packageName, 11010 ai.name); 11011 } else { 11012 errorMsg = mContext.getResources().getText( 11013 com.android.internal.R.string.factorytest_not_system); 11014 } 11015 } else { 11016 errorMsg = mContext.getResources().getText( 11017 com.android.internal.R.string.factorytest_no_action); 11018 } 11019 if (errorMsg != null) { 11020 mTopAction = null; 11021 mTopData = null; 11022 mTopComponent = null; 11023 Message msg = Message.obtain(); 11024 msg.what = SHOW_FACTORY_ERROR_MSG; 11025 msg.getData().putCharSequence("msg", errorMsg); 11026 mHandler.sendMessage(msg); 11027 } 11028 } 11029 } 11030 11031 retrieveSettings(); 11032 loadResourcesOnSystemReady(); 11033 11034 synchronized (this) { 11035 readGrantedUriPermissionsLocked(); 11036 } 11037 11038 if (goingCallback != null) goingCallback.run(); 11039 11040 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11041 Integer.toString(mCurrentUserId), mCurrentUserId); 11042 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11043 Integer.toString(mCurrentUserId), mCurrentUserId); 11044 mSystemServiceManager.startUser(mCurrentUserId); 11045 11046 synchronized (this) { 11047 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11048 try { 11049 List apps = AppGlobals.getPackageManager(). 11050 getPersistentApplications(STOCK_PM_FLAGS); 11051 if (apps != null) { 11052 int N = apps.size(); 11053 int i; 11054 for (i=0; i<N; i++) { 11055 ApplicationInfo info 11056 = (ApplicationInfo)apps.get(i); 11057 if (info != null && 11058 !info.packageName.equals("android")) { 11059 addAppLocked(info, false, null /* ABI override */); 11060 } 11061 } 11062 } 11063 } catch (RemoteException ex) { 11064 // pm is in same process, this will never happen. 11065 } 11066 } 11067 11068 // Start up initial activity. 11069 mBooting = true; 11070 11071 try { 11072 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11073 Message msg = Message.obtain(); 11074 msg.what = SHOW_UID_ERROR_MSG; 11075 mHandler.sendMessage(msg); 11076 } 11077 } catch (RemoteException e) { 11078 } 11079 11080 long ident = Binder.clearCallingIdentity(); 11081 try { 11082 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11083 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11084 | Intent.FLAG_RECEIVER_FOREGROUND); 11085 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11086 broadcastIntentLocked(null, null, intent, 11087 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11088 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11089 intent = new Intent(Intent.ACTION_USER_STARTING); 11090 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11091 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11092 broadcastIntentLocked(null, null, intent, 11093 null, new IIntentReceiver.Stub() { 11094 @Override 11095 public void performReceive(Intent intent, int resultCode, String data, 11096 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11097 throws RemoteException { 11098 } 11099 }, 0, null, null, 11100 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11101 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11102 } catch (Throwable t) { 11103 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11104 } finally { 11105 Binder.restoreCallingIdentity(ident); 11106 } 11107 mStackSupervisor.resumeTopActivitiesLocked(); 11108 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11109 } 11110 } 11111 11112 private boolean makeAppCrashingLocked(ProcessRecord app, 11113 String shortMsg, String longMsg, String stackTrace) { 11114 app.crashing = true; 11115 app.crashingReport = generateProcessError(app, 11116 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11117 startAppProblemLocked(app); 11118 app.stopFreezingAllLocked(); 11119 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11120 } 11121 11122 private void makeAppNotRespondingLocked(ProcessRecord app, 11123 String activity, String shortMsg, String longMsg) { 11124 app.notResponding = true; 11125 app.notRespondingReport = generateProcessError(app, 11126 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11127 activity, shortMsg, longMsg, null); 11128 startAppProblemLocked(app); 11129 app.stopFreezingAllLocked(); 11130 } 11131 11132 /** 11133 * Generate a process error record, suitable for attachment to a ProcessRecord. 11134 * 11135 * @param app The ProcessRecord in which the error occurred. 11136 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11137 * ActivityManager.AppErrorStateInfo 11138 * @param activity The activity associated with the crash, if known. 11139 * @param shortMsg Short message describing the crash. 11140 * @param longMsg Long message describing the crash. 11141 * @param stackTrace Full crash stack trace, may be null. 11142 * 11143 * @return Returns a fully-formed AppErrorStateInfo record. 11144 */ 11145 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11146 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11147 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11148 11149 report.condition = condition; 11150 report.processName = app.processName; 11151 report.pid = app.pid; 11152 report.uid = app.info.uid; 11153 report.tag = activity; 11154 report.shortMsg = shortMsg; 11155 report.longMsg = longMsg; 11156 report.stackTrace = stackTrace; 11157 11158 return report; 11159 } 11160 11161 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11162 synchronized (this) { 11163 app.crashing = false; 11164 app.crashingReport = null; 11165 app.notResponding = false; 11166 app.notRespondingReport = null; 11167 if (app.anrDialog == fromDialog) { 11168 app.anrDialog = null; 11169 } 11170 if (app.waitDialog == fromDialog) { 11171 app.waitDialog = null; 11172 } 11173 if (app.pid > 0 && app.pid != MY_PID) { 11174 handleAppCrashLocked(app, null, null, null); 11175 app.kill("user request after error", true); 11176 } 11177 } 11178 } 11179 11180 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11181 String stackTrace) { 11182 long now = SystemClock.uptimeMillis(); 11183 11184 Long crashTime; 11185 if (!app.isolated) { 11186 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11187 } else { 11188 crashTime = null; 11189 } 11190 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11191 // This process loses! 11192 Slog.w(TAG, "Process " + app.info.processName 11193 + " has crashed too many times: killing!"); 11194 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11195 app.userId, app.info.processName, app.uid); 11196 mStackSupervisor.handleAppCrashLocked(app); 11197 if (!app.persistent) { 11198 // We don't want to start this process again until the user 11199 // explicitly does so... but for persistent process, we really 11200 // need to keep it running. If a persistent process is actually 11201 // repeatedly crashing, then badness for everyone. 11202 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11203 app.info.processName); 11204 if (!app.isolated) { 11205 // XXX We don't have a way to mark isolated processes 11206 // as bad, since they don't have a peristent identity. 11207 mBadProcesses.put(app.info.processName, app.uid, 11208 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11209 mProcessCrashTimes.remove(app.info.processName, app.uid); 11210 } 11211 app.bad = true; 11212 app.removed = true; 11213 // Don't let services in this process be restarted and potentially 11214 // annoy the user repeatedly. Unless it is persistent, since those 11215 // processes run critical code. 11216 removeProcessLocked(app, false, false, "crash"); 11217 mStackSupervisor.resumeTopActivitiesLocked(); 11218 return false; 11219 } 11220 mStackSupervisor.resumeTopActivitiesLocked(); 11221 } else { 11222 mStackSupervisor.finishTopRunningActivityLocked(app); 11223 } 11224 11225 // Bump up the crash count of any services currently running in the proc. 11226 for (int i=app.services.size()-1; i>=0; i--) { 11227 // Any services running in the application need to be placed 11228 // back in the pending list. 11229 ServiceRecord sr = app.services.valueAt(i); 11230 sr.crashCount++; 11231 } 11232 11233 // If the crashing process is what we consider to be the "home process" and it has been 11234 // replaced by a third-party app, clear the package preferred activities from packages 11235 // with a home activity running in the process to prevent a repeatedly crashing app 11236 // from blocking the user to manually clear the list. 11237 final ArrayList<ActivityRecord> activities = app.activities; 11238 if (app == mHomeProcess && activities.size() > 0 11239 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11240 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11241 final ActivityRecord r = activities.get(activityNdx); 11242 if (r.isHomeActivity()) { 11243 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11244 try { 11245 ActivityThread.getPackageManager() 11246 .clearPackagePreferredActivities(r.packageName); 11247 } catch (RemoteException c) { 11248 // pm is in same process, this will never happen. 11249 } 11250 } 11251 } 11252 } 11253 11254 if (!app.isolated) { 11255 // XXX Can't keep track of crash times for isolated processes, 11256 // because they don't have a perisistent identity. 11257 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11258 } 11259 11260 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11261 return true; 11262 } 11263 11264 void startAppProblemLocked(ProcessRecord app) { 11265 // If this app is not running under the current user, then we 11266 // can't give it a report button because that would require 11267 // launching the report UI under a different user. 11268 app.errorReportReceiver = null; 11269 11270 for (int userId : mCurrentProfileIds) { 11271 if (app.userId == userId) { 11272 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11273 mContext, app.info.packageName, app.info.flags); 11274 } 11275 } 11276 skipCurrentReceiverLocked(app); 11277 } 11278 11279 void skipCurrentReceiverLocked(ProcessRecord app) { 11280 for (BroadcastQueue queue : mBroadcastQueues) { 11281 queue.skipCurrentReceiverLocked(app); 11282 } 11283 } 11284 11285 /** 11286 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11287 * The application process will exit immediately after this call returns. 11288 * @param app object of the crashing app, null for the system server 11289 * @param crashInfo describing the exception 11290 */ 11291 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11292 ProcessRecord r = findAppProcess(app, "Crash"); 11293 final String processName = app == null ? "system_server" 11294 : (r == null ? "unknown" : r.processName); 11295 11296 handleApplicationCrashInner("crash", r, processName, crashInfo); 11297 } 11298 11299 /* Native crash reporting uses this inner version because it needs to be somewhat 11300 * decoupled from the AM-managed cleanup lifecycle 11301 */ 11302 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11303 ApplicationErrorReport.CrashInfo crashInfo) { 11304 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11305 UserHandle.getUserId(Binder.getCallingUid()), processName, 11306 r == null ? -1 : r.info.flags, 11307 crashInfo.exceptionClassName, 11308 crashInfo.exceptionMessage, 11309 crashInfo.throwFileName, 11310 crashInfo.throwLineNumber); 11311 11312 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11313 11314 crashApplication(r, crashInfo); 11315 } 11316 11317 public void handleApplicationStrictModeViolation( 11318 IBinder app, 11319 int violationMask, 11320 StrictMode.ViolationInfo info) { 11321 ProcessRecord r = findAppProcess(app, "StrictMode"); 11322 if (r == null) { 11323 return; 11324 } 11325 11326 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11327 Integer stackFingerprint = info.hashCode(); 11328 boolean logIt = true; 11329 synchronized (mAlreadyLoggedViolatedStacks) { 11330 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11331 logIt = false; 11332 // TODO: sub-sample into EventLog for these, with 11333 // the info.durationMillis? Then we'd get 11334 // the relative pain numbers, without logging all 11335 // the stack traces repeatedly. We'd want to do 11336 // likewise in the client code, which also does 11337 // dup suppression, before the Binder call. 11338 } else { 11339 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11340 mAlreadyLoggedViolatedStacks.clear(); 11341 } 11342 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11343 } 11344 } 11345 if (logIt) { 11346 logStrictModeViolationToDropBox(r, info); 11347 } 11348 } 11349 11350 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11351 AppErrorResult result = new AppErrorResult(); 11352 synchronized (this) { 11353 final long origId = Binder.clearCallingIdentity(); 11354 11355 Message msg = Message.obtain(); 11356 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11357 HashMap<String, Object> data = new HashMap<String, Object>(); 11358 data.put("result", result); 11359 data.put("app", r); 11360 data.put("violationMask", violationMask); 11361 data.put("info", info); 11362 msg.obj = data; 11363 mHandler.sendMessage(msg); 11364 11365 Binder.restoreCallingIdentity(origId); 11366 } 11367 int res = result.get(); 11368 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11369 } 11370 } 11371 11372 // Depending on the policy in effect, there could be a bunch of 11373 // these in quick succession so we try to batch these together to 11374 // minimize disk writes, number of dropbox entries, and maximize 11375 // compression, by having more fewer, larger records. 11376 private void logStrictModeViolationToDropBox( 11377 ProcessRecord process, 11378 StrictMode.ViolationInfo info) { 11379 if (info == null) { 11380 return; 11381 } 11382 final boolean isSystemApp = process == null || 11383 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11384 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11385 final String processName = process == null ? "unknown" : process.processName; 11386 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11387 final DropBoxManager dbox = (DropBoxManager) 11388 mContext.getSystemService(Context.DROPBOX_SERVICE); 11389 11390 // Exit early if the dropbox isn't configured to accept this report type. 11391 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11392 11393 boolean bufferWasEmpty; 11394 boolean needsFlush; 11395 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11396 synchronized (sb) { 11397 bufferWasEmpty = sb.length() == 0; 11398 appendDropBoxProcessHeaders(process, processName, sb); 11399 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11400 sb.append("System-App: ").append(isSystemApp).append("\n"); 11401 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11402 if (info.violationNumThisLoop != 0) { 11403 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11404 } 11405 if (info.numAnimationsRunning != 0) { 11406 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11407 } 11408 if (info.broadcastIntentAction != null) { 11409 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11410 } 11411 if (info.durationMillis != -1) { 11412 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11413 } 11414 if (info.numInstances != -1) { 11415 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11416 } 11417 if (info.tags != null) { 11418 for (String tag : info.tags) { 11419 sb.append("Span-Tag: ").append(tag).append("\n"); 11420 } 11421 } 11422 sb.append("\n"); 11423 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11424 sb.append(info.crashInfo.stackTrace); 11425 } 11426 sb.append("\n"); 11427 11428 // Only buffer up to ~64k. Various logging bits truncate 11429 // things at 128k. 11430 needsFlush = (sb.length() > 64 * 1024); 11431 } 11432 11433 // Flush immediately if the buffer's grown too large, or this 11434 // is a non-system app. Non-system apps are isolated with a 11435 // different tag & policy and not batched. 11436 // 11437 // Batching is useful during internal testing with 11438 // StrictMode settings turned up high. Without batching, 11439 // thousands of separate files could be created on boot. 11440 if (!isSystemApp || needsFlush) { 11441 new Thread("Error dump: " + dropboxTag) { 11442 @Override 11443 public void run() { 11444 String report; 11445 synchronized (sb) { 11446 report = sb.toString(); 11447 sb.delete(0, sb.length()); 11448 sb.trimToSize(); 11449 } 11450 if (report.length() != 0) { 11451 dbox.addText(dropboxTag, report); 11452 } 11453 } 11454 }.start(); 11455 return; 11456 } 11457 11458 // System app batching: 11459 if (!bufferWasEmpty) { 11460 // An existing dropbox-writing thread is outstanding, so 11461 // we don't need to start it up. The existing thread will 11462 // catch the buffer appends we just did. 11463 return; 11464 } 11465 11466 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11467 // (After this point, we shouldn't access AMS internal data structures.) 11468 new Thread("Error dump: " + dropboxTag) { 11469 @Override 11470 public void run() { 11471 // 5 second sleep to let stacks arrive and be batched together 11472 try { 11473 Thread.sleep(5000); // 5 seconds 11474 } catch (InterruptedException e) {} 11475 11476 String errorReport; 11477 synchronized (mStrictModeBuffer) { 11478 errorReport = mStrictModeBuffer.toString(); 11479 if (errorReport.length() == 0) { 11480 return; 11481 } 11482 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11483 mStrictModeBuffer.trimToSize(); 11484 } 11485 dbox.addText(dropboxTag, errorReport); 11486 } 11487 }.start(); 11488 } 11489 11490 /** 11491 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11492 * @param app object of the crashing app, null for the system server 11493 * @param tag reported by the caller 11494 * @param system whether this wtf is coming from the system 11495 * @param crashInfo describing the context of the error 11496 * @return true if the process should exit immediately (WTF is fatal) 11497 */ 11498 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11499 final ApplicationErrorReport.CrashInfo crashInfo) { 11500 final ProcessRecord r = findAppProcess(app, "WTF"); 11501 final String processName = app == null ? "system_server" 11502 : (r == null ? "unknown" : r.processName); 11503 11504 EventLog.writeEvent(EventLogTags.AM_WTF, 11505 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11506 processName, 11507 r == null ? -1 : r.info.flags, 11508 tag, crashInfo.exceptionMessage); 11509 11510 if (system) { 11511 // If this is coming from the system, we could very well have low-level 11512 // system locks held, so we want to do this all asynchronously. And we 11513 // never want this to become fatal, so there is that too. 11514 mHandler.post(new Runnable() { 11515 @Override public void run() { 11516 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11517 crashInfo); 11518 } 11519 }); 11520 return false; 11521 } 11522 11523 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11524 11525 if (r != null && r.pid != Process.myPid() && 11526 Settings.Global.getInt(mContext.getContentResolver(), 11527 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11528 crashApplication(r, crashInfo); 11529 return true; 11530 } else { 11531 return false; 11532 } 11533 } 11534 11535 /** 11536 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11537 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11538 */ 11539 private ProcessRecord findAppProcess(IBinder app, String reason) { 11540 if (app == null) { 11541 return null; 11542 } 11543 11544 synchronized (this) { 11545 final int NP = mProcessNames.getMap().size(); 11546 for (int ip=0; ip<NP; ip++) { 11547 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11548 final int NA = apps.size(); 11549 for (int ia=0; ia<NA; ia++) { 11550 ProcessRecord p = apps.valueAt(ia); 11551 if (p.thread != null && p.thread.asBinder() == app) { 11552 return p; 11553 } 11554 } 11555 } 11556 11557 Slog.w(TAG, "Can't find mystery application for " + reason 11558 + " from pid=" + Binder.getCallingPid() 11559 + " uid=" + Binder.getCallingUid() + ": " + app); 11560 return null; 11561 } 11562 } 11563 11564 /** 11565 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11566 * to append various headers to the dropbox log text. 11567 */ 11568 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11569 StringBuilder sb) { 11570 // Watchdog thread ends up invoking this function (with 11571 // a null ProcessRecord) to add the stack file to dropbox. 11572 // Do not acquire a lock on this (am) in such cases, as it 11573 // could cause a potential deadlock, if and when watchdog 11574 // is invoked due to unavailability of lock on am and it 11575 // would prevent watchdog from killing system_server. 11576 if (process == null) { 11577 sb.append("Process: ").append(processName).append("\n"); 11578 return; 11579 } 11580 // Note: ProcessRecord 'process' is guarded by the service 11581 // instance. (notably process.pkgList, which could otherwise change 11582 // concurrently during execution of this method) 11583 synchronized (this) { 11584 sb.append("Process: ").append(processName).append("\n"); 11585 int flags = process.info.flags; 11586 IPackageManager pm = AppGlobals.getPackageManager(); 11587 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11588 for (int ip=0; ip<process.pkgList.size(); ip++) { 11589 String pkg = process.pkgList.keyAt(ip); 11590 sb.append("Package: ").append(pkg); 11591 try { 11592 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11593 if (pi != null) { 11594 sb.append(" v").append(pi.versionCode); 11595 if (pi.versionName != null) { 11596 sb.append(" (").append(pi.versionName).append(")"); 11597 } 11598 } 11599 } catch (RemoteException e) { 11600 Slog.e(TAG, "Error getting package info: " + pkg, e); 11601 } 11602 sb.append("\n"); 11603 } 11604 } 11605 } 11606 11607 private static String processClass(ProcessRecord process) { 11608 if (process == null || process.pid == MY_PID) { 11609 return "system_server"; 11610 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11611 return "system_app"; 11612 } else { 11613 return "data_app"; 11614 } 11615 } 11616 11617 /** 11618 * Write a description of an error (crash, WTF, ANR) to the drop box. 11619 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11620 * @param process which caused the error, null means the system server 11621 * @param activity which triggered the error, null if unknown 11622 * @param parent activity related to the error, null if unknown 11623 * @param subject line related to the error, null if absent 11624 * @param report in long form describing the error, null if absent 11625 * @param logFile to include in the report, null if none 11626 * @param crashInfo giving an application stack trace, null if absent 11627 */ 11628 public void addErrorToDropBox(String eventType, 11629 ProcessRecord process, String processName, ActivityRecord activity, 11630 ActivityRecord parent, String subject, 11631 final String report, final File logFile, 11632 final ApplicationErrorReport.CrashInfo crashInfo) { 11633 // NOTE -- this must never acquire the ActivityManagerService lock, 11634 // otherwise the watchdog may be prevented from resetting the system. 11635 11636 final String dropboxTag = processClass(process) + "_" + eventType; 11637 final DropBoxManager dbox = (DropBoxManager) 11638 mContext.getSystemService(Context.DROPBOX_SERVICE); 11639 11640 // Exit early if the dropbox isn't configured to accept this report type. 11641 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11642 11643 final StringBuilder sb = new StringBuilder(1024); 11644 appendDropBoxProcessHeaders(process, processName, sb); 11645 if (activity != null) { 11646 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11647 } 11648 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11649 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11650 } 11651 if (parent != null && parent != activity) { 11652 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11653 } 11654 if (subject != null) { 11655 sb.append("Subject: ").append(subject).append("\n"); 11656 } 11657 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11658 if (Debug.isDebuggerConnected()) { 11659 sb.append("Debugger: Connected\n"); 11660 } 11661 sb.append("\n"); 11662 11663 // Do the rest in a worker thread to avoid blocking the caller on I/O 11664 // (After this point, we shouldn't access AMS internal data structures.) 11665 Thread worker = new Thread("Error dump: " + dropboxTag) { 11666 @Override 11667 public void run() { 11668 if (report != null) { 11669 sb.append(report); 11670 } 11671 if (logFile != null) { 11672 try { 11673 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11674 "\n\n[[TRUNCATED]]")); 11675 } catch (IOException e) { 11676 Slog.e(TAG, "Error reading " + logFile, e); 11677 } 11678 } 11679 if (crashInfo != null && crashInfo.stackTrace != null) { 11680 sb.append(crashInfo.stackTrace); 11681 } 11682 11683 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11684 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11685 if (lines > 0) { 11686 sb.append("\n"); 11687 11688 // Merge several logcat streams, and take the last N lines 11689 InputStreamReader input = null; 11690 try { 11691 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11692 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11693 "-b", "crash", 11694 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11695 11696 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11697 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11698 input = new InputStreamReader(logcat.getInputStream()); 11699 11700 int num; 11701 char[] buf = new char[8192]; 11702 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11703 } catch (IOException e) { 11704 Slog.e(TAG, "Error running logcat", e); 11705 } finally { 11706 if (input != null) try { input.close(); } catch (IOException e) {} 11707 } 11708 } 11709 11710 dbox.addText(dropboxTag, sb.toString()); 11711 } 11712 }; 11713 11714 if (process == null) { 11715 // If process is null, we are being called from some internal code 11716 // and may be about to die -- run this synchronously. 11717 worker.run(); 11718 } else { 11719 worker.start(); 11720 } 11721 } 11722 11723 /** 11724 * Bring up the "unexpected error" dialog box for a crashing app. 11725 * Deal with edge cases (intercepts from instrumented applications, 11726 * ActivityController, error intent receivers, that sort of thing). 11727 * @param r the application crashing 11728 * @param crashInfo describing the failure 11729 */ 11730 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11731 long timeMillis = System.currentTimeMillis(); 11732 String shortMsg = crashInfo.exceptionClassName; 11733 String longMsg = crashInfo.exceptionMessage; 11734 String stackTrace = crashInfo.stackTrace; 11735 if (shortMsg != null && longMsg != null) { 11736 longMsg = shortMsg + ": " + longMsg; 11737 } else if (shortMsg != null) { 11738 longMsg = shortMsg; 11739 } 11740 11741 AppErrorResult result = new AppErrorResult(); 11742 synchronized (this) { 11743 if (mController != null) { 11744 try { 11745 String name = r != null ? r.processName : null; 11746 int pid = r != null ? r.pid : Binder.getCallingPid(); 11747 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11748 if (!mController.appCrashed(name, pid, 11749 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11750 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11751 && "Native crash".equals(crashInfo.exceptionClassName)) { 11752 Slog.w(TAG, "Skip killing native crashed app " + name 11753 + "(" + pid + ") during testing"); 11754 } else { 11755 Slog.w(TAG, "Force-killing crashed app " + name 11756 + " at watcher's request"); 11757 if (r != null) { 11758 r.kill("crash", true); 11759 } else { 11760 // Huh. 11761 Process.killProcess(pid); 11762 Process.killProcessGroup(uid, pid); 11763 } 11764 } 11765 return; 11766 } 11767 } catch (RemoteException e) { 11768 mController = null; 11769 Watchdog.getInstance().setActivityController(null); 11770 } 11771 } 11772 11773 final long origId = Binder.clearCallingIdentity(); 11774 11775 // If this process is running instrumentation, finish it. 11776 if (r != null && r.instrumentationClass != null) { 11777 Slog.w(TAG, "Error in app " + r.processName 11778 + " running instrumentation " + r.instrumentationClass + ":"); 11779 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11780 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11781 Bundle info = new Bundle(); 11782 info.putString("shortMsg", shortMsg); 11783 info.putString("longMsg", longMsg); 11784 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11785 Binder.restoreCallingIdentity(origId); 11786 return; 11787 } 11788 11789 // If we can't identify the process or it's already exceeded its crash quota, 11790 // quit right away without showing a crash dialog. 11791 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11792 Binder.restoreCallingIdentity(origId); 11793 return; 11794 } 11795 11796 Message msg = Message.obtain(); 11797 msg.what = SHOW_ERROR_MSG; 11798 HashMap data = new HashMap(); 11799 data.put("result", result); 11800 data.put("app", r); 11801 msg.obj = data; 11802 mHandler.sendMessage(msg); 11803 11804 Binder.restoreCallingIdentity(origId); 11805 } 11806 11807 int res = result.get(); 11808 11809 Intent appErrorIntent = null; 11810 synchronized (this) { 11811 if (r != null && !r.isolated) { 11812 // XXX Can't keep track of crash time for isolated processes, 11813 // since they don't have a persistent identity. 11814 mProcessCrashTimes.put(r.info.processName, r.uid, 11815 SystemClock.uptimeMillis()); 11816 } 11817 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11818 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11819 } 11820 } 11821 11822 if (appErrorIntent != null) { 11823 try { 11824 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11825 } catch (ActivityNotFoundException e) { 11826 Slog.w(TAG, "bug report receiver dissappeared", e); 11827 } 11828 } 11829 } 11830 11831 Intent createAppErrorIntentLocked(ProcessRecord r, 11832 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11833 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11834 if (report == null) { 11835 return null; 11836 } 11837 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11838 result.setComponent(r.errorReportReceiver); 11839 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11840 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11841 return result; 11842 } 11843 11844 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11845 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11846 if (r.errorReportReceiver == null) { 11847 return null; 11848 } 11849 11850 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11851 return null; 11852 } 11853 11854 ApplicationErrorReport report = new ApplicationErrorReport(); 11855 report.packageName = r.info.packageName; 11856 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11857 report.processName = r.processName; 11858 report.time = timeMillis; 11859 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11860 11861 if (r.crashing || r.forceCrashReport) { 11862 report.type = ApplicationErrorReport.TYPE_CRASH; 11863 report.crashInfo = crashInfo; 11864 } else if (r.notResponding) { 11865 report.type = ApplicationErrorReport.TYPE_ANR; 11866 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11867 11868 report.anrInfo.activity = r.notRespondingReport.tag; 11869 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11870 report.anrInfo.info = r.notRespondingReport.longMsg; 11871 } 11872 11873 return report; 11874 } 11875 11876 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11877 enforceNotIsolatedCaller("getProcessesInErrorState"); 11878 // assume our apps are happy - lazy create the list 11879 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11880 11881 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11882 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11883 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11884 11885 synchronized (this) { 11886 11887 // iterate across all processes 11888 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11889 ProcessRecord app = mLruProcesses.get(i); 11890 if (!allUsers && app.userId != userId) { 11891 continue; 11892 } 11893 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11894 // This one's in trouble, so we'll generate a report for it 11895 // crashes are higher priority (in case there's a crash *and* an anr) 11896 ActivityManager.ProcessErrorStateInfo report = null; 11897 if (app.crashing) { 11898 report = app.crashingReport; 11899 } else if (app.notResponding) { 11900 report = app.notRespondingReport; 11901 } 11902 11903 if (report != null) { 11904 if (errList == null) { 11905 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11906 } 11907 errList.add(report); 11908 } else { 11909 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11910 " crashing = " + app.crashing + 11911 " notResponding = " + app.notResponding); 11912 } 11913 } 11914 } 11915 } 11916 11917 return errList; 11918 } 11919 11920 static int procStateToImportance(int procState, int memAdj, 11921 ActivityManager.RunningAppProcessInfo currApp) { 11922 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11923 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11924 currApp.lru = memAdj; 11925 } else { 11926 currApp.lru = 0; 11927 } 11928 return imp; 11929 } 11930 11931 private void fillInProcMemInfo(ProcessRecord app, 11932 ActivityManager.RunningAppProcessInfo outInfo) { 11933 outInfo.pid = app.pid; 11934 outInfo.uid = app.info.uid; 11935 if (mHeavyWeightProcess == app) { 11936 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11937 } 11938 if (app.persistent) { 11939 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11940 } 11941 if (app.activities.size() > 0) { 11942 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11943 } 11944 outInfo.lastTrimLevel = app.trimMemoryLevel; 11945 int adj = app.curAdj; 11946 int procState = app.curProcState; 11947 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11948 outInfo.importanceReasonCode = app.adjTypeCode; 11949 outInfo.processState = app.curProcState; 11950 } 11951 11952 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11953 enforceNotIsolatedCaller("getRunningAppProcesses"); 11954 // Lazy instantiation of list 11955 List<ActivityManager.RunningAppProcessInfo> runList = null; 11956 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11957 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11958 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11959 synchronized (this) { 11960 // Iterate across all processes 11961 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11962 ProcessRecord app = mLruProcesses.get(i); 11963 if (!allUsers && app.userId != userId) { 11964 continue; 11965 } 11966 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11967 // Generate process state info for running application 11968 ActivityManager.RunningAppProcessInfo currApp = 11969 new ActivityManager.RunningAppProcessInfo(app.processName, 11970 app.pid, app.getPackageList()); 11971 fillInProcMemInfo(app, currApp); 11972 if (app.adjSource instanceof ProcessRecord) { 11973 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11974 currApp.importanceReasonImportance = 11975 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11976 app.adjSourceProcState); 11977 } else if (app.adjSource instanceof ActivityRecord) { 11978 ActivityRecord r = (ActivityRecord)app.adjSource; 11979 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11980 } 11981 if (app.adjTarget instanceof ComponentName) { 11982 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11983 } 11984 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11985 // + " lru=" + currApp.lru); 11986 if (runList == null) { 11987 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11988 } 11989 runList.add(currApp); 11990 } 11991 } 11992 } 11993 return runList; 11994 } 11995 11996 public List<ApplicationInfo> getRunningExternalApplications() { 11997 enforceNotIsolatedCaller("getRunningExternalApplications"); 11998 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11999 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12000 if (runningApps != null && runningApps.size() > 0) { 12001 Set<String> extList = new HashSet<String>(); 12002 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12003 if (app.pkgList != null) { 12004 for (String pkg : app.pkgList) { 12005 extList.add(pkg); 12006 } 12007 } 12008 } 12009 IPackageManager pm = AppGlobals.getPackageManager(); 12010 for (String pkg : extList) { 12011 try { 12012 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12013 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12014 retList.add(info); 12015 } 12016 } catch (RemoteException e) { 12017 } 12018 } 12019 } 12020 return retList; 12021 } 12022 12023 @Override 12024 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12025 enforceNotIsolatedCaller("getMyMemoryState"); 12026 synchronized (this) { 12027 ProcessRecord proc; 12028 synchronized (mPidsSelfLocked) { 12029 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12030 } 12031 fillInProcMemInfo(proc, outInfo); 12032 } 12033 } 12034 12035 @Override 12036 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12037 if (checkCallingPermission(android.Manifest.permission.DUMP) 12038 != PackageManager.PERMISSION_GRANTED) { 12039 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12040 + Binder.getCallingPid() 12041 + ", uid=" + Binder.getCallingUid() 12042 + " without permission " 12043 + android.Manifest.permission.DUMP); 12044 return; 12045 } 12046 12047 boolean dumpAll = false; 12048 boolean dumpClient = false; 12049 String dumpPackage = null; 12050 12051 int opti = 0; 12052 while (opti < args.length) { 12053 String opt = args[opti]; 12054 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12055 break; 12056 } 12057 opti++; 12058 if ("-a".equals(opt)) { 12059 dumpAll = true; 12060 } else if ("-c".equals(opt)) { 12061 dumpClient = true; 12062 } else if ("-h".equals(opt)) { 12063 pw.println("Activity manager dump options:"); 12064 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12065 pw.println(" cmd may be one of:"); 12066 pw.println(" a[ctivities]: activity stack state"); 12067 pw.println(" r[recents]: recent activities state"); 12068 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12069 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12070 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12071 pw.println(" o[om]: out of memory management"); 12072 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12073 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12074 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12075 pw.println(" service [COMP_SPEC]: service client-side state"); 12076 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12077 pw.println(" all: dump all activities"); 12078 pw.println(" top: dump the top activity"); 12079 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12080 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12081 pw.println(" a partial substring in a component name, a"); 12082 pw.println(" hex object identifier."); 12083 pw.println(" -a: include all available server state."); 12084 pw.println(" -c: include client state."); 12085 return; 12086 } else { 12087 pw.println("Unknown argument: " + opt + "; use -h for help"); 12088 } 12089 } 12090 12091 long origId = Binder.clearCallingIdentity(); 12092 boolean more = false; 12093 // Is the caller requesting to dump a particular piece of data? 12094 if (opti < args.length) { 12095 String cmd = args[opti]; 12096 opti++; 12097 if ("activities".equals(cmd) || "a".equals(cmd)) { 12098 synchronized (this) { 12099 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12100 } 12101 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12102 synchronized (this) { 12103 dumpRecentsLocked(fd, pw, args, opti, true, null); 12104 } 12105 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12106 String[] newArgs; 12107 String name; 12108 if (opti >= args.length) { 12109 name = null; 12110 newArgs = EMPTY_STRING_ARRAY; 12111 } else { 12112 name = 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 } 12118 synchronized (this) { 12119 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12120 } 12121 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12122 String[] newArgs; 12123 String name; 12124 if (opti >= args.length) { 12125 name = null; 12126 newArgs = EMPTY_STRING_ARRAY; 12127 } else { 12128 name = args[opti]; 12129 opti++; 12130 newArgs = new String[args.length - opti]; 12131 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12132 args.length - opti); 12133 } 12134 synchronized (this) { 12135 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12136 } 12137 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12138 String[] newArgs; 12139 String name; 12140 if (opti >= args.length) { 12141 name = null; 12142 newArgs = EMPTY_STRING_ARRAY; 12143 } else { 12144 name = args[opti]; 12145 opti++; 12146 newArgs = new String[args.length - opti]; 12147 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12148 args.length - opti); 12149 } 12150 synchronized (this) { 12151 dumpProcessesLocked(fd, pw, args, opti, true, name); 12152 } 12153 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12154 synchronized (this) { 12155 dumpOomLocked(fd, pw, args, opti, true); 12156 } 12157 } else if ("provider".equals(cmd)) { 12158 String[] newArgs; 12159 String name; 12160 if (opti >= args.length) { 12161 name = null; 12162 newArgs = EMPTY_STRING_ARRAY; 12163 } else { 12164 name = args[opti]; 12165 opti++; 12166 newArgs = new String[args.length - opti]; 12167 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12168 } 12169 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12170 pw.println("No providers match: " + name); 12171 pw.println("Use -h for help."); 12172 } 12173 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12174 synchronized (this) { 12175 dumpProvidersLocked(fd, pw, args, opti, true, null); 12176 } 12177 } else if ("service".equals(cmd)) { 12178 String[] newArgs; 12179 String name; 12180 if (opti >= args.length) { 12181 name = null; 12182 newArgs = EMPTY_STRING_ARRAY; 12183 } else { 12184 name = args[opti]; 12185 opti++; 12186 newArgs = new String[args.length - opti]; 12187 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12188 args.length - opti); 12189 } 12190 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12191 pw.println("No services match: " + name); 12192 pw.println("Use -h for help."); 12193 } 12194 } else if ("package".equals(cmd)) { 12195 String[] newArgs; 12196 if (opti >= args.length) { 12197 pw.println("package: no package name specified"); 12198 pw.println("Use -h for help."); 12199 } else { 12200 dumpPackage = args[opti]; 12201 opti++; 12202 newArgs = new String[args.length - opti]; 12203 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12204 args.length - opti); 12205 args = newArgs; 12206 opti = 0; 12207 more = true; 12208 } 12209 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12210 synchronized (this) { 12211 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12212 } 12213 } else { 12214 // Dumping a single activity? 12215 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12216 pw.println("Bad activity command, or no activities match: " + cmd); 12217 pw.println("Use -h for help."); 12218 } 12219 } 12220 if (!more) { 12221 Binder.restoreCallingIdentity(origId); 12222 return; 12223 } 12224 } 12225 12226 // No piece of data specified, dump everything. 12227 synchronized (this) { 12228 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12229 pw.println(); 12230 if (dumpAll) { 12231 pw.println("-------------------------------------------------------------------------------"); 12232 } 12233 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12234 pw.println(); 12235 if (dumpAll) { 12236 pw.println("-------------------------------------------------------------------------------"); 12237 } 12238 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12239 pw.println(); 12240 if (dumpAll) { 12241 pw.println("-------------------------------------------------------------------------------"); 12242 } 12243 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12244 pw.println(); 12245 if (dumpAll) { 12246 pw.println("-------------------------------------------------------------------------------"); 12247 } 12248 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12249 pw.println(); 12250 if (dumpAll) { 12251 pw.println("-------------------------------------------------------------------------------"); 12252 } 12253 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12254 pw.println(); 12255 if (dumpAll) { 12256 pw.println("-------------------------------------------------------------------------------"); 12257 } 12258 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12259 } 12260 Binder.restoreCallingIdentity(origId); 12261 } 12262 12263 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12264 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12265 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12266 12267 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12268 dumpPackage); 12269 boolean needSep = printedAnything; 12270 12271 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12272 dumpPackage, needSep, " mFocusedActivity: "); 12273 if (printed) { 12274 printedAnything = true; 12275 needSep = false; 12276 } 12277 12278 if (dumpPackage == null) { 12279 if (needSep) { 12280 pw.println(); 12281 } 12282 needSep = true; 12283 printedAnything = true; 12284 mStackSupervisor.dump(pw, " "); 12285 } 12286 12287 if (!printedAnything) { 12288 pw.println(" (nothing)"); 12289 } 12290 } 12291 12292 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12293 int opti, boolean dumpAll, String dumpPackage) { 12294 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12295 12296 boolean printedAnything = false; 12297 12298 if (mRecentTasks.size() > 0) { 12299 boolean printedHeader = false; 12300 12301 final int N = mRecentTasks.size(); 12302 for (int i=0; i<N; i++) { 12303 TaskRecord tr = mRecentTasks.get(i); 12304 if (dumpPackage != null) { 12305 if (tr.realActivity == null || 12306 !dumpPackage.equals(tr.realActivity)) { 12307 continue; 12308 } 12309 } 12310 if (!printedHeader) { 12311 pw.println(" Recent tasks:"); 12312 printedHeader = true; 12313 printedAnything = true; 12314 } 12315 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12316 pw.println(tr); 12317 if (dumpAll) { 12318 mRecentTasks.get(i).dump(pw, " "); 12319 } 12320 } 12321 } 12322 12323 if (!printedAnything) { 12324 pw.println(" (nothing)"); 12325 } 12326 } 12327 12328 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12329 int opti, boolean dumpAll, String dumpPackage) { 12330 boolean needSep = false; 12331 boolean printedAnything = false; 12332 int numPers = 0; 12333 12334 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12335 12336 if (dumpAll) { 12337 final int NP = mProcessNames.getMap().size(); 12338 for (int ip=0; ip<NP; ip++) { 12339 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12340 final int NA = procs.size(); 12341 for (int ia=0; ia<NA; ia++) { 12342 ProcessRecord r = procs.valueAt(ia); 12343 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12344 continue; 12345 } 12346 if (!needSep) { 12347 pw.println(" All known processes:"); 12348 needSep = true; 12349 printedAnything = true; 12350 } 12351 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12352 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12353 pw.print(" "); pw.println(r); 12354 r.dump(pw, " "); 12355 if (r.persistent) { 12356 numPers++; 12357 } 12358 } 12359 } 12360 } 12361 12362 if (mIsolatedProcesses.size() > 0) { 12363 boolean printed = false; 12364 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12365 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12366 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12367 continue; 12368 } 12369 if (!printed) { 12370 if (needSep) { 12371 pw.println(); 12372 } 12373 pw.println(" Isolated process list (sorted by uid):"); 12374 printedAnything = true; 12375 printed = true; 12376 needSep = true; 12377 } 12378 pw.println(String.format("%sIsolated #%2d: %s", 12379 " ", i, r.toString())); 12380 } 12381 } 12382 12383 if (mLruProcesses.size() > 0) { 12384 if (needSep) { 12385 pw.println(); 12386 } 12387 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12388 pw.print(" total, non-act at "); 12389 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12390 pw.print(", non-svc at "); 12391 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12392 pw.println("):"); 12393 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12394 needSep = true; 12395 printedAnything = true; 12396 } 12397 12398 if (dumpAll || dumpPackage != null) { 12399 synchronized (mPidsSelfLocked) { 12400 boolean printed = false; 12401 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12402 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12403 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12404 continue; 12405 } 12406 if (!printed) { 12407 if (needSep) pw.println(); 12408 needSep = true; 12409 pw.println(" PID mappings:"); 12410 printed = true; 12411 printedAnything = true; 12412 } 12413 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12414 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12415 } 12416 } 12417 } 12418 12419 if (mForegroundProcesses.size() > 0) { 12420 synchronized (mPidsSelfLocked) { 12421 boolean printed = false; 12422 for (int i=0; i<mForegroundProcesses.size(); i++) { 12423 ProcessRecord r = mPidsSelfLocked.get( 12424 mForegroundProcesses.valueAt(i).pid); 12425 if (dumpPackage != null && (r == null 12426 || !r.pkgList.containsKey(dumpPackage))) { 12427 continue; 12428 } 12429 if (!printed) { 12430 if (needSep) pw.println(); 12431 needSep = true; 12432 pw.println(" Foreground Processes:"); 12433 printed = true; 12434 printedAnything = true; 12435 } 12436 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12437 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12438 } 12439 } 12440 } 12441 12442 if (mPersistentStartingProcesses.size() > 0) { 12443 if (needSep) pw.println(); 12444 needSep = true; 12445 printedAnything = true; 12446 pw.println(" Persisent processes that are starting:"); 12447 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12448 "Starting Norm", "Restarting PERS", dumpPackage); 12449 } 12450 12451 if (mRemovedProcesses.size() > 0) { 12452 if (needSep) pw.println(); 12453 needSep = true; 12454 printedAnything = true; 12455 pw.println(" Processes that are being removed:"); 12456 dumpProcessList(pw, this, mRemovedProcesses, " ", 12457 "Removed Norm", "Removed PERS", dumpPackage); 12458 } 12459 12460 if (mProcessesOnHold.size() > 0) { 12461 if (needSep) pw.println(); 12462 needSep = true; 12463 printedAnything = true; 12464 pw.println(" Processes that are on old until the system is ready:"); 12465 dumpProcessList(pw, this, mProcessesOnHold, " ", 12466 "OnHold Norm", "OnHold PERS", dumpPackage); 12467 } 12468 12469 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12470 12471 if (mProcessCrashTimes.getMap().size() > 0) { 12472 boolean printed = false; 12473 long now = SystemClock.uptimeMillis(); 12474 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12475 final int NP = pmap.size(); 12476 for (int ip=0; ip<NP; ip++) { 12477 String pname = pmap.keyAt(ip); 12478 SparseArray<Long> uids = pmap.valueAt(ip); 12479 final int N = uids.size(); 12480 for (int i=0; i<N; i++) { 12481 int puid = uids.keyAt(i); 12482 ProcessRecord r = mProcessNames.get(pname, puid); 12483 if (dumpPackage != null && (r == null 12484 || !r.pkgList.containsKey(dumpPackage))) { 12485 continue; 12486 } 12487 if (!printed) { 12488 if (needSep) pw.println(); 12489 needSep = true; 12490 pw.println(" Time since processes crashed:"); 12491 printed = true; 12492 printedAnything = true; 12493 } 12494 pw.print(" Process "); pw.print(pname); 12495 pw.print(" uid "); pw.print(puid); 12496 pw.print(": last crashed "); 12497 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12498 pw.println(" ago"); 12499 } 12500 } 12501 } 12502 12503 if (mBadProcesses.getMap().size() > 0) { 12504 boolean printed = false; 12505 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12506 final int NP = pmap.size(); 12507 for (int ip=0; ip<NP; ip++) { 12508 String pname = pmap.keyAt(ip); 12509 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12510 final int N = uids.size(); 12511 for (int i=0; i<N; i++) { 12512 int puid = uids.keyAt(i); 12513 ProcessRecord r = mProcessNames.get(pname, puid); 12514 if (dumpPackage != null && (r == null 12515 || !r.pkgList.containsKey(dumpPackage))) { 12516 continue; 12517 } 12518 if (!printed) { 12519 if (needSep) pw.println(); 12520 needSep = true; 12521 pw.println(" Bad processes:"); 12522 printedAnything = true; 12523 } 12524 BadProcessInfo info = uids.valueAt(i); 12525 pw.print(" Bad process "); pw.print(pname); 12526 pw.print(" uid "); pw.print(puid); 12527 pw.print(": crashed at time "); pw.println(info.time); 12528 if (info.shortMsg != null) { 12529 pw.print(" Short msg: "); pw.println(info.shortMsg); 12530 } 12531 if (info.longMsg != null) { 12532 pw.print(" Long msg: "); pw.println(info.longMsg); 12533 } 12534 if (info.stack != null) { 12535 pw.println(" Stack:"); 12536 int lastPos = 0; 12537 for (int pos=0; pos<info.stack.length(); pos++) { 12538 if (info.stack.charAt(pos) == '\n') { 12539 pw.print(" "); 12540 pw.write(info.stack, lastPos, pos-lastPos); 12541 pw.println(); 12542 lastPos = pos+1; 12543 } 12544 } 12545 if (lastPos < info.stack.length()) { 12546 pw.print(" "); 12547 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12548 pw.println(); 12549 } 12550 } 12551 } 12552 } 12553 } 12554 12555 if (dumpPackage == null) { 12556 pw.println(); 12557 needSep = false; 12558 pw.println(" mStartedUsers:"); 12559 for (int i=0; i<mStartedUsers.size(); i++) { 12560 UserStartedState uss = mStartedUsers.valueAt(i); 12561 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12562 pw.print(": "); uss.dump("", pw); 12563 } 12564 pw.print(" mStartedUserArray: ["); 12565 for (int i=0; i<mStartedUserArray.length; i++) { 12566 if (i > 0) pw.print(", "); 12567 pw.print(mStartedUserArray[i]); 12568 } 12569 pw.println("]"); 12570 pw.print(" mUserLru: ["); 12571 for (int i=0; i<mUserLru.size(); i++) { 12572 if (i > 0) pw.print(", "); 12573 pw.print(mUserLru.get(i)); 12574 } 12575 pw.println("]"); 12576 if (dumpAll) { 12577 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12578 } 12579 synchronized (mUserProfileGroupIdsSelfLocked) { 12580 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12581 pw.println(" mUserProfileGroupIds:"); 12582 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12583 pw.print(" User #"); 12584 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12585 pw.print(" -> profile #"); 12586 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12587 } 12588 } 12589 } 12590 } 12591 if (mHomeProcess != null && (dumpPackage == null 12592 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12593 if (needSep) { 12594 pw.println(); 12595 needSep = false; 12596 } 12597 pw.println(" mHomeProcess: " + mHomeProcess); 12598 } 12599 if (mPreviousProcess != null && (dumpPackage == null 12600 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12601 if (needSep) { 12602 pw.println(); 12603 needSep = false; 12604 } 12605 pw.println(" mPreviousProcess: " + mPreviousProcess); 12606 } 12607 if (dumpAll) { 12608 StringBuilder sb = new StringBuilder(128); 12609 sb.append(" mPreviousProcessVisibleTime: "); 12610 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12611 pw.println(sb); 12612 } 12613 if (mHeavyWeightProcess != null && (dumpPackage == null 12614 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12615 if (needSep) { 12616 pw.println(); 12617 needSep = false; 12618 } 12619 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12620 } 12621 if (dumpPackage == null) { 12622 pw.println(" mConfiguration: " + mConfiguration); 12623 } 12624 if (dumpAll) { 12625 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12626 if (mCompatModePackages.getPackages().size() > 0) { 12627 boolean printed = false; 12628 for (Map.Entry<String, Integer> entry 12629 : mCompatModePackages.getPackages().entrySet()) { 12630 String pkg = entry.getKey(); 12631 int mode = entry.getValue(); 12632 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12633 continue; 12634 } 12635 if (!printed) { 12636 pw.println(" mScreenCompatPackages:"); 12637 printed = true; 12638 } 12639 pw.print(" "); pw.print(pkg); pw.print(": "); 12640 pw.print(mode); pw.println(); 12641 } 12642 } 12643 } 12644 if (dumpPackage == null) { 12645 if (mSleeping || mWentToSleep || mLockScreenShown) { 12646 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12647 + " mLockScreenShown " + mLockScreenShown); 12648 } 12649 if (mShuttingDown || mRunningVoice) { 12650 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12651 } 12652 } 12653 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12654 || mOrigWaitForDebugger) { 12655 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12656 || dumpPackage.equals(mOrigDebugApp)) { 12657 if (needSep) { 12658 pw.println(); 12659 needSep = false; 12660 } 12661 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12662 + " mDebugTransient=" + mDebugTransient 12663 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12664 } 12665 } 12666 if (mOpenGlTraceApp != null) { 12667 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12668 if (needSep) { 12669 pw.println(); 12670 needSep = false; 12671 } 12672 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12673 } 12674 } 12675 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12676 || mProfileFd != null) { 12677 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12678 if (needSep) { 12679 pw.println(); 12680 needSep = false; 12681 } 12682 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12683 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12684 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12685 + mAutoStopProfiler); 12686 pw.println(" mProfileType=" + mProfileType); 12687 } 12688 } 12689 if (dumpPackage == null) { 12690 if (mAlwaysFinishActivities || mController != null) { 12691 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12692 + " mController=" + mController); 12693 } 12694 if (dumpAll) { 12695 pw.println(" Total persistent processes: " + numPers); 12696 pw.println(" mProcessesReady=" + mProcessesReady 12697 + " mSystemReady=" + mSystemReady); 12698 pw.println(" mBooting=" + mBooting 12699 + " mBooted=" + mBooted 12700 + " mFactoryTest=" + mFactoryTest); 12701 pw.print(" mLastPowerCheckRealtime="); 12702 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12703 pw.println(""); 12704 pw.print(" mLastPowerCheckUptime="); 12705 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12706 pw.println(""); 12707 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12708 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12709 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12710 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12711 + " (" + mLruProcesses.size() + " total)" 12712 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12713 + " mNumServiceProcs=" + mNumServiceProcs 12714 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12715 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12716 + " mLastMemoryLevel" + mLastMemoryLevel 12717 + " mLastNumProcesses" + mLastNumProcesses); 12718 long now = SystemClock.uptimeMillis(); 12719 pw.print(" mLastIdleTime="); 12720 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12721 pw.print(" mLowRamSinceLastIdle="); 12722 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12723 pw.println(); 12724 } 12725 } 12726 12727 if (!printedAnything) { 12728 pw.println(" (nothing)"); 12729 } 12730 } 12731 12732 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12733 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12734 if (mProcessesToGc.size() > 0) { 12735 boolean printed = false; 12736 long now = SystemClock.uptimeMillis(); 12737 for (int i=0; i<mProcessesToGc.size(); i++) { 12738 ProcessRecord proc = mProcessesToGc.get(i); 12739 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12740 continue; 12741 } 12742 if (!printed) { 12743 if (needSep) pw.println(); 12744 needSep = true; 12745 pw.println(" Processes that are waiting to GC:"); 12746 printed = true; 12747 } 12748 pw.print(" Process "); pw.println(proc); 12749 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12750 pw.print(", last gced="); 12751 pw.print(now-proc.lastRequestedGc); 12752 pw.print(" ms ago, last lowMem="); 12753 pw.print(now-proc.lastLowMemory); 12754 pw.println(" ms ago"); 12755 12756 } 12757 } 12758 return needSep; 12759 } 12760 12761 void printOomLevel(PrintWriter pw, String name, int adj) { 12762 pw.print(" "); 12763 if (adj >= 0) { 12764 pw.print(' '); 12765 if (adj < 10) pw.print(' '); 12766 } else { 12767 if (adj > -10) pw.print(' '); 12768 } 12769 pw.print(adj); 12770 pw.print(": "); 12771 pw.print(name); 12772 pw.print(" ("); 12773 pw.print(mProcessList.getMemLevel(adj)/1024); 12774 pw.println(" kB)"); 12775 } 12776 12777 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12778 int opti, boolean dumpAll) { 12779 boolean needSep = false; 12780 12781 if (mLruProcesses.size() > 0) { 12782 if (needSep) pw.println(); 12783 needSep = true; 12784 pw.println(" OOM levels:"); 12785 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12786 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12787 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12788 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12789 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12790 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12791 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12792 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12793 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12794 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12795 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12796 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12797 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12798 12799 if (needSep) pw.println(); 12800 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12801 pw.print(" total, non-act at "); 12802 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12803 pw.print(", non-svc at "); 12804 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12805 pw.println("):"); 12806 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12807 needSep = true; 12808 } 12809 12810 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12811 12812 pw.println(); 12813 pw.println(" mHomeProcess: " + mHomeProcess); 12814 pw.println(" mPreviousProcess: " + mPreviousProcess); 12815 if (mHeavyWeightProcess != null) { 12816 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12817 } 12818 12819 return true; 12820 } 12821 12822 /** 12823 * There are three ways to call this: 12824 * - no provider specified: dump all the providers 12825 * - a flattened component name that matched an existing provider was specified as the 12826 * first arg: dump that one provider 12827 * - the first arg isn't the flattened component name of an existing provider: 12828 * dump all providers whose component contains the first arg as a substring 12829 */ 12830 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12831 int opti, boolean dumpAll) { 12832 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12833 } 12834 12835 static class ItemMatcher { 12836 ArrayList<ComponentName> components; 12837 ArrayList<String> strings; 12838 ArrayList<Integer> objects; 12839 boolean all; 12840 12841 ItemMatcher() { 12842 all = true; 12843 } 12844 12845 void build(String name) { 12846 ComponentName componentName = ComponentName.unflattenFromString(name); 12847 if (componentName != null) { 12848 if (components == null) { 12849 components = new ArrayList<ComponentName>(); 12850 } 12851 components.add(componentName); 12852 all = false; 12853 } else { 12854 int objectId = 0; 12855 // Not a '/' separated full component name; maybe an object ID? 12856 try { 12857 objectId = Integer.parseInt(name, 16); 12858 if (objects == null) { 12859 objects = new ArrayList<Integer>(); 12860 } 12861 objects.add(objectId); 12862 all = false; 12863 } catch (RuntimeException e) { 12864 // Not an integer; just do string match. 12865 if (strings == null) { 12866 strings = new ArrayList<String>(); 12867 } 12868 strings.add(name); 12869 all = false; 12870 } 12871 } 12872 } 12873 12874 int build(String[] args, int opti) { 12875 for (; opti<args.length; opti++) { 12876 String name = args[opti]; 12877 if ("--".equals(name)) { 12878 return opti+1; 12879 } 12880 build(name); 12881 } 12882 return opti; 12883 } 12884 12885 boolean match(Object object, ComponentName comp) { 12886 if (all) { 12887 return true; 12888 } 12889 if (components != null) { 12890 for (int i=0; i<components.size(); i++) { 12891 if (components.get(i).equals(comp)) { 12892 return true; 12893 } 12894 } 12895 } 12896 if (objects != null) { 12897 for (int i=0; i<objects.size(); i++) { 12898 if (System.identityHashCode(object) == objects.get(i)) { 12899 return true; 12900 } 12901 } 12902 } 12903 if (strings != null) { 12904 String flat = comp.flattenToString(); 12905 for (int i=0; i<strings.size(); i++) { 12906 if (flat.contains(strings.get(i))) { 12907 return true; 12908 } 12909 } 12910 } 12911 return false; 12912 } 12913 } 12914 12915 /** 12916 * There are three things that cmd can be: 12917 * - a flattened component name that matches an existing activity 12918 * - the cmd arg isn't the flattened component name of an existing activity: 12919 * dump all activity whose component contains the cmd as a substring 12920 * - A hex number of the ActivityRecord object instance. 12921 */ 12922 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12923 int opti, boolean dumpAll) { 12924 ArrayList<ActivityRecord> activities; 12925 12926 synchronized (this) { 12927 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12928 } 12929 12930 if (activities.size() <= 0) { 12931 return false; 12932 } 12933 12934 String[] newArgs = new String[args.length - opti]; 12935 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12936 12937 TaskRecord lastTask = null; 12938 boolean needSep = false; 12939 for (int i=activities.size()-1; i>=0; i--) { 12940 ActivityRecord r = activities.get(i); 12941 if (needSep) { 12942 pw.println(); 12943 } 12944 needSep = true; 12945 synchronized (this) { 12946 if (lastTask != r.task) { 12947 lastTask = r.task; 12948 pw.print("TASK "); pw.print(lastTask.affinity); 12949 pw.print(" id="); pw.println(lastTask.taskId); 12950 if (dumpAll) { 12951 lastTask.dump(pw, " "); 12952 } 12953 } 12954 } 12955 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12956 } 12957 return true; 12958 } 12959 12960 /** 12961 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12962 * there is a thread associated with the activity. 12963 */ 12964 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12965 final ActivityRecord r, String[] args, boolean dumpAll) { 12966 String innerPrefix = prefix + " "; 12967 synchronized (this) { 12968 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12969 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12970 pw.print(" pid="); 12971 if (r.app != null) pw.println(r.app.pid); 12972 else pw.println("(not running)"); 12973 if (dumpAll) { 12974 r.dump(pw, innerPrefix); 12975 } 12976 } 12977 if (r.app != null && r.app.thread != null) { 12978 // flush anything that is already in the PrintWriter since the thread is going 12979 // to write to the file descriptor directly 12980 pw.flush(); 12981 try { 12982 TransferPipe tp = new TransferPipe(); 12983 try { 12984 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12985 r.appToken, innerPrefix, args); 12986 tp.go(fd); 12987 } finally { 12988 tp.kill(); 12989 } 12990 } catch (IOException e) { 12991 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12992 } catch (RemoteException e) { 12993 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12994 } 12995 } 12996 } 12997 12998 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12999 int opti, boolean dumpAll, String dumpPackage) { 13000 boolean needSep = false; 13001 boolean onlyHistory = false; 13002 boolean printedAnything = false; 13003 13004 if ("history".equals(dumpPackage)) { 13005 if (opti < args.length && "-s".equals(args[opti])) { 13006 dumpAll = false; 13007 } 13008 onlyHistory = true; 13009 dumpPackage = null; 13010 } 13011 13012 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13013 if (!onlyHistory && dumpAll) { 13014 if (mRegisteredReceivers.size() > 0) { 13015 boolean printed = false; 13016 Iterator it = mRegisteredReceivers.values().iterator(); 13017 while (it.hasNext()) { 13018 ReceiverList r = (ReceiverList)it.next(); 13019 if (dumpPackage != null && (r.app == null || 13020 !dumpPackage.equals(r.app.info.packageName))) { 13021 continue; 13022 } 13023 if (!printed) { 13024 pw.println(" Registered Receivers:"); 13025 needSep = true; 13026 printed = true; 13027 printedAnything = true; 13028 } 13029 pw.print(" * "); pw.println(r); 13030 r.dump(pw, " "); 13031 } 13032 } 13033 13034 if (mReceiverResolver.dump(pw, needSep ? 13035 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13036 " ", dumpPackage, false)) { 13037 needSep = true; 13038 printedAnything = true; 13039 } 13040 } 13041 13042 for (BroadcastQueue q : mBroadcastQueues) { 13043 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13044 printedAnything |= needSep; 13045 } 13046 13047 needSep = true; 13048 13049 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13050 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13051 if (needSep) { 13052 pw.println(); 13053 } 13054 needSep = true; 13055 printedAnything = true; 13056 pw.print(" Sticky broadcasts for user "); 13057 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13058 StringBuilder sb = new StringBuilder(128); 13059 for (Map.Entry<String, ArrayList<Intent>> ent 13060 : mStickyBroadcasts.valueAt(user).entrySet()) { 13061 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13062 if (dumpAll) { 13063 pw.println(":"); 13064 ArrayList<Intent> intents = ent.getValue(); 13065 final int N = intents.size(); 13066 for (int i=0; i<N; i++) { 13067 sb.setLength(0); 13068 sb.append(" Intent: "); 13069 intents.get(i).toShortString(sb, false, true, false, false); 13070 pw.println(sb.toString()); 13071 Bundle bundle = intents.get(i).getExtras(); 13072 if (bundle != null) { 13073 pw.print(" "); 13074 pw.println(bundle.toString()); 13075 } 13076 } 13077 } else { 13078 pw.println(""); 13079 } 13080 } 13081 } 13082 } 13083 13084 if (!onlyHistory && dumpAll) { 13085 pw.println(); 13086 for (BroadcastQueue queue : mBroadcastQueues) { 13087 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13088 + queue.mBroadcastsScheduled); 13089 } 13090 pw.println(" mHandler:"); 13091 mHandler.dump(new PrintWriterPrinter(pw), " "); 13092 needSep = true; 13093 printedAnything = true; 13094 } 13095 13096 if (!printedAnything) { 13097 pw.println(" (nothing)"); 13098 } 13099 } 13100 13101 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13102 int opti, boolean dumpAll, String dumpPackage) { 13103 boolean needSep; 13104 boolean printedAnything = false; 13105 13106 ItemMatcher matcher = new ItemMatcher(); 13107 matcher.build(args, opti); 13108 13109 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13110 13111 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13112 printedAnything |= needSep; 13113 13114 if (mLaunchingProviders.size() > 0) { 13115 boolean printed = false; 13116 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13117 ContentProviderRecord r = mLaunchingProviders.get(i); 13118 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13119 continue; 13120 } 13121 if (!printed) { 13122 if (needSep) pw.println(); 13123 needSep = true; 13124 pw.println(" Launching content providers:"); 13125 printed = true; 13126 printedAnything = true; 13127 } 13128 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13129 pw.println(r); 13130 } 13131 } 13132 13133 if (mGrantedUriPermissions.size() > 0) { 13134 boolean printed = false; 13135 int dumpUid = -2; 13136 if (dumpPackage != null) { 13137 try { 13138 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13139 } catch (NameNotFoundException e) { 13140 dumpUid = -1; 13141 } 13142 } 13143 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13144 int uid = mGrantedUriPermissions.keyAt(i); 13145 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13146 continue; 13147 } 13148 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13149 if (!printed) { 13150 if (needSep) pw.println(); 13151 needSep = true; 13152 pw.println(" Granted Uri Permissions:"); 13153 printed = true; 13154 printedAnything = true; 13155 } 13156 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13157 for (UriPermission perm : perms.values()) { 13158 pw.print(" "); pw.println(perm); 13159 if (dumpAll) { 13160 perm.dump(pw, " "); 13161 } 13162 } 13163 } 13164 } 13165 13166 if (!printedAnything) { 13167 pw.println(" (nothing)"); 13168 } 13169 } 13170 13171 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13172 int opti, boolean dumpAll, String dumpPackage) { 13173 boolean printed = false; 13174 13175 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13176 13177 if (mIntentSenderRecords.size() > 0) { 13178 Iterator<WeakReference<PendingIntentRecord>> it 13179 = mIntentSenderRecords.values().iterator(); 13180 while (it.hasNext()) { 13181 WeakReference<PendingIntentRecord> ref = it.next(); 13182 PendingIntentRecord rec = ref != null ? ref.get(): null; 13183 if (dumpPackage != null && (rec == null 13184 || !dumpPackage.equals(rec.key.packageName))) { 13185 continue; 13186 } 13187 printed = true; 13188 if (rec != null) { 13189 pw.print(" * "); pw.println(rec); 13190 if (dumpAll) { 13191 rec.dump(pw, " "); 13192 } 13193 } else { 13194 pw.print(" * "); pw.println(ref); 13195 } 13196 } 13197 } 13198 13199 if (!printed) { 13200 pw.println(" (nothing)"); 13201 } 13202 } 13203 13204 private static final int dumpProcessList(PrintWriter pw, 13205 ActivityManagerService service, List list, 13206 String prefix, String normalLabel, String persistentLabel, 13207 String dumpPackage) { 13208 int numPers = 0; 13209 final int N = list.size()-1; 13210 for (int i=N; i>=0; i--) { 13211 ProcessRecord r = (ProcessRecord)list.get(i); 13212 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13213 continue; 13214 } 13215 pw.println(String.format("%s%s #%2d: %s", 13216 prefix, (r.persistent ? persistentLabel : normalLabel), 13217 i, r.toString())); 13218 if (r.persistent) { 13219 numPers++; 13220 } 13221 } 13222 return numPers; 13223 } 13224 13225 private static final boolean dumpProcessOomList(PrintWriter pw, 13226 ActivityManagerService service, List<ProcessRecord> origList, 13227 String prefix, String normalLabel, String persistentLabel, 13228 boolean inclDetails, String dumpPackage) { 13229 13230 ArrayList<Pair<ProcessRecord, Integer>> list 13231 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13232 for (int i=0; i<origList.size(); i++) { 13233 ProcessRecord r = origList.get(i); 13234 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13235 continue; 13236 } 13237 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13238 } 13239 13240 if (list.size() <= 0) { 13241 return false; 13242 } 13243 13244 Comparator<Pair<ProcessRecord, Integer>> comparator 13245 = new Comparator<Pair<ProcessRecord, Integer>>() { 13246 @Override 13247 public int compare(Pair<ProcessRecord, Integer> object1, 13248 Pair<ProcessRecord, Integer> object2) { 13249 if (object1.first.setAdj != object2.first.setAdj) { 13250 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13251 } 13252 if (object1.second.intValue() != object2.second.intValue()) { 13253 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13254 } 13255 return 0; 13256 } 13257 }; 13258 13259 Collections.sort(list, comparator); 13260 13261 final long curRealtime = SystemClock.elapsedRealtime(); 13262 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13263 final long curUptime = SystemClock.uptimeMillis(); 13264 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13265 13266 for (int i=list.size()-1; i>=0; i--) { 13267 ProcessRecord r = list.get(i).first; 13268 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13269 char schedGroup; 13270 switch (r.setSchedGroup) { 13271 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13272 schedGroup = 'B'; 13273 break; 13274 case Process.THREAD_GROUP_DEFAULT: 13275 schedGroup = 'F'; 13276 break; 13277 default: 13278 schedGroup = '?'; 13279 break; 13280 } 13281 char foreground; 13282 if (r.foregroundActivities) { 13283 foreground = 'A'; 13284 } else if (r.foregroundServices) { 13285 foreground = 'S'; 13286 } else { 13287 foreground = ' '; 13288 } 13289 String procState = ProcessList.makeProcStateString(r.curProcState); 13290 pw.print(prefix); 13291 pw.print(r.persistent ? persistentLabel : normalLabel); 13292 pw.print(" #"); 13293 int num = (origList.size()-1)-list.get(i).second; 13294 if (num < 10) pw.print(' '); 13295 pw.print(num); 13296 pw.print(": "); 13297 pw.print(oomAdj); 13298 pw.print(' '); 13299 pw.print(schedGroup); 13300 pw.print('/'); 13301 pw.print(foreground); 13302 pw.print('/'); 13303 pw.print(procState); 13304 pw.print(" trm:"); 13305 if (r.trimMemoryLevel < 10) pw.print(' '); 13306 pw.print(r.trimMemoryLevel); 13307 pw.print(' '); 13308 pw.print(r.toShortString()); 13309 pw.print(" ("); 13310 pw.print(r.adjType); 13311 pw.println(')'); 13312 if (r.adjSource != null || r.adjTarget != null) { 13313 pw.print(prefix); 13314 pw.print(" "); 13315 if (r.adjTarget instanceof ComponentName) { 13316 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13317 } else if (r.adjTarget != null) { 13318 pw.print(r.adjTarget.toString()); 13319 } else { 13320 pw.print("{null}"); 13321 } 13322 pw.print("<="); 13323 if (r.adjSource instanceof ProcessRecord) { 13324 pw.print("Proc{"); 13325 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13326 pw.println("}"); 13327 } else if (r.adjSource != null) { 13328 pw.println(r.adjSource.toString()); 13329 } else { 13330 pw.println("{null}"); 13331 } 13332 } 13333 if (inclDetails) { 13334 pw.print(prefix); 13335 pw.print(" "); 13336 pw.print("oom: max="); pw.print(r.maxAdj); 13337 pw.print(" curRaw="); pw.print(r.curRawAdj); 13338 pw.print(" setRaw="); pw.print(r.setRawAdj); 13339 pw.print(" cur="); pw.print(r.curAdj); 13340 pw.print(" set="); pw.println(r.setAdj); 13341 pw.print(prefix); 13342 pw.print(" "); 13343 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13344 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13345 pw.print(" lastPss="); pw.print(r.lastPss); 13346 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13347 pw.print(prefix); 13348 pw.print(" "); 13349 pw.print("cached="); pw.print(r.cached); 13350 pw.print(" empty="); pw.print(r.empty); 13351 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13352 13353 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13354 if (r.lastWakeTime != 0) { 13355 long wtime; 13356 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13357 synchronized (stats) { 13358 wtime = stats.getProcessWakeTime(r.info.uid, 13359 r.pid, curRealtime); 13360 } 13361 long timeUsed = wtime - r.lastWakeTime; 13362 pw.print(prefix); 13363 pw.print(" "); 13364 pw.print("keep awake over "); 13365 TimeUtils.formatDuration(realtimeSince, pw); 13366 pw.print(" used "); 13367 TimeUtils.formatDuration(timeUsed, pw); 13368 pw.print(" ("); 13369 pw.print((timeUsed*100)/realtimeSince); 13370 pw.println("%)"); 13371 } 13372 if (r.lastCpuTime != 0) { 13373 long timeUsed = r.curCpuTime - r.lastCpuTime; 13374 pw.print(prefix); 13375 pw.print(" "); 13376 pw.print("run cpu over "); 13377 TimeUtils.formatDuration(uptimeSince, pw); 13378 pw.print(" used "); 13379 TimeUtils.formatDuration(timeUsed, pw); 13380 pw.print(" ("); 13381 pw.print((timeUsed*100)/uptimeSince); 13382 pw.println("%)"); 13383 } 13384 } 13385 } 13386 } 13387 return true; 13388 } 13389 13390 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13391 ArrayList<ProcessRecord> procs; 13392 synchronized (this) { 13393 if (args != null && args.length > start 13394 && args[start].charAt(0) != '-') { 13395 procs = new ArrayList<ProcessRecord>(); 13396 int pid = -1; 13397 try { 13398 pid = Integer.parseInt(args[start]); 13399 } catch (NumberFormatException e) { 13400 } 13401 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13402 ProcessRecord proc = mLruProcesses.get(i); 13403 if (proc.pid == pid) { 13404 procs.add(proc); 13405 } else if (proc.processName.equals(args[start])) { 13406 procs.add(proc); 13407 } 13408 } 13409 if (procs.size() <= 0) { 13410 return null; 13411 } 13412 } else { 13413 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13414 } 13415 } 13416 return procs; 13417 } 13418 13419 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13420 PrintWriter pw, String[] args) { 13421 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13422 if (procs == null) { 13423 pw.println("No process found for: " + args[0]); 13424 return; 13425 } 13426 13427 long uptime = SystemClock.uptimeMillis(); 13428 long realtime = SystemClock.elapsedRealtime(); 13429 pw.println("Applications Graphics Acceleration Info:"); 13430 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13431 13432 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13433 ProcessRecord r = procs.get(i); 13434 if (r.thread != null) { 13435 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13436 pw.flush(); 13437 try { 13438 TransferPipe tp = new TransferPipe(); 13439 try { 13440 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13441 tp.go(fd); 13442 } finally { 13443 tp.kill(); 13444 } 13445 } catch (IOException e) { 13446 pw.println("Failure while dumping the app: " + r); 13447 pw.flush(); 13448 } catch (RemoteException e) { 13449 pw.println("Got a RemoteException while dumping the app " + r); 13450 pw.flush(); 13451 } 13452 } 13453 } 13454 } 13455 13456 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13457 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13458 if (procs == null) { 13459 pw.println("No process found for: " + args[0]); 13460 return; 13461 } 13462 13463 pw.println("Applications Database Info:"); 13464 13465 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13466 ProcessRecord r = procs.get(i); 13467 if (r.thread != null) { 13468 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13469 pw.flush(); 13470 try { 13471 TransferPipe tp = new TransferPipe(); 13472 try { 13473 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13474 tp.go(fd); 13475 } finally { 13476 tp.kill(); 13477 } 13478 } catch (IOException e) { 13479 pw.println("Failure while dumping the app: " + r); 13480 pw.flush(); 13481 } catch (RemoteException e) { 13482 pw.println("Got a RemoteException while dumping the app " + r); 13483 pw.flush(); 13484 } 13485 } 13486 } 13487 } 13488 13489 final static class MemItem { 13490 final boolean isProc; 13491 final String label; 13492 final String shortLabel; 13493 final long pss; 13494 final int id; 13495 final boolean hasActivities; 13496 ArrayList<MemItem> subitems; 13497 13498 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13499 boolean _hasActivities) { 13500 isProc = true; 13501 label = _label; 13502 shortLabel = _shortLabel; 13503 pss = _pss; 13504 id = _id; 13505 hasActivities = _hasActivities; 13506 } 13507 13508 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13509 isProc = false; 13510 label = _label; 13511 shortLabel = _shortLabel; 13512 pss = _pss; 13513 id = _id; 13514 hasActivities = false; 13515 } 13516 } 13517 13518 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13519 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13520 if (sort && !isCompact) { 13521 Collections.sort(items, new Comparator<MemItem>() { 13522 @Override 13523 public int compare(MemItem lhs, MemItem rhs) { 13524 if (lhs.pss < rhs.pss) { 13525 return 1; 13526 } else if (lhs.pss > rhs.pss) { 13527 return -1; 13528 } 13529 return 0; 13530 } 13531 }); 13532 } 13533 13534 for (int i=0; i<items.size(); i++) { 13535 MemItem mi = items.get(i); 13536 if (!isCompact) { 13537 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13538 } else if (mi.isProc) { 13539 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13540 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13541 pw.println(mi.hasActivities ? ",a" : ",e"); 13542 } else { 13543 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13544 pw.println(mi.pss); 13545 } 13546 if (mi.subitems != null) { 13547 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13548 true, isCompact); 13549 } 13550 } 13551 } 13552 13553 // These are in KB. 13554 static final long[] DUMP_MEM_BUCKETS = new long[] { 13555 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13556 120*1024, 160*1024, 200*1024, 13557 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13558 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13559 }; 13560 13561 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13562 boolean stackLike) { 13563 int start = label.lastIndexOf('.'); 13564 if (start >= 0) start++; 13565 else start = 0; 13566 int end = label.length(); 13567 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13568 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13569 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13570 out.append(bucket); 13571 out.append(stackLike ? "MB." : "MB "); 13572 out.append(label, start, end); 13573 return; 13574 } 13575 } 13576 out.append(memKB/1024); 13577 out.append(stackLike ? "MB." : "MB "); 13578 out.append(label, start, end); 13579 } 13580 13581 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13582 ProcessList.NATIVE_ADJ, 13583 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13584 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13585 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13586 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13587 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13588 }; 13589 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13590 "Native", 13591 "System", "Persistent", "Foreground", 13592 "Visible", "Perceptible", 13593 "Heavy Weight", "Backup", 13594 "A Services", "Home", 13595 "Previous", "B Services", "Cached" 13596 }; 13597 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13598 "native", 13599 "sys", "pers", "fore", 13600 "vis", "percept", 13601 "heavy", "backup", 13602 "servicea", "home", 13603 "prev", "serviceb", "cached" 13604 }; 13605 13606 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13607 long realtime, boolean isCheckinRequest, boolean isCompact) { 13608 if (isCheckinRequest || isCompact) { 13609 // short checkin version 13610 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13611 } else { 13612 pw.println("Applications Memory Usage (kB):"); 13613 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13614 } 13615 } 13616 13617 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13618 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13619 boolean dumpDetails = false; 13620 boolean dumpFullDetails = false; 13621 boolean dumpDalvik = false; 13622 boolean oomOnly = false; 13623 boolean isCompact = false; 13624 boolean localOnly = false; 13625 13626 int opti = 0; 13627 while (opti < args.length) { 13628 String opt = args[opti]; 13629 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13630 break; 13631 } 13632 opti++; 13633 if ("-a".equals(opt)) { 13634 dumpDetails = true; 13635 dumpFullDetails = true; 13636 dumpDalvik = true; 13637 } else if ("-d".equals(opt)) { 13638 dumpDalvik = true; 13639 } else if ("-c".equals(opt)) { 13640 isCompact = true; 13641 } else if ("--oom".equals(opt)) { 13642 oomOnly = true; 13643 } else if ("--local".equals(opt)) { 13644 localOnly = true; 13645 } else if ("-h".equals(opt)) { 13646 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13647 pw.println(" -a: include all available information for each process."); 13648 pw.println(" -d: include dalvik details when dumping process details."); 13649 pw.println(" -c: dump in a compact machine-parseable representation."); 13650 pw.println(" --oom: only show processes organized by oom adj."); 13651 pw.println(" --local: only collect details locally, don't call process."); 13652 pw.println("If [process] is specified it can be the name or "); 13653 pw.println("pid of a specific process to dump."); 13654 return; 13655 } else { 13656 pw.println("Unknown argument: " + opt + "; use -h for help"); 13657 } 13658 } 13659 13660 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13661 long uptime = SystemClock.uptimeMillis(); 13662 long realtime = SystemClock.elapsedRealtime(); 13663 final long[] tmpLong = new long[1]; 13664 13665 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13666 if (procs == null) { 13667 // No Java processes. Maybe they want to print a native process. 13668 if (args != null && args.length > opti 13669 && args[opti].charAt(0) != '-') { 13670 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13671 = new ArrayList<ProcessCpuTracker.Stats>(); 13672 updateCpuStatsNow(); 13673 int findPid = -1; 13674 try { 13675 findPid = Integer.parseInt(args[opti]); 13676 } catch (NumberFormatException e) { 13677 } 13678 synchronized (mProcessCpuThread) { 13679 final int N = mProcessCpuTracker.countStats(); 13680 for (int i=0; i<N; i++) { 13681 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13682 if (st.pid == findPid || (st.baseName != null 13683 && st.baseName.equals(args[opti]))) { 13684 nativeProcs.add(st); 13685 } 13686 } 13687 } 13688 if (nativeProcs.size() > 0) { 13689 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13690 isCompact); 13691 Debug.MemoryInfo mi = null; 13692 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13693 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13694 final int pid = r.pid; 13695 if (!isCheckinRequest && dumpDetails) { 13696 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13697 } 13698 if (mi == null) { 13699 mi = new Debug.MemoryInfo(); 13700 } 13701 if (dumpDetails || (!brief && !oomOnly)) { 13702 Debug.getMemoryInfo(pid, mi); 13703 } else { 13704 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13705 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13706 } 13707 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13708 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13709 if (isCheckinRequest) { 13710 pw.println(); 13711 } 13712 } 13713 return; 13714 } 13715 } 13716 pw.println("No process found for: " + args[opti]); 13717 return; 13718 } 13719 13720 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13721 dumpDetails = true; 13722 } 13723 13724 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13725 13726 String[] innerArgs = new String[args.length-opti]; 13727 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13728 13729 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13730 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13731 long nativePss=0, dalvikPss=0, otherPss=0; 13732 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13733 13734 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13735 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13736 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13737 13738 long totalPss = 0; 13739 long cachedPss = 0; 13740 13741 Debug.MemoryInfo mi = null; 13742 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13743 final ProcessRecord r = procs.get(i); 13744 final IApplicationThread thread; 13745 final int pid; 13746 final int oomAdj; 13747 final boolean hasActivities; 13748 synchronized (this) { 13749 thread = r.thread; 13750 pid = r.pid; 13751 oomAdj = r.getSetAdjWithServices(); 13752 hasActivities = r.activities.size() > 0; 13753 } 13754 if (thread != null) { 13755 if (!isCheckinRequest && dumpDetails) { 13756 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13757 } 13758 if (mi == null) { 13759 mi = new Debug.MemoryInfo(); 13760 } 13761 if (dumpDetails || (!brief && !oomOnly)) { 13762 Debug.getMemoryInfo(pid, mi); 13763 } else { 13764 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13765 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13766 } 13767 if (dumpDetails) { 13768 if (localOnly) { 13769 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13770 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13771 if (isCheckinRequest) { 13772 pw.println(); 13773 } 13774 } else { 13775 try { 13776 pw.flush(); 13777 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13778 dumpDalvik, innerArgs); 13779 } catch (RemoteException e) { 13780 if (!isCheckinRequest) { 13781 pw.println("Got RemoteException!"); 13782 pw.flush(); 13783 } 13784 } 13785 } 13786 } 13787 13788 final long myTotalPss = mi.getTotalPss(); 13789 final long myTotalUss = mi.getTotalUss(); 13790 13791 synchronized (this) { 13792 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13793 // Record this for posterity if the process has been stable. 13794 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13795 } 13796 } 13797 13798 if (!isCheckinRequest && mi != null) { 13799 totalPss += myTotalPss; 13800 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13801 (hasActivities ? " / activities)" : ")"), 13802 r.processName, myTotalPss, pid, hasActivities); 13803 procMems.add(pssItem); 13804 procMemsMap.put(pid, pssItem); 13805 13806 nativePss += mi.nativePss; 13807 dalvikPss += mi.dalvikPss; 13808 otherPss += mi.otherPss; 13809 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13810 long mem = mi.getOtherPss(j); 13811 miscPss[j] += mem; 13812 otherPss -= mem; 13813 } 13814 13815 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13816 cachedPss += myTotalPss; 13817 } 13818 13819 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13820 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13821 || oomIndex == (oomPss.length-1)) { 13822 oomPss[oomIndex] += myTotalPss; 13823 if (oomProcs[oomIndex] == null) { 13824 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13825 } 13826 oomProcs[oomIndex].add(pssItem); 13827 break; 13828 } 13829 } 13830 } 13831 } 13832 } 13833 13834 long nativeProcTotalPss = 0; 13835 13836 if (!isCheckinRequest && procs.size() > 1) { 13837 // If we are showing aggregations, also look for native processes to 13838 // include so that our aggregations are more accurate. 13839 updateCpuStatsNow(); 13840 synchronized (mProcessCpuThread) { 13841 final int N = mProcessCpuTracker.countStats(); 13842 for (int i=0; i<N; i++) { 13843 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13844 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13845 if (mi == null) { 13846 mi = new Debug.MemoryInfo(); 13847 } 13848 if (!brief && !oomOnly) { 13849 Debug.getMemoryInfo(st.pid, mi); 13850 } else { 13851 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13852 mi.nativePrivateDirty = (int)tmpLong[0]; 13853 } 13854 13855 final long myTotalPss = mi.getTotalPss(); 13856 totalPss += myTotalPss; 13857 nativeProcTotalPss += myTotalPss; 13858 13859 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13860 st.name, myTotalPss, st.pid, false); 13861 procMems.add(pssItem); 13862 13863 nativePss += mi.nativePss; 13864 dalvikPss += mi.dalvikPss; 13865 otherPss += mi.otherPss; 13866 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13867 long mem = mi.getOtherPss(j); 13868 miscPss[j] += mem; 13869 otherPss -= mem; 13870 } 13871 oomPss[0] += myTotalPss; 13872 if (oomProcs[0] == null) { 13873 oomProcs[0] = new ArrayList<MemItem>(); 13874 } 13875 oomProcs[0].add(pssItem); 13876 } 13877 } 13878 } 13879 13880 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13881 13882 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13883 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13884 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13885 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13886 String label = Debug.MemoryInfo.getOtherLabel(j); 13887 catMems.add(new MemItem(label, label, miscPss[j], j)); 13888 } 13889 13890 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13891 for (int j=0; j<oomPss.length; j++) { 13892 if (oomPss[j] != 0) { 13893 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13894 : DUMP_MEM_OOM_LABEL[j]; 13895 MemItem item = new MemItem(label, label, oomPss[j], 13896 DUMP_MEM_OOM_ADJ[j]); 13897 item.subitems = oomProcs[j]; 13898 oomMems.add(item); 13899 } 13900 } 13901 13902 if (!brief && !oomOnly && !isCompact) { 13903 pw.println(); 13904 pw.println("Total PSS by process:"); 13905 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13906 pw.println(); 13907 } 13908 if (!isCompact) { 13909 pw.println("Total PSS by OOM adjustment:"); 13910 } 13911 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13912 if (!brief && !oomOnly) { 13913 PrintWriter out = categoryPw != null ? categoryPw : pw; 13914 if (!isCompact) { 13915 out.println(); 13916 out.println("Total PSS by category:"); 13917 } 13918 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13919 } 13920 if (!isCompact) { 13921 pw.println(); 13922 } 13923 MemInfoReader memInfo = new MemInfoReader(); 13924 memInfo.readMemInfo(); 13925 if (nativeProcTotalPss > 0) { 13926 synchronized (this) { 13927 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13928 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13929 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13930 nativeProcTotalPss); 13931 } 13932 } 13933 if (!brief) { 13934 if (!isCompact) { 13935 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13936 pw.print(" kB (status "); 13937 switch (mLastMemoryLevel) { 13938 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13939 pw.println("normal)"); 13940 break; 13941 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13942 pw.println("moderate)"); 13943 break; 13944 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13945 pw.println("low)"); 13946 break; 13947 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13948 pw.println("critical)"); 13949 break; 13950 default: 13951 pw.print(mLastMemoryLevel); 13952 pw.println(")"); 13953 break; 13954 } 13955 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13956 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13957 pw.print(cachedPss); pw.print(" cached pss + "); 13958 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13959 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13960 } else { 13961 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13962 pw.print(cachedPss + memInfo.getCachedSizeKb() 13963 + memInfo.getFreeSizeKb()); pw.print(","); 13964 pw.println(totalPss - cachedPss); 13965 } 13966 } 13967 if (!isCompact) { 13968 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13969 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13970 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13971 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13972 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13973 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13974 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13975 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13976 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13977 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13978 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13979 } 13980 if (!brief) { 13981 if (memInfo.getZramTotalSizeKb() != 0) { 13982 if (!isCompact) { 13983 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13984 pw.print(" kB physical used for "); 13985 pw.print(memInfo.getSwapTotalSizeKb() 13986 - memInfo.getSwapFreeSizeKb()); 13987 pw.print(" kB in swap ("); 13988 pw.print(memInfo.getSwapTotalSizeKb()); 13989 pw.println(" kB total swap)"); 13990 } else { 13991 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13992 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13993 pw.println(memInfo.getSwapFreeSizeKb()); 13994 } 13995 } 13996 final int[] SINGLE_LONG_FORMAT = new int[] { 13997 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13998 }; 13999 long[] longOut = new long[1]; 14000 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14001 SINGLE_LONG_FORMAT, null, longOut, null); 14002 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14003 longOut[0] = 0; 14004 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14005 SINGLE_LONG_FORMAT, null, longOut, null); 14006 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14007 longOut[0] = 0; 14008 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14009 SINGLE_LONG_FORMAT, null, longOut, null); 14010 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14011 longOut[0] = 0; 14012 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14013 SINGLE_LONG_FORMAT, null, longOut, null); 14014 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14015 if (!isCompact) { 14016 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14017 pw.print(" KSM: "); pw.print(sharing); 14018 pw.print(" kB saved from shared "); 14019 pw.print(shared); pw.println(" kB"); 14020 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14021 pw.print(voltile); pw.println(" kB volatile"); 14022 } 14023 pw.print(" Tuning: "); 14024 pw.print(ActivityManager.staticGetMemoryClass()); 14025 pw.print(" (large "); 14026 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14027 pw.print("), oom "); 14028 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14029 pw.print(" kB"); 14030 pw.print(", restore limit "); 14031 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14032 pw.print(" kB"); 14033 if (ActivityManager.isLowRamDeviceStatic()) { 14034 pw.print(" (low-ram)"); 14035 } 14036 if (ActivityManager.isHighEndGfx()) { 14037 pw.print(" (high-end-gfx)"); 14038 } 14039 pw.println(); 14040 } else { 14041 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14042 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14043 pw.println(voltile); 14044 pw.print("tuning,"); 14045 pw.print(ActivityManager.staticGetMemoryClass()); 14046 pw.print(','); 14047 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14048 pw.print(','); 14049 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14050 if (ActivityManager.isLowRamDeviceStatic()) { 14051 pw.print(",low-ram"); 14052 } 14053 if (ActivityManager.isHighEndGfx()) { 14054 pw.print(",high-end-gfx"); 14055 } 14056 pw.println(); 14057 } 14058 } 14059 } 14060 } 14061 14062 /** 14063 * Searches array of arguments for the specified string 14064 * @param args array of argument strings 14065 * @param value value to search for 14066 * @return true if the value is contained in the array 14067 */ 14068 private static boolean scanArgs(String[] args, String value) { 14069 if (args != null) { 14070 for (String arg : args) { 14071 if (value.equals(arg)) { 14072 return true; 14073 } 14074 } 14075 } 14076 return false; 14077 } 14078 14079 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14080 ContentProviderRecord cpr, boolean always) { 14081 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14082 14083 if (!inLaunching || always) { 14084 synchronized (cpr) { 14085 cpr.launchingApp = null; 14086 cpr.notifyAll(); 14087 } 14088 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14089 String names[] = cpr.info.authority.split(";"); 14090 for (int j = 0; j < names.length; j++) { 14091 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14092 } 14093 } 14094 14095 for (int i=0; i<cpr.connections.size(); i++) { 14096 ContentProviderConnection conn = cpr.connections.get(i); 14097 if (conn.waiting) { 14098 // If this connection is waiting for the provider, then we don't 14099 // need to mess with its process unless we are always removing 14100 // or for some reason the provider is not currently launching. 14101 if (inLaunching && !always) { 14102 continue; 14103 } 14104 } 14105 ProcessRecord capp = conn.client; 14106 conn.dead = true; 14107 if (conn.stableCount > 0) { 14108 if (!capp.persistent && capp.thread != null 14109 && capp.pid != 0 14110 && capp.pid != MY_PID) { 14111 capp.kill("depends on provider " 14112 + cpr.name.flattenToShortString() 14113 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14114 } 14115 } else if (capp.thread != null && conn.provider.provider != null) { 14116 try { 14117 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14118 } catch (RemoteException e) { 14119 } 14120 // In the protocol here, we don't expect the client to correctly 14121 // clean up this connection, we'll just remove it. 14122 cpr.connections.remove(i); 14123 conn.client.conProviders.remove(conn); 14124 } 14125 } 14126 14127 if (inLaunching && always) { 14128 mLaunchingProviders.remove(cpr); 14129 } 14130 return inLaunching; 14131 } 14132 14133 /** 14134 * Main code for cleaning up a process when it has gone away. This is 14135 * called both as a result of the process dying, or directly when stopping 14136 * a process when running in single process mode. 14137 */ 14138 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14139 boolean restarting, boolean allowRestart, int index) { 14140 if (index >= 0) { 14141 removeLruProcessLocked(app); 14142 ProcessList.remove(app.pid); 14143 } 14144 14145 mProcessesToGc.remove(app); 14146 mPendingPssProcesses.remove(app); 14147 14148 // Dismiss any open dialogs. 14149 if (app.crashDialog != null && !app.forceCrashReport) { 14150 app.crashDialog.dismiss(); 14151 app.crashDialog = null; 14152 } 14153 if (app.anrDialog != null) { 14154 app.anrDialog.dismiss(); 14155 app.anrDialog = null; 14156 } 14157 if (app.waitDialog != null) { 14158 app.waitDialog.dismiss(); 14159 app.waitDialog = null; 14160 } 14161 14162 app.crashing = false; 14163 app.notResponding = false; 14164 14165 app.resetPackageList(mProcessStats); 14166 app.unlinkDeathRecipient(); 14167 app.makeInactive(mProcessStats); 14168 app.waitingToKill = null; 14169 app.forcingToForeground = null; 14170 updateProcessForegroundLocked(app, false, false); 14171 app.foregroundActivities = false; 14172 app.hasShownUi = false; 14173 app.treatLikeActivity = false; 14174 app.hasAboveClient = false; 14175 app.hasClientActivities = false; 14176 14177 mServices.killServicesLocked(app, allowRestart); 14178 14179 boolean restart = false; 14180 14181 // Remove published content providers. 14182 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14183 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14184 final boolean always = app.bad || !allowRestart; 14185 if (removeDyingProviderLocked(app, cpr, always) || always) { 14186 // We left the provider in the launching list, need to 14187 // restart it. 14188 restart = true; 14189 } 14190 14191 cpr.provider = null; 14192 cpr.proc = null; 14193 } 14194 app.pubProviders.clear(); 14195 14196 // Take care of any launching providers waiting for this process. 14197 if (checkAppInLaunchingProvidersLocked(app, false)) { 14198 restart = true; 14199 } 14200 14201 // Unregister from connected content providers. 14202 if (!app.conProviders.isEmpty()) { 14203 for (int i=0; i<app.conProviders.size(); i++) { 14204 ContentProviderConnection conn = app.conProviders.get(i); 14205 conn.provider.connections.remove(conn); 14206 } 14207 app.conProviders.clear(); 14208 } 14209 14210 // At this point there may be remaining entries in mLaunchingProviders 14211 // where we were the only one waiting, so they are no longer of use. 14212 // Look for these and clean up if found. 14213 // XXX Commented out for now. Trying to figure out a way to reproduce 14214 // the actual situation to identify what is actually going on. 14215 if (false) { 14216 for (int i=0; i<mLaunchingProviders.size(); i++) { 14217 ContentProviderRecord cpr = (ContentProviderRecord) 14218 mLaunchingProviders.get(i); 14219 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14220 synchronized (cpr) { 14221 cpr.launchingApp = null; 14222 cpr.notifyAll(); 14223 } 14224 } 14225 } 14226 } 14227 14228 skipCurrentReceiverLocked(app); 14229 14230 // Unregister any receivers. 14231 for (int i=app.receivers.size()-1; i>=0; i--) { 14232 removeReceiverLocked(app.receivers.valueAt(i)); 14233 } 14234 app.receivers.clear(); 14235 14236 // If the app is undergoing backup, tell the backup manager about it 14237 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14238 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14239 + mBackupTarget.appInfo + " died during backup"); 14240 try { 14241 IBackupManager bm = IBackupManager.Stub.asInterface( 14242 ServiceManager.getService(Context.BACKUP_SERVICE)); 14243 bm.agentDisconnected(app.info.packageName); 14244 } catch (RemoteException e) { 14245 // can't happen; backup manager is local 14246 } 14247 } 14248 14249 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14250 ProcessChangeItem item = mPendingProcessChanges.get(i); 14251 if (item.pid == app.pid) { 14252 mPendingProcessChanges.remove(i); 14253 mAvailProcessChanges.add(item); 14254 } 14255 } 14256 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14257 14258 // If the caller is restarting this app, then leave it in its 14259 // current lists and let the caller take care of it. 14260 if (restarting) { 14261 return; 14262 } 14263 14264 if (!app.persistent || app.isolated) { 14265 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14266 "Removing non-persistent process during cleanup: " + app); 14267 mProcessNames.remove(app.processName, app.uid); 14268 mIsolatedProcesses.remove(app.uid); 14269 if (mHeavyWeightProcess == app) { 14270 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14271 mHeavyWeightProcess.userId, 0)); 14272 mHeavyWeightProcess = null; 14273 } 14274 } else if (!app.removed) { 14275 // This app is persistent, so we need to keep its record around. 14276 // If it is not already on the pending app list, add it there 14277 // and start a new process for it. 14278 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14279 mPersistentStartingProcesses.add(app); 14280 restart = true; 14281 } 14282 } 14283 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14284 "Clean-up removing on hold: " + app); 14285 mProcessesOnHold.remove(app); 14286 14287 if (app == mHomeProcess) { 14288 mHomeProcess = null; 14289 } 14290 if (app == mPreviousProcess) { 14291 mPreviousProcess = null; 14292 } 14293 14294 if (restart && !app.isolated) { 14295 // We have components that still need to be running in the 14296 // process, so re-launch it. 14297 mProcessNames.put(app.processName, app.uid, app); 14298 startProcessLocked(app, "restart", app.processName); 14299 } else if (app.pid > 0 && app.pid != MY_PID) { 14300 // Goodbye! 14301 boolean removed; 14302 synchronized (mPidsSelfLocked) { 14303 mPidsSelfLocked.remove(app.pid); 14304 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14305 } 14306 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14307 if (app.isolated) { 14308 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14309 } 14310 app.setPid(0); 14311 } 14312 } 14313 14314 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14315 // Look through the content providers we are waiting to have launched, 14316 // and if any run in this process then either schedule a restart of 14317 // the process or kill the client waiting for it if this process has 14318 // gone bad. 14319 int NL = mLaunchingProviders.size(); 14320 boolean restart = false; 14321 for (int i=0; i<NL; i++) { 14322 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14323 if (cpr.launchingApp == app) { 14324 if (!alwaysBad && !app.bad) { 14325 restart = true; 14326 } else { 14327 removeDyingProviderLocked(app, cpr, true); 14328 // cpr should have been removed from mLaunchingProviders 14329 NL = mLaunchingProviders.size(); 14330 i--; 14331 } 14332 } 14333 } 14334 return restart; 14335 } 14336 14337 // ========================================================= 14338 // SERVICES 14339 // ========================================================= 14340 14341 @Override 14342 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14343 int flags) { 14344 enforceNotIsolatedCaller("getServices"); 14345 synchronized (this) { 14346 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14347 } 14348 } 14349 14350 @Override 14351 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14352 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14353 synchronized (this) { 14354 return mServices.getRunningServiceControlPanelLocked(name); 14355 } 14356 } 14357 14358 @Override 14359 public ComponentName startService(IApplicationThread caller, Intent service, 14360 String resolvedType, int userId) { 14361 enforceNotIsolatedCaller("startService"); 14362 // Refuse possible leaked file descriptors 14363 if (service != null && service.hasFileDescriptors() == true) { 14364 throw new IllegalArgumentException("File descriptors passed in Intent"); 14365 } 14366 14367 if (DEBUG_SERVICE) 14368 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14369 synchronized(this) { 14370 final int callingPid = Binder.getCallingPid(); 14371 final int callingUid = Binder.getCallingUid(); 14372 final long origId = Binder.clearCallingIdentity(); 14373 ComponentName res = mServices.startServiceLocked(caller, service, 14374 resolvedType, callingPid, callingUid, userId); 14375 Binder.restoreCallingIdentity(origId); 14376 return res; 14377 } 14378 } 14379 14380 ComponentName startServiceInPackage(int uid, 14381 Intent service, String resolvedType, int userId) { 14382 synchronized(this) { 14383 if (DEBUG_SERVICE) 14384 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14385 final long origId = Binder.clearCallingIdentity(); 14386 ComponentName res = mServices.startServiceLocked(null, service, 14387 resolvedType, -1, uid, userId); 14388 Binder.restoreCallingIdentity(origId); 14389 return res; 14390 } 14391 } 14392 14393 @Override 14394 public int stopService(IApplicationThread caller, Intent service, 14395 String resolvedType, int userId) { 14396 enforceNotIsolatedCaller("stopService"); 14397 // Refuse possible leaked file descriptors 14398 if (service != null && service.hasFileDescriptors() == true) { 14399 throw new IllegalArgumentException("File descriptors passed in Intent"); 14400 } 14401 14402 synchronized(this) { 14403 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14404 } 14405 } 14406 14407 @Override 14408 public IBinder peekService(Intent service, String resolvedType) { 14409 enforceNotIsolatedCaller("peekService"); 14410 // Refuse possible leaked file descriptors 14411 if (service != null && service.hasFileDescriptors() == true) { 14412 throw new IllegalArgumentException("File descriptors passed in Intent"); 14413 } 14414 synchronized(this) { 14415 return mServices.peekServiceLocked(service, resolvedType); 14416 } 14417 } 14418 14419 @Override 14420 public boolean stopServiceToken(ComponentName className, IBinder token, 14421 int startId) { 14422 synchronized(this) { 14423 return mServices.stopServiceTokenLocked(className, token, startId); 14424 } 14425 } 14426 14427 @Override 14428 public void setServiceForeground(ComponentName className, IBinder token, 14429 int id, Notification notification, boolean removeNotification) { 14430 synchronized(this) { 14431 mServices.setServiceForegroundLocked(className, token, id, notification, 14432 removeNotification); 14433 } 14434 } 14435 14436 @Override 14437 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14438 boolean requireFull, String name, String callerPackage) { 14439 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14440 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14441 } 14442 14443 int unsafeConvertIncomingUser(int userId) { 14444 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14445 ? mCurrentUserId : userId; 14446 } 14447 14448 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14449 int allowMode, String name, String callerPackage) { 14450 final int callingUserId = UserHandle.getUserId(callingUid); 14451 if (callingUserId == userId) { 14452 return userId; 14453 } 14454 14455 // Note that we may be accessing mCurrentUserId outside of a lock... 14456 // shouldn't be a big deal, if this is being called outside 14457 // of a locked context there is intrinsically a race with 14458 // the value the caller will receive and someone else changing it. 14459 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14460 // we will switch to the calling user if access to the current user fails. 14461 int targetUserId = unsafeConvertIncomingUser(userId); 14462 14463 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14464 final boolean allow; 14465 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14466 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14467 // If the caller has this permission, they always pass go. And collect $200. 14468 allow = true; 14469 } else if (allowMode == ALLOW_FULL_ONLY) { 14470 // We require full access, sucks to be you. 14471 allow = false; 14472 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14473 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14474 // If the caller does not have either permission, they are always doomed. 14475 allow = false; 14476 } else if (allowMode == ALLOW_NON_FULL) { 14477 // We are blanket allowing non-full access, you lucky caller! 14478 allow = true; 14479 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14480 // We may or may not allow this depending on whether the two users are 14481 // in the same profile. 14482 synchronized (mUserProfileGroupIdsSelfLocked) { 14483 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14484 UserInfo.NO_PROFILE_GROUP_ID); 14485 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14486 UserInfo.NO_PROFILE_GROUP_ID); 14487 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14488 && callingProfile == targetProfile; 14489 } 14490 } else { 14491 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14492 } 14493 if (!allow) { 14494 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14495 // In this case, they would like to just execute as their 14496 // owner user instead of failing. 14497 targetUserId = callingUserId; 14498 } else { 14499 StringBuilder builder = new StringBuilder(128); 14500 builder.append("Permission Denial: "); 14501 builder.append(name); 14502 if (callerPackage != null) { 14503 builder.append(" from "); 14504 builder.append(callerPackage); 14505 } 14506 builder.append(" asks to run as user "); 14507 builder.append(userId); 14508 builder.append(" but is calling from user "); 14509 builder.append(UserHandle.getUserId(callingUid)); 14510 builder.append("; this requires "); 14511 builder.append(INTERACT_ACROSS_USERS_FULL); 14512 if (allowMode != ALLOW_FULL_ONLY) { 14513 builder.append(" or "); 14514 builder.append(INTERACT_ACROSS_USERS); 14515 } 14516 String msg = builder.toString(); 14517 Slog.w(TAG, msg); 14518 throw new SecurityException(msg); 14519 } 14520 } 14521 } 14522 if (!allowAll && targetUserId < 0) { 14523 throw new IllegalArgumentException( 14524 "Call does not support special user #" + targetUserId); 14525 } 14526 return targetUserId; 14527 } 14528 14529 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14530 String className, int flags) { 14531 boolean result = false; 14532 // For apps that don't have pre-defined UIDs, check for permission 14533 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14534 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14535 if (ActivityManager.checkUidPermission( 14536 INTERACT_ACROSS_USERS, 14537 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14538 ComponentName comp = new ComponentName(aInfo.packageName, className); 14539 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14540 + " requests FLAG_SINGLE_USER, but app does not hold " 14541 + INTERACT_ACROSS_USERS; 14542 Slog.w(TAG, msg); 14543 throw new SecurityException(msg); 14544 } 14545 // Permission passed 14546 result = true; 14547 } 14548 } else if ("system".equals(componentProcessName)) { 14549 result = true; 14550 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14551 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14552 // Phone app is allowed to export singleuser providers. 14553 result = true; 14554 } else { 14555 // App with pre-defined UID, check if it's a persistent app 14556 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14557 } 14558 if (DEBUG_MU) { 14559 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14560 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14561 } 14562 return result; 14563 } 14564 14565 /** 14566 * Checks to see if the caller is in the same app as the singleton 14567 * component, or the component is in a special app. It allows special apps 14568 * to export singleton components but prevents exporting singleton 14569 * components for regular apps. 14570 */ 14571 boolean isValidSingletonCall(int callingUid, int componentUid) { 14572 int componentAppId = UserHandle.getAppId(componentUid); 14573 return UserHandle.isSameApp(callingUid, componentUid) 14574 || componentAppId == Process.SYSTEM_UID 14575 || componentAppId == Process.PHONE_UID 14576 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14577 == PackageManager.PERMISSION_GRANTED; 14578 } 14579 14580 public int bindService(IApplicationThread caller, IBinder token, 14581 Intent service, String resolvedType, 14582 IServiceConnection connection, int flags, int userId) { 14583 enforceNotIsolatedCaller("bindService"); 14584 // Refuse possible leaked file descriptors 14585 if (service != null && service.hasFileDescriptors() == true) { 14586 throw new IllegalArgumentException("File descriptors passed in Intent"); 14587 } 14588 14589 synchronized(this) { 14590 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14591 connection, flags, userId); 14592 } 14593 } 14594 14595 public boolean unbindService(IServiceConnection connection) { 14596 synchronized (this) { 14597 return mServices.unbindServiceLocked(connection); 14598 } 14599 } 14600 14601 public void publishService(IBinder token, Intent intent, IBinder service) { 14602 // Refuse possible leaked file descriptors 14603 if (intent != null && intent.hasFileDescriptors() == true) { 14604 throw new IllegalArgumentException("File descriptors passed in Intent"); 14605 } 14606 14607 synchronized(this) { 14608 if (!(token instanceof ServiceRecord)) { 14609 throw new IllegalArgumentException("Invalid service token"); 14610 } 14611 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14612 } 14613 } 14614 14615 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14616 // Refuse possible leaked file descriptors 14617 if (intent != null && intent.hasFileDescriptors() == true) { 14618 throw new IllegalArgumentException("File descriptors passed in Intent"); 14619 } 14620 14621 synchronized(this) { 14622 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14623 } 14624 } 14625 14626 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14627 synchronized(this) { 14628 if (!(token instanceof ServiceRecord)) { 14629 throw new IllegalArgumentException("Invalid service token"); 14630 } 14631 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14632 } 14633 } 14634 14635 // ========================================================= 14636 // BACKUP AND RESTORE 14637 // ========================================================= 14638 14639 // Cause the target app to be launched if necessary and its backup agent 14640 // instantiated. The backup agent will invoke backupAgentCreated() on the 14641 // activity manager to announce its creation. 14642 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14643 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14644 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14645 14646 synchronized(this) { 14647 // !!! TODO: currently no check here that we're already bound 14648 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14649 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14650 synchronized (stats) { 14651 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14652 } 14653 14654 // Backup agent is now in use, its package can't be stopped. 14655 try { 14656 AppGlobals.getPackageManager().setPackageStoppedState( 14657 app.packageName, false, UserHandle.getUserId(app.uid)); 14658 } catch (RemoteException e) { 14659 } catch (IllegalArgumentException e) { 14660 Slog.w(TAG, "Failed trying to unstop package " 14661 + app.packageName + ": " + e); 14662 } 14663 14664 BackupRecord r = new BackupRecord(ss, app, backupMode); 14665 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14666 ? new ComponentName(app.packageName, app.backupAgentName) 14667 : new ComponentName("android", "FullBackupAgent"); 14668 // startProcessLocked() returns existing proc's record if it's already running 14669 ProcessRecord proc = startProcessLocked(app.processName, app, 14670 false, 0, "backup", hostingName, false, false, false); 14671 if (proc == null) { 14672 Slog.e(TAG, "Unable to start backup agent process " + r); 14673 return false; 14674 } 14675 14676 r.app = proc; 14677 mBackupTarget = r; 14678 mBackupAppName = app.packageName; 14679 14680 // Try not to kill the process during backup 14681 updateOomAdjLocked(proc); 14682 14683 // If the process is already attached, schedule the creation of the backup agent now. 14684 // If it is not yet live, this will be done when it attaches to the framework. 14685 if (proc.thread != null) { 14686 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14687 try { 14688 proc.thread.scheduleCreateBackupAgent(app, 14689 compatibilityInfoForPackageLocked(app), backupMode); 14690 } catch (RemoteException e) { 14691 // Will time out on the backup manager side 14692 } 14693 } else { 14694 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14695 } 14696 // Invariants: at this point, the target app process exists and the application 14697 // is either already running or in the process of coming up. mBackupTarget and 14698 // mBackupAppName describe the app, so that when it binds back to the AM we 14699 // know that it's scheduled for a backup-agent operation. 14700 } 14701 14702 return true; 14703 } 14704 14705 @Override 14706 public void clearPendingBackup() { 14707 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14708 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14709 14710 synchronized (this) { 14711 mBackupTarget = null; 14712 mBackupAppName = null; 14713 } 14714 } 14715 14716 // A backup agent has just come up 14717 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14718 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14719 + " = " + agent); 14720 14721 synchronized(this) { 14722 if (!agentPackageName.equals(mBackupAppName)) { 14723 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14724 return; 14725 } 14726 } 14727 14728 long oldIdent = Binder.clearCallingIdentity(); 14729 try { 14730 IBackupManager bm = IBackupManager.Stub.asInterface( 14731 ServiceManager.getService(Context.BACKUP_SERVICE)); 14732 bm.agentConnected(agentPackageName, agent); 14733 } catch (RemoteException e) { 14734 // can't happen; the backup manager service is local 14735 } catch (Exception e) { 14736 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14737 e.printStackTrace(); 14738 } finally { 14739 Binder.restoreCallingIdentity(oldIdent); 14740 } 14741 } 14742 14743 // done with this agent 14744 public void unbindBackupAgent(ApplicationInfo appInfo) { 14745 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14746 if (appInfo == null) { 14747 Slog.w(TAG, "unbind backup agent for null app"); 14748 return; 14749 } 14750 14751 synchronized(this) { 14752 try { 14753 if (mBackupAppName == null) { 14754 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14755 return; 14756 } 14757 14758 if (!mBackupAppName.equals(appInfo.packageName)) { 14759 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14760 return; 14761 } 14762 14763 // Not backing this app up any more; reset its OOM adjustment 14764 final ProcessRecord proc = mBackupTarget.app; 14765 updateOomAdjLocked(proc); 14766 14767 // If the app crashed during backup, 'thread' will be null here 14768 if (proc.thread != null) { 14769 try { 14770 proc.thread.scheduleDestroyBackupAgent(appInfo, 14771 compatibilityInfoForPackageLocked(appInfo)); 14772 } catch (Exception e) { 14773 Slog.e(TAG, "Exception when unbinding backup agent:"); 14774 e.printStackTrace(); 14775 } 14776 } 14777 } finally { 14778 mBackupTarget = null; 14779 mBackupAppName = null; 14780 } 14781 } 14782 } 14783 // ========================================================= 14784 // BROADCASTS 14785 // ========================================================= 14786 14787 private final List getStickiesLocked(String action, IntentFilter filter, 14788 List cur, int userId) { 14789 final ContentResolver resolver = mContext.getContentResolver(); 14790 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14791 if (stickies == null) { 14792 return cur; 14793 } 14794 final ArrayList<Intent> list = stickies.get(action); 14795 if (list == null) { 14796 return cur; 14797 } 14798 int N = list.size(); 14799 for (int i=0; i<N; i++) { 14800 Intent intent = list.get(i); 14801 if (filter.match(resolver, intent, true, TAG) >= 0) { 14802 if (cur == null) { 14803 cur = new ArrayList<Intent>(); 14804 } 14805 cur.add(intent); 14806 } 14807 } 14808 return cur; 14809 } 14810 14811 boolean isPendingBroadcastProcessLocked(int pid) { 14812 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14813 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14814 } 14815 14816 void skipPendingBroadcastLocked(int pid) { 14817 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14818 for (BroadcastQueue queue : mBroadcastQueues) { 14819 queue.skipPendingBroadcastLocked(pid); 14820 } 14821 } 14822 14823 // The app just attached; send any pending broadcasts that it should receive 14824 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14825 boolean didSomething = false; 14826 for (BroadcastQueue queue : mBroadcastQueues) { 14827 didSomething |= queue.sendPendingBroadcastsLocked(app); 14828 } 14829 return didSomething; 14830 } 14831 14832 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14833 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14834 enforceNotIsolatedCaller("registerReceiver"); 14835 int callingUid; 14836 int callingPid; 14837 synchronized(this) { 14838 ProcessRecord callerApp = null; 14839 if (caller != null) { 14840 callerApp = getRecordForAppLocked(caller); 14841 if (callerApp == null) { 14842 throw new SecurityException( 14843 "Unable to find app for caller " + caller 14844 + " (pid=" + Binder.getCallingPid() 14845 + ") when registering receiver " + receiver); 14846 } 14847 if (callerApp.info.uid != Process.SYSTEM_UID && 14848 !callerApp.pkgList.containsKey(callerPackage) && 14849 !"android".equals(callerPackage)) { 14850 throw new SecurityException("Given caller package " + callerPackage 14851 + " is not running in process " + callerApp); 14852 } 14853 callingUid = callerApp.info.uid; 14854 callingPid = callerApp.pid; 14855 } else { 14856 callerPackage = null; 14857 callingUid = Binder.getCallingUid(); 14858 callingPid = Binder.getCallingPid(); 14859 } 14860 14861 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14862 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14863 14864 List allSticky = null; 14865 14866 // Look for any matching sticky broadcasts... 14867 Iterator actions = filter.actionsIterator(); 14868 if (actions != null) { 14869 while (actions.hasNext()) { 14870 String action = (String)actions.next(); 14871 allSticky = getStickiesLocked(action, filter, allSticky, 14872 UserHandle.USER_ALL); 14873 allSticky = getStickiesLocked(action, filter, allSticky, 14874 UserHandle.getUserId(callingUid)); 14875 } 14876 } else { 14877 allSticky = getStickiesLocked(null, filter, allSticky, 14878 UserHandle.USER_ALL); 14879 allSticky = getStickiesLocked(null, filter, allSticky, 14880 UserHandle.getUserId(callingUid)); 14881 } 14882 14883 // The first sticky in the list is returned directly back to 14884 // the client. 14885 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14886 14887 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14888 + ": " + sticky); 14889 14890 if (receiver == null) { 14891 return sticky; 14892 } 14893 14894 ReceiverList rl 14895 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14896 if (rl == null) { 14897 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14898 userId, receiver); 14899 if (rl.app != null) { 14900 rl.app.receivers.add(rl); 14901 } else { 14902 try { 14903 receiver.asBinder().linkToDeath(rl, 0); 14904 } catch (RemoteException e) { 14905 return sticky; 14906 } 14907 rl.linkedToDeath = true; 14908 } 14909 mRegisteredReceivers.put(receiver.asBinder(), rl); 14910 } else if (rl.uid != callingUid) { 14911 throw new IllegalArgumentException( 14912 "Receiver requested to register for uid " + callingUid 14913 + " was previously registered for uid " + rl.uid); 14914 } else if (rl.pid != callingPid) { 14915 throw new IllegalArgumentException( 14916 "Receiver requested to register for pid " + callingPid 14917 + " was previously registered for pid " + rl.pid); 14918 } else if (rl.userId != userId) { 14919 throw new IllegalArgumentException( 14920 "Receiver requested to register for user " + userId 14921 + " was previously registered for user " + rl.userId); 14922 } 14923 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14924 permission, callingUid, userId); 14925 rl.add(bf); 14926 if (!bf.debugCheck()) { 14927 Slog.w(TAG, "==> For Dynamic broadast"); 14928 } 14929 mReceiverResolver.addFilter(bf); 14930 14931 // Enqueue broadcasts for all existing stickies that match 14932 // this filter. 14933 if (allSticky != null) { 14934 ArrayList receivers = new ArrayList(); 14935 receivers.add(bf); 14936 14937 int N = allSticky.size(); 14938 for (int i=0; i<N; i++) { 14939 Intent intent = (Intent)allSticky.get(i); 14940 BroadcastQueue queue = broadcastQueueForIntent(intent); 14941 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14942 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14943 null, null, false, true, true, -1); 14944 queue.enqueueParallelBroadcastLocked(r); 14945 queue.scheduleBroadcastsLocked(); 14946 } 14947 } 14948 14949 return sticky; 14950 } 14951 } 14952 14953 public void unregisterReceiver(IIntentReceiver receiver) { 14954 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14955 14956 final long origId = Binder.clearCallingIdentity(); 14957 try { 14958 boolean doTrim = false; 14959 14960 synchronized(this) { 14961 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14962 if (rl != null) { 14963 if (rl.curBroadcast != null) { 14964 BroadcastRecord r = rl.curBroadcast; 14965 final boolean doNext = finishReceiverLocked( 14966 receiver.asBinder(), r.resultCode, r.resultData, 14967 r.resultExtras, r.resultAbort); 14968 if (doNext) { 14969 doTrim = true; 14970 r.queue.processNextBroadcast(false); 14971 } 14972 } 14973 14974 if (rl.app != null) { 14975 rl.app.receivers.remove(rl); 14976 } 14977 removeReceiverLocked(rl); 14978 if (rl.linkedToDeath) { 14979 rl.linkedToDeath = false; 14980 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14981 } 14982 } 14983 } 14984 14985 // If we actually concluded any broadcasts, we might now be able 14986 // to trim the recipients' apps from our working set 14987 if (doTrim) { 14988 trimApplications(); 14989 return; 14990 } 14991 14992 } finally { 14993 Binder.restoreCallingIdentity(origId); 14994 } 14995 } 14996 14997 void removeReceiverLocked(ReceiverList rl) { 14998 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14999 int N = rl.size(); 15000 for (int i=0; i<N; i++) { 15001 mReceiverResolver.removeFilter(rl.get(i)); 15002 } 15003 } 15004 15005 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15006 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15007 ProcessRecord r = mLruProcesses.get(i); 15008 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15009 try { 15010 r.thread.dispatchPackageBroadcast(cmd, packages); 15011 } catch (RemoteException ex) { 15012 } 15013 } 15014 } 15015 } 15016 15017 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15018 int[] users) { 15019 List<ResolveInfo> receivers = null; 15020 try { 15021 HashSet<ComponentName> singleUserReceivers = null; 15022 boolean scannedFirstReceivers = false; 15023 for (int user : users) { 15024 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15025 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15026 if (user != 0 && newReceivers != null) { 15027 // If this is not the primary user, we need to check for 15028 // any receivers that should be filtered out. 15029 for (int i=0; i<newReceivers.size(); i++) { 15030 ResolveInfo ri = newReceivers.get(i); 15031 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15032 newReceivers.remove(i); 15033 i--; 15034 } 15035 } 15036 } 15037 if (newReceivers != null && newReceivers.size() == 0) { 15038 newReceivers = null; 15039 } 15040 if (receivers == null) { 15041 receivers = newReceivers; 15042 } else if (newReceivers != null) { 15043 // We need to concatenate the additional receivers 15044 // found with what we have do far. This would be easy, 15045 // but we also need to de-dup any receivers that are 15046 // singleUser. 15047 if (!scannedFirstReceivers) { 15048 // Collect any single user receivers we had already retrieved. 15049 scannedFirstReceivers = true; 15050 for (int i=0; i<receivers.size(); i++) { 15051 ResolveInfo ri = receivers.get(i); 15052 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15053 ComponentName cn = new ComponentName( 15054 ri.activityInfo.packageName, ri.activityInfo.name); 15055 if (singleUserReceivers == null) { 15056 singleUserReceivers = new HashSet<ComponentName>(); 15057 } 15058 singleUserReceivers.add(cn); 15059 } 15060 } 15061 } 15062 // Add the new results to the existing results, tracking 15063 // and de-dupping single user receivers. 15064 for (int i=0; i<newReceivers.size(); i++) { 15065 ResolveInfo ri = newReceivers.get(i); 15066 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15067 ComponentName cn = new ComponentName( 15068 ri.activityInfo.packageName, ri.activityInfo.name); 15069 if (singleUserReceivers == null) { 15070 singleUserReceivers = new HashSet<ComponentName>(); 15071 } 15072 if (!singleUserReceivers.contains(cn)) { 15073 singleUserReceivers.add(cn); 15074 receivers.add(ri); 15075 } 15076 } else { 15077 receivers.add(ri); 15078 } 15079 } 15080 } 15081 } 15082 } catch (RemoteException ex) { 15083 // pm is in same process, this will never happen. 15084 } 15085 return receivers; 15086 } 15087 15088 private final int broadcastIntentLocked(ProcessRecord callerApp, 15089 String callerPackage, Intent intent, String resolvedType, 15090 IIntentReceiver resultTo, int resultCode, String resultData, 15091 Bundle map, String requiredPermission, int appOp, 15092 boolean ordered, boolean sticky, int callingPid, int callingUid, 15093 int userId) { 15094 intent = new Intent(intent); 15095 15096 // By default broadcasts do not go to stopped apps. 15097 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15098 15099 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15100 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15101 + " ordered=" + ordered + " userid=" + userId); 15102 if ((resultTo != null) && !ordered) { 15103 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15104 } 15105 15106 userId = handleIncomingUser(callingPid, callingUid, userId, 15107 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15108 15109 // Make sure that the user who is receiving this broadcast is started. 15110 // If not, we will just skip it. 15111 15112 15113 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15114 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15115 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15116 Slog.w(TAG, "Skipping broadcast of " + intent 15117 + ": user " + userId + " is stopped"); 15118 return ActivityManager.BROADCAST_SUCCESS; 15119 } 15120 } 15121 15122 /* 15123 * Prevent non-system code (defined here to be non-persistent 15124 * processes) from sending protected broadcasts. 15125 */ 15126 int callingAppId = UserHandle.getAppId(callingUid); 15127 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15128 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15129 || callingAppId == Process.NFC_UID || callingUid == 0) { 15130 // Always okay. 15131 } else if (callerApp == null || !callerApp.persistent) { 15132 try { 15133 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15134 intent.getAction())) { 15135 String msg = "Permission Denial: not allowed to send broadcast " 15136 + intent.getAction() + " from pid=" 15137 + callingPid + ", uid=" + callingUid; 15138 Slog.w(TAG, msg); 15139 throw new SecurityException(msg); 15140 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15141 // Special case for compatibility: we don't want apps to send this, 15142 // but historically it has not been protected and apps may be using it 15143 // to poke their own app widget. So, instead of making it protected, 15144 // just limit it to the caller. 15145 if (callerApp == null) { 15146 String msg = "Permission Denial: not allowed to send broadcast " 15147 + intent.getAction() + " from unknown caller."; 15148 Slog.w(TAG, msg); 15149 throw new SecurityException(msg); 15150 } else if (intent.getComponent() != null) { 15151 // They are good enough to send to an explicit component... verify 15152 // it is being sent to the calling app. 15153 if (!intent.getComponent().getPackageName().equals( 15154 callerApp.info.packageName)) { 15155 String msg = "Permission Denial: not allowed to send broadcast " 15156 + intent.getAction() + " to " 15157 + intent.getComponent().getPackageName() + " from " 15158 + callerApp.info.packageName; 15159 Slog.w(TAG, msg); 15160 throw new SecurityException(msg); 15161 } 15162 } else { 15163 // Limit broadcast to their own package. 15164 intent.setPackage(callerApp.info.packageName); 15165 } 15166 } 15167 } catch (RemoteException e) { 15168 Slog.w(TAG, "Remote exception", e); 15169 return ActivityManager.BROADCAST_SUCCESS; 15170 } 15171 } 15172 15173 // Handle special intents: if this broadcast is from the package 15174 // manager about a package being removed, we need to remove all of 15175 // its activities from the history stack. 15176 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15177 intent.getAction()); 15178 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15179 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15180 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15181 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15182 || uidRemoved) { 15183 if (checkComponentPermission( 15184 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15185 callingPid, callingUid, -1, true) 15186 == PackageManager.PERMISSION_GRANTED) { 15187 if (uidRemoved) { 15188 final Bundle intentExtras = intent.getExtras(); 15189 final int uid = intentExtras != null 15190 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15191 if (uid >= 0) { 15192 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15193 synchronized (bs) { 15194 bs.removeUidStatsLocked(uid); 15195 } 15196 mAppOpsService.uidRemoved(uid); 15197 } 15198 } else { 15199 // If resources are unavailable just force stop all 15200 // those packages and flush the attribute cache as well. 15201 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15202 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15203 if (list != null && (list.length > 0)) { 15204 for (String pkg : list) { 15205 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15206 "storage unmount"); 15207 } 15208 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15209 sendPackageBroadcastLocked( 15210 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15211 } 15212 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15213 intent.getAction())) { 15214 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15215 } else { 15216 Uri data = intent.getData(); 15217 String ssp; 15218 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15219 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15220 intent.getAction()); 15221 boolean fullUninstall = removed && 15222 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15223 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15224 forceStopPackageLocked(ssp, UserHandle.getAppId( 15225 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15226 false, fullUninstall, userId, 15227 removed ? "pkg removed" : "pkg changed"); 15228 } 15229 if (removed) { 15230 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15231 new String[] {ssp}, userId); 15232 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15233 mAppOpsService.packageRemoved( 15234 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15235 15236 // Remove all permissions granted from/to this package 15237 removeUriPermissionsForPackageLocked(ssp, userId, true); 15238 } 15239 } 15240 } 15241 } 15242 } 15243 } else { 15244 String msg = "Permission Denial: " + intent.getAction() 15245 + " broadcast from " + callerPackage + " (pid=" + callingPid 15246 + ", uid=" + callingUid + ")" 15247 + " requires " 15248 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15249 Slog.w(TAG, msg); 15250 throw new SecurityException(msg); 15251 } 15252 15253 // Special case for adding a package: by default turn on compatibility 15254 // mode. 15255 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15256 Uri data = intent.getData(); 15257 String ssp; 15258 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15259 mCompatModePackages.handlePackageAddedLocked(ssp, 15260 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15261 } 15262 } 15263 15264 /* 15265 * If this is the time zone changed action, queue up a message that will reset the timezone 15266 * of all currently running processes. This message will get queued up before the broadcast 15267 * happens. 15268 */ 15269 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15270 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15271 } 15272 15273 /* 15274 * If the user set the time, let all running processes know. 15275 */ 15276 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15277 final int is24Hour = intent.getBooleanExtra( 15278 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15279 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15280 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15281 synchronized (stats) { 15282 stats.noteCurrentTimeChangedLocked(); 15283 } 15284 } 15285 15286 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15287 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15288 } 15289 15290 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15291 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15292 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15293 } 15294 15295 // Add to the sticky list if requested. 15296 if (sticky) { 15297 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15298 callingPid, callingUid) 15299 != PackageManager.PERMISSION_GRANTED) { 15300 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15301 + callingPid + ", uid=" + callingUid 15302 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15303 Slog.w(TAG, msg); 15304 throw new SecurityException(msg); 15305 } 15306 if (requiredPermission != null) { 15307 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15308 + " and enforce permission " + requiredPermission); 15309 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15310 } 15311 if (intent.getComponent() != null) { 15312 throw new SecurityException( 15313 "Sticky broadcasts can't target a specific component"); 15314 } 15315 // We use userId directly here, since the "all" target is maintained 15316 // as a separate set of sticky broadcasts. 15317 if (userId != UserHandle.USER_ALL) { 15318 // But first, if this is not a broadcast to all users, then 15319 // make sure it doesn't conflict with an existing broadcast to 15320 // all users. 15321 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15322 UserHandle.USER_ALL); 15323 if (stickies != null) { 15324 ArrayList<Intent> list = stickies.get(intent.getAction()); 15325 if (list != null) { 15326 int N = list.size(); 15327 int i; 15328 for (i=0; i<N; i++) { 15329 if (intent.filterEquals(list.get(i))) { 15330 throw new IllegalArgumentException( 15331 "Sticky broadcast " + intent + " for user " 15332 + userId + " conflicts with existing global broadcast"); 15333 } 15334 } 15335 } 15336 } 15337 } 15338 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15339 if (stickies == null) { 15340 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15341 mStickyBroadcasts.put(userId, stickies); 15342 } 15343 ArrayList<Intent> list = stickies.get(intent.getAction()); 15344 if (list == null) { 15345 list = new ArrayList<Intent>(); 15346 stickies.put(intent.getAction(), list); 15347 } 15348 int N = list.size(); 15349 int i; 15350 for (i=0; i<N; i++) { 15351 if (intent.filterEquals(list.get(i))) { 15352 // This sticky already exists, replace it. 15353 list.set(i, new Intent(intent)); 15354 break; 15355 } 15356 } 15357 if (i >= N) { 15358 list.add(new Intent(intent)); 15359 } 15360 } 15361 15362 int[] users; 15363 if (userId == UserHandle.USER_ALL) { 15364 // Caller wants broadcast to go to all started users. 15365 users = mStartedUserArray; 15366 } else { 15367 // Caller wants broadcast to go to one specific user. 15368 users = new int[] {userId}; 15369 } 15370 15371 // Figure out who all will receive this broadcast. 15372 List receivers = null; 15373 List<BroadcastFilter> registeredReceivers = null; 15374 // Need to resolve the intent to interested receivers... 15375 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15376 == 0) { 15377 receivers = collectReceiverComponents(intent, resolvedType, users); 15378 } 15379 if (intent.getComponent() == null) { 15380 registeredReceivers = mReceiverResolver.queryIntent(intent, 15381 resolvedType, false, userId); 15382 } 15383 15384 final boolean replacePending = 15385 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15386 15387 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15388 + " replacePending=" + replacePending); 15389 15390 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15391 if (!ordered && NR > 0) { 15392 // If we are not serializing this broadcast, then send the 15393 // registered receivers separately so they don't wait for the 15394 // components to be launched. 15395 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15396 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15397 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15398 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15399 ordered, sticky, false, userId); 15400 if (DEBUG_BROADCAST) Slog.v( 15401 TAG, "Enqueueing parallel broadcast " + r); 15402 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15403 if (!replaced) { 15404 queue.enqueueParallelBroadcastLocked(r); 15405 queue.scheduleBroadcastsLocked(); 15406 } 15407 registeredReceivers = null; 15408 NR = 0; 15409 } 15410 15411 // Merge into one list. 15412 int ir = 0; 15413 if (receivers != null) { 15414 // A special case for PACKAGE_ADDED: do not allow the package 15415 // being added to see this broadcast. This prevents them from 15416 // using this as a back door to get run as soon as they are 15417 // installed. Maybe in the future we want to have a special install 15418 // broadcast or such for apps, but we'd like to deliberately make 15419 // this decision. 15420 String skipPackages[] = null; 15421 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15422 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15423 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15424 Uri data = intent.getData(); 15425 if (data != null) { 15426 String pkgName = data.getSchemeSpecificPart(); 15427 if (pkgName != null) { 15428 skipPackages = new String[] { pkgName }; 15429 } 15430 } 15431 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15432 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15433 } 15434 if (skipPackages != null && (skipPackages.length > 0)) { 15435 for (String skipPackage : skipPackages) { 15436 if (skipPackage != null) { 15437 int NT = receivers.size(); 15438 for (int it=0; it<NT; it++) { 15439 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15440 if (curt.activityInfo.packageName.equals(skipPackage)) { 15441 receivers.remove(it); 15442 it--; 15443 NT--; 15444 } 15445 } 15446 } 15447 } 15448 } 15449 15450 int NT = receivers != null ? receivers.size() : 0; 15451 int it = 0; 15452 ResolveInfo curt = null; 15453 BroadcastFilter curr = null; 15454 while (it < NT && ir < NR) { 15455 if (curt == null) { 15456 curt = (ResolveInfo)receivers.get(it); 15457 } 15458 if (curr == null) { 15459 curr = registeredReceivers.get(ir); 15460 } 15461 if (curr.getPriority() >= curt.priority) { 15462 // Insert this broadcast record into the final list. 15463 receivers.add(it, curr); 15464 ir++; 15465 curr = null; 15466 it++; 15467 NT++; 15468 } else { 15469 // Skip to the next ResolveInfo in the final list. 15470 it++; 15471 curt = null; 15472 } 15473 } 15474 } 15475 while (ir < NR) { 15476 if (receivers == null) { 15477 receivers = new ArrayList(); 15478 } 15479 receivers.add(registeredReceivers.get(ir)); 15480 ir++; 15481 } 15482 15483 if ((receivers != null && receivers.size() > 0) 15484 || resultTo != null) { 15485 BroadcastQueue queue = broadcastQueueForIntent(intent); 15486 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15487 callerPackage, callingPid, callingUid, resolvedType, 15488 requiredPermission, appOp, receivers, resultTo, resultCode, 15489 resultData, map, ordered, sticky, false, userId); 15490 if (DEBUG_BROADCAST) Slog.v( 15491 TAG, "Enqueueing ordered broadcast " + r 15492 + ": prev had " + queue.mOrderedBroadcasts.size()); 15493 if (DEBUG_BROADCAST) { 15494 int seq = r.intent.getIntExtra("seq", -1); 15495 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15496 } 15497 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15498 if (!replaced) { 15499 queue.enqueueOrderedBroadcastLocked(r); 15500 queue.scheduleBroadcastsLocked(); 15501 } 15502 } 15503 15504 return ActivityManager.BROADCAST_SUCCESS; 15505 } 15506 15507 final Intent verifyBroadcastLocked(Intent intent) { 15508 // Refuse possible leaked file descriptors 15509 if (intent != null && intent.hasFileDescriptors() == true) { 15510 throw new IllegalArgumentException("File descriptors passed in Intent"); 15511 } 15512 15513 int flags = intent.getFlags(); 15514 15515 if (!mProcessesReady) { 15516 // if the caller really truly claims to know what they're doing, go 15517 // ahead and allow the broadcast without launching any receivers 15518 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15519 intent = new Intent(intent); 15520 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15521 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15522 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15523 + " before boot completion"); 15524 throw new IllegalStateException("Cannot broadcast before boot completed"); 15525 } 15526 } 15527 15528 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15529 throw new IllegalArgumentException( 15530 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15531 } 15532 15533 return intent; 15534 } 15535 15536 public final int broadcastIntent(IApplicationThread caller, 15537 Intent intent, String resolvedType, IIntentReceiver resultTo, 15538 int resultCode, String resultData, Bundle map, 15539 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15540 enforceNotIsolatedCaller("broadcastIntent"); 15541 synchronized(this) { 15542 intent = verifyBroadcastLocked(intent); 15543 15544 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15545 final int callingPid = Binder.getCallingPid(); 15546 final int callingUid = Binder.getCallingUid(); 15547 final long origId = Binder.clearCallingIdentity(); 15548 int res = broadcastIntentLocked(callerApp, 15549 callerApp != null ? callerApp.info.packageName : null, 15550 intent, resolvedType, resultTo, 15551 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15552 callingPid, callingUid, userId); 15553 Binder.restoreCallingIdentity(origId); 15554 return res; 15555 } 15556 } 15557 15558 int broadcastIntentInPackage(String packageName, int uid, 15559 Intent intent, String resolvedType, IIntentReceiver resultTo, 15560 int resultCode, String resultData, Bundle map, 15561 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15562 synchronized(this) { 15563 intent = verifyBroadcastLocked(intent); 15564 15565 final long origId = Binder.clearCallingIdentity(); 15566 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15567 resultTo, resultCode, resultData, map, requiredPermission, 15568 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15569 Binder.restoreCallingIdentity(origId); 15570 return res; 15571 } 15572 } 15573 15574 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15575 // Refuse possible leaked file descriptors 15576 if (intent != null && intent.hasFileDescriptors() == true) { 15577 throw new IllegalArgumentException("File descriptors passed in Intent"); 15578 } 15579 15580 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15581 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15582 15583 synchronized(this) { 15584 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15585 != PackageManager.PERMISSION_GRANTED) { 15586 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15587 + Binder.getCallingPid() 15588 + ", uid=" + Binder.getCallingUid() 15589 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15590 Slog.w(TAG, msg); 15591 throw new SecurityException(msg); 15592 } 15593 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15594 if (stickies != null) { 15595 ArrayList<Intent> list = stickies.get(intent.getAction()); 15596 if (list != null) { 15597 int N = list.size(); 15598 int i; 15599 for (i=0; i<N; i++) { 15600 if (intent.filterEquals(list.get(i))) { 15601 list.remove(i); 15602 break; 15603 } 15604 } 15605 if (list.size() <= 0) { 15606 stickies.remove(intent.getAction()); 15607 } 15608 } 15609 if (stickies.size() <= 0) { 15610 mStickyBroadcasts.remove(userId); 15611 } 15612 } 15613 } 15614 } 15615 15616 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15617 String resultData, Bundle resultExtras, boolean resultAbort) { 15618 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15619 if (r == null) { 15620 Slog.w(TAG, "finishReceiver called but not found on queue"); 15621 return false; 15622 } 15623 15624 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15625 } 15626 15627 void backgroundServicesFinishedLocked(int userId) { 15628 for (BroadcastQueue queue : mBroadcastQueues) { 15629 queue.backgroundServicesFinishedLocked(userId); 15630 } 15631 } 15632 15633 public void finishReceiver(IBinder who, int resultCode, String resultData, 15634 Bundle resultExtras, boolean resultAbort) { 15635 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15636 15637 // Refuse possible leaked file descriptors 15638 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15639 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15640 } 15641 15642 final long origId = Binder.clearCallingIdentity(); 15643 try { 15644 boolean doNext = false; 15645 BroadcastRecord r; 15646 15647 synchronized(this) { 15648 r = broadcastRecordForReceiverLocked(who); 15649 if (r != null) { 15650 doNext = r.queue.finishReceiverLocked(r, resultCode, 15651 resultData, resultExtras, resultAbort, true); 15652 } 15653 } 15654 15655 if (doNext) { 15656 r.queue.processNextBroadcast(false); 15657 } 15658 trimApplications(); 15659 } finally { 15660 Binder.restoreCallingIdentity(origId); 15661 } 15662 } 15663 15664 // ========================================================= 15665 // INSTRUMENTATION 15666 // ========================================================= 15667 15668 public boolean startInstrumentation(ComponentName className, 15669 String profileFile, int flags, Bundle arguments, 15670 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15671 int userId, String abiOverride) { 15672 enforceNotIsolatedCaller("startInstrumentation"); 15673 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15674 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15675 // Refuse possible leaked file descriptors 15676 if (arguments != null && arguments.hasFileDescriptors()) { 15677 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15678 } 15679 15680 synchronized(this) { 15681 InstrumentationInfo ii = null; 15682 ApplicationInfo ai = null; 15683 try { 15684 ii = mContext.getPackageManager().getInstrumentationInfo( 15685 className, STOCK_PM_FLAGS); 15686 ai = AppGlobals.getPackageManager().getApplicationInfo( 15687 ii.targetPackage, STOCK_PM_FLAGS, userId); 15688 } catch (PackageManager.NameNotFoundException e) { 15689 } catch (RemoteException e) { 15690 } 15691 if (ii == null) { 15692 reportStartInstrumentationFailure(watcher, className, 15693 "Unable to find instrumentation info for: " + className); 15694 return false; 15695 } 15696 if (ai == null) { 15697 reportStartInstrumentationFailure(watcher, className, 15698 "Unable to find instrumentation target package: " + ii.targetPackage); 15699 return false; 15700 } 15701 15702 int match = mContext.getPackageManager().checkSignatures( 15703 ii.targetPackage, ii.packageName); 15704 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15705 String msg = "Permission Denial: starting instrumentation " 15706 + className + " from pid=" 15707 + Binder.getCallingPid() 15708 + ", uid=" + Binder.getCallingPid() 15709 + " not allowed because package " + ii.packageName 15710 + " does not have a signature matching the target " 15711 + ii.targetPackage; 15712 reportStartInstrumentationFailure(watcher, className, msg); 15713 throw new SecurityException(msg); 15714 } 15715 15716 final long origId = Binder.clearCallingIdentity(); 15717 // Instrumentation can kill and relaunch even persistent processes 15718 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15719 "start instr"); 15720 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15721 app.instrumentationClass = className; 15722 app.instrumentationInfo = ai; 15723 app.instrumentationProfileFile = profileFile; 15724 app.instrumentationArguments = arguments; 15725 app.instrumentationWatcher = watcher; 15726 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15727 app.instrumentationResultClass = className; 15728 Binder.restoreCallingIdentity(origId); 15729 } 15730 15731 return true; 15732 } 15733 15734 /** 15735 * Report errors that occur while attempting to start Instrumentation. Always writes the 15736 * error to the logs, but if somebody is watching, send the report there too. This enables 15737 * the "am" command to report errors with more information. 15738 * 15739 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15740 * @param cn The component name of the instrumentation. 15741 * @param report The error report. 15742 */ 15743 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15744 ComponentName cn, String report) { 15745 Slog.w(TAG, report); 15746 try { 15747 if (watcher != null) { 15748 Bundle results = new Bundle(); 15749 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15750 results.putString("Error", report); 15751 watcher.instrumentationStatus(cn, -1, results); 15752 } 15753 } catch (RemoteException e) { 15754 Slog.w(TAG, e); 15755 } 15756 } 15757 15758 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15759 if (app.instrumentationWatcher != null) { 15760 try { 15761 // NOTE: IInstrumentationWatcher *must* be oneway here 15762 app.instrumentationWatcher.instrumentationFinished( 15763 app.instrumentationClass, 15764 resultCode, 15765 results); 15766 } catch (RemoteException e) { 15767 } 15768 } 15769 if (app.instrumentationUiAutomationConnection != null) { 15770 try { 15771 app.instrumentationUiAutomationConnection.shutdown(); 15772 } catch (RemoteException re) { 15773 /* ignore */ 15774 } 15775 // Only a UiAutomation can set this flag and now that 15776 // it is finished we make sure it is reset to its default. 15777 mUserIsMonkey = false; 15778 } 15779 app.instrumentationWatcher = null; 15780 app.instrumentationUiAutomationConnection = null; 15781 app.instrumentationClass = null; 15782 app.instrumentationInfo = null; 15783 app.instrumentationProfileFile = null; 15784 app.instrumentationArguments = null; 15785 15786 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15787 "finished inst"); 15788 } 15789 15790 public void finishInstrumentation(IApplicationThread target, 15791 int resultCode, Bundle results) { 15792 int userId = UserHandle.getCallingUserId(); 15793 // Refuse possible leaked file descriptors 15794 if (results != null && results.hasFileDescriptors()) { 15795 throw new IllegalArgumentException("File descriptors passed in Intent"); 15796 } 15797 15798 synchronized(this) { 15799 ProcessRecord app = getRecordForAppLocked(target); 15800 if (app == null) { 15801 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15802 return; 15803 } 15804 final long origId = Binder.clearCallingIdentity(); 15805 finishInstrumentationLocked(app, resultCode, results); 15806 Binder.restoreCallingIdentity(origId); 15807 } 15808 } 15809 15810 // ========================================================= 15811 // CONFIGURATION 15812 // ========================================================= 15813 15814 public ConfigurationInfo getDeviceConfigurationInfo() { 15815 ConfigurationInfo config = new ConfigurationInfo(); 15816 synchronized (this) { 15817 config.reqTouchScreen = mConfiguration.touchscreen; 15818 config.reqKeyboardType = mConfiguration.keyboard; 15819 config.reqNavigation = mConfiguration.navigation; 15820 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15821 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15822 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15823 } 15824 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15825 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15826 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15827 } 15828 config.reqGlEsVersion = GL_ES_VERSION; 15829 } 15830 return config; 15831 } 15832 15833 ActivityStack getFocusedStack() { 15834 return mStackSupervisor.getFocusedStack(); 15835 } 15836 15837 public Configuration getConfiguration() { 15838 Configuration ci; 15839 synchronized(this) { 15840 ci = new Configuration(mConfiguration); 15841 } 15842 return ci; 15843 } 15844 15845 public void updatePersistentConfiguration(Configuration values) { 15846 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15847 "updateConfiguration()"); 15848 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15849 "updateConfiguration()"); 15850 if (values == null) { 15851 throw new NullPointerException("Configuration must not be null"); 15852 } 15853 15854 synchronized(this) { 15855 final long origId = Binder.clearCallingIdentity(); 15856 updateConfigurationLocked(values, null, true, false); 15857 Binder.restoreCallingIdentity(origId); 15858 } 15859 } 15860 15861 public void updateConfiguration(Configuration values) { 15862 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15863 "updateConfiguration()"); 15864 15865 synchronized(this) { 15866 if (values == null && mWindowManager != null) { 15867 // sentinel: fetch the current configuration from the window manager 15868 values = mWindowManager.computeNewConfiguration(); 15869 } 15870 15871 if (mWindowManager != null) { 15872 mProcessList.applyDisplaySize(mWindowManager); 15873 } 15874 15875 final long origId = Binder.clearCallingIdentity(); 15876 if (values != null) { 15877 Settings.System.clearConfiguration(values); 15878 } 15879 updateConfigurationLocked(values, null, false, false); 15880 Binder.restoreCallingIdentity(origId); 15881 } 15882 } 15883 15884 /** 15885 * Do either or both things: (1) change the current configuration, and (2) 15886 * make sure the given activity is running with the (now) current 15887 * configuration. Returns true if the activity has been left running, or 15888 * false if <var>starting</var> is being destroyed to match the new 15889 * configuration. 15890 * @param persistent TODO 15891 */ 15892 boolean updateConfigurationLocked(Configuration values, 15893 ActivityRecord starting, boolean persistent, boolean initLocale) { 15894 int changes = 0; 15895 15896 if (values != null) { 15897 Configuration newConfig = new Configuration(mConfiguration); 15898 changes = newConfig.updateFrom(values); 15899 if (changes != 0) { 15900 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15901 Slog.i(TAG, "Updating configuration to: " + values); 15902 } 15903 15904 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15905 15906 if (values.locale != null && !initLocale) { 15907 saveLocaleLocked(values.locale, 15908 !values.locale.equals(mConfiguration.locale), 15909 values.userSetLocale); 15910 } 15911 15912 mConfigurationSeq++; 15913 if (mConfigurationSeq <= 0) { 15914 mConfigurationSeq = 1; 15915 } 15916 newConfig.seq = mConfigurationSeq; 15917 mConfiguration = newConfig; 15918 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15919 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 15920 //mUsageStatsService.noteStartConfig(newConfig); 15921 15922 final Configuration configCopy = new Configuration(mConfiguration); 15923 15924 // TODO: If our config changes, should we auto dismiss any currently 15925 // showing dialogs? 15926 mShowDialogs = shouldShowDialogs(newConfig); 15927 15928 AttributeCache ac = AttributeCache.instance(); 15929 if (ac != null) { 15930 ac.updateConfiguration(configCopy); 15931 } 15932 15933 // Make sure all resources in our process are updated 15934 // right now, so that anyone who is going to retrieve 15935 // resource values after we return will be sure to get 15936 // the new ones. This is especially important during 15937 // boot, where the first config change needs to guarantee 15938 // all resources have that config before following boot 15939 // code is executed. 15940 mSystemThread.applyConfigurationToResources(configCopy); 15941 15942 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15943 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15944 msg.obj = new Configuration(configCopy); 15945 mHandler.sendMessage(msg); 15946 } 15947 15948 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15949 ProcessRecord app = mLruProcesses.get(i); 15950 try { 15951 if (app.thread != null) { 15952 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15953 + app.processName + " new config " + mConfiguration); 15954 app.thread.scheduleConfigurationChanged(configCopy); 15955 } 15956 } catch (Exception e) { 15957 } 15958 } 15959 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15960 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15961 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15962 | Intent.FLAG_RECEIVER_FOREGROUND); 15963 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15964 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15965 Process.SYSTEM_UID, UserHandle.USER_ALL); 15966 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15967 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15968 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15969 broadcastIntentLocked(null, null, intent, 15970 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15971 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15972 } 15973 } 15974 } 15975 15976 boolean kept = true; 15977 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15978 // mainStack is null during startup. 15979 if (mainStack != null) { 15980 if (changes != 0 && starting == null) { 15981 // If the configuration changed, and the caller is not already 15982 // in the process of starting an activity, then find the top 15983 // activity to check if its configuration needs to change. 15984 starting = mainStack.topRunningActivityLocked(null); 15985 } 15986 15987 if (starting != null) { 15988 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15989 // And we need to make sure at this point that all other activities 15990 // are made visible with the correct configuration. 15991 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15992 } 15993 } 15994 15995 if (values != null && mWindowManager != null) { 15996 mWindowManager.setNewConfiguration(mConfiguration); 15997 } 15998 15999 return kept; 16000 } 16001 16002 /** 16003 * Decide based on the configuration whether we should shouw the ANR, 16004 * crash, etc dialogs. The idea is that if there is no affordnace to 16005 * press the on-screen buttons, we shouldn't show the dialog. 16006 * 16007 * A thought: SystemUI might also want to get told about this, the Power 16008 * dialog / global actions also might want different behaviors. 16009 */ 16010 private static final boolean shouldShowDialogs(Configuration config) { 16011 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16012 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16013 } 16014 16015 /** 16016 * Save the locale. You must be inside a synchronized (this) block. 16017 */ 16018 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16019 if(isDiff) { 16020 SystemProperties.set("user.language", l.getLanguage()); 16021 SystemProperties.set("user.region", l.getCountry()); 16022 } 16023 16024 if(isPersist) { 16025 SystemProperties.set("persist.sys.language", l.getLanguage()); 16026 SystemProperties.set("persist.sys.country", l.getCountry()); 16027 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16028 } 16029 } 16030 16031 @Override 16032 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16033 synchronized (this) { 16034 ActivityRecord srec = ActivityRecord.forToken(token); 16035 if (srec.task != null && srec.task.stack != null) { 16036 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16037 } 16038 } 16039 return false; 16040 } 16041 16042 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16043 Intent resultData) { 16044 16045 synchronized (this) { 16046 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16047 if (stack != null) { 16048 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16049 } 16050 return false; 16051 } 16052 } 16053 16054 public int getLaunchedFromUid(IBinder activityToken) { 16055 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16056 if (srec == null) { 16057 return -1; 16058 } 16059 return srec.launchedFromUid; 16060 } 16061 16062 public String getLaunchedFromPackage(IBinder activityToken) { 16063 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16064 if (srec == null) { 16065 return null; 16066 } 16067 return srec.launchedFromPackage; 16068 } 16069 16070 // ========================================================= 16071 // LIFETIME MANAGEMENT 16072 // ========================================================= 16073 16074 // Returns which broadcast queue the app is the current [or imminent] receiver 16075 // on, or 'null' if the app is not an active broadcast recipient. 16076 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16077 BroadcastRecord r = app.curReceiver; 16078 if (r != null) { 16079 return r.queue; 16080 } 16081 16082 // It's not the current receiver, but it might be starting up to become one 16083 synchronized (this) { 16084 for (BroadcastQueue queue : mBroadcastQueues) { 16085 r = queue.mPendingBroadcast; 16086 if (r != null && r.curApp == app) { 16087 // found it; report which queue it's in 16088 return queue; 16089 } 16090 } 16091 } 16092 16093 return null; 16094 } 16095 16096 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16097 boolean doingAll, long now) { 16098 if (mAdjSeq == app.adjSeq) { 16099 // This adjustment has already been computed. 16100 return app.curRawAdj; 16101 } 16102 16103 if (app.thread == null) { 16104 app.adjSeq = mAdjSeq; 16105 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16106 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16107 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16108 } 16109 16110 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16111 app.adjSource = null; 16112 app.adjTarget = null; 16113 app.empty = false; 16114 app.cached = false; 16115 16116 final int activitiesSize = app.activities.size(); 16117 16118 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16119 // The max adjustment doesn't allow this app to be anything 16120 // below foreground, so it is not worth doing work for it. 16121 app.adjType = "fixed"; 16122 app.adjSeq = mAdjSeq; 16123 app.curRawAdj = app.maxAdj; 16124 app.foregroundActivities = false; 16125 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16126 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16127 // System processes can do UI, and when they do we want to have 16128 // them trim their memory after the user leaves the UI. To 16129 // facilitate this, here we need to determine whether or not it 16130 // is currently showing UI. 16131 app.systemNoUi = true; 16132 if (app == TOP_APP) { 16133 app.systemNoUi = false; 16134 } else if (activitiesSize > 0) { 16135 for (int j = 0; j < activitiesSize; j++) { 16136 final ActivityRecord r = app.activities.get(j); 16137 if (r.visible) { 16138 app.systemNoUi = false; 16139 } 16140 } 16141 } 16142 if (!app.systemNoUi) { 16143 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16144 } 16145 return (app.curAdj=app.maxAdj); 16146 } 16147 16148 app.systemNoUi = false; 16149 16150 // Determine the importance of the process, starting with most 16151 // important to least, and assign an appropriate OOM adjustment. 16152 int adj; 16153 int schedGroup; 16154 int procState; 16155 boolean foregroundActivities = false; 16156 BroadcastQueue queue; 16157 if (app == TOP_APP) { 16158 // The last app on the list is the foreground app. 16159 adj = ProcessList.FOREGROUND_APP_ADJ; 16160 schedGroup = Process.THREAD_GROUP_DEFAULT; 16161 app.adjType = "top-activity"; 16162 foregroundActivities = true; 16163 procState = ActivityManager.PROCESS_STATE_TOP; 16164 } else if (app.instrumentationClass != null) { 16165 // Don't want to kill running instrumentation. 16166 adj = ProcessList.FOREGROUND_APP_ADJ; 16167 schedGroup = Process.THREAD_GROUP_DEFAULT; 16168 app.adjType = "instrumentation"; 16169 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16170 } else if ((queue = isReceivingBroadcast(app)) != null) { 16171 // An app that is currently receiving a broadcast also 16172 // counts as being in the foreground for OOM killer purposes. 16173 // It's placed in a sched group based on the nature of the 16174 // broadcast as reflected by which queue it's active in. 16175 adj = ProcessList.FOREGROUND_APP_ADJ; 16176 schedGroup = (queue == mFgBroadcastQueue) 16177 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16178 app.adjType = "broadcast"; 16179 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16180 } else if (app.executingServices.size() > 0) { 16181 // An app that is currently executing a service callback also 16182 // counts as being in the foreground. 16183 adj = ProcessList.FOREGROUND_APP_ADJ; 16184 schedGroup = app.execServicesFg ? 16185 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16186 app.adjType = "exec-service"; 16187 procState = ActivityManager.PROCESS_STATE_SERVICE; 16188 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16189 } else { 16190 // As far as we know the process is empty. We may change our mind later. 16191 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16192 // At this point we don't actually know the adjustment. Use the cached adj 16193 // value that the caller wants us to. 16194 adj = cachedAdj; 16195 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16196 app.cached = true; 16197 app.empty = true; 16198 app.adjType = "cch-empty"; 16199 } 16200 16201 // Examine all activities if not already foreground. 16202 if (!foregroundActivities && activitiesSize > 0) { 16203 for (int j = 0; j < activitiesSize; j++) { 16204 final ActivityRecord r = app.activities.get(j); 16205 if (r.app != app) { 16206 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16207 + app + "?!?"); 16208 continue; 16209 } 16210 if (r.visible) { 16211 // App has a visible activity; only upgrade adjustment. 16212 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16213 adj = ProcessList.VISIBLE_APP_ADJ; 16214 app.adjType = "visible"; 16215 } 16216 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16217 procState = ActivityManager.PROCESS_STATE_TOP; 16218 } 16219 schedGroup = Process.THREAD_GROUP_DEFAULT; 16220 app.cached = false; 16221 app.empty = false; 16222 foregroundActivities = true; 16223 break; 16224 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16225 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16226 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16227 app.adjType = "pausing"; 16228 } 16229 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16230 procState = ActivityManager.PROCESS_STATE_TOP; 16231 } 16232 schedGroup = Process.THREAD_GROUP_DEFAULT; 16233 app.cached = false; 16234 app.empty = false; 16235 foregroundActivities = true; 16236 } else if (r.state == ActivityState.STOPPING) { 16237 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16238 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16239 app.adjType = "stopping"; 16240 } 16241 // For the process state, we will at this point consider the 16242 // process to be cached. It will be cached either as an activity 16243 // or empty depending on whether the activity is finishing. We do 16244 // this so that we can treat the process as cached for purposes of 16245 // memory trimming (determing current memory level, trim command to 16246 // send to process) since there can be an arbitrary number of stopping 16247 // processes and they should soon all go into the cached state. 16248 if (!r.finishing) { 16249 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16250 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16251 } 16252 } 16253 app.cached = false; 16254 app.empty = false; 16255 foregroundActivities = true; 16256 } else { 16257 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16258 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16259 app.adjType = "cch-act"; 16260 } 16261 } 16262 } 16263 } 16264 16265 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16266 if (app.foregroundServices) { 16267 // The user is aware of this app, so make it visible. 16268 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16269 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16270 app.cached = false; 16271 app.adjType = "fg-service"; 16272 schedGroup = Process.THREAD_GROUP_DEFAULT; 16273 } else if (app.forcingToForeground != null) { 16274 // The user is aware of this app, so make it visible. 16275 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16276 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16277 app.cached = false; 16278 app.adjType = "force-fg"; 16279 app.adjSource = app.forcingToForeground; 16280 schedGroup = Process.THREAD_GROUP_DEFAULT; 16281 } 16282 } 16283 16284 if (app == mHeavyWeightProcess) { 16285 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16286 // We don't want to kill the current heavy-weight process. 16287 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16288 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16289 app.cached = false; 16290 app.adjType = "heavy"; 16291 } 16292 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16293 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16294 } 16295 } 16296 16297 if (app == mHomeProcess) { 16298 if (adj > ProcessList.HOME_APP_ADJ) { 16299 // This process is hosting what we currently consider to be the 16300 // home app, so we don't want to let it go into the background. 16301 adj = ProcessList.HOME_APP_ADJ; 16302 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16303 app.cached = false; 16304 app.adjType = "home"; 16305 } 16306 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16307 procState = ActivityManager.PROCESS_STATE_HOME; 16308 } 16309 } 16310 16311 if (app == mPreviousProcess && app.activities.size() > 0) { 16312 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16313 // This was the previous process that showed UI to the user. 16314 // We want to try to keep it around more aggressively, to give 16315 // a good experience around switching between two apps. 16316 adj = ProcessList.PREVIOUS_APP_ADJ; 16317 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16318 app.cached = false; 16319 app.adjType = "previous"; 16320 } 16321 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16322 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16323 } 16324 } 16325 16326 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16327 + " reason=" + app.adjType); 16328 16329 // By default, we use the computed adjustment. It may be changed if 16330 // there are applications dependent on our services or providers, but 16331 // this gives us a baseline and makes sure we don't get into an 16332 // infinite recursion. 16333 app.adjSeq = mAdjSeq; 16334 app.curRawAdj = adj; 16335 app.hasStartedServices = false; 16336 16337 if (mBackupTarget != null && app == mBackupTarget.app) { 16338 // If possible we want to avoid killing apps while they're being backed up 16339 if (adj > ProcessList.BACKUP_APP_ADJ) { 16340 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16341 adj = ProcessList.BACKUP_APP_ADJ; 16342 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16343 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16344 } 16345 app.adjType = "backup"; 16346 app.cached = false; 16347 } 16348 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16349 procState = ActivityManager.PROCESS_STATE_BACKUP; 16350 } 16351 } 16352 16353 boolean mayBeTop = false; 16354 16355 for (int is = app.services.size()-1; 16356 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16357 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16358 || procState > ActivityManager.PROCESS_STATE_TOP); 16359 is--) { 16360 ServiceRecord s = app.services.valueAt(is); 16361 if (s.startRequested) { 16362 app.hasStartedServices = true; 16363 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16364 procState = ActivityManager.PROCESS_STATE_SERVICE; 16365 } 16366 if (app.hasShownUi && app != mHomeProcess) { 16367 // If this process has shown some UI, let it immediately 16368 // go to the LRU list because it may be pretty heavy with 16369 // UI stuff. We'll tag it with a label just to help 16370 // debug and understand what is going on. 16371 if (adj > ProcessList.SERVICE_ADJ) { 16372 app.adjType = "cch-started-ui-services"; 16373 } 16374 } else { 16375 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16376 // This service has seen some activity within 16377 // recent memory, so we will keep its process ahead 16378 // of the background processes. 16379 if (adj > ProcessList.SERVICE_ADJ) { 16380 adj = ProcessList.SERVICE_ADJ; 16381 app.adjType = "started-services"; 16382 app.cached = false; 16383 } 16384 } 16385 // If we have let the service slide into the background 16386 // state, still have some text describing what it is doing 16387 // even though the service no longer has an impact. 16388 if (adj > ProcessList.SERVICE_ADJ) { 16389 app.adjType = "cch-started-services"; 16390 } 16391 } 16392 } 16393 for (int conni = s.connections.size()-1; 16394 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16395 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16396 || procState > ActivityManager.PROCESS_STATE_TOP); 16397 conni--) { 16398 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16399 for (int i = 0; 16400 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16401 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16402 || procState > ActivityManager.PROCESS_STATE_TOP); 16403 i++) { 16404 // XXX should compute this based on the max of 16405 // all connected clients. 16406 ConnectionRecord cr = clist.get(i); 16407 if (cr.binding.client == app) { 16408 // Binding to ourself is not interesting. 16409 continue; 16410 } 16411 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16412 ProcessRecord client = cr.binding.client; 16413 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16414 TOP_APP, doingAll, now); 16415 int clientProcState = client.curProcState; 16416 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16417 // If the other app is cached for any reason, for purposes here 16418 // we are going to consider it empty. The specific cached state 16419 // doesn't propagate except under certain conditions. 16420 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16421 } 16422 String adjType = null; 16423 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16424 // Not doing bind OOM management, so treat 16425 // this guy more like a started service. 16426 if (app.hasShownUi && app != mHomeProcess) { 16427 // If this process has shown some UI, let it immediately 16428 // go to the LRU list because it may be pretty heavy with 16429 // UI stuff. We'll tag it with a label just to help 16430 // debug and understand what is going on. 16431 if (adj > clientAdj) { 16432 adjType = "cch-bound-ui-services"; 16433 } 16434 app.cached = false; 16435 clientAdj = adj; 16436 clientProcState = procState; 16437 } else { 16438 if (now >= (s.lastActivity 16439 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16440 // This service has not seen activity within 16441 // recent memory, so allow it to drop to the 16442 // LRU list if there is no other reason to keep 16443 // it around. We'll also tag it with a label just 16444 // to help debug and undertand what is going on. 16445 if (adj > clientAdj) { 16446 adjType = "cch-bound-services"; 16447 } 16448 clientAdj = adj; 16449 } 16450 } 16451 } 16452 if (adj > clientAdj) { 16453 // If this process has recently shown UI, and 16454 // the process that is binding to it is less 16455 // important than being visible, then we don't 16456 // care about the binding as much as we care 16457 // about letting this process get into the LRU 16458 // list to be killed and restarted if needed for 16459 // memory. 16460 if (app.hasShownUi && app != mHomeProcess 16461 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16462 adjType = "cch-bound-ui-services"; 16463 } else { 16464 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16465 |Context.BIND_IMPORTANT)) != 0) { 16466 adj = clientAdj; 16467 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16468 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16469 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16470 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16471 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16472 adj = clientAdj; 16473 } else { 16474 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16475 adj = ProcessList.VISIBLE_APP_ADJ; 16476 } 16477 } 16478 if (!client.cached) { 16479 app.cached = false; 16480 } 16481 adjType = "service"; 16482 } 16483 } 16484 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16485 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16486 schedGroup = Process.THREAD_GROUP_DEFAULT; 16487 } 16488 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16489 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16490 // Special handling of clients who are in the top state. 16491 // We *may* want to consider this process to be in the 16492 // top state as well, but only if there is not another 16493 // reason for it to be running. Being on the top is a 16494 // special state, meaning you are specifically running 16495 // for the current top app. If the process is already 16496 // running in the background for some other reason, it 16497 // is more important to continue considering it to be 16498 // in the background state. 16499 mayBeTop = true; 16500 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16501 } else { 16502 // Special handling for above-top states (persistent 16503 // processes). These should not bring the current process 16504 // into the top state, since they are not on top. Instead 16505 // give them the best state after that. 16506 clientProcState = 16507 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16508 } 16509 } 16510 } else { 16511 if (clientProcState < 16512 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16513 clientProcState = 16514 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16515 } 16516 } 16517 if (procState > clientProcState) { 16518 procState = clientProcState; 16519 } 16520 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16521 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16522 app.pendingUiClean = true; 16523 } 16524 if (adjType != null) { 16525 app.adjType = adjType; 16526 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16527 .REASON_SERVICE_IN_USE; 16528 app.adjSource = cr.binding.client; 16529 app.adjSourceProcState = clientProcState; 16530 app.adjTarget = s.name; 16531 } 16532 } 16533 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16534 app.treatLikeActivity = true; 16535 } 16536 final ActivityRecord a = cr.activity; 16537 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16538 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16539 (a.visible || a.state == ActivityState.RESUMED 16540 || a.state == ActivityState.PAUSING)) { 16541 adj = ProcessList.FOREGROUND_APP_ADJ; 16542 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16543 schedGroup = Process.THREAD_GROUP_DEFAULT; 16544 } 16545 app.cached = false; 16546 app.adjType = "service"; 16547 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16548 .REASON_SERVICE_IN_USE; 16549 app.adjSource = a; 16550 app.adjSourceProcState = procState; 16551 app.adjTarget = s.name; 16552 } 16553 } 16554 } 16555 } 16556 } 16557 16558 for (int provi = app.pubProviders.size()-1; 16559 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16560 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16561 || procState > ActivityManager.PROCESS_STATE_TOP); 16562 provi--) { 16563 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16564 for (int i = cpr.connections.size()-1; 16565 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16566 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16567 || procState > ActivityManager.PROCESS_STATE_TOP); 16568 i--) { 16569 ContentProviderConnection conn = cpr.connections.get(i); 16570 ProcessRecord client = conn.client; 16571 if (client == app) { 16572 // Being our own client is not interesting. 16573 continue; 16574 } 16575 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16576 int clientProcState = client.curProcState; 16577 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16578 // If the other app is cached for any reason, for purposes here 16579 // we are going to consider it empty. 16580 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16581 } 16582 if (adj > clientAdj) { 16583 if (app.hasShownUi && app != mHomeProcess 16584 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16585 app.adjType = "cch-ui-provider"; 16586 } else { 16587 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16588 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16589 app.adjType = "provider"; 16590 } 16591 app.cached &= client.cached; 16592 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16593 .REASON_PROVIDER_IN_USE; 16594 app.adjSource = client; 16595 app.adjSourceProcState = clientProcState; 16596 app.adjTarget = cpr.name; 16597 } 16598 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16599 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16600 // Special handling of clients who are in the top state. 16601 // We *may* want to consider this process to be in the 16602 // top state as well, but only if there is not another 16603 // reason for it to be running. Being on the top is a 16604 // special state, meaning you are specifically running 16605 // for the current top app. If the process is already 16606 // running in the background for some other reason, it 16607 // is more important to continue considering it to be 16608 // in the background state. 16609 mayBeTop = true; 16610 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16611 } else { 16612 // Special handling for above-top states (persistent 16613 // processes). These should not bring the current process 16614 // into the top state, since they are not on top. Instead 16615 // give them the best state after that. 16616 clientProcState = 16617 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16618 } 16619 } 16620 if (procState > clientProcState) { 16621 procState = clientProcState; 16622 } 16623 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16624 schedGroup = Process.THREAD_GROUP_DEFAULT; 16625 } 16626 } 16627 // If the provider has external (non-framework) process 16628 // dependencies, ensure that its adjustment is at least 16629 // FOREGROUND_APP_ADJ. 16630 if (cpr.hasExternalProcessHandles()) { 16631 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16632 adj = ProcessList.FOREGROUND_APP_ADJ; 16633 schedGroup = Process.THREAD_GROUP_DEFAULT; 16634 app.cached = false; 16635 app.adjType = "provider"; 16636 app.adjTarget = cpr.name; 16637 } 16638 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16639 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16640 } 16641 } 16642 } 16643 16644 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16645 // A client of one of our services or providers is in the top state. We 16646 // *may* want to be in the top state, but not if we are already running in 16647 // the background for some other reason. For the decision here, we are going 16648 // to pick out a few specific states that we want to remain in when a client 16649 // is top (states that tend to be longer-term) and otherwise allow it to go 16650 // to the top state. 16651 switch (procState) { 16652 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16653 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16654 case ActivityManager.PROCESS_STATE_SERVICE: 16655 // These all are longer-term states, so pull them up to the top 16656 // of the background states, but not all the way to the top state. 16657 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16658 break; 16659 default: 16660 // Otherwise, top is a better choice, so take it. 16661 procState = ActivityManager.PROCESS_STATE_TOP; 16662 break; 16663 } 16664 } 16665 16666 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16667 if (app.hasClientActivities) { 16668 // This is a cached process, but with client activities. Mark it so. 16669 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16670 app.adjType = "cch-client-act"; 16671 } else if (app.treatLikeActivity) { 16672 // This is a cached process, but somebody wants us to treat it like it has 16673 // an activity, okay! 16674 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16675 app.adjType = "cch-as-act"; 16676 } 16677 } 16678 16679 if (adj == ProcessList.SERVICE_ADJ) { 16680 if (doingAll) { 16681 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16682 mNewNumServiceProcs++; 16683 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16684 if (!app.serviceb) { 16685 // This service isn't far enough down on the LRU list to 16686 // normally be a B service, but if we are low on RAM and it 16687 // is large we want to force it down since we would prefer to 16688 // keep launcher over it. 16689 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16690 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16691 app.serviceHighRam = true; 16692 app.serviceb = true; 16693 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16694 } else { 16695 mNewNumAServiceProcs++; 16696 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16697 } 16698 } else { 16699 app.serviceHighRam = false; 16700 } 16701 } 16702 if (app.serviceb) { 16703 adj = ProcessList.SERVICE_B_ADJ; 16704 } 16705 } 16706 16707 app.curRawAdj = adj; 16708 16709 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16710 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16711 if (adj > app.maxAdj) { 16712 adj = app.maxAdj; 16713 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16714 schedGroup = Process.THREAD_GROUP_DEFAULT; 16715 } 16716 } 16717 16718 // Do final modification to adj. Everything we do between here and applying 16719 // the final setAdj must be done in this function, because we will also use 16720 // it when computing the final cached adj later. Note that we don't need to 16721 // worry about this for max adj above, since max adj will always be used to 16722 // keep it out of the cached vaues. 16723 app.curAdj = app.modifyRawOomAdj(adj); 16724 app.curSchedGroup = schedGroup; 16725 app.curProcState = procState; 16726 app.foregroundActivities = foregroundActivities; 16727 16728 return app.curRawAdj; 16729 } 16730 16731 /** 16732 * Schedule PSS collection of a process. 16733 */ 16734 void requestPssLocked(ProcessRecord proc, int procState) { 16735 if (mPendingPssProcesses.contains(proc)) { 16736 return; 16737 } 16738 if (mPendingPssProcesses.size() == 0) { 16739 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16740 } 16741 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16742 proc.pssProcState = procState; 16743 mPendingPssProcesses.add(proc); 16744 } 16745 16746 /** 16747 * Schedule PSS collection of all processes. 16748 */ 16749 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16750 if (!always) { 16751 if (now < (mLastFullPssTime + 16752 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16753 return; 16754 } 16755 } 16756 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16757 mLastFullPssTime = now; 16758 mFullPssPending = true; 16759 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16760 mPendingPssProcesses.clear(); 16761 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16762 ProcessRecord app = mLruProcesses.get(i); 16763 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16764 app.pssProcState = app.setProcState; 16765 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16766 isSleeping(), now); 16767 mPendingPssProcesses.add(app); 16768 } 16769 } 16770 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16771 } 16772 16773 /** 16774 * Ask a given process to GC right now. 16775 */ 16776 final void performAppGcLocked(ProcessRecord app) { 16777 try { 16778 app.lastRequestedGc = SystemClock.uptimeMillis(); 16779 if (app.thread != null) { 16780 if (app.reportLowMemory) { 16781 app.reportLowMemory = false; 16782 app.thread.scheduleLowMemory(); 16783 } else { 16784 app.thread.processInBackground(); 16785 } 16786 } 16787 } catch (Exception e) { 16788 // whatever. 16789 } 16790 } 16791 16792 /** 16793 * Returns true if things are idle enough to perform GCs. 16794 */ 16795 private final boolean canGcNowLocked() { 16796 boolean processingBroadcasts = false; 16797 for (BroadcastQueue q : mBroadcastQueues) { 16798 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16799 processingBroadcasts = true; 16800 } 16801 } 16802 return !processingBroadcasts 16803 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16804 } 16805 16806 /** 16807 * Perform GCs on all processes that are waiting for it, but only 16808 * if things are idle. 16809 */ 16810 final void performAppGcsLocked() { 16811 final int N = mProcessesToGc.size(); 16812 if (N <= 0) { 16813 return; 16814 } 16815 if (canGcNowLocked()) { 16816 while (mProcessesToGc.size() > 0) { 16817 ProcessRecord proc = mProcessesToGc.remove(0); 16818 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16819 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16820 <= SystemClock.uptimeMillis()) { 16821 // To avoid spamming the system, we will GC processes one 16822 // at a time, waiting a few seconds between each. 16823 performAppGcLocked(proc); 16824 scheduleAppGcsLocked(); 16825 return; 16826 } else { 16827 // It hasn't been long enough since we last GCed this 16828 // process... put it in the list to wait for its time. 16829 addProcessToGcListLocked(proc); 16830 break; 16831 } 16832 } 16833 } 16834 16835 scheduleAppGcsLocked(); 16836 } 16837 } 16838 16839 /** 16840 * If all looks good, perform GCs on all processes waiting for them. 16841 */ 16842 final void performAppGcsIfAppropriateLocked() { 16843 if (canGcNowLocked()) { 16844 performAppGcsLocked(); 16845 return; 16846 } 16847 // Still not idle, wait some more. 16848 scheduleAppGcsLocked(); 16849 } 16850 16851 /** 16852 * Schedule the execution of all pending app GCs. 16853 */ 16854 final void scheduleAppGcsLocked() { 16855 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16856 16857 if (mProcessesToGc.size() > 0) { 16858 // Schedule a GC for the time to the next process. 16859 ProcessRecord proc = mProcessesToGc.get(0); 16860 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16861 16862 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16863 long now = SystemClock.uptimeMillis(); 16864 if (when < (now+GC_TIMEOUT)) { 16865 when = now + GC_TIMEOUT; 16866 } 16867 mHandler.sendMessageAtTime(msg, when); 16868 } 16869 } 16870 16871 /** 16872 * Add a process to the array of processes waiting to be GCed. Keeps the 16873 * list in sorted order by the last GC time. The process can't already be 16874 * on the list. 16875 */ 16876 final void addProcessToGcListLocked(ProcessRecord proc) { 16877 boolean added = false; 16878 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16879 if (mProcessesToGc.get(i).lastRequestedGc < 16880 proc.lastRequestedGc) { 16881 added = true; 16882 mProcessesToGc.add(i+1, proc); 16883 break; 16884 } 16885 } 16886 if (!added) { 16887 mProcessesToGc.add(0, proc); 16888 } 16889 } 16890 16891 /** 16892 * Set up to ask a process to GC itself. This will either do it 16893 * immediately, or put it on the list of processes to gc the next 16894 * time things are idle. 16895 */ 16896 final void scheduleAppGcLocked(ProcessRecord app) { 16897 long now = SystemClock.uptimeMillis(); 16898 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16899 return; 16900 } 16901 if (!mProcessesToGc.contains(app)) { 16902 addProcessToGcListLocked(app); 16903 scheduleAppGcsLocked(); 16904 } 16905 } 16906 16907 final void checkExcessivePowerUsageLocked(boolean doKills) { 16908 updateCpuStatsNow(); 16909 16910 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16911 boolean doWakeKills = doKills; 16912 boolean doCpuKills = doKills; 16913 if (mLastPowerCheckRealtime == 0) { 16914 doWakeKills = false; 16915 } 16916 if (mLastPowerCheckUptime == 0) { 16917 doCpuKills = false; 16918 } 16919 if (stats.isScreenOn()) { 16920 doWakeKills = false; 16921 } 16922 final long curRealtime = SystemClock.elapsedRealtime(); 16923 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16924 final long curUptime = SystemClock.uptimeMillis(); 16925 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16926 mLastPowerCheckRealtime = curRealtime; 16927 mLastPowerCheckUptime = curUptime; 16928 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16929 doWakeKills = false; 16930 } 16931 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16932 doCpuKills = false; 16933 } 16934 int i = mLruProcesses.size(); 16935 while (i > 0) { 16936 i--; 16937 ProcessRecord app = mLruProcesses.get(i); 16938 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16939 long wtime; 16940 synchronized (stats) { 16941 wtime = stats.getProcessWakeTime(app.info.uid, 16942 app.pid, curRealtime); 16943 } 16944 long wtimeUsed = wtime - app.lastWakeTime; 16945 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16946 if (DEBUG_POWER) { 16947 StringBuilder sb = new StringBuilder(128); 16948 sb.append("Wake for "); 16949 app.toShortString(sb); 16950 sb.append(": over "); 16951 TimeUtils.formatDuration(realtimeSince, sb); 16952 sb.append(" used "); 16953 TimeUtils.formatDuration(wtimeUsed, sb); 16954 sb.append(" ("); 16955 sb.append((wtimeUsed*100)/realtimeSince); 16956 sb.append("%)"); 16957 Slog.i(TAG, sb.toString()); 16958 sb.setLength(0); 16959 sb.append("CPU for "); 16960 app.toShortString(sb); 16961 sb.append(": over "); 16962 TimeUtils.formatDuration(uptimeSince, sb); 16963 sb.append(" used "); 16964 TimeUtils.formatDuration(cputimeUsed, sb); 16965 sb.append(" ("); 16966 sb.append((cputimeUsed*100)/uptimeSince); 16967 sb.append("%)"); 16968 Slog.i(TAG, sb.toString()); 16969 } 16970 // If a process has held a wake lock for more 16971 // than 50% of the time during this period, 16972 // that sounds bad. Kill! 16973 if (doWakeKills && realtimeSince > 0 16974 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16975 synchronized (stats) { 16976 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16977 realtimeSince, wtimeUsed); 16978 } 16979 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16980 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16981 } else if (doCpuKills && uptimeSince > 0 16982 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16983 synchronized (stats) { 16984 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16985 uptimeSince, cputimeUsed); 16986 } 16987 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 16988 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16989 } else { 16990 app.lastWakeTime = wtime; 16991 app.lastCpuTime = app.curCpuTime; 16992 } 16993 } 16994 } 16995 } 16996 16997 private final boolean applyOomAdjLocked(ProcessRecord app, 16998 ProcessRecord TOP_APP, boolean doingAll, long now) { 16999 boolean success = true; 17000 17001 if (app.curRawAdj != app.setRawAdj) { 17002 app.setRawAdj = app.curRawAdj; 17003 } 17004 17005 int changes = 0; 17006 17007 if (app.curAdj != app.setAdj) { 17008 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17009 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17010 TAG, "Set " + app.pid + " " + app.processName + 17011 " adj " + app.curAdj + ": " + app.adjType); 17012 app.setAdj = app.curAdj; 17013 } 17014 17015 if (app.setSchedGroup != app.curSchedGroup) { 17016 app.setSchedGroup = app.curSchedGroup; 17017 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17018 "Setting process group of " + app.processName 17019 + " to " + app.curSchedGroup); 17020 if (app.waitingToKill != null && 17021 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17022 app.kill(app.waitingToKill, true); 17023 success = false; 17024 } else { 17025 if (true) { 17026 long oldId = Binder.clearCallingIdentity(); 17027 try { 17028 Process.setProcessGroup(app.pid, app.curSchedGroup); 17029 } catch (Exception e) { 17030 Slog.w(TAG, "Failed setting process group of " + app.pid 17031 + " to " + app.curSchedGroup); 17032 e.printStackTrace(); 17033 } finally { 17034 Binder.restoreCallingIdentity(oldId); 17035 } 17036 } else { 17037 if (app.thread != null) { 17038 try { 17039 app.thread.setSchedulingGroup(app.curSchedGroup); 17040 } catch (RemoteException e) { 17041 } 17042 } 17043 } 17044 Process.setSwappiness(app.pid, 17045 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17046 } 17047 } 17048 if (app.repForegroundActivities != app.foregroundActivities) { 17049 app.repForegroundActivities = app.foregroundActivities; 17050 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17051 } 17052 if (app.repProcState != app.curProcState) { 17053 app.repProcState = app.curProcState; 17054 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17055 if (app.thread != null) { 17056 try { 17057 if (false) { 17058 //RuntimeException h = new RuntimeException("here"); 17059 Slog.i(TAG, "Sending new process state " + app.repProcState 17060 + " to " + app /*, h*/); 17061 } 17062 app.thread.setProcessState(app.repProcState); 17063 } catch (RemoteException e) { 17064 } 17065 } 17066 } 17067 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17068 app.setProcState)) { 17069 app.lastStateTime = now; 17070 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17071 isSleeping(), now); 17072 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17073 + ProcessList.makeProcStateString(app.setProcState) + " to " 17074 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17075 + (app.nextPssTime-now) + ": " + app); 17076 } else { 17077 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17078 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17079 requestPssLocked(app, app.setProcState); 17080 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17081 isSleeping(), now); 17082 } else if (false && DEBUG_PSS) { 17083 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17084 } 17085 } 17086 if (app.setProcState != app.curProcState) { 17087 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17088 "Proc state change of " + app.processName 17089 + " to " + app.curProcState); 17090 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17091 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17092 if (setImportant && !curImportant) { 17093 // This app is no longer something we consider important enough to allow to 17094 // use arbitrary amounts of battery power. Note 17095 // its current wake lock time to later know to kill it if 17096 // it is not behaving well. 17097 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17098 synchronized (stats) { 17099 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17100 app.pid, SystemClock.elapsedRealtime()); 17101 } 17102 app.lastCpuTime = app.curCpuTime; 17103 17104 } 17105 app.setProcState = app.curProcState; 17106 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17107 app.notCachedSinceIdle = false; 17108 } 17109 if (!doingAll) { 17110 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17111 } else { 17112 app.procStateChanged = true; 17113 } 17114 } 17115 17116 if (changes != 0) { 17117 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17118 int i = mPendingProcessChanges.size()-1; 17119 ProcessChangeItem item = null; 17120 while (i >= 0) { 17121 item = mPendingProcessChanges.get(i); 17122 if (item.pid == app.pid) { 17123 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17124 break; 17125 } 17126 i--; 17127 } 17128 if (i < 0) { 17129 // No existing item in pending changes; need a new one. 17130 final int NA = mAvailProcessChanges.size(); 17131 if (NA > 0) { 17132 item = mAvailProcessChanges.remove(NA-1); 17133 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17134 } else { 17135 item = new ProcessChangeItem(); 17136 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17137 } 17138 item.changes = 0; 17139 item.pid = app.pid; 17140 item.uid = app.info.uid; 17141 if (mPendingProcessChanges.size() == 0) { 17142 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17143 "*** Enqueueing dispatch processes changed!"); 17144 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17145 } 17146 mPendingProcessChanges.add(item); 17147 } 17148 item.changes |= changes; 17149 item.processState = app.repProcState; 17150 item.foregroundActivities = app.repForegroundActivities; 17151 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17152 + Integer.toHexString(System.identityHashCode(item)) 17153 + " " + app.toShortString() + ": changes=" + item.changes 17154 + " procState=" + item.processState 17155 + " foreground=" + item.foregroundActivities 17156 + " type=" + app.adjType + " source=" + app.adjSource 17157 + " target=" + app.adjTarget); 17158 } 17159 17160 return success; 17161 } 17162 17163 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17164 if (proc.thread != null) { 17165 if (proc.baseProcessTracker != null) { 17166 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17167 } 17168 if (proc.repProcState >= 0) { 17169 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17170 proc.repProcState); 17171 } 17172 } 17173 } 17174 17175 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17176 ProcessRecord TOP_APP, boolean doingAll, long now) { 17177 if (app.thread == null) { 17178 return false; 17179 } 17180 17181 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17182 17183 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17184 } 17185 17186 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17187 boolean oomAdj) { 17188 if (isForeground != proc.foregroundServices) { 17189 proc.foregroundServices = isForeground; 17190 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17191 proc.info.uid); 17192 if (isForeground) { 17193 if (curProcs == null) { 17194 curProcs = new ArrayList<ProcessRecord>(); 17195 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17196 } 17197 if (!curProcs.contains(proc)) { 17198 curProcs.add(proc); 17199 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17200 proc.info.packageName, proc.info.uid); 17201 } 17202 } else { 17203 if (curProcs != null) { 17204 if (curProcs.remove(proc)) { 17205 mBatteryStatsService.noteEvent( 17206 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17207 proc.info.packageName, proc.info.uid); 17208 if (curProcs.size() <= 0) { 17209 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17210 } 17211 } 17212 } 17213 } 17214 if (oomAdj) { 17215 updateOomAdjLocked(); 17216 } 17217 } 17218 } 17219 17220 private final ActivityRecord resumedAppLocked() { 17221 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17222 String pkg; 17223 int uid; 17224 if (act != null) { 17225 pkg = act.packageName; 17226 uid = act.info.applicationInfo.uid; 17227 } else { 17228 pkg = null; 17229 uid = -1; 17230 } 17231 // Has the UID or resumed package name changed? 17232 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17233 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17234 if (mCurResumedPackage != null) { 17235 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17236 mCurResumedPackage, mCurResumedUid); 17237 } 17238 mCurResumedPackage = pkg; 17239 mCurResumedUid = uid; 17240 if (mCurResumedPackage != null) { 17241 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17242 mCurResumedPackage, mCurResumedUid); 17243 } 17244 } 17245 return act; 17246 } 17247 17248 final boolean updateOomAdjLocked(ProcessRecord app) { 17249 final ActivityRecord TOP_ACT = resumedAppLocked(); 17250 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17251 final boolean wasCached = app.cached; 17252 17253 mAdjSeq++; 17254 17255 // This is the desired cached adjusment we want to tell it to use. 17256 // If our app is currently cached, we know it, and that is it. Otherwise, 17257 // we don't know it yet, and it needs to now be cached we will then 17258 // need to do a complete oom adj. 17259 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17260 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17261 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17262 SystemClock.uptimeMillis()); 17263 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17264 // Changed to/from cached state, so apps after it in the LRU 17265 // list may also be changed. 17266 updateOomAdjLocked(); 17267 } 17268 return success; 17269 } 17270 17271 final void updateOomAdjLocked() { 17272 final ActivityRecord TOP_ACT = resumedAppLocked(); 17273 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17274 final long now = SystemClock.uptimeMillis(); 17275 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17276 final int N = mLruProcesses.size(); 17277 17278 if (false) { 17279 RuntimeException e = new RuntimeException(); 17280 e.fillInStackTrace(); 17281 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17282 } 17283 17284 mAdjSeq++; 17285 mNewNumServiceProcs = 0; 17286 mNewNumAServiceProcs = 0; 17287 17288 final int emptyProcessLimit; 17289 final int cachedProcessLimit; 17290 if (mProcessLimit <= 0) { 17291 emptyProcessLimit = cachedProcessLimit = 0; 17292 } else if (mProcessLimit == 1) { 17293 emptyProcessLimit = 1; 17294 cachedProcessLimit = 0; 17295 } else { 17296 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17297 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17298 } 17299 17300 // Let's determine how many processes we have running vs. 17301 // how many slots we have for background processes; we may want 17302 // to put multiple processes in a slot of there are enough of 17303 // them. 17304 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17305 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17306 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17307 if (numEmptyProcs > cachedProcessLimit) { 17308 // If there are more empty processes than our limit on cached 17309 // processes, then use the cached process limit for the factor. 17310 // This ensures that the really old empty processes get pushed 17311 // down to the bottom, so if we are running low on memory we will 17312 // have a better chance at keeping around more cached processes 17313 // instead of a gazillion empty processes. 17314 numEmptyProcs = cachedProcessLimit; 17315 } 17316 int emptyFactor = numEmptyProcs/numSlots; 17317 if (emptyFactor < 1) emptyFactor = 1; 17318 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17319 if (cachedFactor < 1) cachedFactor = 1; 17320 int stepCached = 0; 17321 int stepEmpty = 0; 17322 int numCached = 0; 17323 int numEmpty = 0; 17324 int numTrimming = 0; 17325 17326 mNumNonCachedProcs = 0; 17327 mNumCachedHiddenProcs = 0; 17328 17329 // First update the OOM adjustment for each of the 17330 // application processes based on their current state. 17331 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17332 int nextCachedAdj = curCachedAdj+1; 17333 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17334 int nextEmptyAdj = curEmptyAdj+2; 17335 for (int i=N-1; i>=0; i--) { 17336 ProcessRecord app = mLruProcesses.get(i); 17337 if (!app.killedByAm && app.thread != null) { 17338 app.procStateChanged = false; 17339 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17340 17341 // If we haven't yet assigned the final cached adj 17342 // to the process, do that now. 17343 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17344 switch (app.curProcState) { 17345 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17346 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17347 // This process is a cached process holding activities... 17348 // assign it the next cached value for that type, and then 17349 // step that cached level. 17350 app.curRawAdj = curCachedAdj; 17351 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17352 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17353 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17354 + ")"); 17355 if (curCachedAdj != nextCachedAdj) { 17356 stepCached++; 17357 if (stepCached >= cachedFactor) { 17358 stepCached = 0; 17359 curCachedAdj = nextCachedAdj; 17360 nextCachedAdj += 2; 17361 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17362 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17363 } 17364 } 17365 } 17366 break; 17367 default: 17368 // For everything else, assign next empty cached process 17369 // level and bump that up. Note that this means that 17370 // long-running services that have dropped down to the 17371 // cached level will be treated as empty (since their process 17372 // state is still as a service), which is what we want. 17373 app.curRawAdj = curEmptyAdj; 17374 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17375 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17376 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17377 + ")"); 17378 if (curEmptyAdj != nextEmptyAdj) { 17379 stepEmpty++; 17380 if (stepEmpty >= emptyFactor) { 17381 stepEmpty = 0; 17382 curEmptyAdj = nextEmptyAdj; 17383 nextEmptyAdj += 2; 17384 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17385 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17386 } 17387 } 17388 } 17389 break; 17390 } 17391 } 17392 17393 applyOomAdjLocked(app, TOP_APP, true, now); 17394 17395 // Count the number of process types. 17396 switch (app.curProcState) { 17397 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17398 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17399 mNumCachedHiddenProcs++; 17400 numCached++; 17401 if (numCached > cachedProcessLimit) { 17402 app.kill("cached #" + numCached, true); 17403 } 17404 break; 17405 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17406 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17407 && app.lastActivityTime < oldTime) { 17408 app.kill("empty for " 17409 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17410 / 1000) + "s", true); 17411 } else { 17412 numEmpty++; 17413 if (numEmpty > emptyProcessLimit) { 17414 app.kill("empty #" + numEmpty, true); 17415 } 17416 } 17417 break; 17418 default: 17419 mNumNonCachedProcs++; 17420 break; 17421 } 17422 17423 if (app.isolated && app.services.size() <= 0) { 17424 // If this is an isolated process, and there are no 17425 // services running in it, then the process is no longer 17426 // needed. We agressively kill these because we can by 17427 // definition not re-use the same process again, and it is 17428 // good to avoid having whatever code was running in them 17429 // left sitting around after no longer needed. 17430 app.kill("isolated not needed", true); 17431 } 17432 17433 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17434 && !app.killedByAm) { 17435 numTrimming++; 17436 } 17437 } 17438 } 17439 17440 mNumServiceProcs = mNewNumServiceProcs; 17441 17442 // Now determine the memory trimming level of background processes. 17443 // Unfortunately we need to start at the back of the list to do this 17444 // properly. We only do this if the number of background apps we 17445 // are managing to keep around is less than half the maximum we desire; 17446 // if we are keeping a good number around, we'll let them use whatever 17447 // memory they want. 17448 final int numCachedAndEmpty = numCached + numEmpty; 17449 int memFactor; 17450 if (numCached <= ProcessList.TRIM_CACHED_APPS 17451 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17452 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17453 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17454 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17455 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17456 } else { 17457 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17458 } 17459 } else { 17460 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17461 } 17462 // We always allow the memory level to go up (better). We only allow it to go 17463 // down if we are in a state where that is allowed, *and* the total number of processes 17464 // has gone down since last time. 17465 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17466 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17467 + " last=" + mLastNumProcesses); 17468 if (memFactor > mLastMemoryLevel) { 17469 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17470 memFactor = mLastMemoryLevel; 17471 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17472 } 17473 } 17474 mLastMemoryLevel = memFactor; 17475 mLastNumProcesses = mLruProcesses.size(); 17476 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17477 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17478 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17479 if (mLowRamStartTime == 0) { 17480 mLowRamStartTime = now; 17481 } 17482 int step = 0; 17483 int fgTrimLevel; 17484 switch (memFactor) { 17485 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17486 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17487 break; 17488 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17489 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17490 break; 17491 default: 17492 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17493 break; 17494 } 17495 int factor = numTrimming/3; 17496 int minFactor = 2; 17497 if (mHomeProcess != null) minFactor++; 17498 if (mPreviousProcess != null) minFactor++; 17499 if (factor < minFactor) factor = minFactor; 17500 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17501 for (int i=N-1; i>=0; i--) { 17502 ProcessRecord app = mLruProcesses.get(i); 17503 if (allChanged || app.procStateChanged) { 17504 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17505 app.procStateChanged = false; 17506 } 17507 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17508 && !app.killedByAm) { 17509 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17510 try { 17511 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17512 "Trimming memory of " + app.processName 17513 + " to " + curLevel); 17514 app.thread.scheduleTrimMemory(curLevel); 17515 } catch (RemoteException e) { 17516 } 17517 if (false) { 17518 // For now we won't do this; our memory trimming seems 17519 // to be good enough at this point that destroying 17520 // activities causes more harm than good. 17521 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17522 && app != mHomeProcess && app != mPreviousProcess) { 17523 // Need to do this on its own message because the stack may not 17524 // be in a consistent state at this point. 17525 // For these apps we will also finish their activities 17526 // to help them free memory. 17527 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17528 } 17529 } 17530 } 17531 app.trimMemoryLevel = curLevel; 17532 step++; 17533 if (step >= factor) { 17534 step = 0; 17535 switch (curLevel) { 17536 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17537 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17538 break; 17539 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17540 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17541 break; 17542 } 17543 } 17544 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17545 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17546 && app.thread != null) { 17547 try { 17548 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17549 "Trimming memory of heavy-weight " + app.processName 17550 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17551 app.thread.scheduleTrimMemory( 17552 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17553 } catch (RemoteException e) { 17554 } 17555 } 17556 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17557 } else { 17558 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17559 || app.systemNoUi) && app.pendingUiClean) { 17560 // If this application is now in the background and it 17561 // had done UI, then give it the special trim level to 17562 // have it free UI resources. 17563 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17564 if (app.trimMemoryLevel < level && app.thread != null) { 17565 try { 17566 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17567 "Trimming memory of bg-ui " + app.processName 17568 + " to " + level); 17569 app.thread.scheduleTrimMemory(level); 17570 } catch (RemoteException e) { 17571 } 17572 } 17573 app.pendingUiClean = false; 17574 } 17575 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17576 try { 17577 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17578 "Trimming memory of fg " + app.processName 17579 + " to " + fgTrimLevel); 17580 app.thread.scheduleTrimMemory(fgTrimLevel); 17581 } catch (RemoteException e) { 17582 } 17583 } 17584 app.trimMemoryLevel = fgTrimLevel; 17585 } 17586 } 17587 } else { 17588 if (mLowRamStartTime != 0) { 17589 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17590 mLowRamStartTime = 0; 17591 } 17592 for (int i=N-1; i>=0; i--) { 17593 ProcessRecord app = mLruProcesses.get(i); 17594 if (allChanged || app.procStateChanged) { 17595 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17596 app.procStateChanged = false; 17597 } 17598 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17599 || app.systemNoUi) && app.pendingUiClean) { 17600 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17601 && app.thread != null) { 17602 try { 17603 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17604 "Trimming memory of ui hidden " + app.processName 17605 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17606 app.thread.scheduleTrimMemory( 17607 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17608 } catch (RemoteException e) { 17609 } 17610 } 17611 app.pendingUiClean = false; 17612 } 17613 app.trimMemoryLevel = 0; 17614 } 17615 } 17616 17617 if (mAlwaysFinishActivities) { 17618 // Need to do this on its own message because the stack may not 17619 // be in a consistent state at this point. 17620 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17621 } 17622 17623 if (allChanged) { 17624 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17625 } 17626 17627 if (mProcessStats.shouldWriteNowLocked(now)) { 17628 mHandler.post(new Runnable() { 17629 @Override public void run() { 17630 synchronized (ActivityManagerService.this) { 17631 mProcessStats.writeStateAsyncLocked(); 17632 } 17633 } 17634 }); 17635 } 17636 17637 if (DEBUG_OOM_ADJ) { 17638 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17639 } 17640 } 17641 17642 final void trimApplications() { 17643 synchronized (this) { 17644 int i; 17645 17646 // First remove any unused application processes whose package 17647 // has been removed. 17648 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17649 final ProcessRecord app = mRemovedProcesses.get(i); 17650 if (app.activities.size() == 0 17651 && app.curReceiver == null && app.services.size() == 0) { 17652 Slog.i( 17653 TAG, "Exiting empty application process " 17654 + app.processName + " (" 17655 + (app.thread != null ? app.thread.asBinder() : null) 17656 + ")\n"); 17657 if (app.pid > 0 && app.pid != MY_PID) { 17658 app.kill("empty", false); 17659 } else { 17660 try { 17661 app.thread.scheduleExit(); 17662 } catch (Exception e) { 17663 // Ignore exceptions. 17664 } 17665 } 17666 cleanUpApplicationRecordLocked(app, false, true, -1); 17667 mRemovedProcesses.remove(i); 17668 17669 if (app.persistent) { 17670 addAppLocked(app.info, false, null /* ABI override */); 17671 } 17672 } 17673 } 17674 17675 // Now update the oom adj for all processes. 17676 updateOomAdjLocked(); 17677 } 17678 } 17679 17680 /** This method sends the specified signal to each of the persistent apps */ 17681 public void signalPersistentProcesses(int sig) throws RemoteException { 17682 if (sig != Process.SIGNAL_USR1) { 17683 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17684 } 17685 17686 synchronized (this) { 17687 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17688 != PackageManager.PERMISSION_GRANTED) { 17689 throw new SecurityException("Requires permission " 17690 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17691 } 17692 17693 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17694 ProcessRecord r = mLruProcesses.get(i); 17695 if (r.thread != null && r.persistent) { 17696 Process.sendSignal(r.pid, sig); 17697 } 17698 } 17699 } 17700 } 17701 17702 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17703 if (proc == null || proc == mProfileProc) { 17704 proc = mProfileProc; 17705 profileType = mProfileType; 17706 clearProfilerLocked(); 17707 } 17708 if (proc == null) { 17709 return; 17710 } 17711 try { 17712 proc.thread.profilerControl(false, null, profileType); 17713 } catch (RemoteException e) { 17714 throw new IllegalStateException("Process disappeared"); 17715 } 17716 } 17717 17718 private void clearProfilerLocked() { 17719 if (mProfileFd != null) { 17720 try { 17721 mProfileFd.close(); 17722 } catch (IOException e) { 17723 } 17724 } 17725 mProfileApp = null; 17726 mProfileProc = null; 17727 mProfileFile = null; 17728 mProfileType = 0; 17729 mAutoStopProfiler = false; 17730 mSamplingInterval = 0; 17731 } 17732 17733 public boolean profileControl(String process, int userId, boolean start, 17734 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17735 17736 try { 17737 synchronized (this) { 17738 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17739 // its own permission. 17740 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17741 != PackageManager.PERMISSION_GRANTED) { 17742 throw new SecurityException("Requires permission " 17743 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17744 } 17745 17746 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17747 throw new IllegalArgumentException("null profile info or fd"); 17748 } 17749 17750 ProcessRecord proc = null; 17751 if (process != null) { 17752 proc = findProcessLocked(process, userId, "profileControl"); 17753 } 17754 17755 if (start && (proc == null || proc.thread == null)) { 17756 throw new IllegalArgumentException("Unknown process: " + process); 17757 } 17758 17759 if (start) { 17760 stopProfilerLocked(null, 0); 17761 setProfileApp(proc.info, proc.processName, profilerInfo); 17762 mProfileProc = proc; 17763 mProfileType = profileType; 17764 ParcelFileDescriptor fd = profilerInfo.profileFd; 17765 try { 17766 fd = fd.dup(); 17767 } catch (IOException e) { 17768 fd = null; 17769 } 17770 profilerInfo.profileFd = fd; 17771 proc.thread.profilerControl(start, profilerInfo, profileType); 17772 fd = null; 17773 mProfileFd = null; 17774 } else { 17775 stopProfilerLocked(proc, profileType); 17776 if (profilerInfo != null && profilerInfo.profileFd != null) { 17777 try { 17778 profilerInfo.profileFd.close(); 17779 } catch (IOException e) { 17780 } 17781 } 17782 } 17783 17784 return true; 17785 } 17786 } catch (RemoteException e) { 17787 throw new IllegalStateException("Process disappeared"); 17788 } finally { 17789 if (profilerInfo != null && profilerInfo.profileFd != null) { 17790 try { 17791 profilerInfo.profileFd.close(); 17792 } catch (IOException e) { 17793 } 17794 } 17795 } 17796 } 17797 17798 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17799 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17800 userId, true, ALLOW_FULL_ONLY, callName, null); 17801 ProcessRecord proc = null; 17802 try { 17803 int pid = Integer.parseInt(process); 17804 synchronized (mPidsSelfLocked) { 17805 proc = mPidsSelfLocked.get(pid); 17806 } 17807 } catch (NumberFormatException e) { 17808 } 17809 17810 if (proc == null) { 17811 ArrayMap<String, SparseArray<ProcessRecord>> all 17812 = mProcessNames.getMap(); 17813 SparseArray<ProcessRecord> procs = all.get(process); 17814 if (procs != null && procs.size() > 0) { 17815 proc = procs.valueAt(0); 17816 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17817 for (int i=1; i<procs.size(); i++) { 17818 ProcessRecord thisProc = procs.valueAt(i); 17819 if (thisProc.userId == userId) { 17820 proc = thisProc; 17821 break; 17822 } 17823 } 17824 } 17825 } 17826 } 17827 17828 return proc; 17829 } 17830 17831 public boolean dumpHeap(String process, int userId, boolean managed, 17832 String path, ParcelFileDescriptor fd) throws RemoteException { 17833 17834 try { 17835 synchronized (this) { 17836 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17837 // its own permission (same as profileControl). 17838 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17839 != PackageManager.PERMISSION_GRANTED) { 17840 throw new SecurityException("Requires permission " 17841 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17842 } 17843 17844 if (fd == null) { 17845 throw new IllegalArgumentException("null fd"); 17846 } 17847 17848 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17849 if (proc == null || proc.thread == null) { 17850 throw new IllegalArgumentException("Unknown process: " + process); 17851 } 17852 17853 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17854 if (!isDebuggable) { 17855 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17856 throw new SecurityException("Process not debuggable: " + proc); 17857 } 17858 } 17859 17860 proc.thread.dumpHeap(managed, path, fd); 17861 fd = null; 17862 return true; 17863 } 17864 } catch (RemoteException e) { 17865 throw new IllegalStateException("Process disappeared"); 17866 } finally { 17867 if (fd != null) { 17868 try { 17869 fd.close(); 17870 } catch (IOException e) { 17871 } 17872 } 17873 } 17874 } 17875 17876 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17877 public void monitor() { 17878 synchronized (this) { } 17879 } 17880 17881 void onCoreSettingsChange(Bundle settings) { 17882 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17883 ProcessRecord processRecord = mLruProcesses.get(i); 17884 try { 17885 if (processRecord.thread != null) { 17886 processRecord.thread.setCoreSettings(settings); 17887 } 17888 } catch (RemoteException re) { 17889 /* ignore */ 17890 } 17891 } 17892 } 17893 17894 // Multi-user methods 17895 17896 /** 17897 * Start user, if its not already running, but don't bring it to foreground. 17898 */ 17899 @Override 17900 public boolean startUserInBackground(final int userId) { 17901 return startUser(userId, /* foreground */ false); 17902 } 17903 17904 /** 17905 * Start user, if its not already running, and bring it to foreground. 17906 */ 17907 boolean startUserInForeground(final int userId, Dialog dlg) { 17908 boolean result = startUser(userId, /* foreground */ true); 17909 dlg.dismiss(); 17910 return result; 17911 } 17912 17913 /** 17914 * Refreshes the list of users related to the current user when either a 17915 * user switch happens or when a new related user is started in the 17916 * background. 17917 */ 17918 private void updateCurrentProfileIdsLocked() { 17919 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17920 mCurrentUserId, false /* enabledOnly */); 17921 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17922 for (int i = 0; i < currentProfileIds.length; i++) { 17923 currentProfileIds[i] = profiles.get(i).id; 17924 } 17925 mCurrentProfileIds = currentProfileIds; 17926 17927 synchronized (mUserProfileGroupIdsSelfLocked) { 17928 mUserProfileGroupIdsSelfLocked.clear(); 17929 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17930 for (int i = 0; i < users.size(); i++) { 17931 UserInfo user = users.get(i); 17932 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17933 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17934 } 17935 } 17936 } 17937 } 17938 17939 private Set getProfileIdsLocked(int userId) { 17940 Set userIds = new HashSet<Integer>(); 17941 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17942 userId, false /* enabledOnly */); 17943 for (UserInfo user : profiles) { 17944 userIds.add(Integer.valueOf(user.id)); 17945 } 17946 return userIds; 17947 } 17948 17949 @Override 17950 public boolean switchUser(final int userId) { 17951 String userName; 17952 synchronized (this) { 17953 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17954 if (userInfo == null) { 17955 Slog.w(TAG, "No user info for user #" + userId); 17956 return false; 17957 } 17958 if (userInfo.isManagedProfile()) { 17959 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17960 return false; 17961 } 17962 userName = userInfo.name; 17963 } 17964 mHandler.removeMessages(START_USER_SWITCH_MSG); 17965 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17966 return true; 17967 } 17968 17969 private void showUserSwitchDialog(int userId, String userName) { 17970 // The dialog will show and then initiate the user switch by calling startUserInForeground 17971 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17972 true /* above system */); 17973 d.show(); 17974 } 17975 17976 private boolean startUser(final int userId, final boolean foreground) { 17977 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17978 != PackageManager.PERMISSION_GRANTED) { 17979 String msg = "Permission Denial: switchUser() from pid=" 17980 + Binder.getCallingPid() 17981 + ", uid=" + Binder.getCallingUid() 17982 + " requires " + INTERACT_ACROSS_USERS_FULL; 17983 Slog.w(TAG, msg); 17984 throw new SecurityException(msg); 17985 } 17986 17987 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17988 17989 final long ident = Binder.clearCallingIdentity(); 17990 try { 17991 synchronized (this) { 17992 final int oldUserId = mCurrentUserId; 17993 if (oldUserId == userId) { 17994 return true; 17995 } 17996 17997 mStackSupervisor.setLockTaskModeLocked(null, false); 17998 17999 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18000 if (userInfo == null) { 18001 Slog.w(TAG, "No user info for user #" + userId); 18002 return false; 18003 } 18004 if (foreground && userInfo.isManagedProfile()) { 18005 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18006 return false; 18007 } 18008 18009 if (foreground) { 18010 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18011 R.anim.screen_user_enter); 18012 } 18013 18014 boolean needStart = false; 18015 18016 // If the user we are switching to is not currently started, then 18017 // we need to start it now. 18018 if (mStartedUsers.get(userId) == null) { 18019 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18020 updateStartedUserArrayLocked(); 18021 needStart = true; 18022 } 18023 18024 final Integer userIdInt = Integer.valueOf(userId); 18025 mUserLru.remove(userIdInt); 18026 mUserLru.add(userIdInt); 18027 18028 if (foreground) { 18029 mCurrentUserId = userId; 18030 updateCurrentProfileIdsLocked(); 18031 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18032 // Once the internal notion of the active user has switched, we lock the device 18033 // with the option to show the user switcher on the keyguard. 18034 mWindowManager.lockNow(null); 18035 } else { 18036 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18037 updateCurrentProfileIdsLocked(); 18038 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18039 mUserLru.remove(currentUserIdInt); 18040 mUserLru.add(currentUserIdInt); 18041 } 18042 18043 final UserStartedState uss = mStartedUsers.get(userId); 18044 18045 // Make sure user is in the started state. If it is currently 18046 // stopping, we need to knock that off. 18047 if (uss.mState == UserStartedState.STATE_STOPPING) { 18048 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18049 // so we can just fairly silently bring the user back from 18050 // the almost-dead. 18051 uss.mState = UserStartedState.STATE_RUNNING; 18052 updateStartedUserArrayLocked(); 18053 needStart = true; 18054 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18055 // This means ACTION_SHUTDOWN has been sent, so we will 18056 // need to treat this as a new boot of the user. 18057 uss.mState = UserStartedState.STATE_BOOTING; 18058 updateStartedUserArrayLocked(); 18059 needStart = true; 18060 } 18061 18062 if (uss.mState == UserStartedState.STATE_BOOTING) { 18063 // Booting up a new user, need to tell system services about it. 18064 // Note that this is on the same handler as scheduling of broadcasts, 18065 // which is important because it needs to go first. 18066 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18067 } 18068 18069 if (foreground) { 18070 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18071 oldUserId)); 18072 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18073 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18074 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18075 oldUserId, userId, uss)); 18076 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18077 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18078 } 18079 18080 if (needStart) { 18081 // Send USER_STARTED broadcast 18082 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18083 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18084 | Intent.FLAG_RECEIVER_FOREGROUND); 18085 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18086 broadcastIntentLocked(null, null, intent, 18087 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18088 false, false, MY_PID, Process.SYSTEM_UID, userId); 18089 } 18090 18091 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18092 if (userId != UserHandle.USER_OWNER) { 18093 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18094 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18095 broadcastIntentLocked(null, null, intent, null, 18096 new IIntentReceiver.Stub() { 18097 public void performReceive(Intent intent, int resultCode, 18098 String data, Bundle extras, boolean ordered, 18099 boolean sticky, int sendingUser) { 18100 onUserInitialized(uss, foreground, oldUserId, userId); 18101 } 18102 }, 0, null, null, null, AppOpsManager.OP_NONE, 18103 true, false, MY_PID, Process.SYSTEM_UID, 18104 userId); 18105 uss.initializing = true; 18106 } else { 18107 getUserManagerLocked().makeInitialized(userInfo.id); 18108 } 18109 } 18110 18111 if (foreground) { 18112 if (!uss.initializing) { 18113 moveUserToForeground(uss, oldUserId, userId); 18114 } 18115 } else { 18116 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18117 } 18118 18119 if (needStart) { 18120 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18121 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18122 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18123 broadcastIntentLocked(null, null, intent, 18124 null, new IIntentReceiver.Stub() { 18125 @Override 18126 public void performReceive(Intent intent, int resultCode, String data, 18127 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18128 throws RemoteException { 18129 } 18130 }, 0, null, null, 18131 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18132 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18133 } 18134 } 18135 } finally { 18136 Binder.restoreCallingIdentity(ident); 18137 } 18138 18139 return true; 18140 } 18141 18142 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18143 long ident = Binder.clearCallingIdentity(); 18144 try { 18145 Intent intent; 18146 if (oldUserId >= 0) { 18147 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18148 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18149 int count = profiles.size(); 18150 for (int i = 0; i < count; i++) { 18151 int profileUserId = profiles.get(i).id; 18152 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18153 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18154 | Intent.FLAG_RECEIVER_FOREGROUND); 18155 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18156 broadcastIntentLocked(null, null, intent, 18157 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18158 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18159 } 18160 } 18161 if (newUserId >= 0) { 18162 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18163 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18164 int count = profiles.size(); 18165 for (int i = 0; i < count; i++) { 18166 int profileUserId = profiles.get(i).id; 18167 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18168 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18169 | Intent.FLAG_RECEIVER_FOREGROUND); 18170 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18171 broadcastIntentLocked(null, null, intent, 18172 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18173 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18174 } 18175 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18176 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18177 | Intent.FLAG_RECEIVER_FOREGROUND); 18178 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18179 broadcastIntentLocked(null, null, intent, 18180 null, null, 0, null, null, 18181 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18182 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18183 } 18184 } finally { 18185 Binder.restoreCallingIdentity(ident); 18186 } 18187 } 18188 18189 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18190 final int newUserId) { 18191 final int N = mUserSwitchObservers.beginBroadcast(); 18192 if (N > 0) { 18193 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18194 int mCount = 0; 18195 @Override 18196 public void sendResult(Bundle data) throws RemoteException { 18197 synchronized (ActivityManagerService.this) { 18198 if (mCurUserSwitchCallback == this) { 18199 mCount++; 18200 if (mCount == N) { 18201 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18202 } 18203 } 18204 } 18205 } 18206 }; 18207 synchronized (this) { 18208 uss.switching = true; 18209 mCurUserSwitchCallback = callback; 18210 } 18211 for (int i=0; i<N; i++) { 18212 try { 18213 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18214 newUserId, callback); 18215 } catch (RemoteException e) { 18216 } 18217 } 18218 } else { 18219 synchronized (this) { 18220 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18221 } 18222 } 18223 mUserSwitchObservers.finishBroadcast(); 18224 } 18225 18226 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18227 synchronized (this) { 18228 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18229 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18230 } 18231 } 18232 18233 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18234 mCurUserSwitchCallback = null; 18235 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18236 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18237 oldUserId, newUserId, uss)); 18238 } 18239 18240 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18241 synchronized (this) { 18242 if (foreground) { 18243 moveUserToForeground(uss, oldUserId, newUserId); 18244 } 18245 } 18246 18247 completeSwitchAndInitalize(uss, newUserId, true, false); 18248 } 18249 18250 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18251 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18252 if (homeInFront) { 18253 startHomeActivityLocked(newUserId); 18254 } else { 18255 mStackSupervisor.resumeTopActivitiesLocked(); 18256 } 18257 EventLogTags.writeAmSwitchUser(newUserId); 18258 getUserManagerLocked().userForeground(newUserId); 18259 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18260 } 18261 18262 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18263 completeSwitchAndInitalize(uss, newUserId, false, true); 18264 } 18265 18266 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18267 boolean clearInitializing, boolean clearSwitching) { 18268 boolean unfrozen = false; 18269 synchronized (this) { 18270 if (clearInitializing) { 18271 uss.initializing = false; 18272 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18273 } 18274 if (clearSwitching) { 18275 uss.switching = false; 18276 } 18277 if (!uss.switching && !uss.initializing) { 18278 mWindowManager.stopFreezingScreen(); 18279 unfrozen = true; 18280 } 18281 } 18282 if (unfrozen) { 18283 final int N = mUserSwitchObservers.beginBroadcast(); 18284 for (int i=0; i<N; i++) { 18285 try { 18286 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18287 } catch (RemoteException e) { 18288 } 18289 } 18290 mUserSwitchObservers.finishBroadcast(); 18291 } 18292 } 18293 18294 void scheduleStartProfilesLocked() { 18295 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18296 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18297 DateUtils.SECOND_IN_MILLIS); 18298 } 18299 } 18300 18301 void startProfilesLocked() { 18302 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18303 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18304 mCurrentUserId, false /* enabledOnly */); 18305 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18306 for (UserInfo user : profiles) { 18307 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18308 && user.id != mCurrentUserId) { 18309 toStart.add(user); 18310 } 18311 } 18312 final int n = toStart.size(); 18313 int i = 0; 18314 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18315 startUserInBackground(toStart.get(i).id); 18316 } 18317 if (i < n) { 18318 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18319 } 18320 } 18321 18322 void finishUserBoot(UserStartedState uss) { 18323 synchronized (this) { 18324 if (uss.mState == UserStartedState.STATE_BOOTING 18325 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18326 uss.mState = UserStartedState.STATE_RUNNING; 18327 final int userId = uss.mHandle.getIdentifier(); 18328 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18329 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18330 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18331 broadcastIntentLocked(null, null, intent, 18332 null, null, 0, null, null, 18333 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18334 true, false, MY_PID, Process.SYSTEM_UID, userId); 18335 } 18336 } 18337 } 18338 18339 void finishUserSwitch(UserStartedState uss) { 18340 synchronized (this) { 18341 finishUserBoot(uss); 18342 18343 startProfilesLocked(); 18344 18345 int num = mUserLru.size(); 18346 int i = 0; 18347 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18348 Integer oldUserId = mUserLru.get(i); 18349 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18350 if (oldUss == null) { 18351 // Shouldn't happen, but be sane if it does. 18352 mUserLru.remove(i); 18353 num--; 18354 continue; 18355 } 18356 if (oldUss.mState == UserStartedState.STATE_STOPPING 18357 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18358 // This user is already stopping, doesn't count. 18359 num--; 18360 i++; 18361 continue; 18362 } 18363 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18364 // Owner and current can't be stopped, but count as running. 18365 i++; 18366 continue; 18367 } 18368 // This is a user to be stopped. 18369 stopUserLocked(oldUserId, null); 18370 num--; 18371 i++; 18372 } 18373 } 18374 } 18375 18376 @Override 18377 public int stopUser(final int userId, final IStopUserCallback callback) { 18378 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18379 != PackageManager.PERMISSION_GRANTED) { 18380 String msg = "Permission Denial: switchUser() from pid=" 18381 + Binder.getCallingPid() 18382 + ", uid=" + Binder.getCallingUid() 18383 + " requires " + INTERACT_ACROSS_USERS_FULL; 18384 Slog.w(TAG, msg); 18385 throw new SecurityException(msg); 18386 } 18387 if (userId <= 0) { 18388 throw new IllegalArgumentException("Can't stop primary user " + userId); 18389 } 18390 synchronized (this) { 18391 return stopUserLocked(userId, callback); 18392 } 18393 } 18394 18395 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18396 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18397 if (mCurrentUserId == userId) { 18398 return ActivityManager.USER_OP_IS_CURRENT; 18399 } 18400 18401 final UserStartedState uss = mStartedUsers.get(userId); 18402 if (uss == null) { 18403 // User is not started, nothing to do... but we do need to 18404 // callback if requested. 18405 if (callback != null) { 18406 mHandler.post(new Runnable() { 18407 @Override 18408 public void run() { 18409 try { 18410 callback.userStopped(userId); 18411 } catch (RemoteException e) { 18412 } 18413 } 18414 }); 18415 } 18416 return ActivityManager.USER_OP_SUCCESS; 18417 } 18418 18419 if (callback != null) { 18420 uss.mStopCallbacks.add(callback); 18421 } 18422 18423 if (uss.mState != UserStartedState.STATE_STOPPING 18424 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18425 uss.mState = UserStartedState.STATE_STOPPING; 18426 updateStartedUserArrayLocked(); 18427 18428 long ident = Binder.clearCallingIdentity(); 18429 try { 18430 // We are going to broadcast ACTION_USER_STOPPING and then 18431 // once that is done send a final ACTION_SHUTDOWN and then 18432 // stop the user. 18433 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18434 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18435 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18436 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18437 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18438 // This is the result receiver for the final shutdown broadcast. 18439 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18440 @Override 18441 public void performReceive(Intent intent, int resultCode, String data, 18442 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18443 finishUserStop(uss); 18444 } 18445 }; 18446 // This is the result receiver for the initial stopping broadcast. 18447 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18448 @Override 18449 public void performReceive(Intent intent, int resultCode, String data, 18450 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18451 // On to the next. 18452 synchronized (ActivityManagerService.this) { 18453 if (uss.mState != UserStartedState.STATE_STOPPING) { 18454 // Whoops, we are being started back up. Abort, abort! 18455 return; 18456 } 18457 uss.mState = UserStartedState.STATE_SHUTDOWN; 18458 } 18459 mBatteryStatsService.noteEvent( 18460 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18461 Integer.toString(userId), userId); 18462 mSystemServiceManager.stopUser(userId); 18463 broadcastIntentLocked(null, null, shutdownIntent, 18464 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18465 true, false, MY_PID, Process.SYSTEM_UID, userId); 18466 } 18467 }; 18468 // Kick things off. 18469 broadcastIntentLocked(null, null, stoppingIntent, 18470 null, stoppingReceiver, 0, null, null, 18471 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18472 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18473 } finally { 18474 Binder.restoreCallingIdentity(ident); 18475 } 18476 } 18477 18478 return ActivityManager.USER_OP_SUCCESS; 18479 } 18480 18481 void finishUserStop(UserStartedState uss) { 18482 final int userId = uss.mHandle.getIdentifier(); 18483 boolean stopped; 18484 ArrayList<IStopUserCallback> callbacks; 18485 synchronized (this) { 18486 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18487 if (mStartedUsers.get(userId) != uss) { 18488 stopped = false; 18489 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18490 stopped = false; 18491 } else { 18492 stopped = true; 18493 // User can no longer run. 18494 mStartedUsers.remove(userId); 18495 mUserLru.remove(Integer.valueOf(userId)); 18496 updateStartedUserArrayLocked(); 18497 18498 // Clean up all state and processes associated with the user. 18499 // Kill all the processes for the user. 18500 forceStopUserLocked(userId, "finish user"); 18501 } 18502 18503 // Explicitly remove the old information in mRecentTasks. 18504 removeRecentTasksForUserLocked(userId); 18505 } 18506 18507 for (int i=0; i<callbacks.size(); i++) { 18508 try { 18509 if (stopped) callbacks.get(i).userStopped(userId); 18510 else callbacks.get(i).userStopAborted(userId); 18511 } catch (RemoteException e) { 18512 } 18513 } 18514 18515 if (stopped) { 18516 mSystemServiceManager.cleanupUser(userId); 18517 synchronized (this) { 18518 mStackSupervisor.removeUserLocked(userId); 18519 } 18520 } 18521 } 18522 18523 @Override 18524 public UserInfo getCurrentUser() { 18525 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18526 != PackageManager.PERMISSION_GRANTED) && ( 18527 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18528 != PackageManager.PERMISSION_GRANTED)) { 18529 String msg = "Permission Denial: getCurrentUser() from pid=" 18530 + Binder.getCallingPid() 18531 + ", uid=" + Binder.getCallingUid() 18532 + " requires " + INTERACT_ACROSS_USERS; 18533 Slog.w(TAG, msg); 18534 throw new SecurityException(msg); 18535 } 18536 synchronized (this) { 18537 return getUserManagerLocked().getUserInfo(mCurrentUserId); 18538 } 18539 } 18540 18541 int getCurrentUserIdLocked() { 18542 return mCurrentUserId; 18543 } 18544 18545 @Override 18546 public boolean isUserRunning(int userId, boolean orStopped) { 18547 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18548 != PackageManager.PERMISSION_GRANTED) { 18549 String msg = "Permission Denial: isUserRunning() from pid=" 18550 + Binder.getCallingPid() 18551 + ", uid=" + Binder.getCallingUid() 18552 + " requires " + INTERACT_ACROSS_USERS; 18553 Slog.w(TAG, msg); 18554 throw new SecurityException(msg); 18555 } 18556 synchronized (this) { 18557 return isUserRunningLocked(userId, orStopped); 18558 } 18559 } 18560 18561 boolean isUserRunningLocked(int userId, boolean orStopped) { 18562 UserStartedState state = mStartedUsers.get(userId); 18563 if (state == null) { 18564 return false; 18565 } 18566 if (orStopped) { 18567 return true; 18568 } 18569 return state.mState != UserStartedState.STATE_STOPPING 18570 && state.mState != UserStartedState.STATE_SHUTDOWN; 18571 } 18572 18573 @Override 18574 public int[] getRunningUserIds() { 18575 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18576 != PackageManager.PERMISSION_GRANTED) { 18577 String msg = "Permission Denial: isUserRunning() from pid=" 18578 + Binder.getCallingPid() 18579 + ", uid=" + Binder.getCallingUid() 18580 + " requires " + INTERACT_ACROSS_USERS; 18581 Slog.w(TAG, msg); 18582 throw new SecurityException(msg); 18583 } 18584 synchronized (this) { 18585 return mStartedUserArray; 18586 } 18587 } 18588 18589 private void updateStartedUserArrayLocked() { 18590 int num = 0; 18591 for (int i=0; i<mStartedUsers.size(); i++) { 18592 UserStartedState uss = mStartedUsers.valueAt(i); 18593 // This list does not include stopping users. 18594 if (uss.mState != UserStartedState.STATE_STOPPING 18595 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18596 num++; 18597 } 18598 } 18599 mStartedUserArray = new int[num]; 18600 num = 0; 18601 for (int i=0; i<mStartedUsers.size(); i++) { 18602 UserStartedState uss = mStartedUsers.valueAt(i); 18603 if (uss.mState != UserStartedState.STATE_STOPPING 18604 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18605 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18606 num++; 18607 } 18608 } 18609 } 18610 18611 @Override 18612 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18613 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18614 != PackageManager.PERMISSION_GRANTED) { 18615 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18616 + Binder.getCallingPid() 18617 + ", uid=" + Binder.getCallingUid() 18618 + " requires " + INTERACT_ACROSS_USERS_FULL; 18619 Slog.w(TAG, msg); 18620 throw new SecurityException(msg); 18621 } 18622 18623 mUserSwitchObservers.register(observer); 18624 } 18625 18626 @Override 18627 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18628 mUserSwitchObservers.unregister(observer); 18629 } 18630 18631 private boolean userExists(int userId) { 18632 if (userId == 0) { 18633 return true; 18634 } 18635 UserManagerService ums = getUserManagerLocked(); 18636 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18637 } 18638 18639 int[] getUsersLocked() { 18640 UserManagerService ums = getUserManagerLocked(); 18641 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18642 } 18643 18644 UserManagerService getUserManagerLocked() { 18645 if (mUserManager == null) { 18646 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18647 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18648 } 18649 return mUserManager; 18650 } 18651 18652 private int applyUserId(int uid, int userId) { 18653 return UserHandle.getUid(userId, uid); 18654 } 18655 18656 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18657 if (info == null) return null; 18658 ApplicationInfo newInfo = new ApplicationInfo(info); 18659 newInfo.uid = applyUserId(info.uid, userId); 18660 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18661 + info.packageName; 18662 return newInfo; 18663 } 18664 18665 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18666 if (aInfo == null 18667 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18668 return aInfo; 18669 } 18670 18671 ActivityInfo info = new ActivityInfo(aInfo); 18672 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18673 return info; 18674 } 18675 18676 private final class LocalService extends ActivityManagerInternal { 18677 @Override 18678 public void goingToSleep() { 18679 ActivityManagerService.this.goingToSleep(); 18680 } 18681 18682 @Override 18683 public void wakingUp() { 18684 ActivityManagerService.this.wakingUp(); 18685 } 18686 18687 @Override 18688 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18689 String processName, String abiOverride, int uid, Runnable crashHandler) { 18690 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18691 processName, abiOverride, uid, crashHandler); 18692 } 18693 } 18694 18695 /** 18696 * An implementation of IAppTask, that allows an app to manage its own tasks via 18697 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18698 * only the process that calls getAppTasks() can call the AppTask methods. 18699 */ 18700 class AppTaskImpl extends IAppTask.Stub { 18701 private int mTaskId; 18702 private int mCallingUid; 18703 18704 public AppTaskImpl(int taskId, int callingUid) { 18705 mTaskId = taskId; 18706 mCallingUid = callingUid; 18707 } 18708 18709 private void checkCaller() { 18710 if (mCallingUid != Binder.getCallingUid()) { 18711 throw new SecurityException("Caller " + mCallingUid 18712 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18713 } 18714 } 18715 18716 @Override 18717 public void finishAndRemoveTask() { 18718 checkCaller(); 18719 18720 synchronized (ActivityManagerService.this) { 18721 long origId = Binder.clearCallingIdentity(); 18722 try { 18723 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18724 if (tr == null) { 18725 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18726 } 18727 // Only kill the process if we are not a new document 18728 int flags = tr.getBaseIntent().getFlags(); 18729 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18730 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18731 removeTaskByIdLocked(mTaskId, 18732 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18733 } finally { 18734 Binder.restoreCallingIdentity(origId); 18735 } 18736 } 18737 } 18738 18739 @Override 18740 public ActivityManager.RecentTaskInfo getTaskInfo() { 18741 checkCaller(); 18742 18743 synchronized (ActivityManagerService.this) { 18744 long origId = Binder.clearCallingIdentity(); 18745 try { 18746 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18747 if (tr == null) { 18748 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18749 } 18750 return createRecentTaskInfoFromTaskRecord(tr); 18751 } finally { 18752 Binder.restoreCallingIdentity(origId); 18753 } 18754 } 18755 } 18756 18757 @Override 18758 public void moveToFront() { 18759 checkCaller(); 18760 18761 final TaskRecord tr; 18762 synchronized (ActivityManagerService.this) { 18763 tr = recentTaskForIdLocked(mTaskId); 18764 if (tr == null) { 18765 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18766 } 18767 if (tr.getRootActivity() != null) { 18768 long origId = Binder.clearCallingIdentity(); 18769 try { 18770 moveTaskToFrontLocked(tr.taskId, 0, null); 18771 return; 18772 } finally { 18773 Binder.restoreCallingIdentity(origId); 18774 } 18775 } 18776 } 18777 18778 startActivityFromRecentsInner(tr.taskId, null); 18779 } 18780 18781 @Override 18782 public int startActivity(IBinder whoThread, String callingPackage, 18783 Intent intent, String resolvedType, Bundle options) { 18784 checkCaller(); 18785 18786 int callingUser = UserHandle.getCallingUserId(); 18787 TaskRecord tr; 18788 IApplicationThread appThread; 18789 synchronized (ActivityManagerService.this) { 18790 tr = recentTaskForIdLocked(mTaskId); 18791 if (tr == null) { 18792 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18793 } 18794 appThread = ApplicationThreadNative.asInterface(whoThread); 18795 if (appThread == null) { 18796 throw new IllegalArgumentException("Bad app thread " + appThread); 18797 } 18798 } 18799 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18800 resolvedType, null, null, null, null, 0, 0, null, null, 18801 null, options, callingUser, null, tr); 18802 } 18803 18804 @Override 18805 public void setExcludeFromRecents(boolean exclude) { 18806 checkCaller(); 18807 18808 synchronized (ActivityManagerService.this) { 18809 long origId = Binder.clearCallingIdentity(); 18810 try { 18811 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18812 if (tr == null) { 18813 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18814 } 18815 Intent intent = tr.getBaseIntent(); 18816 if (exclude) { 18817 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18818 } else { 18819 intent.setFlags(intent.getFlags() 18820 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18821 } 18822 } finally { 18823 Binder.restoreCallingIdentity(origId); 18824 } 18825 } 18826 } 18827 } 18828} 18829