ActivityManagerService.java revision 2ade126e626d5d6d2d2e82fce4060458a0ca21c5
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; 199import dalvik.system.VMRuntime; 200 201import java.io.BufferedInputStream; 202import java.io.BufferedOutputStream; 203import java.io.DataInputStream; 204import java.io.DataOutputStream; 205import java.io.File; 206import java.io.FileDescriptor; 207import java.io.FileInputStream; 208import java.io.FileNotFoundException; 209import java.io.FileOutputStream; 210import java.io.IOException; 211import java.io.InputStreamReader; 212import java.io.PrintWriter; 213import java.io.StringWriter; 214import java.lang.ref.WeakReference; 215import java.util.ArrayList; 216import java.util.Arrays; 217import java.util.Collections; 218import java.util.Comparator; 219import java.util.HashMap; 220import java.util.HashSet; 221import java.util.Iterator; 222import java.util.List; 223import java.util.Locale; 224import java.util.Map; 225import java.util.Set; 226import java.util.concurrent.atomic.AtomicBoolean; 227import java.util.concurrent.atomic.AtomicLong; 228 229public final class ActivityManagerService extends ActivityManagerNative 230 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 231 232 private static final String USER_DATA_DIR = "/data/user/"; 233 // File that stores last updated system version and called preboot receivers 234 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 235 236 static final String TAG = "ActivityManager"; 237 static final String TAG_MU = "ActivityManagerServiceMU"; 238 static final boolean DEBUG = false; 239 static final boolean localLOGV = DEBUG; 240 static final boolean DEBUG_BACKUP = localLOGV || false; 241 static final boolean DEBUG_BROADCAST = localLOGV || false; 242 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 244 static final boolean DEBUG_CLEANUP = localLOGV || false; 245 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 246 static final boolean DEBUG_FOCUS = false; 247 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 248 static final boolean DEBUG_MU = localLOGV || false; 249 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 250 static final boolean DEBUG_LRU = localLOGV || false; 251 static final boolean DEBUG_PAUSE = localLOGV || false; 252 static final boolean DEBUG_POWER = localLOGV || false; 253 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 254 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 255 static final boolean DEBUG_PROCESSES = localLOGV || false; 256 static final boolean DEBUG_PROVIDER = localLOGV || false; 257 static final boolean DEBUG_RESULTS = localLOGV || false; 258 static final boolean DEBUG_SERVICE = localLOGV || false; 259 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 260 static final boolean DEBUG_STACK = localLOGV || false; 261 static final boolean DEBUG_SWITCH = localLOGV || false; 262 static final boolean DEBUG_TASKS = localLOGV || false; 263 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 264 static final boolean DEBUG_TRANSITION = localLOGV || false; 265 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 266 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 267 static final boolean DEBUG_VISBILITY = localLOGV || false; 268 static final boolean DEBUG_PSS = localLOGV || false; 269 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 270 static final boolean DEBUG_RECENTS = localLOGV || false; 271 static final boolean VALIDATE_TOKENS = false; 272 static final boolean SHOW_ACTIVITY_START_TIME = true; 273 274 // Control over CPU and battery monitoring. 275 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 276 static final boolean MONITOR_CPU_USAGE = true; 277 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 278 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 279 static final boolean MONITOR_THREAD_CPU_USAGE = false; 280 281 // The flags that are set for all calls we make to the package manager. 282 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 283 284 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 285 286 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 287 288 // Maximum number recent bitmaps to keep in memory. 289 static final int MAX_RECENT_BITMAPS = 5; 290 291 // Amount of time after a call to stopAppSwitches() during which we will 292 // prevent further untrusted switches from happening. 293 static final long APP_SWITCH_DELAY_TIME = 5*1000; 294 295 // How long we wait for a launched process to attach to the activity manager 296 // before we decide it's never going to come up for real. 297 static final int PROC_START_TIMEOUT = 10*1000; 298 299 // How long we wait for a launched process to attach to the activity manager 300 // before we decide it's never going to come up for real, when the process was 301 // started with a wrapper for instrumentation (such as Valgrind) because it 302 // could take much longer than usual. 303 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 304 305 // How long to wait after going idle before forcing apps to GC. 306 static final int GC_TIMEOUT = 5*1000; 307 308 // The minimum amount of time between successive GC requests for a process. 309 static final int GC_MIN_INTERVAL = 60*1000; 310 311 // The minimum amount of time between successive PSS requests for a process. 312 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 313 314 // The minimum amount of time between successive PSS requests for a process 315 // when the request is due to the memory state being lowered. 316 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 317 318 // The rate at which we check for apps using excessive power -- 15 mins. 319 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 320 321 // The minimum sample duration we will allow before deciding we have 322 // enough data on wake locks to start killing things. 323 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 324 325 // The minimum sample duration we will allow before deciding we have 326 // enough data on CPU usage to start killing things. 327 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 328 329 // How long we allow a receiver to run before giving up on it. 330 static final int BROADCAST_FG_TIMEOUT = 10*1000; 331 static final int BROADCAST_BG_TIMEOUT = 60*1000; 332 333 // How long we wait until we timeout on key dispatching. 334 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 335 336 // How long we wait until we timeout on key dispatching during instrumentation. 337 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 338 339 // Amount of time we wait for observers to handle a user switch before 340 // giving up on them and unfreezing the screen. 341 static final int USER_SWITCH_TIMEOUT = 2*1000; 342 343 // Maximum number of users we allow to be running at a time. 344 static final int MAX_RUNNING_USERS = 3; 345 346 // How long to wait in getAssistContextExtras for the activity and foreground services 347 // to respond with the result. 348 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 349 350 // Maximum number of persisted Uri grants a package is allowed 351 static final int MAX_PERSISTED_URI_GRANTS = 128; 352 353 static final int MY_PID = Process.myPid(); 354 355 static final String[] EMPTY_STRING_ARRAY = new String[0]; 356 357 // How many bytes to write into the dropbox log before truncating 358 static final int DROPBOX_MAX_SIZE = 256 * 1024; 359 360 // Access modes for handleIncomingUser. 361 static final int ALLOW_NON_FULL = 0; 362 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 363 static final int ALLOW_FULL_ONLY = 2; 364 365 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 366 367 /** All system services */ 368 SystemServiceManager mSystemServiceManager; 369 370 /** Run all ActivityStacks through this */ 371 ActivityStackSupervisor mStackSupervisor; 372 373 public IntentFirewall mIntentFirewall; 374 375 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 376 // default actuion automatically. Important for devices without direct input 377 // devices. 378 private boolean mShowDialogs = true; 379 380 BroadcastQueue mFgBroadcastQueue; 381 BroadcastQueue mBgBroadcastQueue; 382 // Convenient for easy iteration over the queues. Foreground is first 383 // so that dispatch of foreground broadcasts gets precedence. 384 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 385 386 BroadcastQueue broadcastQueueForIntent(Intent intent) { 387 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 388 if (DEBUG_BACKGROUND_BROADCAST) { 389 Slog.i(TAG, "Broadcast intent " + intent + " on " 390 + (isFg ? "foreground" : "background") 391 + " queue"); 392 } 393 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 394 } 395 396 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 397 for (BroadcastQueue queue : mBroadcastQueues) { 398 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 399 if (r != null) { 400 return r; 401 } 402 } 403 return null; 404 } 405 406 /** 407 * Activity we have told the window manager to have key focus. 408 */ 409 ActivityRecord mFocusedActivity = null; 410 411 /** 412 * List of intents that were used to start the most recent tasks. 413 */ 414 ArrayList<TaskRecord> mRecentTasks; 415 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>(); 416 417 /** 418 * For addAppTask: cached of the last activity component that was added. 419 */ 420 ComponentName mLastAddedTaskComponent; 421 422 /** 423 * For addAppTask: cached of the last activity uid that was added. 424 */ 425 int mLastAddedTaskUid; 426 427 /** 428 * For addAppTask: cached of the last ActivityInfo that was added. 429 */ 430 ActivityInfo mLastAddedTaskActivity; 431 432 public class PendingAssistExtras extends Binder implements Runnable { 433 public final ActivityRecord activity; 434 public boolean haveResult = false; 435 public Bundle result = null; 436 public PendingAssistExtras(ActivityRecord _activity) { 437 activity = _activity; 438 } 439 @Override 440 public void run() { 441 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 442 synchronized (this) { 443 haveResult = true; 444 notifyAll(); 445 } 446 } 447 } 448 449 final ArrayList<PendingAssistExtras> mPendingAssistExtras 450 = new ArrayList<PendingAssistExtras>(); 451 452 /** 453 * Process management. 454 */ 455 final ProcessList mProcessList = new ProcessList(); 456 457 /** 458 * All of the applications we currently have running organized by name. 459 * The keys are strings of the application package name (as 460 * returned by the package manager), and the keys are ApplicationRecord 461 * objects. 462 */ 463 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 464 465 /** 466 * Tracking long-term execution of processes to look for abuse and other 467 * bad app behavior. 468 */ 469 final ProcessStatsService mProcessStats; 470 471 /** 472 * The currently running isolated processes. 473 */ 474 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 475 476 /** 477 * Counter for assigning isolated process uids, to avoid frequently reusing the 478 * same ones. 479 */ 480 int mNextIsolatedProcessUid = 0; 481 482 /** 483 * The currently running heavy-weight process, if any. 484 */ 485 ProcessRecord mHeavyWeightProcess = null; 486 487 /** 488 * The last time that various processes have crashed. 489 */ 490 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 491 492 /** 493 * Information about a process that is currently marked as bad. 494 */ 495 static final class BadProcessInfo { 496 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 497 this.time = time; 498 this.shortMsg = shortMsg; 499 this.longMsg = longMsg; 500 this.stack = stack; 501 } 502 503 final long time; 504 final String shortMsg; 505 final String longMsg; 506 final String stack; 507 } 508 509 /** 510 * Set of applications that we consider to be bad, and will reject 511 * incoming broadcasts from (which the user has no control over). 512 * Processes are added to this set when they have crashed twice within 513 * a minimum amount of time; they are removed from it when they are 514 * later restarted (hopefully due to some user action). The value is the 515 * time it was added to the list. 516 */ 517 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 518 519 /** 520 * All of the processes we currently have running organized by pid. 521 * The keys are the pid running the application. 522 * 523 * <p>NOTE: This object is protected by its own lock, NOT the global 524 * activity manager lock! 525 */ 526 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 527 528 /** 529 * All of the processes that have been forced to be foreground. The key 530 * is the pid of the caller who requested it (we hold a death 531 * link on it). 532 */ 533 abstract class ForegroundToken implements IBinder.DeathRecipient { 534 int pid; 535 IBinder token; 536 } 537 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 538 539 /** 540 * List of records for processes that someone had tried to start before the 541 * system was ready. We don't start them at that point, but ensure they 542 * are started by the time booting is complete. 543 */ 544 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 545 546 /** 547 * List of persistent applications that are in the process 548 * of being started. 549 */ 550 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 551 552 /** 553 * Processes that are being forcibly torn down. 554 */ 555 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 556 557 /** 558 * List of running applications, sorted by recent usage. 559 * The first entry in the list is the least recently used. 560 */ 561 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Where in mLruProcesses that the processes hosting activities start. 565 */ 566 int mLruProcessActivityStart = 0; 567 568 /** 569 * Where in mLruProcesses that the processes hosting services start. 570 * This is after (lower index) than mLruProcessesActivityStart. 571 */ 572 int mLruProcessServiceStart = 0; 573 574 /** 575 * List of processes that should gc as soon as things are idle. 576 */ 577 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 578 579 /** 580 * Processes we want to collect PSS data from. 581 */ 582 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 583 584 /** 585 * Last time we requested PSS data of all processes. 586 */ 587 long mLastFullPssTime = SystemClock.uptimeMillis(); 588 589 /** 590 * If set, the next time we collect PSS data we should do a full collection 591 * with data from native processes and the kernel. 592 */ 593 boolean mFullPssPending = false; 594 595 /** 596 * This is the process holding what we currently consider to be 597 * the "home" activity. 598 */ 599 ProcessRecord mHomeProcess; 600 601 /** 602 * This is the process holding the activity the user last visited that 603 * is in a different process from the one they are currently in. 604 */ 605 ProcessRecord mPreviousProcess; 606 607 /** 608 * The time at which the previous process was last visible. 609 */ 610 long mPreviousProcessVisibleTime; 611 612 /** 613 * Which uses have been started, so are allowed to run code. 614 */ 615 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 616 617 /** 618 * LRU list of history of current users. Most recently current is at the end. 619 */ 620 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 621 622 /** 623 * Constant array of the users that are currently started. 624 */ 625 int[] mStartedUserArray = new int[] { 0 }; 626 627 /** 628 * Registered observers of the user switching mechanics. 629 */ 630 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 631 = new RemoteCallbackList<IUserSwitchObserver>(); 632 633 /** 634 * Currently active user switch. 635 */ 636 Object mCurUserSwitchCallback; 637 638 /** 639 * Packages that the user has asked to have run in screen size 640 * compatibility mode instead of filling the screen. 641 */ 642 final CompatModePackages mCompatModePackages; 643 644 /** 645 * Set of IntentSenderRecord objects that are currently active. 646 */ 647 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 648 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 649 650 /** 651 * Fingerprints (hashCode()) of stack traces that we've 652 * already logged DropBox entries for. Guarded by itself. If 653 * something (rogue user app) forces this over 654 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 655 */ 656 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 657 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 658 659 /** 660 * Strict Mode background batched logging state. 661 * 662 * The string buffer is guarded by itself, and its lock is also 663 * used to determine if another batched write is already 664 * in-flight. 665 */ 666 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 667 668 /** 669 * Keeps track of all IIntentReceivers that have been registered for 670 * broadcasts. Hash keys are the receiver IBinder, hash value is 671 * a ReceiverList. 672 */ 673 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 674 new HashMap<IBinder, ReceiverList>(); 675 676 /** 677 * Resolver for broadcast intents to registered receivers. 678 * Holds BroadcastFilter (subclass of IntentFilter). 679 */ 680 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 681 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 682 @Override 683 protected boolean allowFilterResult( 684 BroadcastFilter filter, List<BroadcastFilter> dest) { 685 IBinder target = filter.receiverList.receiver.asBinder(); 686 for (int i=dest.size()-1; i>=0; i--) { 687 if (dest.get(i).receiverList.receiver.asBinder() == target) { 688 return false; 689 } 690 } 691 return true; 692 } 693 694 @Override 695 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 696 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 697 || userId == filter.owningUserId) { 698 return super.newResult(filter, match, userId); 699 } 700 return null; 701 } 702 703 @Override 704 protected BroadcastFilter[] newArray(int size) { 705 return new BroadcastFilter[size]; 706 } 707 708 @Override 709 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 710 return packageName.equals(filter.packageName); 711 } 712 }; 713 714 /** 715 * State of all active sticky broadcasts per user. Keys are the action of the 716 * sticky Intent, values are an ArrayList of all broadcasted intents with 717 * that action (which should usually be one). The SparseArray is keyed 718 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 719 * for stickies that are sent to all users. 720 */ 721 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 722 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 723 724 final ActiveServices mServices; 725 726 /** 727 * Backup/restore process management 728 */ 729 String mBackupAppName = null; 730 BackupRecord mBackupTarget = null; 731 732 final ProviderMap mProviderMap; 733 734 /** 735 * List of content providers who have clients waiting for them. The 736 * application is currently being launched and the provider will be 737 * removed from this list once it is published. 738 */ 739 final ArrayList<ContentProviderRecord> mLaunchingProviders 740 = new ArrayList<ContentProviderRecord>(); 741 742 /** 743 * File storing persisted {@link #mGrantedUriPermissions}. 744 */ 745 private final AtomicFile mGrantFile; 746 747 /** XML constants used in {@link #mGrantFile} */ 748 private static final String TAG_URI_GRANTS = "uri-grants"; 749 private static final String TAG_URI_GRANT = "uri-grant"; 750 private static final String ATTR_USER_HANDLE = "userHandle"; 751 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 752 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 753 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 754 private static final String ATTR_TARGET_PKG = "targetPkg"; 755 private static final String ATTR_URI = "uri"; 756 private static final String ATTR_MODE_FLAGS = "modeFlags"; 757 private static final String ATTR_CREATED_TIME = "createdTime"; 758 private static final String ATTR_PREFIX = "prefix"; 759 760 /** 761 * Global set of specific {@link Uri} permissions that have been granted. 762 * This optimized lookup structure maps from {@link UriPermission#targetUid} 763 * to {@link UriPermission#uri} to {@link UriPermission}. 764 */ 765 @GuardedBy("this") 766 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 767 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 768 769 public static class GrantUri { 770 public final int sourceUserId; 771 public final Uri uri; 772 public boolean prefix; 773 774 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 775 this.sourceUserId = sourceUserId; 776 this.uri = uri; 777 this.prefix = prefix; 778 } 779 780 @Override 781 public int hashCode() { 782 return toString().hashCode(); 783 } 784 785 @Override 786 public boolean equals(Object o) { 787 if (o instanceof GrantUri) { 788 GrantUri other = (GrantUri) o; 789 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 790 && prefix == other.prefix; 791 } 792 return false; 793 } 794 795 @Override 796 public String toString() { 797 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 798 if (prefix) result += " [prefix]"; 799 return result; 800 } 801 802 public String toSafeString() { 803 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 804 if (prefix) result += " [prefix]"; 805 return result; 806 } 807 808 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 809 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 810 ContentProvider.getUriWithoutUserId(uri), false); 811 } 812 } 813 814 CoreSettingsObserver mCoreSettingsObserver; 815 816 /** 817 * Thread-local storage used to carry caller permissions over through 818 * indirect content-provider access. 819 */ 820 private class Identity { 821 public int pid; 822 public int uid; 823 824 Identity(int _pid, int _uid) { 825 pid = _pid; 826 uid = _uid; 827 } 828 } 829 830 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 831 832 /** 833 * All information we have collected about the runtime performance of 834 * any user id that can impact battery performance. 835 */ 836 final BatteryStatsService mBatteryStatsService; 837 838 /** 839 * Information about component usage 840 */ 841 UsageStatsManagerInternal mUsageStatsService; 842 843 /** 844 * Information about and control over application operations 845 */ 846 final AppOpsService mAppOpsService; 847 848 /** 849 * Save recent tasks information across reboots. 850 */ 851 final TaskPersister mTaskPersister; 852 853 /** 854 * Current configuration information. HistoryRecord objects are given 855 * a reference to this object to indicate which configuration they are 856 * currently running in, so this object must be kept immutable. 857 */ 858 Configuration mConfiguration = new Configuration(); 859 860 /** 861 * Current sequencing integer of the configuration, for skipping old 862 * configurations. 863 */ 864 int mConfigurationSeq = 0; 865 866 /** 867 * Hardware-reported OpenGLES version. 868 */ 869 final int GL_ES_VERSION; 870 871 /** 872 * List of initialization arguments to pass to all processes when binding applications to them. 873 * For example, references to the commonly used services. 874 */ 875 HashMap<String, IBinder> mAppBindArgs; 876 877 /** 878 * Temporary to avoid allocations. Protected by main lock. 879 */ 880 final StringBuilder mStringBuilder = new StringBuilder(256); 881 882 /** 883 * Used to control how we initialize the service. 884 */ 885 ComponentName mTopComponent; 886 String mTopAction = Intent.ACTION_MAIN; 887 String mTopData; 888 boolean mProcessesReady = false; 889 boolean mSystemReady = false; 890 boolean mBooting = false; 891 boolean mWaitingUpdate = false; 892 boolean mDidUpdate = false; 893 boolean mOnBattery = false; 894 boolean mLaunchWarningShown = false; 895 896 Context mContext; 897 898 int mFactoryTest; 899 900 boolean mCheckedForSetup; 901 902 /** 903 * The time at which we will allow normal application switches again, 904 * after a call to {@link #stopAppSwitches()}. 905 */ 906 long mAppSwitchesAllowedTime; 907 908 /** 909 * This is set to true after the first switch after mAppSwitchesAllowedTime 910 * is set; any switches after that will clear the time. 911 */ 912 boolean mDidAppSwitch; 913 914 /** 915 * Last time (in realtime) at which we checked for power usage. 916 */ 917 long mLastPowerCheckRealtime; 918 919 /** 920 * Last time (in uptime) at which we checked for power usage. 921 */ 922 long mLastPowerCheckUptime; 923 924 /** 925 * Set while we are wanting to sleep, to prevent any 926 * activities from being started/resumed. 927 */ 928 private boolean mSleeping = false; 929 930 /** 931 * Set while we are running a voice interaction. This overrides 932 * sleeping while it is active. 933 */ 934 private boolean mRunningVoice = false; 935 936 /** 937 * State of external calls telling us if the device is asleep. 938 */ 939 private boolean mWentToSleep = false; 940 941 /** 942 * State of external call telling us if the lock screen is shown. 943 */ 944 private boolean mLockScreenShown = false; 945 946 /** 947 * Set if we are shutting down the system, similar to sleeping. 948 */ 949 boolean mShuttingDown = false; 950 951 /** 952 * Current sequence id for oom_adj computation traversal. 953 */ 954 int mAdjSeq = 0; 955 956 /** 957 * Current sequence id for process LRU updating. 958 */ 959 int mLruSeq = 0; 960 961 /** 962 * Keep track of the non-cached/empty process we last found, to help 963 * determine how to distribute cached/empty processes next time. 964 */ 965 int mNumNonCachedProcs = 0; 966 967 /** 968 * Keep track of the number of cached hidden procs, to balance oom adj 969 * distribution between those and empty procs. 970 */ 971 int mNumCachedHiddenProcs = 0; 972 973 /** 974 * Keep track of the number of service processes we last found, to 975 * determine on the next iteration which should be B services. 976 */ 977 int mNumServiceProcs = 0; 978 int mNewNumAServiceProcs = 0; 979 int mNewNumServiceProcs = 0; 980 981 /** 982 * Allow the current computed overall memory level of the system to go down? 983 * This is set to false when we are killing processes for reasons other than 984 * memory management, so that the now smaller process list will not be taken as 985 * an indication that memory is tighter. 986 */ 987 boolean mAllowLowerMemLevel = false; 988 989 /** 990 * The last computed memory level, for holding when we are in a state that 991 * processes are going away for other reasons. 992 */ 993 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 994 995 /** 996 * The last total number of process we have, to determine if changes actually look 997 * like a shrinking number of process due to lower RAM. 998 */ 999 int mLastNumProcesses; 1000 1001 /** 1002 * The uptime of the last time we performed idle maintenance. 1003 */ 1004 long mLastIdleTime = SystemClock.uptimeMillis(); 1005 1006 /** 1007 * Total time spent with RAM that has been added in the past since the last idle time. 1008 */ 1009 long mLowRamTimeSinceLastIdle = 0; 1010 1011 /** 1012 * If RAM is currently low, when that horrible situation started. 1013 */ 1014 long mLowRamStartTime = 0; 1015 1016 /** 1017 * For reporting to battery stats the current top application. 1018 */ 1019 private String mCurResumedPackage = null; 1020 private int mCurResumedUid = -1; 1021 1022 /** 1023 * For reporting to battery stats the apps currently running foreground 1024 * service. The ProcessMap is package/uid tuples; each of these contain 1025 * an array of the currently foreground processes. 1026 */ 1027 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1028 = new ProcessMap<ArrayList<ProcessRecord>>(); 1029 1030 /** 1031 * This is set if we had to do a delayed dexopt of an app before launching 1032 * it, to increase the ANR timeouts in that case. 1033 */ 1034 boolean mDidDexOpt; 1035 1036 /** 1037 * Set if the systemServer made a call to enterSafeMode. 1038 */ 1039 boolean mSafeMode; 1040 1041 String mDebugApp = null; 1042 boolean mWaitForDebugger = false; 1043 boolean mDebugTransient = false; 1044 String mOrigDebugApp = null; 1045 boolean mOrigWaitForDebugger = false; 1046 boolean mAlwaysFinishActivities = false; 1047 IActivityController mController = null; 1048 String mProfileApp = null; 1049 ProcessRecord mProfileProc = null; 1050 String mProfileFile; 1051 ParcelFileDescriptor mProfileFd; 1052 int mSamplingInterval = 0; 1053 boolean mAutoStopProfiler = false; 1054 int mProfileType = 0; 1055 String mOpenGlTraceApp = null; 1056 1057 static class ProcessChangeItem { 1058 static final int CHANGE_ACTIVITIES = 1<<0; 1059 static final int CHANGE_PROCESS_STATE = 1<<1; 1060 int changes; 1061 int uid; 1062 int pid; 1063 int processState; 1064 boolean foregroundActivities; 1065 } 1066 1067 final RemoteCallbackList<IProcessObserver> mProcessObservers 1068 = new RemoteCallbackList<IProcessObserver>(); 1069 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1070 1071 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1072 = new ArrayList<ProcessChangeItem>(); 1073 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1074 = new ArrayList<ProcessChangeItem>(); 1075 1076 /** 1077 * Runtime CPU use collection thread. This object's lock is used to 1078 * protect all related state. 1079 */ 1080 final Thread mProcessCpuThread; 1081 1082 /** 1083 * Used to collect process stats when showing not responding dialog. 1084 * Protected by mProcessCpuThread. 1085 */ 1086 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1087 MONITOR_THREAD_CPU_USAGE); 1088 final AtomicLong mLastCpuTime = new AtomicLong(0); 1089 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1090 1091 long mLastWriteTime = 0; 1092 1093 /** 1094 * Used to retain an update lock when the foreground activity is in 1095 * immersive mode. 1096 */ 1097 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1098 1099 /** 1100 * Set to true after the system has finished booting. 1101 */ 1102 boolean mBooted = false; 1103 1104 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1105 int mProcessLimitOverride = -1; 1106 1107 WindowManagerService mWindowManager; 1108 1109 final ActivityThread mSystemThread; 1110 1111 // Holds the current foreground user's id 1112 int mCurrentUserId = 0; 1113 // Holds the target user's id during a user switch 1114 int mTargetUserId = UserHandle.USER_NULL; 1115 // If there are multiple profiles for the current user, their ids are here 1116 // Currently only the primary user can have managed profiles 1117 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1118 1119 /** 1120 * Mapping from each known user ID to the profile group ID it is associated with. 1121 */ 1122 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1123 1124 private UserManagerService mUserManager; 1125 1126 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1127 final ProcessRecord mApp; 1128 final int mPid; 1129 final IApplicationThread mAppThread; 1130 1131 AppDeathRecipient(ProcessRecord app, int pid, 1132 IApplicationThread thread) { 1133 if (localLOGV) Slog.v( 1134 TAG, "New death recipient " + this 1135 + " for thread " + thread.asBinder()); 1136 mApp = app; 1137 mPid = pid; 1138 mAppThread = thread; 1139 } 1140 1141 @Override 1142 public void binderDied() { 1143 if (localLOGV) Slog.v( 1144 TAG, "Death received in " + this 1145 + " for thread " + mAppThread.asBinder()); 1146 synchronized(ActivityManagerService.this) { 1147 appDiedLocked(mApp, mPid, mAppThread); 1148 } 1149 } 1150 } 1151 1152 static final int SHOW_ERROR_MSG = 1; 1153 static final int SHOW_NOT_RESPONDING_MSG = 2; 1154 static final int SHOW_FACTORY_ERROR_MSG = 3; 1155 static final int UPDATE_CONFIGURATION_MSG = 4; 1156 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1157 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1158 static final int SERVICE_TIMEOUT_MSG = 12; 1159 static final int UPDATE_TIME_ZONE = 13; 1160 static final int SHOW_UID_ERROR_MSG = 14; 1161 static final int IM_FEELING_LUCKY_MSG = 15; 1162 static final int PROC_START_TIMEOUT_MSG = 20; 1163 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1164 static final int KILL_APPLICATION_MSG = 22; 1165 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1166 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1167 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1168 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1169 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1170 static final int CLEAR_DNS_CACHE_MSG = 28; 1171 static final int UPDATE_HTTP_PROXY_MSG = 29; 1172 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1173 static final int DISPATCH_PROCESSES_CHANGED = 31; 1174 static final int DISPATCH_PROCESS_DIED = 32; 1175 static final int REPORT_MEM_USAGE_MSG = 33; 1176 static final int REPORT_USER_SWITCH_MSG = 34; 1177 static final int CONTINUE_USER_SWITCH_MSG = 35; 1178 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1179 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1180 static final int PERSIST_URI_GRANTS_MSG = 38; 1181 static final int REQUEST_ALL_PSS_MSG = 39; 1182 static final int START_PROFILES_MSG = 40; 1183 static final int UPDATE_TIME = 41; 1184 static final int SYSTEM_USER_START_MSG = 42; 1185 static final int SYSTEM_USER_CURRENT_MSG = 43; 1186 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1187 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1188 static final int START_USER_SWITCH_MSG = 46; 1189 1190 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1191 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1192 static final int FIRST_COMPAT_MODE_MSG = 300; 1193 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1194 1195 AlertDialog mUidAlert; 1196 CompatModeDialog mCompatModeDialog; 1197 long mLastMemUsageReportTime = 0; 1198 1199 private LockToAppRequestDialog mLockToAppRequest; 1200 1201 /** 1202 * Flag whether the current user is a "monkey", i.e. whether 1203 * the UI is driven by a UI automation tool. 1204 */ 1205 private boolean mUserIsMonkey; 1206 1207 /** Flag whether the device has a Recents UI */ 1208 boolean mHasRecents; 1209 1210 /** The dimensions of the thumbnails in the Recents UI. */ 1211 int mThumbnailWidth; 1212 int mThumbnailHeight; 1213 1214 final ServiceThread mHandlerThread; 1215 final MainHandler mHandler; 1216 1217 final class MainHandler extends Handler { 1218 public MainHandler(Looper looper) { 1219 super(looper, null, true); 1220 } 1221 1222 @Override 1223 public void handleMessage(Message msg) { 1224 switch (msg.what) { 1225 case SHOW_ERROR_MSG: { 1226 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1227 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1228 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1229 synchronized (ActivityManagerService.this) { 1230 ProcessRecord proc = (ProcessRecord)data.get("app"); 1231 AppErrorResult res = (AppErrorResult) data.get("result"); 1232 if (proc != null && proc.crashDialog != null) { 1233 Slog.e(TAG, "App already has crash dialog: " + proc); 1234 if (res != null) { 1235 res.set(0); 1236 } 1237 return; 1238 } 1239 boolean isBackground = (UserHandle.getAppId(proc.uid) 1240 >= Process.FIRST_APPLICATION_UID 1241 && proc.pid != MY_PID); 1242 for (int userId : mCurrentProfileIds) { 1243 isBackground &= (proc.userId != userId); 1244 } 1245 if (isBackground && !showBackground) { 1246 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1247 if (res != null) { 1248 res.set(0); 1249 } 1250 return; 1251 } 1252 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1253 Dialog d = new AppErrorDialog(mContext, 1254 ActivityManagerService.this, res, proc); 1255 d.show(); 1256 proc.crashDialog = d; 1257 } else { 1258 // The device is asleep, so just pretend that the user 1259 // saw a crash dialog and hit "force quit". 1260 if (res != null) { 1261 res.set(0); 1262 } 1263 } 1264 } 1265 1266 ensureBootCompleted(); 1267 } break; 1268 case SHOW_NOT_RESPONDING_MSG: { 1269 synchronized (ActivityManagerService.this) { 1270 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1271 ProcessRecord proc = (ProcessRecord)data.get("app"); 1272 if (proc != null && proc.anrDialog != null) { 1273 Slog.e(TAG, "App already has anr dialog: " + proc); 1274 return; 1275 } 1276 1277 Intent intent = new Intent("android.intent.action.ANR"); 1278 if (!mProcessesReady) { 1279 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1280 | Intent.FLAG_RECEIVER_FOREGROUND); 1281 } 1282 broadcastIntentLocked(null, null, intent, 1283 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1284 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1285 1286 if (mShowDialogs) { 1287 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1288 mContext, proc, (ActivityRecord)data.get("activity"), 1289 msg.arg1 != 0); 1290 d.show(); 1291 proc.anrDialog = d; 1292 } else { 1293 // Just kill the app if there is no dialog to be shown. 1294 killAppAtUsersRequest(proc, null); 1295 } 1296 } 1297 1298 ensureBootCompleted(); 1299 } break; 1300 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1301 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1302 synchronized (ActivityManagerService.this) { 1303 ProcessRecord proc = (ProcessRecord) data.get("app"); 1304 if (proc == null) { 1305 Slog.e(TAG, "App not found when showing strict mode dialog."); 1306 break; 1307 } 1308 if (proc.crashDialog != null) { 1309 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1310 return; 1311 } 1312 AppErrorResult res = (AppErrorResult) data.get("result"); 1313 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1314 Dialog d = new StrictModeViolationDialog(mContext, 1315 ActivityManagerService.this, res, proc); 1316 d.show(); 1317 proc.crashDialog = d; 1318 } else { 1319 // The device is asleep, so just pretend that the user 1320 // saw a crash dialog and hit "force quit". 1321 res.set(0); 1322 } 1323 } 1324 ensureBootCompleted(); 1325 } break; 1326 case SHOW_FACTORY_ERROR_MSG: { 1327 Dialog d = new FactoryErrorDialog( 1328 mContext, msg.getData().getCharSequence("msg")); 1329 d.show(); 1330 ensureBootCompleted(); 1331 } break; 1332 case UPDATE_CONFIGURATION_MSG: { 1333 final ContentResolver resolver = mContext.getContentResolver(); 1334 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1335 } break; 1336 case GC_BACKGROUND_PROCESSES_MSG: { 1337 synchronized (ActivityManagerService.this) { 1338 performAppGcsIfAppropriateLocked(); 1339 } 1340 } break; 1341 case WAIT_FOR_DEBUGGER_MSG: { 1342 synchronized (ActivityManagerService.this) { 1343 ProcessRecord app = (ProcessRecord)msg.obj; 1344 if (msg.arg1 != 0) { 1345 if (!app.waitedForDebugger) { 1346 Dialog d = new AppWaitingForDebuggerDialog( 1347 ActivityManagerService.this, 1348 mContext, app); 1349 app.waitDialog = d; 1350 app.waitedForDebugger = true; 1351 d.show(); 1352 } 1353 } else { 1354 if (app.waitDialog != null) { 1355 app.waitDialog.dismiss(); 1356 app.waitDialog = null; 1357 } 1358 } 1359 } 1360 } break; 1361 case SERVICE_TIMEOUT_MSG: { 1362 if (mDidDexOpt) { 1363 mDidDexOpt = false; 1364 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1365 nmsg.obj = msg.obj; 1366 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1367 return; 1368 } 1369 mServices.serviceTimeout((ProcessRecord)msg.obj); 1370 } break; 1371 case UPDATE_TIME_ZONE: { 1372 synchronized (ActivityManagerService.this) { 1373 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1374 ProcessRecord r = mLruProcesses.get(i); 1375 if (r.thread != null) { 1376 try { 1377 r.thread.updateTimeZone(); 1378 } catch (RemoteException ex) { 1379 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1380 } 1381 } 1382 } 1383 } 1384 } break; 1385 case CLEAR_DNS_CACHE_MSG: { 1386 synchronized (ActivityManagerService.this) { 1387 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1388 ProcessRecord r = mLruProcesses.get(i); 1389 if (r.thread != null) { 1390 try { 1391 r.thread.clearDnsCache(); 1392 } catch (RemoteException ex) { 1393 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1394 } 1395 } 1396 } 1397 } 1398 } break; 1399 case UPDATE_HTTP_PROXY_MSG: { 1400 ProxyInfo proxy = (ProxyInfo)msg.obj; 1401 String host = ""; 1402 String port = ""; 1403 String exclList = ""; 1404 Uri pacFileUrl = Uri.EMPTY; 1405 if (proxy != null) { 1406 host = proxy.getHost(); 1407 port = Integer.toString(proxy.getPort()); 1408 exclList = proxy.getExclusionListAsString(); 1409 pacFileUrl = proxy.getPacFileUrl(); 1410 } 1411 synchronized (ActivityManagerService.this) { 1412 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1413 ProcessRecord r = mLruProcesses.get(i); 1414 if (r.thread != null) { 1415 try { 1416 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1417 } catch (RemoteException ex) { 1418 Slog.w(TAG, "Failed to update http proxy for: " + 1419 r.info.processName); 1420 } 1421 } 1422 } 1423 } 1424 } break; 1425 case SHOW_UID_ERROR_MSG: { 1426 String title = "System UIDs Inconsistent"; 1427 String text = "UIDs on the system are inconsistent, you need to wipe your" 1428 + " data partition or your device will be unstable."; 1429 Log.e(TAG, title + ": " + text); 1430 if (mShowDialogs) { 1431 // XXX This is a temporary dialog, no need to localize. 1432 AlertDialog d = new BaseErrorDialog(mContext); 1433 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1434 d.setCancelable(false); 1435 d.setTitle(title); 1436 d.setMessage(text); 1437 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1438 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1439 mUidAlert = d; 1440 d.show(); 1441 } 1442 } break; 1443 case IM_FEELING_LUCKY_MSG: { 1444 if (mUidAlert != null) { 1445 mUidAlert.dismiss(); 1446 mUidAlert = null; 1447 } 1448 } break; 1449 case PROC_START_TIMEOUT_MSG: { 1450 if (mDidDexOpt) { 1451 mDidDexOpt = false; 1452 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1453 nmsg.obj = msg.obj; 1454 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1455 return; 1456 } 1457 ProcessRecord app = (ProcessRecord)msg.obj; 1458 synchronized (ActivityManagerService.this) { 1459 processStartTimedOutLocked(app); 1460 } 1461 } break; 1462 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1463 synchronized (ActivityManagerService.this) { 1464 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1465 } 1466 } break; 1467 case KILL_APPLICATION_MSG: { 1468 synchronized (ActivityManagerService.this) { 1469 int appid = msg.arg1; 1470 boolean restart = (msg.arg2 == 1); 1471 Bundle bundle = (Bundle)msg.obj; 1472 String pkg = bundle.getString("pkg"); 1473 String reason = bundle.getString("reason"); 1474 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1475 false, UserHandle.USER_ALL, reason); 1476 } 1477 } break; 1478 case FINALIZE_PENDING_INTENT_MSG: { 1479 ((PendingIntentRecord)msg.obj).completeFinalize(); 1480 } break; 1481 case POST_HEAVY_NOTIFICATION_MSG: { 1482 INotificationManager inm = NotificationManager.getService(); 1483 if (inm == null) { 1484 return; 1485 } 1486 1487 ActivityRecord root = (ActivityRecord)msg.obj; 1488 ProcessRecord process = root.app; 1489 if (process == null) { 1490 return; 1491 } 1492 1493 try { 1494 Context context = mContext.createPackageContext(process.info.packageName, 0); 1495 String text = mContext.getString(R.string.heavy_weight_notification, 1496 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1497 Notification notification = new Notification(); 1498 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1499 notification.when = 0; 1500 notification.flags = Notification.FLAG_ONGOING_EVENT; 1501 notification.tickerText = text; 1502 notification.defaults = 0; // please be quiet 1503 notification.sound = null; 1504 notification.vibrate = null; 1505 notification.color = mContext.getResources().getColor( 1506 com.android.internal.R.color.system_notification_accent_color); 1507 notification.setLatestEventInfo(context, text, 1508 mContext.getText(R.string.heavy_weight_notification_detail), 1509 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1510 PendingIntent.FLAG_CANCEL_CURRENT, null, 1511 new UserHandle(root.userId))); 1512 1513 try { 1514 int[] outId = new int[1]; 1515 inm.enqueueNotificationWithTag("android", "android", null, 1516 R.string.heavy_weight_notification, 1517 notification, outId, root.userId); 1518 } catch (RuntimeException e) { 1519 Slog.w(ActivityManagerService.TAG, 1520 "Error showing notification for heavy-weight app", e); 1521 } catch (RemoteException e) { 1522 } 1523 } catch (NameNotFoundException e) { 1524 Slog.w(TAG, "Unable to create context for heavy notification", e); 1525 } 1526 } break; 1527 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1528 INotificationManager inm = NotificationManager.getService(); 1529 if (inm == null) { 1530 return; 1531 } 1532 try { 1533 inm.cancelNotificationWithTag("android", null, 1534 R.string.heavy_weight_notification, msg.arg1); 1535 } catch (RuntimeException e) { 1536 Slog.w(ActivityManagerService.TAG, 1537 "Error canceling notification for service", e); 1538 } catch (RemoteException e) { 1539 } 1540 } break; 1541 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1542 synchronized (ActivityManagerService.this) { 1543 checkExcessivePowerUsageLocked(true); 1544 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1545 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1546 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1547 } 1548 } break; 1549 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1550 synchronized (ActivityManagerService.this) { 1551 ActivityRecord ar = (ActivityRecord)msg.obj; 1552 if (mCompatModeDialog != null) { 1553 if (mCompatModeDialog.mAppInfo.packageName.equals( 1554 ar.info.applicationInfo.packageName)) { 1555 return; 1556 } 1557 mCompatModeDialog.dismiss(); 1558 mCompatModeDialog = null; 1559 } 1560 if (ar != null && false) { 1561 if (mCompatModePackages.getPackageAskCompatModeLocked( 1562 ar.packageName)) { 1563 int mode = mCompatModePackages.computeCompatModeLocked( 1564 ar.info.applicationInfo); 1565 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1566 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1567 mCompatModeDialog = new CompatModeDialog( 1568 ActivityManagerService.this, mContext, 1569 ar.info.applicationInfo); 1570 mCompatModeDialog.show(); 1571 } 1572 } 1573 } 1574 } 1575 break; 1576 } 1577 case DISPATCH_PROCESSES_CHANGED: { 1578 dispatchProcessesChanged(); 1579 break; 1580 } 1581 case DISPATCH_PROCESS_DIED: { 1582 final int pid = msg.arg1; 1583 final int uid = msg.arg2; 1584 dispatchProcessDied(pid, uid); 1585 break; 1586 } 1587 case REPORT_MEM_USAGE_MSG: { 1588 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1589 Thread thread = new Thread() { 1590 @Override public void run() { 1591 final SparseArray<ProcessMemInfo> infoMap 1592 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1593 for (int i=0, N=memInfos.size(); i<N; i++) { 1594 ProcessMemInfo mi = memInfos.get(i); 1595 infoMap.put(mi.pid, mi); 1596 } 1597 updateCpuStatsNow(); 1598 synchronized (mProcessCpuThread) { 1599 final int N = mProcessCpuTracker.countStats(); 1600 for (int i=0; i<N; i++) { 1601 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1602 if (st.vsize > 0) { 1603 long pss = Debug.getPss(st.pid, null); 1604 if (pss > 0) { 1605 if (infoMap.indexOfKey(st.pid) < 0) { 1606 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1607 ProcessList.NATIVE_ADJ, -1, "native", null); 1608 mi.pss = pss; 1609 memInfos.add(mi); 1610 } 1611 } 1612 } 1613 } 1614 } 1615 1616 long totalPss = 0; 1617 for (int i=0, N=memInfos.size(); i<N; i++) { 1618 ProcessMemInfo mi = memInfos.get(i); 1619 if (mi.pss == 0) { 1620 mi.pss = Debug.getPss(mi.pid, null); 1621 } 1622 totalPss += mi.pss; 1623 } 1624 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1625 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1626 if (lhs.oomAdj != rhs.oomAdj) { 1627 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1628 } 1629 if (lhs.pss != rhs.pss) { 1630 return lhs.pss < rhs.pss ? 1 : -1; 1631 } 1632 return 0; 1633 } 1634 }); 1635 1636 StringBuilder tag = new StringBuilder(128); 1637 StringBuilder stack = new StringBuilder(128); 1638 tag.append("Low on memory -- "); 1639 appendMemBucket(tag, totalPss, "total", false); 1640 appendMemBucket(stack, totalPss, "total", true); 1641 1642 StringBuilder logBuilder = new StringBuilder(1024); 1643 logBuilder.append("Low on memory:\n"); 1644 1645 boolean firstLine = true; 1646 int lastOomAdj = Integer.MIN_VALUE; 1647 for (int i=0, N=memInfos.size(); i<N; i++) { 1648 ProcessMemInfo mi = memInfos.get(i); 1649 1650 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1651 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1652 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1653 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1654 if (lastOomAdj != mi.oomAdj) { 1655 lastOomAdj = mi.oomAdj; 1656 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1657 tag.append(" / "); 1658 } 1659 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1660 if (firstLine) { 1661 stack.append(":"); 1662 firstLine = false; 1663 } 1664 stack.append("\n\t at "); 1665 } else { 1666 stack.append("$"); 1667 } 1668 } else { 1669 tag.append(" "); 1670 stack.append("$"); 1671 } 1672 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1673 appendMemBucket(tag, mi.pss, mi.name, false); 1674 } 1675 appendMemBucket(stack, mi.pss, mi.name, true); 1676 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1677 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1678 stack.append("("); 1679 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1680 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1681 stack.append(DUMP_MEM_OOM_LABEL[k]); 1682 stack.append(":"); 1683 stack.append(DUMP_MEM_OOM_ADJ[k]); 1684 } 1685 } 1686 stack.append(")"); 1687 } 1688 } 1689 1690 logBuilder.append(" "); 1691 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1692 logBuilder.append(' '); 1693 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1694 logBuilder.append(' '); 1695 ProcessList.appendRamKb(logBuilder, mi.pss); 1696 logBuilder.append(" kB: "); 1697 logBuilder.append(mi.name); 1698 logBuilder.append(" ("); 1699 logBuilder.append(mi.pid); 1700 logBuilder.append(") "); 1701 logBuilder.append(mi.adjType); 1702 logBuilder.append('\n'); 1703 if (mi.adjReason != null) { 1704 logBuilder.append(" "); 1705 logBuilder.append(mi.adjReason); 1706 logBuilder.append('\n'); 1707 } 1708 } 1709 1710 logBuilder.append(" "); 1711 ProcessList.appendRamKb(logBuilder, totalPss); 1712 logBuilder.append(" kB: TOTAL\n"); 1713 1714 long[] infos = new long[Debug.MEMINFO_COUNT]; 1715 Debug.getMemInfo(infos); 1716 logBuilder.append(" MemInfo: "); 1717 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1718 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1719 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1720 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1721 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1722 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1723 logBuilder.append(" ZRAM: "); 1724 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1725 logBuilder.append(" kB RAM, "); 1726 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1727 logBuilder.append(" kB swap total, "); 1728 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1729 logBuilder.append(" kB swap free\n"); 1730 } 1731 Slog.i(TAG, logBuilder.toString()); 1732 1733 StringBuilder dropBuilder = new StringBuilder(1024); 1734 /* 1735 StringWriter oomSw = new StringWriter(); 1736 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1737 StringWriter catSw = new StringWriter(); 1738 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1739 String[] emptyArgs = new String[] { }; 1740 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1741 oomPw.flush(); 1742 String oomString = oomSw.toString(); 1743 */ 1744 dropBuilder.append(stack); 1745 dropBuilder.append('\n'); 1746 dropBuilder.append('\n'); 1747 dropBuilder.append(logBuilder); 1748 dropBuilder.append('\n'); 1749 /* 1750 dropBuilder.append(oomString); 1751 dropBuilder.append('\n'); 1752 */ 1753 StringWriter catSw = new StringWriter(); 1754 synchronized (ActivityManagerService.this) { 1755 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1756 String[] emptyArgs = new String[] { }; 1757 catPw.println(); 1758 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1759 catPw.println(); 1760 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1761 false, false, null); 1762 catPw.println(); 1763 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1764 catPw.flush(); 1765 } 1766 dropBuilder.append(catSw.toString()); 1767 addErrorToDropBox("lowmem", null, "system_server", null, 1768 null, tag.toString(), dropBuilder.toString(), null, null); 1769 //Slog.i(TAG, "Sent to dropbox:"); 1770 //Slog.i(TAG, dropBuilder.toString()); 1771 synchronized (ActivityManagerService.this) { 1772 long now = SystemClock.uptimeMillis(); 1773 if (mLastMemUsageReportTime < now) { 1774 mLastMemUsageReportTime = now; 1775 } 1776 } 1777 } 1778 }; 1779 thread.start(); 1780 break; 1781 } 1782 case START_USER_SWITCH_MSG: { 1783 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1784 break; 1785 } 1786 case REPORT_USER_SWITCH_MSG: { 1787 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1788 break; 1789 } 1790 case CONTINUE_USER_SWITCH_MSG: { 1791 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1792 break; 1793 } 1794 case USER_SWITCH_TIMEOUT_MSG: { 1795 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1796 break; 1797 } 1798 case IMMERSIVE_MODE_LOCK_MSG: { 1799 final boolean nextState = (msg.arg1 != 0); 1800 if (mUpdateLock.isHeld() != nextState) { 1801 if (DEBUG_IMMERSIVE) { 1802 final ActivityRecord r = (ActivityRecord) msg.obj; 1803 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1804 } 1805 if (nextState) { 1806 mUpdateLock.acquire(); 1807 } else { 1808 mUpdateLock.release(); 1809 } 1810 } 1811 break; 1812 } 1813 case PERSIST_URI_GRANTS_MSG: { 1814 writeGrantedUriPermissions(); 1815 break; 1816 } 1817 case REQUEST_ALL_PSS_MSG: { 1818 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1819 break; 1820 } 1821 case START_PROFILES_MSG: { 1822 synchronized (ActivityManagerService.this) { 1823 startProfilesLocked(); 1824 } 1825 break; 1826 } 1827 case UPDATE_TIME: { 1828 synchronized (ActivityManagerService.this) { 1829 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1830 ProcessRecord r = mLruProcesses.get(i); 1831 if (r.thread != null) { 1832 try { 1833 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1834 } catch (RemoteException ex) { 1835 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1836 } 1837 } 1838 } 1839 } 1840 break; 1841 } 1842 case SYSTEM_USER_START_MSG: { 1843 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1844 Integer.toString(msg.arg1), msg.arg1); 1845 mSystemServiceManager.startUser(msg.arg1); 1846 break; 1847 } 1848 case SYSTEM_USER_CURRENT_MSG: { 1849 mBatteryStatsService.noteEvent( 1850 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1851 Integer.toString(msg.arg2), msg.arg2); 1852 mBatteryStatsService.noteEvent( 1853 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1854 Integer.toString(msg.arg1), msg.arg1); 1855 mSystemServiceManager.switchUser(msg.arg1); 1856 mLockToAppRequest.clearPrompt(); 1857 break; 1858 } 1859 case ENTER_ANIMATION_COMPLETE_MSG: { 1860 synchronized (ActivityManagerService.this) { 1861 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1862 if (r != null && r.app != null && r.app.thread != null) { 1863 try { 1864 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1865 } catch (RemoteException e) { 1866 } 1867 } 1868 } 1869 break; 1870 } 1871 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1872 enableScreenAfterBoot(); 1873 break; 1874 } 1875 } 1876 } 1877 }; 1878 1879 static final int COLLECT_PSS_BG_MSG = 1; 1880 1881 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1882 @Override 1883 public void handleMessage(Message msg) { 1884 switch (msg.what) { 1885 case COLLECT_PSS_BG_MSG: { 1886 long start = SystemClock.uptimeMillis(); 1887 MemInfoReader memInfo = null; 1888 synchronized (ActivityManagerService.this) { 1889 if (mFullPssPending) { 1890 mFullPssPending = false; 1891 memInfo = new MemInfoReader(); 1892 } 1893 } 1894 if (memInfo != null) { 1895 updateCpuStatsNow(); 1896 long nativeTotalPss = 0; 1897 synchronized (mProcessCpuThread) { 1898 final int N = mProcessCpuTracker.countStats(); 1899 for (int j=0; j<N; j++) { 1900 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1901 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1902 // This is definitely an application process; skip it. 1903 continue; 1904 } 1905 synchronized (mPidsSelfLocked) { 1906 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1907 // This is one of our own processes; skip it. 1908 continue; 1909 } 1910 } 1911 nativeTotalPss += Debug.getPss(st.pid, null); 1912 } 1913 } 1914 memInfo.readMemInfo(); 1915 synchronized (this) { 1916 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1917 + (SystemClock.uptimeMillis()-start) + "ms"); 1918 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1919 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1920 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1921 +memInfo.getSlabSizeKb(), 1922 nativeTotalPss); 1923 } 1924 } 1925 1926 int i=0, num=0; 1927 long[] tmp = new long[1]; 1928 do { 1929 ProcessRecord proc; 1930 int procState; 1931 int pid; 1932 synchronized (ActivityManagerService.this) { 1933 if (i >= mPendingPssProcesses.size()) { 1934 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1935 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1936 mPendingPssProcesses.clear(); 1937 return; 1938 } 1939 proc = mPendingPssProcesses.get(i); 1940 procState = proc.pssProcState; 1941 if (proc.thread != null && procState == proc.setProcState) { 1942 pid = proc.pid; 1943 } else { 1944 proc = null; 1945 pid = 0; 1946 } 1947 i++; 1948 } 1949 if (proc != null) { 1950 long pss = Debug.getPss(pid, tmp); 1951 synchronized (ActivityManagerService.this) { 1952 if (proc.thread != null && proc.setProcState == procState 1953 && proc.pid == pid) { 1954 num++; 1955 proc.lastPssTime = SystemClock.uptimeMillis(); 1956 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1957 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1958 + ": " + pss + " lastPss=" + proc.lastPss 1959 + " state=" + ProcessList.makeProcStateString(procState)); 1960 if (proc.initialIdlePss == 0) { 1961 proc.initialIdlePss = pss; 1962 } 1963 proc.lastPss = pss; 1964 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1965 proc.lastCachedPss = pss; 1966 } 1967 } 1968 } 1969 } 1970 } while (true); 1971 } 1972 } 1973 } 1974 }; 1975 1976 /** 1977 * Monitor for package changes and update our internal state. 1978 */ 1979 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1980 @Override 1981 public void onPackageRemoved(String packageName, int uid) { 1982 // Remove all tasks with activities in the specified package from the list of recent tasks 1983 synchronized (ActivityManagerService.this) { 1984 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1985 TaskRecord tr = mRecentTasks.get(i); 1986 ComponentName cn = tr.intent.getComponent(); 1987 if (cn != null && cn.getPackageName().equals(packageName)) { 1988 // If the package name matches, remove the task and kill the process 1989 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1990 } 1991 } 1992 } 1993 } 1994 1995 @Override 1996 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1997 onPackageModified(packageName); 1998 return true; 1999 } 2000 2001 @Override 2002 public void onPackageModified(String packageName) { 2003 final PackageManager pm = mContext.getPackageManager(); 2004 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2005 new ArrayList<Pair<Intent, Integer>>(); 2006 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2007 // Copy the list of recent tasks so that we don't hold onto the lock on 2008 // ActivityManagerService for long periods while checking if components exist. 2009 synchronized (ActivityManagerService.this) { 2010 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2011 TaskRecord tr = mRecentTasks.get(i); 2012 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2013 } 2014 } 2015 // Check the recent tasks and filter out all tasks with components that no longer exist. 2016 Intent tmpI = new Intent(); 2017 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2018 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2019 ComponentName cn = p.first.getComponent(); 2020 if (cn != null && cn.getPackageName().equals(packageName)) { 2021 try { 2022 // Add the task to the list to remove if the component no longer exists 2023 tmpI.setComponent(cn); 2024 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2025 tasksToRemove.add(p.second); 2026 } 2027 } catch (Exception e) {} 2028 } 2029 } 2030 // Prune all the tasks with removed components from the list of recent tasks 2031 synchronized (ActivityManagerService.this) { 2032 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2033 // Remove the task but don't kill the process (since other components in that 2034 // package may still be running and in the background) 2035 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2036 } 2037 } 2038 } 2039 2040 @Override 2041 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2042 // Force stop the specified packages 2043 if (packages != null) { 2044 for (String pkg : packages) { 2045 synchronized (ActivityManagerService.this) { 2046 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2047 "finished booting")) { 2048 return true; 2049 } 2050 } 2051 } 2052 } 2053 return false; 2054 } 2055 }; 2056 2057 public void setSystemProcess() { 2058 try { 2059 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2060 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2061 ServiceManager.addService("meminfo", new MemBinder(this)); 2062 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2063 ServiceManager.addService("dbinfo", new DbBinder(this)); 2064 if (MONITOR_CPU_USAGE) { 2065 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2066 } 2067 ServiceManager.addService("permission", new PermissionController(this)); 2068 2069 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2070 "android", STOCK_PM_FLAGS); 2071 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2072 2073 synchronized (this) { 2074 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2075 app.persistent = true; 2076 app.pid = MY_PID; 2077 app.maxAdj = ProcessList.SYSTEM_ADJ; 2078 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2079 mProcessNames.put(app.processName, app.uid, app); 2080 synchronized (mPidsSelfLocked) { 2081 mPidsSelfLocked.put(app.pid, app); 2082 } 2083 updateLruProcessLocked(app, false, null); 2084 updateOomAdjLocked(); 2085 } 2086 } catch (PackageManager.NameNotFoundException e) { 2087 throw new RuntimeException( 2088 "Unable to find android system package", e); 2089 } 2090 } 2091 2092 public void setWindowManager(WindowManagerService wm) { 2093 mWindowManager = wm; 2094 mStackSupervisor.setWindowManager(wm); 2095 } 2096 2097 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2098 mUsageStatsService = usageStatsManager; 2099 } 2100 2101 public void startObservingNativeCrashes() { 2102 final NativeCrashListener ncl = new NativeCrashListener(this); 2103 ncl.start(); 2104 } 2105 2106 public IAppOpsService getAppOpsService() { 2107 return mAppOpsService; 2108 } 2109 2110 static class MemBinder extends Binder { 2111 ActivityManagerService mActivityManagerService; 2112 MemBinder(ActivityManagerService activityManagerService) { 2113 mActivityManagerService = activityManagerService; 2114 } 2115 2116 @Override 2117 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2118 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2119 != PackageManager.PERMISSION_GRANTED) { 2120 pw.println("Permission Denial: can't dump meminfo from from pid=" 2121 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2122 + " without permission " + android.Manifest.permission.DUMP); 2123 return; 2124 } 2125 2126 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2127 } 2128 } 2129 2130 static class GraphicsBinder extends Binder { 2131 ActivityManagerService mActivityManagerService; 2132 GraphicsBinder(ActivityManagerService activityManagerService) { 2133 mActivityManagerService = activityManagerService; 2134 } 2135 2136 @Override 2137 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2138 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2139 != PackageManager.PERMISSION_GRANTED) { 2140 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2141 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2142 + " without permission " + android.Manifest.permission.DUMP); 2143 return; 2144 } 2145 2146 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2147 } 2148 } 2149 2150 static class DbBinder extends Binder { 2151 ActivityManagerService mActivityManagerService; 2152 DbBinder(ActivityManagerService activityManagerService) { 2153 mActivityManagerService = activityManagerService; 2154 } 2155 2156 @Override 2157 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2158 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2159 != PackageManager.PERMISSION_GRANTED) { 2160 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2161 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2162 + " without permission " + android.Manifest.permission.DUMP); 2163 return; 2164 } 2165 2166 mActivityManagerService.dumpDbInfo(fd, pw, args); 2167 } 2168 } 2169 2170 static class CpuBinder extends Binder { 2171 ActivityManagerService mActivityManagerService; 2172 CpuBinder(ActivityManagerService activityManagerService) { 2173 mActivityManagerService = activityManagerService; 2174 } 2175 2176 @Override 2177 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2178 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2179 != PackageManager.PERMISSION_GRANTED) { 2180 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2181 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2182 + " without permission " + android.Manifest.permission.DUMP); 2183 return; 2184 } 2185 2186 synchronized (mActivityManagerService.mProcessCpuThread) { 2187 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2188 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2189 SystemClock.uptimeMillis())); 2190 } 2191 } 2192 } 2193 2194 public static final class Lifecycle extends SystemService { 2195 private final ActivityManagerService mService; 2196 2197 public Lifecycle(Context context) { 2198 super(context); 2199 mService = new ActivityManagerService(context); 2200 } 2201 2202 @Override 2203 public void onStart() { 2204 mService.start(); 2205 } 2206 2207 public ActivityManagerService getService() { 2208 return mService; 2209 } 2210 } 2211 2212 // Note: This method is invoked on the main thread but may need to attach various 2213 // handlers to other threads. So take care to be explicit about the looper. 2214 public ActivityManagerService(Context systemContext) { 2215 mContext = systemContext; 2216 mFactoryTest = FactoryTest.getMode(); 2217 mSystemThread = ActivityThread.currentActivityThread(); 2218 2219 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2220 2221 mHandlerThread = new ServiceThread(TAG, 2222 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2223 mHandlerThread.start(); 2224 mHandler = new MainHandler(mHandlerThread.getLooper()); 2225 2226 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2227 "foreground", BROADCAST_FG_TIMEOUT, false); 2228 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2229 "background", BROADCAST_BG_TIMEOUT, true); 2230 mBroadcastQueues[0] = mFgBroadcastQueue; 2231 mBroadcastQueues[1] = mBgBroadcastQueue; 2232 2233 mServices = new ActiveServices(this); 2234 mProviderMap = new ProviderMap(this); 2235 2236 // TODO: Move creation of battery stats service outside of activity manager service. 2237 File dataDir = Environment.getDataDirectory(); 2238 File systemDir = new File(dataDir, "system"); 2239 systemDir.mkdirs(); 2240 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2241 mBatteryStatsService.getActiveStatistics().readLocked(); 2242 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2243 mOnBattery = DEBUG_POWER ? true 2244 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2245 mBatteryStatsService.getActiveStatistics().setCallback(this); 2246 2247 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2248 2249 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2250 2251 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2252 2253 // User 0 is the first and only user that runs at boot. 2254 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2255 mUserLru.add(Integer.valueOf(0)); 2256 updateStartedUserArrayLocked(); 2257 2258 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2259 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2260 2261 mConfiguration.setToDefaults(); 2262 mConfiguration.setLocale(Locale.getDefault()); 2263 2264 mConfigurationSeq = mConfiguration.seq = 1; 2265 mProcessCpuTracker.init(); 2266 2267 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2268 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2269 mStackSupervisor = new ActivityStackSupervisor(this); 2270 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2271 2272 mProcessCpuThread = new Thread("CpuTracker") { 2273 @Override 2274 public void run() { 2275 while (true) { 2276 try { 2277 try { 2278 synchronized(this) { 2279 final long now = SystemClock.uptimeMillis(); 2280 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2281 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2282 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2283 // + ", write delay=" + nextWriteDelay); 2284 if (nextWriteDelay < nextCpuDelay) { 2285 nextCpuDelay = nextWriteDelay; 2286 } 2287 if (nextCpuDelay > 0) { 2288 mProcessCpuMutexFree.set(true); 2289 this.wait(nextCpuDelay); 2290 } 2291 } 2292 } catch (InterruptedException e) { 2293 } 2294 updateCpuStatsNow(); 2295 } catch (Exception e) { 2296 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2297 } 2298 } 2299 } 2300 }; 2301 2302 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2303 2304 Watchdog.getInstance().addMonitor(this); 2305 Watchdog.getInstance().addThread(mHandler); 2306 } 2307 2308 public void setSystemServiceManager(SystemServiceManager mgr) { 2309 mSystemServiceManager = mgr; 2310 } 2311 2312 private void start() { 2313 Process.removeAllProcessGroups(); 2314 mProcessCpuThread.start(); 2315 2316 mBatteryStatsService.publish(mContext); 2317 mAppOpsService.publish(mContext); 2318 Slog.d("AppOps", "AppOpsService published"); 2319 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2320 } 2321 2322 public void initPowerManagement() { 2323 mStackSupervisor.initPowerManagement(); 2324 mBatteryStatsService.initPowerManagement(); 2325 } 2326 2327 @Override 2328 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2329 throws RemoteException { 2330 if (code == SYSPROPS_TRANSACTION) { 2331 // We need to tell all apps about the system property change. 2332 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2333 synchronized(this) { 2334 final int NP = mProcessNames.getMap().size(); 2335 for (int ip=0; ip<NP; ip++) { 2336 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2337 final int NA = apps.size(); 2338 for (int ia=0; ia<NA; ia++) { 2339 ProcessRecord app = apps.valueAt(ia); 2340 if (app.thread != null) { 2341 procs.add(app.thread.asBinder()); 2342 } 2343 } 2344 } 2345 } 2346 2347 int N = procs.size(); 2348 for (int i=0; i<N; i++) { 2349 Parcel data2 = Parcel.obtain(); 2350 try { 2351 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2352 } catch (RemoteException e) { 2353 } 2354 data2.recycle(); 2355 } 2356 } 2357 try { 2358 return super.onTransact(code, data, reply, flags); 2359 } catch (RuntimeException e) { 2360 // The activity manager only throws security exceptions, so let's 2361 // log all others. 2362 if (!(e instanceof SecurityException)) { 2363 Slog.wtf(TAG, "Activity Manager Crash", e); 2364 } 2365 throw e; 2366 } 2367 } 2368 2369 void updateCpuStats() { 2370 final long now = SystemClock.uptimeMillis(); 2371 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2372 return; 2373 } 2374 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2375 synchronized (mProcessCpuThread) { 2376 mProcessCpuThread.notify(); 2377 } 2378 } 2379 } 2380 2381 void updateCpuStatsNow() { 2382 synchronized (mProcessCpuThread) { 2383 mProcessCpuMutexFree.set(false); 2384 final long now = SystemClock.uptimeMillis(); 2385 boolean haveNewCpuStats = false; 2386 2387 if (MONITOR_CPU_USAGE && 2388 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2389 mLastCpuTime.set(now); 2390 haveNewCpuStats = true; 2391 mProcessCpuTracker.update(); 2392 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2393 //Slog.i(TAG, "Total CPU usage: " 2394 // + mProcessCpu.getTotalCpuPercent() + "%"); 2395 2396 // Slog the cpu usage if the property is set. 2397 if ("true".equals(SystemProperties.get("events.cpu"))) { 2398 int user = mProcessCpuTracker.getLastUserTime(); 2399 int system = mProcessCpuTracker.getLastSystemTime(); 2400 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2401 int irq = mProcessCpuTracker.getLastIrqTime(); 2402 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2403 int idle = mProcessCpuTracker.getLastIdleTime(); 2404 2405 int total = user + system + iowait + irq + softIrq + idle; 2406 if (total == 0) total = 1; 2407 2408 EventLog.writeEvent(EventLogTags.CPU, 2409 ((user+system+iowait+irq+softIrq) * 100) / total, 2410 (user * 100) / total, 2411 (system * 100) / total, 2412 (iowait * 100) / total, 2413 (irq * 100) / total, 2414 (softIrq * 100) / total); 2415 } 2416 } 2417 2418 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2419 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2420 synchronized(bstats) { 2421 synchronized(mPidsSelfLocked) { 2422 if (haveNewCpuStats) { 2423 if (mOnBattery) { 2424 int perc = bstats.startAddingCpuLocked(); 2425 int totalUTime = 0; 2426 int totalSTime = 0; 2427 final int N = mProcessCpuTracker.countStats(); 2428 for (int i=0; i<N; i++) { 2429 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2430 if (!st.working) { 2431 continue; 2432 } 2433 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2434 int otherUTime = (st.rel_utime*perc)/100; 2435 int otherSTime = (st.rel_stime*perc)/100; 2436 totalUTime += otherUTime; 2437 totalSTime += otherSTime; 2438 if (pr != null) { 2439 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2440 if (ps == null || !ps.isActive()) { 2441 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2442 pr.info.uid, pr.processName); 2443 } 2444 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2445 st.rel_stime-otherSTime); 2446 ps.addSpeedStepTimes(cpuSpeedTimes); 2447 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2448 } else { 2449 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2450 if (ps == null || !ps.isActive()) { 2451 st.batteryStats = ps = bstats.getProcessStatsLocked( 2452 bstats.mapUid(st.uid), st.name); 2453 } 2454 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2455 st.rel_stime-otherSTime); 2456 ps.addSpeedStepTimes(cpuSpeedTimes); 2457 } 2458 } 2459 bstats.finishAddingCpuLocked(perc, totalUTime, 2460 totalSTime, cpuSpeedTimes); 2461 } 2462 } 2463 } 2464 2465 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2466 mLastWriteTime = now; 2467 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2468 } 2469 } 2470 } 2471 } 2472 2473 @Override 2474 public void batteryNeedsCpuUpdate() { 2475 updateCpuStatsNow(); 2476 } 2477 2478 @Override 2479 public void batteryPowerChanged(boolean onBattery) { 2480 // When plugging in, update the CPU stats first before changing 2481 // the plug state. 2482 updateCpuStatsNow(); 2483 synchronized (this) { 2484 synchronized(mPidsSelfLocked) { 2485 mOnBattery = DEBUG_POWER ? true : onBattery; 2486 } 2487 } 2488 } 2489 2490 /** 2491 * Initialize the application bind args. These are passed to each 2492 * process when the bindApplication() IPC is sent to the process. They're 2493 * lazily setup to make sure the services are running when they're asked for. 2494 */ 2495 private HashMap<String, IBinder> getCommonServicesLocked() { 2496 if (mAppBindArgs == null) { 2497 mAppBindArgs = new HashMap<String, IBinder>(); 2498 2499 // Setup the application init args 2500 mAppBindArgs.put("package", ServiceManager.getService("package")); 2501 mAppBindArgs.put("window", ServiceManager.getService("window")); 2502 mAppBindArgs.put(Context.ALARM_SERVICE, 2503 ServiceManager.getService(Context.ALARM_SERVICE)); 2504 } 2505 return mAppBindArgs; 2506 } 2507 2508 final void setFocusedActivityLocked(ActivityRecord r) { 2509 if (mFocusedActivity != r) { 2510 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2511 mFocusedActivity = r; 2512 if (r.task != null && r.task.voiceInteractor != null) { 2513 startRunningVoiceLocked(); 2514 } else { 2515 finishRunningVoiceLocked(); 2516 } 2517 mStackSupervisor.setFocusedStack(r); 2518 if (r != null) { 2519 mWindowManager.setFocusedApp(r.appToken, true); 2520 } 2521 applyUpdateLockStateLocked(r); 2522 } 2523 } 2524 2525 final void clearFocusedActivity(ActivityRecord r) { 2526 if (mFocusedActivity == r) { 2527 mFocusedActivity = null; 2528 } 2529 } 2530 2531 @Override 2532 public void setFocusedStack(int stackId) { 2533 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2534 synchronized (ActivityManagerService.this) { 2535 ActivityStack stack = mStackSupervisor.getStack(stackId); 2536 if (stack != null) { 2537 ActivityRecord r = stack.topRunningActivityLocked(null); 2538 if (r != null) { 2539 setFocusedActivityLocked(r); 2540 } 2541 } 2542 } 2543 } 2544 2545 @Override 2546 public void notifyActivityDrawn(IBinder token) { 2547 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2548 synchronized (this) { 2549 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2550 if (r != null) { 2551 r.task.stack.notifyActivityDrawnLocked(r); 2552 } 2553 } 2554 } 2555 2556 final void applyUpdateLockStateLocked(ActivityRecord r) { 2557 // Modifications to the UpdateLock state are done on our handler, outside 2558 // the activity manager's locks. The new state is determined based on the 2559 // state *now* of the relevant activity record. The object is passed to 2560 // the handler solely for logging detail, not to be consulted/modified. 2561 final boolean nextState = r != null && r.immersive; 2562 mHandler.sendMessage( 2563 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2564 } 2565 2566 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2567 Message msg = Message.obtain(); 2568 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2569 msg.obj = r.task.askedCompatMode ? null : r; 2570 mHandler.sendMessage(msg); 2571 } 2572 2573 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2574 String what, Object obj, ProcessRecord srcApp) { 2575 app.lastActivityTime = now; 2576 2577 if (app.activities.size() > 0) { 2578 // Don't want to touch dependent processes that are hosting activities. 2579 return index; 2580 } 2581 2582 int lrui = mLruProcesses.lastIndexOf(app); 2583 if (lrui < 0) { 2584 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2585 + what + " " + obj + " from " + srcApp); 2586 return index; 2587 } 2588 2589 if (lrui >= index) { 2590 // Don't want to cause this to move dependent processes *back* in the 2591 // list as if they were less frequently used. 2592 return index; 2593 } 2594 2595 if (lrui >= mLruProcessActivityStart) { 2596 // Don't want to touch dependent processes that are hosting activities. 2597 return index; 2598 } 2599 2600 mLruProcesses.remove(lrui); 2601 if (index > 0) { 2602 index--; 2603 } 2604 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2605 + " in LRU list: " + app); 2606 mLruProcesses.add(index, app); 2607 return index; 2608 } 2609 2610 final void removeLruProcessLocked(ProcessRecord app) { 2611 int lrui = mLruProcesses.lastIndexOf(app); 2612 if (lrui >= 0) { 2613 if (lrui <= mLruProcessActivityStart) { 2614 mLruProcessActivityStart--; 2615 } 2616 if (lrui <= mLruProcessServiceStart) { 2617 mLruProcessServiceStart--; 2618 } 2619 mLruProcesses.remove(lrui); 2620 } 2621 } 2622 2623 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2624 ProcessRecord client) { 2625 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2626 || app.treatLikeActivity; 2627 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2628 if (!activityChange && hasActivity) { 2629 // The process has activities, so we are only allowing activity-based adjustments 2630 // to move it. It should be kept in the front of the list with other 2631 // processes that have activities, and we don't want those to change their 2632 // order except due to activity operations. 2633 return; 2634 } 2635 2636 mLruSeq++; 2637 final long now = SystemClock.uptimeMillis(); 2638 app.lastActivityTime = now; 2639 2640 // First a quick reject: if the app is already at the position we will 2641 // put it, then there is nothing to do. 2642 if (hasActivity) { 2643 final int N = mLruProcesses.size(); 2644 if (N > 0 && mLruProcesses.get(N-1) == app) { 2645 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2646 return; 2647 } 2648 } else { 2649 if (mLruProcessServiceStart > 0 2650 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2651 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2652 return; 2653 } 2654 } 2655 2656 int lrui = mLruProcesses.lastIndexOf(app); 2657 2658 if (app.persistent && lrui >= 0) { 2659 // We don't care about the position of persistent processes, as long as 2660 // they are in the list. 2661 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2662 return; 2663 } 2664 2665 /* In progress: compute new position first, so we can avoid doing work 2666 if the process is not actually going to move. Not yet working. 2667 int addIndex; 2668 int nextIndex; 2669 boolean inActivity = false, inService = false; 2670 if (hasActivity) { 2671 // Process has activities, put it at the very tipsy-top. 2672 addIndex = mLruProcesses.size(); 2673 nextIndex = mLruProcessServiceStart; 2674 inActivity = true; 2675 } else if (hasService) { 2676 // Process has services, put it at the top of the service list. 2677 addIndex = mLruProcessActivityStart; 2678 nextIndex = mLruProcessServiceStart; 2679 inActivity = true; 2680 inService = true; 2681 } else { 2682 // Process not otherwise of interest, it goes to the top of the non-service area. 2683 addIndex = mLruProcessServiceStart; 2684 if (client != null) { 2685 int clientIndex = mLruProcesses.lastIndexOf(client); 2686 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2687 + app); 2688 if (clientIndex >= 0 && addIndex > clientIndex) { 2689 addIndex = clientIndex; 2690 } 2691 } 2692 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2693 } 2694 2695 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2696 + mLruProcessActivityStart + "): " + app); 2697 */ 2698 2699 if (lrui >= 0) { 2700 if (lrui < mLruProcessActivityStart) { 2701 mLruProcessActivityStart--; 2702 } 2703 if (lrui < mLruProcessServiceStart) { 2704 mLruProcessServiceStart--; 2705 } 2706 /* 2707 if (addIndex > lrui) { 2708 addIndex--; 2709 } 2710 if (nextIndex > lrui) { 2711 nextIndex--; 2712 } 2713 */ 2714 mLruProcesses.remove(lrui); 2715 } 2716 2717 /* 2718 mLruProcesses.add(addIndex, app); 2719 if (inActivity) { 2720 mLruProcessActivityStart++; 2721 } 2722 if (inService) { 2723 mLruProcessActivityStart++; 2724 } 2725 */ 2726 2727 int nextIndex; 2728 if (hasActivity) { 2729 final int N = mLruProcesses.size(); 2730 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2731 // Process doesn't have activities, but has clients with 2732 // activities... move it up, but one below the top (the top 2733 // should always have a real activity). 2734 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2735 mLruProcesses.add(N-1, app); 2736 // To keep it from spamming the LRU list (by making a bunch of clients), 2737 // we will push down any other entries owned by the app. 2738 final int uid = app.info.uid; 2739 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2740 ProcessRecord subProc = mLruProcesses.get(i); 2741 if (subProc.info.uid == uid) { 2742 // We want to push this one down the list. If the process after 2743 // it is for the same uid, however, don't do so, because we don't 2744 // want them internally to be re-ordered. 2745 if (mLruProcesses.get(i-1).info.uid != uid) { 2746 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2747 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2748 ProcessRecord tmp = mLruProcesses.get(i); 2749 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2750 mLruProcesses.set(i-1, tmp); 2751 i--; 2752 } 2753 } else { 2754 // A gap, we can stop here. 2755 break; 2756 } 2757 } 2758 } else { 2759 // Process has activities, put it at the very tipsy-top. 2760 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2761 mLruProcesses.add(app); 2762 } 2763 nextIndex = mLruProcessServiceStart; 2764 } else if (hasService) { 2765 // Process has services, put it at the top of the service list. 2766 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2767 mLruProcesses.add(mLruProcessActivityStart, app); 2768 nextIndex = mLruProcessServiceStart; 2769 mLruProcessActivityStart++; 2770 } else { 2771 // Process not otherwise of interest, it goes to the top of the non-service area. 2772 int index = mLruProcessServiceStart; 2773 if (client != null) { 2774 // If there is a client, don't allow the process to be moved up higher 2775 // in the list than that client. 2776 int clientIndex = mLruProcesses.lastIndexOf(client); 2777 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2778 + " when updating " + app); 2779 if (clientIndex <= lrui) { 2780 // Don't allow the client index restriction to push it down farther in the 2781 // list than it already is. 2782 clientIndex = lrui; 2783 } 2784 if (clientIndex >= 0 && index > clientIndex) { 2785 index = clientIndex; 2786 } 2787 } 2788 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2789 mLruProcesses.add(index, app); 2790 nextIndex = index-1; 2791 mLruProcessActivityStart++; 2792 mLruProcessServiceStart++; 2793 } 2794 2795 // If the app is currently using a content provider or service, 2796 // bump those processes as well. 2797 for (int j=app.connections.size()-1; j>=0; j--) { 2798 ConnectionRecord cr = app.connections.valueAt(j); 2799 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2800 && cr.binding.service.app != null 2801 && cr.binding.service.app.lruSeq != mLruSeq 2802 && !cr.binding.service.app.persistent) { 2803 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2804 "service connection", cr, app); 2805 } 2806 } 2807 for (int j=app.conProviders.size()-1; j>=0; j--) { 2808 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2809 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2810 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2811 "provider reference", cpr, app); 2812 } 2813 } 2814 } 2815 2816 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2817 if (uid == Process.SYSTEM_UID) { 2818 // The system gets to run in any process. If there are multiple 2819 // processes with the same uid, just pick the first (this 2820 // should never happen). 2821 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2822 if (procs == null) return null; 2823 final int N = procs.size(); 2824 for (int i = 0; i < N; i++) { 2825 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2826 } 2827 } 2828 ProcessRecord proc = mProcessNames.get(processName, uid); 2829 if (false && proc != null && !keepIfLarge 2830 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2831 && proc.lastCachedPss >= 4000) { 2832 // Turn this condition on to cause killing to happen regularly, for testing. 2833 if (proc.baseProcessTracker != null) { 2834 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2835 } 2836 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2837 } else if (proc != null && !keepIfLarge 2838 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2839 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2840 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2841 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2842 if (proc.baseProcessTracker != null) { 2843 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2844 } 2845 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2846 } 2847 } 2848 return proc; 2849 } 2850 2851 void ensurePackageDexOpt(String packageName) { 2852 IPackageManager pm = AppGlobals.getPackageManager(); 2853 try { 2854 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2855 mDidDexOpt = true; 2856 } 2857 } catch (RemoteException e) { 2858 } 2859 } 2860 2861 boolean isNextTransitionForward() { 2862 int transit = mWindowManager.getPendingAppTransition(); 2863 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2864 || transit == AppTransition.TRANSIT_TASK_OPEN 2865 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2866 } 2867 2868 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2869 String processName, String abiOverride, int uid, Runnable crashHandler) { 2870 synchronized(this) { 2871 ApplicationInfo info = new ApplicationInfo(); 2872 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2873 // For isolated processes, the former contains the parent's uid and the latter the 2874 // actual uid of the isolated process. 2875 // In the special case introduced by this method (which is, starting an isolated 2876 // process directly from the SystemServer without an actual parent app process) the 2877 // closest thing to a parent's uid is SYSTEM_UID. 2878 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2879 // the |isolated| logic in the ProcessRecord constructor. 2880 info.uid = Process.SYSTEM_UID; 2881 info.processName = processName; 2882 info.className = entryPoint; 2883 info.packageName = "android"; 2884 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2885 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2886 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2887 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2888 crashHandler); 2889 return proc != null ? proc.pid : 0; 2890 } 2891 } 2892 2893 final ProcessRecord startProcessLocked(String processName, 2894 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2895 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2896 boolean isolated, boolean keepIfLarge) { 2897 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2898 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2899 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2900 null /* crashHandler */); 2901 } 2902 2903 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2904 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2905 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2906 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2907 long startTime = SystemClock.elapsedRealtime(); 2908 ProcessRecord app; 2909 if (!isolated) { 2910 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2911 checkTime(startTime, "startProcess: after getProcessRecord"); 2912 } else { 2913 // If this is an isolated process, it can't re-use an existing process. 2914 app = null; 2915 } 2916 // We don't have to do anything more if: 2917 // (1) There is an existing application record; and 2918 // (2) The caller doesn't think it is dead, OR there is no thread 2919 // object attached to it so we know it couldn't have crashed; and 2920 // (3) There is a pid assigned to it, so it is either starting or 2921 // already running. 2922 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2923 + " app=" + app + " knownToBeDead=" + knownToBeDead 2924 + " thread=" + (app != null ? app.thread : null) 2925 + " pid=" + (app != null ? app.pid : -1)); 2926 if (app != null && app.pid > 0) { 2927 if (!knownToBeDead || app.thread == null) { 2928 // We already have the app running, or are waiting for it to 2929 // come up (we have a pid but not yet its thread), so keep it. 2930 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2931 // If this is a new package in the process, add the package to the list 2932 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2933 checkTime(startTime, "startProcess: done, added package to proc"); 2934 return app; 2935 } 2936 2937 // An application record is attached to a previous process, 2938 // clean it up now. 2939 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2940 checkTime(startTime, "startProcess: bad proc running, killing"); 2941 Process.killProcessGroup(app.info.uid, app.pid); 2942 handleAppDiedLocked(app, true, true); 2943 checkTime(startTime, "startProcess: done killing old proc"); 2944 } 2945 2946 String hostingNameStr = hostingName != null 2947 ? hostingName.flattenToShortString() : null; 2948 2949 if (!isolated) { 2950 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2951 // If we are in the background, then check to see if this process 2952 // is bad. If so, we will just silently fail. 2953 if (mBadProcesses.get(info.processName, info.uid) != null) { 2954 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2955 + "/" + info.processName); 2956 return null; 2957 } 2958 } else { 2959 // When the user is explicitly starting a process, then clear its 2960 // crash count so that we won't make it bad until they see at 2961 // least one crash dialog again, and make the process good again 2962 // if it had been bad. 2963 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2964 + "/" + info.processName); 2965 mProcessCrashTimes.remove(info.processName, info.uid); 2966 if (mBadProcesses.get(info.processName, info.uid) != null) { 2967 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2968 UserHandle.getUserId(info.uid), info.uid, 2969 info.processName); 2970 mBadProcesses.remove(info.processName, info.uid); 2971 if (app != null) { 2972 app.bad = false; 2973 } 2974 } 2975 } 2976 } 2977 2978 if (app == null) { 2979 checkTime(startTime, "startProcess: creating new process record"); 2980 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2981 app.crashHandler = crashHandler; 2982 if (app == null) { 2983 Slog.w(TAG, "Failed making new process record for " 2984 + processName + "/" + info.uid + " isolated=" + isolated); 2985 return null; 2986 } 2987 mProcessNames.put(processName, app.uid, app); 2988 if (isolated) { 2989 mIsolatedProcesses.put(app.uid, app); 2990 } 2991 checkTime(startTime, "startProcess: done creating new process record"); 2992 } else { 2993 // If this is a new package in the process, add the package to the list 2994 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2995 checkTime(startTime, "startProcess: added package to existing proc"); 2996 } 2997 2998 // If the system is not ready yet, then hold off on starting this 2999 // process until it is. 3000 if (!mProcessesReady 3001 && !isAllowedWhileBooting(info) 3002 && !allowWhileBooting) { 3003 if (!mProcessesOnHold.contains(app)) { 3004 mProcessesOnHold.add(app); 3005 } 3006 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3007 checkTime(startTime, "startProcess: returning with proc on hold"); 3008 return app; 3009 } 3010 3011 checkTime(startTime, "startProcess: stepping in to startProcess"); 3012 startProcessLocked( 3013 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3014 checkTime(startTime, "startProcess: done starting proc!"); 3015 return (app.pid != 0) ? app : null; 3016 } 3017 3018 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3019 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3020 } 3021 3022 private final void startProcessLocked(ProcessRecord app, 3023 String hostingType, String hostingNameStr) { 3024 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3025 null /* entryPoint */, null /* entryPointArgs */); 3026 } 3027 3028 private final void startProcessLocked(ProcessRecord app, String hostingType, 3029 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3030 long startTime = SystemClock.elapsedRealtime(); 3031 if (app.pid > 0 && app.pid != MY_PID) { 3032 checkTime(startTime, "startProcess: removing from pids map"); 3033 synchronized (mPidsSelfLocked) { 3034 mPidsSelfLocked.remove(app.pid); 3035 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3036 } 3037 checkTime(startTime, "startProcess: done removing from pids map"); 3038 app.setPid(0); 3039 } 3040 3041 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3042 "startProcessLocked removing on hold: " + app); 3043 mProcessesOnHold.remove(app); 3044 3045 checkTime(startTime, "startProcess: starting to update cpu stats"); 3046 updateCpuStats(); 3047 checkTime(startTime, "startProcess: done updating cpu stats"); 3048 3049 try { 3050 int uid = app.uid; 3051 3052 int[] gids = null; 3053 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3054 if (!app.isolated) { 3055 int[] permGids = null; 3056 try { 3057 checkTime(startTime, "startProcess: getting gids from package manager"); 3058 final PackageManager pm = mContext.getPackageManager(); 3059 permGids = pm.getPackageGids(app.info.packageName); 3060 3061 if (Environment.isExternalStorageEmulated()) { 3062 checkTime(startTime, "startProcess: checking external storage perm"); 3063 if (pm.checkPermission( 3064 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3065 app.info.packageName) == PERMISSION_GRANTED) { 3066 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3067 } else { 3068 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3069 } 3070 } 3071 } catch (PackageManager.NameNotFoundException e) { 3072 Slog.w(TAG, "Unable to retrieve gids", e); 3073 } 3074 3075 /* 3076 * Add shared application and profile GIDs so applications can share some 3077 * resources like shared libraries and access user-wide resources 3078 */ 3079 if (permGids == null) { 3080 gids = new int[2]; 3081 } else { 3082 gids = new int[permGids.length + 2]; 3083 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3084 } 3085 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3086 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3087 } 3088 checkTime(startTime, "startProcess: building args"); 3089 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3090 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3091 && mTopComponent != null 3092 && app.processName.equals(mTopComponent.getPackageName())) { 3093 uid = 0; 3094 } 3095 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3096 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3097 uid = 0; 3098 } 3099 } 3100 int debugFlags = 0; 3101 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3102 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3103 // Also turn on CheckJNI for debuggable apps. It's quite 3104 // awkward to turn on otherwise. 3105 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3106 } 3107 // Run the app in safe mode if its manifest requests so or the 3108 // system is booted in safe mode. 3109 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3110 mSafeMode == true) { 3111 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3112 } 3113 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3114 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3115 } 3116 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3117 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3118 } 3119 if ("1".equals(SystemProperties.get("debug.assert"))) { 3120 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3121 } 3122 3123 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3124 if (requiredAbi == null) { 3125 requiredAbi = Build.SUPPORTED_ABIS[0]; 3126 } 3127 3128 String instructionSet = null; 3129 if (app.info.primaryCpuAbi != null) { 3130 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3131 } 3132 3133 // Start the process. It will either succeed and return a result containing 3134 // the PID of the new process, or else throw a RuntimeException. 3135 boolean isActivityProcess = (entryPoint == null); 3136 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3137 checkTime(startTime, "startProcess: asking zygote to start proc"); 3138 Process.ProcessStartResult startResult = Process.start(entryPoint, 3139 app.processName, uid, uid, gids, debugFlags, mountExternal, 3140 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, 3141 entryPointArgs); 3142 checkTime(startTime, "startProcess: returned from zygote!"); 3143 3144 if (app.isolated) { 3145 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3146 } 3147 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3148 checkTime(startTime, "startProcess: done updating battery stats"); 3149 3150 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3151 UserHandle.getUserId(uid), startResult.pid, uid, 3152 app.processName, hostingType, 3153 hostingNameStr != null ? hostingNameStr : ""); 3154 3155 if (app.persistent) { 3156 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3157 } 3158 3159 checkTime(startTime, "startProcess: building log message"); 3160 StringBuilder buf = mStringBuilder; 3161 buf.setLength(0); 3162 buf.append("Start proc "); 3163 buf.append(app.processName); 3164 if (!isActivityProcess) { 3165 buf.append(" ["); 3166 buf.append(entryPoint); 3167 buf.append("]"); 3168 } 3169 buf.append(" for "); 3170 buf.append(hostingType); 3171 if (hostingNameStr != null) { 3172 buf.append(" "); 3173 buf.append(hostingNameStr); 3174 } 3175 buf.append(": pid="); 3176 buf.append(startResult.pid); 3177 buf.append(" uid="); 3178 buf.append(uid); 3179 buf.append(" gids={"); 3180 if (gids != null) { 3181 for (int gi=0; gi<gids.length; gi++) { 3182 if (gi != 0) buf.append(", "); 3183 buf.append(gids[gi]); 3184 3185 } 3186 } 3187 buf.append("}"); 3188 if (requiredAbi != null) { 3189 buf.append(" abi="); 3190 buf.append(requiredAbi); 3191 } 3192 Slog.i(TAG, buf.toString()); 3193 app.setPid(startResult.pid); 3194 app.usingWrapper = startResult.usingWrapper; 3195 app.removed = false; 3196 app.killedByAm = false; 3197 checkTime(startTime, "startProcess: starting to update pids map"); 3198 synchronized (mPidsSelfLocked) { 3199 this.mPidsSelfLocked.put(startResult.pid, app); 3200 if (isActivityProcess) { 3201 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3202 msg.obj = app; 3203 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3204 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3205 } 3206 } 3207 checkTime(startTime, "startProcess: done updating pids map"); 3208 } catch (RuntimeException e) { 3209 // XXX do better error recovery. 3210 app.setPid(0); 3211 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3212 if (app.isolated) { 3213 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3214 } 3215 Slog.e(TAG, "Failure starting process " + app.processName, e); 3216 } 3217 } 3218 3219 void updateUsageStats(ActivityRecord component, boolean resumed) { 3220 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3221 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3222 if (resumed) { 3223 if (mUsageStatsService != null) { 3224 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3225 UsageEvents.Event.MOVE_TO_FOREGROUND); 3226 } 3227 synchronized (stats) { 3228 stats.noteActivityResumedLocked(component.app.uid); 3229 } 3230 } else { 3231 if (mUsageStatsService != null) { 3232 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3233 UsageEvents.Event.MOVE_TO_BACKGROUND); 3234 } 3235 synchronized (stats) { 3236 stats.noteActivityPausedLocked(component.app.uid); 3237 } 3238 } 3239 } 3240 3241 Intent getHomeIntent() { 3242 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3243 intent.setComponent(mTopComponent); 3244 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3245 intent.addCategory(Intent.CATEGORY_HOME); 3246 } 3247 return intent; 3248 } 3249 3250 boolean startHomeActivityLocked(int userId) { 3251 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3252 && mTopAction == null) { 3253 // We are running in factory test mode, but unable to find 3254 // the factory test app, so just sit around displaying the 3255 // error message and don't try to start anything. 3256 return false; 3257 } 3258 Intent intent = getHomeIntent(); 3259 ActivityInfo aInfo = 3260 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3261 if (aInfo != null) { 3262 intent.setComponent(new ComponentName( 3263 aInfo.applicationInfo.packageName, aInfo.name)); 3264 // Don't do this if the home app is currently being 3265 // instrumented. 3266 aInfo = new ActivityInfo(aInfo); 3267 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3268 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3269 aInfo.applicationInfo.uid, true); 3270 if (app == null || app.instrumentationClass == null) { 3271 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3272 mStackSupervisor.startHomeActivity(intent, aInfo); 3273 } 3274 } 3275 3276 return true; 3277 } 3278 3279 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3280 ActivityInfo ai = null; 3281 ComponentName comp = intent.getComponent(); 3282 try { 3283 if (comp != null) { 3284 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3285 } else { 3286 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3287 intent, 3288 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3289 flags, userId); 3290 3291 if (info != null) { 3292 ai = info.activityInfo; 3293 } 3294 } 3295 } catch (RemoteException e) { 3296 // ignore 3297 } 3298 3299 return ai; 3300 } 3301 3302 /** 3303 * Starts the "new version setup screen" if appropriate. 3304 */ 3305 void startSetupActivityLocked() { 3306 // Only do this once per boot. 3307 if (mCheckedForSetup) { 3308 return; 3309 } 3310 3311 // We will show this screen if the current one is a different 3312 // version than the last one shown, and we are not running in 3313 // low-level factory test mode. 3314 final ContentResolver resolver = mContext.getContentResolver(); 3315 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3316 Settings.Global.getInt(resolver, 3317 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3318 mCheckedForSetup = true; 3319 3320 // See if we should be showing the platform update setup UI. 3321 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3322 List<ResolveInfo> ris = mContext.getPackageManager() 3323 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3324 3325 // We don't allow third party apps to replace this. 3326 ResolveInfo ri = null; 3327 for (int i=0; ris != null && i<ris.size(); i++) { 3328 if ((ris.get(i).activityInfo.applicationInfo.flags 3329 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3330 ri = ris.get(i); 3331 break; 3332 } 3333 } 3334 3335 if (ri != null) { 3336 String vers = ri.activityInfo.metaData != null 3337 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3338 : null; 3339 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3340 vers = ri.activityInfo.applicationInfo.metaData.getString( 3341 Intent.METADATA_SETUP_VERSION); 3342 } 3343 String lastVers = Settings.Secure.getString( 3344 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3345 if (vers != null && !vers.equals(lastVers)) { 3346 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3347 intent.setComponent(new ComponentName( 3348 ri.activityInfo.packageName, ri.activityInfo.name)); 3349 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3350 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3351 null); 3352 } 3353 } 3354 } 3355 } 3356 3357 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3358 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3359 } 3360 3361 void enforceNotIsolatedCaller(String caller) { 3362 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3363 throw new SecurityException("Isolated process not allowed to call " + caller); 3364 } 3365 } 3366 3367 @Override 3368 public int getFrontActivityScreenCompatMode() { 3369 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3370 synchronized (this) { 3371 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3372 } 3373 } 3374 3375 @Override 3376 public void setFrontActivityScreenCompatMode(int mode) { 3377 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3378 "setFrontActivityScreenCompatMode"); 3379 synchronized (this) { 3380 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3381 } 3382 } 3383 3384 @Override 3385 public int getPackageScreenCompatMode(String packageName) { 3386 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3387 synchronized (this) { 3388 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3389 } 3390 } 3391 3392 @Override 3393 public void setPackageScreenCompatMode(String packageName, int mode) { 3394 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3395 "setPackageScreenCompatMode"); 3396 synchronized (this) { 3397 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3398 } 3399 } 3400 3401 @Override 3402 public boolean getPackageAskScreenCompat(String packageName) { 3403 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3404 synchronized (this) { 3405 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3406 } 3407 } 3408 3409 @Override 3410 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3411 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3412 "setPackageAskScreenCompat"); 3413 synchronized (this) { 3414 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3415 } 3416 } 3417 3418 private void dispatchProcessesChanged() { 3419 int N; 3420 synchronized (this) { 3421 N = mPendingProcessChanges.size(); 3422 if (mActiveProcessChanges.length < N) { 3423 mActiveProcessChanges = new ProcessChangeItem[N]; 3424 } 3425 mPendingProcessChanges.toArray(mActiveProcessChanges); 3426 mAvailProcessChanges.addAll(mPendingProcessChanges); 3427 mPendingProcessChanges.clear(); 3428 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3429 } 3430 3431 int i = mProcessObservers.beginBroadcast(); 3432 while (i > 0) { 3433 i--; 3434 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3435 if (observer != null) { 3436 try { 3437 for (int j=0; j<N; j++) { 3438 ProcessChangeItem item = mActiveProcessChanges[j]; 3439 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3440 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3441 + item.pid + " uid=" + item.uid + ": " 3442 + item.foregroundActivities); 3443 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3444 item.foregroundActivities); 3445 } 3446 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3447 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3448 + item.pid + " uid=" + item.uid + ": " + item.processState); 3449 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3450 } 3451 } 3452 } catch (RemoteException e) { 3453 } 3454 } 3455 } 3456 mProcessObservers.finishBroadcast(); 3457 } 3458 3459 private void dispatchProcessDied(int pid, int uid) { 3460 int i = mProcessObservers.beginBroadcast(); 3461 while (i > 0) { 3462 i--; 3463 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3464 if (observer != null) { 3465 try { 3466 observer.onProcessDied(pid, uid); 3467 } catch (RemoteException e) { 3468 } 3469 } 3470 } 3471 mProcessObservers.finishBroadcast(); 3472 } 3473 3474 @Override 3475 public final int startActivity(IApplicationThread caller, String callingPackage, 3476 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3477 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3478 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3479 resultWho, requestCode, startFlags, profilerInfo, options, 3480 UserHandle.getCallingUserId()); 3481 } 3482 3483 @Override 3484 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3485 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3486 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3487 enforceNotIsolatedCaller("startActivity"); 3488 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3489 false, ALLOW_FULL_ONLY, "startActivity", null); 3490 // TODO: Switch to user app stacks here. 3491 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3492 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3493 profilerInfo, null, null, options, userId, null, null); 3494 } 3495 3496 @Override 3497 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3498 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3499 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3500 3501 // This is very dangerous -- it allows you to perform a start activity (including 3502 // permission grants) as any app that may launch one of your own activities. So 3503 // we will only allow this to be done from activities that are part of the core framework, 3504 // and then only when they are running as the system. 3505 final ActivityRecord sourceRecord; 3506 final int targetUid; 3507 final String targetPackage; 3508 synchronized (this) { 3509 if (resultTo == null) { 3510 throw new SecurityException("Must be called from an activity"); 3511 } 3512 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3513 if (sourceRecord == null) { 3514 throw new SecurityException("Called with bad activity token: " + resultTo); 3515 } 3516 if (!sourceRecord.info.packageName.equals("android")) { 3517 throw new SecurityException( 3518 "Must be called from an activity that is declared in the android package"); 3519 } 3520 if (sourceRecord.app == null) { 3521 throw new SecurityException("Called without a process attached to activity"); 3522 } 3523 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3524 // This is still okay, as long as this activity is running under the 3525 // uid of the original calling activity. 3526 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3527 throw new SecurityException( 3528 "Calling activity in uid " + sourceRecord.app.uid 3529 + " must be system uid or original calling uid " 3530 + sourceRecord.launchedFromUid); 3531 } 3532 } 3533 targetUid = sourceRecord.launchedFromUid; 3534 targetPackage = sourceRecord.launchedFromPackage; 3535 } 3536 3537 // TODO: Switch to user app stacks here. 3538 try { 3539 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3540 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3541 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3542 return ret; 3543 } catch (SecurityException e) { 3544 // XXX need to figure out how to propagate to original app. 3545 // A SecurityException here is generally actually a fault of the original 3546 // calling activity (such as a fairly granting permissions), so propagate it 3547 // back to them. 3548 /* 3549 StringBuilder msg = new StringBuilder(); 3550 msg.append("While launching"); 3551 msg.append(intent.toString()); 3552 msg.append(": "); 3553 msg.append(e.getMessage()); 3554 */ 3555 throw e; 3556 } 3557 } 3558 3559 @Override 3560 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3561 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3562 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3563 enforceNotIsolatedCaller("startActivityAndWait"); 3564 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3565 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3566 WaitResult res = new WaitResult(); 3567 // TODO: Switch to user app stacks here. 3568 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3569 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3570 options, userId, null, null); 3571 return res; 3572 } 3573 3574 @Override 3575 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3576 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3577 int startFlags, Configuration config, Bundle options, int userId) { 3578 enforceNotIsolatedCaller("startActivityWithConfig"); 3579 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3580 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3581 // TODO: Switch to user app stacks here. 3582 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3583 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3584 null, null, config, options, userId, null, null); 3585 return ret; 3586 } 3587 3588 @Override 3589 public int startActivityIntentSender(IApplicationThread caller, 3590 IntentSender intent, Intent fillInIntent, String resolvedType, 3591 IBinder resultTo, String resultWho, int requestCode, 3592 int flagsMask, int flagsValues, Bundle options) { 3593 enforceNotIsolatedCaller("startActivityIntentSender"); 3594 // Refuse possible leaked file descriptors 3595 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3596 throw new IllegalArgumentException("File descriptors passed in Intent"); 3597 } 3598 3599 IIntentSender sender = intent.getTarget(); 3600 if (!(sender instanceof PendingIntentRecord)) { 3601 throw new IllegalArgumentException("Bad PendingIntent object"); 3602 } 3603 3604 PendingIntentRecord pir = (PendingIntentRecord)sender; 3605 3606 synchronized (this) { 3607 // If this is coming from the currently resumed activity, it is 3608 // effectively saying that app switches are allowed at this point. 3609 final ActivityStack stack = getFocusedStack(); 3610 if (stack.mResumedActivity != null && 3611 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3612 mAppSwitchesAllowedTime = 0; 3613 } 3614 } 3615 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3616 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3617 return ret; 3618 } 3619 3620 @Override 3621 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3622 Intent intent, String resolvedType, IVoiceInteractionSession session, 3623 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3624 Bundle options, int userId) { 3625 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3626 != PackageManager.PERMISSION_GRANTED) { 3627 String msg = "Permission Denial: startVoiceActivity() from pid=" 3628 + Binder.getCallingPid() 3629 + ", uid=" + Binder.getCallingUid() 3630 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3631 Slog.w(TAG, msg); 3632 throw new SecurityException(msg); 3633 } 3634 if (session == null || interactor == null) { 3635 throw new NullPointerException("null session or interactor"); 3636 } 3637 userId = handleIncomingUser(callingPid, callingUid, userId, 3638 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3639 // TODO: Switch to user app stacks here. 3640 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3641 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3642 null, options, userId, null, null); 3643 } 3644 3645 @Override 3646 public boolean startNextMatchingActivity(IBinder callingActivity, 3647 Intent intent, Bundle options) { 3648 // Refuse possible leaked file descriptors 3649 if (intent != null && intent.hasFileDescriptors() == true) { 3650 throw new IllegalArgumentException("File descriptors passed in Intent"); 3651 } 3652 3653 synchronized (this) { 3654 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3655 if (r == null) { 3656 ActivityOptions.abort(options); 3657 return false; 3658 } 3659 if (r.app == null || r.app.thread == null) { 3660 // The caller is not running... d'oh! 3661 ActivityOptions.abort(options); 3662 return false; 3663 } 3664 intent = new Intent(intent); 3665 // The caller is not allowed to change the data. 3666 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3667 // And we are resetting to find the next component... 3668 intent.setComponent(null); 3669 3670 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3671 3672 ActivityInfo aInfo = null; 3673 try { 3674 List<ResolveInfo> resolves = 3675 AppGlobals.getPackageManager().queryIntentActivities( 3676 intent, r.resolvedType, 3677 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3678 UserHandle.getCallingUserId()); 3679 3680 // Look for the original activity in the list... 3681 final int N = resolves != null ? resolves.size() : 0; 3682 for (int i=0; i<N; i++) { 3683 ResolveInfo rInfo = resolves.get(i); 3684 if (rInfo.activityInfo.packageName.equals(r.packageName) 3685 && rInfo.activityInfo.name.equals(r.info.name)) { 3686 // We found the current one... the next matching is 3687 // after it. 3688 i++; 3689 if (i<N) { 3690 aInfo = resolves.get(i).activityInfo; 3691 } 3692 if (debug) { 3693 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3694 + "/" + r.info.name); 3695 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3696 + "/" + aInfo.name); 3697 } 3698 break; 3699 } 3700 } 3701 } catch (RemoteException e) { 3702 } 3703 3704 if (aInfo == null) { 3705 // Nobody who is next! 3706 ActivityOptions.abort(options); 3707 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3708 return false; 3709 } 3710 3711 intent.setComponent(new ComponentName( 3712 aInfo.applicationInfo.packageName, aInfo.name)); 3713 intent.setFlags(intent.getFlags()&~( 3714 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3715 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3716 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3717 Intent.FLAG_ACTIVITY_NEW_TASK)); 3718 3719 // Okay now we need to start the new activity, replacing the 3720 // currently running activity. This is a little tricky because 3721 // we want to start the new one as if the current one is finished, 3722 // but not finish the current one first so that there is no flicker. 3723 // And thus... 3724 final boolean wasFinishing = r.finishing; 3725 r.finishing = true; 3726 3727 // Propagate reply information over to the new activity. 3728 final ActivityRecord resultTo = r.resultTo; 3729 final String resultWho = r.resultWho; 3730 final int requestCode = r.requestCode; 3731 r.resultTo = null; 3732 if (resultTo != null) { 3733 resultTo.removeResultsLocked(r, resultWho, requestCode); 3734 } 3735 3736 final long origId = Binder.clearCallingIdentity(); 3737 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3738 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3739 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3740 options, false, null, null, null); 3741 Binder.restoreCallingIdentity(origId); 3742 3743 r.finishing = wasFinishing; 3744 if (res != ActivityManager.START_SUCCESS) { 3745 return false; 3746 } 3747 return true; 3748 } 3749 } 3750 3751 @Override 3752 public final int startActivityFromRecents(int taskId, Bundle options) { 3753 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3754 String msg = "Permission Denial: startActivityFromRecents called without " + 3755 START_TASKS_FROM_RECENTS; 3756 Slog.w(TAG, msg); 3757 throw new SecurityException(msg); 3758 } 3759 return startActivityFromRecentsInner(taskId, options); 3760 } 3761 3762 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3763 final TaskRecord task; 3764 final int callingUid; 3765 final String callingPackage; 3766 final Intent intent; 3767 final int userId; 3768 synchronized (this) { 3769 task = recentTaskForIdLocked(taskId); 3770 if (task == null) { 3771 throw new IllegalArgumentException("Task " + taskId + " not found."); 3772 } 3773 callingUid = task.mCallingUid; 3774 callingPackage = task.mCallingPackage; 3775 intent = task.intent; 3776 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3777 userId = task.userId; 3778 } 3779 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3780 options, userId, null, task); 3781 } 3782 3783 final int startActivityInPackage(int uid, String callingPackage, 3784 Intent intent, String resolvedType, IBinder resultTo, 3785 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3786 IActivityContainer container, TaskRecord inTask) { 3787 3788 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3789 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3790 3791 // TODO: Switch to user app stacks here. 3792 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3793 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3794 null, null, null, options, userId, container, inTask); 3795 return ret; 3796 } 3797 3798 @Override 3799 public final int startActivities(IApplicationThread caller, String callingPackage, 3800 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3801 int userId) { 3802 enforceNotIsolatedCaller("startActivities"); 3803 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3804 false, ALLOW_FULL_ONLY, "startActivity", null); 3805 // TODO: Switch to user app stacks here. 3806 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3807 resolvedTypes, resultTo, options, userId); 3808 return ret; 3809 } 3810 3811 final int startActivitiesInPackage(int uid, String callingPackage, 3812 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3813 Bundle options, int userId) { 3814 3815 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3816 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3817 // TODO: Switch to user app stacks here. 3818 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3819 resultTo, options, userId); 3820 return ret; 3821 } 3822 3823 //explicitly remove thd old information in mRecentTasks when removing existing user. 3824 private void removeRecentTasksForUserLocked(int userId) { 3825 if(userId <= 0) { 3826 Slog.i(TAG, "Can't remove recent task on user " + userId); 3827 return; 3828 } 3829 3830 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3831 TaskRecord tr = mRecentTasks.get(i); 3832 if (tr.userId == userId) { 3833 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3834 + " when finishing user" + userId); 3835 mRecentTasks.remove(i); 3836 tr.removedFromRecents(mTaskPersister); 3837 } 3838 } 3839 3840 // Remove tasks from persistent storage. 3841 mTaskPersister.wakeup(null, true); 3842 } 3843 3844 // Sort by taskId 3845 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() { 3846 @Override 3847 public int compare(TaskRecord lhs, TaskRecord rhs) { 3848 return rhs.taskId - lhs.taskId; 3849 } 3850 }; 3851 3852 // Extract the affiliates of the chain containing mRecentTasks[start]. 3853 private int processNextAffiliateChain(int start) { 3854 final TaskRecord startTask = mRecentTasks.get(start); 3855 final int affiliateId = startTask.mAffiliatedTaskId; 3856 3857 // Quick identification of isolated tasks. I.e. those not launched behind. 3858 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null && 3859 startTask.mNextAffiliate == null) { 3860 // There is still a slim chance that there are other tasks that point to this task 3861 // and that the chain is so messed up that this task no longer points to them but 3862 // the gain of this optimization outweighs the risk. 3863 startTask.inRecents = true; 3864 return start + 1; 3865 } 3866 3867 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents. 3868 mTmpRecents.clear(); 3869 for (int i = mRecentTasks.size() - 1; i >= start; --i) { 3870 final TaskRecord task = mRecentTasks.get(i); 3871 if (task.mAffiliatedTaskId == affiliateId) { 3872 mRecentTasks.remove(i); 3873 mTmpRecents.add(task); 3874 } 3875 } 3876 3877 // Sort them all by taskId. That is the order they were create in and that order will 3878 // always be correct. 3879 Collections.sort(mTmpRecents, mTaskRecordComparator); 3880 3881 // Go through and fix up the linked list. 3882 // The first one is the end of the chain and has no next. 3883 final TaskRecord first = mTmpRecents.get(0); 3884 first.inRecents = true; 3885 if (first.mNextAffiliate != null) { 3886 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate); 3887 first.setNextAffiliate(null); 3888 mTaskPersister.wakeup(first, false); 3889 } 3890 // Everything in the middle is doubly linked from next to prev. 3891 final int tmpSize = mTmpRecents.size(); 3892 for (int i = 0; i < tmpSize - 1; ++i) { 3893 final TaskRecord next = mTmpRecents.get(i); 3894 final TaskRecord prev = mTmpRecents.get(i + 1); 3895 if (next.mPrevAffiliate != prev) { 3896 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate + 3897 " setting prev=" + prev); 3898 next.setPrevAffiliate(prev); 3899 mTaskPersister.wakeup(next, false); 3900 } 3901 if (prev.mNextAffiliate != next) { 3902 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate + 3903 " setting next=" + next); 3904 prev.setNextAffiliate(next); 3905 mTaskPersister.wakeup(prev, false); 3906 } 3907 prev.inRecents = true; 3908 } 3909 // The last one is the beginning of the list and has no prev. 3910 final TaskRecord last = mTmpRecents.get(tmpSize - 1); 3911 if (last.mPrevAffiliate != null) { 3912 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate); 3913 last.setPrevAffiliate(null); 3914 mTaskPersister.wakeup(last, false); 3915 } 3916 3917 // Insert the group back into mRecentTasks at start. 3918 mRecentTasks.addAll(start, mTmpRecents); 3919 3920 // Let the caller know where we left off. 3921 return start + tmpSize; 3922 } 3923 3924 /** 3925 * Update the recent tasks lists: make sure tasks should still be here (their 3926 * applications / activities still exist), update their availability, fixup ordering 3927 * of affiliations. 3928 */ 3929 void cleanupRecentTasksLocked(int userId) { 3930 if (mRecentTasks == null) { 3931 // Happens when called from the packagemanager broadcast before boot. 3932 return; 3933 } 3934 3935 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3936 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3937 final IPackageManager pm = AppGlobals.getPackageManager(); 3938 final ActivityInfo dummyAct = new ActivityInfo(); 3939 final ApplicationInfo dummyApp = new ApplicationInfo(); 3940 3941 int N = mRecentTasks.size(); 3942 3943 int[] users = userId == UserHandle.USER_ALL 3944 ? getUsersLocked() : new int[] { userId }; 3945 for (int user : users) { 3946 for (int i = 0; i < N; i++) { 3947 TaskRecord task = mRecentTasks.get(i); 3948 if (task.userId != user) { 3949 // Only look at tasks for the user ID of interest. 3950 continue; 3951 } 3952 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3953 // This situation is broken, and we should just get rid of it now. 3954 mRecentTasks.remove(i); 3955 task.removedFromRecents(mTaskPersister); 3956 i--; 3957 N--; 3958 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3959 continue; 3960 } 3961 // Check whether this activity is currently available. 3962 if (task.realActivity != null) { 3963 ActivityInfo ai = availActCache.get(task.realActivity); 3964 if (ai == null) { 3965 try { 3966 ai = pm.getActivityInfo(task.realActivity, 3967 PackageManager.GET_UNINSTALLED_PACKAGES 3968 | PackageManager.GET_DISABLED_COMPONENTS, user); 3969 } catch (RemoteException e) { 3970 // Will never happen. 3971 continue; 3972 } 3973 if (ai == null) { 3974 ai = dummyAct; 3975 } 3976 availActCache.put(task.realActivity, ai); 3977 } 3978 if (ai == dummyAct) { 3979 // This could be either because the activity no longer exists, or the 3980 // app is temporarily gone. For the former we want to remove the recents 3981 // entry; for the latter we want to mark it as unavailable. 3982 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3983 if (app == null) { 3984 try { 3985 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3986 PackageManager.GET_UNINSTALLED_PACKAGES 3987 | PackageManager.GET_DISABLED_COMPONENTS, user); 3988 } catch (RemoteException e) { 3989 // Will never happen. 3990 continue; 3991 } 3992 if (app == null) { 3993 app = dummyApp; 3994 } 3995 availAppCache.put(task.realActivity.getPackageName(), app); 3996 } 3997 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3998 // Doesn't exist any more! Good-bye. 3999 mRecentTasks.remove(i); 4000 task.removedFromRecents(mTaskPersister); 4001 i--; 4002 N--; 4003 Slog.w(TAG, "Removing no longer valid recent: " + task); 4004 continue; 4005 } else { 4006 // Otherwise just not available for now. 4007 if (task.isAvailable) { 4008 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4009 + task); 4010 } 4011 task.isAvailable = false; 4012 } 4013 } else { 4014 if (!ai.enabled || !ai.applicationInfo.enabled 4015 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 4016 if (task.isAvailable) { 4017 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 4018 + task + " (enabled=" + ai.enabled + "/" 4019 + ai.applicationInfo.enabled + " flags=" 4020 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 4021 } 4022 task.isAvailable = false; 4023 } else { 4024 if (!task.isAvailable) { 4025 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 4026 + task); 4027 } 4028 task.isAvailable = true; 4029 } 4030 } 4031 } 4032 } 4033 } 4034 4035 // Verify the affiliate chain for each task. 4036 for (int i = 0; i < N; i = processNextAffiliateChain(i)) { 4037 } 4038 4039 mTmpRecents.clear(); 4040 // mRecentTasks is now in sorted, affiliated order. 4041 } 4042 4043 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4044 int N = mRecentTasks.size(); 4045 TaskRecord top = task; 4046 int topIndex = taskIndex; 4047 while (top.mNextAffiliate != null && topIndex > 0) { 4048 top = top.mNextAffiliate; 4049 topIndex--; 4050 } 4051 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4052 + topIndex + " from intial " + taskIndex); 4053 // Find the end of the chain, doing a sanity check along the way. 4054 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4055 int endIndex = topIndex; 4056 TaskRecord prev = top; 4057 while (endIndex < N) { 4058 TaskRecord cur = mRecentTasks.get(endIndex); 4059 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4060 + endIndex + " " + cur); 4061 if (cur == top) { 4062 // Verify start of the chain. 4063 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4064 Slog.wtf(TAG, "Bad chain @" + endIndex 4065 + ": first task has next affiliate: " + prev); 4066 sane = false; 4067 break; 4068 } 4069 } else { 4070 // Verify middle of the chain's next points back to the one before. 4071 if (cur.mNextAffiliate != prev 4072 || cur.mNextAffiliateTaskId != prev.taskId) { 4073 Slog.wtf(TAG, "Bad chain @" + endIndex 4074 + ": middle task " + cur + " @" + endIndex 4075 + " has bad next affiliate " 4076 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4077 + ", expected " + prev); 4078 sane = false; 4079 break; 4080 } 4081 } 4082 if (cur.mPrevAffiliateTaskId == -1) { 4083 // Chain ends here. 4084 if (cur.mPrevAffiliate != null) { 4085 Slog.wtf(TAG, "Bad chain @" + endIndex 4086 + ": last task " + cur + " has previous affiliate " 4087 + cur.mPrevAffiliate); 4088 sane = false; 4089 } 4090 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4091 break; 4092 } else { 4093 // Verify middle of the chain's prev points to a valid item. 4094 if (cur.mPrevAffiliate == null) { 4095 Slog.wtf(TAG, "Bad chain @" + endIndex 4096 + ": task " + cur + " has previous affiliate " 4097 + cur.mPrevAffiliate + " but should be id " 4098 + cur.mPrevAffiliate); 4099 sane = false; 4100 break; 4101 } 4102 } 4103 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4104 Slog.wtf(TAG, "Bad chain @" + endIndex 4105 + ": task " + cur + " has affiliated id " 4106 + cur.mAffiliatedTaskId + " but should be " 4107 + task.mAffiliatedTaskId); 4108 sane = false; 4109 break; 4110 } 4111 prev = cur; 4112 endIndex++; 4113 if (endIndex >= N) { 4114 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4115 + ": last task " + prev); 4116 sane = false; 4117 break; 4118 } 4119 } 4120 if (sane) { 4121 if (endIndex < taskIndex) { 4122 Slog.wtf(TAG, "Bad chain @" + endIndex 4123 + ": did not extend to task " + task + " @" + taskIndex); 4124 sane = false; 4125 } 4126 } 4127 if (sane) { 4128 // All looks good, we can just move all of the affiliated tasks 4129 // to the top. 4130 for (int i=topIndex; i<=endIndex; i++) { 4131 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4132 + " from " + i + " to " + (i-topIndex)); 4133 TaskRecord cur = mRecentTasks.remove(i); 4134 mRecentTasks.add(i-topIndex, cur); 4135 } 4136 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4137 + " to " + endIndex); 4138 return true; 4139 } 4140 4141 // Whoops, couldn't do it. 4142 return false; 4143 } 4144 4145 final void addRecentTaskLocked(TaskRecord task) { 4146 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4147 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4148 4149 int N = mRecentTasks.size(); 4150 // Quick case: check if the top-most recent task is the same. 4151 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4152 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4153 return; 4154 } 4155 // Another quick case: check if this is part of a set of affiliated 4156 // tasks that are at the top. 4157 if (isAffiliated && N > 0 && task.inRecents 4158 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4159 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4160 + " at top when adding " + task); 4161 return; 4162 } 4163 // Another quick case: never add voice sessions. 4164 if (task.voiceSession != null) { 4165 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4166 return; 4167 } 4168 4169 boolean needAffiliationFix = false; 4170 4171 // Slightly less quick case: the task is already in recents, so all we need 4172 // to do is move it. 4173 if (task.inRecents) { 4174 int taskIndex = mRecentTasks.indexOf(task); 4175 if (taskIndex >= 0) { 4176 if (!isAffiliated) { 4177 // Simple case: this is not an affiliated task, so we just move it to the front. 4178 mRecentTasks.remove(taskIndex); 4179 mRecentTasks.add(0, task); 4180 notifyTaskPersisterLocked(task, false); 4181 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4182 + " from " + taskIndex); 4183 return; 4184 } else { 4185 // More complicated: need to keep all affiliated tasks together. 4186 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4187 // All went well. 4188 return; 4189 } 4190 4191 // Uh oh... something bad in the affiliation chain, try to rebuild 4192 // everything and then go through our general path of adding a new task. 4193 needAffiliationFix = true; 4194 } 4195 } else { 4196 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4197 needAffiliationFix = true; 4198 } 4199 } 4200 4201 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4202 trimRecentsForTask(task, true); 4203 4204 N = mRecentTasks.size(); 4205 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4206 final TaskRecord tr = mRecentTasks.remove(N - 1); 4207 tr.removedFromRecents(mTaskPersister); 4208 N--; 4209 } 4210 task.inRecents = true; 4211 if (!isAffiliated || needAffiliationFix) { 4212 // If this is a simple non-affiliated task, or we had some failure trying to 4213 // handle it as part of an affilated task, then just place it at the top. 4214 mRecentTasks.add(0, task); 4215 } else if (isAffiliated) { 4216 // If this is a new affiliated task, then move all of the affiliated tasks 4217 // to the front and insert this new one. 4218 TaskRecord other = task.mNextAffiliate; 4219 if (other == null) { 4220 other = task.mPrevAffiliate; 4221 } 4222 if (other != null) { 4223 int otherIndex = mRecentTasks.indexOf(other); 4224 if (otherIndex >= 0) { 4225 // Insert new task at appropriate location. 4226 int taskIndex; 4227 if (other == task.mNextAffiliate) { 4228 // We found the index of our next affiliation, which is who is 4229 // before us in the list, so add after that point. 4230 taskIndex = otherIndex+1; 4231 } else { 4232 // We found the index of our previous affiliation, which is who is 4233 // after us in the list, so add at their position. 4234 taskIndex = otherIndex; 4235 } 4236 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4237 + taskIndex + ": " + task); 4238 mRecentTasks.add(taskIndex, task); 4239 4240 // Now move everything to the front. 4241 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4242 // All went well. 4243 return; 4244 } 4245 4246 // Uh oh... something bad in the affiliation chain, try to rebuild 4247 // everything and then go through our general path of adding a new task. 4248 needAffiliationFix = true; 4249 } else { 4250 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4251 + other); 4252 needAffiliationFix = true; 4253 } 4254 } else { 4255 if (DEBUG_RECENTS) Slog.d(TAG, 4256 "addRecent: adding affiliated task without next/prev:" + task); 4257 needAffiliationFix = true; 4258 } 4259 } 4260 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4261 4262 if (needAffiliationFix) { 4263 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4264 cleanupRecentTasksLocked(task.userId); 4265 } 4266 } 4267 4268 /** 4269 * If needed, remove oldest existing entries in recents that are for the same kind 4270 * of task as the given one. 4271 */ 4272 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4273 int N = mRecentTasks.size(); 4274 final Intent intent = task.intent; 4275 final boolean document = intent != null && intent.isDocument(); 4276 4277 int maxRecents = task.maxRecents - 1; 4278 for (int i=0; i<N; i++) { 4279 final TaskRecord tr = mRecentTasks.get(i); 4280 if (task != tr) { 4281 if (task.userId != tr.userId) { 4282 continue; 4283 } 4284 if (i > MAX_RECENT_BITMAPS) { 4285 tr.freeLastThumbnail(); 4286 } 4287 final Intent trIntent = tr.intent; 4288 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4289 (intent == null || !intent.filterEquals(trIntent))) { 4290 continue; 4291 } 4292 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4293 if (document && trIsDocument) { 4294 // These are the same document activity (not necessarily the same doc). 4295 if (maxRecents > 0) { 4296 --maxRecents; 4297 continue; 4298 } 4299 // Hit the maximum number of documents for this task. Fall through 4300 // and remove this document from recents. 4301 } else if (document || trIsDocument) { 4302 // Only one of these is a document. Not the droid we're looking for. 4303 continue; 4304 } 4305 } 4306 4307 if (!doTrim) { 4308 // If the caller is not actually asking for a trim, just tell them we reached 4309 // a point where the trim would happen. 4310 return i; 4311 } 4312 4313 // Either task and tr are the same or, their affinities match or their intents match 4314 // and neither of them is a document, or they are documents using the same activity 4315 // and their maxRecents has been reached. 4316 tr.disposeThumbnail(); 4317 mRecentTasks.remove(i); 4318 if (task != tr) { 4319 tr.removedFromRecents(mTaskPersister); 4320 } 4321 i--; 4322 N--; 4323 if (task.intent == null) { 4324 // If the new recent task we are adding is not fully 4325 // specified, then replace it with the existing recent task. 4326 task = tr; 4327 } 4328 notifyTaskPersisterLocked(tr, false); 4329 } 4330 4331 return -1; 4332 } 4333 4334 @Override 4335 public void reportActivityFullyDrawn(IBinder token) { 4336 synchronized (this) { 4337 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4338 if (r == null) { 4339 return; 4340 } 4341 r.reportFullyDrawnLocked(); 4342 } 4343 } 4344 4345 @Override 4346 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4347 synchronized (this) { 4348 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4349 if (r == null) { 4350 return; 4351 } 4352 final long origId = Binder.clearCallingIdentity(); 4353 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4354 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4355 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4356 if (config != null) { 4357 r.frozenBeforeDestroy = true; 4358 if (!updateConfigurationLocked(config, r, false, false)) { 4359 mStackSupervisor.resumeTopActivitiesLocked(); 4360 } 4361 } 4362 Binder.restoreCallingIdentity(origId); 4363 } 4364 } 4365 4366 @Override 4367 public int getRequestedOrientation(IBinder token) { 4368 synchronized (this) { 4369 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4370 if (r == null) { 4371 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4372 } 4373 return mWindowManager.getAppOrientation(r.appToken); 4374 } 4375 } 4376 4377 /** 4378 * This is the internal entry point for handling Activity.finish(). 4379 * 4380 * @param token The Binder token referencing the Activity we want to finish. 4381 * @param resultCode Result code, if any, from this Activity. 4382 * @param resultData Result data (Intent), if any, from this Activity. 4383 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4384 * the root Activity in the task. 4385 * 4386 * @return Returns true if the activity successfully finished, or false if it is still running. 4387 */ 4388 @Override 4389 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4390 boolean finishTask) { 4391 // Refuse possible leaked file descriptors 4392 if (resultData != null && resultData.hasFileDescriptors() == true) { 4393 throw new IllegalArgumentException("File descriptors passed in Intent"); 4394 } 4395 4396 synchronized(this) { 4397 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4398 if (r == null) { 4399 return true; 4400 } 4401 // Keep track of the root activity of the task before we finish it 4402 TaskRecord tr = r.task; 4403 ActivityRecord rootR = tr.getRootActivity(); 4404 // Do not allow task to finish in Lock Task mode. 4405 if (tr == mStackSupervisor.mLockTaskModeTask) { 4406 if (rootR == r) { 4407 mStackSupervisor.showLockTaskToast(); 4408 return false; 4409 } 4410 } 4411 if (mController != null) { 4412 // Find the first activity that is not finishing. 4413 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4414 if (next != null) { 4415 // ask watcher if this is allowed 4416 boolean resumeOK = true; 4417 try { 4418 resumeOK = mController.activityResuming(next.packageName); 4419 } catch (RemoteException e) { 4420 mController = null; 4421 Watchdog.getInstance().setActivityController(null); 4422 } 4423 4424 if (!resumeOK) { 4425 return false; 4426 } 4427 } 4428 } 4429 final long origId = Binder.clearCallingIdentity(); 4430 try { 4431 boolean res; 4432 if (finishTask && r == rootR) { 4433 // If requested, remove the task that is associated to this activity only if it 4434 // was the root activity in the task. The result code and data is ignored because 4435 // we don't support returning them across task boundaries. 4436 res = removeTaskByIdLocked(tr.taskId, 0); 4437 } else { 4438 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4439 resultData, "app-request", true); 4440 } 4441 return res; 4442 } finally { 4443 Binder.restoreCallingIdentity(origId); 4444 } 4445 } 4446 } 4447 4448 @Override 4449 public final void finishHeavyWeightApp() { 4450 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4451 != PackageManager.PERMISSION_GRANTED) { 4452 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4453 + Binder.getCallingPid() 4454 + ", uid=" + Binder.getCallingUid() 4455 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4456 Slog.w(TAG, msg); 4457 throw new SecurityException(msg); 4458 } 4459 4460 synchronized(this) { 4461 if (mHeavyWeightProcess == null) { 4462 return; 4463 } 4464 4465 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4466 mHeavyWeightProcess.activities); 4467 for (int i=0; i<activities.size(); i++) { 4468 ActivityRecord r = activities.get(i); 4469 if (!r.finishing) { 4470 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4471 null, "finish-heavy", true); 4472 } 4473 } 4474 4475 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4476 mHeavyWeightProcess.userId, 0)); 4477 mHeavyWeightProcess = null; 4478 } 4479 } 4480 4481 @Override 4482 public void crashApplication(int uid, int initialPid, String packageName, 4483 String message) { 4484 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4485 != PackageManager.PERMISSION_GRANTED) { 4486 String msg = "Permission Denial: crashApplication() from pid=" 4487 + Binder.getCallingPid() 4488 + ", uid=" + Binder.getCallingUid() 4489 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4490 Slog.w(TAG, msg); 4491 throw new SecurityException(msg); 4492 } 4493 4494 synchronized(this) { 4495 ProcessRecord proc = null; 4496 4497 // Figure out which process to kill. We don't trust that initialPid 4498 // still has any relation to current pids, so must scan through the 4499 // list. 4500 synchronized (mPidsSelfLocked) { 4501 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4502 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4503 if (p.uid != uid) { 4504 continue; 4505 } 4506 if (p.pid == initialPid) { 4507 proc = p; 4508 break; 4509 } 4510 if (p.pkgList.containsKey(packageName)) { 4511 proc = p; 4512 } 4513 } 4514 } 4515 4516 if (proc == null) { 4517 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4518 + " initialPid=" + initialPid 4519 + " packageName=" + packageName); 4520 return; 4521 } 4522 4523 if (proc.thread != null) { 4524 if (proc.pid == Process.myPid()) { 4525 Log.w(TAG, "crashApplication: trying to crash self!"); 4526 return; 4527 } 4528 long ident = Binder.clearCallingIdentity(); 4529 try { 4530 proc.thread.scheduleCrash(message); 4531 } catch (RemoteException e) { 4532 } 4533 Binder.restoreCallingIdentity(ident); 4534 } 4535 } 4536 } 4537 4538 @Override 4539 public final void finishSubActivity(IBinder token, String resultWho, 4540 int requestCode) { 4541 synchronized(this) { 4542 final long origId = Binder.clearCallingIdentity(); 4543 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4544 if (r != null) { 4545 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4546 } 4547 Binder.restoreCallingIdentity(origId); 4548 } 4549 } 4550 4551 @Override 4552 public boolean finishActivityAffinity(IBinder token) { 4553 synchronized(this) { 4554 final long origId = Binder.clearCallingIdentity(); 4555 try { 4556 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4557 4558 ActivityRecord rootR = r.task.getRootActivity(); 4559 // Do not allow task to finish in Lock Task mode. 4560 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4561 if (rootR == r) { 4562 mStackSupervisor.showLockTaskToast(); 4563 return false; 4564 } 4565 } 4566 boolean res = false; 4567 if (r != null) { 4568 res = r.task.stack.finishActivityAffinityLocked(r); 4569 } 4570 return res; 4571 } finally { 4572 Binder.restoreCallingIdentity(origId); 4573 } 4574 } 4575 } 4576 4577 @Override 4578 public void finishVoiceTask(IVoiceInteractionSession session) { 4579 synchronized(this) { 4580 final long origId = Binder.clearCallingIdentity(); 4581 try { 4582 mStackSupervisor.finishVoiceTask(session); 4583 } finally { 4584 Binder.restoreCallingIdentity(origId); 4585 } 4586 } 4587 4588 } 4589 4590 @Override 4591 public boolean releaseActivityInstance(IBinder token) { 4592 synchronized(this) { 4593 final long origId = Binder.clearCallingIdentity(); 4594 try { 4595 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4596 if (r.task == null || r.task.stack == null) { 4597 return false; 4598 } 4599 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4600 } finally { 4601 Binder.restoreCallingIdentity(origId); 4602 } 4603 } 4604 } 4605 4606 @Override 4607 public void releaseSomeActivities(IApplicationThread appInt) { 4608 synchronized(this) { 4609 final long origId = Binder.clearCallingIdentity(); 4610 try { 4611 ProcessRecord app = getRecordForAppLocked(appInt); 4612 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4613 } finally { 4614 Binder.restoreCallingIdentity(origId); 4615 } 4616 } 4617 } 4618 4619 @Override 4620 public boolean willActivityBeVisible(IBinder token) { 4621 synchronized(this) { 4622 ActivityStack stack = ActivityRecord.getStackLocked(token); 4623 if (stack != null) { 4624 return stack.willActivityBeVisibleLocked(token); 4625 } 4626 return false; 4627 } 4628 } 4629 4630 @Override 4631 public void overridePendingTransition(IBinder token, String packageName, 4632 int enterAnim, int exitAnim) { 4633 synchronized(this) { 4634 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4635 if (self == null) { 4636 return; 4637 } 4638 4639 final long origId = Binder.clearCallingIdentity(); 4640 4641 if (self.state == ActivityState.RESUMED 4642 || self.state == ActivityState.PAUSING) { 4643 mWindowManager.overridePendingAppTransition(packageName, 4644 enterAnim, exitAnim, null); 4645 } 4646 4647 Binder.restoreCallingIdentity(origId); 4648 } 4649 } 4650 4651 /** 4652 * Main function for removing an existing process from the activity manager 4653 * as a result of that process going away. Clears out all connections 4654 * to the process. 4655 */ 4656 private final void handleAppDiedLocked(ProcessRecord app, 4657 boolean restarting, boolean allowRestart) { 4658 int pid = app.pid; 4659 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4660 if (!restarting) { 4661 removeLruProcessLocked(app); 4662 if (pid > 0) { 4663 ProcessList.remove(pid); 4664 } 4665 } 4666 4667 if (mProfileProc == app) { 4668 clearProfilerLocked(); 4669 } 4670 4671 // Remove this application's activities from active lists. 4672 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4673 4674 app.activities.clear(); 4675 4676 if (app.instrumentationClass != null) { 4677 Slog.w(TAG, "Crash of app " + app.processName 4678 + " running instrumentation " + app.instrumentationClass); 4679 Bundle info = new Bundle(); 4680 info.putString("shortMsg", "Process crashed."); 4681 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4682 } 4683 4684 if (!restarting) { 4685 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4686 // If there was nothing to resume, and we are not already 4687 // restarting this process, but there is a visible activity that 4688 // is hosted by the process... then make sure all visible 4689 // activities are running, taking care of restarting this 4690 // process. 4691 if (hasVisibleActivities) { 4692 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4693 } 4694 } 4695 } 4696 } 4697 4698 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4699 IBinder threadBinder = thread.asBinder(); 4700 // Find the application record. 4701 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4702 ProcessRecord rec = mLruProcesses.get(i); 4703 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4704 return i; 4705 } 4706 } 4707 return -1; 4708 } 4709 4710 final ProcessRecord getRecordForAppLocked( 4711 IApplicationThread thread) { 4712 if (thread == null) { 4713 return null; 4714 } 4715 4716 int appIndex = getLRURecordIndexForAppLocked(thread); 4717 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4718 } 4719 4720 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4721 // If there are no longer any background processes running, 4722 // and the app that died was not running instrumentation, 4723 // then tell everyone we are now low on memory. 4724 boolean haveBg = false; 4725 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4726 ProcessRecord rec = mLruProcesses.get(i); 4727 if (rec.thread != null 4728 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4729 haveBg = true; 4730 break; 4731 } 4732 } 4733 4734 if (!haveBg) { 4735 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4736 if (doReport) { 4737 long now = SystemClock.uptimeMillis(); 4738 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4739 doReport = false; 4740 } else { 4741 mLastMemUsageReportTime = now; 4742 } 4743 } 4744 final ArrayList<ProcessMemInfo> memInfos 4745 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4746 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4747 long now = SystemClock.uptimeMillis(); 4748 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4749 ProcessRecord rec = mLruProcesses.get(i); 4750 if (rec == dyingProc || rec.thread == null) { 4751 continue; 4752 } 4753 if (doReport) { 4754 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4755 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4756 } 4757 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4758 // The low memory report is overriding any current 4759 // state for a GC request. Make sure to do 4760 // heavy/important/visible/foreground processes first. 4761 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4762 rec.lastRequestedGc = 0; 4763 } else { 4764 rec.lastRequestedGc = rec.lastLowMemory; 4765 } 4766 rec.reportLowMemory = true; 4767 rec.lastLowMemory = now; 4768 mProcessesToGc.remove(rec); 4769 addProcessToGcListLocked(rec); 4770 } 4771 } 4772 if (doReport) { 4773 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4774 mHandler.sendMessage(msg); 4775 } 4776 scheduleAppGcsLocked(); 4777 } 4778 } 4779 4780 final void appDiedLocked(ProcessRecord app) { 4781 appDiedLocked(app, app.pid, app.thread); 4782 } 4783 4784 final void appDiedLocked(ProcessRecord app, int pid, 4785 IApplicationThread thread) { 4786 4787 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4788 synchronized (stats) { 4789 stats.noteProcessDiedLocked(app.info.uid, pid); 4790 } 4791 4792 Process.killProcessGroup(app.info.uid, pid); 4793 4794 // Clean up already done if the process has been re-started. 4795 if (app.pid == pid && app.thread != null && 4796 app.thread.asBinder() == thread.asBinder()) { 4797 boolean doLowMem = app.instrumentationClass == null; 4798 boolean doOomAdj = doLowMem; 4799 if (!app.killedByAm) { 4800 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4801 + ") has died."); 4802 mAllowLowerMemLevel = true; 4803 } else { 4804 // Note that we always want to do oom adj to update our state with the 4805 // new number of procs. 4806 mAllowLowerMemLevel = false; 4807 doLowMem = false; 4808 } 4809 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4810 if (DEBUG_CLEANUP) Slog.v( 4811 TAG, "Dying app: " + app + ", pid: " + pid 4812 + ", thread: " + thread.asBinder()); 4813 handleAppDiedLocked(app, false, true); 4814 4815 if (doOomAdj) { 4816 updateOomAdjLocked(); 4817 } 4818 if (doLowMem) { 4819 doLowMemReportIfNeededLocked(app); 4820 } 4821 } else if (app.pid != pid) { 4822 // A new process has already been started. 4823 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4824 + ") has died and restarted (pid " + app.pid + ")."); 4825 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4826 } else if (DEBUG_PROCESSES) { 4827 Slog.d(TAG, "Received spurious death notification for thread " 4828 + thread.asBinder()); 4829 } 4830 } 4831 4832 /** 4833 * If a stack trace dump file is configured, dump process stack traces. 4834 * @param clearTraces causes the dump file to be erased prior to the new 4835 * traces being written, if true; when false, the new traces will be 4836 * appended to any existing file content. 4837 * @param firstPids of dalvik VM processes to dump stack traces for first 4838 * @param lastPids of dalvik VM processes to dump stack traces for last 4839 * @param nativeProcs optional list of native process names to dump stack crawls 4840 * @return file containing stack traces, or null if no dump file is configured 4841 */ 4842 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4843 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4844 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4845 if (tracesPath == null || tracesPath.length() == 0) { 4846 return null; 4847 } 4848 4849 File tracesFile = new File(tracesPath); 4850 try { 4851 File tracesDir = tracesFile.getParentFile(); 4852 if (!tracesDir.exists()) { 4853 tracesFile.mkdirs(); 4854 if (!SELinux.restorecon(tracesDir)) { 4855 return null; 4856 } 4857 } 4858 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4859 4860 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4861 tracesFile.createNewFile(); 4862 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4863 } catch (IOException e) { 4864 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4865 return null; 4866 } 4867 4868 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4869 return tracesFile; 4870 } 4871 4872 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4873 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4874 // Use a FileObserver to detect when traces finish writing. 4875 // The order of traces is considered important to maintain for legibility. 4876 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4877 @Override 4878 public synchronized void onEvent(int event, String path) { notify(); } 4879 }; 4880 4881 try { 4882 observer.startWatching(); 4883 4884 // First collect all of the stacks of the most important pids. 4885 if (firstPids != null) { 4886 try { 4887 int num = firstPids.size(); 4888 for (int i = 0; i < num; i++) { 4889 synchronized (observer) { 4890 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4891 observer.wait(200); // Wait for write-close, give up after 200msec 4892 } 4893 } 4894 } catch (InterruptedException e) { 4895 Log.wtf(TAG, e); 4896 } 4897 } 4898 4899 // Next collect the stacks of the native pids 4900 if (nativeProcs != null) { 4901 int[] pids = Process.getPidsForCommands(nativeProcs); 4902 if (pids != null) { 4903 for (int pid : pids) { 4904 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4905 } 4906 } 4907 } 4908 4909 // Lastly, measure CPU usage. 4910 if (processCpuTracker != null) { 4911 processCpuTracker.init(); 4912 System.gc(); 4913 processCpuTracker.update(); 4914 try { 4915 synchronized (processCpuTracker) { 4916 processCpuTracker.wait(500); // measure over 1/2 second. 4917 } 4918 } catch (InterruptedException e) { 4919 } 4920 processCpuTracker.update(); 4921 4922 // We'll take the stack crawls of just the top apps using CPU. 4923 final int N = processCpuTracker.countWorkingStats(); 4924 int numProcs = 0; 4925 for (int i=0; i<N && numProcs<5; i++) { 4926 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4927 if (lastPids.indexOfKey(stats.pid) >= 0) { 4928 numProcs++; 4929 try { 4930 synchronized (observer) { 4931 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4932 observer.wait(200); // Wait for write-close, give up after 200msec 4933 } 4934 } catch (InterruptedException e) { 4935 Log.wtf(TAG, e); 4936 } 4937 4938 } 4939 } 4940 } 4941 } finally { 4942 observer.stopWatching(); 4943 } 4944 } 4945 4946 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4947 if (true || IS_USER_BUILD) { 4948 return; 4949 } 4950 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4951 if (tracesPath == null || tracesPath.length() == 0) { 4952 return; 4953 } 4954 4955 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4956 StrictMode.allowThreadDiskWrites(); 4957 try { 4958 final File tracesFile = new File(tracesPath); 4959 final File tracesDir = tracesFile.getParentFile(); 4960 final File tracesTmp = new File(tracesDir, "__tmp__"); 4961 try { 4962 if (!tracesDir.exists()) { 4963 tracesFile.mkdirs(); 4964 if (!SELinux.restorecon(tracesDir.getPath())) { 4965 return; 4966 } 4967 } 4968 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4969 4970 if (tracesFile.exists()) { 4971 tracesTmp.delete(); 4972 tracesFile.renameTo(tracesTmp); 4973 } 4974 StringBuilder sb = new StringBuilder(); 4975 Time tobj = new Time(); 4976 tobj.set(System.currentTimeMillis()); 4977 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4978 sb.append(": "); 4979 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4980 sb.append(" since "); 4981 sb.append(msg); 4982 FileOutputStream fos = new FileOutputStream(tracesFile); 4983 fos.write(sb.toString().getBytes()); 4984 if (app == null) { 4985 fos.write("\n*** No application process!".getBytes()); 4986 } 4987 fos.close(); 4988 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4989 } catch (IOException e) { 4990 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4991 return; 4992 } 4993 4994 if (app != null) { 4995 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4996 firstPids.add(app.pid); 4997 dumpStackTraces(tracesPath, firstPids, null, null, null); 4998 } 4999 5000 File lastTracesFile = null; 5001 File curTracesFile = null; 5002 for (int i=9; i>=0; i--) { 5003 String name = String.format(Locale.US, "slow%02d.txt", i); 5004 curTracesFile = new File(tracesDir, name); 5005 if (curTracesFile.exists()) { 5006 if (lastTracesFile != null) { 5007 curTracesFile.renameTo(lastTracesFile); 5008 } else { 5009 curTracesFile.delete(); 5010 } 5011 } 5012 lastTracesFile = curTracesFile; 5013 } 5014 tracesFile.renameTo(curTracesFile); 5015 if (tracesTmp.exists()) { 5016 tracesTmp.renameTo(tracesFile); 5017 } 5018 } finally { 5019 StrictMode.setThreadPolicy(oldPolicy); 5020 } 5021 } 5022 5023 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 5024 ActivityRecord parent, boolean aboveSystem, final String annotation) { 5025 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 5026 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 5027 5028 if (mController != null) { 5029 try { 5030 // 0 == continue, -1 = kill process immediately 5031 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 5032 if (res < 0 && app.pid != MY_PID) { 5033 app.kill("anr", true); 5034 } 5035 } catch (RemoteException e) { 5036 mController = null; 5037 Watchdog.getInstance().setActivityController(null); 5038 } 5039 } 5040 5041 long anrTime = SystemClock.uptimeMillis(); 5042 if (MONITOR_CPU_USAGE) { 5043 updateCpuStatsNow(); 5044 } 5045 5046 synchronized (this) { 5047 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5048 if (mShuttingDown) { 5049 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5050 return; 5051 } else if (app.notResponding) { 5052 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5053 return; 5054 } else if (app.crashing) { 5055 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5056 return; 5057 } 5058 5059 // In case we come through here for the same app before completing 5060 // this one, mark as anring now so we will bail out. 5061 app.notResponding = true; 5062 5063 // Log the ANR to the event log. 5064 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5065 app.processName, app.info.flags, annotation); 5066 5067 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5068 firstPids.add(app.pid); 5069 5070 int parentPid = app.pid; 5071 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5072 if (parentPid != app.pid) firstPids.add(parentPid); 5073 5074 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5075 5076 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5077 ProcessRecord r = mLruProcesses.get(i); 5078 if (r != null && r.thread != null) { 5079 int pid = r.pid; 5080 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5081 if (r.persistent) { 5082 firstPids.add(pid); 5083 } else { 5084 lastPids.put(pid, Boolean.TRUE); 5085 } 5086 } 5087 } 5088 } 5089 } 5090 5091 // Log the ANR to the main log. 5092 StringBuilder info = new StringBuilder(); 5093 info.setLength(0); 5094 info.append("ANR in ").append(app.processName); 5095 if (activity != null && activity.shortComponentName != null) { 5096 info.append(" (").append(activity.shortComponentName).append(")"); 5097 } 5098 info.append("\n"); 5099 info.append("PID: ").append(app.pid).append("\n"); 5100 if (annotation != null) { 5101 info.append("Reason: ").append(annotation).append("\n"); 5102 } 5103 if (parent != null && parent != activity) { 5104 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5105 } 5106 5107 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5108 5109 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5110 NATIVE_STACKS_OF_INTEREST); 5111 5112 String cpuInfo = null; 5113 if (MONITOR_CPU_USAGE) { 5114 updateCpuStatsNow(); 5115 synchronized (mProcessCpuThread) { 5116 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5117 } 5118 info.append(processCpuTracker.printCurrentLoad()); 5119 info.append(cpuInfo); 5120 } 5121 5122 info.append(processCpuTracker.printCurrentState(anrTime)); 5123 5124 Slog.e(TAG, info.toString()); 5125 if (tracesFile == null) { 5126 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5127 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5128 } 5129 5130 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5131 cpuInfo, tracesFile, null); 5132 5133 if (mController != null) { 5134 try { 5135 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5136 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5137 if (res != 0) { 5138 if (res < 0 && app.pid != MY_PID) { 5139 app.kill("anr", true); 5140 } else { 5141 synchronized (this) { 5142 mServices.scheduleServiceTimeoutLocked(app); 5143 } 5144 } 5145 return; 5146 } 5147 } catch (RemoteException e) { 5148 mController = null; 5149 Watchdog.getInstance().setActivityController(null); 5150 } 5151 } 5152 5153 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5154 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5155 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5156 5157 synchronized (this) { 5158 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5159 app.kill("bg anr", true); 5160 return; 5161 } 5162 5163 // Set the app's notResponding state, and look up the errorReportReceiver 5164 makeAppNotRespondingLocked(app, 5165 activity != null ? activity.shortComponentName : null, 5166 annotation != null ? "ANR " + annotation : "ANR", 5167 info.toString()); 5168 5169 // Bring up the infamous App Not Responding dialog 5170 Message msg = Message.obtain(); 5171 HashMap<String, Object> map = new HashMap<String, Object>(); 5172 msg.what = SHOW_NOT_RESPONDING_MSG; 5173 msg.obj = map; 5174 msg.arg1 = aboveSystem ? 1 : 0; 5175 map.put("app", app); 5176 if (activity != null) { 5177 map.put("activity", activity); 5178 } 5179 5180 mHandler.sendMessage(msg); 5181 } 5182 } 5183 5184 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5185 if (!mLaunchWarningShown) { 5186 mLaunchWarningShown = true; 5187 mHandler.post(new Runnable() { 5188 @Override 5189 public void run() { 5190 synchronized (ActivityManagerService.this) { 5191 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5192 d.show(); 5193 mHandler.postDelayed(new Runnable() { 5194 @Override 5195 public void run() { 5196 synchronized (ActivityManagerService.this) { 5197 d.dismiss(); 5198 mLaunchWarningShown = false; 5199 } 5200 } 5201 }, 4000); 5202 } 5203 } 5204 }); 5205 } 5206 } 5207 5208 @Override 5209 public boolean clearApplicationUserData(final String packageName, 5210 final IPackageDataObserver observer, int userId) { 5211 enforceNotIsolatedCaller("clearApplicationUserData"); 5212 int uid = Binder.getCallingUid(); 5213 int pid = Binder.getCallingPid(); 5214 userId = handleIncomingUser(pid, uid, 5215 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5216 long callingId = Binder.clearCallingIdentity(); 5217 try { 5218 IPackageManager pm = AppGlobals.getPackageManager(); 5219 int pkgUid = -1; 5220 synchronized(this) { 5221 try { 5222 pkgUid = pm.getPackageUid(packageName, userId); 5223 } catch (RemoteException e) { 5224 } 5225 if (pkgUid == -1) { 5226 Slog.w(TAG, "Invalid packageName: " + packageName); 5227 if (observer != null) { 5228 try { 5229 observer.onRemoveCompleted(packageName, false); 5230 } catch (RemoteException e) { 5231 Slog.i(TAG, "Observer no longer exists."); 5232 } 5233 } 5234 return false; 5235 } 5236 if (uid == pkgUid || checkComponentPermission( 5237 android.Manifest.permission.CLEAR_APP_USER_DATA, 5238 pid, uid, -1, true) 5239 == PackageManager.PERMISSION_GRANTED) { 5240 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5241 } else { 5242 throw new SecurityException("PID " + pid + " does not have permission " 5243 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5244 + " of package " + packageName); 5245 } 5246 5247 // Remove all tasks match the cleared application package and user 5248 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5249 final TaskRecord tr = mRecentTasks.get(i); 5250 final String taskPackageName = 5251 tr.getBaseIntent().getComponent().getPackageName(); 5252 if (tr.userId != userId) continue; 5253 if (!taskPackageName.equals(packageName)) continue; 5254 removeTaskByIdLocked(tr.taskId, 0); 5255 } 5256 } 5257 5258 try { 5259 // Clear application user data 5260 pm.clearApplicationUserData(packageName, observer, userId); 5261 5262 synchronized(this) { 5263 // Remove all permissions granted from/to this package 5264 removeUriPermissionsForPackageLocked(packageName, userId, true); 5265 } 5266 5267 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5268 Uri.fromParts("package", packageName, null)); 5269 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5270 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5271 null, null, 0, null, null, null, false, false, userId); 5272 } catch (RemoteException e) { 5273 } 5274 } finally { 5275 Binder.restoreCallingIdentity(callingId); 5276 } 5277 return true; 5278 } 5279 5280 @Override 5281 public void killBackgroundProcesses(final String packageName, int userId) { 5282 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5283 != PackageManager.PERMISSION_GRANTED && 5284 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5285 != PackageManager.PERMISSION_GRANTED) { 5286 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5287 + Binder.getCallingPid() 5288 + ", uid=" + Binder.getCallingUid() 5289 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5290 Slog.w(TAG, msg); 5291 throw new SecurityException(msg); 5292 } 5293 5294 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5295 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5296 long callingId = Binder.clearCallingIdentity(); 5297 try { 5298 IPackageManager pm = AppGlobals.getPackageManager(); 5299 synchronized(this) { 5300 int appId = -1; 5301 try { 5302 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5303 } catch (RemoteException e) { 5304 } 5305 if (appId == -1) { 5306 Slog.w(TAG, "Invalid packageName: " + packageName); 5307 return; 5308 } 5309 killPackageProcessesLocked(packageName, appId, userId, 5310 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5311 } 5312 } finally { 5313 Binder.restoreCallingIdentity(callingId); 5314 } 5315 } 5316 5317 @Override 5318 public void killAllBackgroundProcesses() { 5319 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5320 != PackageManager.PERMISSION_GRANTED) { 5321 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5322 + Binder.getCallingPid() 5323 + ", uid=" + Binder.getCallingUid() 5324 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5325 Slog.w(TAG, msg); 5326 throw new SecurityException(msg); 5327 } 5328 5329 long callingId = Binder.clearCallingIdentity(); 5330 try { 5331 synchronized(this) { 5332 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5333 final int NP = mProcessNames.getMap().size(); 5334 for (int ip=0; ip<NP; ip++) { 5335 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5336 final int NA = apps.size(); 5337 for (int ia=0; ia<NA; ia++) { 5338 ProcessRecord app = apps.valueAt(ia); 5339 if (app.persistent) { 5340 // we don't kill persistent processes 5341 continue; 5342 } 5343 if (app.removed) { 5344 procs.add(app); 5345 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5346 app.removed = true; 5347 procs.add(app); 5348 } 5349 } 5350 } 5351 5352 int N = procs.size(); 5353 for (int i=0; i<N; i++) { 5354 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5355 } 5356 mAllowLowerMemLevel = true; 5357 updateOomAdjLocked(); 5358 doLowMemReportIfNeededLocked(null); 5359 } 5360 } finally { 5361 Binder.restoreCallingIdentity(callingId); 5362 } 5363 } 5364 5365 @Override 5366 public void forceStopPackage(final String packageName, int userId) { 5367 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5368 != PackageManager.PERMISSION_GRANTED) { 5369 String msg = "Permission Denial: forceStopPackage() from pid=" 5370 + Binder.getCallingPid() 5371 + ", uid=" + Binder.getCallingUid() 5372 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5373 Slog.w(TAG, msg); 5374 throw new SecurityException(msg); 5375 } 5376 final int callingPid = Binder.getCallingPid(); 5377 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5378 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5379 long callingId = Binder.clearCallingIdentity(); 5380 try { 5381 IPackageManager pm = AppGlobals.getPackageManager(); 5382 synchronized(this) { 5383 int[] users = userId == UserHandle.USER_ALL 5384 ? getUsersLocked() : new int[] { userId }; 5385 for (int user : users) { 5386 int pkgUid = -1; 5387 try { 5388 pkgUid = pm.getPackageUid(packageName, user); 5389 } catch (RemoteException e) { 5390 } 5391 if (pkgUid == -1) { 5392 Slog.w(TAG, "Invalid packageName: " + packageName); 5393 continue; 5394 } 5395 try { 5396 pm.setPackageStoppedState(packageName, true, user); 5397 } catch (RemoteException e) { 5398 } catch (IllegalArgumentException e) { 5399 Slog.w(TAG, "Failed trying to unstop package " 5400 + packageName + ": " + e); 5401 } 5402 if (isUserRunningLocked(user, false)) { 5403 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5404 } 5405 } 5406 } 5407 } finally { 5408 Binder.restoreCallingIdentity(callingId); 5409 } 5410 } 5411 5412 @Override 5413 public void addPackageDependency(String packageName) { 5414 synchronized (this) { 5415 int callingPid = Binder.getCallingPid(); 5416 if (callingPid == Process.myPid()) { 5417 // Yeah, um, no. 5418 Slog.w(TAG, "Can't addPackageDependency on system process"); 5419 return; 5420 } 5421 ProcessRecord proc; 5422 synchronized (mPidsSelfLocked) { 5423 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5424 } 5425 if (proc != null) { 5426 if (proc.pkgDeps == null) { 5427 proc.pkgDeps = new ArraySet<String>(1); 5428 } 5429 proc.pkgDeps.add(packageName); 5430 } 5431 } 5432 } 5433 5434 /* 5435 * The pkg name and app id have to be specified. 5436 */ 5437 @Override 5438 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5439 if (pkg == null) { 5440 return; 5441 } 5442 // Make sure the uid is valid. 5443 if (appid < 0) { 5444 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5445 return; 5446 } 5447 int callerUid = Binder.getCallingUid(); 5448 // Only the system server can kill an application 5449 if (callerUid == Process.SYSTEM_UID) { 5450 // Post an aysnc message to kill the application 5451 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5452 msg.arg1 = appid; 5453 msg.arg2 = 0; 5454 Bundle bundle = new Bundle(); 5455 bundle.putString("pkg", pkg); 5456 bundle.putString("reason", reason); 5457 msg.obj = bundle; 5458 mHandler.sendMessage(msg); 5459 } else { 5460 throw new SecurityException(callerUid + " cannot kill pkg: " + 5461 pkg); 5462 } 5463 } 5464 5465 @Override 5466 public void closeSystemDialogs(String reason) { 5467 enforceNotIsolatedCaller("closeSystemDialogs"); 5468 5469 final int pid = Binder.getCallingPid(); 5470 final int uid = Binder.getCallingUid(); 5471 final long origId = Binder.clearCallingIdentity(); 5472 try { 5473 synchronized (this) { 5474 // Only allow this from foreground processes, so that background 5475 // applications can't abuse it to prevent system UI from being shown. 5476 if (uid >= Process.FIRST_APPLICATION_UID) { 5477 ProcessRecord proc; 5478 synchronized (mPidsSelfLocked) { 5479 proc = mPidsSelfLocked.get(pid); 5480 } 5481 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5482 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5483 + " from background process " + proc); 5484 return; 5485 } 5486 } 5487 closeSystemDialogsLocked(reason); 5488 } 5489 } finally { 5490 Binder.restoreCallingIdentity(origId); 5491 } 5492 } 5493 5494 void closeSystemDialogsLocked(String reason) { 5495 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5496 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5497 | Intent.FLAG_RECEIVER_FOREGROUND); 5498 if (reason != null) { 5499 intent.putExtra("reason", reason); 5500 } 5501 mWindowManager.closeSystemDialogs(reason); 5502 5503 mStackSupervisor.closeSystemDialogsLocked(); 5504 5505 broadcastIntentLocked(null, null, intent, null, 5506 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5507 Process.SYSTEM_UID, UserHandle.USER_ALL); 5508 } 5509 5510 @Override 5511 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5512 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5513 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5514 for (int i=pids.length-1; i>=0; i--) { 5515 ProcessRecord proc; 5516 int oomAdj; 5517 synchronized (this) { 5518 synchronized (mPidsSelfLocked) { 5519 proc = mPidsSelfLocked.get(pids[i]); 5520 oomAdj = proc != null ? proc.setAdj : 0; 5521 } 5522 } 5523 infos[i] = new Debug.MemoryInfo(); 5524 Debug.getMemoryInfo(pids[i], infos[i]); 5525 if (proc != null) { 5526 synchronized (this) { 5527 if (proc.thread != null && proc.setAdj == oomAdj) { 5528 // Record this for posterity if the process has been stable. 5529 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5530 infos[i].getTotalUss(), false, proc.pkgList); 5531 } 5532 } 5533 } 5534 } 5535 return infos; 5536 } 5537 5538 @Override 5539 public long[] getProcessPss(int[] pids) { 5540 enforceNotIsolatedCaller("getProcessPss"); 5541 long[] pss = new long[pids.length]; 5542 for (int i=pids.length-1; i>=0; i--) { 5543 ProcessRecord proc; 5544 int oomAdj; 5545 synchronized (this) { 5546 synchronized (mPidsSelfLocked) { 5547 proc = mPidsSelfLocked.get(pids[i]); 5548 oomAdj = proc != null ? proc.setAdj : 0; 5549 } 5550 } 5551 long[] tmpUss = new long[1]; 5552 pss[i] = Debug.getPss(pids[i], tmpUss); 5553 if (proc != null) { 5554 synchronized (this) { 5555 if (proc.thread != null && proc.setAdj == oomAdj) { 5556 // Record this for posterity if the process has been stable. 5557 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5558 } 5559 } 5560 } 5561 } 5562 return pss; 5563 } 5564 5565 @Override 5566 public void killApplicationProcess(String processName, int uid) { 5567 if (processName == null) { 5568 return; 5569 } 5570 5571 int callerUid = Binder.getCallingUid(); 5572 // Only the system server can kill an application 5573 if (callerUid == Process.SYSTEM_UID) { 5574 synchronized (this) { 5575 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5576 if (app != null && app.thread != null) { 5577 try { 5578 app.thread.scheduleSuicide(); 5579 } catch (RemoteException e) { 5580 // If the other end already died, then our work here is done. 5581 } 5582 } else { 5583 Slog.w(TAG, "Process/uid not found attempting kill of " 5584 + processName + " / " + uid); 5585 } 5586 } 5587 } else { 5588 throw new SecurityException(callerUid + " cannot kill app process: " + 5589 processName); 5590 } 5591 } 5592 5593 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5594 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5595 false, true, false, false, UserHandle.getUserId(uid), reason); 5596 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5597 Uri.fromParts("package", packageName, null)); 5598 if (!mProcessesReady) { 5599 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5600 | Intent.FLAG_RECEIVER_FOREGROUND); 5601 } 5602 intent.putExtra(Intent.EXTRA_UID, uid); 5603 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5604 broadcastIntentLocked(null, null, intent, 5605 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5606 false, false, 5607 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5608 } 5609 5610 private void forceStopUserLocked(int userId, String reason) { 5611 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5612 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5613 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5614 | Intent.FLAG_RECEIVER_FOREGROUND); 5615 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5616 broadcastIntentLocked(null, null, intent, 5617 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5618 false, false, 5619 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5620 } 5621 5622 private final boolean killPackageProcessesLocked(String packageName, int appId, 5623 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5624 boolean doit, boolean evenPersistent, String reason) { 5625 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5626 5627 // Remove all processes this package may have touched: all with the 5628 // same UID (except for the system or root user), and all whose name 5629 // matches the package name. 5630 final int NP = mProcessNames.getMap().size(); 5631 for (int ip=0; ip<NP; ip++) { 5632 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5633 final int NA = apps.size(); 5634 for (int ia=0; ia<NA; ia++) { 5635 ProcessRecord app = apps.valueAt(ia); 5636 if (app.persistent && !evenPersistent) { 5637 // we don't kill persistent processes 5638 continue; 5639 } 5640 if (app.removed) { 5641 if (doit) { 5642 procs.add(app); 5643 } 5644 continue; 5645 } 5646 5647 // Skip process if it doesn't meet our oom adj requirement. 5648 if (app.setAdj < minOomAdj) { 5649 continue; 5650 } 5651 5652 // If no package is specified, we call all processes under the 5653 // give user id. 5654 if (packageName == null) { 5655 if (app.userId != userId) { 5656 continue; 5657 } 5658 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5659 continue; 5660 } 5661 // Package has been specified, we want to hit all processes 5662 // that match it. We need to qualify this by the processes 5663 // that are running under the specified app and user ID. 5664 } else { 5665 final boolean isDep = app.pkgDeps != null 5666 && app.pkgDeps.contains(packageName); 5667 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5668 continue; 5669 } 5670 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5671 continue; 5672 } 5673 if (!app.pkgList.containsKey(packageName) && !isDep) { 5674 continue; 5675 } 5676 } 5677 5678 // Process has passed all conditions, kill it! 5679 if (!doit) { 5680 return true; 5681 } 5682 app.removed = true; 5683 procs.add(app); 5684 } 5685 } 5686 5687 int N = procs.size(); 5688 for (int i=0; i<N; i++) { 5689 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5690 } 5691 updateOomAdjLocked(); 5692 return N > 0; 5693 } 5694 5695 private final boolean forceStopPackageLocked(String name, int appId, 5696 boolean callerWillRestart, boolean purgeCache, boolean doit, 5697 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5698 int i; 5699 int N; 5700 5701 if (userId == UserHandle.USER_ALL && name == null) { 5702 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5703 } 5704 5705 if (appId < 0 && name != null) { 5706 try { 5707 appId = UserHandle.getAppId( 5708 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5709 } catch (RemoteException e) { 5710 } 5711 } 5712 5713 if (doit) { 5714 if (name != null) { 5715 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5716 + " user=" + userId + ": " + reason); 5717 } else { 5718 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5719 } 5720 5721 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5722 for (int ip=pmap.size()-1; ip>=0; ip--) { 5723 SparseArray<Long> ba = pmap.valueAt(ip); 5724 for (i=ba.size()-1; i>=0; i--) { 5725 boolean remove = false; 5726 final int entUid = ba.keyAt(i); 5727 if (name != null) { 5728 if (userId == UserHandle.USER_ALL) { 5729 if (UserHandle.getAppId(entUid) == appId) { 5730 remove = true; 5731 } 5732 } else { 5733 if (entUid == UserHandle.getUid(userId, appId)) { 5734 remove = true; 5735 } 5736 } 5737 } else if (UserHandle.getUserId(entUid) == userId) { 5738 remove = true; 5739 } 5740 if (remove) { 5741 ba.removeAt(i); 5742 } 5743 } 5744 if (ba.size() == 0) { 5745 pmap.removeAt(ip); 5746 } 5747 } 5748 } 5749 5750 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5751 -100, callerWillRestart, true, doit, evenPersistent, 5752 name == null ? ("stop user " + userId) : ("stop " + name)); 5753 5754 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5755 if (!doit) { 5756 return true; 5757 } 5758 didSomething = true; 5759 } 5760 5761 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5762 if (!doit) { 5763 return true; 5764 } 5765 didSomething = true; 5766 } 5767 5768 if (name == null) { 5769 // Remove all sticky broadcasts from this user. 5770 mStickyBroadcasts.remove(userId); 5771 } 5772 5773 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5774 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5775 userId, providers)) { 5776 if (!doit) { 5777 return true; 5778 } 5779 didSomething = true; 5780 } 5781 N = providers.size(); 5782 for (i=0; i<N; i++) { 5783 removeDyingProviderLocked(null, providers.get(i), true); 5784 } 5785 5786 // Remove transient permissions granted from/to this package/user 5787 removeUriPermissionsForPackageLocked(name, userId, false); 5788 5789 if (name == null || uninstalling) { 5790 // Remove pending intents. For now we only do this when force 5791 // stopping users, because we have some problems when doing this 5792 // for packages -- app widgets are not currently cleaned up for 5793 // such packages, so they can be left with bad pending intents. 5794 if (mIntentSenderRecords.size() > 0) { 5795 Iterator<WeakReference<PendingIntentRecord>> it 5796 = mIntentSenderRecords.values().iterator(); 5797 while (it.hasNext()) { 5798 WeakReference<PendingIntentRecord> wpir = it.next(); 5799 if (wpir == null) { 5800 it.remove(); 5801 continue; 5802 } 5803 PendingIntentRecord pir = wpir.get(); 5804 if (pir == null) { 5805 it.remove(); 5806 continue; 5807 } 5808 if (name == null) { 5809 // Stopping user, remove all objects for the user. 5810 if (pir.key.userId != userId) { 5811 // Not the same user, skip it. 5812 continue; 5813 } 5814 } else { 5815 if (UserHandle.getAppId(pir.uid) != appId) { 5816 // Different app id, skip it. 5817 continue; 5818 } 5819 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5820 // Different user, skip it. 5821 continue; 5822 } 5823 if (!pir.key.packageName.equals(name)) { 5824 // Different package, skip it. 5825 continue; 5826 } 5827 } 5828 if (!doit) { 5829 return true; 5830 } 5831 didSomething = true; 5832 it.remove(); 5833 pir.canceled = true; 5834 if (pir.key.activity != null) { 5835 pir.key.activity.pendingResults.remove(pir.ref); 5836 } 5837 } 5838 } 5839 } 5840 5841 if (doit) { 5842 if (purgeCache && name != null) { 5843 AttributeCache ac = AttributeCache.instance(); 5844 if (ac != null) { 5845 ac.removePackage(name); 5846 } 5847 } 5848 if (mBooted) { 5849 mStackSupervisor.resumeTopActivitiesLocked(); 5850 mStackSupervisor.scheduleIdleLocked(); 5851 } 5852 } 5853 5854 return didSomething; 5855 } 5856 5857 private final boolean removeProcessLocked(ProcessRecord app, 5858 boolean callerWillRestart, boolean allowRestart, String reason) { 5859 final String name = app.processName; 5860 final int uid = app.uid; 5861 if (DEBUG_PROCESSES) Slog.d( 5862 TAG, "Force removing proc " + app.toShortString() + " (" + name 5863 + "/" + uid + ")"); 5864 5865 mProcessNames.remove(name, 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 boolean needRestart = false; 5873 if (app.pid > 0 && app.pid != MY_PID) { 5874 int pid = app.pid; 5875 synchronized (mPidsSelfLocked) { 5876 mPidsSelfLocked.remove(pid); 5877 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5878 } 5879 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5880 if (app.isolated) { 5881 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5882 } 5883 app.kill(reason, true); 5884 handleAppDiedLocked(app, true, allowRestart); 5885 removeLruProcessLocked(app); 5886 5887 if (app.persistent && !app.isolated) { 5888 if (!callerWillRestart) { 5889 addAppLocked(app.info, false, null /* ABI override */); 5890 } else { 5891 needRestart = true; 5892 } 5893 } 5894 } else { 5895 mRemovedProcesses.add(app); 5896 } 5897 5898 return needRestart; 5899 } 5900 5901 private final void processStartTimedOutLocked(ProcessRecord app) { 5902 final int pid = app.pid; 5903 boolean gone = false; 5904 synchronized (mPidsSelfLocked) { 5905 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5906 if (knownApp != null && knownApp.thread == null) { 5907 mPidsSelfLocked.remove(pid); 5908 gone = true; 5909 } 5910 } 5911 5912 if (gone) { 5913 Slog.w(TAG, "Process " + app + " failed to attach"); 5914 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5915 pid, app.uid, app.processName); 5916 mProcessNames.remove(app.processName, app.uid); 5917 mIsolatedProcesses.remove(app.uid); 5918 if (mHeavyWeightProcess == app) { 5919 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5920 mHeavyWeightProcess.userId, 0)); 5921 mHeavyWeightProcess = null; 5922 } 5923 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5924 if (app.isolated) { 5925 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5926 } 5927 // Take care of any launching providers waiting for this process. 5928 checkAppInLaunchingProvidersLocked(app, true); 5929 // Take care of any services that are waiting for the process. 5930 mServices.processStartTimedOutLocked(app); 5931 app.kill("start timeout", true); 5932 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5933 Slog.w(TAG, "Unattached app died before backup, skipping"); 5934 try { 5935 IBackupManager bm = IBackupManager.Stub.asInterface( 5936 ServiceManager.getService(Context.BACKUP_SERVICE)); 5937 bm.agentDisconnected(app.info.packageName); 5938 } catch (RemoteException e) { 5939 // Can't happen; the backup manager is local 5940 } 5941 } 5942 if (isPendingBroadcastProcessLocked(pid)) { 5943 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5944 skipPendingBroadcastLocked(pid); 5945 } 5946 } else { 5947 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5948 } 5949 } 5950 5951 private final boolean attachApplicationLocked(IApplicationThread thread, 5952 int pid) { 5953 5954 // Find the application record that is being attached... either via 5955 // the pid if we are running in multiple processes, or just pull the 5956 // next app record if we are emulating process with anonymous threads. 5957 ProcessRecord app; 5958 if (pid != MY_PID && pid >= 0) { 5959 synchronized (mPidsSelfLocked) { 5960 app = mPidsSelfLocked.get(pid); 5961 } 5962 } else { 5963 app = null; 5964 } 5965 5966 if (app == null) { 5967 Slog.w(TAG, "No pending application record for pid " + pid 5968 + " (IApplicationThread " + thread + "); dropping process"); 5969 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5970 if (pid > 0 && pid != MY_PID) { 5971 Process.killProcessQuiet(pid); 5972 //TODO: Process.killProcessGroup(app.info.uid, pid); 5973 } else { 5974 try { 5975 thread.scheduleExit(); 5976 } catch (Exception e) { 5977 // Ignore exceptions. 5978 } 5979 } 5980 return false; 5981 } 5982 5983 // If this application record is still attached to a previous 5984 // process, clean it up now. 5985 if (app.thread != null) { 5986 handleAppDiedLocked(app, true, true); 5987 } 5988 5989 // Tell the process all about itself. 5990 5991 if (localLOGV) Slog.v( 5992 TAG, "Binding process pid " + pid + " to record " + app); 5993 5994 final String processName = app.processName; 5995 try { 5996 AppDeathRecipient adr = new AppDeathRecipient( 5997 app, pid, thread); 5998 thread.asBinder().linkToDeath(adr, 0); 5999 app.deathRecipient = adr; 6000 } catch (RemoteException e) { 6001 app.resetPackageList(mProcessStats); 6002 startProcessLocked(app, "link fail", processName); 6003 return false; 6004 } 6005 6006 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6007 6008 app.makeActive(thread, mProcessStats); 6009 app.curAdj = app.setAdj = -100; 6010 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 6011 app.forcingToForeground = null; 6012 updateProcessForegroundLocked(app, false, false); 6013 app.hasShownUi = false; 6014 app.debugging = false; 6015 app.cached = false; 6016 6017 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6018 6019 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6020 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6021 6022 if (!normalMode) { 6023 Slog.i(TAG, "Launching preboot mode app: " + app); 6024 } 6025 6026 if (localLOGV) Slog.v( 6027 TAG, "New app record " + app 6028 + " thread=" + thread.asBinder() + " pid=" + pid); 6029 try { 6030 int testMode = IApplicationThread.DEBUG_OFF; 6031 if (mDebugApp != null && mDebugApp.equals(processName)) { 6032 testMode = mWaitForDebugger 6033 ? IApplicationThread.DEBUG_WAIT 6034 : IApplicationThread.DEBUG_ON; 6035 app.debugging = true; 6036 if (mDebugTransient) { 6037 mDebugApp = mOrigDebugApp; 6038 mWaitForDebugger = mOrigWaitForDebugger; 6039 } 6040 } 6041 String profileFile = app.instrumentationProfileFile; 6042 ParcelFileDescriptor profileFd = null; 6043 int samplingInterval = 0; 6044 boolean profileAutoStop = false; 6045 if (mProfileApp != null && mProfileApp.equals(processName)) { 6046 mProfileProc = app; 6047 profileFile = mProfileFile; 6048 profileFd = mProfileFd; 6049 samplingInterval = mSamplingInterval; 6050 profileAutoStop = mAutoStopProfiler; 6051 } 6052 boolean enableOpenGlTrace = false; 6053 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6054 enableOpenGlTrace = true; 6055 mOpenGlTraceApp = null; 6056 } 6057 6058 // If the app is being launched for restore or full backup, set it up specially 6059 boolean isRestrictedBackupMode = false; 6060 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6061 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6062 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6063 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6064 } 6065 6066 ensurePackageDexOpt(app.instrumentationInfo != null 6067 ? app.instrumentationInfo.packageName 6068 : app.info.packageName); 6069 if (app.instrumentationClass != null) { 6070 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6071 } 6072 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6073 + processName + " with config " + mConfiguration); 6074 ApplicationInfo appInfo = app.instrumentationInfo != null 6075 ? app.instrumentationInfo : app.info; 6076 app.compat = compatibilityInfoForPackageLocked(appInfo); 6077 if (profileFd != null) { 6078 profileFd = profileFd.dup(); 6079 } 6080 ProfilerInfo profilerInfo = profileFile == null ? null 6081 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6082 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6083 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6084 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6085 isRestrictedBackupMode || !normalMode, app.persistent, 6086 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6087 mCoreSettingsObserver.getCoreSettingsLocked()); 6088 updateLruProcessLocked(app, false, null); 6089 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6090 } catch (Exception e) { 6091 // todo: Yikes! What should we do? For now we will try to 6092 // start another process, but that could easily get us in 6093 // an infinite loop of restarting processes... 6094 Slog.w(TAG, "Exception thrown during bind!", e); 6095 6096 app.resetPackageList(mProcessStats); 6097 app.unlinkDeathRecipient(); 6098 startProcessLocked(app, "bind fail", processName); 6099 return false; 6100 } 6101 6102 // Remove this record from the list of starting applications. 6103 mPersistentStartingProcesses.remove(app); 6104 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6105 "Attach application locked removing on hold: " + app); 6106 mProcessesOnHold.remove(app); 6107 6108 boolean badApp = false; 6109 boolean didSomething = false; 6110 6111 // See if the top visible activity is waiting to run in this process... 6112 if (normalMode) { 6113 try { 6114 if (mStackSupervisor.attachApplicationLocked(app)) { 6115 didSomething = true; 6116 } 6117 } catch (Exception e) { 6118 badApp = true; 6119 } 6120 } 6121 6122 // Find any services that should be running in this process... 6123 if (!badApp) { 6124 try { 6125 didSomething |= mServices.attachApplicationLocked(app, processName); 6126 } catch (Exception e) { 6127 badApp = true; 6128 } 6129 } 6130 6131 // Check if a next-broadcast receiver is in this process... 6132 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6133 try { 6134 didSomething |= sendPendingBroadcastsLocked(app); 6135 } catch (Exception e) { 6136 // If the app died trying to launch the receiver we declare it 'bad' 6137 badApp = true; 6138 } 6139 } 6140 6141 // Check whether the next backup agent is in this process... 6142 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6143 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6144 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6145 try { 6146 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6147 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6148 mBackupTarget.backupMode); 6149 } catch (Exception e) { 6150 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6151 e.printStackTrace(); 6152 } 6153 } 6154 6155 if (badApp) { 6156 // todo: Also need to kill application to deal with all 6157 // kinds of exceptions. 6158 handleAppDiedLocked(app, false, true); 6159 return false; 6160 } 6161 6162 if (!didSomething) { 6163 updateOomAdjLocked(); 6164 } 6165 6166 return true; 6167 } 6168 6169 @Override 6170 public final void attachApplication(IApplicationThread thread) { 6171 synchronized (this) { 6172 int callingPid = Binder.getCallingPid(); 6173 final long origId = Binder.clearCallingIdentity(); 6174 attachApplicationLocked(thread, callingPid); 6175 Binder.restoreCallingIdentity(origId); 6176 } 6177 } 6178 6179 @Override 6180 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6181 final long origId = Binder.clearCallingIdentity(); 6182 synchronized (this) { 6183 ActivityStack stack = ActivityRecord.getStackLocked(token); 6184 if (stack != null) { 6185 ActivityRecord r = 6186 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6187 if (stopProfiling) { 6188 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6189 try { 6190 mProfileFd.close(); 6191 } catch (IOException e) { 6192 } 6193 clearProfilerLocked(); 6194 } 6195 } 6196 } 6197 } 6198 Binder.restoreCallingIdentity(origId); 6199 } 6200 6201 void postEnableScreenAfterBootLocked() { 6202 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6203 } 6204 6205 void enableScreenAfterBoot() { 6206 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6207 SystemClock.uptimeMillis()); 6208 mWindowManager.enableScreenAfterBoot(); 6209 6210 synchronized (this) { 6211 updateEventDispatchingLocked(); 6212 } 6213 } 6214 6215 @Override 6216 public void showBootMessage(final CharSequence msg, final boolean always) { 6217 enforceNotIsolatedCaller("showBootMessage"); 6218 mWindowManager.showBootMessage(msg, always); 6219 } 6220 6221 @Override 6222 public void keyguardWaitingForActivityDrawn() { 6223 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6224 final long token = Binder.clearCallingIdentity(); 6225 try { 6226 synchronized (this) { 6227 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6228 mWindowManager.keyguardWaitingForActivityDrawn(); 6229 } 6230 } finally { 6231 Binder.restoreCallingIdentity(token); 6232 } 6233 } 6234 6235 final void finishBooting() { 6236 // Register receivers to handle package update events 6237 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6238 6239 // Let system services know. 6240 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6241 6242 synchronized (this) { 6243 // Ensure that any processes we had put on hold are now started 6244 // up. 6245 final int NP = mProcessesOnHold.size(); 6246 if (NP > 0) { 6247 ArrayList<ProcessRecord> procs = 6248 new ArrayList<ProcessRecord>(mProcessesOnHold); 6249 for (int ip=0; ip<NP; ip++) { 6250 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6251 + procs.get(ip)); 6252 startProcessLocked(procs.get(ip), "on-hold", null); 6253 } 6254 } 6255 6256 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6257 // Start looking for apps that are abusing wake locks. 6258 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6259 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6260 // Tell anyone interested that we are done booting! 6261 SystemProperties.set("sys.boot_completed", "1"); 6262 SystemProperties.set("dev.bootcomplete", "1"); 6263 for (int i=0; i<mStartedUsers.size(); i++) { 6264 UserStartedState uss = mStartedUsers.valueAt(i); 6265 if (uss.mState == UserStartedState.STATE_BOOTING) { 6266 uss.mState = UserStartedState.STATE_RUNNING; 6267 final int userId = mStartedUsers.keyAt(i); 6268 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6269 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6270 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6271 broadcastIntentLocked(null, null, intent, null, 6272 new IIntentReceiver.Stub() { 6273 @Override 6274 public void performReceive(Intent intent, int resultCode, 6275 String data, Bundle extras, boolean ordered, 6276 boolean sticky, int sendingUser) { 6277 synchronized (ActivityManagerService.this) { 6278 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6279 true, false); 6280 } 6281 } 6282 }, 6283 0, null, null, 6284 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6285 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6286 userId); 6287 } 6288 } 6289 scheduleStartProfilesLocked(); 6290 } 6291 } 6292 } 6293 6294 final void ensureBootCompleted() { 6295 boolean booting; 6296 boolean enableScreen; 6297 synchronized (this) { 6298 booting = mBooting; 6299 mBooting = false; 6300 enableScreen = !mBooted; 6301 mBooted = true; 6302 } 6303 6304 if (booting) { 6305 finishBooting(); 6306 } 6307 6308 if (enableScreen) { 6309 enableScreenAfterBoot(); 6310 } 6311 } 6312 6313 @Override 6314 public final void activityResumed(IBinder token) { 6315 final long origId = Binder.clearCallingIdentity(); 6316 synchronized(this) { 6317 ActivityStack stack = ActivityRecord.getStackLocked(token); 6318 if (stack != null) { 6319 ActivityRecord.activityResumedLocked(token); 6320 } 6321 } 6322 Binder.restoreCallingIdentity(origId); 6323 } 6324 6325 @Override 6326 public final void activityPaused(IBinder token) { 6327 final long origId = Binder.clearCallingIdentity(); 6328 synchronized(this) { 6329 ActivityStack stack = ActivityRecord.getStackLocked(token); 6330 if (stack != null) { 6331 stack.activityPausedLocked(token, false); 6332 } 6333 } 6334 Binder.restoreCallingIdentity(origId); 6335 } 6336 6337 @Override 6338 public final void activityStopped(IBinder token, Bundle icicle, 6339 PersistableBundle persistentState, CharSequence description) { 6340 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6341 6342 // Refuse possible leaked file descriptors 6343 if (icicle != null && icicle.hasFileDescriptors()) { 6344 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6345 } 6346 6347 final long origId = Binder.clearCallingIdentity(); 6348 6349 synchronized (this) { 6350 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6351 if (r != null) { 6352 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6353 } 6354 } 6355 6356 trimApplications(); 6357 6358 Binder.restoreCallingIdentity(origId); 6359 } 6360 6361 @Override 6362 public final void activityDestroyed(IBinder token) { 6363 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6364 synchronized (this) { 6365 ActivityStack stack = ActivityRecord.getStackLocked(token); 6366 if (stack != null) { 6367 stack.activityDestroyedLocked(token); 6368 } 6369 } 6370 } 6371 6372 @Override 6373 public final void backgroundResourcesReleased(IBinder token) { 6374 final long origId = Binder.clearCallingIdentity(); 6375 try { 6376 synchronized (this) { 6377 ActivityStack stack = ActivityRecord.getStackLocked(token); 6378 if (stack != null) { 6379 stack.backgroundResourcesReleased(token); 6380 } 6381 } 6382 } finally { 6383 Binder.restoreCallingIdentity(origId); 6384 } 6385 } 6386 6387 @Override 6388 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6389 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6390 } 6391 6392 @Override 6393 public final void notifyEnterAnimationComplete(IBinder token) { 6394 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6395 } 6396 6397 @Override 6398 public String getCallingPackage(IBinder token) { 6399 synchronized (this) { 6400 ActivityRecord r = getCallingRecordLocked(token); 6401 return r != null ? r.info.packageName : null; 6402 } 6403 } 6404 6405 @Override 6406 public ComponentName getCallingActivity(IBinder token) { 6407 synchronized (this) { 6408 ActivityRecord r = getCallingRecordLocked(token); 6409 return r != null ? r.intent.getComponent() : null; 6410 } 6411 } 6412 6413 private ActivityRecord getCallingRecordLocked(IBinder token) { 6414 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6415 if (r == null) { 6416 return null; 6417 } 6418 return r.resultTo; 6419 } 6420 6421 @Override 6422 public ComponentName getActivityClassForToken(IBinder token) { 6423 synchronized(this) { 6424 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6425 if (r == null) { 6426 return null; 6427 } 6428 return r.intent.getComponent(); 6429 } 6430 } 6431 6432 @Override 6433 public String getPackageForToken(IBinder token) { 6434 synchronized(this) { 6435 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6436 if (r == null) { 6437 return null; 6438 } 6439 return r.packageName; 6440 } 6441 } 6442 6443 @Override 6444 public IIntentSender getIntentSender(int type, 6445 String packageName, IBinder token, String resultWho, 6446 int requestCode, Intent[] intents, String[] resolvedTypes, 6447 int flags, Bundle options, int userId) { 6448 enforceNotIsolatedCaller("getIntentSender"); 6449 // Refuse possible leaked file descriptors 6450 if (intents != null) { 6451 if (intents.length < 1) { 6452 throw new IllegalArgumentException("Intents array length must be >= 1"); 6453 } 6454 for (int i=0; i<intents.length; i++) { 6455 Intent intent = intents[i]; 6456 if (intent != null) { 6457 if (intent.hasFileDescriptors()) { 6458 throw new IllegalArgumentException("File descriptors passed in Intent"); 6459 } 6460 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6461 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6462 throw new IllegalArgumentException( 6463 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6464 } 6465 intents[i] = new Intent(intent); 6466 } 6467 } 6468 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6469 throw new IllegalArgumentException( 6470 "Intent array length does not match resolvedTypes length"); 6471 } 6472 } 6473 if (options != null) { 6474 if (options.hasFileDescriptors()) { 6475 throw new IllegalArgumentException("File descriptors passed in options"); 6476 } 6477 } 6478 6479 synchronized(this) { 6480 int callingUid = Binder.getCallingUid(); 6481 int origUserId = userId; 6482 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6483 type == ActivityManager.INTENT_SENDER_BROADCAST, 6484 ALLOW_NON_FULL, "getIntentSender", null); 6485 if (origUserId == UserHandle.USER_CURRENT) { 6486 // We don't want to evaluate this until the pending intent is 6487 // actually executed. However, we do want to always do the 6488 // security checking for it above. 6489 userId = UserHandle.USER_CURRENT; 6490 } 6491 try { 6492 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6493 int uid = AppGlobals.getPackageManager() 6494 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6495 if (!UserHandle.isSameApp(callingUid, uid)) { 6496 String msg = "Permission Denial: getIntentSender() from pid=" 6497 + Binder.getCallingPid() 6498 + ", uid=" + Binder.getCallingUid() 6499 + ", (need uid=" + uid + ")" 6500 + " is not allowed to send as package " + packageName; 6501 Slog.w(TAG, msg); 6502 throw new SecurityException(msg); 6503 } 6504 } 6505 6506 return getIntentSenderLocked(type, packageName, callingUid, userId, 6507 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6508 6509 } catch (RemoteException e) { 6510 throw new SecurityException(e); 6511 } 6512 } 6513 } 6514 6515 IIntentSender getIntentSenderLocked(int type, String packageName, 6516 int callingUid, int userId, IBinder token, String resultWho, 6517 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6518 Bundle options) { 6519 if (DEBUG_MU) 6520 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6521 ActivityRecord activity = null; 6522 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6523 activity = ActivityRecord.isInStackLocked(token); 6524 if (activity == null) { 6525 return null; 6526 } 6527 if (activity.finishing) { 6528 return null; 6529 } 6530 } 6531 6532 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6533 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6534 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6535 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6536 |PendingIntent.FLAG_UPDATE_CURRENT); 6537 6538 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6539 type, packageName, activity, resultWho, 6540 requestCode, intents, resolvedTypes, flags, options, userId); 6541 WeakReference<PendingIntentRecord> ref; 6542 ref = mIntentSenderRecords.get(key); 6543 PendingIntentRecord rec = ref != null ? ref.get() : null; 6544 if (rec != null) { 6545 if (!cancelCurrent) { 6546 if (updateCurrent) { 6547 if (rec.key.requestIntent != null) { 6548 rec.key.requestIntent.replaceExtras(intents != null ? 6549 intents[intents.length - 1] : null); 6550 } 6551 if (intents != null) { 6552 intents[intents.length-1] = rec.key.requestIntent; 6553 rec.key.allIntents = intents; 6554 rec.key.allResolvedTypes = resolvedTypes; 6555 } else { 6556 rec.key.allIntents = null; 6557 rec.key.allResolvedTypes = null; 6558 } 6559 } 6560 return rec; 6561 } 6562 rec.canceled = true; 6563 mIntentSenderRecords.remove(key); 6564 } 6565 if (noCreate) { 6566 return rec; 6567 } 6568 rec = new PendingIntentRecord(this, key, callingUid); 6569 mIntentSenderRecords.put(key, rec.ref); 6570 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6571 if (activity.pendingResults == null) { 6572 activity.pendingResults 6573 = new HashSet<WeakReference<PendingIntentRecord>>(); 6574 } 6575 activity.pendingResults.add(rec.ref); 6576 } 6577 return rec; 6578 } 6579 6580 @Override 6581 public void cancelIntentSender(IIntentSender sender) { 6582 if (!(sender instanceof PendingIntentRecord)) { 6583 return; 6584 } 6585 synchronized(this) { 6586 PendingIntentRecord rec = (PendingIntentRecord)sender; 6587 try { 6588 int uid = AppGlobals.getPackageManager() 6589 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6590 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6591 String msg = "Permission Denial: cancelIntentSender() from pid=" 6592 + Binder.getCallingPid() 6593 + ", uid=" + Binder.getCallingUid() 6594 + " is not allowed to cancel packges " 6595 + rec.key.packageName; 6596 Slog.w(TAG, msg); 6597 throw new SecurityException(msg); 6598 } 6599 } catch (RemoteException e) { 6600 throw new SecurityException(e); 6601 } 6602 cancelIntentSenderLocked(rec, true); 6603 } 6604 } 6605 6606 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6607 rec.canceled = true; 6608 mIntentSenderRecords.remove(rec.key); 6609 if (cleanActivity && rec.key.activity != null) { 6610 rec.key.activity.pendingResults.remove(rec.ref); 6611 } 6612 } 6613 6614 @Override 6615 public String getPackageForIntentSender(IIntentSender pendingResult) { 6616 if (!(pendingResult instanceof PendingIntentRecord)) { 6617 return null; 6618 } 6619 try { 6620 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6621 return res.key.packageName; 6622 } catch (ClassCastException e) { 6623 } 6624 return null; 6625 } 6626 6627 @Override 6628 public int getUidForIntentSender(IIntentSender sender) { 6629 if (sender instanceof PendingIntentRecord) { 6630 try { 6631 PendingIntentRecord res = (PendingIntentRecord)sender; 6632 return res.uid; 6633 } catch (ClassCastException e) { 6634 } 6635 } 6636 return -1; 6637 } 6638 6639 @Override 6640 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6641 if (!(pendingResult instanceof PendingIntentRecord)) { 6642 return false; 6643 } 6644 try { 6645 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6646 if (res.key.allIntents == null) { 6647 return false; 6648 } 6649 for (int i=0; i<res.key.allIntents.length; i++) { 6650 Intent intent = res.key.allIntents[i]; 6651 if (intent.getPackage() != null && intent.getComponent() != null) { 6652 return false; 6653 } 6654 } 6655 return true; 6656 } catch (ClassCastException e) { 6657 } 6658 return false; 6659 } 6660 6661 @Override 6662 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6663 if (!(pendingResult instanceof PendingIntentRecord)) { 6664 return false; 6665 } 6666 try { 6667 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6668 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6669 return true; 6670 } 6671 return false; 6672 } catch (ClassCastException e) { 6673 } 6674 return false; 6675 } 6676 6677 @Override 6678 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6679 if (!(pendingResult instanceof PendingIntentRecord)) { 6680 return null; 6681 } 6682 try { 6683 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6684 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6685 } catch (ClassCastException e) { 6686 } 6687 return null; 6688 } 6689 6690 @Override 6691 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6692 if (!(pendingResult instanceof PendingIntentRecord)) { 6693 return null; 6694 } 6695 try { 6696 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6697 Intent intent = res.key.requestIntent; 6698 if (intent != null) { 6699 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6700 || res.lastTagPrefix.equals(prefix))) { 6701 return res.lastTag; 6702 } 6703 res.lastTagPrefix = prefix; 6704 StringBuilder sb = new StringBuilder(128); 6705 if (prefix != null) { 6706 sb.append(prefix); 6707 } 6708 if (intent.getAction() != null) { 6709 sb.append(intent.getAction()); 6710 } else if (intent.getComponent() != null) { 6711 intent.getComponent().appendShortString(sb); 6712 } else { 6713 sb.append("?"); 6714 } 6715 return res.lastTag = sb.toString(); 6716 } 6717 } catch (ClassCastException e) { 6718 } 6719 return null; 6720 } 6721 6722 @Override 6723 public void setProcessLimit(int max) { 6724 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6725 "setProcessLimit()"); 6726 synchronized (this) { 6727 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6728 mProcessLimitOverride = max; 6729 } 6730 trimApplications(); 6731 } 6732 6733 @Override 6734 public int getProcessLimit() { 6735 synchronized (this) { 6736 return mProcessLimitOverride; 6737 } 6738 } 6739 6740 void foregroundTokenDied(ForegroundToken token) { 6741 synchronized (ActivityManagerService.this) { 6742 synchronized (mPidsSelfLocked) { 6743 ForegroundToken cur 6744 = mForegroundProcesses.get(token.pid); 6745 if (cur != token) { 6746 return; 6747 } 6748 mForegroundProcesses.remove(token.pid); 6749 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6750 if (pr == null) { 6751 return; 6752 } 6753 pr.forcingToForeground = null; 6754 updateProcessForegroundLocked(pr, false, false); 6755 } 6756 updateOomAdjLocked(); 6757 } 6758 } 6759 6760 @Override 6761 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6762 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6763 "setProcessForeground()"); 6764 synchronized(this) { 6765 boolean changed = false; 6766 6767 synchronized (mPidsSelfLocked) { 6768 ProcessRecord pr = mPidsSelfLocked.get(pid); 6769 if (pr == null && isForeground) { 6770 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6771 return; 6772 } 6773 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6774 if (oldToken != null) { 6775 oldToken.token.unlinkToDeath(oldToken, 0); 6776 mForegroundProcesses.remove(pid); 6777 if (pr != null) { 6778 pr.forcingToForeground = null; 6779 } 6780 changed = true; 6781 } 6782 if (isForeground && token != null) { 6783 ForegroundToken newToken = new ForegroundToken() { 6784 @Override 6785 public void binderDied() { 6786 foregroundTokenDied(this); 6787 } 6788 }; 6789 newToken.pid = pid; 6790 newToken.token = token; 6791 try { 6792 token.linkToDeath(newToken, 0); 6793 mForegroundProcesses.put(pid, newToken); 6794 pr.forcingToForeground = token; 6795 changed = true; 6796 } catch (RemoteException e) { 6797 // If the process died while doing this, we will later 6798 // do the cleanup with the process death link. 6799 } 6800 } 6801 } 6802 6803 if (changed) { 6804 updateOomAdjLocked(); 6805 } 6806 } 6807 } 6808 6809 // ========================================================= 6810 // PERMISSIONS 6811 // ========================================================= 6812 6813 static class PermissionController extends IPermissionController.Stub { 6814 ActivityManagerService mActivityManagerService; 6815 PermissionController(ActivityManagerService activityManagerService) { 6816 mActivityManagerService = activityManagerService; 6817 } 6818 6819 @Override 6820 public boolean checkPermission(String permission, int pid, int uid) { 6821 return mActivityManagerService.checkPermission(permission, pid, 6822 uid) == PackageManager.PERMISSION_GRANTED; 6823 } 6824 } 6825 6826 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6827 @Override 6828 public int checkComponentPermission(String permission, int pid, int uid, 6829 int owningUid, boolean exported) { 6830 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6831 owningUid, exported); 6832 } 6833 6834 @Override 6835 public Object getAMSLock() { 6836 return ActivityManagerService.this; 6837 } 6838 } 6839 6840 /** 6841 * This can be called with or without the global lock held. 6842 */ 6843 int checkComponentPermission(String permission, int pid, int uid, 6844 int owningUid, boolean exported) { 6845 // We might be performing an operation on behalf of an indirect binder 6846 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6847 // client identity accordingly before proceeding. 6848 Identity tlsIdentity = sCallerIdentity.get(); 6849 if (tlsIdentity != null) { 6850 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6851 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6852 uid = tlsIdentity.uid; 6853 pid = tlsIdentity.pid; 6854 } 6855 6856 if (pid == MY_PID) { 6857 return PackageManager.PERMISSION_GRANTED; 6858 } 6859 6860 return ActivityManager.checkComponentPermission(permission, uid, 6861 owningUid, exported); 6862 } 6863 6864 /** 6865 * As the only public entry point for permissions checking, this method 6866 * can enforce the semantic that requesting a check on a null global 6867 * permission is automatically denied. (Internally a null permission 6868 * string is used when calling {@link #checkComponentPermission} in cases 6869 * when only uid-based security is needed.) 6870 * 6871 * This can be called with or without the global lock held. 6872 */ 6873 @Override 6874 public int checkPermission(String permission, int pid, int uid) { 6875 if (permission == null) { 6876 return PackageManager.PERMISSION_DENIED; 6877 } 6878 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6879 } 6880 6881 /** 6882 * Binder IPC calls go through the public entry point. 6883 * This can be called with or without the global lock held. 6884 */ 6885 int checkCallingPermission(String permission) { 6886 return checkPermission(permission, 6887 Binder.getCallingPid(), 6888 UserHandle.getAppId(Binder.getCallingUid())); 6889 } 6890 6891 /** 6892 * This can be called with or without the global lock held. 6893 */ 6894 void enforceCallingPermission(String permission, String func) { 6895 if (checkCallingPermission(permission) 6896 == PackageManager.PERMISSION_GRANTED) { 6897 return; 6898 } 6899 6900 String msg = "Permission Denial: " + func + " from pid=" 6901 + Binder.getCallingPid() 6902 + ", uid=" + Binder.getCallingUid() 6903 + " requires " + permission; 6904 Slog.w(TAG, msg); 6905 throw new SecurityException(msg); 6906 } 6907 6908 /** 6909 * Determine if UID is holding permissions required to access {@link Uri} in 6910 * the given {@link ProviderInfo}. Final permission checking is always done 6911 * in {@link ContentProvider}. 6912 */ 6913 private final boolean checkHoldingPermissionsLocked( 6914 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6915 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6916 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6917 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6918 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6919 != PERMISSION_GRANTED) { 6920 return false; 6921 } 6922 } 6923 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6924 } 6925 6926 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6927 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6928 if (pi.applicationInfo.uid == uid) { 6929 return true; 6930 } else if (!pi.exported) { 6931 return false; 6932 } 6933 6934 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6935 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6936 try { 6937 // check if target holds top-level <provider> permissions 6938 if (!readMet && pi.readPermission != null && considerUidPermissions 6939 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6940 readMet = true; 6941 } 6942 if (!writeMet && pi.writePermission != null && considerUidPermissions 6943 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6944 writeMet = true; 6945 } 6946 6947 // track if unprotected read/write is allowed; any denied 6948 // <path-permission> below removes this ability 6949 boolean allowDefaultRead = pi.readPermission == null; 6950 boolean allowDefaultWrite = pi.writePermission == null; 6951 6952 // check if target holds any <path-permission> that match uri 6953 final PathPermission[] pps = pi.pathPermissions; 6954 if (pps != null) { 6955 final String path = grantUri.uri.getPath(); 6956 int i = pps.length; 6957 while (i > 0 && (!readMet || !writeMet)) { 6958 i--; 6959 PathPermission pp = pps[i]; 6960 if (pp.match(path)) { 6961 if (!readMet) { 6962 final String pprperm = pp.getReadPermission(); 6963 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6964 + pprperm + " for " + pp.getPath() 6965 + ": match=" + pp.match(path) 6966 + " check=" + pm.checkUidPermission(pprperm, uid)); 6967 if (pprperm != null) { 6968 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6969 == PERMISSION_GRANTED) { 6970 readMet = true; 6971 } else { 6972 allowDefaultRead = false; 6973 } 6974 } 6975 } 6976 if (!writeMet) { 6977 final String ppwperm = pp.getWritePermission(); 6978 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6979 + ppwperm + " for " + pp.getPath() 6980 + ": match=" + pp.match(path) 6981 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6982 if (ppwperm != null) { 6983 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6984 == PERMISSION_GRANTED) { 6985 writeMet = true; 6986 } else { 6987 allowDefaultWrite = false; 6988 } 6989 } 6990 } 6991 } 6992 } 6993 } 6994 6995 // grant unprotected <provider> read/write, if not blocked by 6996 // <path-permission> above 6997 if (allowDefaultRead) readMet = true; 6998 if (allowDefaultWrite) writeMet = true; 6999 7000 } catch (RemoteException e) { 7001 return false; 7002 } 7003 7004 return readMet && writeMet; 7005 } 7006 7007 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 7008 ProviderInfo pi = null; 7009 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 7010 if (cpr != null) { 7011 pi = cpr.info; 7012 } else { 7013 try { 7014 pi = AppGlobals.getPackageManager().resolveContentProvider( 7015 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 7016 } catch (RemoteException ex) { 7017 } 7018 } 7019 return pi; 7020 } 7021 7022 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 7023 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7024 if (targetUris != null) { 7025 return targetUris.get(grantUri); 7026 } 7027 return null; 7028 } 7029 7030 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 7031 String targetPkg, int targetUid, GrantUri grantUri) { 7032 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 7033 if (targetUris == null) { 7034 targetUris = Maps.newArrayMap(); 7035 mGrantedUriPermissions.put(targetUid, targetUris); 7036 } 7037 7038 UriPermission perm = targetUris.get(grantUri); 7039 if (perm == null) { 7040 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 7041 targetUris.put(grantUri, perm); 7042 } 7043 7044 return perm; 7045 } 7046 7047 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7048 final int modeFlags) { 7049 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7050 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7051 : UriPermission.STRENGTH_OWNED; 7052 7053 // Root gets to do everything. 7054 if (uid == 0) { 7055 return true; 7056 } 7057 7058 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7059 if (perms == null) return false; 7060 7061 // First look for exact match 7062 final UriPermission exactPerm = perms.get(grantUri); 7063 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7064 return true; 7065 } 7066 7067 // No exact match, look for prefixes 7068 final int N = perms.size(); 7069 for (int i = 0; i < N; i++) { 7070 final UriPermission perm = perms.valueAt(i); 7071 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7072 && perm.getStrength(modeFlags) >= minStrength) { 7073 return true; 7074 } 7075 } 7076 7077 return false; 7078 } 7079 7080 /** 7081 * @param uri This uri must NOT contain an embedded userId. 7082 * @param userId The userId in which the uri is to be resolved. 7083 */ 7084 @Override 7085 public int checkUriPermission(Uri uri, int pid, int uid, 7086 final int modeFlags, int userId) { 7087 enforceNotIsolatedCaller("checkUriPermission"); 7088 7089 // Another redirected-binder-call permissions check as in 7090 // {@link checkComponentPermission}. 7091 Identity tlsIdentity = sCallerIdentity.get(); 7092 if (tlsIdentity != null) { 7093 uid = tlsIdentity.uid; 7094 pid = tlsIdentity.pid; 7095 } 7096 7097 // Our own process gets to do everything. 7098 if (pid == MY_PID) { 7099 return PackageManager.PERMISSION_GRANTED; 7100 } 7101 synchronized (this) { 7102 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7103 ? PackageManager.PERMISSION_GRANTED 7104 : PackageManager.PERMISSION_DENIED; 7105 } 7106 } 7107 7108 /** 7109 * Check if the targetPkg can be granted permission to access uri by 7110 * the callingUid using the given modeFlags. Throws a security exception 7111 * if callingUid is not allowed to do this. Returns the uid of the target 7112 * if the URI permission grant should be performed; returns -1 if it is not 7113 * needed (for example targetPkg already has permission to access the URI). 7114 * If you already know the uid of the target, you can supply it in 7115 * lastTargetUid else set that to -1. 7116 */ 7117 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7118 final int modeFlags, int lastTargetUid) { 7119 if (!Intent.isAccessUriMode(modeFlags)) { 7120 return -1; 7121 } 7122 7123 if (targetPkg != null) { 7124 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7125 "Checking grant " + targetPkg + " permission to " + grantUri); 7126 } 7127 7128 final IPackageManager pm = AppGlobals.getPackageManager(); 7129 7130 // If this is not a content: uri, we can't do anything with it. 7131 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7132 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7133 "Can't grant URI permission for non-content URI: " + grantUri); 7134 return -1; 7135 } 7136 7137 final String authority = grantUri.uri.getAuthority(); 7138 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7139 if (pi == null) { 7140 Slog.w(TAG, "No content provider found for permission check: " + 7141 grantUri.uri.toSafeString()); 7142 return -1; 7143 } 7144 7145 int targetUid = lastTargetUid; 7146 if (targetUid < 0 && targetPkg != null) { 7147 try { 7148 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7149 if (targetUid < 0) { 7150 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7151 "Can't grant URI permission no uid for: " + targetPkg); 7152 return -1; 7153 } 7154 } catch (RemoteException ex) { 7155 return -1; 7156 } 7157 } 7158 7159 if (targetUid >= 0) { 7160 // First... does the target actually need this permission? 7161 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7162 // No need to grant the target this permission. 7163 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7164 "Target " + targetPkg + " already has full permission to " + grantUri); 7165 return -1; 7166 } 7167 } else { 7168 // First... there is no target package, so can anyone access it? 7169 boolean allowed = pi.exported; 7170 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7171 if (pi.readPermission != null) { 7172 allowed = false; 7173 } 7174 } 7175 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7176 if (pi.writePermission != null) { 7177 allowed = false; 7178 } 7179 } 7180 if (allowed) { 7181 return -1; 7182 } 7183 } 7184 7185 /* There is a special cross user grant if: 7186 * - The target is on another user. 7187 * - Apps on the current user can access the uri without any uid permissions. 7188 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7189 * grant uri permissions. 7190 */ 7191 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7192 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7193 modeFlags, false /*without considering the uid permissions*/); 7194 7195 // Second... is the provider allowing granting of URI permissions? 7196 if (!specialCrossUserGrant) { 7197 if (!pi.grantUriPermissions) { 7198 throw new SecurityException("Provider " + pi.packageName 7199 + "/" + pi.name 7200 + " does not allow granting of Uri permissions (uri " 7201 + grantUri + ")"); 7202 } 7203 if (pi.uriPermissionPatterns != null) { 7204 final int N = pi.uriPermissionPatterns.length; 7205 boolean allowed = false; 7206 for (int i=0; i<N; i++) { 7207 if (pi.uriPermissionPatterns[i] != null 7208 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7209 allowed = true; 7210 break; 7211 } 7212 } 7213 if (!allowed) { 7214 throw new SecurityException("Provider " + pi.packageName 7215 + "/" + pi.name 7216 + " does not allow granting of permission to path of Uri " 7217 + grantUri); 7218 } 7219 } 7220 } 7221 7222 // Third... does the caller itself have permission to access 7223 // this uri? 7224 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7225 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7226 // Require they hold a strong enough Uri permission 7227 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7228 throw new SecurityException("Uid " + callingUid 7229 + " does not have permission to uri " + grantUri); 7230 } 7231 } 7232 } 7233 return targetUid; 7234 } 7235 7236 /** 7237 * @param uri This uri must NOT contain an embedded userId. 7238 * @param userId The userId in which the uri is to be resolved. 7239 */ 7240 @Override 7241 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7242 final int modeFlags, int userId) { 7243 enforceNotIsolatedCaller("checkGrantUriPermission"); 7244 synchronized(this) { 7245 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7246 new GrantUri(userId, uri, false), modeFlags, -1); 7247 } 7248 } 7249 7250 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7251 final int modeFlags, UriPermissionOwner owner) { 7252 if (!Intent.isAccessUriMode(modeFlags)) { 7253 return; 7254 } 7255 7256 // So here we are: the caller has the assumed permission 7257 // to the uri, and the target doesn't. Let's now give this to 7258 // the target. 7259 7260 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7261 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7262 7263 final String authority = grantUri.uri.getAuthority(); 7264 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7265 if (pi == null) { 7266 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7267 return; 7268 } 7269 7270 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7271 grantUri.prefix = true; 7272 } 7273 final UriPermission perm = findOrCreateUriPermissionLocked( 7274 pi.packageName, targetPkg, targetUid, grantUri); 7275 perm.grantModes(modeFlags, owner); 7276 } 7277 7278 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7279 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7280 if (targetPkg == null) { 7281 throw new NullPointerException("targetPkg"); 7282 } 7283 int targetUid; 7284 final IPackageManager pm = AppGlobals.getPackageManager(); 7285 try { 7286 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7287 } catch (RemoteException ex) { 7288 return; 7289 } 7290 7291 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7292 targetUid); 7293 if (targetUid < 0) { 7294 return; 7295 } 7296 7297 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7298 owner); 7299 } 7300 7301 static class NeededUriGrants extends ArrayList<GrantUri> { 7302 final String targetPkg; 7303 final int targetUid; 7304 final int flags; 7305 7306 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7307 this.targetPkg = targetPkg; 7308 this.targetUid = targetUid; 7309 this.flags = flags; 7310 } 7311 } 7312 7313 /** 7314 * Like checkGrantUriPermissionLocked, but takes an Intent. 7315 */ 7316 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7317 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7318 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7319 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7320 + " clip=" + (intent != null ? intent.getClipData() : null) 7321 + " from " + intent + "; flags=0x" 7322 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7323 7324 if (targetPkg == null) { 7325 throw new NullPointerException("targetPkg"); 7326 } 7327 7328 if (intent == null) { 7329 return null; 7330 } 7331 Uri data = intent.getData(); 7332 ClipData clip = intent.getClipData(); 7333 if (data == null && clip == null) { 7334 return null; 7335 } 7336 // Default userId for uris in the intent (if they don't specify it themselves) 7337 int contentUserHint = intent.getContentUserHint(); 7338 if (contentUserHint == UserHandle.USER_CURRENT) { 7339 contentUserHint = UserHandle.getUserId(callingUid); 7340 } 7341 final IPackageManager pm = AppGlobals.getPackageManager(); 7342 int targetUid; 7343 if (needed != null) { 7344 targetUid = needed.targetUid; 7345 } else { 7346 try { 7347 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7348 } catch (RemoteException ex) { 7349 return null; 7350 } 7351 if (targetUid < 0) { 7352 if (DEBUG_URI_PERMISSION) { 7353 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7354 + " on user " + targetUserId); 7355 } 7356 return null; 7357 } 7358 } 7359 if (data != null) { 7360 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7361 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7362 targetUid); 7363 if (targetUid > 0) { 7364 if (needed == null) { 7365 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7366 } 7367 needed.add(grantUri); 7368 } 7369 } 7370 if (clip != null) { 7371 for (int i=0; i<clip.getItemCount(); i++) { 7372 Uri uri = clip.getItemAt(i).getUri(); 7373 if (uri != null) { 7374 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7375 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7376 targetUid); 7377 if (targetUid > 0) { 7378 if (needed == null) { 7379 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7380 } 7381 needed.add(grantUri); 7382 } 7383 } else { 7384 Intent clipIntent = clip.getItemAt(i).getIntent(); 7385 if (clipIntent != null) { 7386 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7387 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7388 if (newNeeded != null) { 7389 needed = newNeeded; 7390 } 7391 } 7392 } 7393 } 7394 } 7395 7396 return needed; 7397 } 7398 7399 /** 7400 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7401 */ 7402 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7403 UriPermissionOwner owner) { 7404 if (needed != null) { 7405 for (int i=0; i<needed.size(); i++) { 7406 GrantUri grantUri = needed.get(i); 7407 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7408 grantUri, needed.flags, owner); 7409 } 7410 } 7411 } 7412 7413 void grantUriPermissionFromIntentLocked(int callingUid, 7414 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7415 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7416 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7417 if (needed == null) { 7418 return; 7419 } 7420 7421 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7422 } 7423 7424 /** 7425 * @param uri This uri must NOT contain an embedded userId. 7426 * @param userId The userId in which the uri is to be resolved. 7427 */ 7428 @Override 7429 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7430 final int modeFlags, int userId) { 7431 enforceNotIsolatedCaller("grantUriPermission"); 7432 GrantUri grantUri = new GrantUri(userId, uri, false); 7433 synchronized(this) { 7434 final ProcessRecord r = getRecordForAppLocked(caller); 7435 if (r == null) { 7436 throw new SecurityException("Unable to find app for caller " 7437 + caller 7438 + " when granting permission to uri " + grantUri); 7439 } 7440 if (targetPkg == null) { 7441 throw new IllegalArgumentException("null target"); 7442 } 7443 if (grantUri == null) { 7444 throw new IllegalArgumentException("null uri"); 7445 } 7446 7447 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7448 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7449 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7450 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7451 7452 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7453 UserHandle.getUserId(r.uid)); 7454 } 7455 } 7456 7457 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7458 if (perm.modeFlags == 0) { 7459 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7460 perm.targetUid); 7461 if (perms != null) { 7462 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7463 "Removing " + perm.targetUid + " permission to " + perm.uri); 7464 7465 perms.remove(perm.uri); 7466 if (perms.isEmpty()) { 7467 mGrantedUriPermissions.remove(perm.targetUid); 7468 } 7469 } 7470 } 7471 } 7472 7473 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7474 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7475 7476 final IPackageManager pm = AppGlobals.getPackageManager(); 7477 final String authority = grantUri.uri.getAuthority(); 7478 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7479 if (pi == null) { 7480 Slog.w(TAG, "No content provider found for permission revoke: " 7481 + grantUri.toSafeString()); 7482 return; 7483 } 7484 7485 // Does the caller have this permission on the URI? 7486 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7487 // Right now, if you are not the original owner of the permission, 7488 // you are not allowed to revoke it. 7489 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7490 throw new SecurityException("Uid " + callingUid 7491 + " does not have permission to uri " + grantUri); 7492 //} 7493 } 7494 7495 boolean persistChanged = false; 7496 7497 // Go through all of the permissions and remove any that match. 7498 int N = mGrantedUriPermissions.size(); 7499 for (int i = 0; i < N; i++) { 7500 final int targetUid = mGrantedUriPermissions.keyAt(i); 7501 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7502 7503 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7504 final UriPermission perm = it.next(); 7505 if (perm.uri.sourceUserId == grantUri.sourceUserId 7506 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7507 if (DEBUG_URI_PERMISSION) 7508 Slog.v(TAG, 7509 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7510 persistChanged |= perm.revokeModes( 7511 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7512 if (perm.modeFlags == 0) { 7513 it.remove(); 7514 } 7515 } 7516 } 7517 7518 if (perms.isEmpty()) { 7519 mGrantedUriPermissions.remove(targetUid); 7520 N--; 7521 i--; 7522 } 7523 } 7524 7525 if (persistChanged) { 7526 schedulePersistUriGrants(); 7527 } 7528 } 7529 7530 /** 7531 * @param uri This uri must NOT contain an embedded userId. 7532 * @param userId The userId in which the uri is to be resolved. 7533 */ 7534 @Override 7535 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7536 int userId) { 7537 enforceNotIsolatedCaller("revokeUriPermission"); 7538 synchronized(this) { 7539 final ProcessRecord r = getRecordForAppLocked(caller); 7540 if (r == null) { 7541 throw new SecurityException("Unable to find app for caller " 7542 + caller 7543 + " when revoking permission to uri " + uri); 7544 } 7545 if (uri == null) { 7546 Slog.w(TAG, "revokeUriPermission: null uri"); 7547 return; 7548 } 7549 7550 if (!Intent.isAccessUriMode(modeFlags)) { 7551 return; 7552 } 7553 7554 final IPackageManager pm = AppGlobals.getPackageManager(); 7555 final String authority = uri.getAuthority(); 7556 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7557 if (pi == null) { 7558 Slog.w(TAG, "No content provider found for permission revoke: " 7559 + uri.toSafeString()); 7560 return; 7561 } 7562 7563 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7564 } 7565 } 7566 7567 /** 7568 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7569 * given package. 7570 * 7571 * @param packageName Package name to match, or {@code null} to apply to all 7572 * packages. 7573 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7574 * to all users. 7575 * @param persistable If persistable grants should be removed. 7576 */ 7577 private void removeUriPermissionsForPackageLocked( 7578 String packageName, int userHandle, boolean persistable) { 7579 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7580 throw new IllegalArgumentException("Must narrow by either package or user"); 7581 } 7582 7583 boolean persistChanged = false; 7584 7585 int N = mGrantedUriPermissions.size(); 7586 for (int i = 0; i < N; i++) { 7587 final int targetUid = mGrantedUriPermissions.keyAt(i); 7588 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7589 7590 // Only inspect grants matching user 7591 if (userHandle == UserHandle.USER_ALL 7592 || userHandle == UserHandle.getUserId(targetUid)) { 7593 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7594 final UriPermission perm = it.next(); 7595 7596 // Only inspect grants matching package 7597 if (packageName == null || perm.sourcePkg.equals(packageName) 7598 || perm.targetPkg.equals(packageName)) { 7599 persistChanged |= perm.revokeModes( 7600 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7601 7602 // Only remove when no modes remain; any persisted grants 7603 // will keep this alive. 7604 if (perm.modeFlags == 0) { 7605 it.remove(); 7606 } 7607 } 7608 } 7609 7610 if (perms.isEmpty()) { 7611 mGrantedUriPermissions.remove(targetUid); 7612 N--; 7613 i--; 7614 } 7615 } 7616 } 7617 7618 if (persistChanged) { 7619 schedulePersistUriGrants(); 7620 } 7621 } 7622 7623 @Override 7624 public IBinder newUriPermissionOwner(String name) { 7625 enforceNotIsolatedCaller("newUriPermissionOwner"); 7626 synchronized(this) { 7627 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7628 return owner.getExternalTokenLocked(); 7629 } 7630 } 7631 7632 /** 7633 * @param uri This uri must NOT contain an embedded userId. 7634 * @param sourceUserId The userId in which the uri is to be resolved. 7635 * @param targetUserId The userId of the app that receives the grant. 7636 */ 7637 @Override 7638 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7639 final int modeFlags, int sourceUserId, int targetUserId) { 7640 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7641 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7642 synchronized(this) { 7643 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7644 if (owner == null) { 7645 throw new IllegalArgumentException("Unknown owner: " + token); 7646 } 7647 if (fromUid != Binder.getCallingUid()) { 7648 if (Binder.getCallingUid() != Process.myUid()) { 7649 // Only system code can grant URI permissions on behalf 7650 // of other users. 7651 throw new SecurityException("nice try"); 7652 } 7653 } 7654 if (targetPkg == null) { 7655 throw new IllegalArgumentException("null target"); 7656 } 7657 if (uri == null) { 7658 throw new IllegalArgumentException("null uri"); 7659 } 7660 7661 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7662 modeFlags, owner, targetUserId); 7663 } 7664 } 7665 7666 /** 7667 * @param uri This uri must NOT contain an embedded userId. 7668 * @param userId The userId in which the uri is to be resolved. 7669 */ 7670 @Override 7671 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7672 synchronized(this) { 7673 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7674 if (owner == null) { 7675 throw new IllegalArgumentException("Unknown owner: " + token); 7676 } 7677 7678 if (uri == null) { 7679 owner.removeUriPermissionsLocked(mode); 7680 } else { 7681 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7682 } 7683 } 7684 } 7685 7686 private void schedulePersistUriGrants() { 7687 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7688 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7689 10 * DateUtils.SECOND_IN_MILLIS); 7690 } 7691 } 7692 7693 private void writeGrantedUriPermissions() { 7694 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7695 7696 // Snapshot permissions so we can persist without lock 7697 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7698 synchronized (this) { 7699 final int size = mGrantedUriPermissions.size(); 7700 for (int i = 0; i < size; i++) { 7701 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7702 for (UriPermission perm : perms.values()) { 7703 if (perm.persistedModeFlags != 0) { 7704 persist.add(perm.snapshot()); 7705 } 7706 } 7707 } 7708 } 7709 7710 FileOutputStream fos = null; 7711 try { 7712 fos = mGrantFile.startWrite(); 7713 7714 XmlSerializer out = new FastXmlSerializer(); 7715 out.setOutput(fos, "utf-8"); 7716 out.startDocument(null, true); 7717 out.startTag(null, TAG_URI_GRANTS); 7718 for (UriPermission.Snapshot perm : persist) { 7719 out.startTag(null, TAG_URI_GRANT); 7720 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7721 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7722 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7723 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7724 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7725 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7726 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7727 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7728 out.endTag(null, TAG_URI_GRANT); 7729 } 7730 out.endTag(null, TAG_URI_GRANTS); 7731 out.endDocument(); 7732 7733 mGrantFile.finishWrite(fos); 7734 } catch (IOException e) { 7735 if (fos != null) { 7736 mGrantFile.failWrite(fos); 7737 } 7738 } 7739 } 7740 7741 private void readGrantedUriPermissionsLocked() { 7742 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7743 7744 final long now = System.currentTimeMillis(); 7745 7746 FileInputStream fis = null; 7747 try { 7748 fis = mGrantFile.openRead(); 7749 final XmlPullParser in = Xml.newPullParser(); 7750 in.setInput(fis, null); 7751 7752 int type; 7753 while ((type = in.next()) != END_DOCUMENT) { 7754 final String tag = in.getName(); 7755 if (type == START_TAG) { 7756 if (TAG_URI_GRANT.equals(tag)) { 7757 final int sourceUserId; 7758 final int targetUserId; 7759 final int userHandle = readIntAttribute(in, 7760 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7761 if (userHandle != UserHandle.USER_NULL) { 7762 // For backwards compatibility. 7763 sourceUserId = userHandle; 7764 targetUserId = userHandle; 7765 } else { 7766 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7767 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7768 } 7769 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7770 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7771 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7772 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7773 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7774 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7775 7776 // Sanity check that provider still belongs to source package 7777 final ProviderInfo pi = getProviderInfoLocked( 7778 uri.getAuthority(), sourceUserId); 7779 if (pi != null && sourcePkg.equals(pi.packageName)) { 7780 int targetUid = -1; 7781 try { 7782 targetUid = AppGlobals.getPackageManager() 7783 .getPackageUid(targetPkg, targetUserId); 7784 } catch (RemoteException e) { 7785 } 7786 if (targetUid != -1) { 7787 final UriPermission perm = findOrCreateUriPermissionLocked( 7788 sourcePkg, targetPkg, targetUid, 7789 new GrantUri(sourceUserId, uri, prefix)); 7790 perm.initPersistedModes(modeFlags, createdTime); 7791 } 7792 } else { 7793 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7794 + " but instead found " + pi); 7795 } 7796 } 7797 } 7798 } 7799 } catch (FileNotFoundException e) { 7800 // Missing grants is okay 7801 } catch (IOException e) { 7802 Log.wtf(TAG, "Failed reading Uri grants", e); 7803 } catch (XmlPullParserException e) { 7804 Log.wtf(TAG, "Failed reading Uri grants", e); 7805 } finally { 7806 IoUtils.closeQuietly(fis); 7807 } 7808 } 7809 7810 /** 7811 * @param uri This uri must NOT contain an embedded userId. 7812 * @param userId The userId in which the uri is to be resolved. 7813 */ 7814 @Override 7815 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7816 enforceNotIsolatedCaller("takePersistableUriPermission"); 7817 7818 Preconditions.checkFlagsArgument(modeFlags, 7819 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7820 7821 synchronized (this) { 7822 final int callingUid = Binder.getCallingUid(); 7823 boolean persistChanged = false; 7824 GrantUri grantUri = new GrantUri(userId, uri, false); 7825 7826 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7827 new GrantUri(userId, uri, false)); 7828 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7829 new GrantUri(userId, uri, true)); 7830 7831 final boolean exactValid = (exactPerm != null) 7832 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7833 final boolean prefixValid = (prefixPerm != null) 7834 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7835 7836 if (!(exactValid || prefixValid)) { 7837 throw new SecurityException("No persistable permission grants found for UID " 7838 + callingUid + " and Uri " + grantUri.toSafeString()); 7839 } 7840 7841 if (exactValid) { 7842 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7843 } 7844 if (prefixValid) { 7845 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7846 } 7847 7848 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7849 7850 if (persistChanged) { 7851 schedulePersistUriGrants(); 7852 } 7853 } 7854 } 7855 7856 /** 7857 * @param uri This uri must NOT contain an embedded userId. 7858 * @param userId The userId in which the uri is to be resolved. 7859 */ 7860 @Override 7861 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7862 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7863 7864 Preconditions.checkFlagsArgument(modeFlags, 7865 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7866 7867 synchronized (this) { 7868 final int callingUid = Binder.getCallingUid(); 7869 boolean persistChanged = false; 7870 7871 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7872 new GrantUri(userId, uri, false)); 7873 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7874 new GrantUri(userId, uri, true)); 7875 if (exactPerm == null && prefixPerm == null) { 7876 throw new SecurityException("No permission grants found for UID " + callingUid 7877 + " and Uri " + uri.toSafeString()); 7878 } 7879 7880 if (exactPerm != null) { 7881 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7882 removeUriPermissionIfNeededLocked(exactPerm); 7883 } 7884 if (prefixPerm != null) { 7885 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7886 removeUriPermissionIfNeededLocked(prefixPerm); 7887 } 7888 7889 if (persistChanged) { 7890 schedulePersistUriGrants(); 7891 } 7892 } 7893 } 7894 7895 /** 7896 * Prune any older {@link UriPermission} for the given UID until outstanding 7897 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7898 * 7899 * @return if any mutations occured that require persisting. 7900 */ 7901 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7902 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7903 if (perms == null) return false; 7904 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7905 7906 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7907 for (UriPermission perm : perms.values()) { 7908 if (perm.persistedModeFlags != 0) { 7909 persisted.add(perm); 7910 } 7911 } 7912 7913 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7914 if (trimCount <= 0) return false; 7915 7916 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7917 for (int i = 0; i < trimCount; i++) { 7918 final UriPermission perm = persisted.get(i); 7919 7920 if (DEBUG_URI_PERMISSION) { 7921 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7922 } 7923 7924 perm.releasePersistableModes(~0); 7925 removeUriPermissionIfNeededLocked(perm); 7926 } 7927 7928 return true; 7929 } 7930 7931 @Override 7932 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7933 String packageName, boolean incoming) { 7934 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7935 Preconditions.checkNotNull(packageName, "packageName"); 7936 7937 final int callingUid = Binder.getCallingUid(); 7938 final IPackageManager pm = AppGlobals.getPackageManager(); 7939 try { 7940 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7941 if (packageUid != callingUid) { 7942 throw new SecurityException( 7943 "Package " + packageName + " does not belong to calling UID " + callingUid); 7944 } 7945 } catch (RemoteException e) { 7946 throw new SecurityException("Failed to verify package name ownership"); 7947 } 7948 7949 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7950 synchronized (this) { 7951 if (incoming) { 7952 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7953 callingUid); 7954 if (perms == null) { 7955 Slog.w(TAG, "No permission grants found for " + packageName); 7956 } else { 7957 for (UriPermission perm : perms.values()) { 7958 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7959 result.add(perm.buildPersistedPublicApiObject()); 7960 } 7961 } 7962 } 7963 } else { 7964 final int size = mGrantedUriPermissions.size(); 7965 for (int i = 0; i < size; i++) { 7966 final ArrayMap<GrantUri, UriPermission> perms = 7967 mGrantedUriPermissions.valueAt(i); 7968 for (UriPermission perm : perms.values()) { 7969 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7970 result.add(perm.buildPersistedPublicApiObject()); 7971 } 7972 } 7973 } 7974 } 7975 } 7976 return new ParceledListSlice<android.content.UriPermission>(result); 7977 } 7978 7979 @Override 7980 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7981 synchronized (this) { 7982 ProcessRecord app = 7983 who != null ? getRecordForAppLocked(who) : null; 7984 if (app == null) return; 7985 7986 Message msg = Message.obtain(); 7987 msg.what = WAIT_FOR_DEBUGGER_MSG; 7988 msg.obj = app; 7989 msg.arg1 = waiting ? 1 : 0; 7990 mHandler.sendMessage(msg); 7991 } 7992 } 7993 7994 @Override 7995 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7996 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7997 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7998 outInfo.availMem = Process.getFreeMemory(); 7999 outInfo.totalMem = Process.getTotalMemory(); 8000 outInfo.threshold = homeAppMem; 8001 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 8002 outInfo.hiddenAppThreshold = cachedAppMem; 8003 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 8004 ProcessList.SERVICE_ADJ); 8005 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 8006 ProcessList.VISIBLE_APP_ADJ); 8007 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 8008 ProcessList.FOREGROUND_APP_ADJ); 8009 } 8010 8011 // ========================================================= 8012 // TASK MANAGEMENT 8013 // ========================================================= 8014 8015 @Override 8016 public List<IAppTask> getAppTasks(String callingPackage) { 8017 int callingUid = Binder.getCallingUid(); 8018 long ident = Binder.clearCallingIdentity(); 8019 8020 synchronized(this) { 8021 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 8022 try { 8023 if (localLOGV) Slog.v(TAG, "getAppTasks"); 8024 8025 final int N = mRecentTasks.size(); 8026 for (int i = 0; i < N; i++) { 8027 TaskRecord tr = mRecentTasks.get(i); 8028 // Skip tasks that do not match the caller. We don't need to verify 8029 // callingPackage, because we are also limiting to callingUid and know 8030 // that will limit to the correct security sandbox. 8031 if (tr.effectiveUid != callingUid) { 8032 continue; 8033 } 8034 Intent intent = tr.getBaseIntent(); 8035 if (intent == null || 8036 !callingPackage.equals(intent.getComponent().getPackageName())) { 8037 continue; 8038 } 8039 ActivityManager.RecentTaskInfo taskInfo = 8040 createRecentTaskInfoFromTaskRecord(tr); 8041 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 8042 list.add(taskImpl); 8043 } 8044 } finally { 8045 Binder.restoreCallingIdentity(ident); 8046 } 8047 return list; 8048 } 8049 } 8050 8051 @Override 8052 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8053 final int callingUid = Binder.getCallingUid(); 8054 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8055 8056 synchronized(this) { 8057 if (localLOGV) Slog.v( 8058 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8059 8060 final boolean allowed = checkCallingPermission( 8061 android.Manifest.permission.GET_TASKS) 8062 == PackageManager.PERMISSION_GRANTED; 8063 if (!allowed) { 8064 Slog.w(TAG, "getTasks: caller " + callingUid 8065 + " does not hold GET_TASKS; limiting output"); 8066 } 8067 8068 // TODO: Improve with MRU list from all ActivityStacks. 8069 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8070 } 8071 8072 return list; 8073 } 8074 8075 TaskRecord getMostRecentTask() { 8076 return mRecentTasks.get(0); 8077 } 8078 8079 /** 8080 * Creates a new RecentTaskInfo from a TaskRecord. 8081 */ 8082 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8083 // Update the task description to reflect any changes in the task stack 8084 tr.updateTaskDescription(); 8085 8086 // Compose the recent task info 8087 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8088 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8089 rti.persistentId = tr.taskId; 8090 rti.baseIntent = new Intent(tr.getBaseIntent()); 8091 rti.origActivity = tr.origActivity; 8092 rti.description = tr.lastDescription; 8093 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8094 rti.userId = tr.userId; 8095 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8096 rti.firstActiveTime = tr.firstActiveTime; 8097 rti.lastActiveTime = tr.lastActiveTime; 8098 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8099 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8100 return rti; 8101 } 8102 8103 @Override 8104 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8105 final int callingUid = Binder.getCallingUid(); 8106 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8107 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8108 8109 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8110 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8111 synchronized (this) { 8112 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8113 == PackageManager.PERMISSION_GRANTED; 8114 if (!allowed) { 8115 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8116 + " does not hold GET_TASKS; limiting output"); 8117 } 8118 final boolean detailed = checkCallingPermission( 8119 android.Manifest.permission.GET_DETAILED_TASKS) 8120 == PackageManager.PERMISSION_GRANTED; 8121 8122 final int N = mRecentTasks.size(); 8123 ArrayList<ActivityManager.RecentTaskInfo> res 8124 = new ArrayList<ActivityManager.RecentTaskInfo>( 8125 maxNum < N ? maxNum : N); 8126 8127 final Set<Integer> includedUsers; 8128 if (includeProfiles) { 8129 includedUsers = getProfileIdsLocked(userId); 8130 } else { 8131 includedUsers = new HashSet<Integer>(); 8132 } 8133 includedUsers.add(Integer.valueOf(userId)); 8134 8135 for (int i=0; i<N && maxNum > 0; i++) { 8136 TaskRecord tr = mRecentTasks.get(i); 8137 // Only add calling user or related users recent tasks 8138 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8139 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8140 continue; 8141 } 8142 8143 // Return the entry if desired by the caller. We always return 8144 // the first entry, because callers always expect this to be the 8145 // foreground app. We may filter others if the caller has 8146 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8147 // we should exclude the entry. 8148 8149 if (i == 0 8150 || withExcluded 8151 || (tr.intent == null) 8152 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8153 == 0)) { 8154 if (!allowed) { 8155 // If the caller doesn't have the GET_TASKS permission, then only 8156 // allow them to see a small subset of tasks -- their own and home. 8157 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8158 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8159 continue; 8160 } 8161 } 8162 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8163 if (tr.stack != null && tr.stack.isHomeStack()) { 8164 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8165 continue; 8166 } 8167 } 8168 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8169 // Don't include auto remove tasks that are finished or finishing. 8170 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8171 + tr); 8172 continue; 8173 } 8174 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8175 && !tr.isAvailable) { 8176 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8177 continue; 8178 } 8179 8180 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8181 if (!detailed) { 8182 rti.baseIntent.replaceExtras((Bundle)null); 8183 } 8184 8185 res.add(rti); 8186 maxNum--; 8187 } 8188 } 8189 return res; 8190 } 8191 } 8192 8193 private TaskRecord recentTaskForIdLocked(int id) { 8194 final int N = mRecentTasks.size(); 8195 for (int i=0; i<N; i++) { 8196 TaskRecord tr = mRecentTasks.get(i); 8197 if (tr.taskId == id) { 8198 return tr; 8199 } 8200 } 8201 return null; 8202 } 8203 8204 @Override 8205 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8206 synchronized (this) { 8207 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8208 "getTaskThumbnail()"); 8209 TaskRecord tr = recentTaskForIdLocked(id); 8210 if (tr != null) { 8211 return tr.getTaskThumbnailLocked(); 8212 } 8213 } 8214 return null; 8215 } 8216 8217 @Override 8218 public int addAppTask(IBinder activityToken, Intent intent, 8219 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8220 final int callingUid = Binder.getCallingUid(); 8221 final long callingIdent = Binder.clearCallingIdentity(); 8222 8223 try { 8224 synchronized (this) { 8225 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8226 if (r == null) { 8227 throw new IllegalArgumentException("Activity does not exist; token=" 8228 + activityToken); 8229 } 8230 ComponentName comp = intent.getComponent(); 8231 if (comp == null) { 8232 throw new IllegalArgumentException("Intent " + intent 8233 + " must specify explicit component"); 8234 } 8235 if (thumbnail.getWidth() != mThumbnailWidth 8236 || thumbnail.getHeight() != mThumbnailHeight) { 8237 throw new IllegalArgumentException("Bad thumbnail size: got " 8238 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8239 + mThumbnailWidth + "x" + mThumbnailHeight); 8240 } 8241 if (intent.getSelector() != null) { 8242 intent.setSelector(null); 8243 } 8244 if (intent.getSourceBounds() != null) { 8245 intent.setSourceBounds(null); 8246 } 8247 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8248 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8249 // The caller has added this as an auto-remove task... that makes no 8250 // sense, so turn off auto-remove. 8251 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8252 } 8253 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8254 // Must be a new task. 8255 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8256 } 8257 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8258 mLastAddedTaskActivity = null; 8259 } 8260 ActivityInfo ainfo = mLastAddedTaskActivity; 8261 if (ainfo == null) { 8262 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8263 comp, 0, UserHandle.getUserId(callingUid)); 8264 if (ainfo.applicationInfo.uid != callingUid) { 8265 throw new SecurityException( 8266 "Can't add task for another application: target uid=" 8267 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8268 } 8269 } 8270 8271 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8272 intent, description); 8273 8274 int trimIdx = trimRecentsForTask(task, false); 8275 if (trimIdx >= 0) { 8276 // If this would have caused a trim, then we'll abort because that 8277 // means it would be added at the end of the list but then just removed. 8278 return -1; 8279 } 8280 8281 final int N = mRecentTasks.size(); 8282 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8283 final TaskRecord tr = mRecentTasks.remove(N - 1); 8284 tr.removedFromRecents(mTaskPersister); 8285 } 8286 8287 task.inRecents = true; 8288 mRecentTasks.add(task); 8289 r.task.stack.addTask(task, false, false); 8290 8291 task.setLastThumbnail(thumbnail); 8292 task.freeLastThumbnail(); 8293 8294 return task.taskId; 8295 } 8296 } finally { 8297 Binder.restoreCallingIdentity(callingIdent); 8298 } 8299 } 8300 8301 @Override 8302 public Point getAppTaskThumbnailSize() { 8303 synchronized (this) { 8304 return new Point(mThumbnailWidth, mThumbnailHeight); 8305 } 8306 } 8307 8308 @Override 8309 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8310 synchronized (this) { 8311 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8312 if (r != null) { 8313 r.taskDescription = td; 8314 r.task.updateTaskDescription(); 8315 } 8316 } 8317 } 8318 8319 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8320 mRecentTasks.remove(tr); 8321 tr.removedFromRecents(mTaskPersister); 8322 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8323 Intent baseIntent = new Intent( 8324 tr.intent != null ? tr.intent : tr.affinityIntent); 8325 ComponentName component = baseIntent.getComponent(); 8326 if (component == null) { 8327 Slog.w(TAG, "Now component for base intent of task: " + tr); 8328 return; 8329 } 8330 8331 // Find any running services associated with this app. 8332 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8333 8334 if (killProcesses) { 8335 // Find any running processes associated with this app. 8336 final String pkg = component.getPackageName(); 8337 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8338 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8339 for (int i=0; i<pmap.size(); i++) { 8340 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8341 for (int j=0; j<uids.size(); j++) { 8342 ProcessRecord proc = uids.valueAt(j); 8343 if (proc.userId != tr.userId) { 8344 continue; 8345 } 8346 if (!proc.pkgList.containsKey(pkg)) { 8347 continue; 8348 } 8349 procs.add(proc); 8350 } 8351 } 8352 8353 // Kill the running processes. 8354 for (int i=0; i<procs.size(); i++) { 8355 ProcessRecord pr = procs.get(i); 8356 if (pr == mHomeProcess) { 8357 // Don't kill the home process along with tasks from the same package. 8358 continue; 8359 } 8360 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8361 pr.kill("remove task", true); 8362 } else { 8363 pr.waitingToKill = "remove task"; 8364 } 8365 } 8366 } 8367 } 8368 8369 /** 8370 * Removes the task with the specified task id. 8371 * 8372 * @param taskId Identifier of the task to be removed. 8373 * @param flags Additional operational flags. May be 0 or 8374 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8375 * @return Returns true if the given task was found and removed. 8376 */ 8377 private boolean removeTaskByIdLocked(int taskId, int flags) { 8378 TaskRecord tr = recentTaskForIdLocked(taskId); 8379 if (tr != null) { 8380 tr.removeTaskActivitiesLocked(); 8381 cleanUpRemovedTaskLocked(tr, flags); 8382 if (tr.isPersistable) { 8383 notifyTaskPersisterLocked(null, true); 8384 } 8385 return true; 8386 } 8387 return false; 8388 } 8389 8390 @Override 8391 public boolean removeTask(int taskId, int flags) { 8392 synchronized (this) { 8393 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8394 "removeTask()"); 8395 long ident = Binder.clearCallingIdentity(); 8396 try { 8397 return removeTaskByIdLocked(taskId, flags); 8398 } finally { 8399 Binder.restoreCallingIdentity(ident); 8400 } 8401 } 8402 } 8403 8404 /** 8405 * TODO: Add mController hook 8406 */ 8407 @Override 8408 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8409 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8410 "moveTaskToFront()"); 8411 8412 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8413 synchronized(this) { 8414 moveTaskToFrontLocked(taskId, flags, options); 8415 } 8416 } 8417 8418 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8419 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8420 Binder.getCallingUid(), "Task to front")) { 8421 ActivityOptions.abort(options); 8422 return; 8423 } 8424 final long origId = Binder.clearCallingIdentity(); 8425 try { 8426 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8427 if (task == null) { 8428 return; 8429 } 8430 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8431 mStackSupervisor.showLockTaskToast(); 8432 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8433 return; 8434 } 8435 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8436 if (prev != null && prev.isRecentsActivity()) { 8437 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8438 } 8439 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8440 } finally { 8441 Binder.restoreCallingIdentity(origId); 8442 } 8443 ActivityOptions.abort(options); 8444 } 8445 8446 @Override 8447 public void moveTaskToBack(int taskId) { 8448 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8449 "moveTaskToBack()"); 8450 8451 synchronized(this) { 8452 TaskRecord tr = recentTaskForIdLocked(taskId); 8453 if (tr != null) { 8454 if (tr == mStackSupervisor.mLockTaskModeTask) { 8455 mStackSupervisor.showLockTaskToast(); 8456 return; 8457 } 8458 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8459 ActivityStack stack = tr.stack; 8460 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8461 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8462 Binder.getCallingUid(), "Task to back")) { 8463 return; 8464 } 8465 } 8466 final long origId = Binder.clearCallingIdentity(); 8467 try { 8468 stack.moveTaskToBackLocked(taskId, null); 8469 } finally { 8470 Binder.restoreCallingIdentity(origId); 8471 } 8472 } 8473 } 8474 } 8475 8476 /** 8477 * Moves an activity, and all of the other activities within the same task, to the bottom 8478 * of the history stack. The activity's order within the task is unchanged. 8479 * 8480 * @param token A reference to the activity we wish to move 8481 * @param nonRoot If false then this only works if the activity is the root 8482 * of a task; if true it will work for any activity in a task. 8483 * @return Returns true if the move completed, false if not. 8484 */ 8485 @Override 8486 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8487 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8488 synchronized(this) { 8489 final long origId = Binder.clearCallingIdentity(); 8490 try { 8491 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8492 if (taskId >= 0) { 8493 if ((mStackSupervisor.mLockTaskModeTask != null) 8494 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8495 mStackSupervisor.showLockTaskToast(); 8496 return false; 8497 } 8498 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8499 } 8500 } finally { 8501 Binder.restoreCallingIdentity(origId); 8502 } 8503 } 8504 return false; 8505 } 8506 8507 @Override 8508 public void moveTaskBackwards(int task) { 8509 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8510 "moveTaskBackwards()"); 8511 8512 synchronized(this) { 8513 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8514 Binder.getCallingUid(), "Task backwards")) { 8515 return; 8516 } 8517 final long origId = Binder.clearCallingIdentity(); 8518 moveTaskBackwardsLocked(task); 8519 Binder.restoreCallingIdentity(origId); 8520 } 8521 } 8522 8523 private final void moveTaskBackwardsLocked(int task) { 8524 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8525 } 8526 8527 @Override 8528 public IBinder getHomeActivityToken() throws RemoteException { 8529 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8530 "getHomeActivityToken()"); 8531 synchronized (this) { 8532 return mStackSupervisor.getHomeActivityToken(); 8533 } 8534 } 8535 8536 @Override 8537 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8538 IActivityContainerCallback callback) throws RemoteException { 8539 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8540 "createActivityContainer()"); 8541 synchronized (this) { 8542 if (parentActivityToken == null) { 8543 throw new IllegalArgumentException("parent token must not be null"); 8544 } 8545 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8546 if (r == null) { 8547 return null; 8548 } 8549 if (callback == null) { 8550 throw new IllegalArgumentException("callback must not be null"); 8551 } 8552 return mStackSupervisor.createActivityContainer(r, callback); 8553 } 8554 } 8555 8556 @Override 8557 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8558 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8559 "deleteActivityContainer()"); 8560 synchronized (this) { 8561 mStackSupervisor.deleteActivityContainer(container); 8562 } 8563 } 8564 8565 @Override 8566 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8567 throws RemoteException { 8568 synchronized (this) { 8569 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8570 if (stack != null) { 8571 return stack.mActivityContainer; 8572 } 8573 return null; 8574 } 8575 } 8576 8577 @Override 8578 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8579 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8580 "moveTaskToStack()"); 8581 if (stackId == HOME_STACK_ID) { 8582 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8583 new RuntimeException("here").fillInStackTrace()); 8584 } 8585 synchronized (this) { 8586 long ident = Binder.clearCallingIdentity(); 8587 try { 8588 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8589 + stackId + " toTop=" + toTop); 8590 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8591 } finally { 8592 Binder.restoreCallingIdentity(ident); 8593 } 8594 } 8595 } 8596 8597 @Override 8598 public void resizeStack(int stackBoxId, Rect bounds) { 8599 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8600 "resizeStackBox()"); 8601 long ident = Binder.clearCallingIdentity(); 8602 try { 8603 mWindowManager.resizeStack(stackBoxId, bounds); 8604 } finally { 8605 Binder.restoreCallingIdentity(ident); 8606 } 8607 } 8608 8609 @Override 8610 public List<StackInfo> getAllStackInfos() { 8611 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8612 "getAllStackInfos()"); 8613 long ident = Binder.clearCallingIdentity(); 8614 try { 8615 synchronized (this) { 8616 return mStackSupervisor.getAllStackInfosLocked(); 8617 } 8618 } finally { 8619 Binder.restoreCallingIdentity(ident); 8620 } 8621 } 8622 8623 @Override 8624 public StackInfo getStackInfo(int stackId) { 8625 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8626 "getStackInfo()"); 8627 long ident = Binder.clearCallingIdentity(); 8628 try { 8629 synchronized (this) { 8630 return mStackSupervisor.getStackInfoLocked(stackId); 8631 } 8632 } finally { 8633 Binder.restoreCallingIdentity(ident); 8634 } 8635 } 8636 8637 @Override 8638 public boolean isInHomeStack(int taskId) { 8639 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8640 "getStackInfo()"); 8641 long ident = Binder.clearCallingIdentity(); 8642 try { 8643 synchronized (this) { 8644 TaskRecord tr = recentTaskForIdLocked(taskId); 8645 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8646 } 8647 } finally { 8648 Binder.restoreCallingIdentity(ident); 8649 } 8650 } 8651 8652 @Override 8653 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8654 synchronized(this) { 8655 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8656 } 8657 } 8658 8659 private boolean isLockTaskAuthorized(String pkg) { 8660 final DevicePolicyManager dpm = (DevicePolicyManager) 8661 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8662 try { 8663 int uid = mContext.getPackageManager().getPackageUid(pkg, 8664 Binder.getCallingUserHandle().getIdentifier()); 8665 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8666 } catch (NameNotFoundException e) { 8667 return false; 8668 } 8669 } 8670 8671 void startLockTaskMode(TaskRecord task) { 8672 final String pkg; 8673 synchronized (this) { 8674 pkg = task.intent.getComponent().getPackageName(); 8675 } 8676 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8677 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8678 final TaskRecord taskRecord = task; 8679 mHandler.post(new Runnable() { 8680 @Override 8681 public void run() { 8682 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8683 } 8684 }); 8685 return; 8686 } 8687 long ident = Binder.clearCallingIdentity(); 8688 try { 8689 synchronized (this) { 8690 // Since we lost lock on task, make sure it is still there. 8691 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8692 if (task != null) { 8693 if (!isSystemInitiated 8694 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8695 throw new IllegalArgumentException("Invalid task, not in foreground"); 8696 } 8697 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8698 } 8699 } 8700 } finally { 8701 Binder.restoreCallingIdentity(ident); 8702 } 8703 } 8704 8705 @Override 8706 public void startLockTaskMode(int taskId) { 8707 final TaskRecord task; 8708 long ident = Binder.clearCallingIdentity(); 8709 try { 8710 synchronized (this) { 8711 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8712 } 8713 } finally { 8714 Binder.restoreCallingIdentity(ident); 8715 } 8716 if (task != null) { 8717 startLockTaskMode(task); 8718 } 8719 } 8720 8721 @Override 8722 public void startLockTaskMode(IBinder token) { 8723 final TaskRecord task; 8724 long ident = Binder.clearCallingIdentity(); 8725 try { 8726 synchronized (this) { 8727 final ActivityRecord r = ActivityRecord.forToken(token); 8728 if (r == null) { 8729 return; 8730 } 8731 task = r.task; 8732 } 8733 } finally { 8734 Binder.restoreCallingIdentity(ident); 8735 } 8736 if (task != null) { 8737 startLockTaskMode(task); 8738 } 8739 } 8740 8741 @Override 8742 public void startLockTaskModeOnCurrent() throws RemoteException { 8743 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8744 "startLockTaskModeOnCurrent"); 8745 ActivityRecord r = null; 8746 synchronized (this) { 8747 r = mStackSupervisor.topRunningActivityLocked(); 8748 } 8749 startLockTaskMode(r.task); 8750 } 8751 8752 @Override 8753 public void stopLockTaskMode() { 8754 // Verify that the user matches the package of the intent for the TaskRecord 8755 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8756 // and stopLockTaskMode. 8757 final int callingUid = Binder.getCallingUid(); 8758 if (callingUid != Process.SYSTEM_UID) { 8759 try { 8760 String pkg = 8761 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8762 int uid = mContext.getPackageManager().getPackageUid(pkg, 8763 Binder.getCallingUserHandle().getIdentifier()); 8764 if (uid != callingUid) { 8765 throw new SecurityException("Invalid uid, expected " + uid); 8766 } 8767 } catch (NameNotFoundException e) { 8768 Log.d(TAG, "stopLockTaskMode " + e); 8769 return; 8770 } 8771 } 8772 long ident = Binder.clearCallingIdentity(); 8773 try { 8774 Log.d(TAG, "stopLockTaskMode"); 8775 // Stop lock task 8776 synchronized (this) { 8777 mStackSupervisor.setLockTaskModeLocked(null, false); 8778 } 8779 } finally { 8780 Binder.restoreCallingIdentity(ident); 8781 } 8782 } 8783 8784 @Override 8785 public void stopLockTaskModeOnCurrent() throws RemoteException { 8786 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8787 "stopLockTaskModeOnCurrent"); 8788 long ident = Binder.clearCallingIdentity(); 8789 try { 8790 stopLockTaskMode(); 8791 } finally { 8792 Binder.restoreCallingIdentity(ident); 8793 } 8794 } 8795 8796 @Override 8797 public boolean isInLockTaskMode() { 8798 synchronized (this) { 8799 return mStackSupervisor.isInLockTaskMode(); 8800 } 8801 } 8802 8803 // ========================================================= 8804 // CONTENT PROVIDERS 8805 // ========================================================= 8806 8807 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8808 List<ProviderInfo> providers = null; 8809 try { 8810 providers = AppGlobals.getPackageManager(). 8811 queryContentProviders(app.processName, app.uid, 8812 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8813 } catch (RemoteException ex) { 8814 } 8815 if (DEBUG_MU) 8816 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8817 int userId = app.userId; 8818 if (providers != null) { 8819 int N = providers.size(); 8820 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8821 for (int i=0; i<N; i++) { 8822 ProviderInfo cpi = 8823 (ProviderInfo)providers.get(i); 8824 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8825 cpi.name, cpi.flags); 8826 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8827 // This is a singleton provider, but a user besides the 8828 // default user is asking to initialize a process it runs 8829 // in... well, no, it doesn't actually run in this process, 8830 // it runs in the process of the default user. Get rid of it. 8831 providers.remove(i); 8832 N--; 8833 i--; 8834 continue; 8835 } 8836 8837 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8838 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8839 if (cpr == null) { 8840 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8841 mProviderMap.putProviderByClass(comp, cpr); 8842 } 8843 if (DEBUG_MU) 8844 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8845 app.pubProviders.put(cpi.name, cpr); 8846 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8847 // Don't add this if it is a platform component that is marked 8848 // to run in multiple processes, because this is actually 8849 // part of the framework so doesn't make sense to track as a 8850 // separate apk in the process. 8851 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8852 mProcessStats); 8853 } 8854 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8855 } 8856 } 8857 return providers; 8858 } 8859 8860 /** 8861 * Check if {@link ProcessRecord} has a possible chance at accessing the 8862 * given {@link ProviderInfo}. Final permission checking is always done 8863 * in {@link ContentProvider}. 8864 */ 8865 private final String checkContentProviderPermissionLocked( 8866 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8867 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8868 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8869 boolean checkedGrants = false; 8870 if (checkUser) { 8871 // Looking for cross-user grants before enforcing the typical cross-users permissions 8872 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8873 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8874 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8875 return null; 8876 } 8877 checkedGrants = true; 8878 } 8879 userId = handleIncomingUser(callingPid, callingUid, userId, 8880 false, ALLOW_NON_FULL, 8881 "checkContentProviderPermissionLocked " + cpi.authority, null); 8882 if (userId != tmpTargetUserId) { 8883 // When we actually went to determine the final targer user ID, this ended 8884 // up different than our initial check for the authority. This is because 8885 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8886 // SELF. So we need to re-check the grants again. 8887 checkedGrants = false; 8888 } 8889 } 8890 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8891 cpi.applicationInfo.uid, cpi.exported) 8892 == PackageManager.PERMISSION_GRANTED) { 8893 return null; 8894 } 8895 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8896 cpi.applicationInfo.uid, cpi.exported) 8897 == PackageManager.PERMISSION_GRANTED) { 8898 return null; 8899 } 8900 8901 PathPermission[] pps = cpi.pathPermissions; 8902 if (pps != null) { 8903 int i = pps.length; 8904 while (i > 0) { 8905 i--; 8906 PathPermission pp = pps[i]; 8907 String pprperm = pp.getReadPermission(); 8908 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8909 cpi.applicationInfo.uid, cpi.exported) 8910 == PackageManager.PERMISSION_GRANTED) { 8911 return null; 8912 } 8913 String ppwperm = pp.getWritePermission(); 8914 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8915 cpi.applicationInfo.uid, cpi.exported) 8916 == PackageManager.PERMISSION_GRANTED) { 8917 return null; 8918 } 8919 } 8920 } 8921 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8922 return null; 8923 } 8924 8925 String msg; 8926 if (!cpi.exported) { 8927 msg = "Permission Denial: opening provider " + cpi.name 8928 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8929 + ", uid=" + callingUid + ") that is not exported from uid " 8930 + cpi.applicationInfo.uid; 8931 } else { 8932 msg = "Permission Denial: opening provider " + cpi.name 8933 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8934 + ", uid=" + callingUid + ") requires " 8935 + cpi.readPermission + " or " + cpi.writePermission; 8936 } 8937 Slog.w(TAG, msg); 8938 return msg; 8939 } 8940 8941 /** 8942 * Returns if the ContentProvider has granted a uri to callingUid 8943 */ 8944 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8945 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8946 if (perms != null) { 8947 for (int i=perms.size()-1; i>=0; i--) { 8948 GrantUri grantUri = perms.keyAt(i); 8949 if (grantUri.sourceUserId == userId || !checkUser) { 8950 if (matchesProvider(grantUri.uri, cpi)) { 8951 return true; 8952 } 8953 } 8954 } 8955 } 8956 return false; 8957 } 8958 8959 /** 8960 * Returns true if the uri authority is one of the authorities specified in the provider. 8961 */ 8962 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8963 String uriAuth = uri.getAuthority(); 8964 String cpiAuth = cpi.authority; 8965 if (cpiAuth.indexOf(';') == -1) { 8966 return cpiAuth.equals(uriAuth); 8967 } 8968 String[] cpiAuths = cpiAuth.split(";"); 8969 int length = cpiAuths.length; 8970 for (int i = 0; i < length; i++) { 8971 if (cpiAuths[i].equals(uriAuth)) return true; 8972 } 8973 return false; 8974 } 8975 8976 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8977 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8978 if (r != null) { 8979 for (int i=0; i<r.conProviders.size(); i++) { 8980 ContentProviderConnection conn = r.conProviders.get(i); 8981 if (conn.provider == cpr) { 8982 if (DEBUG_PROVIDER) Slog.v(TAG, 8983 "Adding provider requested by " 8984 + r.processName + " from process " 8985 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8986 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8987 if (stable) { 8988 conn.stableCount++; 8989 conn.numStableIncs++; 8990 } else { 8991 conn.unstableCount++; 8992 conn.numUnstableIncs++; 8993 } 8994 return conn; 8995 } 8996 } 8997 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8998 if (stable) { 8999 conn.stableCount = 1; 9000 conn.numStableIncs = 1; 9001 } else { 9002 conn.unstableCount = 1; 9003 conn.numUnstableIncs = 1; 9004 } 9005 cpr.connections.add(conn); 9006 r.conProviders.add(conn); 9007 return conn; 9008 } 9009 cpr.addExternalProcessHandleLocked(externalProcessToken); 9010 return null; 9011 } 9012 9013 boolean decProviderCountLocked(ContentProviderConnection conn, 9014 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 9015 if (conn != null) { 9016 cpr = conn.provider; 9017 if (DEBUG_PROVIDER) Slog.v(TAG, 9018 "Removing provider requested by " 9019 + conn.client.processName + " from process " 9020 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 9021 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 9022 if (stable) { 9023 conn.stableCount--; 9024 } else { 9025 conn.unstableCount--; 9026 } 9027 if (conn.stableCount == 0 && conn.unstableCount == 0) { 9028 cpr.connections.remove(conn); 9029 conn.client.conProviders.remove(conn); 9030 return true; 9031 } 9032 return false; 9033 } 9034 cpr.removeExternalProcessHandleLocked(externalProcessToken); 9035 return false; 9036 } 9037 9038 private void checkTime(long startTime, String where) { 9039 long now = SystemClock.elapsedRealtime(); 9040 if ((now-startTime) > 1000) { 9041 // If we are taking more than a second, log about it. 9042 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9043 } 9044 } 9045 9046 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9047 String name, IBinder token, boolean stable, int userId) { 9048 ContentProviderRecord cpr; 9049 ContentProviderConnection conn = null; 9050 ProviderInfo cpi = null; 9051 9052 synchronized(this) { 9053 long startTime = SystemClock.elapsedRealtime(); 9054 9055 ProcessRecord r = null; 9056 if (caller != null) { 9057 r = getRecordForAppLocked(caller); 9058 if (r == null) { 9059 throw new SecurityException( 9060 "Unable to find app for caller " + caller 9061 + " (pid=" + Binder.getCallingPid() 9062 + ") when getting content provider " + name); 9063 } 9064 } 9065 9066 boolean checkCrossUser = true; 9067 9068 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9069 9070 // First check if this content provider has been published... 9071 cpr = mProviderMap.getProviderByName(name, userId); 9072 // If that didn't work, check if it exists for user 0 and then 9073 // verify that it's a singleton provider before using it. 9074 if (cpr == null && userId != UserHandle.USER_OWNER) { 9075 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9076 if (cpr != null) { 9077 cpi = cpr.info; 9078 if (isSingleton(cpi.processName, cpi.applicationInfo, 9079 cpi.name, cpi.flags) 9080 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9081 userId = UserHandle.USER_OWNER; 9082 checkCrossUser = false; 9083 } else { 9084 cpr = null; 9085 cpi = null; 9086 } 9087 } 9088 } 9089 9090 boolean providerRunning = cpr != null; 9091 if (providerRunning) { 9092 cpi = cpr.info; 9093 String msg; 9094 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9095 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9096 != null) { 9097 throw new SecurityException(msg); 9098 } 9099 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9100 9101 if (r != null && cpr.canRunHere(r)) { 9102 // This provider has been published or is in the process 9103 // of being published... but it is also allowed to run 9104 // in the caller's process, so don't make a connection 9105 // and just let the caller instantiate its own instance. 9106 ContentProviderHolder holder = cpr.newHolder(null); 9107 // don't give caller the provider object, it needs 9108 // to make its own. 9109 holder.provider = null; 9110 return holder; 9111 } 9112 9113 final long origId = Binder.clearCallingIdentity(); 9114 9115 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9116 9117 // In this case the provider instance already exists, so we can 9118 // return it right away. 9119 conn = incProviderCountLocked(r, cpr, token, stable); 9120 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9121 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9122 // If this is a perceptible app accessing the provider, 9123 // make sure to count it as being accessed and thus 9124 // back up on the LRU list. This is good because 9125 // content providers are often expensive to start. 9126 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9127 updateLruProcessLocked(cpr.proc, false, null); 9128 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9129 } 9130 } 9131 9132 if (cpr.proc != null) { 9133 if (false) { 9134 if (cpr.name.flattenToShortString().equals( 9135 "com.android.providers.calendar/.CalendarProvider2")) { 9136 Slog.v(TAG, "****************** KILLING " 9137 + cpr.name.flattenToShortString()); 9138 Process.killProcess(cpr.proc.pid); 9139 } 9140 } 9141 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9142 boolean success = updateOomAdjLocked(cpr.proc); 9143 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9144 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9145 // NOTE: there is still a race here where a signal could be 9146 // pending on the process even though we managed to update its 9147 // adj level. Not sure what to do about this, but at least 9148 // the race is now smaller. 9149 if (!success) { 9150 // Uh oh... it looks like the provider's process 9151 // has been killed on us. We need to wait for a new 9152 // process to be started, and make sure its death 9153 // doesn't kill our process. 9154 Slog.i(TAG, 9155 "Existing provider " + cpr.name.flattenToShortString() 9156 + " is crashing; detaching " + r); 9157 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9158 checkTime(startTime, "getContentProviderImpl: before appDied"); 9159 appDiedLocked(cpr.proc); 9160 checkTime(startTime, "getContentProviderImpl: after appDied"); 9161 if (!lastRef) { 9162 // This wasn't the last ref our process had on 9163 // the provider... we have now been killed, bail. 9164 return null; 9165 } 9166 providerRunning = false; 9167 conn = null; 9168 } 9169 } 9170 9171 Binder.restoreCallingIdentity(origId); 9172 } 9173 9174 boolean singleton; 9175 if (!providerRunning) { 9176 try { 9177 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9178 cpi = AppGlobals.getPackageManager(). 9179 resolveContentProvider(name, 9180 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9181 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9182 } catch (RemoteException ex) { 9183 } 9184 if (cpi == null) { 9185 return null; 9186 } 9187 // If the provider is a singleton AND 9188 // (it's a call within the same user || the provider is a 9189 // privileged app) 9190 // Then allow connecting to the singleton provider 9191 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9192 cpi.name, cpi.flags) 9193 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9194 if (singleton) { 9195 userId = UserHandle.USER_OWNER; 9196 } 9197 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9198 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9199 9200 String msg; 9201 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9202 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9203 != null) { 9204 throw new SecurityException(msg); 9205 } 9206 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9207 9208 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9209 && !cpi.processName.equals("system")) { 9210 // If this content provider does not run in the system 9211 // process, and the system is not yet ready to run other 9212 // processes, then fail fast instead of hanging. 9213 throw new IllegalArgumentException( 9214 "Attempt to launch content provider before system ready"); 9215 } 9216 9217 // Make sure that the user who owns this provider is started. If not, 9218 // we don't want to allow it to run. 9219 if (mStartedUsers.get(userId) == null) { 9220 Slog.w(TAG, "Unable to launch app " 9221 + cpi.applicationInfo.packageName + "/" 9222 + cpi.applicationInfo.uid + " for provider " 9223 + name + ": user " + userId + " is stopped"); 9224 return null; 9225 } 9226 9227 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9228 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9229 cpr = mProviderMap.getProviderByClass(comp, userId); 9230 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9231 final boolean firstClass = cpr == null; 9232 if (firstClass) { 9233 try { 9234 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9235 ApplicationInfo ai = 9236 AppGlobals.getPackageManager(). 9237 getApplicationInfo( 9238 cpi.applicationInfo.packageName, 9239 STOCK_PM_FLAGS, userId); 9240 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9241 if (ai == null) { 9242 Slog.w(TAG, "No package info for content provider " 9243 + cpi.name); 9244 return null; 9245 } 9246 ai = getAppInfoForUser(ai, userId); 9247 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9248 } catch (RemoteException ex) { 9249 // pm is in same process, this will never happen. 9250 } 9251 } 9252 9253 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9254 9255 if (r != null && cpr.canRunHere(r)) { 9256 // If this is a multiprocess provider, then just return its 9257 // info and allow the caller to instantiate it. Only do 9258 // this if the provider is the same user as the caller's 9259 // process, or can run as root (so can be in any process). 9260 return cpr.newHolder(null); 9261 } 9262 9263 if (DEBUG_PROVIDER) { 9264 RuntimeException e = new RuntimeException("here"); 9265 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9266 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9267 } 9268 9269 // This is single process, and our app is now connecting to it. 9270 // See if we are already in the process of launching this 9271 // provider. 9272 final int N = mLaunchingProviders.size(); 9273 int i; 9274 for (i=0; i<N; i++) { 9275 if (mLaunchingProviders.get(i) == cpr) { 9276 break; 9277 } 9278 } 9279 9280 // If the provider is not already being launched, then get it 9281 // started. 9282 if (i >= N) { 9283 final long origId = Binder.clearCallingIdentity(); 9284 9285 try { 9286 // Content provider is now in use, its package can't be stopped. 9287 try { 9288 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9289 AppGlobals.getPackageManager().setPackageStoppedState( 9290 cpr.appInfo.packageName, false, userId); 9291 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9292 } catch (RemoteException e) { 9293 } catch (IllegalArgumentException e) { 9294 Slog.w(TAG, "Failed trying to unstop package " 9295 + cpr.appInfo.packageName + ": " + e); 9296 } 9297 9298 // Use existing process if already started 9299 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9300 ProcessRecord proc = getProcessRecordLocked( 9301 cpi.processName, cpr.appInfo.uid, false); 9302 if (proc != null && proc.thread != null) { 9303 if (DEBUG_PROVIDER) { 9304 Slog.d(TAG, "Installing in existing process " + proc); 9305 } 9306 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9307 proc.pubProviders.put(cpi.name, cpr); 9308 try { 9309 proc.thread.scheduleInstallProvider(cpi); 9310 } catch (RemoteException e) { 9311 } 9312 } else { 9313 checkTime(startTime, "getContentProviderImpl: before start process"); 9314 proc = startProcessLocked(cpi.processName, 9315 cpr.appInfo, false, 0, "content provider", 9316 new ComponentName(cpi.applicationInfo.packageName, 9317 cpi.name), false, false, false); 9318 checkTime(startTime, "getContentProviderImpl: after start process"); 9319 if (proc == null) { 9320 Slog.w(TAG, "Unable to launch app " 9321 + cpi.applicationInfo.packageName + "/" 9322 + cpi.applicationInfo.uid + " for provider " 9323 + name + ": process is bad"); 9324 return null; 9325 } 9326 } 9327 cpr.launchingApp = proc; 9328 mLaunchingProviders.add(cpr); 9329 } finally { 9330 Binder.restoreCallingIdentity(origId); 9331 } 9332 } 9333 9334 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9335 9336 // Make sure the provider is published (the same provider class 9337 // may be published under multiple names). 9338 if (firstClass) { 9339 mProviderMap.putProviderByClass(comp, cpr); 9340 } 9341 9342 mProviderMap.putProviderByName(name, cpr); 9343 conn = incProviderCountLocked(r, cpr, token, stable); 9344 if (conn != null) { 9345 conn.waiting = true; 9346 } 9347 } 9348 checkTime(startTime, "getContentProviderImpl: done!"); 9349 } 9350 9351 // Wait for the provider to be published... 9352 synchronized (cpr) { 9353 while (cpr.provider == null) { 9354 if (cpr.launchingApp == null) { 9355 Slog.w(TAG, "Unable to launch app " 9356 + cpi.applicationInfo.packageName + "/" 9357 + cpi.applicationInfo.uid + " for provider " 9358 + name + ": launching app became null"); 9359 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9360 UserHandle.getUserId(cpi.applicationInfo.uid), 9361 cpi.applicationInfo.packageName, 9362 cpi.applicationInfo.uid, name); 9363 return null; 9364 } 9365 try { 9366 if (DEBUG_MU) { 9367 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9368 + cpr.launchingApp); 9369 } 9370 if (conn != null) { 9371 conn.waiting = true; 9372 } 9373 cpr.wait(); 9374 } catch (InterruptedException ex) { 9375 } finally { 9376 if (conn != null) { 9377 conn.waiting = false; 9378 } 9379 } 9380 } 9381 } 9382 return cpr != null ? cpr.newHolder(conn) : null; 9383 } 9384 9385 @Override 9386 public final ContentProviderHolder getContentProvider( 9387 IApplicationThread caller, String name, int userId, boolean stable) { 9388 enforceNotIsolatedCaller("getContentProvider"); 9389 if (caller == null) { 9390 String msg = "null IApplicationThread when getting content provider " 9391 + name; 9392 Slog.w(TAG, msg); 9393 throw new SecurityException(msg); 9394 } 9395 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9396 // with cross-user grant. 9397 return getContentProviderImpl(caller, name, null, stable, userId); 9398 } 9399 9400 public ContentProviderHolder getContentProviderExternal( 9401 String name, int userId, IBinder token) { 9402 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9403 "Do not have permission in call getContentProviderExternal()"); 9404 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9405 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9406 return getContentProviderExternalUnchecked(name, token, userId); 9407 } 9408 9409 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9410 IBinder token, int userId) { 9411 return getContentProviderImpl(null, name, token, true, userId); 9412 } 9413 9414 /** 9415 * Drop a content provider from a ProcessRecord's bookkeeping 9416 */ 9417 public void removeContentProvider(IBinder connection, boolean stable) { 9418 enforceNotIsolatedCaller("removeContentProvider"); 9419 long ident = Binder.clearCallingIdentity(); 9420 try { 9421 synchronized (this) { 9422 ContentProviderConnection conn; 9423 try { 9424 conn = (ContentProviderConnection)connection; 9425 } catch (ClassCastException e) { 9426 String msg ="removeContentProvider: " + connection 9427 + " not a ContentProviderConnection"; 9428 Slog.w(TAG, msg); 9429 throw new IllegalArgumentException(msg); 9430 } 9431 if (conn == null) { 9432 throw new NullPointerException("connection is null"); 9433 } 9434 if (decProviderCountLocked(conn, null, null, stable)) { 9435 updateOomAdjLocked(); 9436 } 9437 } 9438 } finally { 9439 Binder.restoreCallingIdentity(ident); 9440 } 9441 } 9442 9443 public void removeContentProviderExternal(String name, IBinder token) { 9444 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9445 "Do not have permission in call removeContentProviderExternal()"); 9446 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9447 } 9448 9449 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9450 synchronized (this) { 9451 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9452 if(cpr == null) { 9453 //remove from mProvidersByClass 9454 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9455 return; 9456 } 9457 9458 //update content provider record entry info 9459 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9460 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9461 if (localCpr.hasExternalProcessHandles()) { 9462 if (localCpr.removeExternalProcessHandleLocked(token)) { 9463 updateOomAdjLocked(); 9464 } else { 9465 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9466 + " with no external reference for token: " 9467 + token + "."); 9468 } 9469 } else { 9470 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9471 + " with no external references."); 9472 } 9473 } 9474 } 9475 9476 public final void publishContentProviders(IApplicationThread caller, 9477 List<ContentProviderHolder> providers) { 9478 if (providers == null) { 9479 return; 9480 } 9481 9482 enforceNotIsolatedCaller("publishContentProviders"); 9483 synchronized (this) { 9484 final ProcessRecord r = getRecordForAppLocked(caller); 9485 if (DEBUG_MU) 9486 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9487 if (r == null) { 9488 throw new SecurityException( 9489 "Unable to find app for caller " + caller 9490 + " (pid=" + Binder.getCallingPid() 9491 + ") when publishing content providers"); 9492 } 9493 9494 final long origId = Binder.clearCallingIdentity(); 9495 9496 final int N = providers.size(); 9497 for (int i=0; i<N; i++) { 9498 ContentProviderHolder src = providers.get(i); 9499 if (src == null || src.info == null || src.provider == null) { 9500 continue; 9501 } 9502 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9503 if (DEBUG_MU) 9504 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9505 if (dst != null) { 9506 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9507 mProviderMap.putProviderByClass(comp, dst); 9508 String names[] = dst.info.authority.split(";"); 9509 for (int j = 0; j < names.length; j++) { 9510 mProviderMap.putProviderByName(names[j], dst); 9511 } 9512 9513 int NL = mLaunchingProviders.size(); 9514 int j; 9515 for (j=0; j<NL; j++) { 9516 if (mLaunchingProviders.get(j) == dst) { 9517 mLaunchingProviders.remove(j); 9518 j--; 9519 NL--; 9520 } 9521 } 9522 synchronized (dst) { 9523 dst.provider = src.provider; 9524 dst.proc = r; 9525 dst.notifyAll(); 9526 } 9527 updateOomAdjLocked(r); 9528 } 9529 } 9530 9531 Binder.restoreCallingIdentity(origId); 9532 } 9533 } 9534 9535 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9536 ContentProviderConnection conn; 9537 try { 9538 conn = (ContentProviderConnection)connection; 9539 } catch (ClassCastException e) { 9540 String msg ="refContentProvider: " + connection 9541 + " not a ContentProviderConnection"; 9542 Slog.w(TAG, msg); 9543 throw new IllegalArgumentException(msg); 9544 } 9545 if (conn == null) { 9546 throw new NullPointerException("connection is null"); 9547 } 9548 9549 synchronized (this) { 9550 if (stable > 0) { 9551 conn.numStableIncs += stable; 9552 } 9553 stable = conn.stableCount + stable; 9554 if (stable < 0) { 9555 throw new IllegalStateException("stableCount < 0: " + stable); 9556 } 9557 9558 if (unstable > 0) { 9559 conn.numUnstableIncs += unstable; 9560 } 9561 unstable = conn.unstableCount + unstable; 9562 if (unstable < 0) { 9563 throw new IllegalStateException("unstableCount < 0: " + unstable); 9564 } 9565 9566 if ((stable+unstable) <= 0) { 9567 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9568 + stable + " unstable=" + unstable); 9569 } 9570 conn.stableCount = stable; 9571 conn.unstableCount = unstable; 9572 return !conn.dead; 9573 } 9574 } 9575 9576 public void unstableProviderDied(IBinder connection) { 9577 ContentProviderConnection conn; 9578 try { 9579 conn = (ContentProviderConnection)connection; 9580 } catch (ClassCastException e) { 9581 String msg ="refContentProvider: " + connection 9582 + " not a ContentProviderConnection"; 9583 Slog.w(TAG, msg); 9584 throw new IllegalArgumentException(msg); 9585 } 9586 if (conn == null) { 9587 throw new NullPointerException("connection is null"); 9588 } 9589 9590 // Safely retrieve the content provider associated with the connection. 9591 IContentProvider provider; 9592 synchronized (this) { 9593 provider = conn.provider.provider; 9594 } 9595 9596 if (provider == null) { 9597 // Um, yeah, we're way ahead of you. 9598 return; 9599 } 9600 9601 // Make sure the caller is being honest with us. 9602 if (provider.asBinder().pingBinder()) { 9603 // Er, no, still looks good to us. 9604 synchronized (this) { 9605 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9606 + " says " + conn + " died, but we don't agree"); 9607 return; 9608 } 9609 } 9610 9611 // Well look at that! It's dead! 9612 synchronized (this) { 9613 if (conn.provider.provider != provider) { 9614 // But something changed... good enough. 9615 return; 9616 } 9617 9618 ProcessRecord proc = conn.provider.proc; 9619 if (proc == null || proc.thread == null) { 9620 // Seems like the process is already cleaned up. 9621 return; 9622 } 9623 9624 // As far as we're concerned, this is just like receiving a 9625 // death notification... just a bit prematurely. 9626 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9627 + ") early provider death"); 9628 final long ident = Binder.clearCallingIdentity(); 9629 try { 9630 appDiedLocked(proc); 9631 } finally { 9632 Binder.restoreCallingIdentity(ident); 9633 } 9634 } 9635 } 9636 9637 @Override 9638 public void appNotRespondingViaProvider(IBinder connection) { 9639 enforceCallingPermission( 9640 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9641 9642 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9643 if (conn == null) { 9644 Slog.w(TAG, "ContentProviderConnection is null"); 9645 return; 9646 } 9647 9648 final ProcessRecord host = conn.provider.proc; 9649 if (host == null) { 9650 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9651 return; 9652 } 9653 9654 final long token = Binder.clearCallingIdentity(); 9655 try { 9656 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9657 } finally { 9658 Binder.restoreCallingIdentity(token); 9659 } 9660 } 9661 9662 public final void installSystemProviders() { 9663 List<ProviderInfo> providers; 9664 synchronized (this) { 9665 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9666 providers = generateApplicationProvidersLocked(app); 9667 if (providers != null) { 9668 for (int i=providers.size()-1; i>=0; i--) { 9669 ProviderInfo pi = (ProviderInfo)providers.get(i); 9670 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9671 Slog.w(TAG, "Not installing system proc provider " + pi.name 9672 + ": not system .apk"); 9673 providers.remove(i); 9674 } 9675 } 9676 } 9677 } 9678 if (providers != null) { 9679 mSystemThread.installSystemProviders(providers); 9680 } 9681 9682 mCoreSettingsObserver = new CoreSettingsObserver(this); 9683 9684 //mUsageStatsService.monitorPackages(); 9685 } 9686 9687 /** 9688 * Allows apps to retrieve the MIME type of a URI. 9689 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9690 * users, then it does not need permission to access the ContentProvider. 9691 * Either, it needs cross-user uri grants. 9692 * 9693 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9694 * 9695 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9696 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9697 */ 9698 public String getProviderMimeType(Uri uri, int userId) { 9699 enforceNotIsolatedCaller("getProviderMimeType"); 9700 final String name = uri.getAuthority(); 9701 int callingUid = Binder.getCallingUid(); 9702 int callingPid = Binder.getCallingPid(); 9703 long ident = 0; 9704 boolean clearedIdentity = false; 9705 userId = unsafeConvertIncomingUser(userId); 9706 if (UserHandle.getUserId(callingUid) != userId) { 9707 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9708 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9709 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9710 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9711 clearedIdentity = true; 9712 ident = Binder.clearCallingIdentity(); 9713 } 9714 } 9715 ContentProviderHolder holder = null; 9716 try { 9717 holder = getContentProviderExternalUnchecked(name, null, userId); 9718 if (holder != null) { 9719 return holder.provider.getType(uri); 9720 } 9721 } catch (RemoteException e) { 9722 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9723 return null; 9724 } finally { 9725 // We need to clear the identity to call removeContentProviderExternalUnchecked 9726 if (!clearedIdentity) { 9727 ident = Binder.clearCallingIdentity(); 9728 } 9729 try { 9730 if (holder != null) { 9731 removeContentProviderExternalUnchecked(name, null, userId); 9732 } 9733 } finally { 9734 Binder.restoreCallingIdentity(ident); 9735 } 9736 } 9737 9738 return null; 9739 } 9740 9741 // ========================================================= 9742 // GLOBAL MANAGEMENT 9743 // ========================================================= 9744 9745 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9746 boolean isolated, int isolatedUid) { 9747 String proc = customProcess != null ? customProcess : info.processName; 9748 BatteryStatsImpl.Uid.Proc ps = null; 9749 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9750 int uid = info.uid; 9751 if (isolated) { 9752 if (isolatedUid == 0) { 9753 int userId = UserHandle.getUserId(uid); 9754 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9755 while (true) { 9756 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9757 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9758 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9759 } 9760 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9761 mNextIsolatedProcessUid++; 9762 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9763 // No process for this uid, use it. 9764 break; 9765 } 9766 stepsLeft--; 9767 if (stepsLeft <= 0) { 9768 return null; 9769 } 9770 } 9771 } else { 9772 // Special case for startIsolatedProcess (internal only), where 9773 // the uid of the isolated process is specified by the caller. 9774 uid = isolatedUid; 9775 } 9776 } 9777 return new ProcessRecord(stats, info, proc, uid); 9778 } 9779 9780 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9781 String abiOverride) { 9782 ProcessRecord app; 9783 if (!isolated) { 9784 app = getProcessRecordLocked(info.processName, info.uid, true); 9785 } else { 9786 app = null; 9787 } 9788 9789 if (app == null) { 9790 app = newProcessRecordLocked(info, null, isolated, 0); 9791 mProcessNames.put(info.processName, app.uid, app); 9792 if (isolated) { 9793 mIsolatedProcesses.put(app.uid, app); 9794 } 9795 updateLruProcessLocked(app, false, null); 9796 updateOomAdjLocked(); 9797 } 9798 9799 // This package really, really can not be stopped. 9800 try { 9801 AppGlobals.getPackageManager().setPackageStoppedState( 9802 info.packageName, false, UserHandle.getUserId(app.uid)); 9803 } catch (RemoteException e) { 9804 } catch (IllegalArgumentException e) { 9805 Slog.w(TAG, "Failed trying to unstop package " 9806 + info.packageName + ": " + e); 9807 } 9808 9809 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9810 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9811 app.persistent = true; 9812 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9813 } 9814 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9815 mPersistentStartingProcesses.add(app); 9816 startProcessLocked(app, "added application", app.processName, abiOverride, 9817 null /* entryPoint */, null /* entryPointArgs */); 9818 } 9819 9820 return app; 9821 } 9822 9823 public void unhandledBack() { 9824 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9825 "unhandledBack()"); 9826 9827 synchronized(this) { 9828 final long origId = Binder.clearCallingIdentity(); 9829 try { 9830 getFocusedStack().unhandledBackLocked(); 9831 } finally { 9832 Binder.restoreCallingIdentity(origId); 9833 } 9834 } 9835 } 9836 9837 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9838 enforceNotIsolatedCaller("openContentUri"); 9839 final int userId = UserHandle.getCallingUserId(); 9840 String name = uri.getAuthority(); 9841 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9842 ParcelFileDescriptor pfd = null; 9843 if (cph != null) { 9844 // We record the binder invoker's uid in thread-local storage before 9845 // going to the content provider to open the file. Later, in the code 9846 // that handles all permissions checks, we look for this uid and use 9847 // that rather than the Activity Manager's own uid. The effect is that 9848 // we do the check against the caller's permissions even though it looks 9849 // to the content provider like the Activity Manager itself is making 9850 // the request. 9851 sCallerIdentity.set(new Identity( 9852 Binder.getCallingPid(), Binder.getCallingUid())); 9853 try { 9854 pfd = cph.provider.openFile(null, uri, "r", null); 9855 } catch (FileNotFoundException e) { 9856 // do nothing; pfd will be returned null 9857 } finally { 9858 // Ensure that whatever happens, we clean up the identity state 9859 sCallerIdentity.remove(); 9860 } 9861 9862 // We've got the fd now, so we're done with the provider. 9863 removeContentProviderExternalUnchecked(name, null, userId); 9864 } else { 9865 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9866 } 9867 return pfd; 9868 } 9869 9870 // Actually is sleeping or shutting down or whatever else in the future 9871 // is an inactive state. 9872 public boolean isSleepingOrShuttingDown() { 9873 return mSleeping || mShuttingDown; 9874 } 9875 9876 public boolean isSleeping() { 9877 return mSleeping; 9878 } 9879 9880 void goingToSleep() { 9881 synchronized(this) { 9882 mWentToSleep = true; 9883 updateEventDispatchingLocked(); 9884 goToSleepIfNeededLocked(); 9885 } 9886 } 9887 9888 void finishRunningVoiceLocked() { 9889 if (mRunningVoice) { 9890 mRunningVoice = false; 9891 goToSleepIfNeededLocked(); 9892 } 9893 } 9894 9895 void goToSleepIfNeededLocked() { 9896 if (mWentToSleep && !mRunningVoice) { 9897 if (!mSleeping) { 9898 mSleeping = true; 9899 mStackSupervisor.goingToSleepLocked(); 9900 9901 // Initialize the wake times of all processes. 9902 checkExcessivePowerUsageLocked(false); 9903 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9904 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9905 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9906 } 9907 } 9908 } 9909 9910 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9911 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9912 // Never persist the home stack. 9913 return; 9914 } 9915 mTaskPersister.wakeup(task, flush); 9916 } 9917 9918 @Override 9919 public boolean shutdown(int timeout) { 9920 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9921 != PackageManager.PERMISSION_GRANTED) { 9922 throw new SecurityException("Requires permission " 9923 + android.Manifest.permission.SHUTDOWN); 9924 } 9925 9926 boolean timedout = false; 9927 9928 synchronized(this) { 9929 mShuttingDown = true; 9930 updateEventDispatchingLocked(); 9931 timedout = mStackSupervisor.shutdownLocked(timeout); 9932 } 9933 9934 mAppOpsService.shutdown(); 9935 if (mUsageStatsService != null) { 9936 mUsageStatsService.prepareShutdown(); 9937 } 9938 mBatteryStatsService.shutdown(); 9939 synchronized (this) { 9940 mProcessStats.shutdownLocked(); 9941 } 9942 notifyTaskPersisterLocked(null, true); 9943 9944 return timedout; 9945 } 9946 9947 public final void activitySlept(IBinder token) { 9948 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9949 9950 final long origId = Binder.clearCallingIdentity(); 9951 9952 synchronized (this) { 9953 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9954 if (r != null) { 9955 mStackSupervisor.activitySleptLocked(r); 9956 } 9957 } 9958 9959 Binder.restoreCallingIdentity(origId); 9960 } 9961 9962 void logLockScreen(String msg) { 9963 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9964 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9965 mWentToSleep + " mSleeping=" + mSleeping); 9966 } 9967 9968 private void comeOutOfSleepIfNeededLocked() { 9969 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9970 if (mSleeping) { 9971 mSleeping = false; 9972 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9973 } 9974 } 9975 } 9976 9977 void wakingUp() { 9978 synchronized(this) { 9979 mWentToSleep = false; 9980 updateEventDispatchingLocked(); 9981 comeOutOfSleepIfNeededLocked(); 9982 } 9983 } 9984 9985 void startRunningVoiceLocked() { 9986 if (!mRunningVoice) { 9987 mRunningVoice = true; 9988 comeOutOfSleepIfNeededLocked(); 9989 } 9990 } 9991 9992 private void updateEventDispatchingLocked() { 9993 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 9994 } 9995 9996 public void setLockScreenShown(boolean shown) { 9997 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9998 != PackageManager.PERMISSION_GRANTED) { 9999 throw new SecurityException("Requires permission " 10000 + android.Manifest.permission.DEVICE_POWER); 10001 } 10002 10003 synchronized(this) { 10004 long ident = Binder.clearCallingIdentity(); 10005 try { 10006 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 10007 mLockScreenShown = shown; 10008 comeOutOfSleepIfNeededLocked(); 10009 } finally { 10010 Binder.restoreCallingIdentity(ident); 10011 } 10012 } 10013 } 10014 10015 @Override 10016 public void stopAppSwitches() { 10017 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10018 != PackageManager.PERMISSION_GRANTED) { 10019 throw new SecurityException("Requires permission " 10020 + android.Manifest.permission.STOP_APP_SWITCHES); 10021 } 10022 10023 synchronized(this) { 10024 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 10025 + APP_SWITCH_DELAY_TIME; 10026 mDidAppSwitch = false; 10027 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10028 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 10029 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 10030 } 10031 } 10032 10033 public void resumeAppSwitches() { 10034 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 10035 != PackageManager.PERMISSION_GRANTED) { 10036 throw new SecurityException("Requires permission " 10037 + android.Manifest.permission.STOP_APP_SWITCHES); 10038 } 10039 10040 synchronized(this) { 10041 // Note that we don't execute any pending app switches... we will 10042 // let those wait until either the timeout, or the next start 10043 // activity request. 10044 mAppSwitchesAllowedTime = 0; 10045 } 10046 } 10047 10048 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 10049 String name) { 10050 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10051 return true; 10052 } 10053 10054 final int perm = checkComponentPermission( 10055 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10056 callingUid, -1, true); 10057 if (perm == PackageManager.PERMISSION_GRANTED) { 10058 return true; 10059 } 10060 10061 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 10062 return false; 10063 } 10064 10065 public void setDebugApp(String packageName, boolean waitForDebugger, 10066 boolean persistent) { 10067 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10068 "setDebugApp()"); 10069 10070 long ident = Binder.clearCallingIdentity(); 10071 try { 10072 // Note that this is not really thread safe if there are multiple 10073 // callers into it at the same time, but that's not a situation we 10074 // care about. 10075 if (persistent) { 10076 final ContentResolver resolver = mContext.getContentResolver(); 10077 Settings.Global.putString( 10078 resolver, Settings.Global.DEBUG_APP, 10079 packageName); 10080 Settings.Global.putInt( 10081 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10082 waitForDebugger ? 1 : 0); 10083 } 10084 10085 synchronized (this) { 10086 if (!persistent) { 10087 mOrigDebugApp = mDebugApp; 10088 mOrigWaitForDebugger = mWaitForDebugger; 10089 } 10090 mDebugApp = packageName; 10091 mWaitForDebugger = waitForDebugger; 10092 mDebugTransient = !persistent; 10093 if (packageName != null) { 10094 forceStopPackageLocked(packageName, -1, false, false, true, true, 10095 false, UserHandle.USER_ALL, "set debug app"); 10096 } 10097 } 10098 } finally { 10099 Binder.restoreCallingIdentity(ident); 10100 } 10101 } 10102 10103 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10104 synchronized (this) { 10105 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10106 if (!isDebuggable) { 10107 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10108 throw new SecurityException("Process not debuggable: " + app.packageName); 10109 } 10110 } 10111 10112 mOpenGlTraceApp = processName; 10113 } 10114 } 10115 10116 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10117 synchronized (this) { 10118 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10119 if (!isDebuggable) { 10120 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10121 throw new SecurityException("Process not debuggable: " + app.packageName); 10122 } 10123 } 10124 mProfileApp = processName; 10125 mProfileFile = profilerInfo.profileFile; 10126 if (mProfileFd != null) { 10127 try { 10128 mProfileFd.close(); 10129 } catch (IOException e) { 10130 } 10131 mProfileFd = null; 10132 } 10133 mProfileFd = profilerInfo.profileFd; 10134 mSamplingInterval = profilerInfo.samplingInterval; 10135 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10136 mProfileType = 0; 10137 } 10138 } 10139 10140 @Override 10141 public void setAlwaysFinish(boolean enabled) { 10142 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10143 "setAlwaysFinish()"); 10144 10145 Settings.Global.putInt( 10146 mContext.getContentResolver(), 10147 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10148 10149 synchronized (this) { 10150 mAlwaysFinishActivities = enabled; 10151 } 10152 } 10153 10154 @Override 10155 public void setActivityController(IActivityController controller) { 10156 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10157 "setActivityController()"); 10158 synchronized (this) { 10159 mController = controller; 10160 Watchdog.getInstance().setActivityController(controller); 10161 } 10162 } 10163 10164 @Override 10165 public void setUserIsMonkey(boolean userIsMonkey) { 10166 synchronized (this) { 10167 synchronized (mPidsSelfLocked) { 10168 final int callingPid = Binder.getCallingPid(); 10169 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10170 if (precessRecord == null) { 10171 throw new SecurityException("Unknown process: " + callingPid); 10172 } 10173 if (precessRecord.instrumentationUiAutomationConnection == null) { 10174 throw new SecurityException("Only an instrumentation process " 10175 + "with a UiAutomation can call setUserIsMonkey"); 10176 } 10177 } 10178 mUserIsMonkey = userIsMonkey; 10179 } 10180 } 10181 10182 @Override 10183 public boolean isUserAMonkey() { 10184 synchronized (this) { 10185 // If there is a controller also implies the user is a monkey. 10186 return (mUserIsMonkey || mController != null); 10187 } 10188 } 10189 10190 public void requestBugReport() { 10191 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10192 SystemProperties.set("ctl.start", "bugreport"); 10193 } 10194 10195 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10196 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10197 } 10198 10199 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10200 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10201 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10202 } 10203 return KEY_DISPATCHING_TIMEOUT; 10204 } 10205 10206 @Override 10207 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10208 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10209 != PackageManager.PERMISSION_GRANTED) { 10210 throw new SecurityException("Requires permission " 10211 + android.Manifest.permission.FILTER_EVENTS); 10212 } 10213 ProcessRecord proc; 10214 long timeout; 10215 synchronized (this) { 10216 synchronized (mPidsSelfLocked) { 10217 proc = mPidsSelfLocked.get(pid); 10218 } 10219 timeout = getInputDispatchingTimeoutLocked(proc); 10220 } 10221 10222 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10223 return -1; 10224 } 10225 10226 return timeout; 10227 } 10228 10229 /** 10230 * Handle input dispatching timeouts. 10231 * Returns whether input dispatching should be aborted or not. 10232 */ 10233 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10234 final ActivityRecord activity, final ActivityRecord parent, 10235 final boolean aboveSystem, String reason) { 10236 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10237 != PackageManager.PERMISSION_GRANTED) { 10238 throw new SecurityException("Requires permission " 10239 + android.Manifest.permission.FILTER_EVENTS); 10240 } 10241 10242 final String annotation; 10243 if (reason == null) { 10244 annotation = "Input dispatching timed out"; 10245 } else { 10246 annotation = "Input dispatching timed out (" + reason + ")"; 10247 } 10248 10249 if (proc != null) { 10250 synchronized (this) { 10251 if (proc.debugging) { 10252 return false; 10253 } 10254 10255 if (mDidDexOpt) { 10256 // Give more time since we were dexopting. 10257 mDidDexOpt = false; 10258 return false; 10259 } 10260 10261 if (proc.instrumentationClass != null) { 10262 Bundle info = new Bundle(); 10263 info.putString("shortMsg", "keyDispatchingTimedOut"); 10264 info.putString("longMsg", annotation); 10265 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10266 return true; 10267 } 10268 } 10269 mHandler.post(new Runnable() { 10270 @Override 10271 public void run() { 10272 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10273 } 10274 }); 10275 } 10276 10277 return true; 10278 } 10279 10280 public Bundle getAssistContextExtras(int requestType) { 10281 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10282 "getAssistContextExtras()"); 10283 PendingAssistExtras pae; 10284 Bundle extras = new Bundle(); 10285 synchronized (this) { 10286 ActivityRecord activity = getFocusedStack().mResumedActivity; 10287 if (activity == null) { 10288 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10289 return null; 10290 } 10291 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10292 if (activity.app == null || activity.app.thread == null) { 10293 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10294 return extras; 10295 } 10296 if (activity.app.pid == Binder.getCallingPid()) { 10297 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10298 return extras; 10299 } 10300 pae = new PendingAssistExtras(activity); 10301 try { 10302 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10303 requestType); 10304 mPendingAssistExtras.add(pae); 10305 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10306 } catch (RemoteException e) { 10307 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10308 return extras; 10309 } 10310 } 10311 synchronized (pae) { 10312 while (!pae.haveResult) { 10313 try { 10314 pae.wait(); 10315 } catch (InterruptedException e) { 10316 } 10317 } 10318 if (pae.result != null) { 10319 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10320 } 10321 } 10322 synchronized (this) { 10323 mPendingAssistExtras.remove(pae); 10324 mHandler.removeCallbacks(pae); 10325 } 10326 return extras; 10327 } 10328 10329 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10330 PendingAssistExtras pae = (PendingAssistExtras)token; 10331 synchronized (pae) { 10332 pae.result = extras; 10333 pae.haveResult = true; 10334 pae.notifyAll(); 10335 } 10336 } 10337 10338 public void registerProcessObserver(IProcessObserver observer) { 10339 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10340 "registerProcessObserver()"); 10341 synchronized (this) { 10342 mProcessObservers.register(observer); 10343 } 10344 } 10345 10346 @Override 10347 public void unregisterProcessObserver(IProcessObserver observer) { 10348 synchronized (this) { 10349 mProcessObservers.unregister(observer); 10350 } 10351 } 10352 10353 @Override 10354 public boolean convertFromTranslucent(IBinder token) { 10355 final long origId = Binder.clearCallingIdentity(); 10356 try { 10357 synchronized (this) { 10358 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10359 if (r == null) { 10360 return false; 10361 } 10362 final boolean translucentChanged = r.changeWindowTranslucency(true); 10363 if (translucentChanged) { 10364 r.task.stack.releaseBackgroundResources(); 10365 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10366 } 10367 mWindowManager.setAppFullscreen(token, true); 10368 return translucentChanged; 10369 } 10370 } finally { 10371 Binder.restoreCallingIdentity(origId); 10372 } 10373 } 10374 10375 @Override 10376 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10377 final long origId = Binder.clearCallingIdentity(); 10378 try { 10379 synchronized (this) { 10380 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10381 if (r == null) { 10382 return false; 10383 } 10384 int index = r.task.mActivities.lastIndexOf(r); 10385 if (index > 0) { 10386 ActivityRecord under = r.task.mActivities.get(index - 1); 10387 under.returningOptions = options; 10388 } 10389 final boolean translucentChanged = r.changeWindowTranslucency(false); 10390 if (translucentChanged) { 10391 r.task.stack.convertToTranslucent(r); 10392 } 10393 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10394 mWindowManager.setAppFullscreen(token, false); 10395 return translucentChanged; 10396 } 10397 } finally { 10398 Binder.restoreCallingIdentity(origId); 10399 } 10400 } 10401 10402 @Override 10403 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10404 final long origId = Binder.clearCallingIdentity(); 10405 try { 10406 synchronized (this) { 10407 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10408 if (r != null) { 10409 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10410 } 10411 } 10412 return false; 10413 } finally { 10414 Binder.restoreCallingIdentity(origId); 10415 } 10416 } 10417 10418 @Override 10419 public boolean isBackgroundVisibleBehind(IBinder token) { 10420 final long origId = Binder.clearCallingIdentity(); 10421 try { 10422 synchronized (this) { 10423 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10424 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10425 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10426 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10427 return visible; 10428 } 10429 } finally { 10430 Binder.restoreCallingIdentity(origId); 10431 } 10432 } 10433 10434 @Override 10435 public ActivityOptions getActivityOptions(IBinder token) { 10436 final long origId = Binder.clearCallingIdentity(); 10437 try { 10438 synchronized (this) { 10439 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10440 if (r != null) { 10441 final ActivityOptions activityOptions = r.pendingOptions; 10442 r.pendingOptions = null; 10443 return activityOptions; 10444 } 10445 return null; 10446 } 10447 } finally { 10448 Binder.restoreCallingIdentity(origId); 10449 } 10450 } 10451 10452 @Override 10453 public void setImmersive(IBinder token, boolean immersive) { 10454 synchronized(this) { 10455 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10456 if (r == null) { 10457 throw new IllegalArgumentException(); 10458 } 10459 r.immersive = immersive; 10460 10461 // update associated state if we're frontmost 10462 if (r == mFocusedActivity) { 10463 if (DEBUG_IMMERSIVE) { 10464 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10465 } 10466 applyUpdateLockStateLocked(r); 10467 } 10468 } 10469 } 10470 10471 @Override 10472 public boolean isImmersive(IBinder token) { 10473 synchronized (this) { 10474 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10475 if (r == null) { 10476 throw new IllegalArgumentException(); 10477 } 10478 return r.immersive; 10479 } 10480 } 10481 10482 public boolean isTopActivityImmersive() { 10483 enforceNotIsolatedCaller("startActivity"); 10484 synchronized (this) { 10485 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10486 return (r != null) ? r.immersive : false; 10487 } 10488 } 10489 10490 @Override 10491 public boolean isTopOfTask(IBinder token) { 10492 synchronized (this) { 10493 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10494 if (r == null) { 10495 throw new IllegalArgumentException(); 10496 } 10497 return r.task.getTopActivity() == r; 10498 } 10499 } 10500 10501 public final void enterSafeMode() { 10502 synchronized(this) { 10503 // It only makes sense to do this before the system is ready 10504 // and started launching other packages. 10505 if (!mSystemReady) { 10506 try { 10507 AppGlobals.getPackageManager().enterSafeMode(); 10508 } catch (RemoteException e) { 10509 } 10510 } 10511 10512 mSafeMode = true; 10513 } 10514 } 10515 10516 public final void showSafeModeOverlay() { 10517 View v = LayoutInflater.from(mContext).inflate( 10518 com.android.internal.R.layout.safe_mode, null); 10519 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10520 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10521 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10522 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10523 lp.gravity = Gravity.BOTTOM | Gravity.START; 10524 lp.format = v.getBackground().getOpacity(); 10525 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10526 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10527 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10528 ((WindowManager)mContext.getSystemService( 10529 Context.WINDOW_SERVICE)).addView(v, lp); 10530 } 10531 10532 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10533 if (!(sender instanceof PendingIntentRecord)) { 10534 return; 10535 } 10536 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10537 synchronized (stats) { 10538 if (mBatteryStatsService.isOnBattery()) { 10539 mBatteryStatsService.enforceCallingPermission(); 10540 PendingIntentRecord rec = (PendingIntentRecord)sender; 10541 int MY_UID = Binder.getCallingUid(); 10542 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10543 BatteryStatsImpl.Uid.Pkg pkg = 10544 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10545 sourcePkg != null ? sourcePkg : rec.key.packageName); 10546 pkg.incWakeupsLocked(); 10547 } 10548 } 10549 } 10550 10551 public boolean killPids(int[] pids, String pReason, boolean secure) { 10552 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10553 throw new SecurityException("killPids only available to the system"); 10554 } 10555 String reason = (pReason == null) ? "Unknown" : pReason; 10556 // XXX Note: don't acquire main activity lock here, because the window 10557 // manager calls in with its locks held. 10558 10559 boolean killed = false; 10560 synchronized (mPidsSelfLocked) { 10561 int[] types = new int[pids.length]; 10562 int worstType = 0; 10563 for (int i=0; i<pids.length; i++) { 10564 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10565 if (proc != null) { 10566 int type = proc.setAdj; 10567 types[i] = type; 10568 if (type > worstType) { 10569 worstType = type; 10570 } 10571 } 10572 } 10573 10574 // If the worst oom_adj is somewhere in the cached proc LRU range, 10575 // then constrain it so we will kill all cached procs. 10576 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10577 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10578 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10579 } 10580 10581 // If this is not a secure call, don't let it kill processes that 10582 // are important. 10583 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10584 worstType = ProcessList.SERVICE_ADJ; 10585 } 10586 10587 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10588 for (int i=0; i<pids.length; i++) { 10589 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10590 if (proc == null) { 10591 continue; 10592 } 10593 int adj = proc.setAdj; 10594 if (adj >= worstType && !proc.killedByAm) { 10595 proc.kill(reason, true); 10596 killed = true; 10597 } 10598 } 10599 } 10600 return killed; 10601 } 10602 10603 @Override 10604 public void killUid(int uid, String reason) { 10605 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10606 throw new SecurityException("killUid only available to the system"); 10607 } 10608 synchronized (this) { 10609 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10610 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10611 reason != null ? reason : "kill uid"); 10612 } 10613 } 10614 10615 @Override 10616 public boolean killProcessesBelowForeground(String reason) { 10617 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10618 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10619 } 10620 10621 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10622 } 10623 10624 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10625 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10626 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10627 } 10628 10629 boolean killed = false; 10630 synchronized (mPidsSelfLocked) { 10631 final int size = mPidsSelfLocked.size(); 10632 for (int i = 0; i < size; i++) { 10633 final int pid = mPidsSelfLocked.keyAt(i); 10634 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10635 if (proc == null) continue; 10636 10637 final int adj = proc.setAdj; 10638 if (adj > belowAdj && !proc.killedByAm) { 10639 proc.kill(reason, true); 10640 killed = true; 10641 } 10642 } 10643 } 10644 return killed; 10645 } 10646 10647 @Override 10648 public void hang(final IBinder who, boolean allowRestart) { 10649 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10650 != PackageManager.PERMISSION_GRANTED) { 10651 throw new SecurityException("Requires permission " 10652 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10653 } 10654 10655 final IBinder.DeathRecipient death = new DeathRecipient() { 10656 @Override 10657 public void binderDied() { 10658 synchronized (this) { 10659 notifyAll(); 10660 } 10661 } 10662 }; 10663 10664 try { 10665 who.linkToDeath(death, 0); 10666 } catch (RemoteException e) { 10667 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10668 return; 10669 } 10670 10671 synchronized (this) { 10672 Watchdog.getInstance().setAllowRestart(allowRestart); 10673 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10674 synchronized (death) { 10675 while (who.isBinderAlive()) { 10676 try { 10677 death.wait(); 10678 } catch (InterruptedException e) { 10679 } 10680 } 10681 } 10682 Watchdog.getInstance().setAllowRestart(true); 10683 } 10684 } 10685 10686 @Override 10687 public void restart() { 10688 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10689 != PackageManager.PERMISSION_GRANTED) { 10690 throw new SecurityException("Requires permission " 10691 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10692 } 10693 10694 Log.i(TAG, "Sending shutdown broadcast..."); 10695 10696 BroadcastReceiver br = new BroadcastReceiver() { 10697 @Override public void onReceive(Context context, Intent intent) { 10698 // Now the broadcast is done, finish up the low-level shutdown. 10699 Log.i(TAG, "Shutting down activity manager..."); 10700 shutdown(10000); 10701 Log.i(TAG, "Shutdown complete, restarting!"); 10702 Process.killProcess(Process.myPid()); 10703 System.exit(10); 10704 } 10705 }; 10706 10707 // First send the high-level shut down broadcast. 10708 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10709 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10710 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10711 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10712 mContext.sendOrderedBroadcastAsUser(intent, 10713 UserHandle.ALL, null, br, mHandler, 0, null, null); 10714 */ 10715 br.onReceive(mContext, intent); 10716 } 10717 10718 private long getLowRamTimeSinceIdle(long now) { 10719 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10720 } 10721 10722 @Override 10723 public void performIdleMaintenance() { 10724 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10725 != PackageManager.PERMISSION_GRANTED) { 10726 throw new SecurityException("Requires permission " 10727 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10728 } 10729 10730 synchronized (this) { 10731 final long now = SystemClock.uptimeMillis(); 10732 final long timeSinceLastIdle = now - mLastIdleTime; 10733 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10734 mLastIdleTime = now; 10735 mLowRamTimeSinceLastIdle = 0; 10736 if (mLowRamStartTime != 0) { 10737 mLowRamStartTime = now; 10738 } 10739 10740 StringBuilder sb = new StringBuilder(128); 10741 sb.append("Idle maintenance over "); 10742 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10743 sb.append(" low RAM for "); 10744 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10745 Slog.i(TAG, sb.toString()); 10746 10747 // If at least 1/3 of our time since the last idle period has been spent 10748 // with RAM low, then we want to kill processes. 10749 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10750 10751 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10752 ProcessRecord proc = mLruProcesses.get(i); 10753 if (proc.notCachedSinceIdle) { 10754 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10755 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10756 if (doKilling && proc.initialIdlePss != 0 10757 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10758 proc.kill("idle maint (pss " + proc.lastPss 10759 + " from " + proc.initialIdlePss + ")", true); 10760 } 10761 } 10762 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10763 proc.notCachedSinceIdle = true; 10764 proc.initialIdlePss = 0; 10765 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10766 isSleeping(), now); 10767 } 10768 } 10769 10770 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10771 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10772 } 10773 } 10774 10775 private void retrieveSettings() { 10776 final ContentResolver resolver = mContext.getContentResolver(); 10777 String debugApp = Settings.Global.getString( 10778 resolver, Settings.Global.DEBUG_APP); 10779 boolean waitForDebugger = Settings.Global.getInt( 10780 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10781 boolean alwaysFinishActivities = Settings.Global.getInt( 10782 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10783 boolean forceRtl = Settings.Global.getInt( 10784 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10785 // Transfer any global setting for forcing RTL layout, into a System Property 10786 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10787 10788 Configuration configuration = new Configuration(); 10789 Settings.System.getConfiguration(resolver, configuration); 10790 if (forceRtl) { 10791 // This will take care of setting the correct layout direction flags 10792 configuration.setLayoutDirection(configuration.locale); 10793 } 10794 10795 synchronized (this) { 10796 mDebugApp = mOrigDebugApp = debugApp; 10797 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10798 mAlwaysFinishActivities = alwaysFinishActivities; 10799 // This happens before any activities are started, so we can 10800 // change mConfiguration in-place. 10801 updateConfigurationLocked(configuration, null, false, true); 10802 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10803 } 10804 } 10805 10806 /** Loads resources after the current configuration has been set. */ 10807 private void loadResourcesOnSystemReady() { 10808 final Resources res = mContext.getResources(); 10809 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10810 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10811 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10812 } 10813 10814 public boolean testIsSystemReady() { 10815 // no need to synchronize(this) just to read & return the value 10816 return mSystemReady; 10817 } 10818 10819 private static File getCalledPreBootReceiversFile() { 10820 File dataDir = Environment.getDataDirectory(); 10821 File systemDir = new File(dataDir, "system"); 10822 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10823 return fname; 10824 } 10825 10826 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10827 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10828 File file = getCalledPreBootReceiversFile(); 10829 FileInputStream fis = null; 10830 try { 10831 fis = new FileInputStream(file); 10832 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10833 int fvers = dis.readInt(); 10834 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10835 String vers = dis.readUTF(); 10836 String codename = dis.readUTF(); 10837 String build = dis.readUTF(); 10838 if (android.os.Build.VERSION.RELEASE.equals(vers) 10839 && android.os.Build.VERSION.CODENAME.equals(codename) 10840 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10841 int num = dis.readInt(); 10842 while (num > 0) { 10843 num--; 10844 String pkg = dis.readUTF(); 10845 String cls = dis.readUTF(); 10846 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10847 } 10848 } 10849 } 10850 } catch (FileNotFoundException e) { 10851 } catch (IOException e) { 10852 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10853 } finally { 10854 if (fis != null) { 10855 try { 10856 fis.close(); 10857 } catch (IOException e) { 10858 } 10859 } 10860 } 10861 return lastDoneReceivers; 10862 } 10863 10864 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10865 File file = getCalledPreBootReceiversFile(); 10866 FileOutputStream fos = null; 10867 DataOutputStream dos = null; 10868 try { 10869 fos = new FileOutputStream(file); 10870 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10871 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10872 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10873 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10874 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10875 dos.writeInt(list.size()); 10876 for (int i=0; i<list.size(); i++) { 10877 dos.writeUTF(list.get(i).getPackageName()); 10878 dos.writeUTF(list.get(i).getClassName()); 10879 } 10880 } catch (IOException e) { 10881 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10882 file.delete(); 10883 } finally { 10884 FileUtils.sync(fos); 10885 if (dos != null) { 10886 try { 10887 dos.close(); 10888 } catch (IOException e) { 10889 // TODO Auto-generated catch block 10890 e.printStackTrace(); 10891 } 10892 } 10893 } 10894 } 10895 10896 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10897 ArrayList<ComponentName> doneReceivers, int userId) { 10898 boolean waitingUpdate = false; 10899 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10900 List<ResolveInfo> ris = null; 10901 try { 10902 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10903 intent, null, 0, userId); 10904 } catch (RemoteException e) { 10905 } 10906 if (ris != null) { 10907 for (int i=ris.size()-1; i>=0; i--) { 10908 if ((ris.get(i).activityInfo.applicationInfo.flags 10909 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10910 ris.remove(i); 10911 } 10912 } 10913 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10914 10915 // For User 0, load the version number. When delivering to a new user, deliver 10916 // to all receivers. 10917 if (userId == UserHandle.USER_OWNER) { 10918 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10919 for (int i=0; i<ris.size(); i++) { 10920 ActivityInfo ai = ris.get(i).activityInfo; 10921 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10922 if (lastDoneReceivers.contains(comp)) { 10923 // We already did the pre boot receiver for this app with the current 10924 // platform version, so don't do it again... 10925 ris.remove(i); 10926 i--; 10927 // ...however, do keep it as one that has been done, so we don't 10928 // forget about it when rewriting the file of last done receivers. 10929 doneReceivers.add(comp); 10930 } 10931 } 10932 } 10933 10934 // If primary user, send broadcast to all available users, else just to userId 10935 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10936 : new int[] { userId }; 10937 for (int i = 0; i < ris.size(); i++) { 10938 ActivityInfo ai = ris.get(i).activityInfo; 10939 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10940 doneReceivers.add(comp); 10941 intent.setComponent(comp); 10942 for (int j=0; j<users.length; j++) { 10943 IIntentReceiver finisher = null; 10944 // On last receiver and user, set up a completion callback 10945 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10946 finisher = new IIntentReceiver.Stub() { 10947 public void performReceive(Intent intent, int resultCode, 10948 String data, Bundle extras, boolean ordered, 10949 boolean sticky, int sendingUser) { 10950 // The raw IIntentReceiver interface is called 10951 // with the AM lock held, so redispatch to 10952 // execute our code without the lock. 10953 mHandler.post(onFinishCallback); 10954 } 10955 }; 10956 } 10957 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10958 + " for user " + users[j]); 10959 broadcastIntentLocked(null, null, intent, null, finisher, 10960 0, null, null, null, AppOpsManager.OP_NONE, 10961 true, false, MY_PID, Process.SYSTEM_UID, 10962 users[j]); 10963 if (finisher != null) { 10964 waitingUpdate = true; 10965 } 10966 } 10967 } 10968 } 10969 10970 return waitingUpdate; 10971 } 10972 10973 public void systemReady(final Runnable goingCallback) { 10974 synchronized(this) { 10975 if (mSystemReady) { 10976 // If we're done calling all the receivers, run the next "boot phase" passed in 10977 // by the SystemServer 10978 if (goingCallback != null) { 10979 goingCallback.run(); 10980 } 10981 return; 10982 } 10983 10984 // Make sure we have the current profile info, since it is needed for 10985 // security checks. 10986 updateCurrentProfileIdsLocked(); 10987 10988 if (mRecentTasks == null) { 10989 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10990 if (!mRecentTasks.isEmpty()) { 10991 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10992 } 10993 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10994 mTaskPersister.startPersisting(); 10995 } 10996 10997 // Check to see if there are any update receivers to run. 10998 if (!mDidUpdate) { 10999 if (mWaitingUpdate) { 11000 return; 11001 } 11002 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 11003 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 11004 public void run() { 11005 synchronized (ActivityManagerService.this) { 11006 mDidUpdate = true; 11007 } 11008 writeLastDonePreBootReceivers(doneReceivers); 11009 showBootMessage(mContext.getText( 11010 R.string.android_upgrading_complete), 11011 false); 11012 systemReady(goingCallback); 11013 } 11014 }, doneReceivers, UserHandle.USER_OWNER); 11015 11016 if (mWaitingUpdate) { 11017 return; 11018 } 11019 mDidUpdate = true; 11020 } 11021 11022 mAppOpsService.systemReady(); 11023 mSystemReady = true; 11024 } 11025 11026 ArrayList<ProcessRecord> procsToKill = null; 11027 synchronized(mPidsSelfLocked) { 11028 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 11029 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 11030 if (!isAllowedWhileBooting(proc.info)){ 11031 if (procsToKill == null) { 11032 procsToKill = new ArrayList<ProcessRecord>(); 11033 } 11034 procsToKill.add(proc); 11035 } 11036 } 11037 } 11038 11039 synchronized(this) { 11040 if (procsToKill != null) { 11041 for (int i=procsToKill.size()-1; i>=0; i--) { 11042 ProcessRecord proc = procsToKill.get(i); 11043 Slog.i(TAG, "Removing system update proc: " + proc); 11044 removeProcessLocked(proc, true, false, "system update done"); 11045 } 11046 } 11047 11048 // Now that we have cleaned up any update processes, we 11049 // are ready to start launching real processes and know that 11050 // we won't trample on them any more. 11051 mProcessesReady = true; 11052 } 11053 11054 Slog.i(TAG, "System now ready"); 11055 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11056 SystemClock.uptimeMillis()); 11057 11058 synchronized(this) { 11059 // Make sure we have no pre-ready processes sitting around. 11060 11061 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11062 ResolveInfo ri = mContext.getPackageManager() 11063 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11064 STOCK_PM_FLAGS); 11065 CharSequence errorMsg = null; 11066 if (ri != null) { 11067 ActivityInfo ai = ri.activityInfo; 11068 ApplicationInfo app = ai.applicationInfo; 11069 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11070 mTopAction = Intent.ACTION_FACTORY_TEST; 11071 mTopData = null; 11072 mTopComponent = new ComponentName(app.packageName, 11073 ai.name); 11074 } else { 11075 errorMsg = mContext.getResources().getText( 11076 com.android.internal.R.string.factorytest_not_system); 11077 } 11078 } else { 11079 errorMsg = mContext.getResources().getText( 11080 com.android.internal.R.string.factorytest_no_action); 11081 } 11082 if (errorMsg != null) { 11083 mTopAction = null; 11084 mTopData = null; 11085 mTopComponent = null; 11086 Message msg = Message.obtain(); 11087 msg.what = SHOW_FACTORY_ERROR_MSG; 11088 msg.getData().putCharSequence("msg", errorMsg); 11089 mHandler.sendMessage(msg); 11090 } 11091 } 11092 } 11093 11094 retrieveSettings(); 11095 loadResourcesOnSystemReady(); 11096 11097 synchronized (this) { 11098 readGrantedUriPermissionsLocked(); 11099 } 11100 11101 if (goingCallback != null) goingCallback.run(); 11102 11103 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11104 Integer.toString(mCurrentUserId), mCurrentUserId); 11105 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11106 Integer.toString(mCurrentUserId), mCurrentUserId); 11107 mSystemServiceManager.startUser(mCurrentUserId); 11108 11109 synchronized (this) { 11110 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11111 try { 11112 List apps = AppGlobals.getPackageManager(). 11113 getPersistentApplications(STOCK_PM_FLAGS); 11114 if (apps != null) { 11115 int N = apps.size(); 11116 int i; 11117 for (i=0; i<N; i++) { 11118 ApplicationInfo info 11119 = (ApplicationInfo)apps.get(i); 11120 if (info != null && 11121 !info.packageName.equals("android")) { 11122 addAppLocked(info, false, null /* ABI override */); 11123 } 11124 } 11125 } 11126 } catch (RemoteException ex) { 11127 // pm is in same process, this will never happen. 11128 } 11129 } 11130 11131 // Start up initial activity. 11132 mBooting = true; 11133 11134 try { 11135 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11136 Message msg = Message.obtain(); 11137 msg.what = SHOW_UID_ERROR_MSG; 11138 mHandler.sendMessage(msg); 11139 } 11140 } catch (RemoteException e) { 11141 } 11142 11143 long ident = Binder.clearCallingIdentity(); 11144 try { 11145 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11146 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11147 | Intent.FLAG_RECEIVER_FOREGROUND); 11148 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11149 broadcastIntentLocked(null, null, intent, 11150 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11151 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11152 intent = new Intent(Intent.ACTION_USER_STARTING); 11153 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11154 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11155 broadcastIntentLocked(null, null, intent, 11156 null, new IIntentReceiver.Stub() { 11157 @Override 11158 public void performReceive(Intent intent, int resultCode, String data, 11159 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11160 throws RemoteException { 11161 } 11162 }, 0, null, null, 11163 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11164 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11165 } catch (Throwable t) { 11166 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11167 } finally { 11168 Binder.restoreCallingIdentity(ident); 11169 } 11170 mStackSupervisor.resumeTopActivitiesLocked(); 11171 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11172 } 11173 } 11174 11175 private boolean makeAppCrashingLocked(ProcessRecord app, 11176 String shortMsg, String longMsg, String stackTrace) { 11177 app.crashing = true; 11178 app.crashingReport = generateProcessError(app, 11179 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11180 startAppProblemLocked(app); 11181 app.stopFreezingAllLocked(); 11182 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11183 } 11184 11185 private void makeAppNotRespondingLocked(ProcessRecord app, 11186 String activity, String shortMsg, String longMsg) { 11187 app.notResponding = true; 11188 app.notRespondingReport = generateProcessError(app, 11189 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11190 activity, shortMsg, longMsg, null); 11191 startAppProblemLocked(app); 11192 app.stopFreezingAllLocked(); 11193 } 11194 11195 /** 11196 * Generate a process error record, suitable for attachment to a ProcessRecord. 11197 * 11198 * @param app The ProcessRecord in which the error occurred. 11199 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11200 * ActivityManager.AppErrorStateInfo 11201 * @param activity The activity associated with the crash, if known. 11202 * @param shortMsg Short message describing the crash. 11203 * @param longMsg Long message describing the crash. 11204 * @param stackTrace Full crash stack trace, may be null. 11205 * 11206 * @return Returns a fully-formed AppErrorStateInfo record. 11207 */ 11208 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11209 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11210 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11211 11212 report.condition = condition; 11213 report.processName = app.processName; 11214 report.pid = app.pid; 11215 report.uid = app.info.uid; 11216 report.tag = activity; 11217 report.shortMsg = shortMsg; 11218 report.longMsg = longMsg; 11219 report.stackTrace = stackTrace; 11220 11221 return report; 11222 } 11223 11224 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11225 synchronized (this) { 11226 app.crashing = false; 11227 app.crashingReport = null; 11228 app.notResponding = false; 11229 app.notRespondingReport = null; 11230 if (app.anrDialog == fromDialog) { 11231 app.anrDialog = null; 11232 } 11233 if (app.waitDialog == fromDialog) { 11234 app.waitDialog = null; 11235 } 11236 if (app.pid > 0 && app.pid != MY_PID) { 11237 handleAppCrashLocked(app, null, null, null); 11238 app.kill("user request after error", true); 11239 } 11240 } 11241 } 11242 11243 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11244 String stackTrace) { 11245 long now = SystemClock.uptimeMillis(); 11246 11247 Long crashTime; 11248 if (!app.isolated) { 11249 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11250 } else { 11251 crashTime = null; 11252 } 11253 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11254 // This process loses! 11255 Slog.w(TAG, "Process " + app.info.processName 11256 + " has crashed too many times: killing!"); 11257 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11258 app.userId, app.info.processName, app.uid); 11259 mStackSupervisor.handleAppCrashLocked(app); 11260 if (!app.persistent) { 11261 // We don't want to start this process again until the user 11262 // explicitly does so... but for persistent process, we really 11263 // need to keep it running. If a persistent process is actually 11264 // repeatedly crashing, then badness for everyone. 11265 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11266 app.info.processName); 11267 if (!app.isolated) { 11268 // XXX We don't have a way to mark isolated processes 11269 // as bad, since they don't have a peristent identity. 11270 mBadProcesses.put(app.info.processName, app.uid, 11271 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11272 mProcessCrashTimes.remove(app.info.processName, app.uid); 11273 } 11274 app.bad = true; 11275 app.removed = true; 11276 // Don't let services in this process be restarted and potentially 11277 // annoy the user repeatedly. Unless it is persistent, since those 11278 // processes run critical code. 11279 removeProcessLocked(app, false, false, "crash"); 11280 mStackSupervisor.resumeTopActivitiesLocked(); 11281 return false; 11282 } 11283 mStackSupervisor.resumeTopActivitiesLocked(); 11284 } else { 11285 mStackSupervisor.finishTopRunningActivityLocked(app); 11286 } 11287 11288 // Bump up the crash count of any services currently running in the proc. 11289 for (int i=app.services.size()-1; i>=0; i--) { 11290 // Any services running in the application need to be placed 11291 // back in the pending list. 11292 ServiceRecord sr = app.services.valueAt(i); 11293 sr.crashCount++; 11294 } 11295 11296 // If the crashing process is what we consider to be the "home process" and it has been 11297 // replaced by a third-party app, clear the package preferred activities from packages 11298 // with a home activity running in the process to prevent a repeatedly crashing app 11299 // from blocking the user to manually clear the list. 11300 final ArrayList<ActivityRecord> activities = app.activities; 11301 if (app == mHomeProcess && activities.size() > 0 11302 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11303 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11304 final ActivityRecord r = activities.get(activityNdx); 11305 if (r.isHomeActivity()) { 11306 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11307 try { 11308 ActivityThread.getPackageManager() 11309 .clearPackagePreferredActivities(r.packageName); 11310 } catch (RemoteException c) { 11311 // pm is in same process, this will never happen. 11312 } 11313 } 11314 } 11315 } 11316 11317 if (!app.isolated) { 11318 // XXX Can't keep track of crash times for isolated processes, 11319 // because they don't have a perisistent identity. 11320 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11321 } 11322 11323 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11324 return true; 11325 } 11326 11327 void startAppProblemLocked(ProcessRecord app) { 11328 // If this app is not running under the current user, then we 11329 // can't give it a report button because that would require 11330 // launching the report UI under a different user. 11331 app.errorReportReceiver = null; 11332 11333 for (int userId : mCurrentProfileIds) { 11334 if (app.userId == userId) { 11335 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11336 mContext, app.info.packageName, app.info.flags); 11337 } 11338 } 11339 skipCurrentReceiverLocked(app); 11340 } 11341 11342 void skipCurrentReceiverLocked(ProcessRecord app) { 11343 for (BroadcastQueue queue : mBroadcastQueues) { 11344 queue.skipCurrentReceiverLocked(app); 11345 } 11346 } 11347 11348 /** 11349 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11350 * The application process will exit immediately after this call returns. 11351 * @param app object of the crashing app, null for the system server 11352 * @param crashInfo describing the exception 11353 */ 11354 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11355 ProcessRecord r = findAppProcess(app, "Crash"); 11356 final String processName = app == null ? "system_server" 11357 : (r == null ? "unknown" : r.processName); 11358 11359 handleApplicationCrashInner("crash", r, processName, crashInfo); 11360 } 11361 11362 /* Native crash reporting uses this inner version because it needs to be somewhat 11363 * decoupled from the AM-managed cleanup lifecycle 11364 */ 11365 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11366 ApplicationErrorReport.CrashInfo crashInfo) { 11367 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11368 UserHandle.getUserId(Binder.getCallingUid()), processName, 11369 r == null ? -1 : r.info.flags, 11370 crashInfo.exceptionClassName, 11371 crashInfo.exceptionMessage, 11372 crashInfo.throwFileName, 11373 crashInfo.throwLineNumber); 11374 11375 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11376 11377 crashApplication(r, crashInfo); 11378 } 11379 11380 public void handleApplicationStrictModeViolation( 11381 IBinder app, 11382 int violationMask, 11383 StrictMode.ViolationInfo info) { 11384 ProcessRecord r = findAppProcess(app, "StrictMode"); 11385 if (r == null) { 11386 return; 11387 } 11388 11389 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11390 Integer stackFingerprint = info.hashCode(); 11391 boolean logIt = true; 11392 synchronized (mAlreadyLoggedViolatedStacks) { 11393 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11394 logIt = false; 11395 // TODO: sub-sample into EventLog for these, with 11396 // the info.durationMillis? Then we'd get 11397 // the relative pain numbers, without logging all 11398 // the stack traces repeatedly. We'd want to do 11399 // likewise in the client code, which also does 11400 // dup suppression, before the Binder call. 11401 } else { 11402 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11403 mAlreadyLoggedViolatedStacks.clear(); 11404 } 11405 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11406 } 11407 } 11408 if (logIt) { 11409 logStrictModeViolationToDropBox(r, info); 11410 } 11411 } 11412 11413 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11414 AppErrorResult result = new AppErrorResult(); 11415 synchronized (this) { 11416 final long origId = Binder.clearCallingIdentity(); 11417 11418 Message msg = Message.obtain(); 11419 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11420 HashMap<String, Object> data = new HashMap<String, Object>(); 11421 data.put("result", result); 11422 data.put("app", r); 11423 data.put("violationMask", violationMask); 11424 data.put("info", info); 11425 msg.obj = data; 11426 mHandler.sendMessage(msg); 11427 11428 Binder.restoreCallingIdentity(origId); 11429 } 11430 int res = result.get(); 11431 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11432 } 11433 } 11434 11435 // Depending on the policy in effect, there could be a bunch of 11436 // these in quick succession so we try to batch these together to 11437 // minimize disk writes, number of dropbox entries, and maximize 11438 // compression, by having more fewer, larger records. 11439 private void logStrictModeViolationToDropBox( 11440 ProcessRecord process, 11441 StrictMode.ViolationInfo info) { 11442 if (info == null) { 11443 return; 11444 } 11445 final boolean isSystemApp = process == null || 11446 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11447 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11448 final String processName = process == null ? "unknown" : process.processName; 11449 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11450 final DropBoxManager dbox = (DropBoxManager) 11451 mContext.getSystemService(Context.DROPBOX_SERVICE); 11452 11453 // Exit early if the dropbox isn't configured to accept this report type. 11454 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11455 11456 boolean bufferWasEmpty; 11457 boolean needsFlush; 11458 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11459 synchronized (sb) { 11460 bufferWasEmpty = sb.length() == 0; 11461 appendDropBoxProcessHeaders(process, processName, sb); 11462 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11463 sb.append("System-App: ").append(isSystemApp).append("\n"); 11464 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11465 if (info.violationNumThisLoop != 0) { 11466 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11467 } 11468 if (info.numAnimationsRunning != 0) { 11469 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11470 } 11471 if (info.broadcastIntentAction != null) { 11472 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11473 } 11474 if (info.durationMillis != -1) { 11475 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11476 } 11477 if (info.numInstances != -1) { 11478 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11479 } 11480 if (info.tags != null) { 11481 for (String tag : info.tags) { 11482 sb.append("Span-Tag: ").append(tag).append("\n"); 11483 } 11484 } 11485 sb.append("\n"); 11486 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11487 sb.append(info.crashInfo.stackTrace); 11488 } 11489 sb.append("\n"); 11490 11491 // Only buffer up to ~64k. Various logging bits truncate 11492 // things at 128k. 11493 needsFlush = (sb.length() > 64 * 1024); 11494 } 11495 11496 // Flush immediately if the buffer's grown too large, or this 11497 // is a non-system app. Non-system apps are isolated with a 11498 // different tag & policy and not batched. 11499 // 11500 // Batching is useful during internal testing with 11501 // StrictMode settings turned up high. Without batching, 11502 // thousands of separate files could be created on boot. 11503 if (!isSystemApp || needsFlush) { 11504 new Thread("Error dump: " + dropboxTag) { 11505 @Override 11506 public void run() { 11507 String report; 11508 synchronized (sb) { 11509 report = sb.toString(); 11510 sb.delete(0, sb.length()); 11511 sb.trimToSize(); 11512 } 11513 if (report.length() != 0) { 11514 dbox.addText(dropboxTag, report); 11515 } 11516 } 11517 }.start(); 11518 return; 11519 } 11520 11521 // System app batching: 11522 if (!bufferWasEmpty) { 11523 // An existing dropbox-writing thread is outstanding, so 11524 // we don't need to start it up. The existing thread will 11525 // catch the buffer appends we just did. 11526 return; 11527 } 11528 11529 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11530 // (After this point, we shouldn't access AMS internal data structures.) 11531 new Thread("Error dump: " + dropboxTag) { 11532 @Override 11533 public void run() { 11534 // 5 second sleep to let stacks arrive and be batched together 11535 try { 11536 Thread.sleep(5000); // 5 seconds 11537 } catch (InterruptedException e) {} 11538 11539 String errorReport; 11540 synchronized (mStrictModeBuffer) { 11541 errorReport = mStrictModeBuffer.toString(); 11542 if (errorReport.length() == 0) { 11543 return; 11544 } 11545 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11546 mStrictModeBuffer.trimToSize(); 11547 } 11548 dbox.addText(dropboxTag, errorReport); 11549 } 11550 }.start(); 11551 } 11552 11553 /** 11554 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11555 * @param app object of the crashing app, null for the system server 11556 * @param tag reported by the caller 11557 * @param system whether this wtf is coming from the system 11558 * @param crashInfo describing the context of the error 11559 * @return true if the process should exit immediately (WTF is fatal) 11560 */ 11561 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11562 final ApplicationErrorReport.CrashInfo crashInfo) { 11563 final ProcessRecord r = findAppProcess(app, "WTF"); 11564 final String processName = app == null ? "system_server" 11565 : (r == null ? "unknown" : r.processName); 11566 11567 EventLog.writeEvent(EventLogTags.AM_WTF, 11568 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11569 processName, 11570 r == null ? -1 : r.info.flags, 11571 tag, crashInfo.exceptionMessage); 11572 11573 if (system) { 11574 // If this is coming from the system, we could very well have low-level 11575 // system locks held, so we want to do this all asynchronously. And we 11576 // never want this to become fatal, so there is that too. 11577 mHandler.post(new Runnable() { 11578 @Override public void run() { 11579 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11580 crashInfo); 11581 } 11582 }); 11583 return false; 11584 } 11585 11586 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11587 11588 if (r != null && r.pid != Process.myPid() && 11589 Settings.Global.getInt(mContext.getContentResolver(), 11590 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11591 crashApplication(r, crashInfo); 11592 return true; 11593 } else { 11594 return false; 11595 } 11596 } 11597 11598 /** 11599 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11600 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11601 */ 11602 private ProcessRecord findAppProcess(IBinder app, String reason) { 11603 if (app == null) { 11604 return null; 11605 } 11606 11607 synchronized (this) { 11608 final int NP = mProcessNames.getMap().size(); 11609 for (int ip=0; ip<NP; ip++) { 11610 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11611 final int NA = apps.size(); 11612 for (int ia=0; ia<NA; ia++) { 11613 ProcessRecord p = apps.valueAt(ia); 11614 if (p.thread != null && p.thread.asBinder() == app) { 11615 return p; 11616 } 11617 } 11618 } 11619 11620 Slog.w(TAG, "Can't find mystery application for " + reason 11621 + " from pid=" + Binder.getCallingPid() 11622 + " uid=" + Binder.getCallingUid() + ": " + app); 11623 return null; 11624 } 11625 } 11626 11627 /** 11628 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11629 * to append various headers to the dropbox log text. 11630 */ 11631 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11632 StringBuilder sb) { 11633 // Watchdog thread ends up invoking this function (with 11634 // a null ProcessRecord) to add the stack file to dropbox. 11635 // Do not acquire a lock on this (am) in such cases, as it 11636 // could cause a potential deadlock, if and when watchdog 11637 // is invoked due to unavailability of lock on am and it 11638 // would prevent watchdog from killing system_server. 11639 if (process == null) { 11640 sb.append("Process: ").append(processName).append("\n"); 11641 return; 11642 } 11643 // Note: ProcessRecord 'process' is guarded by the service 11644 // instance. (notably process.pkgList, which could otherwise change 11645 // concurrently during execution of this method) 11646 synchronized (this) { 11647 sb.append("Process: ").append(processName).append("\n"); 11648 int flags = process.info.flags; 11649 IPackageManager pm = AppGlobals.getPackageManager(); 11650 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11651 for (int ip=0; ip<process.pkgList.size(); ip++) { 11652 String pkg = process.pkgList.keyAt(ip); 11653 sb.append("Package: ").append(pkg); 11654 try { 11655 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11656 if (pi != null) { 11657 sb.append(" v").append(pi.versionCode); 11658 if (pi.versionName != null) { 11659 sb.append(" (").append(pi.versionName).append(")"); 11660 } 11661 } 11662 } catch (RemoteException e) { 11663 Slog.e(TAG, "Error getting package info: " + pkg, e); 11664 } 11665 sb.append("\n"); 11666 } 11667 } 11668 } 11669 11670 private static String processClass(ProcessRecord process) { 11671 if (process == null || process.pid == MY_PID) { 11672 return "system_server"; 11673 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11674 return "system_app"; 11675 } else { 11676 return "data_app"; 11677 } 11678 } 11679 11680 /** 11681 * Write a description of an error (crash, WTF, ANR) to the drop box. 11682 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11683 * @param process which caused the error, null means the system server 11684 * @param activity which triggered the error, null if unknown 11685 * @param parent activity related to the error, null if unknown 11686 * @param subject line related to the error, null if absent 11687 * @param report in long form describing the error, null if absent 11688 * @param logFile to include in the report, null if none 11689 * @param crashInfo giving an application stack trace, null if absent 11690 */ 11691 public void addErrorToDropBox(String eventType, 11692 ProcessRecord process, String processName, ActivityRecord activity, 11693 ActivityRecord parent, String subject, 11694 final String report, final File logFile, 11695 final ApplicationErrorReport.CrashInfo crashInfo) { 11696 // NOTE -- this must never acquire the ActivityManagerService lock, 11697 // otherwise the watchdog may be prevented from resetting the system. 11698 11699 final String dropboxTag = processClass(process) + "_" + eventType; 11700 final DropBoxManager dbox = (DropBoxManager) 11701 mContext.getSystemService(Context.DROPBOX_SERVICE); 11702 11703 // Exit early if the dropbox isn't configured to accept this report type. 11704 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11705 11706 final StringBuilder sb = new StringBuilder(1024); 11707 appendDropBoxProcessHeaders(process, processName, sb); 11708 if (activity != null) { 11709 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11710 } 11711 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11712 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11713 } 11714 if (parent != null && parent != activity) { 11715 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11716 } 11717 if (subject != null) { 11718 sb.append("Subject: ").append(subject).append("\n"); 11719 } 11720 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11721 if (Debug.isDebuggerConnected()) { 11722 sb.append("Debugger: Connected\n"); 11723 } 11724 sb.append("\n"); 11725 11726 // Do the rest in a worker thread to avoid blocking the caller on I/O 11727 // (After this point, we shouldn't access AMS internal data structures.) 11728 Thread worker = new Thread("Error dump: " + dropboxTag) { 11729 @Override 11730 public void run() { 11731 if (report != null) { 11732 sb.append(report); 11733 } 11734 if (logFile != null) { 11735 try { 11736 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11737 "\n\n[[TRUNCATED]]")); 11738 } catch (IOException e) { 11739 Slog.e(TAG, "Error reading " + logFile, e); 11740 } 11741 } 11742 if (crashInfo != null && crashInfo.stackTrace != null) { 11743 sb.append(crashInfo.stackTrace); 11744 } 11745 11746 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11747 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11748 if (lines > 0) { 11749 sb.append("\n"); 11750 11751 // Merge several logcat streams, and take the last N lines 11752 InputStreamReader input = null; 11753 try { 11754 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11755 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11756 "-b", "crash", 11757 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11758 11759 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11760 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11761 input = new InputStreamReader(logcat.getInputStream()); 11762 11763 int num; 11764 char[] buf = new char[8192]; 11765 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11766 } catch (IOException e) { 11767 Slog.e(TAG, "Error running logcat", e); 11768 } finally { 11769 if (input != null) try { input.close(); } catch (IOException e) {} 11770 } 11771 } 11772 11773 dbox.addText(dropboxTag, sb.toString()); 11774 } 11775 }; 11776 11777 if (process == null) { 11778 // If process is null, we are being called from some internal code 11779 // and may be about to die -- run this synchronously. 11780 worker.run(); 11781 } else { 11782 worker.start(); 11783 } 11784 } 11785 11786 /** 11787 * Bring up the "unexpected error" dialog box for a crashing app. 11788 * Deal with edge cases (intercepts from instrumented applications, 11789 * ActivityController, error intent receivers, that sort of thing). 11790 * @param r the application crashing 11791 * @param crashInfo describing the failure 11792 */ 11793 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11794 long timeMillis = System.currentTimeMillis(); 11795 String shortMsg = crashInfo.exceptionClassName; 11796 String longMsg = crashInfo.exceptionMessage; 11797 String stackTrace = crashInfo.stackTrace; 11798 if (shortMsg != null && longMsg != null) { 11799 longMsg = shortMsg + ": " + longMsg; 11800 } else if (shortMsg != null) { 11801 longMsg = shortMsg; 11802 } 11803 11804 AppErrorResult result = new AppErrorResult(); 11805 synchronized (this) { 11806 if (mController != null) { 11807 try { 11808 String name = r != null ? r.processName : null; 11809 int pid = r != null ? r.pid : Binder.getCallingPid(); 11810 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11811 if (!mController.appCrashed(name, pid, 11812 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11813 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11814 && "Native crash".equals(crashInfo.exceptionClassName)) { 11815 Slog.w(TAG, "Skip killing native crashed app " + name 11816 + "(" + pid + ") during testing"); 11817 } else { 11818 Slog.w(TAG, "Force-killing crashed app " + name 11819 + " at watcher's request"); 11820 if (r != null) { 11821 r.kill("crash", true); 11822 } else { 11823 // Huh. 11824 Process.killProcess(pid); 11825 Process.killProcessGroup(uid, pid); 11826 } 11827 } 11828 return; 11829 } 11830 } catch (RemoteException e) { 11831 mController = null; 11832 Watchdog.getInstance().setActivityController(null); 11833 } 11834 } 11835 11836 final long origId = Binder.clearCallingIdentity(); 11837 11838 // If this process is running instrumentation, finish it. 11839 if (r != null && r.instrumentationClass != null) { 11840 Slog.w(TAG, "Error in app " + r.processName 11841 + " running instrumentation " + r.instrumentationClass + ":"); 11842 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11843 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11844 Bundle info = new Bundle(); 11845 info.putString("shortMsg", shortMsg); 11846 info.putString("longMsg", longMsg); 11847 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11848 Binder.restoreCallingIdentity(origId); 11849 return; 11850 } 11851 11852 // If we can't identify the process or it's already exceeded its crash quota, 11853 // quit right away without showing a crash dialog. 11854 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11855 Binder.restoreCallingIdentity(origId); 11856 return; 11857 } 11858 11859 Message msg = Message.obtain(); 11860 msg.what = SHOW_ERROR_MSG; 11861 HashMap data = new HashMap(); 11862 data.put("result", result); 11863 data.put("app", r); 11864 msg.obj = data; 11865 mHandler.sendMessage(msg); 11866 11867 Binder.restoreCallingIdentity(origId); 11868 } 11869 11870 int res = result.get(); 11871 11872 Intent appErrorIntent = null; 11873 synchronized (this) { 11874 if (r != null && !r.isolated) { 11875 // XXX Can't keep track of crash time for isolated processes, 11876 // since they don't have a persistent identity. 11877 mProcessCrashTimes.put(r.info.processName, r.uid, 11878 SystemClock.uptimeMillis()); 11879 } 11880 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11881 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11882 } 11883 } 11884 11885 if (appErrorIntent != null) { 11886 try { 11887 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11888 } catch (ActivityNotFoundException e) { 11889 Slog.w(TAG, "bug report receiver dissappeared", e); 11890 } 11891 } 11892 } 11893 11894 Intent createAppErrorIntentLocked(ProcessRecord r, 11895 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11896 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11897 if (report == null) { 11898 return null; 11899 } 11900 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11901 result.setComponent(r.errorReportReceiver); 11902 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11903 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11904 return result; 11905 } 11906 11907 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11908 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11909 if (r.errorReportReceiver == null) { 11910 return null; 11911 } 11912 11913 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11914 return null; 11915 } 11916 11917 ApplicationErrorReport report = new ApplicationErrorReport(); 11918 report.packageName = r.info.packageName; 11919 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11920 report.processName = r.processName; 11921 report.time = timeMillis; 11922 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11923 11924 if (r.crashing || r.forceCrashReport) { 11925 report.type = ApplicationErrorReport.TYPE_CRASH; 11926 report.crashInfo = crashInfo; 11927 } else if (r.notResponding) { 11928 report.type = ApplicationErrorReport.TYPE_ANR; 11929 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11930 11931 report.anrInfo.activity = r.notRespondingReport.tag; 11932 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11933 report.anrInfo.info = r.notRespondingReport.longMsg; 11934 } 11935 11936 return report; 11937 } 11938 11939 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11940 enforceNotIsolatedCaller("getProcessesInErrorState"); 11941 // assume our apps are happy - lazy create the list 11942 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11943 11944 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11945 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11946 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11947 11948 synchronized (this) { 11949 11950 // iterate across all processes 11951 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11952 ProcessRecord app = mLruProcesses.get(i); 11953 if (!allUsers && app.userId != userId) { 11954 continue; 11955 } 11956 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11957 // This one's in trouble, so we'll generate a report for it 11958 // crashes are higher priority (in case there's a crash *and* an anr) 11959 ActivityManager.ProcessErrorStateInfo report = null; 11960 if (app.crashing) { 11961 report = app.crashingReport; 11962 } else if (app.notResponding) { 11963 report = app.notRespondingReport; 11964 } 11965 11966 if (report != null) { 11967 if (errList == null) { 11968 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11969 } 11970 errList.add(report); 11971 } else { 11972 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11973 " crashing = " + app.crashing + 11974 " notResponding = " + app.notResponding); 11975 } 11976 } 11977 } 11978 } 11979 11980 return errList; 11981 } 11982 11983 static int procStateToImportance(int procState, int memAdj, 11984 ActivityManager.RunningAppProcessInfo currApp) { 11985 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11986 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11987 currApp.lru = memAdj; 11988 } else { 11989 currApp.lru = 0; 11990 } 11991 return imp; 11992 } 11993 11994 private void fillInProcMemInfo(ProcessRecord app, 11995 ActivityManager.RunningAppProcessInfo outInfo) { 11996 outInfo.pid = app.pid; 11997 outInfo.uid = app.info.uid; 11998 if (mHeavyWeightProcess == app) { 11999 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 12000 } 12001 if (app.persistent) { 12002 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 12003 } 12004 if (app.activities.size() > 0) { 12005 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 12006 } 12007 outInfo.lastTrimLevel = app.trimMemoryLevel; 12008 int adj = app.curAdj; 12009 int procState = app.curProcState; 12010 outInfo.importance = procStateToImportance(procState, adj, outInfo); 12011 outInfo.importanceReasonCode = app.adjTypeCode; 12012 outInfo.processState = app.curProcState; 12013 } 12014 12015 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 12016 enforceNotIsolatedCaller("getRunningAppProcesses"); 12017 // Lazy instantiation of list 12018 List<ActivityManager.RunningAppProcessInfo> runList = null; 12019 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 12020 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 12021 int userId = UserHandle.getUserId(Binder.getCallingUid()); 12022 synchronized (this) { 12023 // Iterate across all processes 12024 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12025 ProcessRecord app = mLruProcesses.get(i); 12026 if (!allUsers && app.userId != userId) { 12027 continue; 12028 } 12029 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 12030 // Generate process state info for running application 12031 ActivityManager.RunningAppProcessInfo currApp = 12032 new ActivityManager.RunningAppProcessInfo(app.processName, 12033 app.pid, app.getPackageList()); 12034 fillInProcMemInfo(app, currApp); 12035 if (app.adjSource instanceof ProcessRecord) { 12036 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 12037 currApp.importanceReasonImportance = 12038 ActivityManager.RunningAppProcessInfo.procStateToImportance( 12039 app.adjSourceProcState); 12040 } else if (app.adjSource instanceof ActivityRecord) { 12041 ActivityRecord r = (ActivityRecord)app.adjSource; 12042 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12043 } 12044 if (app.adjTarget instanceof ComponentName) { 12045 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12046 } 12047 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12048 // + " lru=" + currApp.lru); 12049 if (runList == null) { 12050 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12051 } 12052 runList.add(currApp); 12053 } 12054 } 12055 } 12056 return runList; 12057 } 12058 12059 public List<ApplicationInfo> getRunningExternalApplications() { 12060 enforceNotIsolatedCaller("getRunningExternalApplications"); 12061 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12062 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12063 if (runningApps != null && runningApps.size() > 0) { 12064 Set<String> extList = new HashSet<String>(); 12065 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12066 if (app.pkgList != null) { 12067 for (String pkg : app.pkgList) { 12068 extList.add(pkg); 12069 } 12070 } 12071 } 12072 IPackageManager pm = AppGlobals.getPackageManager(); 12073 for (String pkg : extList) { 12074 try { 12075 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12076 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12077 retList.add(info); 12078 } 12079 } catch (RemoteException e) { 12080 } 12081 } 12082 } 12083 return retList; 12084 } 12085 12086 @Override 12087 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12088 enforceNotIsolatedCaller("getMyMemoryState"); 12089 synchronized (this) { 12090 ProcessRecord proc; 12091 synchronized (mPidsSelfLocked) { 12092 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12093 } 12094 fillInProcMemInfo(proc, outInfo); 12095 } 12096 } 12097 12098 @Override 12099 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12100 if (checkCallingPermission(android.Manifest.permission.DUMP) 12101 != PackageManager.PERMISSION_GRANTED) { 12102 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12103 + Binder.getCallingPid() 12104 + ", uid=" + Binder.getCallingUid() 12105 + " without permission " 12106 + android.Manifest.permission.DUMP); 12107 return; 12108 } 12109 12110 boolean dumpAll = false; 12111 boolean dumpClient = false; 12112 String dumpPackage = null; 12113 12114 int opti = 0; 12115 while (opti < args.length) { 12116 String opt = args[opti]; 12117 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12118 break; 12119 } 12120 opti++; 12121 if ("-a".equals(opt)) { 12122 dumpAll = true; 12123 } else if ("-c".equals(opt)) { 12124 dumpClient = true; 12125 } else if ("-h".equals(opt)) { 12126 pw.println("Activity manager dump options:"); 12127 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12128 pw.println(" cmd may be one of:"); 12129 pw.println(" a[ctivities]: activity stack state"); 12130 pw.println(" r[recents]: recent activities state"); 12131 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12132 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12133 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12134 pw.println(" o[om]: out of memory management"); 12135 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12136 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12137 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12138 pw.println(" service [COMP_SPEC]: service client-side state"); 12139 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12140 pw.println(" all: dump all activities"); 12141 pw.println(" top: dump the top activity"); 12142 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12143 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12144 pw.println(" a partial substring in a component name, a"); 12145 pw.println(" hex object identifier."); 12146 pw.println(" -a: include all available server state."); 12147 pw.println(" -c: include client state."); 12148 return; 12149 } else { 12150 pw.println("Unknown argument: " + opt + "; use -h for help"); 12151 } 12152 } 12153 12154 long origId = Binder.clearCallingIdentity(); 12155 boolean more = false; 12156 // Is the caller requesting to dump a particular piece of data? 12157 if (opti < args.length) { 12158 String cmd = args[opti]; 12159 opti++; 12160 if ("activities".equals(cmd) || "a".equals(cmd)) { 12161 synchronized (this) { 12162 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12163 } 12164 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12165 synchronized (this) { 12166 dumpRecentsLocked(fd, pw, args, opti, true, null); 12167 } 12168 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12169 String[] newArgs; 12170 String name; 12171 if (opti >= args.length) { 12172 name = null; 12173 newArgs = EMPTY_STRING_ARRAY; 12174 } else { 12175 name = args[opti]; 12176 opti++; 12177 newArgs = new String[args.length - opti]; 12178 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12179 args.length - opti); 12180 } 12181 synchronized (this) { 12182 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12183 } 12184 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12185 String[] newArgs; 12186 String name; 12187 if (opti >= args.length) { 12188 name = null; 12189 newArgs = EMPTY_STRING_ARRAY; 12190 } else { 12191 name = args[opti]; 12192 opti++; 12193 newArgs = new String[args.length - opti]; 12194 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12195 args.length - opti); 12196 } 12197 synchronized (this) { 12198 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12199 } 12200 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12201 String[] newArgs; 12202 String name; 12203 if (opti >= args.length) { 12204 name = null; 12205 newArgs = EMPTY_STRING_ARRAY; 12206 } else { 12207 name = args[opti]; 12208 opti++; 12209 newArgs = new String[args.length - opti]; 12210 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12211 args.length - opti); 12212 } 12213 synchronized (this) { 12214 dumpProcessesLocked(fd, pw, args, opti, true, name); 12215 } 12216 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12217 synchronized (this) { 12218 dumpOomLocked(fd, pw, args, opti, true); 12219 } 12220 } else if ("provider".equals(cmd)) { 12221 String[] newArgs; 12222 String name; 12223 if (opti >= args.length) { 12224 name = null; 12225 newArgs = EMPTY_STRING_ARRAY; 12226 } else { 12227 name = args[opti]; 12228 opti++; 12229 newArgs = new String[args.length - opti]; 12230 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12231 } 12232 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12233 pw.println("No providers match: " + name); 12234 pw.println("Use -h for help."); 12235 } 12236 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12237 synchronized (this) { 12238 dumpProvidersLocked(fd, pw, args, opti, true, null); 12239 } 12240 } else if ("service".equals(cmd)) { 12241 String[] newArgs; 12242 String name; 12243 if (opti >= args.length) { 12244 name = null; 12245 newArgs = EMPTY_STRING_ARRAY; 12246 } else { 12247 name = args[opti]; 12248 opti++; 12249 newArgs = new String[args.length - opti]; 12250 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12251 args.length - opti); 12252 } 12253 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12254 pw.println("No services match: " + name); 12255 pw.println("Use -h for help."); 12256 } 12257 } else if ("package".equals(cmd)) { 12258 String[] newArgs; 12259 if (opti >= args.length) { 12260 pw.println("package: no package name specified"); 12261 pw.println("Use -h for help."); 12262 } else { 12263 dumpPackage = args[opti]; 12264 opti++; 12265 newArgs = new String[args.length - opti]; 12266 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12267 args.length - opti); 12268 args = newArgs; 12269 opti = 0; 12270 more = true; 12271 } 12272 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12273 synchronized (this) { 12274 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12275 } 12276 } else { 12277 // Dumping a single activity? 12278 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12279 pw.println("Bad activity command, or no activities match: " + cmd); 12280 pw.println("Use -h for help."); 12281 } 12282 } 12283 if (!more) { 12284 Binder.restoreCallingIdentity(origId); 12285 return; 12286 } 12287 } 12288 12289 // No piece of data specified, dump everything. 12290 synchronized (this) { 12291 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12292 pw.println(); 12293 if (dumpAll) { 12294 pw.println("-------------------------------------------------------------------------------"); 12295 } 12296 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12297 pw.println(); 12298 if (dumpAll) { 12299 pw.println("-------------------------------------------------------------------------------"); 12300 } 12301 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12302 pw.println(); 12303 if (dumpAll) { 12304 pw.println("-------------------------------------------------------------------------------"); 12305 } 12306 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12307 pw.println(); 12308 if (dumpAll) { 12309 pw.println("-------------------------------------------------------------------------------"); 12310 } 12311 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12312 pw.println(); 12313 if (dumpAll) { 12314 pw.println("-------------------------------------------------------------------------------"); 12315 } 12316 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12317 pw.println(); 12318 if (dumpAll) { 12319 pw.println("-------------------------------------------------------------------------------"); 12320 } 12321 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12322 } 12323 Binder.restoreCallingIdentity(origId); 12324 } 12325 12326 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12327 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12328 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12329 12330 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12331 dumpPackage); 12332 boolean needSep = printedAnything; 12333 12334 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12335 dumpPackage, needSep, " mFocusedActivity: "); 12336 if (printed) { 12337 printedAnything = true; 12338 needSep = false; 12339 } 12340 12341 if (dumpPackage == null) { 12342 if (needSep) { 12343 pw.println(); 12344 } 12345 needSep = true; 12346 printedAnything = true; 12347 mStackSupervisor.dump(pw, " "); 12348 } 12349 12350 if (!printedAnything) { 12351 pw.println(" (nothing)"); 12352 } 12353 } 12354 12355 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12356 int opti, boolean dumpAll, String dumpPackage) { 12357 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12358 12359 boolean printedAnything = false; 12360 12361 if (mRecentTasks.size() > 0) { 12362 boolean printedHeader = false; 12363 12364 final int N = mRecentTasks.size(); 12365 for (int i=0; i<N; i++) { 12366 TaskRecord tr = mRecentTasks.get(i); 12367 if (dumpPackage != null) { 12368 if (tr.realActivity == null || 12369 !dumpPackage.equals(tr.realActivity)) { 12370 continue; 12371 } 12372 } 12373 if (!printedHeader) { 12374 pw.println(" Recent tasks:"); 12375 printedHeader = true; 12376 printedAnything = true; 12377 } 12378 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12379 pw.println(tr); 12380 if (dumpAll) { 12381 mRecentTasks.get(i).dump(pw, " "); 12382 } 12383 } 12384 } 12385 12386 if (!printedAnything) { 12387 pw.println(" (nothing)"); 12388 } 12389 } 12390 12391 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12392 int opti, boolean dumpAll, String dumpPackage) { 12393 boolean needSep = false; 12394 boolean printedAnything = false; 12395 int numPers = 0; 12396 12397 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12398 12399 if (dumpAll) { 12400 final int NP = mProcessNames.getMap().size(); 12401 for (int ip=0; ip<NP; ip++) { 12402 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12403 final int NA = procs.size(); 12404 for (int ia=0; ia<NA; ia++) { 12405 ProcessRecord r = procs.valueAt(ia); 12406 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12407 continue; 12408 } 12409 if (!needSep) { 12410 pw.println(" All known processes:"); 12411 needSep = true; 12412 printedAnything = true; 12413 } 12414 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12415 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12416 pw.print(" "); pw.println(r); 12417 r.dump(pw, " "); 12418 if (r.persistent) { 12419 numPers++; 12420 } 12421 } 12422 } 12423 } 12424 12425 if (mIsolatedProcesses.size() > 0) { 12426 boolean printed = false; 12427 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12428 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12429 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12430 continue; 12431 } 12432 if (!printed) { 12433 if (needSep) { 12434 pw.println(); 12435 } 12436 pw.println(" Isolated process list (sorted by uid):"); 12437 printedAnything = true; 12438 printed = true; 12439 needSep = true; 12440 } 12441 pw.println(String.format("%sIsolated #%2d: %s", 12442 " ", i, r.toString())); 12443 } 12444 } 12445 12446 if (mLruProcesses.size() > 0) { 12447 if (needSep) { 12448 pw.println(); 12449 } 12450 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12451 pw.print(" total, non-act at "); 12452 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12453 pw.print(", non-svc at "); 12454 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12455 pw.println("):"); 12456 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12457 needSep = true; 12458 printedAnything = true; 12459 } 12460 12461 if (dumpAll || dumpPackage != null) { 12462 synchronized (mPidsSelfLocked) { 12463 boolean printed = false; 12464 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12465 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12466 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12467 continue; 12468 } 12469 if (!printed) { 12470 if (needSep) pw.println(); 12471 needSep = true; 12472 pw.println(" PID mappings:"); 12473 printed = true; 12474 printedAnything = true; 12475 } 12476 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12477 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12478 } 12479 } 12480 } 12481 12482 if (mForegroundProcesses.size() > 0) { 12483 synchronized (mPidsSelfLocked) { 12484 boolean printed = false; 12485 for (int i=0; i<mForegroundProcesses.size(); i++) { 12486 ProcessRecord r = mPidsSelfLocked.get( 12487 mForegroundProcesses.valueAt(i).pid); 12488 if (dumpPackage != null && (r == null 12489 || !r.pkgList.containsKey(dumpPackage))) { 12490 continue; 12491 } 12492 if (!printed) { 12493 if (needSep) pw.println(); 12494 needSep = true; 12495 pw.println(" Foreground Processes:"); 12496 printed = true; 12497 printedAnything = true; 12498 } 12499 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12500 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12501 } 12502 } 12503 } 12504 12505 if (mPersistentStartingProcesses.size() > 0) { 12506 if (needSep) pw.println(); 12507 needSep = true; 12508 printedAnything = true; 12509 pw.println(" Persisent processes that are starting:"); 12510 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12511 "Starting Norm", "Restarting PERS", dumpPackage); 12512 } 12513 12514 if (mRemovedProcesses.size() > 0) { 12515 if (needSep) pw.println(); 12516 needSep = true; 12517 printedAnything = true; 12518 pw.println(" Processes that are being removed:"); 12519 dumpProcessList(pw, this, mRemovedProcesses, " ", 12520 "Removed Norm", "Removed PERS", dumpPackage); 12521 } 12522 12523 if (mProcessesOnHold.size() > 0) { 12524 if (needSep) pw.println(); 12525 needSep = true; 12526 printedAnything = true; 12527 pw.println(" Processes that are on old until the system is ready:"); 12528 dumpProcessList(pw, this, mProcessesOnHold, " ", 12529 "OnHold Norm", "OnHold PERS", dumpPackage); 12530 } 12531 12532 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12533 12534 if (mProcessCrashTimes.getMap().size() > 0) { 12535 boolean printed = false; 12536 long now = SystemClock.uptimeMillis(); 12537 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12538 final int NP = pmap.size(); 12539 for (int ip=0; ip<NP; ip++) { 12540 String pname = pmap.keyAt(ip); 12541 SparseArray<Long> uids = pmap.valueAt(ip); 12542 final int N = uids.size(); 12543 for (int i=0; i<N; i++) { 12544 int puid = uids.keyAt(i); 12545 ProcessRecord r = mProcessNames.get(pname, puid); 12546 if (dumpPackage != null && (r == null 12547 || !r.pkgList.containsKey(dumpPackage))) { 12548 continue; 12549 } 12550 if (!printed) { 12551 if (needSep) pw.println(); 12552 needSep = true; 12553 pw.println(" Time since processes crashed:"); 12554 printed = true; 12555 printedAnything = true; 12556 } 12557 pw.print(" Process "); pw.print(pname); 12558 pw.print(" uid "); pw.print(puid); 12559 pw.print(": last crashed "); 12560 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12561 pw.println(" ago"); 12562 } 12563 } 12564 } 12565 12566 if (mBadProcesses.getMap().size() > 0) { 12567 boolean printed = false; 12568 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12569 final int NP = pmap.size(); 12570 for (int ip=0; ip<NP; ip++) { 12571 String pname = pmap.keyAt(ip); 12572 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12573 final int N = uids.size(); 12574 for (int i=0; i<N; i++) { 12575 int puid = uids.keyAt(i); 12576 ProcessRecord r = mProcessNames.get(pname, puid); 12577 if (dumpPackage != null && (r == null 12578 || !r.pkgList.containsKey(dumpPackage))) { 12579 continue; 12580 } 12581 if (!printed) { 12582 if (needSep) pw.println(); 12583 needSep = true; 12584 pw.println(" Bad processes:"); 12585 printedAnything = true; 12586 } 12587 BadProcessInfo info = uids.valueAt(i); 12588 pw.print(" Bad process "); pw.print(pname); 12589 pw.print(" uid "); pw.print(puid); 12590 pw.print(": crashed at time "); pw.println(info.time); 12591 if (info.shortMsg != null) { 12592 pw.print(" Short msg: "); pw.println(info.shortMsg); 12593 } 12594 if (info.longMsg != null) { 12595 pw.print(" Long msg: "); pw.println(info.longMsg); 12596 } 12597 if (info.stack != null) { 12598 pw.println(" Stack:"); 12599 int lastPos = 0; 12600 for (int pos=0; pos<info.stack.length(); pos++) { 12601 if (info.stack.charAt(pos) == '\n') { 12602 pw.print(" "); 12603 pw.write(info.stack, lastPos, pos-lastPos); 12604 pw.println(); 12605 lastPos = pos+1; 12606 } 12607 } 12608 if (lastPos < info.stack.length()) { 12609 pw.print(" "); 12610 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12611 pw.println(); 12612 } 12613 } 12614 } 12615 } 12616 } 12617 12618 if (dumpPackage == null) { 12619 pw.println(); 12620 needSep = false; 12621 pw.println(" mStartedUsers:"); 12622 for (int i=0; i<mStartedUsers.size(); i++) { 12623 UserStartedState uss = mStartedUsers.valueAt(i); 12624 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12625 pw.print(": "); uss.dump("", pw); 12626 } 12627 pw.print(" mStartedUserArray: ["); 12628 for (int i=0; i<mStartedUserArray.length; i++) { 12629 if (i > 0) pw.print(", "); 12630 pw.print(mStartedUserArray[i]); 12631 } 12632 pw.println("]"); 12633 pw.print(" mUserLru: ["); 12634 for (int i=0; i<mUserLru.size(); i++) { 12635 if (i > 0) pw.print(", "); 12636 pw.print(mUserLru.get(i)); 12637 } 12638 pw.println("]"); 12639 if (dumpAll) { 12640 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12641 } 12642 synchronized (mUserProfileGroupIdsSelfLocked) { 12643 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12644 pw.println(" mUserProfileGroupIds:"); 12645 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12646 pw.print(" User #"); 12647 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12648 pw.print(" -> profile #"); 12649 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12650 } 12651 } 12652 } 12653 } 12654 if (mHomeProcess != null && (dumpPackage == null 12655 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12656 if (needSep) { 12657 pw.println(); 12658 needSep = false; 12659 } 12660 pw.println(" mHomeProcess: " + mHomeProcess); 12661 } 12662 if (mPreviousProcess != null && (dumpPackage == null 12663 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12664 if (needSep) { 12665 pw.println(); 12666 needSep = false; 12667 } 12668 pw.println(" mPreviousProcess: " + mPreviousProcess); 12669 } 12670 if (dumpAll) { 12671 StringBuilder sb = new StringBuilder(128); 12672 sb.append(" mPreviousProcessVisibleTime: "); 12673 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12674 pw.println(sb); 12675 } 12676 if (mHeavyWeightProcess != null && (dumpPackage == null 12677 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12678 if (needSep) { 12679 pw.println(); 12680 needSep = false; 12681 } 12682 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12683 } 12684 if (dumpPackage == null) { 12685 pw.println(" mConfiguration: " + mConfiguration); 12686 } 12687 if (dumpAll) { 12688 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12689 if (mCompatModePackages.getPackages().size() > 0) { 12690 boolean printed = false; 12691 for (Map.Entry<String, Integer> entry 12692 : mCompatModePackages.getPackages().entrySet()) { 12693 String pkg = entry.getKey(); 12694 int mode = entry.getValue(); 12695 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12696 continue; 12697 } 12698 if (!printed) { 12699 pw.println(" mScreenCompatPackages:"); 12700 printed = true; 12701 } 12702 pw.print(" "); pw.print(pkg); pw.print(": "); 12703 pw.print(mode); pw.println(); 12704 } 12705 } 12706 } 12707 if (dumpPackage == null) { 12708 if (mSleeping || mWentToSleep || mLockScreenShown) { 12709 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12710 + " mLockScreenShown " + mLockScreenShown); 12711 } 12712 if (mShuttingDown || mRunningVoice) { 12713 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12714 } 12715 } 12716 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12717 || mOrigWaitForDebugger) { 12718 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12719 || dumpPackage.equals(mOrigDebugApp)) { 12720 if (needSep) { 12721 pw.println(); 12722 needSep = false; 12723 } 12724 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12725 + " mDebugTransient=" + mDebugTransient 12726 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12727 } 12728 } 12729 if (mOpenGlTraceApp != null) { 12730 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12731 if (needSep) { 12732 pw.println(); 12733 needSep = false; 12734 } 12735 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12736 } 12737 } 12738 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12739 || mProfileFd != null) { 12740 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12741 if (needSep) { 12742 pw.println(); 12743 needSep = false; 12744 } 12745 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12746 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12747 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12748 + mAutoStopProfiler); 12749 pw.println(" mProfileType=" + mProfileType); 12750 } 12751 } 12752 if (dumpPackage == null) { 12753 if (mAlwaysFinishActivities || mController != null) { 12754 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12755 + " mController=" + mController); 12756 } 12757 if (dumpAll) { 12758 pw.println(" Total persistent processes: " + numPers); 12759 pw.println(" mProcessesReady=" + mProcessesReady 12760 + " mSystemReady=" + mSystemReady); 12761 pw.println(" mBooting=" + mBooting 12762 + " mBooted=" + mBooted 12763 + " mFactoryTest=" + mFactoryTest); 12764 pw.print(" mLastPowerCheckRealtime="); 12765 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12766 pw.println(""); 12767 pw.print(" mLastPowerCheckUptime="); 12768 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12769 pw.println(""); 12770 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12771 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12772 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12773 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12774 + " (" + mLruProcesses.size() + " total)" 12775 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12776 + " mNumServiceProcs=" + mNumServiceProcs 12777 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12778 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12779 + " mLastMemoryLevel" + mLastMemoryLevel 12780 + " mLastNumProcesses" + mLastNumProcesses); 12781 long now = SystemClock.uptimeMillis(); 12782 pw.print(" mLastIdleTime="); 12783 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12784 pw.print(" mLowRamSinceLastIdle="); 12785 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12786 pw.println(); 12787 } 12788 } 12789 12790 if (!printedAnything) { 12791 pw.println(" (nothing)"); 12792 } 12793 } 12794 12795 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12796 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12797 if (mProcessesToGc.size() > 0) { 12798 boolean printed = false; 12799 long now = SystemClock.uptimeMillis(); 12800 for (int i=0; i<mProcessesToGc.size(); i++) { 12801 ProcessRecord proc = mProcessesToGc.get(i); 12802 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12803 continue; 12804 } 12805 if (!printed) { 12806 if (needSep) pw.println(); 12807 needSep = true; 12808 pw.println(" Processes that are waiting to GC:"); 12809 printed = true; 12810 } 12811 pw.print(" Process "); pw.println(proc); 12812 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12813 pw.print(", last gced="); 12814 pw.print(now-proc.lastRequestedGc); 12815 pw.print(" ms ago, last lowMem="); 12816 pw.print(now-proc.lastLowMemory); 12817 pw.println(" ms ago"); 12818 12819 } 12820 } 12821 return needSep; 12822 } 12823 12824 void printOomLevel(PrintWriter pw, String name, int adj) { 12825 pw.print(" "); 12826 if (adj >= 0) { 12827 pw.print(' '); 12828 if (adj < 10) pw.print(' '); 12829 } else { 12830 if (adj > -10) pw.print(' '); 12831 } 12832 pw.print(adj); 12833 pw.print(": "); 12834 pw.print(name); 12835 pw.print(" ("); 12836 pw.print(mProcessList.getMemLevel(adj)/1024); 12837 pw.println(" kB)"); 12838 } 12839 12840 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12841 int opti, boolean dumpAll) { 12842 boolean needSep = false; 12843 12844 if (mLruProcesses.size() > 0) { 12845 if (needSep) pw.println(); 12846 needSep = true; 12847 pw.println(" OOM levels:"); 12848 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12849 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12850 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12851 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12852 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12853 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12854 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12855 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12856 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12857 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12858 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12859 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12860 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12861 12862 if (needSep) pw.println(); 12863 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12864 pw.print(" total, non-act at "); 12865 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12866 pw.print(", non-svc at "); 12867 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12868 pw.println("):"); 12869 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12870 needSep = true; 12871 } 12872 12873 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12874 12875 pw.println(); 12876 pw.println(" mHomeProcess: " + mHomeProcess); 12877 pw.println(" mPreviousProcess: " + mPreviousProcess); 12878 if (mHeavyWeightProcess != null) { 12879 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12880 } 12881 12882 return true; 12883 } 12884 12885 /** 12886 * There are three ways to call this: 12887 * - no provider specified: dump all the providers 12888 * - a flattened component name that matched an existing provider was specified as the 12889 * first arg: dump that one provider 12890 * - the first arg isn't the flattened component name of an existing provider: 12891 * dump all providers whose component contains the first arg as a substring 12892 */ 12893 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12894 int opti, boolean dumpAll) { 12895 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12896 } 12897 12898 static class ItemMatcher { 12899 ArrayList<ComponentName> components; 12900 ArrayList<String> strings; 12901 ArrayList<Integer> objects; 12902 boolean all; 12903 12904 ItemMatcher() { 12905 all = true; 12906 } 12907 12908 void build(String name) { 12909 ComponentName componentName = ComponentName.unflattenFromString(name); 12910 if (componentName != null) { 12911 if (components == null) { 12912 components = new ArrayList<ComponentName>(); 12913 } 12914 components.add(componentName); 12915 all = false; 12916 } else { 12917 int objectId = 0; 12918 // Not a '/' separated full component name; maybe an object ID? 12919 try { 12920 objectId = Integer.parseInt(name, 16); 12921 if (objects == null) { 12922 objects = new ArrayList<Integer>(); 12923 } 12924 objects.add(objectId); 12925 all = false; 12926 } catch (RuntimeException e) { 12927 // Not an integer; just do string match. 12928 if (strings == null) { 12929 strings = new ArrayList<String>(); 12930 } 12931 strings.add(name); 12932 all = false; 12933 } 12934 } 12935 } 12936 12937 int build(String[] args, int opti) { 12938 for (; opti<args.length; opti++) { 12939 String name = args[opti]; 12940 if ("--".equals(name)) { 12941 return opti+1; 12942 } 12943 build(name); 12944 } 12945 return opti; 12946 } 12947 12948 boolean match(Object object, ComponentName comp) { 12949 if (all) { 12950 return true; 12951 } 12952 if (components != null) { 12953 for (int i=0; i<components.size(); i++) { 12954 if (components.get(i).equals(comp)) { 12955 return true; 12956 } 12957 } 12958 } 12959 if (objects != null) { 12960 for (int i=0; i<objects.size(); i++) { 12961 if (System.identityHashCode(object) == objects.get(i)) { 12962 return true; 12963 } 12964 } 12965 } 12966 if (strings != null) { 12967 String flat = comp.flattenToString(); 12968 for (int i=0; i<strings.size(); i++) { 12969 if (flat.contains(strings.get(i))) { 12970 return true; 12971 } 12972 } 12973 } 12974 return false; 12975 } 12976 } 12977 12978 /** 12979 * There are three things that cmd can be: 12980 * - a flattened component name that matches an existing activity 12981 * - the cmd arg isn't the flattened component name of an existing activity: 12982 * dump all activity whose component contains the cmd as a substring 12983 * - A hex number of the ActivityRecord object instance. 12984 */ 12985 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12986 int opti, boolean dumpAll) { 12987 ArrayList<ActivityRecord> activities; 12988 12989 synchronized (this) { 12990 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12991 } 12992 12993 if (activities.size() <= 0) { 12994 return false; 12995 } 12996 12997 String[] newArgs = new String[args.length - opti]; 12998 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12999 13000 TaskRecord lastTask = null; 13001 boolean needSep = false; 13002 for (int i=activities.size()-1; i>=0; i--) { 13003 ActivityRecord r = activities.get(i); 13004 if (needSep) { 13005 pw.println(); 13006 } 13007 needSep = true; 13008 synchronized (this) { 13009 if (lastTask != r.task) { 13010 lastTask = r.task; 13011 pw.print("TASK "); pw.print(lastTask.affinity); 13012 pw.print(" id="); pw.println(lastTask.taskId); 13013 if (dumpAll) { 13014 lastTask.dump(pw, " "); 13015 } 13016 } 13017 } 13018 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 13019 } 13020 return true; 13021 } 13022 13023 /** 13024 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 13025 * there is a thread associated with the activity. 13026 */ 13027 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 13028 final ActivityRecord r, String[] args, boolean dumpAll) { 13029 String innerPrefix = prefix + " "; 13030 synchronized (this) { 13031 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 13032 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 13033 pw.print(" pid="); 13034 if (r.app != null) pw.println(r.app.pid); 13035 else pw.println("(not running)"); 13036 if (dumpAll) { 13037 r.dump(pw, innerPrefix); 13038 } 13039 } 13040 if (r.app != null && r.app.thread != null) { 13041 // flush anything that is already in the PrintWriter since the thread is going 13042 // to write to the file descriptor directly 13043 pw.flush(); 13044 try { 13045 TransferPipe tp = new TransferPipe(); 13046 try { 13047 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13048 r.appToken, innerPrefix, args); 13049 tp.go(fd); 13050 } finally { 13051 tp.kill(); 13052 } 13053 } catch (IOException e) { 13054 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13055 } catch (RemoteException e) { 13056 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13057 } 13058 } 13059 } 13060 13061 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13062 int opti, boolean dumpAll, String dumpPackage) { 13063 boolean needSep = false; 13064 boolean onlyHistory = false; 13065 boolean printedAnything = false; 13066 13067 if ("history".equals(dumpPackage)) { 13068 if (opti < args.length && "-s".equals(args[opti])) { 13069 dumpAll = false; 13070 } 13071 onlyHistory = true; 13072 dumpPackage = null; 13073 } 13074 13075 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13076 if (!onlyHistory && dumpAll) { 13077 if (mRegisteredReceivers.size() > 0) { 13078 boolean printed = false; 13079 Iterator it = mRegisteredReceivers.values().iterator(); 13080 while (it.hasNext()) { 13081 ReceiverList r = (ReceiverList)it.next(); 13082 if (dumpPackage != null && (r.app == null || 13083 !dumpPackage.equals(r.app.info.packageName))) { 13084 continue; 13085 } 13086 if (!printed) { 13087 pw.println(" Registered Receivers:"); 13088 needSep = true; 13089 printed = true; 13090 printedAnything = true; 13091 } 13092 pw.print(" * "); pw.println(r); 13093 r.dump(pw, " "); 13094 } 13095 } 13096 13097 if (mReceiverResolver.dump(pw, needSep ? 13098 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13099 " ", dumpPackage, false)) { 13100 needSep = true; 13101 printedAnything = true; 13102 } 13103 } 13104 13105 for (BroadcastQueue q : mBroadcastQueues) { 13106 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13107 printedAnything |= needSep; 13108 } 13109 13110 needSep = true; 13111 13112 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13113 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13114 if (needSep) { 13115 pw.println(); 13116 } 13117 needSep = true; 13118 printedAnything = true; 13119 pw.print(" Sticky broadcasts for user "); 13120 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13121 StringBuilder sb = new StringBuilder(128); 13122 for (Map.Entry<String, ArrayList<Intent>> ent 13123 : mStickyBroadcasts.valueAt(user).entrySet()) { 13124 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13125 if (dumpAll) { 13126 pw.println(":"); 13127 ArrayList<Intent> intents = ent.getValue(); 13128 final int N = intents.size(); 13129 for (int i=0; i<N; i++) { 13130 sb.setLength(0); 13131 sb.append(" Intent: "); 13132 intents.get(i).toShortString(sb, false, true, false, false); 13133 pw.println(sb.toString()); 13134 Bundle bundle = intents.get(i).getExtras(); 13135 if (bundle != null) { 13136 pw.print(" "); 13137 pw.println(bundle.toString()); 13138 } 13139 } 13140 } else { 13141 pw.println(""); 13142 } 13143 } 13144 } 13145 } 13146 13147 if (!onlyHistory && dumpAll) { 13148 pw.println(); 13149 for (BroadcastQueue queue : mBroadcastQueues) { 13150 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13151 + queue.mBroadcastsScheduled); 13152 } 13153 pw.println(" mHandler:"); 13154 mHandler.dump(new PrintWriterPrinter(pw), " "); 13155 needSep = true; 13156 printedAnything = true; 13157 } 13158 13159 if (!printedAnything) { 13160 pw.println(" (nothing)"); 13161 } 13162 } 13163 13164 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13165 int opti, boolean dumpAll, String dumpPackage) { 13166 boolean needSep; 13167 boolean printedAnything = false; 13168 13169 ItemMatcher matcher = new ItemMatcher(); 13170 matcher.build(args, opti); 13171 13172 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13173 13174 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13175 printedAnything |= needSep; 13176 13177 if (mLaunchingProviders.size() > 0) { 13178 boolean printed = false; 13179 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13180 ContentProviderRecord r = mLaunchingProviders.get(i); 13181 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13182 continue; 13183 } 13184 if (!printed) { 13185 if (needSep) pw.println(); 13186 needSep = true; 13187 pw.println(" Launching content providers:"); 13188 printed = true; 13189 printedAnything = true; 13190 } 13191 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13192 pw.println(r); 13193 } 13194 } 13195 13196 if (mGrantedUriPermissions.size() > 0) { 13197 boolean printed = false; 13198 int dumpUid = -2; 13199 if (dumpPackage != null) { 13200 try { 13201 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13202 } catch (NameNotFoundException e) { 13203 dumpUid = -1; 13204 } 13205 } 13206 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13207 int uid = mGrantedUriPermissions.keyAt(i); 13208 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13209 continue; 13210 } 13211 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13212 if (!printed) { 13213 if (needSep) pw.println(); 13214 needSep = true; 13215 pw.println(" Granted Uri Permissions:"); 13216 printed = true; 13217 printedAnything = true; 13218 } 13219 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13220 for (UriPermission perm : perms.values()) { 13221 pw.print(" "); pw.println(perm); 13222 if (dumpAll) { 13223 perm.dump(pw, " "); 13224 } 13225 } 13226 } 13227 } 13228 13229 if (!printedAnything) { 13230 pw.println(" (nothing)"); 13231 } 13232 } 13233 13234 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13235 int opti, boolean dumpAll, String dumpPackage) { 13236 boolean printed = false; 13237 13238 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13239 13240 if (mIntentSenderRecords.size() > 0) { 13241 Iterator<WeakReference<PendingIntentRecord>> it 13242 = mIntentSenderRecords.values().iterator(); 13243 while (it.hasNext()) { 13244 WeakReference<PendingIntentRecord> ref = it.next(); 13245 PendingIntentRecord rec = ref != null ? ref.get(): null; 13246 if (dumpPackage != null && (rec == null 13247 || !dumpPackage.equals(rec.key.packageName))) { 13248 continue; 13249 } 13250 printed = true; 13251 if (rec != null) { 13252 pw.print(" * "); pw.println(rec); 13253 if (dumpAll) { 13254 rec.dump(pw, " "); 13255 } 13256 } else { 13257 pw.print(" * "); pw.println(ref); 13258 } 13259 } 13260 } 13261 13262 if (!printed) { 13263 pw.println(" (nothing)"); 13264 } 13265 } 13266 13267 private static final int dumpProcessList(PrintWriter pw, 13268 ActivityManagerService service, List list, 13269 String prefix, String normalLabel, String persistentLabel, 13270 String dumpPackage) { 13271 int numPers = 0; 13272 final int N = list.size()-1; 13273 for (int i=N; i>=0; i--) { 13274 ProcessRecord r = (ProcessRecord)list.get(i); 13275 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13276 continue; 13277 } 13278 pw.println(String.format("%s%s #%2d: %s", 13279 prefix, (r.persistent ? persistentLabel : normalLabel), 13280 i, r.toString())); 13281 if (r.persistent) { 13282 numPers++; 13283 } 13284 } 13285 return numPers; 13286 } 13287 13288 private static final boolean dumpProcessOomList(PrintWriter pw, 13289 ActivityManagerService service, List<ProcessRecord> origList, 13290 String prefix, String normalLabel, String persistentLabel, 13291 boolean inclDetails, String dumpPackage) { 13292 13293 ArrayList<Pair<ProcessRecord, Integer>> list 13294 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13295 for (int i=0; i<origList.size(); i++) { 13296 ProcessRecord r = origList.get(i); 13297 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13298 continue; 13299 } 13300 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13301 } 13302 13303 if (list.size() <= 0) { 13304 return false; 13305 } 13306 13307 Comparator<Pair<ProcessRecord, Integer>> comparator 13308 = new Comparator<Pair<ProcessRecord, Integer>>() { 13309 @Override 13310 public int compare(Pair<ProcessRecord, Integer> object1, 13311 Pair<ProcessRecord, Integer> object2) { 13312 if (object1.first.setAdj != object2.first.setAdj) { 13313 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13314 } 13315 if (object1.second.intValue() != object2.second.intValue()) { 13316 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13317 } 13318 return 0; 13319 } 13320 }; 13321 13322 Collections.sort(list, comparator); 13323 13324 final long curRealtime = SystemClock.elapsedRealtime(); 13325 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13326 final long curUptime = SystemClock.uptimeMillis(); 13327 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13328 13329 for (int i=list.size()-1; i>=0; i--) { 13330 ProcessRecord r = list.get(i).first; 13331 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13332 char schedGroup; 13333 switch (r.setSchedGroup) { 13334 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13335 schedGroup = 'B'; 13336 break; 13337 case Process.THREAD_GROUP_DEFAULT: 13338 schedGroup = 'F'; 13339 break; 13340 default: 13341 schedGroup = '?'; 13342 break; 13343 } 13344 char foreground; 13345 if (r.foregroundActivities) { 13346 foreground = 'A'; 13347 } else if (r.foregroundServices) { 13348 foreground = 'S'; 13349 } else { 13350 foreground = ' '; 13351 } 13352 String procState = ProcessList.makeProcStateString(r.curProcState); 13353 pw.print(prefix); 13354 pw.print(r.persistent ? persistentLabel : normalLabel); 13355 pw.print(" #"); 13356 int num = (origList.size()-1)-list.get(i).second; 13357 if (num < 10) pw.print(' '); 13358 pw.print(num); 13359 pw.print(": "); 13360 pw.print(oomAdj); 13361 pw.print(' '); 13362 pw.print(schedGroup); 13363 pw.print('/'); 13364 pw.print(foreground); 13365 pw.print('/'); 13366 pw.print(procState); 13367 pw.print(" trm:"); 13368 if (r.trimMemoryLevel < 10) pw.print(' '); 13369 pw.print(r.trimMemoryLevel); 13370 pw.print(' '); 13371 pw.print(r.toShortString()); 13372 pw.print(" ("); 13373 pw.print(r.adjType); 13374 pw.println(')'); 13375 if (r.adjSource != null || r.adjTarget != null) { 13376 pw.print(prefix); 13377 pw.print(" "); 13378 if (r.adjTarget instanceof ComponentName) { 13379 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13380 } else if (r.adjTarget != null) { 13381 pw.print(r.adjTarget.toString()); 13382 } else { 13383 pw.print("{null}"); 13384 } 13385 pw.print("<="); 13386 if (r.adjSource instanceof ProcessRecord) { 13387 pw.print("Proc{"); 13388 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13389 pw.println("}"); 13390 } else if (r.adjSource != null) { 13391 pw.println(r.adjSource.toString()); 13392 } else { 13393 pw.println("{null}"); 13394 } 13395 } 13396 if (inclDetails) { 13397 pw.print(prefix); 13398 pw.print(" "); 13399 pw.print("oom: max="); pw.print(r.maxAdj); 13400 pw.print(" curRaw="); pw.print(r.curRawAdj); 13401 pw.print(" setRaw="); pw.print(r.setRawAdj); 13402 pw.print(" cur="); pw.print(r.curAdj); 13403 pw.print(" set="); pw.println(r.setAdj); 13404 pw.print(prefix); 13405 pw.print(" "); 13406 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13407 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13408 pw.print(" lastPss="); pw.print(r.lastPss); 13409 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13410 pw.print(prefix); 13411 pw.print(" "); 13412 pw.print("cached="); pw.print(r.cached); 13413 pw.print(" empty="); pw.print(r.empty); 13414 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13415 13416 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13417 if (r.lastWakeTime != 0) { 13418 long wtime; 13419 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13420 synchronized (stats) { 13421 wtime = stats.getProcessWakeTime(r.info.uid, 13422 r.pid, curRealtime); 13423 } 13424 long timeUsed = wtime - r.lastWakeTime; 13425 pw.print(prefix); 13426 pw.print(" "); 13427 pw.print("keep awake over "); 13428 TimeUtils.formatDuration(realtimeSince, pw); 13429 pw.print(" used "); 13430 TimeUtils.formatDuration(timeUsed, pw); 13431 pw.print(" ("); 13432 pw.print((timeUsed*100)/realtimeSince); 13433 pw.println("%)"); 13434 } 13435 if (r.lastCpuTime != 0) { 13436 long timeUsed = r.curCpuTime - r.lastCpuTime; 13437 pw.print(prefix); 13438 pw.print(" "); 13439 pw.print("run cpu over "); 13440 TimeUtils.formatDuration(uptimeSince, pw); 13441 pw.print(" used "); 13442 TimeUtils.formatDuration(timeUsed, pw); 13443 pw.print(" ("); 13444 pw.print((timeUsed*100)/uptimeSince); 13445 pw.println("%)"); 13446 } 13447 } 13448 } 13449 } 13450 return true; 13451 } 13452 13453 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13454 ArrayList<ProcessRecord> procs; 13455 synchronized (this) { 13456 if (args != null && args.length > start 13457 && args[start].charAt(0) != '-') { 13458 procs = new ArrayList<ProcessRecord>(); 13459 int pid = -1; 13460 try { 13461 pid = Integer.parseInt(args[start]); 13462 } catch (NumberFormatException e) { 13463 } 13464 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13465 ProcessRecord proc = mLruProcesses.get(i); 13466 if (proc.pid == pid) { 13467 procs.add(proc); 13468 } else if (proc.processName.equals(args[start])) { 13469 procs.add(proc); 13470 } 13471 } 13472 if (procs.size() <= 0) { 13473 return null; 13474 } 13475 } else { 13476 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13477 } 13478 } 13479 return procs; 13480 } 13481 13482 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13483 PrintWriter pw, String[] args) { 13484 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13485 if (procs == null) { 13486 pw.println("No process found for: " + args[0]); 13487 return; 13488 } 13489 13490 long uptime = SystemClock.uptimeMillis(); 13491 long realtime = SystemClock.elapsedRealtime(); 13492 pw.println("Applications Graphics Acceleration Info:"); 13493 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13494 13495 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13496 ProcessRecord r = procs.get(i); 13497 if (r.thread != null) { 13498 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13499 pw.flush(); 13500 try { 13501 TransferPipe tp = new TransferPipe(); 13502 try { 13503 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13504 tp.go(fd); 13505 } finally { 13506 tp.kill(); 13507 } 13508 } catch (IOException e) { 13509 pw.println("Failure while dumping the app: " + r); 13510 pw.flush(); 13511 } catch (RemoteException e) { 13512 pw.println("Got a RemoteException while dumping the app " + r); 13513 pw.flush(); 13514 } 13515 } 13516 } 13517 } 13518 13519 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13520 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13521 if (procs == null) { 13522 pw.println("No process found for: " + args[0]); 13523 return; 13524 } 13525 13526 pw.println("Applications Database Info:"); 13527 13528 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13529 ProcessRecord r = procs.get(i); 13530 if (r.thread != null) { 13531 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13532 pw.flush(); 13533 try { 13534 TransferPipe tp = new TransferPipe(); 13535 try { 13536 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13537 tp.go(fd); 13538 } finally { 13539 tp.kill(); 13540 } 13541 } catch (IOException e) { 13542 pw.println("Failure while dumping the app: " + r); 13543 pw.flush(); 13544 } catch (RemoteException e) { 13545 pw.println("Got a RemoteException while dumping the app " + r); 13546 pw.flush(); 13547 } 13548 } 13549 } 13550 } 13551 13552 final static class MemItem { 13553 final boolean isProc; 13554 final String label; 13555 final String shortLabel; 13556 final long pss; 13557 final int id; 13558 final boolean hasActivities; 13559 ArrayList<MemItem> subitems; 13560 13561 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13562 boolean _hasActivities) { 13563 isProc = true; 13564 label = _label; 13565 shortLabel = _shortLabel; 13566 pss = _pss; 13567 id = _id; 13568 hasActivities = _hasActivities; 13569 } 13570 13571 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13572 isProc = false; 13573 label = _label; 13574 shortLabel = _shortLabel; 13575 pss = _pss; 13576 id = _id; 13577 hasActivities = false; 13578 } 13579 } 13580 13581 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13582 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13583 if (sort && !isCompact) { 13584 Collections.sort(items, new Comparator<MemItem>() { 13585 @Override 13586 public int compare(MemItem lhs, MemItem rhs) { 13587 if (lhs.pss < rhs.pss) { 13588 return 1; 13589 } else if (lhs.pss > rhs.pss) { 13590 return -1; 13591 } 13592 return 0; 13593 } 13594 }); 13595 } 13596 13597 for (int i=0; i<items.size(); i++) { 13598 MemItem mi = items.get(i); 13599 if (!isCompact) { 13600 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13601 } else if (mi.isProc) { 13602 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13603 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13604 pw.println(mi.hasActivities ? ",a" : ",e"); 13605 } else { 13606 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13607 pw.println(mi.pss); 13608 } 13609 if (mi.subitems != null) { 13610 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13611 true, isCompact); 13612 } 13613 } 13614 } 13615 13616 // These are in KB. 13617 static final long[] DUMP_MEM_BUCKETS = new long[] { 13618 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13619 120*1024, 160*1024, 200*1024, 13620 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13621 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13622 }; 13623 13624 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13625 boolean stackLike) { 13626 int start = label.lastIndexOf('.'); 13627 if (start >= 0) start++; 13628 else start = 0; 13629 int end = label.length(); 13630 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13631 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13632 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13633 out.append(bucket); 13634 out.append(stackLike ? "MB." : "MB "); 13635 out.append(label, start, end); 13636 return; 13637 } 13638 } 13639 out.append(memKB/1024); 13640 out.append(stackLike ? "MB." : "MB "); 13641 out.append(label, start, end); 13642 } 13643 13644 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13645 ProcessList.NATIVE_ADJ, 13646 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13647 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13648 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13649 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13650 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13651 }; 13652 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13653 "Native", 13654 "System", "Persistent", "Foreground", 13655 "Visible", "Perceptible", 13656 "Heavy Weight", "Backup", 13657 "A Services", "Home", 13658 "Previous", "B Services", "Cached" 13659 }; 13660 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13661 "native", 13662 "sys", "pers", "fore", 13663 "vis", "percept", 13664 "heavy", "backup", 13665 "servicea", "home", 13666 "prev", "serviceb", "cached" 13667 }; 13668 13669 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13670 long realtime, boolean isCheckinRequest, boolean isCompact) { 13671 if (isCheckinRequest || isCompact) { 13672 // short checkin version 13673 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13674 } else { 13675 pw.println("Applications Memory Usage (kB):"); 13676 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13677 } 13678 } 13679 13680 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13681 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13682 boolean dumpDetails = false; 13683 boolean dumpFullDetails = false; 13684 boolean dumpDalvik = false; 13685 boolean oomOnly = false; 13686 boolean isCompact = false; 13687 boolean localOnly = false; 13688 13689 int opti = 0; 13690 while (opti < args.length) { 13691 String opt = args[opti]; 13692 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13693 break; 13694 } 13695 opti++; 13696 if ("-a".equals(opt)) { 13697 dumpDetails = true; 13698 dumpFullDetails = true; 13699 dumpDalvik = true; 13700 } else if ("-d".equals(opt)) { 13701 dumpDalvik = true; 13702 } else if ("-c".equals(opt)) { 13703 isCompact = true; 13704 } else if ("--oom".equals(opt)) { 13705 oomOnly = true; 13706 } else if ("--local".equals(opt)) { 13707 localOnly = true; 13708 } else if ("-h".equals(opt)) { 13709 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13710 pw.println(" -a: include all available information for each process."); 13711 pw.println(" -d: include dalvik details when dumping process details."); 13712 pw.println(" -c: dump in a compact machine-parseable representation."); 13713 pw.println(" --oom: only show processes organized by oom adj."); 13714 pw.println(" --local: only collect details locally, don't call process."); 13715 pw.println("If [process] is specified it can be the name or "); 13716 pw.println("pid of a specific process to dump."); 13717 return; 13718 } else { 13719 pw.println("Unknown argument: " + opt + "; use -h for help"); 13720 } 13721 } 13722 13723 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13724 long uptime = SystemClock.uptimeMillis(); 13725 long realtime = SystemClock.elapsedRealtime(); 13726 final long[] tmpLong = new long[1]; 13727 13728 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13729 if (procs == null) { 13730 // No Java processes. Maybe they want to print a native process. 13731 if (args != null && args.length > opti 13732 && args[opti].charAt(0) != '-') { 13733 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13734 = new ArrayList<ProcessCpuTracker.Stats>(); 13735 updateCpuStatsNow(); 13736 int findPid = -1; 13737 try { 13738 findPid = Integer.parseInt(args[opti]); 13739 } catch (NumberFormatException e) { 13740 } 13741 synchronized (mProcessCpuThread) { 13742 final int N = mProcessCpuTracker.countStats(); 13743 for (int i=0; i<N; i++) { 13744 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13745 if (st.pid == findPid || (st.baseName != null 13746 && st.baseName.equals(args[opti]))) { 13747 nativeProcs.add(st); 13748 } 13749 } 13750 } 13751 if (nativeProcs.size() > 0) { 13752 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13753 isCompact); 13754 Debug.MemoryInfo mi = null; 13755 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13756 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13757 final int pid = r.pid; 13758 if (!isCheckinRequest && dumpDetails) { 13759 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13760 } 13761 if (mi == null) { 13762 mi = new Debug.MemoryInfo(); 13763 } 13764 if (dumpDetails || (!brief && !oomOnly)) { 13765 Debug.getMemoryInfo(pid, mi); 13766 } else { 13767 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13768 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13769 } 13770 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13771 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13772 if (isCheckinRequest) { 13773 pw.println(); 13774 } 13775 } 13776 return; 13777 } 13778 } 13779 pw.println("No process found for: " + args[opti]); 13780 return; 13781 } 13782 13783 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13784 dumpDetails = true; 13785 } 13786 13787 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13788 13789 String[] innerArgs = new String[args.length-opti]; 13790 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13791 13792 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13793 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13794 long nativePss=0, dalvikPss=0, otherPss=0; 13795 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13796 13797 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13798 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13799 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13800 13801 long totalPss = 0; 13802 long cachedPss = 0; 13803 13804 Debug.MemoryInfo mi = null; 13805 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13806 final ProcessRecord r = procs.get(i); 13807 final IApplicationThread thread; 13808 final int pid; 13809 final int oomAdj; 13810 final boolean hasActivities; 13811 synchronized (this) { 13812 thread = r.thread; 13813 pid = r.pid; 13814 oomAdj = r.getSetAdjWithServices(); 13815 hasActivities = r.activities.size() > 0; 13816 } 13817 if (thread != null) { 13818 if (!isCheckinRequest && dumpDetails) { 13819 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13820 } 13821 if (mi == null) { 13822 mi = new Debug.MemoryInfo(); 13823 } 13824 if (dumpDetails || (!brief && !oomOnly)) { 13825 Debug.getMemoryInfo(pid, mi); 13826 } else { 13827 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13828 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13829 } 13830 if (dumpDetails) { 13831 if (localOnly) { 13832 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13833 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13834 if (isCheckinRequest) { 13835 pw.println(); 13836 } 13837 } else { 13838 try { 13839 pw.flush(); 13840 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13841 dumpDalvik, innerArgs); 13842 } catch (RemoteException e) { 13843 if (!isCheckinRequest) { 13844 pw.println("Got RemoteException!"); 13845 pw.flush(); 13846 } 13847 } 13848 } 13849 } 13850 13851 final long myTotalPss = mi.getTotalPss(); 13852 final long myTotalUss = mi.getTotalUss(); 13853 13854 synchronized (this) { 13855 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13856 // Record this for posterity if the process has been stable. 13857 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13858 } 13859 } 13860 13861 if (!isCheckinRequest && mi != null) { 13862 totalPss += myTotalPss; 13863 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13864 (hasActivities ? " / activities)" : ")"), 13865 r.processName, myTotalPss, pid, hasActivities); 13866 procMems.add(pssItem); 13867 procMemsMap.put(pid, pssItem); 13868 13869 nativePss += mi.nativePss; 13870 dalvikPss += mi.dalvikPss; 13871 otherPss += mi.otherPss; 13872 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13873 long mem = mi.getOtherPss(j); 13874 miscPss[j] += mem; 13875 otherPss -= mem; 13876 } 13877 13878 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13879 cachedPss += myTotalPss; 13880 } 13881 13882 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13883 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13884 || oomIndex == (oomPss.length-1)) { 13885 oomPss[oomIndex] += myTotalPss; 13886 if (oomProcs[oomIndex] == null) { 13887 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13888 } 13889 oomProcs[oomIndex].add(pssItem); 13890 break; 13891 } 13892 } 13893 } 13894 } 13895 } 13896 13897 long nativeProcTotalPss = 0; 13898 13899 if (!isCheckinRequest && procs.size() > 1) { 13900 // If we are showing aggregations, also look for native processes to 13901 // include so that our aggregations are more accurate. 13902 updateCpuStatsNow(); 13903 synchronized (mProcessCpuThread) { 13904 final int N = mProcessCpuTracker.countStats(); 13905 for (int i=0; i<N; i++) { 13906 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13907 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13908 if (mi == null) { 13909 mi = new Debug.MemoryInfo(); 13910 } 13911 if (!brief && !oomOnly) { 13912 Debug.getMemoryInfo(st.pid, mi); 13913 } else { 13914 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13915 mi.nativePrivateDirty = (int)tmpLong[0]; 13916 } 13917 13918 final long myTotalPss = mi.getTotalPss(); 13919 totalPss += myTotalPss; 13920 nativeProcTotalPss += myTotalPss; 13921 13922 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13923 st.name, myTotalPss, st.pid, false); 13924 procMems.add(pssItem); 13925 13926 nativePss += mi.nativePss; 13927 dalvikPss += mi.dalvikPss; 13928 otherPss += mi.otherPss; 13929 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13930 long mem = mi.getOtherPss(j); 13931 miscPss[j] += mem; 13932 otherPss -= mem; 13933 } 13934 oomPss[0] += myTotalPss; 13935 if (oomProcs[0] == null) { 13936 oomProcs[0] = new ArrayList<MemItem>(); 13937 } 13938 oomProcs[0].add(pssItem); 13939 } 13940 } 13941 } 13942 13943 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13944 13945 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13946 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13947 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13948 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13949 String label = Debug.MemoryInfo.getOtherLabel(j); 13950 catMems.add(new MemItem(label, label, miscPss[j], j)); 13951 } 13952 13953 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13954 for (int j=0; j<oomPss.length; j++) { 13955 if (oomPss[j] != 0) { 13956 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13957 : DUMP_MEM_OOM_LABEL[j]; 13958 MemItem item = new MemItem(label, label, oomPss[j], 13959 DUMP_MEM_OOM_ADJ[j]); 13960 item.subitems = oomProcs[j]; 13961 oomMems.add(item); 13962 } 13963 } 13964 13965 if (!brief && !oomOnly && !isCompact) { 13966 pw.println(); 13967 pw.println("Total PSS by process:"); 13968 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13969 pw.println(); 13970 } 13971 if (!isCompact) { 13972 pw.println("Total PSS by OOM adjustment:"); 13973 } 13974 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13975 if (!brief && !oomOnly) { 13976 PrintWriter out = categoryPw != null ? categoryPw : pw; 13977 if (!isCompact) { 13978 out.println(); 13979 out.println("Total PSS by category:"); 13980 } 13981 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13982 } 13983 if (!isCompact) { 13984 pw.println(); 13985 } 13986 MemInfoReader memInfo = new MemInfoReader(); 13987 memInfo.readMemInfo(); 13988 if (nativeProcTotalPss > 0) { 13989 synchronized (this) { 13990 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13991 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13992 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13993 nativeProcTotalPss); 13994 } 13995 } 13996 if (!brief) { 13997 if (!isCompact) { 13998 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13999 pw.print(" kB (status "); 14000 switch (mLastMemoryLevel) { 14001 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 14002 pw.println("normal)"); 14003 break; 14004 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 14005 pw.println("moderate)"); 14006 break; 14007 case ProcessStats.ADJ_MEM_FACTOR_LOW: 14008 pw.println("low)"); 14009 break; 14010 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 14011 pw.println("critical)"); 14012 break; 14013 default: 14014 pw.print(mLastMemoryLevel); 14015 pw.println(")"); 14016 break; 14017 } 14018 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 14019 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 14020 pw.print(cachedPss); pw.print(" cached pss + "); 14021 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 14022 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 14023 } else { 14024 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 14025 pw.print(cachedPss + memInfo.getCachedSizeKb() 14026 + memInfo.getFreeSizeKb()); pw.print(","); 14027 pw.println(totalPss - cachedPss); 14028 } 14029 } 14030 if (!isCompact) { 14031 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 14032 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 14033 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 14034 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 14035 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 14036 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 14037 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 14038 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 14039 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 14040 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 14041 - memInfo.getSlabSizeKb()); pw.println(" kB"); 14042 } 14043 if (!brief) { 14044 if (memInfo.getZramTotalSizeKb() != 0) { 14045 if (!isCompact) { 14046 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14047 pw.print(" kB physical used for "); 14048 pw.print(memInfo.getSwapTotalSizeKb() 14049 - memInfo.getSwapFreeSizeKb()); 14050 pw.print(" kB in swap ("); 14051 pw.print(memInfo.getSwapTotalSizeKb()); 14052 pw.println(" kB total swap)"); 14053 } else { 14054 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14055 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14056 pw.println(memInfo.getSwapFreeSizeKb()); 14057 } 14058 } 14059 final int[] SINGLE_LONG_FORMAT = new int[] { 14060 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14061 }; 14062 long[] longOut = new long[1]; 14063 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14064 SINGLE_LONG_FORMAT, null, longOut, null); 14065 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14066 longOut[0] = 0; 14067 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14068 SINGLE_LONG_FORMAT, null, longOut, null); 14069 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14070 longOut[0] = 0; 14071 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14072 SINGLE_LONG_FORMAT, null, longOut, null); 14073 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14074 longOut[0] = 0; 14075 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14076 SINGLE_LONG_FORMAT, null, longOut, null); 14077 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14078 if (!isCompact) { 14079 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14080 pw.print(" KSM: "); pw.print(sharing); 14081 pw.print(" kB saved from shared "); 14082 pw.print(shared); pw.println(" kB"); 14083 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14084 pw.print(voltile); pw.println(" kB volatile"); 14085 } 14086 pw.print(" Tuning: "); 14087 pw.print(ActivityManager.staticGetMemoryClass()); 14088 pw.print(" (large "); 14089 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14090 pw.print("), oom "); 14091 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14092 pw.print(" kB"); 14093 pw.print(", restore limit "); 14094 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14095 pw.print(" kB"); 14096 if (ActivityManager.isLowRamDeviceStatic()) { 14097 pw.print(" (low-ram)"); 14098 } 14099 if (ActivityManager.isHighEndGfx()) { 14100 pw.print(" (high-end-gfx)"); 14101 } 14102 pw.println(); 14103 } else { 14104 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14105 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14106 pw.println(voltile); 14107 pw.print("tuning,"); 14108 pw.print(ActivityManager.staticGetMemoryClass()); 14109 pw.print(','); 14110 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14111 pw.print(','); 14112 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14113 if (ActivityManager.isLowRamDeviceStatic()) { 14114 pw.print(",low-ram"); 14115 } 14116 if (ActivityManager.isHighEndGfx()) { 14117 pw.print(",high-end-gfx"); 14118 } 14119 pw.println(); 14120 } 14121 } 14122 } 14123 } 14124 14125 /** 14126 * Searches array of arguments for the specified string 14127 * @param args array of argument strings 14128 * @param value value to search for 14129 * @return true if the value is contained in the array 14130 */ 14131 private static boolean scanArgs(String[] args, String value) { 14132 if (args != null) { 14133 for (String arg : args) { 14134 if (value.equals(arg)) { 14135 return true; 14136 } 14137 } 14138 } 14139 return false; 14140 } 14141 14142 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14143 ContentProviderRecord cpr, boolean always) { 14144 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14145 14146 if (!inLaunching || always) { 14147 synchronized (cpr) { 14148 cpr.launchingApp = null; 14149 cpr.notifyAll(); 14150 } 14151 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14152 String names[] = cpr.info.authority.split(";"); 14153 for (int j = 0; j < names.length; j++) { 14154 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14155 } 14156 } 14157 14158 for (int i=0; i<cpr.connections.size(); i++) { 14159 ContentProviderConnection conn = cpr.connections.get(i); 14160 if (conn.waiting) { 14161 // If this connection is waiting for the provider, then we don't 14162 // need to mess with its process unless we are always removing 14163 // or for some reason the provider is not currently launching. 14164 if (inLaunching && !always) { 14165 continue; 14166 } 14167 } 14168 ProcessRecord capp = conn.client; 14169 conn.dead = true; 14170 if (conn.stableCount > 0) { 14171 if (!capp.persistent && capp.thread != null 14172 && capp.pid != 0 14173 && capp.pid != MY_PID) { 14174 capp.kill("depends on provider " 14175 + cpr.name.flattenToShortString() 14176 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14177 } 14178 } else if (capp.thread != null && conn.provider.provider != null) { 14179 try { 14180 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14181 } catch (RemoteException e) { 14182 } 14183 // In the protocol here, we don't expect the client to correctly 14184 // clean up this connection, we'll just remove it. 14185 cpr.connections.remove(i); 14186 conn.client.conProviders.remove(conn); 14187 } 14188 } 14189 14190 if (inLaunching && always) { 14191 mLaunchingProviders.remove(cpr); 14192 } 14193 return inLaunching; 14194 } 14195 14196 /** 14197 * Main code for cleaning up a process when it has gone away. This is 14198 * called both as a result of the process dying, or directly when stopping 14199 * a process when running in single process mode. 14200 */ 14201 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14202 boolean restarting, boolean allowRestart, int index) { 14203 if (index >= 0) { 14204 removeLruProcessLocked(app); 14205 ProcessList.remove(app.pid); 14206 } 14207 14208 mProcessesToGc.remove(app); 14209 mPendingPssProcesses.remove(app); 14210 14211 // Dismiss any open dialogs. 14212 if (app.crashDialog != null && !app.forceCrashReport) { 14213 app.crashDialog.dismiss(); 14214 app.crashDialog = null; 14215 } 14216 if (app.anrDialog != null) { 14217 app.anrDialog.dismiss(); 14218 app.anrDialog = null; 14219 } 14220 if (app.waitDialog != null) { 14221 app.waitDialog.dismiss(); 14222 app.waitDialog = null; 14223 } 14224 14225 app.crashing = false; 14226 app.notResponding = false; 14227 14228 app.resetPackageList(mProcessStats); 14229 app.unlinkDeathRecipient(); 14230 app.makeInactive(mProcessStats); 14231 app.waitingToKill = null; 14232 app.forcingToForeground = null; 14233 updateProcessForegroundLocked(app, false, false); 14234 app.foregroundActivities = false; 14235 app.hasShownUi = false; 14236 app.treatLikeActivity = false; 14237 app.hasAboveClient = false; 14238 app.hasClientActivities = false; 14239 14240 mServices.killServicesLocked(app, allowRestart); 14241 14242 boolean restart = false; 14243 14244 // Remove published content providers. 14245 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14246 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14247 final boolean always = app.bad || !allowRestart; 14248 if (removeDyingProviderLocked(app, cpr, always) || always) { 14249 // We left the provider in the launching list, need to 14250 // restart it. 14251 restart = true; 14252 } 14253 14254 cpr.provider = null; 14255 cpr.proc = null; 14256 } 14257 app.pubProviders.clear(); 14258 14259 // Take care of any launching providers waiting for this process. 14260 if (checkAppInLaunchingProvidersLocked(app, false)) { 14261 restart = true; 14262 } 14263 14264 // Unregister from connected content providers. 14265 if (!app.conProviders.isEmpty()) { 14266 for (int i=0; i<app.conProviders.size(); i++) { 14267 ContentProviderConnection conn = app.conProviders.get(i); 14268 conn.provider.connections.remove(conn); 14269 } 14270 app.conProviders.clear(); 14271 } 14272 14273 // At this point there may be remaining entries in mLaunchingProviders 14274 // where we were the only one waiting, so they are no longer of use. 14275 // Look for these and clean up if found. 14276 // XXX Commented out for now. Trying to figure out a way to reproduce 14277 // the actual situation to identify what is actually going on. 14278 if (false) { 14279 for (int i=0; i<mLaunchingProviders.size(); i++) { 14280 ContentProviderRecord cpr = (ContentProviderRecord) 14281 mLaunchingProviders.get(i); 14282 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14283 synchronized (cpr) { 14284 cpr.launchingApp = null; 14285 cpr.notifyAll(); 14286 } 14287 } 14288 } 14289 } 14290 14291 skipCurrentReceiverLocked(app); 14292 14293 // Unregister any receivers. 14294 for (int i=app.receivers.size()-1; i>=0; i--) { 14295 removeReceiverLocked(app.receivers.valueAt(i)); 14296 } 14297 app.receivers.clear(); 14298 14299 // If the app is undergoing backup, tell the backup manager about it 14300 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14301 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14302 + mBackupTarget.appInfo + " died during backup"); 14303 try { 14304 IBackupManager bm = IBackupManager.Stub.asInterface( 14305 ServiceManager.getService(Context.BACKUP_SERVICE)); 14306 bm.agentDisconnected(app.info.packageName); 14307 } catch (RemoteException e) { 14308 // can't happen; backup manager is local 14309 } 14310 } 14311 14312 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14313 ProcessChangeItem item = mPendingProcessChanges.get(i); 14314 if (item.pid == app.pid) { 14315 mPendingProcessChanges.remove(i); 14316 mAvailProcessChanges.add(item); 14317 } 14318 } 14319 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14320 14321 // If the caller is restarting this app, then leave it in its 14322 // current lists and let the caller take care of it. 14323 if (restarting) { 14324 return; 14325 } 14326 14327 if (!app.persistent || app.isolated) { 14328 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14329 "Removing non-persistent process during cleanup: " + app); 14330 mProcessNames.remove(app.processName, app.uid); 14331 mIsolatedProcesses.remove(app.uid); 14332 if (mHeavyWeightProcess == app) { 14333 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14334 mHeavyWeightProcess.userId, 0)); 14335 mHeavyWeightProcess = null; 14336 } 14337 } else if (!app.removed) { 14338 // This app is persistent, so we need to keep its record around. 14339 // If it is not already on the pending app list, add it there 14340 // and start a new process for it. 14341 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14342 mPersistentStartingProcesses.add(app); 14343 restart = true; 14344 } 14345 } 14346 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14347 "Clean-up removing on hold: " + app); 14348 mProcessesOnHold.remove(app); 14349 14350 if (app == mHomeProcess) { 14351 mHomeProcess = null; 14352 } 14353 if (app == mPreviousProcess) { 14354 mPreviousProcess = null; 14355 } 14356 14357 if (restart && !app.isolated) { 14358 // We have components that still need to be running in the 14359 // process, so re-launch it. 14360 mProcessNames.put(app.processName, app.uid, app); 14361 startProcessLocked(app, "restart", app.processName); 14362 } else if (app.pid > 0 && app.pid != MY_PID) { 14363 // Goodbye! 14364 boolean removed; 14365 synchronized (mPidsSelfLocked) { 14366 mPidsSelfLocked.remove(app.pid); 14367 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14368 } 14369 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14370 if (app.isolated) { 14371 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14372 } 14373 app.setPid(0); 14374 } 14375 } 14376 14377 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14378 // Look through the content providers we are waiting to have launched, 14379 // and if any run in this process then either schedule a restart of 14380 // the process or kill the client waiting for it if this process has 14381 // gone bad. 14382 int NL = mLaunchingProviders.size(); 14383 boolean restart = false; 14384 for (int i=0; i<NL; i++) { 14385 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14386 if (cpr.launchingApp == app) { 14387 if (!alwaysBad && !app.bad) { 14388 restart = true; 14389 } else { 14390 removeDyingProviderLocked(app, cpr, true); 14391 // cpr should have been removed from mLaunchingProviders 14392 NL = mLaunchingProviders.size(); 14393 i--; 14394 } 14395 } 14396 } 14397 return restart; 14398 } 14399 14400 // ========================================================= 14401 // SERVICES 14402 // ========================================================= 14403 14404 @Override 14405 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14406 int flags) { 14407 enforceNotIsolatedCaller("getServices"); 14408 synchronized (this) { 14409 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14410 } 14411 } 14412 14413 @Override 14414 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14415 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14416 synchronized (this) { 14417 return mServices.getRunningServiceControlPanelLocked(name); 14418 } 14419 } 14420 14421 @Override 14422 public ComponentName startService(IApplicationThread caller, Intent service, 14423 String resolvedType, int userId) { 14424 enforceNotIsolatedCaller("startService"); 14425 // Refuse possible leaked file descriptors 14426 if (service != null && service.hasFileDescriptors() == true) { 14427 throw new IllegalArgumentException("File descriptors passed in Intent"); 14428 } 14429 14430 if (DEBUG_SERVICE) 14431 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14432 synchronized(this) { 14433 final int callingPid = Binder.getCallingPid(); 14434 final int callingUid = Binder.getCallingUid(); 14435 final long origId = Binder.clearCallingIdentity(); 14436 ComponentName res = mServices.startServiceLocked(caller, service, 14437 resolvedType, callingPid, callingUid, userId); 14438 Binder.restoreCallingIdentity(origId); 14439 return res; 14440 } 14441 } 14442 14443 ComponentName startServiceInPackage(int uid, 14444 Intent service, String resolvedType, int userId) { 14445 synchronized(this) { 14446 if (DEBUG_SERVICE) 14447 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14448 final long origId = Binder.clearCallingIdentity(); 14449 ComponentName res = mServices.startServiceLocked(null, service, 14450 resolvedType, -1, uid, userId); 14451 Binder.restoreCallingIdentity(origId); 14452 return res; 14453 } 14454 } 14455 14456 @Override 14457 public int stopService(IApplicationThread caller, Intent service, 14458 String resolvedType, int userId) { 14459 enforceNotIsolatedCaller("stopService"); 14460 // Refuse possible leaked file descriptors 14461 if (service != null && service.hasFileDescriptors() == true) { 14462 throw new IllegalArgumentException("File descriptors passed in Intent"); 14463 } 14464 14465 synchronized(this) { 14466 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14467 } 14468 } 14469 14470 @Override 14471 public IBinder peekService(Intent service, String resolvedType) { 14472 enforceNotIsolatedCaller("peekService"); 14473 // Refuse possible leaked file descriptors 14474 if (service != null && service.hasFileDescriptors() == true) { 14475 throw new IllegalArgumentException("File descriptors passed in Intent"); 14476 } 14477 synchronized(this) { 14478 return mServices.peekServiceLocked(service, resolvedType); 14479 } 14480 } 14481 14482 @Override 14483 public boolean stopServiceToken(ComponentName className, IBinder token, 14484 int startId) { 14485 synchronized(this) { 14486 return mServices.stopServiceTokenLocked(className, token, startId); 14487 } 14488 } 14489 14490 @Override 14491 public void setServiceForeground(ComponentName className, IBinder token, 14492 int id, Notification notification, boolean removeNotification) { 14493 synchronized(this) { 14494 mServices.setServiceForegroundLocked(className, token, id, notification, 14495 removeNotification); 14496 } 14497 } 14498 14499 @Override 14500 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14501 boolean requireFull, String name, String callerPackage) { 14502 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14503 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14504 } 14505 14506 int unsafeConvertIncomingUser(int userId) { 14507 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14508 ? mCurrentUserId : userId; 14509 } 14510 14511 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14512 int allowMode, String name, String callerPackage) { 14513 final int callingUserId = UserHandle.getUserId(callingUid); 14514 if (callingUserId == userId) { 14515 return userId; 14516 } 14517 14518 // Note that we may be accessing mCurrentUserId outside of a lock... 14519 // shouldn't be a big deal, if this is being called outside 14520 // of a locked context there is intrinsically a race with 14521 // the value the caller will receive and someone else changing it. 14522 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14523 // we will switch to the calling user if access to the current user fails. 14524 int targetUserId = unsafeConvertIncomingUser(userId); 14525 14526 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14527 final boolean allow; 14528 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14529 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14530 // If the caller has this permission, they always pass go. And collect $200. 14531 allow = true; 14532 } else if (allowMode == ALLOW_FULL_ONLY) { 14533 // We require full access, sucks to be you. 14534 allow = false; 14535 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14536 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14537 // If the caller does not have either permission, they are always doomed. 14538 allow = false; 14539 } else if (allowMode == ALLOW_NON_FULL) { 14540 // We are blanket allowing non-full access, you lucky caller! 14541 allow = true; 14542 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14543 // We may or may not allow this depending on whether the two users are 14544 // in the same profile. 14545 synchronized (mUserProfileGroupIdsSelfLocked) { 14546 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14547 UserInfo.NO_PROFILE_GROUP_ID); 14548 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14549 UserInfo.NO_PROFILE_GROUP_ID); 14550 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14551 && callingProfile == targetProfile; 14552 } 14553 } else { 14554 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14555 } 14556 if (!allow) { 14557 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14558 // In this case, they would like to just execute as their 14559 // owner user instead of failing. 14560 targetUserId = callingUserId; 14561 } else { 14562 StringBuilder builder = new StringBuilder(128); 14563 builder.append("Permission Denial: "); 14564 builder.append(name); 14565 if (callerPackage != null) { 14566 builder.append(" from "); 14567 builder.append(callerPackage); 14568 } 14569 builder.append(" asks to run as user "); 14570 builder.append(userId); 14571 builder.append(" but is calling from user "); 14572 builder.append(UserHandle.getUserId(callingUid)); 14573 builder.append("; this requires "); 14574 builder.append(INTERACT_ACROSS_USERS_FULL); 14575 if (allowMode != ALLOW_FULL_ONLY) { 14576 builder.append(" or "); 14577 builder.append(INTERACT_ACROSS_USERS); 14578 } 14579 String msg = builder.toString(); 14580 Slog.w(TAG, msg); 14581 throw new SecurityException(msg); 14582 } 14583 } 14584 } 14585 if (!allowAll && targetUserId < 0) { 14586 throw new IllegalArgumentException( 14587 "Call does not support special user #" + targetUserId); 14588 } 14589 return targetUserId; 14590 } 14591 14592 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14593 String className, int flags) { 14594 boolean result = false; 14595 // For apps that don't have pre-defined UIDs, check for permission 14596 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14597 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14598 if (ActivityManager.checkUidPermission( 14599 INTERACT_ACROSS_USERS, 14600 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14601 ComponentName comp = new ComponentName(aInfo.packageName, className); 14602 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14603 + " requests FLAG_SINGLE_USER, but app does not hold " 14604 + INTERACT_ACROSS_USERS; 14605 Slog.w(TAG, msg); 14606 throw new SecurityException(msg); 14607 } 14608 // Permission passed 14609 result = true; 14610 } 14611 } else if ("system".equals(componentProcessName)) { 14612 result = true; 14613 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14614 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14615 // Phone app is allowed to export singleuser providers. 14616 result = true; 14617 } else { 14618 // App with pre-defined UID, check if it's a persistent app 14619 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14620 } 14621 if (DEBUG_MU) { 14622 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14623 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14624 } 14625 return result; 14626 } 14627 14628 /** 14629 * Checks to see if the caller is in the same app as the singleton 14630 * component, or the component is in a special app. It allows special apps 14631 * to export singleton components but prevents exporting singleton 14632 * components for regular apps. 14633 */ 14634 boolean isValidSingletonCall(int callingUid, int componentUid) { 14635 int componentAppId = UserHandle.getAppId(componentUid); 14636 return UserHandle.isSameApp(callingUid, componentUid) 14637 || componentAppId == Process.SYSTEM_UID 14638 || componentAppId == Process.PHONE_UID 14639 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14640 == PackageManager.PERMISSION_GRANTED; 14641 } 14642 14643 public int bindService(IApplicationThread caller, IBinder token, 14644 Intent service, String resolvedType, 14645 IServiceConnection connection, int flags, int userId) { 14646 enforceNotIsolatedCaller("bindService"); 14647 // Refuse possible leaked file descriptors 14648 if (service != null && service.hasFileDescriptors() == true) { 14649 throw new IllegalArgumentException("File descriptors passed in Intent"); 14650 } 14651 14652 synchronized(this) { 14653 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14654 connection, flags, userId); 14655 } 14656 } 14657 14658 public boolean unbindService(IServiceConnection connection) { 14659 synchronized (this) { 14660 return mServices.unbindServiceLocked(connection); 14661 } 14662 } 14663 14664 public void publishService(IBinder token, Intent intent, IBinder service) { 14665 // Refuse possible leaked file descriptors 14666 if (intent != null && intent.hasFileDescriptors() == true) { 14667 throw new IllegalArgumentException("File descriptors passed in Intent"); 14668 } 14669 14670 synchronized(this) { 14671 if (!(token instanceof ServiceRecord)) { 14672 throw new IllegalArgumentException("Invalid service token"); 14673 } 14674 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14675 } 14676 } 14677 14678 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14679 // Refuse possible leaked file descriptors 14680 if (intent != null && intent.hasFileDescriptors() == true) { 14681 throw new IllegalArgumentException("File descriptors passed in Intent"); 14682 } 14683 14684 synchronized(this) { 14685 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14686 } 14687 } 14688 14689 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14690 synchronized(this) { 14691 if (!(token instanceof ServiceRecord)) { 14692 throw new IllegalArgumentException("Invalid service token"); 14693 } 14694 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14695 } 14696 } 14697 14698 // ========================================================= 14699 // BACKUP AND RESTORE 14700 // ========================================================= 14701 14702 // Cause the target app to be launched if necessary and its backup agent 14703 // instantiated. The backup agent will invoke backupAgentCreated() on the 14704 // activity manager to announce its creation. 14705 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14706 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14707 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14708 14709 synchronized(this) { 14710 // !!! TODO: currently no check here that we're already bound 14711 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14712 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14713 synchronized (stats) { 14714 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14715 } 14716 14717 // Backup agent is now in use, its package can't be stopped. 14718 try { 14719 AppGlobals.getPackageManager().setPackageStoppedState( 14720 app.packageName, false, UserHandle.getUserId(app.uid)); 14721 } catch (RemoteException e) { 14722 } catch (IllegalArgumentException e) { 14723 Slog.w(TAG, "Failed trying to unstop package " 14724 + app.packageName + ": " + e); 14725 } 14726 14727 BackupRecord r = new BackupRecord(ss, app, backupMode); 14728 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14729 ? new ComponentName(app.packageName, app.backupAgentName) 14730 : new ComponentName("android", "FullBackupAgent"); 14731 // startProcessLocked() returns existing proc's record if it's already running 14732 ProcessRecord proc = startProcessLocked(app.processName, app, 14733 false, 0, "backup", hostingName, false, false, false); 14734 if (proc == null) { 14735 Slog.e(TAG, "Unable to start backup agent process " + r); 14736 return false; 14737 } 14738 14739 r.app = proc; 14740 mBackupTarget = r; 14741 mBackupAppName = app.packageName; 14742 14743 // Try not to kill the process during backup 14744 updateOomAdjLocked(proc); 14745 14746 // If the process is already attached, schedule the creation of the backup agent now. 14747 // If it is not yet live, this will be done when it attaches to the framework. 14748 if (proc.thread != null) { 14749 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14750 try { 14751 proc.thread.scheduleCreateBackupAgent(app, 14752 compatibilityInfoForPackageLocked(app), backupMode); 14753 } catch (RemoteException e) { 14754 // Will time out on the backup manager side 14755 } 14756 } else { 14757 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14758 } 14759 // Invariants: at this point, the target app process exists and the application 14760 // is either already running or in the process of coming up. mBackupTarget and 14761 // mBackupAppName describe the app, so that when it binds back to the AM we 14762 // know that it's scheduled for a backup-agent operation. 14763 } 14764 14765 return true; 14766 } 14767 14768 @Override 14769 public void clearPendingBackup() { 14770 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14771 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14772 14773 synchronized (this) { 14774 mBackupTarget = null; 14775 mBackupAppName = null; 14776 } 14777 } 14778 14779 // A backup agent has just come up 14780 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14781 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14782 + " = " + agent); 14783 14784 synchronized(this) { 14785 if (!agentPackageName.equals(mBackupAppName)) { 14786 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14787 return; 14788 } 14789 } 14790 14791 long oldIdent = Binder.clearCallingIdentity(); 14792 try { 14793 IBackupManager bm = IBackupManager.Stub.asInterface( 14794 ServiceManager.getService(Context.BACKUP_SERVICE)); 14795 bm.agentConnected(agentPackageName, agent); 14796 } catch (RemoteException e) { 14797 // can't happen; the backup manager service is local 14798 } catch (Exception e) { 14799 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14800 e.printStackTrace(); 14801 } finally { 14802 Binder.restoreCallingIdentity(oldIdent); 14803 } 14804 } 14805 14806 // done with this agent 14807 public void unbindBackupAgent(ApplicationInfo appInfo) { 14808 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14809 if (appInfo == null) { 14810 Slog.w(TAG, "unbind backup agent for null app"); 14811 return; 14812 } 14813 14814 synchronized(this) { 14815 try { 14816 if (mBackupAppName == null) { 14817 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14818 return; 14819 } 14820 14821 if (!mBackupAppName.equals(appInfo.packageName)) { 14822 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14823 return; 14824 } 14825 14826 // Not backing this app up any more; reset its OOM adjustment 14827 final ProcessRecord proc = mBackupTarget.app; 14828 updateOomAdjLocked(proc); 14829 14830 // If the app crashed during backup, 'thread' will be null here 14831 if (proc.thread != null) { 14832 try { 14833 proc.thread.scheduleDestroyBackupAgent(appInfo, 14834 compatibilityInfoForPackageLocked(appInfo)); 14835 } catch (Exception e) { 14836 Slog.e(TAG, "Exception when unbinding backup agent:"); 14837 e.printStackTrace(); 14838 } 14839 } 14840 } finally { 14841 mBackupTarget = null; 14842 mBackupAppName = null; 14843 } 14844 } 14845 } 14846 // ========================================================= 14847 // BROADCASTS 14848 // ========================================================= 14849 14850 private final List getStickiesLocked(String action, IntentFilter filter, 14851 List cur, int userId) { 14852 final ContentResolver resolver = mContext.getContentResolver(); 14853 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14854 if (stickies == null) { 14855 return cur; 14856 } 14857 final ArrayList<Intent> list = stickies.get(action); 14858 if (list == null) { 14859 return cur; 14860 } 14861 int N = list.size(); 14862 for (int i=0; i<N; i++) { 14863 Intent intent = list.get(i); 14864 if (filter.match(resolver, intent, true, TAG) >= 0) { 14865 if (cur == null) { 14866 cur = new ArrayList<Intent>(); 14867 } 14868 cur.add(intent); 14869 } 14870 } 14871 return cur; 14872 } 14873 14874 boolean isPendingBroadcastProcessLocked(int pid) { 14875 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14876 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14877 } 14878 14879 void skipPendingBroadcastLocked(int pid) { 14880 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14881 for (BroadcastQueue queue : mBroadcastQueues) { 14882 queue.skipPendingBroadcastLocked(pid); 14883 } 14884 } 14885 14886 // The app just attached; send any pending broadcasts that it should receive 14887 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14888 boolean didSomething = false; 14889 for (BroadcastQueue queue : mBroadcastQueues) { 14890 didSomething |= queue.sendPendingBroadcastsLocked(app); 14891 } 14892 return didSomething; 14893 } 14894 14895 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14896 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14897 enforceNotIsolatedCaller("registerReceiver"); 14898 int callingUid; 14899 int callingPid; 14900 synchronized(this) { 14901 ProcessRecord callerApp = null; 14902 if (caller != null) { 14903 callerApp = getRecordForAppLocked(caller); 14904 if (callerApp == null) { 14905 throw new SecurityException( 14906 "Unable to find app for caller " + caller 14907 + " (pid=" + Binder.getCallingPid() 14908 + ") when registering receiver " + receiver); 14909 } 14910 if (callerApp.info.uid != Process.SYSTEM_UID && 14911 !callerApp.pkgList.containsKey(callerPackage) && 14912 !"android".equals(callerPackage)) { 14913 throw new SecurityException("Given caller package " + callerPackage 14914 + " is not running in process " + callerApp); 14915 } 14916 callingUid = callerApp.info.uid; 14917 callingPid = callerApp.pid; 14918 } else { 14919 callerPackage = null; 14920 callingUid = Binder.getCallingUid(); 14921 callingPid = Binder.getCallingPid(); 14922 } 14923 14924 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14925 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14926 14927 List allSticky = null; 14928 14929 // Look for any matching sticky broadcasts... 14930 Iterator actions = filter.actionsIterator(); 14931 if (actions != null) { 14932 while (actions.hasNext()) { 14933 String action = (String)actions.next(); 14934 allSticky = getStickiesLocked(action, filter, allSticky, 14935 UserHandle.USER_ALL); 14936 allSticky = getStickiesLocked(action, filter, allSticky, 14937 UserHandle.getUserId(callingUid)); 14938 } 14939 } else { 14940 allSticky = getStickiesLocked(null, filter, allSticky, 14941 UserHandle.USER_ALL); 14942 allSticky = getStickiesLocked(null, filter, allSticky, 14943 UserHandle.getUserId(callingUid)); 14944 } 14945 14946 // The first sticky in the list is returned directly back to 14947 // the client. 14948 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14949 14950 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14951 + ": " + sticky); 14952 14953 if (receiver == null) { 14954 return sticky; 14955 } 14956 14957 ReceiverList rl 14958 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14959 if (rl == null) { 14960 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14961 userId, receiver); 14962 if (rl.app != null) { 14963 rl.app.receivers.add(rl); 14964 } else { 14965 try { 14966 receiver.asBinder().linkToDeath(rl, 0); 14967 } catch (RemoteException e) { 14968 return sticky; 14969 } 14970 rl.linkedToDeath = true; 14971 } 14972 mRegisteredReceivers.put(receiver.asBinder(), rl); 14973 } else if (rl.uid != callingUid) { 14974 throw new IllegalArgumentException( 14975 "Receiver requested to register for uid " + callingUid 14976 + " was previously registered for uid " + rl.uid); 14977 } else if (rl.pid != callingPid) { 14978 throw new IllegalArgumentException( 14979 "Receiver requested to register for pid " + callingPid 14980 + " was previously registered for pid " + rl.pid); 14981 } else if (rl.userId != userId) { 14982 throw new IllegalArgumentException( 14983 "Receiver requested to register for user " + userId 14984 + " was previously registered for user " + rl.userId); 14985 } 14986 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14987 permission, callingUid, userId); 14988 rl.add(bf); 14989 if (!bf.debugCheck()) { 14990 Slog.w(TAG, "==> For Dynamic broadast"); 14991 } 14992 mReceiverResolver.addFilter(bf); 14993 14994 // Enqueue broadcasts for all existing stickies that match 14995 // this filter. 14996 if (allSticky != null) { 14997 ArrayList receivers = new ArrayList(); 14998 receivers.add(bf); 14999 15000 int N = allSticky.size(); 15001 for (int i=0; i<N; i++) { 15002 Intent intent = (Intent)allSticky.get(i); 15003 BroadcastQueue queue = broadcastQueueForIntent(intent); 15004 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 15005 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 15006 null, null, false, true, true, -1); 15007 queue.enqueueParallelBroadcastLocked(r); 15008 queue.scheduleBroadcastsLocked(); 15009 } 15010 } 15011 15012 return sticky; 15013 } 15014 } 15015 15016 public void unregisterReceiver(IIntentReceiver receiver) { 15017 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 15018 15019 final long origId = Binder.clearCallingIdentity(); 15020 try { 15021 boolean doTrim = false; 15022 15023 synchronized(this) { 15024 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 15025 if (rl != null) { 15026 if (rl.curBroadcast != null) { 15027 BroadcastRecord r = rl.curBroadcast; 15028 final boolean doNext = finishReceiverLocked( 15029 receiver.asBinder(), r.resultCode, r.resultData, 15030 r.resultExtras, r.resultAbort); 15031 if (doNext) { 15032 doTrim = true; 15033 r.queue.processNextBroadcast(false); 15034 } 15035 } 15036 15037 if (rl.app != null) { 15038 rl.app.receivers.remove(rl); 15039 } 15040 removeReceiverLocked(rl); 15041 if (rl.linkedToDeath) { 15042 rl.linkedToDeath = false; 15043 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15044 } 15045 } 15046 } 15047 15048 // If we actually concluded any broadcasts, we might now be able 15049 // to trim the recipients' apps from our working set 15050 if (doTrim) { 15051 trimApplications(); 15052 return; 15053 } 15054 15055 } finally { 15056 Binder.restoreCallingIdentity(origId); 15057 } 15058 } 15059 15060 void removeReceiverLocked(ReceiverList rl) { 15061 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15062 int N = rl.size(); 15063 for (int i=0; i<N; i++) { 15064 mReceiverResolver.removeFilter(rl.get(i)); 15065 } 15066 } 15067 15068 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15069 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15070 ProcessRecord r = mLruProcesses.get(i); 15071 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15072 try { 15073 r.thread.dispatchPackageBroadcast(cmd, packages); 15074 } catch (RemoteException ex) { 15075 } 15076 } 15077 } 15078 } 15079 15080 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15081 int[] users) { 15082 List<ResolveInfo> receivers = null; 15083 try { 15084 HashSet<ComponentName> singleUserReceivers = null; 15085 boolean scannedFirstReceivers = false; 15086 for (int user : users) { 15087 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15088 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15089 if (user != 0 && newReceivers != null) { 15090 // If this is not the primary user, we need to check for 15091 // any receivers that should be filtered out. 15092 for (int i=0; i<newReceivers.size(); i++) { 15093 ResolveInfo ri = newReceivers.get(i); 15094 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15095 newReceivers.remove(i); 15096 i--; 15097 } 15098 } 15099 } 15100 if (newReceivers != null && newReceivers.size() == 0) { 15101 newReceivers = null; 15102 } 15103 if (receivers == null) { 15104 receivers = newReceivers; 15105 } else if (newReceivers != null) { 15106 // We need to concatenate the additional receivers 15107 // found with what we have do far. This would be easy, 15108 // but we also need to de-dup any receivers that are 15109 // singleUser. 15110 if (!scannedFirstReceivers) { 15111 // Collect any single user receivers we had already retrieved. 15112 scannedFirstReceivers = true; 15113 for (int i=0; i<receivers.size(); i++) { 15114 ResolveInfo ri = receivers.get(i); 15115 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15116 ComponentName cn = new ComponentName( 15117 ri.activityInfo.packageName, ri.activityInfo.name); 15118 if (singleUserReceivers == null) { 15119 singleUserReceivers = new HashSet<ComponentName>(); 15120 } 15121 singleUserReceivers.add(cn); 15122 } 15123 } 15124 } 15125 // Add the new results to the existing results, tracking 15126 // and de-dupping single user receivers. 15127 for (int i=0; i<newReceivers.size(); i++) { 15128 ResolveInfo ri = newReceivers.get(i); 15129 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15130 ComponentName cn = new ComponentName( 15131 ri.activityInfo.packageName, ri.activityInfo.name); 15132 if (singleUserReceivers == null) { 15133 singleUserReceivers = new HashSet<ComponentName>(); 15134 } 15135 if (!singleUserReceivers.contains(cn)) { 15136 singleUserReceivers.add(cn); 15137 receivers.add(ri); 15138 } 15139 } else { 15140 receivers.add(ri); 15141 } 15142 } 15143 } 15144 } 15145 } catch (RemoteException ex) { 15146 // pm is in same process, this will never happen. 15147 } 15148 return receivers; 15149 } 15150 15151 private final int broadcastIntentLocked(ProcessRecord callerApp, 15152 String callerPackage, Intent intent, String resolvedType, 15153 IIntentReceiver resultTo, int resultCode, String resultData, 15154 Bundle map, String requiredPermission, int appOp, 15155 boolean ordered, boolean sticky, int callingPid, int callingUid, 15156 int userId) { 15157 intent = new Intent(intent); 15158 15159 // By default broadcasts do not go to stopped apps. 15160 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15161 15162 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15163 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15164 + " ordered=" + ordered + " userid=" + userId); 15165 if ((resultTo != null) && !ordered) { 15166 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15167 } 15168 15169 userId = handleIncomingUser(callingPid, callingUid, userId, 15170 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15171 15172 // Make sure that the user who is receiving this broadcast is started. 15173 // If not, we will just skip it. 15174 15175 15176 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15177 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15178 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15179 Slog.w(TAG, "Skipping broadcast of " + intent 15180 + ": user " + userId + " is stopped"); 15181 return ActivityManager.BROADCAST_SUCCESS; 15182 } 15183 } 15184 15185 /* 15186 * Prevent non-system code (defined here to be non-persistent 15187 * processes) from sending protected broadcasts. 15188 */ 15189 int callingAppId = UserHandle.getAppId(callingUid); 15190 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15191 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15192 || callingAppId == Process.NFC_UID || callingUid == 0) { 15193 // Always okay. 15194 } else if (callerApp == null || !callerApp.persistent) { 15195 try { 15196 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15197 intent.getAction())) { 15198 String msg = "Permission Denial: not allowed to send broadcast " 15199 + intent.getAction() + " from pid=" 15200 + callingPid + ", uid=" + callingUid; 15201 Slog.w(TAG, msg); 15202 throw new SecurityException(msg); 15203 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15204 // Special case for compatibility: we don't want apps to send this, 15205 // but historically it has not been protected and apps may be using it 15206 // to poke their own app widget. So, instead of making it protected, 15207 // just limit it to the caller. 15208 if (callerApp == null) { 15209 String msg = "Permission Denial: not allowed to send broadcast " 15210 + intent.getAction() + " from unknown caller."; 15211 Slog.w(TAG, msg); 15212 throw new SecurityException(msg); 15213 } else if (intent.getComponent() != null) { 15214 // They are good enough to send to an explicit component... verify 15215 // it is being sent to the calling app. 15216 if (!intent.getComponent().getPackageName().equals( 15217 callerApp.info.packageName)) { 15218 String msg = "Permission Denial: not allowed to send broadcast " 15219 + intent.getAction() + " to " 15220 + intent.getComponent().getPackageName() + " from " 15221 + callerApp.info.packageName; 15222 Slog.w(TAG, msg); 15223 throw new SecurityException(msg); 15224 } 15225 } else { 15226 // Limit broadcast to their own package. 15227 intent.setPackage(callerApp.info.packageName); 15228 } 15229 } 15230 } catch (RemoteException e) { 15231 Slog.w(TAG, "Remote exception", e); 15232 return ActivityManager.BROADCAST_SUCCESS; 15233 } 15234 } 15235 15236 // Handle special intents: if this broadcast is from the package 15237 // manager about a package being removed, we need to remove all of 15238 // its activities from the history stack. 15239 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15240 intent.getAction()); 15241 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15242 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15243 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15244 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15245 || uidRemoved) { 15246 if (checkComponentPermission( 15247 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15248 callingPid, callingUid, -1, true) 15249 == PackageManager.PERMISSION_GRANTED) { 15250 if (uidRemoved) { 15251 final Bundle intentExtras = intent.getExtras(); 15252 final int uid = intentExtras != null 15253 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15254 if (uid >= 0) { 15255 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15256 synchronized (bs) { 15257 bs.removeUidStatsLocked(uid); 15258 } 15259 mAppOpsService.uidRemoved(uid); 15260 } 15261 } else { 15262 // If resources are unavailable just force stop all 15263 // those packages and flush the attribute cache as well. 15264 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15265 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15266 if (list != null && (list.length > 0)) { 15267 for (String pkg : list) { 15268 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15269 "storage unmount"); 15270 } 15271 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15272 sendPackageBroadcastLocked( 15273 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15274 } 15275 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15276 intent.getAction())) { 15277 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15278 } else { 15279 Uri data = intent.getData(); 15280 String ssp; 15281 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15282 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15283 intent.getAction()); 15284 boolean fullUninstall = removed && 15285 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15286 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15287 forceStopPackageLocked(ssp, UserHandle.getAppId( 15288 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15289 false, fullUninstall, userId, 15290 removed ? "pkg removed" : "pkg changed"); 15291 } 15292 if (removed) { 15293 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15294 new String[] {ssp}, userId); 15295 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15296 mAppOpsService.packageRemoved( 15297 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15298 15299 // Remove all permissions granted from/to this package 15300 removeUriPermissionsForPackageLocked(ssp, userId, true); 15301 } 15302 } 15303 } 15304 } 15305 } 15306 } else { 15307 String msg = "Permission Denial: " + intent.getAction() 15308 + " broadcast from " + callerPackage + " (pid=" + callingPid 15309 + ", uid=" + callingUid + ")" 15310 + " requires " 15311 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15312 Slog.w(TAG, msg); 15313 throw new SecurityException(msg); 15314 } 15315 15316 // Special case for adding a package: by default turn on compatibility 15317 // mode. 15318 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15319 Uri data = intent.getData(); 15320 String ssp; 15321 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15322 mCompatModePackages.handlePackageAddedLocked(ssp, 15323 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15324 } 15325 } 15326 15327 /* 15328 * If this is the time zone changed action, queue up a message that will reset the timezone 15329 * of all currently running processes. This message will get queued up before the broadcast 15330 * happens. 15331 */ 15332 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15333 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15334 } 15335 15336 /* 15337 * If the user set the time, let all running processes know. 15338 */ 15339 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15340 final int is24Hour = intent.getBooleanExtra( 15341 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15342 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15343 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15344 synchronized (stats) { 15345 stats.noteCurrentTimeChangedLocked(); 15346 } 15347 } 15348 15349 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15350 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15351 } 15352 15353 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15354 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15355 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15356 } 15357 15358 // Add to the sticky list if requested. 15359 if (sticky) { 15360 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15361 callingPid, callingUid) 15362 != PackageManager.PERMISSION_GRANTED) { 15363 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15364 + callingPid + ", uid=" + callingUid 15365 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15366 Slog.w(TAG, msg); 15367 throw new SecurityException(msg); 15368 } 15369 if (requiredPermission != null) { 15370 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15371 + " and enforce permission " + requiredPermission); 15372 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15373 } 15374 if (intent.getComponent() != null) { 15375 throw new SecurityException( 15376 "Sticky broadcasts can't target a specific component"); 15377 } 15378 // We use userId directly here, since the "all" target is maintained 15379 // as a separate set of sticky broadcasts. 15380 if (userId != UserHandle.USER_ALL) { 15381 // But first, if this is not a broadcast to all users, then 15382 // make sure it doesn't conflict with an existing broadcast to 15383 // all users. 15384 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15385 UserHandle.USER_ALL); 15386 if (stickies != null) { 15387 ArrayList<Intent> list = stickies.get(intent.getAction()); 15388 if (list != null) { 15389 int N = list.size(); 15390 int i; 15391 for (i=0; i<N; i++) { 15392 if (intent.filterEquals(list.get(i))) { 15393 throw new IllegalArgumentException( 15394 "Sticky broadcast " + intent + " for user " 15395 + userId + " conflicts with existing global broadcast"); 15396 } 15397 } 15398 } 15399 } 15400 } 15401 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15402 if (stickies == null) { 15403 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15404 mStickyBroadcasts.put(userId, stickies); 15405 } 15406 ArrayList<Intent> list = stickies.get(intent.getAction()); 15407 if (list == null) { 15408 list = new ArrayList<Intent>(); 15409 stickies.put(intent.getAction(), list); 15410 } 15411 int N = list.size(); 15412 int i; 15413 for (i=0; i<N; i++) { 15414 if (intent.filterEquals(list.get(i))) { 15415 // This sticky already exists, replace it. 15416 list.set(i, new Intent(intent)); 15417 break; 15418 } 15419 } 15420 if (i >= N) { 15421 list.add(new Intent(intent)); 15422 } 15423 } 15424 15425 int[] users; 15426 if (userId == UserHandle.USER_ALL) { 15427 // Caller wants broadcast to go to all started users. 15428 users = mStartedUserArray; 15429 } else { 15430 // Caller wants broadcast to go to one specific user. 15431 users = new int[] {userId}; 15432 } 15433 15434 // Figure out who all will receive this broadcast. 15435 List receivers = null; 15436 List<BroadcastFilter> registeredReceivers = null; 15437 // Need to resolve the intent to interested receivers... 15438 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15439 == 0) { 15440 receivers = collectReceiverComponents(intent, resolvedType, users); 15441 } 15442 if (intent.getComponent() == null) { 15443 registeredReceivers = mReceiverResolver.queryIntent(intent, 15444 resolvedType, false, userId); 15445 } 15446 15447 final boolean replacePending = 15448 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15449 15450 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15451 + " replacePending=" + replacePending); 15452 15453 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15454 if (!ordered && NR > 0) { 15455 // If we are not serializing this broadcast, then send the 15456 // registered receivers separately so they don't wait for the 15457 // components to be launched. 15458 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15459 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15460 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15461 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15462 ordered, sticky, false, userId); 15463 if (DEBUG_BROADCAST) Slog.v( 15464 TAG, "Enqueueing parallel broadcast " + r); 15465 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15466 if (!replaced) { 15467 queue.enqueueParallelBroadcastLocked(r); 15468 queue.scheduleBroadcastsLocked(); 15469 } 15470 registeredReceivers = null; 15471 NR = 0; 15472 } 15473 15474 // Merge into one list. 15475 int ir = 0; 15476 if (receivers != null) { 15477 // A special case for PACKAGE_ADDED: do not allow the package 15478 // being added to see this broadcast. This prevents them from 15479 // using this as a back door to get run as soon as they are 15480 // installed. Maybe in the future we want to have a special install 15481 // broadcast or such for apps, but we'd like to deliberately make 15482 // this decision. 15483 String skipPackages[] = null; 15484 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15485 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15486 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15487 Uri data = intent.getData(); 15488 if (data != null) { 15489 String pkgName = data.getSchemeSpecificPart(); 15490 if (pkgName != null) { 15491 skipPackages = new String[] { pkgName }; 15492 } 15493 } 15494 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15495 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15496 } 15497 if (skipPackages != null && (skipPackages.length > 0)) { 15498 for (String skipPackage : skipPackages) { 15499 if (skipPackage != null) { 15500 int NT = receivers.size(); 15501 for (int it=0; it<NT; it++) { 15502 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15503 if (curt.activityInfo.packageName.equals(skipPackage)) { 15504 receivers.remove(it); 15505 it--; 15506 NT--; 15507 } 15508 } 15509 } 15510 } 15511 } 15512 15513 int NT = receivers != null ? receivers.size() : 0; 15514 int it = 0; 15515 ResolveInfo curt = null; 15516 BroadcastFilter curr = null; 15517 while (it < NT && ir < NR) { 15518 if (curt == null) { 15519 curt = (ResolveInfo)receivers.get(it); 15520 } 15521 if (curr == null) { 15522 curr = registeredReceivers.get(ir); 15523 } 15524 if (curr.getPriority() >= curt.priority) { 15525 // Insert this broadcast record into the final list. 15526 receivers.add(it, curr); 15527 ir++; 15528 curr = null; 15529 it++; 15530 NT++; 15531 } else { 15532 // Skip to the next ResolveInfo in the final list. 15533 it++; 15534 curt = null; 15535 } 15536 } 15537 } 15538 while (ir < NR) { 15539 if (receivers == null) { 15540 receivers = new ArrayList(); 15541 } 15542 receivers.add(registeredReceivers.get(ir)); 15543 ir++; 15544 } 15545 15546 if ((receivers != null && receivers.size() > 0) 15547 || resultTo != null) { 15548 BroadcastQueue queue = broadcastQueueForIntent(intent); 15549 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15550 callerPackage, callingPid, callingUid, resolvedType, 15551 requiredPermission, appOp, receivers, resultTo, resultCode, 15552 resultData, map, ordered, sticky, false, userId); 15553 if (DEBUG_BROADCAST) Slog.v( 15554 TAG, "Enqueueing ordered broadcast " + r 15555 + ": prev had " + queue.mOrderedBroadcasts.size()); 15556 if (DEBUG_BROADCAST) { 15557 int seq = r.intent.getIntExtra("seq", -1); 15558 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15559 } 15560 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15561 if (!replaced) { 15562 queue.enqueueOrderedBroadcastLocked(r); 15563 queue.scheduleBroadcastsLocked(); 15564 } 15565 } 15566 15567 return ActivityManager.BROADCAST_SUCCESS; 15568 } 15569 15570 final Intent verifyBroadcastLocked(Intent intent) { 15571 // Refuse possible leaked file descriptors 15572 if (intent != null && intent.hasFileDescriptors() == true) { 15573 throw new IllegalArgumentException("File descriptors passed in Intent"); 15574 } 15575 15576 int flags = intent.getFlags(); 15577 15578 if (!mProcessesReady) { 15579 // if the caller really truly claims to know what they're doing, go 15580 // ahead and allow the broadcast without launching any receivers 15581 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15582 intent = new Intent(intent); 15583 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15584 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15585 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15586 + " before boot completion"); 15587 throw new IllegalStateException("Cannot broadcast before boot completed"); 15588 } 15589 } 15590 15591 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15592 throw new IllegalArgumentException( 15593 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15594 } 15595 15596 return intent; 15597 } 15598 15599 public final int broadcastIntent(IApplicationThread caller, 15600 Intent intent, String resolvedType, IIntentReceiver resultTo, 15601 int resultCode, String resultData, Bundle map, 15602 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15603 enforceNotIsolatedCaller("broadcastIntent"); 15604 synchronized(this) { 15605 intent = verifyBroadcastLocked(intent); 15606 15607 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15608 final int callingPid = Binder.getCallingPid(); 15609 final int callingUid = Binder.getCallingUid(); 15610 final long origId = Binder.clearCallingIdentity(); 15611 int res = broadcastIntentLocked(callerApp, 15612 callerApp != null ? callerApp.info.packageName : null, 15613 intent, resolvedType, resultTo, 15614 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15615 callingPid, callingUid, userId); 15616 Binder.restoreCallingIdentity(origId); 15617 return res; 15618 } 15619 } 15620 15621 int broadcastIntentInPackage(String packageName, int uid, 15622 Intent intent, String resolvedType, IIntentReceiver resultTo, 15623 int resultCode, String resultData, Bundle map, 15624 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15625 synchronized(this) { 15626 intent = verifyBroadcastLocked(intent); 15627 15628 final long origId = Binder.clearCallingIdentity(); 15629 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15630 resultTo, resultCode, resultData, map, requiredPermission, 15631 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15632 Binder.restoreCallingIdentity(origId); 15633 return res; 15634 } 15635 } 15636 15637 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15638 // Refuse possible leaked file descriptors 15639 if (intent != null && intent.hasFileDescriptors() == true) { 15640 throw new IllegalArgumentException("File descriptors passed in Intent"); 15641 } 15642 15643 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15644 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15645 15646 synchronized(this) { 15647 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15648 != PackageManager.PERMISSION_GRANTED) { 15649 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15650 + Binder.getCallingPid() 15651 + ", uid=" + Binder.getCallingUid() 15652 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15653 Slog.w(TAG, msg); 15654 throw new SecurityException(msg); 15655 } 15656 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15657 if (stickies != null) { 15658 ArrayList<Intent> list = stickies.get(intent.getAction()); 15659 if (list != null) { 15660 int N = list.size(); 15661 int i; 15662 for (i=0; i<N; i++) { 15663 if (intent.filterEquals(list.get(i))) { 15664 list.remove(i); 15665 break; 15666 } 15667 } 15668 if (list.size() <= 0) { 15669 stickies.remove(intent.getAction()); 15670 } 15671 } 15672 if (stickies.size() <= 0) { 15673 mStickyBroadcasts.remove(userId); 15674 } 15675 } 15676 } 15677 } 15678 15679 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15680 String resultData, Bundle resultExtras, boolean resultAbort) { 15681 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15682 if (r == null) { 15683 Slog.w(TAG, "finishReceiver called but not found on queue"); 15684 return false; 15685 } 15686 15687 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15688 } 15689 15690 void backgroundServicesFinishedLocked(int userId) { 15691 for (BroadcastQueue queue : mBroadcastQueues) { 15692 queue.backgroundServicesFinishedLocked(userId); 15693 } 15694 } 15695 15696 public void finishReceiver(IBinder who, int resultCode, String resultData, 15697 Bundle resultExtras, boolean resultAbort) { 15698 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15699 15700 // Refuse possible leaked file descriptors 15701 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15702 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15703 } 15704 15705 final long origId = Binder.clearCallingIdentity(); 15706 try { 15707 boolean doNext = false; 15708 BroadcastRecord r; 15709 15710 synchronized(this) { 15711 r = broadcastRecordForReceiverLocked(who); 15712 if (r != null) { 15713 doNext = r.queue.finishReceiverLocked(r, resultCode, 15714 resultData, resultExtras, resultAbort, true); 15715 } 15716 } 15717 15718 if (doNext) { 15719 r.queue.processNextBroadcast(false); 15720 } 15721 trimApplications(); 15722 } finally { 15723 Binder.restoreCallingIdentity(origId); 15724 } 15725 } 15726 15727 // ========================================================= 15728 // INSTRUMENTATION 15729 // ========================================================= 15730 15731 public boolean startInstrumentation(ComponentName className, 15732 String profileFile, int flags, Bundle arguments, 15733 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15734 int userId, String abiOverride) { 15735 enforceNotIsolatedCaller("startInstrumentation"); 15736 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15737 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15738 // Refuse possible leaked file descriptors 15739 if (arguments != null && arguments.hasFileDescriptors()) { 15740 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15741 } 15742 15743 synchronized(this) { 15744 InstrumentationInfo ii = null; 15745 ApplicationInfo ai = null; 15746 try { 15747 ii = mContext.getPackageManager().getInstrumentationInfo( 15748 className, STOCK_PM_FLAGS); 15749 ai = AppGlobals.getPackageManager().getApplicationInfo( 15750 ii.targetPackage, STOCK_PM_FLAGS, userId); 15751 } catch (PackageManager.NameNotFoundException e) { 15752 } catch (RemoteException e) { 15753 } 15754 if (ii == null) { 15755 reportStartInstrumentationFailure(watcher, className, 15756 "Unable to find instrumentation info for: " + className); 15757 return false; 15758 } 15759 if (ai == null) { 15760 reportStartInstrumentationFailure(watcher, className, 15761 "Unable to find instrumentation target package: " + ii.targetPackage); 15762 return false; 15763 } 15764 15765 int match = mContext.getPackageManager().checkSignatures( 15766 ii.targetPackage, ii.packageName); 15767 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15768 String msg = "Permission Denial: starting instrumentation " 15769 + className + " from pid=" 15770 + Binder.getCallingPid() 15771 + ", uid=" + Binder.getCallingPid() 15772 + " not allowed because package " + ii.packageName 15773 + " does not have a signature matching the target " 15774 + ii.targetPackage; 15775 reportStartInstrumentationFailure(watcher, className, msg); 15776 throw new SecurityException(msg); 15777 } 15778 15779 final long origId = Binder.clearCallingIdentity(); 15780 // Instrumentation can kill and relaunch even persistent processes 15781 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15782 "start instr"); 15783 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15784 app.instrumentationClass = className; 15785 app.instrumentationInfo = ai; 15786 app.instrumentationProfileFile = profileFile; 15787 app.instrumentationArguments = arguments; 15788 app.instrumentationWatcher = watcher; 15789 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15790 app.instrumentationResultClass = className; 15791 Binder.restoreCallingIdentity(origId); 15792 } 15793 15794 return true; 15795 } 15796 15797 /** 15798 * Report errors that occur while attempting to start Instrumentation. Always writes the 15799 * error to the logs, but if somebody is watching, send the report there too. This enables 15800 * the "am" command to report errors with more information. 15801 * 15802 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15803 * @param cn The component name of the instrumentation. 15804 * @param report The error report. 15805 */ 15806 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15807 ComponentName cn, String report) { 15808 Slog.w(TAG, report); 15809 try { 15810 if (watcher != null) { 15811 Bundle results = new Bundle(); 15812 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15813 results.putString("Error", report); 15814 watcher.instrumentationStatus(cn, -1, results); 15815 } 15816 } catch (RemoteException e) { 15817 Slog.w(TAG, e); 15818 } 15819 } 15820 15821 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15822 if (app.instrumentationWatcher != null) { 15823 try { 15824 // NOTE: IInstrumentationWatcher *must* be oneway here 15825 app.instrumentationWatcher.instrumentationFinished( 15826 app.instrumentationClass, 15827 resultCode, 15828 results); 15829 } catch (RemoteException e) { 15830 } 15831 } 15832 if (app.instrumentationUiAutomationConnection != null) { 15833 try { 15834 app.instrumentationUiAutomationConnection.shutdown(); 15835 } catch (RemoteException re) { 15836 /* ignore */ 15837 } 15838 // Only a UiAutomation can set this flag and now that 15839 // it is finished we make sure it is reset to its default. 15840 mUserIsMonkey = false; 15841 } 15842 app.instrumentationWatcher = null; 15843 app.instrumentationUiAutomationConnection = null; 15844 app.instrumentationClass = null; 15845 app.instrumentationInfo = null; 15846 app.instrumentationProfileFile = null; 15847 app.instrumentationArguments = null; 15848 15849 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15850 "finished inst"); 15851 } 15852 15853 public void finishInstrumentation(IApplicationThread target, 15854 int resultCode, Bundle results) { 15855 int userId = UserHandle.getCallingUserId(); 15856 // Refuse possible leaked file descriptors 15857 if (results != null && results.hasFileDescriptors()) { 15858 throw new IllegalArgumentException("File descriptors passed in Intent"); 15859 } 15860 15861 synchronized(this) { 15862 ProcessRecord app = getRecordForAppLocked(target); 15863 if (app == null) { 15864 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15865 return; 15866 } 15867 final long origId = Binder.clearCallingIdentity(); 15868 finishInstrumentationLocked(app, resultCode, results); 15869 Binder.restoreCallingIdentity(origId); 15870 } 15871 } 15872 15873 // ========================================================= 15874 // CONFIGURATION 15875 // ========================================================= 15876 15877 public ConfigurationInfo getDeviceConfigurationInfo() { 15878 ConfigurationInfo config = new ConfigurationInfo(); 15879 synchronized (this) { 15880 config.reqTouchScreen = mConfiguration.touchscreen; 15881 config.reqKeyboardType = mConfiguration.keyboard; 15882 config.reqNavigation = mConfiguration.navigation; 15883 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15884 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15885 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15886 } 15887 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15888 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15889 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15890 } 15891 config.reqGlEsVersion = GL_ES_VERSION; 15892 } 15893 return config; 15894 } 15895 15896 ActivityStack getFocusedStack() { 15897 return mStackSupervisor.getFocusedStack(); 15898 } 15899 15900 public Configuration getConfiguration() { 15901 Configuration ci; 15902 synchronized(this) { 15903 ci = new Configuration(mConfiguration); 15904 } 15905 return ci; 15906 } 15907 15908 public void updatePersistentConfiguration(Configuration values) { 15909 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15910 "updateConfiguration()"); 15911 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15912 "updateConfiguration()"); 15913 if (values == null) { 15914 throw new NullPointerException("Configuration must not be null"); 15915 } 15916 15917 synchronized(this) { 15918 final long origId = Binder.clearCallingIdentity(); 15919 updateConfigurationLocked(values, null, true, false); 15920 Binder.restoreCallingIdentity(origId); 15921 } 15922 } 15923 15924 public void updateConfiguration(Configuration values) { 15925 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15926 "updateConfiguration()"); 15927 15928 synchronized(this) { 15929 if (values == null && mWindowManager != null) { 15930 // sentinel: fetch the current configuration from the window manager 15931 values = mWindowManager.computeNewConfiguration(); 15932 } 15933 15934 if (mWindowManager != null) { 15935 mProcessList.applyDisplaySize(mWindowManager); 15936 } 15937 15938 final long origId = Binder.clearCallingIdentity(); 15939 if (values != null) { 15940 Settings.System.clearConfiguration(values); 15941 } 15942 updateConfigurationLocked(values, null, false, false); 15943 Binder.restoreCallingIdentity(origId); 15944 } 15945 } 15946 15947 /** 15948 * Do either or both things: (1) change the current configuration, and (2) 15949 * make sure the given activity is running with the (now) current 15950 * configuration. Returns true if the activity has been left running, or 15951 * false if <var>starting</var> is being destroyed to match the new 15952 * configuration. 15953 * @param persistent TODO 15954 */ 15955 boolean updateConfigurationLocked(Configuration values, 15956 ActivityRecord starting, boolean persistent, boolean initLocale) { 15957 int changes = 0; 15958 15959 if (values != null) { 15960 Configuration newConfig = new Configuration(mConfiguration); 15961 changes = newConfig.updateFrom(values); 15962 if (changes != 0) { 15963 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15964 Slog.i(TAG, "Updating configuration to: " + values); 15965 } 15966 15967 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15968 15969 if (values.locale != null && !initLocale) { 15970 saveLocaleLocked(values.locale, 15971 !values.locale.equals(mConfiguration.locale), 15972 values.userSetLocale); 15973 } 15974 15975 mConfigurationSeq++; 15976 if (mConfigurationSeq <= 0) { 15977 mConfigurationSeq = 1; 15978 } 15979 newConfig.seq = mConfigurationSeq; 15980 mConfiguration = newConfig; 15981 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15982 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId); 15983 //mUsageStatsService.noteStartConfig(newConfig); 15984 15985 final Configuration configCopy = new Configuration(mConfiguration); 15986 15987 // TODO: If our config changes, should we auto dismiss any currently 15988 // showing dialogs? 15989 mShowDialogs = shouldShowDialogs(newConfig); 15990 15991 AttributeCache ac = AttributeCache.instance(); 15992 if (ac != null) { 15993 ac.updateConfiguration(configCopy); 15994 } 15995 15996 // Make sure all resources in our process are updated 15997 // right now, so that anyone who is going to retrieve 15998 // resource values after we return will be sure to get 15999 // the new ones. This is especially important during 16000 // boot, where the first config change needs to guarantee 16001 // all resources have that config before following boot 16002 // code is executed. 16003 mSystemThread.applyConfigurationToResources(configCopy); 16004 16005 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 16006 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 16007 msg.obj = new Configuration(configCopy); 16008 mHandler.sendMessage(msg); 16009 } 16010 16011 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16012 ProcessRecord app = mLruProcesses.get(i); 16013 try { 16014 if (app.thread != null) { 16015 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 16016 + app.processName + " new config " + mConfiguration); 16017 app.thread.scheduleConfigurationChanged(configCopy); 16018 } 16019 } catch (Exception e) { 16020 } 16021 } 16022 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 16023 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16024 | Intent.FLAG_RECEIVER_REPLACE_PENDING 16025 | Intent.FLAG_RECEIVER_FOREGROUND); 16026 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 16027 null, AppOpsManager.OP_NONE, false, false, MY_PID, 16028 Process.SYSTEM_UID, UserHandle.USER_ALL); 16029 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 16030 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 16031 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16032 broadcastIntentLocked(null, null, intent, 16033 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16034 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16035 } 16036 } 16037 } 16038 16039 boolean kept = true; 16040 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 16041 // mainStack is null during startup. 16042 if (mainStack != null) { 16043 if (changes != 0 && starting == null) { 16044 // If the configuration changed, and the caller is not already 16045 // in the process of starting an activity, then find the top 16046 // activity to check if its configuration needs to change. 16047 starting = mainStack.topRunningActivityLocked(null); 16048 } 16049 16050 if (starting != null) { 16051 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16052 // And we need to make sure at this point that all other activities 16053 // are made visible with the correct configuration. 16054 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16055 } 16056 } 16057 16058 if (values != null && mWindowManager != null) { 16059 mWindowManager.setNewConfiguration(mConfiguration); 16060 } 16061 16062 return kept; 16063 } 16064 16065 /** 16066 * Decide based on the configuration whether we should shouw the ANR, 16067 * crash, etc dialogs. The idea is that if there is no affordnace to 16068 * press the on-screen buttons, we shouldn't show the dialog. 16069 * 16070 * A thought: SystemUI might also want to get told about this, the Power 16071 * dialog / global actions also might want different behaviors. 16072 */ 16073 private static final boolean shouldShowDialogs(Configuration config) { 16074 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16075 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16076 } 16077 16078 /** 16079 * Save the locale. You must be inside a synchronized (this) block. 16080 */ 16081 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16082 if(isDiff) { 16083 SystemProperties.set("user.language", l.getLanguage()); 16084 SystemProperties.set("user.region", l.getCountry()); 16085 } 16086 16087 if(isPersist) { 16088 SystemProperties.set("persist.sys.language", l.getLanguage()); 16089 SystemProperties.set("persist.sys.country", l.getCountry()); 16090 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16091 } 16092 } 16093 16094 @Override 16095 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16096 synchronized (this) { 16097 ActivityRecord srec = ActivityRecord.forToken(token); 16098 if (srec.task != null && srec.task.stack != null) { 16099 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16100 } 16101 } 16102 return false; 16103 } 16104 16105 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16106 Intent resultData) { 16107 16108 synchronized (this) { 16109 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16110 if (stack != null) { 16111 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16112 } 16113 return false; 16114 } 16115 } 16116 16117 public int getLaunchedFromUid(IBinder activityToken) { 16118 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16119 if (srec == null) { 16120 return -1; 16121 } 16122 return srec.launchedFromUid; 16123 } 16124 16125 public String getLaunchedFromPackage(IBinder activityToken) { 16126 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16127 if (srec == null) { 16128 return null; 16129 } 16130 return srec.launchedFromPackage; 16131 } 16132 16133 // ========================================================= 16134 // LIFETIME MANAGEMENT 16135 // ========================================================= 16136 16137 // Returns which broadcast queue the app is the current [or imminent] receiver 16138 // on, or 'null' if the app is not an active broadcast recipient. 16139 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16140 BroadcastRecord r = app.curReceiver; 16141 if (r != null) { 16142 return r.queue; 16143 } 16144 16145 // It's not the current receiver, but it might be starting up to become one 16146 synchronized (this) { 16147 for (BroadcastQueue queue : mBroadcastQueues) { 16148 r = queue.mPendingBroadcast; 16149 if (r != null && r.curApp == app) { 16150 // found it; report which queue it's in 16151 return queue; 16152 } 16153 } 16154 } 16155 16156 return null; 16157 } 16158 16159 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16160 boolean doingAll, long now) { 16161 if (mAdjSeq == app.adjSeq) { 16162 // This adjustment has already been computed. 16163 return app.curRawAdj; 16164 } 16165 16166 if (app.thread == null) { 16167 app.adjSeq = mAdjSeq; 16168 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16169 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16170 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16171 } 16172 16173 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16174 app.adjSource = null; 16175 app.adjTarget = null; 16176 app.empty = false; 16177 app.cached = false; 16178 16179 final int activitiesSize = app.activities.size(); 16180 16181 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16182 // The max adjustment doesn't allow this app to be anything 16183 // below foreground, so it is not worth doing work for it. 16184 app.adjType = "fixed"; 16185 app.adjSeq = mAdjSeq; 16186 app.curRawAdj = app.maxAdj; 16187 app.foregroundActivities = false; 16188 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16189 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16190 // System processes can do UI, and when they do we want to have 16191 // them trim their memory after the user leaves the UI. To 16192 // facilitate this, here we need to determine whether or not it 16193 // is currently showing UI. 16194 app.systemNoUi = true; 16195 if (app == TOP_APP) { 16196 app.systemNoUi = false; 16197 } else if (activitiesSize > 0) { 16198 for (int j = 0; j < activitiesSize; j++) { 16199 final ActivityRecord r = app.activities.get(j); 16200 if (r.visible) { 16201 app.systemNoUi = false; 16202 } 16203 } 16204 } 16205 if (!app.systemNoUi) { 16206 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16207 } 16208 return (app.curAdj=app.maxAdj); 16209 } 16210 16211 app.systemNoUi = false; 16212 16213 // Determine the importance of the process, starting with most 16214 // important to least, and assign an appropriate OOM adjustment. 16215 int adj; 16216 int schedGroup; 16217 int procState; 16218 boolean foregroundActivities = false; 16219 BroadcastQueue queue; 16220 if (app == TOP_APP) { 16221 // The last app on the list is the foreground app. 16222 adj = ProcessList.FOREGROUND_APP_ADJ; 16223 schedGroup = Process.THREAD_GROUP_DEFAULT; 16224 app.adjType = "top-activity"; 16225 foregroundActivities = true; 16226 procState = ActivityManager.PROCESS_STATE_TOP; 16227 } else if (app.instrumentationClass != null) { 16228 // Don't want to kill running instrumentation. 16229 adj = ProcessList.FOREGROUND_APP_ADJ; 16230 schedGroup = Process.THREAD_GROUP_DEFAULT; 16231 app.adjType = "instrumentation"; 16232 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16233 } else if ((queue = isReceivingBroadcast(app)) != null) { 16234 // An app that is currently receiving a broadcast also 16235 // counts as being in the foreground for OOM killer purposes. 16236 // It's placed in a sched group based on the nature of the 16237 // broadcast as reflected by which queue it's active in. 16238 adj = ProcessList.FOREGROUND_APP_ADJ; 16239 schedGroup = (queue == mFgBroadcastQueue) 16240 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16241 app.adjType = "broadcast"; 16242 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16243 } else if (app.executingServices.size() > 0) { 16244 // An app that is currently executing a service callback also 16245 // counts as being in the foreground. 16246 adj = ProcessList.FOREGROUND_APP_ADJ; 16247 schedGroup = app.execServicesFg ? 16248 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16249 app.adjType = "exec-service"; 16250 procState = ActivityManager.PROCESS_STATE_SERVICE; 16251 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16252 } else { 16253 // As far as we know the process is empty. We may change our mind later. 16254 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16255 // At this point we don't actually know the adjustment. Use the cached adj 16256 // value that the caller wants us to. 16257 adj = cachedAdj; 16258 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16259 app.cached = true; 16260 app.empty = true; 16261 app.adjType = "cch-empty"; 16262 } 16263 16264 // Examine all activities if not already foreground. 16265 if (!foregroundActivities && activitiesSize > 0) { 16266 for (int j = 0; j < activitiesSize; j++) { 16267 final ActivityRecord r = app.activities.get(j); 16268 if (r.app != app) { 16269 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16270 + app + "?!?"); 16271 continue; 16272 } 16273 if (r.visible) { 16274 // App has a visible activity; only upgrade adjustment. 16275 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16276 adj = ProcessList.VISIBLE_APP_ADJ; 16277 app.adjType = "visible"; 16278 } 16279 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16280 procState = ActivityManager.PROCESS_STATE_TOP; 16281 } 16282 schedGroup = Process.THREAD_GROUP_DEFAULT; 16283 app.cached = false; 16284 app.empty = false; 16285 foregroundActivities = true; 16286 break; 16287 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16288 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16289 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16290 app.adjType = "pausing"; 16291 } 16292 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16293 procState = ActivityManager.PROCESS_STATE_TOP; 16294 } 16295 schedGroup = Process.THREAD_GROUP_DEFAULT; 16296 app.cached = false; 16297 app.empty = false; 16298 foregroundActivities = true; 16299 } else if (r.state == ActivityState.STOPPING) { 16300 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16301 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16302 app.adjType = "stopping"; 16303 } 16304 // For the process state, we will at this point consider the 16305 // process to be cached. It will be cached either as an activity 16306 // or empty depending on whether the activity is finishing. We do 16307 // this so that we can treat the process as cached for purposes of 16308 // memory trimming (determing current memory level, trim command to 16309 // send to process) since there can be an arbitrary number of stopping 16310 // processes and they should soon all go into the cached state. 16311 if (!r.finishing) { 16312 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16313 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16314 } 16315 } 16316 app.cached = false; 16317 app.empty = false; 16318 foregroundActivities = true; 16319 } else { 16320 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16321 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16322 app.adjType = "cch-act"; 16323 } 16324 } 16325 } 16326 } 16327 16328 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16329 if (app.foregroundServices) { 16330 // The user is aware of this app, so make it visible. 16331 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16332 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16333 app.cached = false; 16334 app.adjType = "fg-service"; 16335 schedGroup = Process.THREAD_GROUP_DEFAULT; 16336 } else if (app.forcingToForeground != null) { 16337 // The user is aware of this app, so make it visible. 16338 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16339 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16340 app.cached = false; 16341 app.adjType = "force-fg"; 16342 app.adjSource = app.forcingToForeground; 16343 schedGroup = Process.THREAD_GROUP_DEFAULT; 16344 } 16345 } 16346 16347 if (app == mHeavyWeightProcess) { 16348 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16349 // We don't want to kill the current heavy-weight process. 16350 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16351 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16352 app.cached = false; 16353 app.adjType = "heavy"; 16354 } 16355 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16356 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16357 } 16358 } 16359 16360 if (app == mHomeProcess) { 16361 if (adj > ProcessList.HOME_APP_ADJ) { 16362 // This process is hosting what we currently consider to be the 16363 // home app, so we don't want to let it go into the background. 16364 adj = ProcessList.HOME_APP_ADJ; 16365 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16366 app.cached = false; 16367 app.adjType = "home"; 16368 } 16369 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16370 procState = ActivityManager.PROCESS_STATE_HOME; 16371 } 16372 } 16373 16374 if (app == mPreviousProcess && app.activities.size() > 0) { 16375 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16376 // This was the previous process that showed UI to the user. 16377 // We want to try to keep it around more aggressively, to give 16378 // a good experience around switching between two apps. 16379 adj = ProcessList.PREVIOUS_APP_ADJ; 16380 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16381 app.cached = false; 16382 app.adjType = "previous"; 16383 } 16384 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16385 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16386 } 16387 } 16388 16389 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16390 + " reason=" + app.adjType); 16391 16392 // By default, we use the computed adjustment. It may be changed if 16393 // there are applications dependent on our services or providers, but 16394 // this gives us a baseline and makes sure we don't get into an 16395 // infinite recursion. 16396 app.adjSeq = mAdjSeq; 16397 app.curRawAdj = adj; 16398 app.hasStartedServices = false; 16399 16400 if (mBackupTarget != null && app == mBackupTarget.app) { 16401 // If possible we want to avoid killing apps while they're being backed up 16402 if (adj > ProcessList.BACKUP_APP_ADJ) { 16403 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16404 adj = ProcessList.BACKUP_APP_ADJ; 16405 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16406 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16407 } 16408 app.adjType = "backup"; 16409 app.cached = false; 16410 } 16411 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16412 procState = ActivityManager.PROCESS_STATE_BACKUP; 16413 } 16414 } 16415 16416 boolean mayBeTop = false; 16417 16418 for (int is = app.services.size()-1; 16419 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16420 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16421 || procState > ActivityManager.PROCESS_STATE_TOP); 16422 is--) { 16423 ServiceRecord s = app.services.valueAt(is); 16424 if (s.startRequested) { 16425 app.hasStartedServices = true; 16426 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16427 procState = ActivityManager.PROCESS_STATE_SERVICE; 16428 } 16429 if (app.hasShownUi && app != mHomeProcess) { 16430 // If this process has shown some UI, let it immediately 16431 // go to the LRU list because it may be pretty heavy with 16432 // UI stuff. We'll tag it with a label just to help 16433 // debug and understand what is going on. 16434 if (adj > ProcessList.SERVICE_ADJ) { 16435 app.adjType = "cch-started-ui-services"; 16436 } 16437 } else { 16438 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16439 // This service has seen some activity within 16440 // recent memory, so we will keep its process ahead 16441 // of the background processes. 16442 if (adj > ProcessList.SERVICE_ADJ) { 16443 adj = ProcessList.SERVICE_ADJ; 16444 app.adjType = "started-services"; 16445 app.cached = false; 16446 } 16447 } 16448 // If we have let the service slide into the background 16449 // state, still have some text describing what it is doing 16450 // even though the service no longer has an impact. 16451 if (adj > ProcessList.SERVICE_ADJ) { 16452 app.adjType = "cch-started-services"; 16453 } 16454 } 16455 } 16456 for (int conni = s.connections.size()-1; 16457 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16458 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16459 || procState > ActivityManager.PROCESS_STATE_TOP); 16460 conni--) { 16461 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16462 for (int i = 0; 16463 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16464 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16465 || procState > ActivityManager.PROCESS_STATE_TOP); 16466 i++) { 16467 // XXX should compute this based on the max of 16468 // all connected clients. 16469 ConnectionRecord cr = clist.get(i); 16470 if (cr.binding.client == app) { 16471 // Binding to ourself is not interesting. 16472 continue; 16473 } 16474 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16475 ProcessRecord client = cr.binding.client; 16476 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16477 TOP_APP, doingAll, now); 16478 int clientProcState = client.curProcState; 16479 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16480 // If the other app is cached for any reason, for purposes here 16481 // we are going to consider it empty. The specific cached state 16482 // doesn't propagate except under certain conditions. 16483 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16484 } 16485 String adjType = null; 16486 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16487 // Not doing bind OOM management, so treat 16488 // this guy more like a started service. 16489 if (app.hasShownUi && app != mHomeProcess) { 16490 // If this process has shown some UI, let it immediately 16491 // go to the LRU list because it may be pretty heavy with 16492 // UI stuff. We'll tag it with a label just to help 16493 // debug and understand what is going on. 16494 if (adj > clientAdj) { 16495 adjType = "cch-bound-ui-services"; 16496 } 16497 app.cached = false; 16498 clientAdj = adj; 16499 clientProcState = procState; 16500 } else { 16501 if (now >= (s.lastActivity 16502 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16503 // This service has not seen activity within 16504 // recent memory, so allow it to drop to the 16505 // LRU list if there is no other reason to keep 16506 // it around. We'll also tag it with a label just 16507 // to help debug and undertand what is going on. 16508 if (adj > clientAdj) { 16509 adjType = "cch-bound-services"; 16510 } 16511 clientAdj = adj; 16512 } 16513 } 16514 } 16515 if (adj > clientAdj) { 16516 // If this process has recently shown UI, and 16517 // the process that is binding to it is less 16518 // important than being visible, then we don't 16519 // care about the binding as much as we care 16520 // about letting this process get into the LRU 16521 // list to be killed and restarted if needed for 16522 // memory. 16523 if (app.hasShownUi && app != mHomeProcess 16524 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16525 adjType = "cch-bound-ui-services"; 16526 } else { 16527 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16528 |Context.BIND_IMPORTANT)) != 0) { 16529 adj = clientAdj; 16530 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16531 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16532 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16533 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16534 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16535 adj = clientAdj; 16536 } else { 16537 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16538 adj = ProcessList.VISIBLE_APP_ADJ; 16539 } 16540 } 16541 if (!client.cached) { 16542 app.cached = false; 16543 } 16544 adjType = "service"; 16545 } 16546 } 16547 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16548 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16549 schedGroup = Process.THREAD_GROUP_DEFAULT; 16550 } 16551 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16552 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16553 // Special handling of clients who are in the top state. 16554 // We *may* want to consider this process to be in the 16555 // top state as well, but only if there is not another 16556 // reason for it to be running. Being on the top is a 16557 // special state, meaning you are specifically running 16558 // for the current top app. If the process is already 16559 // running in the background for some other reason, it 16560 // is more important to continue considering it to be 16561 // in the background state. 16562 mayBeTop = true; 16563 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16564 } else { 16565 // Special handling for above-top states (persistent 16566 // processes). These should not bring the current process 16567 // into the top state, since they are not on top. Instead 16568 // give them the best state after that. 16569 clientProcState = 16570 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16571 } 16572 } 16573 } else { 16574 if (clientProcState < 16575 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16576 clientProcState = 16577 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16578 } 16579 } 16580 if (procState > clientProcState) { 16581 procState = clientProcState; 16582 } 16583 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16584 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16585 app.pendingUiClean = true; 16586 } 16587 if (adjType != null) { 16588 app.adjType = adjType; 16589 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16590 .REASON_SERVICE_IN_USE; 16591 app.adjSource = cr.binding.client; 16592 app.adjSourceProcState = clientProcState; 16593 app.adjTarget = s.name; 16594 } 16595 } 16596 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16597 app.treatLikeActivity = true; 16598 } 16599 final ActivityRecord a = cr.activity; 16600 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16601 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16602 (a.visible || a.state == ActivityState.RESUMED 16603 || a.state == ActivityState.PAUSING)) { 16604 adj = ProcessList.FOREGROUND_APP_ADJ; 16605 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16606 schedGroup = Process.THREAD_GROUP_DEFAULT; 16607 } 16608 app.cached = false; 16609 app.adjType = "service"; 16610 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16611 .REASON_SERVICE_IN_USE; 16612 app.adjSource = a; 16613 app.adjSourceProcState = procState; 16614 app.adjTarget = s.name; 16615 } 16616 } 16617 } 16618 } 16619 } 16620 16621 for (int provi = app.pubProviders.size()-1; 16622 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16623 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16624 || procState > ActivityManager.PROCESS_STATE_TOP); 16625 provi--) { 16626 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16627 for (int i = cpr.connections.size()-1; 16628 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16629 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16630 || procState > ActivityManager.PROCESS_STATE_TOP); 16631 i--) { 16632 ContentProviderConnection conn = cpr.connections.get(i); 16633 ProcessRecord client = conn.client; 16634 if (client == app) { 16635 // Being our own client is not interesting. 16636 continue; 16637 } 16638 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16639 int clientProcState = client.curProcState; 16640 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16641 // If the other app is cached for any reason, for purposes here 16642 // we are going to consider it empty. 16643 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16644 } 16645 if (adj > clientAdj) { 16646 if (app.hasShownUi && app != mHomeProcess 16647 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16648 app.adjType = "cch-ui-provider"; 16649 } else { 16650 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16651 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16652 app.adjType = "provider"; 16653 } 16654 app.cached &= client.cached; 16655 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16656 .REASON_PROVIDER_IN_USE; 16657 app.adjSource = client; 16658 app.adjSourceProcState = clientProcState; 16659 app.adjTarget = cpr.name; 16660 } 16661 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16662 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16663 // Special handling of clients who are in the top state. 16664 // We *may* want to consider this process to be in the 16665 // top state as well, but only if there is not another 16666 // reason for it to be running. Being on the top is a 16667 // special state, meaning you are specifically running 16668 // for the current top app. If the process is already 16669 // running in the background for some other reason, it 16670 // is more important to continue considering it to be 16671 // in the background state. 16672 mayBeTop = true; 16673 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16674 } else { 16675 // Special handling for above-top states (persistent 16676 // processes). These should not bring the current process 16677 // into the top state, since they are not on top. Instead 16678 // give them the best state after that. 16679 clientProcState = 16680 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16681 } 16682 } 16683 if (procState > clientProcState) { 16684 procState = clientProcState; 16685 } 16686 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16687 schedGroup = Process.THREAD_GROUP_DEFAULT; 16688 } 16689 } 16690 // If the provider has external (non-framework) process 16691 // dependencies, ensure that its adjustment is at least 16692 // FOREGROUND_APP_ADJ. 16693 if (cpr.hasExternalProcessHandles()) { 16694 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16695 adj = ProcessList.FOREGROUND_APP_ADJ; 16696 schedGroup = Process.THREAD_GROUP_DEFAULT; 16697 app.cached = false; 16698 app.adjType = "provider"; 16699 app.adjTarget = cpr.name; 16700 } 16701 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16702 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16703 } 16704 } 16705 } 16706 16707 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16708 // A client of one of our services or providers is in the top state. We 16709 // *may* want to be in the top state, but not if we are already running in 16710 // the background for some other reason. For the decision here, we are going 16711 // to pick out a few specific states that we want to remain in when a client 16712 // is top (states that tend to be longer-term) and otherwise allow it to go 16713 // to the top state. 16714 switch (procState) { 16715 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16716 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16717 case ActivityManager.PROCESS_STATE_SERVICE: 16718 // These all are longer-term states, so pull them up to the top 16719 // of the background states, but not all the way to the top state. 16720 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16721 break; 16722 default: 16723 // Otherwise, top is a better choice, so take it. 16724 procState = ActivityManager.PROCESS_STATE_TOP; 16725 break; 16726 } 16727 } 16728 16729 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16730 if (app.hasClientActivities) { 16731 // This is a cached process, but with client activities. Mark it so. 16732 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16733 app.adjType = "cch-client-act"; 16734 } else if (app.treatLikeActivity) { 16735 // This is a cached process, but somebody wants us to treat it like it has 16736 // an activity, okay! 16737 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16738 app.adjType = "cch-as-act"; 16739 } 16740 } 16741 16742 if (adj == ProcessList.SERVICE_ADJ) { 16743 if (doingAll) { 16744 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16745 mNewNumServiceProcs++; 16746 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16747 if (!app.serviceb) { 16748 // This service isn't far enough down on the LRU list to 16749 // normally be a B service, but if we are low on RAM and it 16750 // is large we want to force it down since we would prefer to 16751 // keep launcher over it. 16752 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16753 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16754 app.serviceHighRam = true; 16755 app.serviceb = true; 16756 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16757 } else { 16758 mNewNumAServiceProcs++; 16759 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16760 } 16761 } else { 16762 app.serviceHighRam = false; 16763 } 16764 } 16765 if (app.serviceb) { 16766 adj = ProcessList.SERVICE_B_ADJ; 16767 } 16768 } 16769 16770 app.curRawAdj = adj; 16771 16772 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16773 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16774 if (adj > app.maxAdj) { 16775 adj = app.maxAdj; 16776 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16777 schedGroup = Process.THREAD_GROUP_DEFAULT; 16778 } 16779 } 16780 16781 // Do final modification to adj. Everything we do between here and applying 16782 // the final setAdj must be done in this function, because we will also use 16783 // it when computing the final cached adj later. Note that we don't need to 16784 // worry about this for max adj above, since max adj will always be used to 16785 // keep it out of the cached vaues. 16786 app.curAdj = app.modifyRawOomAdj(adj); 16787 app.curSchedGroup = schedGroup; 16788 app.curProcState = procState; 16789 app.foregroundActivities = foregroundActivities; 16790 16791 return app.curRawAdj; 16792 } 16793 16794 /** 16795 * Schedule PSS collection of a process. 16796 */ 16797 void requestPssLocked(ProcessRecord proc, int procState) { 16798 if (mPendingPssProcesses.contains(proc)) { 16799 return; 16800 } 16801 if (mPendingPssProcesses.size() == 0) { 16802 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16803 } 16804 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16805 proc.pssProcState = procState; 16806 mPendingPssProcesses.add(proc); 16807 } 16808 16809 /** 16810 * Schedule PSS collection of all processes. 16811 */ 16812 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16813 if (!always) { 16814 if (now < (mLastFullPssTime + 16815 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16816 return; 16817 } 16818 } 16819 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16820 mLastFullPssTime = now; 16821 mFullPssPending = true; 16822 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16823 mPendingPssProcesses.clear(); 16824 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16825 ProcessRecord app = mLruProcesses.get(i); 16826 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16827 app.pssProcState = app.setProcState; 16828 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16829 isSleeping(), now); 16830 mPendingPssProcesses.add(app); 16831 } 16832 } 16833 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16834 } 16835 16836 /** 16837 * Ask a given process to GC right now. 16838 */ 16839 final void performAppGcLocked(ProcessRecord app) { 16840 try { 16841 app.lastRequestedGc = SystemClock.uptimeMillis(); 16842 if (app.thread != null) { 16843 if (app.reportLowMemory) { 16844 app.reportLowMemory = false; 16845 app.thread.scheduleLowMemory(); 16846 } else { 16847 app.thread.processInBackground(); 16848 } 16849 } 16850 } catch (Exception e) { 16851 // whatever. 16852 } 16853 } 16854 16855 /** 16856 * Returns true if things are idle enough to perform GCs. 16857 */ 16858 private final boolean canGcNowLocked() { 16859 boolean processingBroadcasts = false; 16860 for (BroadcastQueue q : mBroadcastQueues) { 16861 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16862 processingBroadcasts = true; 16863 } 16864 } 16865 return !processingBroadcasts 16866 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16867 } 16868 16869 /** 16870 * Perform GCs on all processes that are waiting for it, but only 16871 * if things are idle. 16872 */ 16873 final void performAppGcsLocked() { 16874 final int N = mProcessesToGc.size(); 16875 if (N <= 0) { 16876 return; 16877 } 16878 if (canGcNowLocked()) { 16879 while (mProcessesToGc.size() > 0) { 16880 ProcessRecord proc = mProcessesToGc.remove(0); 16881 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16882 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16883 <= SystemClock.uptimeMillis()) { 16884 // To avoid spamming the system, we will GC processes one 16885 // at a time, waiting a few seconds between each. 16886 performAppGcLocked(proc); 16887 scheduleAppGcsLocked(); 16888 return; 16889 } else { 16890 // It hasn't been long enough since we last GCed this 16891 // process... put it in the list to wait for its time. 16892 addProcessToGcListLocked(proc); 16893 break; 16894 } 16895 } 16896 } 16897 16898 scheduleAppGcsLocked(); 16899 } 16900 } 16901 16902 /** 16903 * If all looks good, perform GCs on all processes waiting for them. 16904 */ 16905 final void performAppGcsIfAppropriateLocked() { 16906 if (canGcNowLocked()) { 16907 performAppGcsLocked(); 16908 return; 16909 } 16910 // Still not idle, wait some more. 16911 scheduleAppGcsLocked(); 16912 } 16913 16914 /** 16915 * Schedule the execution of all pending app GCs. 16916 */ 16917 final void scheduleAppGcsLocked() { 16918 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16919 16920 if (mProcessesToGc.size() > 0) { 16921 // Schedule a GC for the time to the next process. 16922 ProcessRecord proc = mProcessesToGc.get(0); 16923 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16924 16925 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16926 long now = SystemClock.uptimeMillis(); 16927 if (when < (now+GC_TIMEOUT)) { 16928 when = now + GC_TIMEOUT; 16929 } 16930 mHandler.sendMessageAtTime(msg, when); 16931 } 16932 } 16933 16934 /** 16935 * Add a process to the array of processes waiting to be GCed. Keeps the 16936 * list in sorted order by the last GC time. The process can't already be 16937 * on the list. 16938 */ 16939 final void addProcessToGcListLocked(ProcessRecord proc) { 16940 boolean added = false; 16941 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16942 if (mProcessesToGc.get(i).lastRequestedGc < 16943 proc.lastRequestedGc) { 16944 added = true; 16945 mProcessesToGc.add(i+1, proc); 16946 break; 16947 } 16948 } 16949 if (!added) { 16950 mProcessesToGc.add(0, proc); 16951 } 16952 } 16953 16954 /** 16955 * Set up to ask a process to GC itself. This will either do it 16956 * immediately, or put it on the list of processes to gc the next 16957 * time things are idle. 16958 */ 16959 final void scheduleAppGcLocked(ProcessRecord app) { 16960 long now = SystemClock.uptimeMillis(); 16961 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16962 return; 16963 } 16964 if (!mProcessesToGc.contains(app)) { 16965 addProcessToGcListLocked(app); 16966 scheduleAppGcsLocked(); 16967 } 16968 } 16969 16970 final void checkExcessivePowerUsageLocked(boolean doKills) { 16971 updateCpuStatsNow(); 16972 16973 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16974 boolean doWakeKills = doKills; 16975 boolean doCpuKills = doKills; 16976 if (mLastPowerCheckRealtime == 0) { 16977 doWakeKills = false; 16978 } 16979 if (mLastPowerCheckUptime == 0) { 16980 doCpuKills = false; 16981 } 16982 if (stats.isScreenOn()) { 16983 doWakeKills = false; 16984 } 16985 final long curRealtime = SystemClock.elapsedRealtime(); 16986 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16987 final long curUptime = SystemClock.uptimeMillis(); 16988 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16989 mLastPowerCheckRealtime = curRealtime; 16990 mLastPowerCheckUptime = curUptime; 16991 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16992 doWakeKills = false; 16993 } 16994 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16995 doCpuKills = false; 16996 } 16997 int i = mLruProcesses.size(); 16998 while (i > 0) { 16999 i--; 17000 ProcessRecord app = mLruProcesses.get(i); 17001 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17002 long wtime; 17003 synchronized (stats) { 17004 wtime = stats.getProcessWakeTime(app.info.uid, 17005 app.pid, curRealtime); 17006 } 17007 long wtimeUsed = wtime - app.lastWakeTime; 17008 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 17009 if (DEBUG_POWER) { 17010 StringBuilder sb = new StringBuilder(128); 17011 sb.append("Wake for "); 17012 app.toShortString(sb); 17013 sb.append(": over "); 17014 TimeUtils.formatDuration(realtimeSince, sb); 17015 sb.append(" used "); 17016 TimeUtils.formatDuration(wtimeUsed, sb); 17017 sb.append(" ("); 17018 sb.append((wtimeUsed*100)/realtimeSince); 17019 sb.append("%)"); 17020 Slog.i(TAG, sb.toString()); 17021 sb.setLength(0); 17022 sb.append("CPU for "); 17023 app.toShortString(sb); 17024 sb.append(": over "); 17025 TimeUtils.formatDuration(uptimeSince, sb); 17026 sb.append(" used "); 17027 TimeUtils.formatDuration(cputimeUsed, sb); 17028 sb.append(" ("); 17029 sb.append((cputimeUsed*100)/uptimeSince); 17030 sb.append("%)"); 17031 Slog.i(TAG, sb.toString()); 17032 } 17033 // If a process has held a wake lock for more 17034 // than 50% of the time during this period, 17035 // that sounds bad. Kill! 17036 if (doWakeKills && realtimeSince > 0 17037 && ((wtimeUsed*100)/realtimeSince) >= 50) { 17038 synchronized (stats) { 17039 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 17040 realtimeSince, wtimeUsed); 17041 } 17042 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 17043 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17044 } else if (doCpuKills && uptimeSince > 0 17045 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17046 synchronized (stats) { 17047 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17048 uptimeSince, cputimeUsed); 17049 } 17050 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17051 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17052 } else { 17053 app.lastWakeTime = wtime; 17054 app.lastCpuTime = app.curCpuTime; 17055 } 17056 } 17057 } 17058 } 17059 17060 private final boolean applyOomAdjLocked(ProcessRecord app, 17061 ProcessRecord TOP_APP, boolean doingAll, long now) { 17062 boolean success = true; 17063 17064 if (app.curRawAdj != app.setRawAdj) { 17065 app.setRawAdj = app.curRawAdj; 17066 } 17067 17068 int changes = 0; 17069 17070 if (app.curAdj != app.setAdj) { 17071 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17072 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17073 TAG, "Set " + app.pid + " " + app.processName + 17074 " adj " + app.curAdj + ": " + app.adjType); 17075 app.setAdj = app.curAdj; 17076 } 17077 17078 if (app.setSchedGroup != app.curSchedGroup) { 17079 app.setSchedGroup = app.curSchedGroup; 17080 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17081 "Setting process group of " + app.processName 17082 + " to " + app.curSchedGroup); 17083 if (app.waitingToKill != null && 17084 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17085 app.kill(app.waitingToKill, true); 17086 success = false; 17087 } else { 17088 if (true) { 17089 long oldId = Binder.clearCallingIdentity(); 17090 try { 17091 Process.setProcessGroup(app.pid, app.curSchedGroup); 17092 } catch (Exception e) { 17093 Slog.w(TAG, "Failed setting process group of " + app.pid 17094 + " to " + app.curSchedGroup); 17095 e.printStackTrace(); 17096 } finally { 17097 Binder.restoreCallingIdentity(oldId); 17098 } 17099 } else { 17100 if (app.thread != null) { 17101 try { 17102 app.thread.setSchedulingGroup(app.curSchedGroup); 17103 } catch (RemoteException e) { 17104 } 17105 } 17106 } 17107 Process.setSwappiness(app.pid, 17108 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17109 } 17110 } 17111 if (app.repForegroundActivities != app.foregroundActivities) { 17112 app.repForegroundActivities = app.foregroundActivities; 17113 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17114 } 17115 if (app.repProcState != app.curProcState) { 17116 app.repProcState = app.curProcState; 17117 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17118 if (app.thread != null) { 17119 try { 17120 if (false) { 17121 //RuntimeException h = new RuntimeException("here"); 17122 Slog.i(TAG, "Sending new process state " + app.repProcState 17123 + " to " + app /*, h*/); 17124 } 17125 app.thread.setProcessState(app.repProcState); 17126 } catch (RemoteException e) { 17127 } 17128 } 17129 } 17130 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17131 app.setProcState)) { 17132 app.lastStateTime = now; 17133 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17134 isSleeping(), now); 17135 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17136 + ProcessList.makeProcStateString(app.setProcState) + " to " 17137 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17138 + (app.nextPssTime-now) + ": " + app); 17139 } else { 17140 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17141 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17142 requestPssLocked(app, app.setProcState); 17143 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17144 isSleeping(), now); 17145 } else if (false && DEBUG_PSS) { 17146 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17147 } 17148 } 17149 if (app.setProcState != app.curProcState) { 17150 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17151 "Proc state change of " + app.processName 17152 + " to " + app.curProcState); 17153 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17154 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17155 if (setImportant && !curImportant) { 17156 // This app is no longer something we consider important enough to allow to 17157 // use arbitrary amounts of battery power. Note 17158 // its current wake lock time to later know to kill it if 17159 // it is not behaving well. 17160 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17161 synchronized (stats) { 17162 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17163 app.pid, SystemClock.elapsedRealtime()); 17164 } 17165 app.lastCpuTime = app.curCpuTime; 17166 17167 } 17168 app.setProcState = app.curProcState; 17169 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17170 app.notCachedSinceIdle = false; 17171 } 17172 if (!doingAll) { 17173 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17174 } else { 17175 app.procStateChanged = true; 17176 } 17177 } 17178 17179 if (changes != 0) { 17180 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17181 int i = mPendingProcessChanges.size()-1; 17182 ProcessChangeItem item = null; 17183 while (i >= 0) { 17184 item = mPendingProcessChanges.get(i); 17185 if (item.pid == app.pid) { 17186 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17187 break; 17188 } 17189 i--; 17190 } 17191 if (i < 0) { 17192 // No existing item in pending changes; need a new one. 17193 final int NA = mAvailProcessChanges.size(); 17194 if (NA > 0) { 17195 item = mAvailProcessChanges.remove(NA-1); 17196 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17197 } else { 17198 item = new ProcessChangeItem(); 17199 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17200 } 17201 item.changes = 0; 17202 item.pid = app.pid; 17203 item.uid = app.info.uid; 17204 if (mPendingProcessChanges.size() == 0) { 17205 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17206 "*** Enqueueing dispatch processes changed!"); 17207 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17208 } 17209 mPendingProcessChanges.add(item); 17210 } 17211 item.changes |= changes; 17212 item.processState = app.repProcState; 17213 item.foregroundActivities = app.repForegroundActivities; 17214 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17215 + Integer.toHexString(System.identityHashCode(item)) 17216 + " " + app.toShortString() + ": changes=" + item.changes 17217 + " procState=" + item.processState 17218 + " foreground=" + item.foregroundActivities 17219 + " type=" + app.adjType + " source=" + app.adjSource 17220 + " target=" + app.adjTarget); 17221 } 17222 17223 return success; 17224 } 17225 17226 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17227 if (proc.thread != null) { 17228 if (proc.baseProcessTracker != null) { 17229 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17230 } 17231 if (proc.repProcState >= 0) { 17232 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17233 proc.repProcState); 17234 } 17235 } 17236 } 17237 17238 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17239 ProcessRecord TOP_APP, boolean doingAll, long now) { 17240 if (app.thread == null) { 17241 return false; 17242 } 17243 17244 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17245 17246 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17247 } 17248 17249 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17250 boolean oomAdj) { 17251 if (isForeground != proc.foregroundServices) { 17252 proc.foregroundServices = isForeground; 17253 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17254 proc.info.uid); 17255 if (isForeground) { 17256 if (curProcs == null) { 17257 curProcs = new ArrayList<ProcessRecord>(); 17258 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17259 } 17260 if (!curProcs.contains(proc)) { 17261 curProcs.add(proc); 17262 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17263 proc.info.packageName, proc.info.uid); 17264 } 17265 } else { 17266 if (curProcs != null) { 17267 if (curProcs.remove(proc)) { 17268 mBatteryStatsService.noteEvent( 17269 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17270 proc.info.packageName, proc.info.uid); 17271 if (curProcs.size() <= 0) { 17272 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17273 } 17274 } 17275 } 17276 } 17277 if (oomAdj) { 17278 updateOomAdjLocked(); 17279 } 17280 } 17281 } 17282 17283 private final ActivityRecord resumedAppLocked() { 17284 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17285 String pkg; 17286 int uid; 17287 if (act != null) { 17288 pkg = act.packageName; 17289 uid = act.info.applicationInfo.uid; 17290 } else { 17291 pkg = null; 17292 uid = -1; 17293 } 17294 // Has the UID or resumed package name changed? 17295 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17296 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17297 if (mCurResumedPackage != null) { 17298 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17299 mCurResumedPackage, mCurResumedUid); 17300 } 17301 mCurResumedPackage = pkg; 17302 mCurResumedUid = uid; 17303 if (mCurResumedPackage != null) { 17304 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17305 mCurResumedPackage, mCurResumedUid); 17306 } 17307 } 17308 return act; 17309 } 17310 17311 final boolean updateOomAdjLocked(ProcessRecord app) { 17312 final ActivityRecord TOP_ACT = resumedAppLocked(); 17313 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17314 final boolean wasCached = app.cached; 17315 17316 mAdjSeq++; 17317 17318 // This is the desired cached adjusment we want to tell it to use. 17319 // If our app is currently cached, we know it, and that is it. Otherwise, 17320 // we don't know it yet, and it needs to now be cached we will then 17321 // need to do a complete oom adj. 17322 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17323 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17324 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17325 SystemClock.uptimeMillis()); 17326 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17327 // Changed to/from cached state, so apps after it in the LRU 17328 // list may also be changed. 17329 updateOomAdjLocked(); 17330 } 17331 return success; 17332 } 17333 17334 final void updateOomAdjLocked() { 17335 final ActivityRecord TOP_ACT = resumedAppLocked(); 17336 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17337 final long now = SystemClock.uptimeMillis(); 17338 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17339 final int N = mLruProcesses.size(); 17340 17341 if (false) { 17342 RuntimeException e = new RuntimeException(); 17343 e.fillInStackTrace(); 17344 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17345 } 17346 17347 mAdjSeq++; 17348 mNewNumServiceProcs = 0; 17349 mNewNumAServiceProcs = 0; 17350 17351 final int emptyProcessLimit; 17352 final int cachedProcessLimit; 17353 if (mProcessLimit <= 0) { 17354 emptyProcessLimit = cachedProcessLimit = 0; 17355 } else if (mProcessLimit == 1) { 17356 emptyProcessLimit = 1; 17357 cachedProcessLimit = 0; 17358 } else { 17359 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17360 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17361 } 17362 17363 // Let's determine how many processes we have running vs. 17364 // how many slots we have for background processes; we may want 17365 // to put multiple processes in a slot of there are enough of 17366 // them. 17367 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17368 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17369 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17370 if (numEmptyProcs > cachedProcessLimit) { 17371 // If there are more empty processes than our limit on cached 17372 // processes, then use the cached process limit for the factor. 17373 // This ensures that the really old empty processes get pushed 17374 // down to the bottom, so if we are running low on memory we will 17375 // have a better chance at keeping around more cached processes 17376 // instead of a gazillion empty processes. 17377 numEmptyProcs = cachedProcessLimit; 17378 } 17379 int emptyFactor = numEmptyProcs/numSlots; 17380 if (emptyFactor < 1) emptyFactor = 1; 17381 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17382 if (cachedFactor < 1) cachedFactor = 1; 17383 int stepCached = 0; 17384 int stepEmpty = 0; 17385 int numCached = 0; 17386 int numEmpty = 0; 17387 int numTrimming = 0; 17388 17389 mNumNonCachedProcs = 0; 17390 mNumCachedHiddenProcs = 0; 17391 17392 // First update the OOM adjustment for each of the 17393 // application processes based on their current state. 17394 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17395 int nextCachedAdj = curCachedAdj+1; 17396 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17397 int nextEmptyAdj = curEmptyAdj+2; 17398 for (int i=N-1; i>=0; i--) { 17399 ProcessRecord app = mLruProcesses.get(i); 17400 if (!app.killedByAm && app.thread != null) { 17401 app.procStateChanged = false; 17402 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17403 17404 // If we haven't yet assigned the final cached adj 17405 // to the process, do that now. 17406 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17407 switch (app.curProcState) { 17408 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17409 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17410 // This process is a cached process holding activities... 17411 // assign it the next cached value for that type, and then 17412 // step that cached level. 17413 app.curRawAdj = curCachedAdj; 17414 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17415 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17416 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17417 + ")"); 17418 if (curCachedAdj != nextCachedAdj) { 17419 stepCached++; 17420 if (stepCached >= cachedFactor) { 17421 stepCached = 0; 17422 curCachedAdj = nextCachedAdj; 17423 nextCachedAdj += 2; 17424 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17425 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17426 } 17427 } 17428 } 17429 break; 17430 default: 17431 // For everything else, assign next empty cached process 17432 // level and bump that up. Note that this means that 17433 // long-running services that have dropped down to the 17434 // cached level will be treated as empty (since their process 17435 // state is still as a service), which is what we want. 17436 app.curRawAdj = curEmptyAdj; 17437 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17438 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17439 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17440 + ")"); 17441 if (curEmptyAdj != nextEmptyAdj) { 17442 stepEmpty++; 17443 if (stepEmpty >= emptyFactor) { 17444 stepEmpty = 0; 17445 curEmptyAdj = nextEmptyAdj; 17446 nextEmptyAdj += 2; 17447 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17448 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17449 } 17450 } 17451 } 17452 break; 17453 } 17454 } 17455 17456 applyOomAdjLocked(app, TOP_APP, true, now); 17457 17458 // Count the number of process types. 17459 switch (app.curProcState) { 17460 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17461 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17462 mNumCachedHiddenProcs++; 17463 numCached++; 17464 if (numCached > cachedProcessLimit) { 17465 app.kill("cached #" + numCached, true); 17466 } 17467 break; 17468 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17469 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17470 && app.lastActivityTime < oldTime) { 17471 app.kill("empty for " 17472 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17473 / 1000) + "s", true); 17474 } else { 17475 numEmpty++; 17476 if (numEmpty > emptyProcessLimit) { 17477 app.kill("empty #" + numEmpty, true); 17478 } 17479 } 17480 break; 17481 default: 17482 mNumNonCachedProcs++; 17483 break; 17484 } 17485 17486 if (app.isolated && app.services.size() <= 0) { 17487 // If this is an isolated process, and there are no 17488 // services running in it, then the process is no longer 17489 // needed. We agressively kill these because we can by 17490 // definition not re-use the same process again, and it is 17491 // good to avoid having whatever code was running in them 17492 // left sitting around after no longer needed. 17493 app.kill("isolated not needed", true); 17494 } 17495 17496 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17497 && !app.killedByAm) { 17498 numTrimming++; 17499 } 17500 } 17501 } 17502 17503 mNumServiceProcs = mNewNumServiceProcs; 17504 17505 // Now determine the memory trimming level of background processes. 17506 // Unfortunately we need to start at the back of the list to do this 17507 // properly. We only do this if the number of background apps we 17508 // are managing to keep around is less than half the maximum we desire; 17509 // if we are keeping a good number around, we'll let them use whatever 17510 // memory they want. 17511 final int numCachedAndEmpty = numCached + numEmpty; 17512 int memFactor; 17513 if (numCached <= ProcessList.TRIM_CACHED_APPS 17514 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17515 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17516 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17517 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17518 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17519 } else { 17520 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17521 } 17522 } else { 17523 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17524 } 17525 // We always allow the memory level to go up (better). We only allow it to go 17526 // down if we are in a state where that is allowed, *and* the total number of processes 17527 // has gone down since last time. 17528 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17529 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17530 + " last=" + mLastNumProcesses); 17531 if (memFactor > mLastMemoryLevel) { 17532 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17533 memFactor = mLastMemoryLevel; 17534 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17535 } 17536 } 17537 mLastMemoryLevel = memFactor; 17538 mLastNumProcesses = mLruProcesses.size(); 17539 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17540 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17541 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17542 if (mLowRamStartTime == 0) { 17543 mLowRamStartTime = now; 17544 } 17545 int step = 0; 17546 int fgTrimLevel; 17547 switch (memFactor) { 17548 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17549 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17550 break; 17551 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17552 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17553 break; 17554 default: 17555 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17556 break; 17557 } 17558 int factor = numTrimming/3; 17559 int minFactor = 2; 17560 if (mHomeProcess != null) minFactor++; 17561 if (mPreviousProcess != null) minFactor++; 17562 if (factor < minFactor) factor = minFactor; 17563 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17564 for (int i=N-1; i>=0; i--) { 17565 ProcessRecord app = mLruProcesses.get(i); 17566 if (allChanged || app.procStateChanged) { 17567 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17568 app.procStateChanged = false; 17569 } 17570 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17571 && !app.killedByAm) { 17572 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17573 try { 17574 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17575 "Trimming memory of " + app.processName 17576 + " to " + curLevel); 17577 app.thread.scheduleTrimMemory(curLevel); 17578 } catch (RemoteException e) { 17579 } 17580 if (false) { 17581 // For now we won't do this; our memory trimming seems 17582 // to be good enough at this point that destroying 17583 // activities causes more harm than good. 17584 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17585 && app != mHomeProcess && app != mPreviousProcess) { 17586 // Need to do this on its own message because the stack may not 17587 // be in a consistent state at this point. 17588 // For these apps we will also finish their activities 17589 // to help them free memory. 17590 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17591 } 17592 } 17593 } 17594 app.trimMemoryLevel = curLevel; 17595 step++; 17596 if (step >= factor) { 17597 step = 0; 17598 switch (curLevel) { 17599 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17600 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17601 break; 17602 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17603 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17604 break; 17605 } 17606 } 17607 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17608 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17609 && app.thread != null) { 17610 try { 17611 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17612 "Trimming memory of heavy-weight " + app.processName 17613 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17614 app.thread.scheduleTrimMemory( 17615 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17616 } catch (RemoteException e) { 17617 } 17618 } 17619 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17620 } else { 17621 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17622 || app.systemNoUi) && app.pendingUiClean) { 17623 // If this application is now in the background and it 17624 // had done UI, then give it the special trim level to 17625 // have it free UI resources. 17626 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17627 if (app.trimMemoryLevel < level && app.thread != null) { 17628 try { 17629 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17630 "Trimming memory of bg-ui " + app.processName 17631 + " to " + level); 17632 app.thread.scheduleTrimMemory(level); 17633 } catch (RemoteException e) { 17634 } 17635 } 17636 app.pendingUiClean = false; 17637 } 17638 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17639 try { 17640 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17641 "Trimming memory of fg " + app.processName 17642 + " to " + fgTrimLevel); 17643 app.thread.scheduleTrimMemory(fgTrimLevel); 17644 } catch (RemoteException e) { 17645 } 17646 } 17647 app.trimMemoryLevel = fgTrimLevel; 17648 } 17649 } 17650 } else { 17651 if (mLowRamStartTime != 0) { 17652 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17653 mLowRamStartTime = 0; 17654 } 17655 for (int i=N-1; i>=0; i--) { 17656 ProcessRecord app = mLruProcesses.get(i); 17657 if (allChanged || app.procStateChanged) { 17658 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17659 app.procStateChanged = false; 17660 } 17661 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17662 || app.systemNoUi) && app.pendingUiClean) { 17663 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17664 && app.thread != null) { 17665 try { 17666 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17667 "Trimming memory of ui hidden " + app.processName 17668 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17669 app.thread.scheduleTrimMemory( 17670 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17671 } catch (RemoteException e) { 17672 } 17673 } 17674 app.pendingUiClean = false; 17675 } 17676 app.trimMemoryLevel = 0; 17677 } 17678 } 17679 17680 if (mAlwaysFinishActivities) { 17681 // Need to do this on its own message because the stack may not 17682 // be in a consistent state at this point. 17683 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17684 } 17685 17686 if (allChanged) { 17687 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17688 } 17689 17690 if (mProcessStats.shouldWriteNowLocked(now)) { 17691 mHandler.post(new Runnable() { 17692 @Override public void run() { 17693 synchronized (ActivityManagerService.this) { 17694 mProcessStats.writeStateAsyncLocked(); 17695 } 17696 } 17697 }); 17698 } 17699 17700 if (DEBUG_OOM_ADJ) { 17701 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17702 } 17703 } 17704 17705 final void trimApplications() { 17706 synchronized (this) { 17707 int i; 17708 17709 // First remove any unused application processes whose package 17710 // has been removed. 17711 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17712 final ProcessRecord app = mRemovedProcesses.get(i); 17713 if (app.activities.size() == 0 17714 && app.curReceiver == null && app.services.size() == 0) { 17715 Slog.i( 17716 TAG, "Exiting empty application process " 17717 + app.processName + " (" 17718 + (app.thread != null ? app.thread.asBinder() : null) 17719 + ")\n"); 17720 if (app.pid > 0 && app.pid != MY_PID) { 17721 app.kill("empty", false); 17722 } else { 17723 try { 17724 app.thread.scheduleExit(); 17725 } catch (Exception e) { 17726 // Ignore exceptions. 17727 } 17728 } 17729 cleanUpApplicationRecordLocked(app, false, true, -1); 17730 mRemovedProcesses.remove(i); 17731 17732 if (app.persistent) { 17733 addAppLocked(app.info, false, null /* ABI override */); 17734 } 17735 } 17736 } 17737 17738 // Now update the oom adj for all processes. 17739 updateOomAdjLocked(); 17740 } 17741 } 17742 17743 /** This method sends the specified signal to each of the persistent apps */ 17744 public void signalPersistentProcesses(int sig) throws RemoteException { 17745 if (sig != Process.SIGNAL_USR1) { 17746 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17747 } 17748 17749 synchronized (this) { 17750 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17751 != PackageManager.PERMISSION_GRANTED) { 17752 throw new SecurityException("Requires permission " 17753 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17754 } 17755 17756 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17757 ProcessRecord r = mLruProcesses.get(i); 17758 if (r.thread != null && r.persistent) { 17759 Process.sendSignal(r.pid, sig); 17760 } 17761 } 17762 } 17763 } 17764 17765 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17766 if (proc == null || proc == mProfileProc) { 17767 proc = mProfileProc; 17768 profileType = mProfileType; 17769 clearProfilerLocked(); 17770 } 17771 if (proc == null) { 17772 return; 17773 } 17774 try { 17775 proc.thread.profilerControl(false, null, profileType); 17776 } catch (RemoteException e) { 17777 throw new IllegalStateException("Process disappeared"); 17778 } 17779 } 17780 17781 private void clearProfilerLocked() { 17782 if (mProfileFd != null) { 17783 try { 17784 mProfileFd.close(); 17785 } catch (IOException e) { 17786 } 17787 } 17788 mProfileApp = null; 17789 mProfileProc = null; 17790 mProfileFile = null; 17791 mProfileType = 0; 17792 mAutoStopProfiler = false; 17793 mSamplingInterval = 0; 17794 } 17795 17796 public boolean profileControl(String process, int userId, boolean start, 17797 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17798 17799 try { 17800 synchronized (this) { 17801 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17802 // its own permission. 17803 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17804 != PackageManager.PERMISSION_GRANTED) { 17805 throw new SecurityException("Requires permission " 17806 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17807 } 17808 17809 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17810 throw new IllegalArgumentException("null profile info or fd"); 17811 } 17812 17813 ProcessRecord proc = null; 17814 if (process != null) { 17815 proc = findProcessLocked(process, userId, "profileControl"); 17816 } 17817 17818 if (start && (proc == null || proc.thread == null)) { 17819 throw new IllegalArgumentException("Unknown process: " + process); 17820 } 17821 17822 if (start) { 17823 stopProfilerLocked(null, 0); 17824 setProfileApp(proc.info, proc.processName, profilerInfo); 17825 mProfileProc = proc; 17826 mProfileType = profileType; 17827 ParcelFileDescriptor fd = profilerInfo.profileFd; 17828 try { 17829 fd = fd.dup(); 17830 } catch (IOException e) { 17831 fd = null; 17832 } 17833 profilerInfo.profileFd = fd; 17834 proc.thread.profilerControl(start, profilerInfo, profileType); 17835 fd = null; 17836 mProfileFd = null; 17837 } else { 17838 stopProfilerLocked(proc, profileType); 17839 if (profilerInfo != null && profilerInfo.profileFd != null) { 17840 try { 17841 profilerInfo.profileFd.close(); 17842 } catch (IOException e) { 17843 } 17844 } 17845 } 17846 17847 return true; 17848 } 17849 } catch (RemoteException e) { 17850 throw new IllegalStateException("Process disappeared"); 17851 } finally { 17852 if (profilerInfo != null && profilerInfo.profileFd != null) { 17853 try { 17854 profilerInfo.profileFd.close(); 17855 } catch (IOException e) { 17856 } 17857 } 17858 } 17859 } 17860 17861 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17862 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17863 userId, true, ALLOW_FULL_ONLY, callName, null); 17864 ProcessRecord proc = null; 17865 try { 17866 int pid = Integer.parseInt(process); 17867 synchronized (mPidsSelfLocked) { 17868 proc = mPidsSelfLocked.get(pid); 17869 } 17870 } catch (NumberFormatException e) { 17871 } 17872 17873 if (proc == null) { 17874 ArrayMap<String, SparseArray<ProcessRecord>> all 17875 = mProcessNames.getMap(); 17876 SparseArray<ProcessRecord> procs = all.get(process); 17877 if (procs != null && procs.size() > 0) { 17878 proc = procs.valueAt(0); 17879 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17880 for (int i=1; i<procs.size(); i++) { 17881 ProcessRecord thisProc = procs.valueAt(i); 17882 if (thisProc.userId == userId) { 17883 proc = thisProc; 17884 break; 17885 } 17886 } 17887 } 17888 } 17889 } 17890 17891 return proc; 17892 } 17893 17894 public boolean dumpHeap(String process, int userId, boolean managed, 17895 String path, ParcelFileDescriptor fd) throws RemoteException { 17896 17897 try { 17898 synchronized (this) { 17899 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17900 // its own permission (same as profileControl). 17901 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17902 != PackageManager.PERMISSION_GRANTED) { 17903 throw new SecurityException("Requires permission " 17904 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17905 } 17906 17907 if (fd == null) { 17908 throw new IllegalArgumentException("null fd"); 17909 } 17910 17911 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17912 if (proc == null || proc.thread == null) { 17913 throw new IllegalArgumentException("Unknown process: " + process); 17914 } 17915 17916 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17917 if (!isDebuggable) { 17918 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17919 throw new SecurityException("Process not debuggable: " + proc); 17920 } 17921 } 17922 17923 proc.thread.dumpHeap(managed, path, fd); 17924 fd = null; 17925 return true; 17926 } 17927 } catch (RemoteException e) { 17928 throw new IllegalStateException("Process disappeared"); 17929 } finally { 17930 if (fd != null) { 17931 try { 17932 fd.close(); 17933 } catch (IOException e) { 17934 } 17935 } 17936 } 17937 } 17938 17939 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17940 public void monitor() { 17941 synchronized (this) { } 17942 } 17943 17944 void onCoreSettingsChange(Bundle settings) { 17945 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17946 ProcessRecord processRecord = mLruProcesses.get(i); 17947 try { 17948 if (processRecord.thread != null) { 17949 processRecord.thread.setCoreSettings(settings); 17950 } 17951 } catch (RemoteException re) { 17952 /* ignore */ 17953 } 17954 } 17955 } 17956 17957 // Multi-user methods 17958 17959 /** 17960 * Start user, if its not already running, but don't bring it to foreground. 17961 */ 17962 @Override 17963 public boolean startUserInBackground(final int userId) { 17964 return startUser(userId, /* foreground */ false); 17965 } 17966 17967 /** 17968 * Start user, if its not already running, and bring it to foreground. 17969 */ 17970 boolean startUserInForeground(final int userId, Dialog dlg) { 17971 boolean result = startUser(userId, /* foreground */ true); 17972 dlg.dismiss(); 17973 return result; 17974 } 17975 17976 /** 17977 * Refreshes the list of users related to the current user when either a 17978 * user switch happens or when a new related user is started in the 17979 * background. 17980 */ 17981 private void updateCurrentProfileIdsLocked() { 17982 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17983 mCurrentUserId, false /* enabledOnly */); 17984 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17985 for (int i = 0; i < currentProfileIds.length; i++) { 17986 currentProfileIds[i] = profiles.get(i).id; 17987 } 17988 mCurrentProfileIds = currentProfileIds; 17989 17990 synchronized (mUserProfileGroupIdsSelfLocked) { 17991 mUserProfileGroupIdsSelfLocked.clear(); 17992 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17993 for (int i = 0; i < users.size(); i++) { 17994 UserInfo user = users.get(i); 17995 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17996 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17997 } 17998 } 17999 } 18000 } 18001 18002 private Set getProfileIdsLocked(int userId) { 18003 Set userIds = new HashSet<Integer>(); 18004 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18005 userId, false /* enabledOnly */); 18006 for (UserInfo user : profiles) { 18007 userIds.add(Integer.valueOf(user.id)); 18008 } 18009 return userIds; 18010 } 18011 18012 @Override 18013 public boolean switchUser(final int userId) { 18014 String userName; 18015 synchronized (this) { 18016 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18017 if (userInfo == null) { 18018 Slog.w(TAG, "No user info for user #" + userId); 18019 return false; 18020 } 18021 if (userInfo.isManagedProfile()) { 18022 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18023 return false; 18024 } 18025 userName = userInfo.name; 18026 mTargetUserId = userId; 18027 } 18028 mHandler.removeMessages(START_USER_SWITCH_MSG); 18029 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 18030 return true; 18031 } 18032 18033 private void showUserSwitchDialog(int userId, String userName) { 18034 // The dialog will show and then initiate the user switch by calling startUserInForeground 18035 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 18036 true /* above system */); 18037 d.show(); 18038 } 18039 18040 private boolean startUser(final int userId, final boolean foreground) { 18041 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18042 != PackageManager.PERMISSION_GRANTED) { 18043 String msg = "Permission Denial: switchUser() from pid=" 18044 + Binder.getCallingPid() 18045 + ", uid=" + Binder.getCallingUid() 18046 + " requires " + INTERACT_ACROSS_USERS_FULL; 18047 Slog.w(TAG, msg); 18048 throw new SecurityException(msg); 18049 } 18050 18051 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18052 18053 final long ident = Binder.clearCallingIdentity(); 18054 try { 18055 synchronized (this) { 18056 final int oldUserId = mCurrentUserId; 18057 if (oldUserId == userId) { 18058 return true; 18059 } 18060 18061 mStackSupervisor.setLockTaskModeLocked(null, false); 18062 18063 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18064 if (userInfo == null) { 18065 Slog.w(TAG, "No user info for user #" + userId); 18066 return false; 18067 } 18068 if (foreground && userInfo.isManagedProfile()) { 18069 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18070 return false; 18071 } 18072 18073 if (foreground) { 18074 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18075 R.anim.screen_user_enter); 18076 } 18077 18078 boolean needStart = false; 18079 18080 // If the user we are switching to is not currently started, then 18081 // we need to start it now. 18082 if (mStartedUsers.get(userId) == null) { 18083 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18084 updateStartedUserArrayLocked(); 18085 needStart = true; 18086 } 18087 18088 final Integer userIdInt = Integer.valueOf(userId); 18089 mUserLru.remove(userIdInt); 18090 mUserLru.add(userIdInt); 18091 18092 if (foreground) { 18093 mCurrentUserId = userId; 18094 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18095 updateCurrentProfileIdsLocked(); 18096 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18097 // Once the internal notion of the active user has switched, we lock the device 18098 // with the option to show the user switcher on the keyguard. 18099 mWindowManager.lockNow(null); 18100 } else { 18101 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18102 updateCurrentProfileIdsLocked(); 18103 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18104 mUserLru.remove(currentUserIdInt); 18105 mUserLru.add(currentUserIdInt); 18106 } 18107 18108 final UserStartedState uss = mStartedUsers.get(userId); 18109 18110 // Make sure user is in the started state. If it is currently 18111 // stopping, we need to knock that off. 18112 if (uss.mState == UserStartedState.STATE_STOPPING) { 18113 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18114 // so we can just fairly silently bring the user back from 18115 // the almost-dead. 18116 uss.mState = UserStartedState.STATE_RUNNING; 18117 updateStartedUserArrayLocked(); 18118 needStart = true; 18119 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18120 // This means ACTION_SHUTDOWN has been sent, so we will 18121 // need to treat this as a new boot of the user. 18122 uss.mState = UserStartedState.STATE_BOOTING; 18123 updateStartedUserArrayLocked(); 18124 needStart = true; 18125 } 18126 18127 if (uss.mState == UserStartedState.STATE_BOOTING) { 18128 // Booting up a new user, need to tell system services about it. 18129 // Note that this is on the same handler as scheduling of broadcasts, 18130 // which is important because it needs to go first. 18131 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18132 } 18133 18134 if (foreground) { 18135 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18136 oldUserId)); 18137 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18138 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18139 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18140 oldUserId, userId, uss)); 18141 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18142 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18143 } 18144 18145 if (needStart) { 18146 // Send USER_STARTED broadcast 18147 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18148 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18149 | Intent.FLAG_RECEIVER_FOREGROUND); 18150 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18151 broadcastIntentLocked(null, null, intent, 18152 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18153 false, false, MY_PID, Process.SYSTEM_UID, userId); 18154 } 18155 18156 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18157 if (userId != UserHandle.USER_OWNER) { 18158 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18159 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18160 broadcastIntentLocked(null, null, intent, null, 18161 new IIntentReceiver.Stub() { 18162 public void performReceive(Intent intent, int resultCode, 18163 String data, Bundle extras, boolean ordered, 18164 boolean sticky, int sendingUser) { 18165 onUserInitialized(uss, foreground, oldUserId, userId); 18166 } 18167 }, 0, null, null, null, AppOpsManager.OP_NONE, 18168 true, false, MY_PID, Process.SYSTEM_UID, 18169 userId); 18170 uss.initializing = true; 18171 } else { 18172 getUserManagerLocked().makeInitialized(userInfo.id); 18173 } 18174 } 18175 18176 if (foreground) { 18177 if (!uss.initializing) { 18178 moveUserToForeground(uss, oldUserId, userId); 18179 } 18180 } else { 18181 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18182 } 18183 18184 if (needStart) { 18185 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18186 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18187 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18188 broadcastIntentLocked(null, null, intent, 18189 null, new IIntentReceiver.Stub() { 18190 @Override 18191 public void performReceive(Intent intent, int resultCode, String data, 18192 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18193 throws RemoteException { 18194 } 18195 }, 0, null, null, 18196 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18197 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18198 } 18199 } 18200 } finally { 18201 Binder.restoreCallingIdentity(ident); 18202 } 18203 18204 return true; 18205 } 18206 18207 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18208 long ident = Binder.clearCallingIdentity(); 18209 try { 18210 Intent intent; 18211 if (oldUserId >= 0) { 18212 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18213 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18214 int count = profiles.size(); 18215 for (int i = 0; i < count; i++) { 18216 int profileUserId = profiles.get(i).id; 18217 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18218 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18219 | Intent.FLAG_RECEIVER_FOREGROUND); 18220 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18221 broadcastIntentLocked(null, null, intent, 18222 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18223 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18224 } 18225 } 18226 if (newUserId >= 0) { 18227 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18228 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18229 int count = profiles.size(); 18230 for (int i = 0; i < count; i++) { 18231 int profileUserId = profiles.get(i).id; 18232 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18233 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18234 | Intent.FLAG_RECEIVER_FOREGROUND); 18235 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18236 broadcastIntentLocked(null, null, intent, 18237 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18238 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18239 } 18240 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18241 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18242 | Intent.FLAG_RECEIVER_FOREGROUND); 18243 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18244 broadcastIntentLocked(null, null, intent, 18245 null, null, 0, null, null, 18246 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18247 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18248 } 18249 } finally { 18250 Binder.restoreCallingIdentity(ident); 18251 } 18252 } 18253 18254 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18255 final int newUserId) { 18256 final int N = mUserSwitchObservers.beginBroadcast(); 18257 if (N > 0) { 18258 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18259 int mCount = 0; 18260 @Override 18261 public void sendResult(Bundle data) throws RemoteException { 18262 synchronized (ActivityManagerService.this) { 18263 if (mCurUserSwitchCallback == this) { 18264 mCount++; 18265 if (mCount == N) { 18266 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18267 } 18268 } 18269 } 18270 } 18271 }; 18272 synchronized (this) { 18273 uss.switching = true; 18274 mCurUserSwitchCallback = callback; 18275 } 18276 for (int i=0; i<N; i++) { 18277 try { 18278 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18279 newUserId, callback); 18280 } catch (RemoteException e) { 18281 } 18282 } 18283 } else { 18284 synchronized (this) { 18285 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18286 } 18287 } 18288 mUserSwitchObservers.finishBroadcast(); 18289 } 18290 18291 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18292 synchronized (this) { 18293 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18294 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18295 } 18296 } 18297 18298 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18299 mCurUserSwitchCallback = null; 18300 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18301 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18302 oldUserId, newUserId, uss)); 18303 } 18304 18305 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18306 synchronized (this) { 18307 if (foreground) { 18308 moveUserToForeground(uss, oldUserId, newUserId); 18309 } 18310 } 18311 18312 completeSwitchAndInitalize(uss, newUserId, true, false); 18313 } 18314 18315 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18316 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18317 if (homeInFront) { 18318 startHomeActivityLocked(newUserId); 18319 } else { 18320 mStackSupervisor.resumeTopActivitiesLocked(); 18321 } 18322 EventLogTags.writeAmSwitchUser(newUserId); 18323 getUserManagerLocked().userForeground(newUserId); 18324 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18325 } 18326 18327 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18328 completeSwitchAndInitalize(uss, newUserId, false, true); 18329 } 18330 18331 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18332 boolean clearInitializing, boolean clearSwitching) { 18333 boolean unfrozen = false; 18334 synchronized (this) { 18335 if (clearInitializing) { 18336 uss.initializing = false; 18337 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18338 } 18339 if (clearSwitching) { 18340 uss.switching = false; 18341 } 18342 if (!uss.switching && !uss.initializing) { 18343 mWindowManager.stopFreezingScreen(); 18344 unfrozen = true; 18345 } 18346 } 18347 if (unfrozen) { 18348 final int N = mUserSwitchObservers.beginBroadcast(); 18349 for (int i=0; i<N; i++) { 18350 try { 18351 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18352 } catch (RemoteException e) { 18353 } 18354 } 18355 mUserSwitchObservers.finishBroadcast(); 18356 } 18357 } 18358 18359 void scheduleStartProfilesLocked() { 18360 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18361 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18362 DateUtils.SECOND_IN_MILLIS); 18363 } 18364 } 18365 18366 void startProfilesLocked() { 18367 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18368 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18369 mCurrentUserId, false /* enabledOnly */); 18370 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18371 for (UserInfo user : profiles) { 18372 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18373 && user.id != mCurrentUserId) { 18374 toStart.add(user); 18375 } 18376 } 18377 final int n = toStart.size(); 18378 int i = 0; 18379 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18380 startUserInBackground(toStart.get(i).id); 18381 } 18382 if (i < n) { 18383 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18384 } 18385 } 18386 18387 void finishUserBoot(UserStartedState uss) { 18388 synchronized (this) { 18389 if (uss.mState == UserStartedState.STATE_BOOTING 18390 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18391 uss.mState = UserStartedState.STATE_RUNNING; 18392 final int userId = uss.mHandle.getIdentifier(); 18393 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18394 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18395 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18396 broadcastIntentLocked(null, null, intent, 18397 null, null, 0, null, null, 18398 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18399 true, false, MY_PID, Process.SYSTEM_UID, userId); 18400 } 18401 } 18402 } 18403 18404 void finishUserSwitch(UserStartedState uss) { 18405 synchronized (this) { 18406 finishUserBoot(uss); 18407 18408 startProfilesLocked(); 18409 18410 int num = mUserLru.size(); 18411 int i = 0; 18412 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18413 Integer oldUserId = mUserLru.get(i); 18414 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18415 if (oldUss == null) { 18416 // Shouldn't happen, but be sane if it does. 18417 mUserLru.remove(i); 18418 num--; 18419 continue; 18420 } 18421 if (oldUss.mState == UserStartedState.STATE_STOPPING 18422 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18423 // This user is already stopping, doesn't count. 18424 num--; 18425 i++; 18426 continue; 18427 } 18428 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18429 // Owner and current can't be stopped, but count as running. 18430 i++; 18431 continue; 18432 } 18433 // This is a user to be stopped. 18434 stopUserLocked(oldUserId, null); 18435 num--; 18436 i++; 18437 } 18438 } 18439 } 18440 18441 @Override 18442 public int stopUser(final int userId, final IStopUserCallback callback) { 18443 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18444 != PackageManager.PERMISSION_GRANTED) { 18445 String msg = "Permission Denial: switchUser() from pid=" 18446 + Binder.getCallingPid() 18447 + ", uid=" + Binder.getCallingUid() 18448 + " requires " + INTERACT_ACROSS_USERS_FULL; 18449 Slog.w(TAG, msg); 18450 throw new SecurityException(msg); 18451 } 18452 if (userId <= 0) { 18453 throw new IllegalArgumentException("Can't stop primary user " + userId); 18454 } 18455 synchronized (this) { 18456 return stopUserLocked(userId, callback); 18457 } 18458 } 18459 18460 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18461 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18462 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18463 return ActivityManager.USER_OP_IS_CURRENT; 18464 } 18465 18466 final UserStartedState uss = mStartedUsers.get(userId); 18467 if (uss == null) { 18468 // User is not started, nothing to do... but we do need to 18469 // callback if requested. 18470 if (callback != null) { 18471 mHandler.post(new Runnable() { 18472 @Override 18473 public void run() { 18474 try { 18475 callback.userStopped(userId); 18476 } catch (RemoteException e) { 18477 } 18478 } 18479 }); 18480 } 18481 return ActivityManager.USER_OP_SUCCESS; 18482 } 18483 18484 if (callback != null) { 18485 uss.mStopCallbacks.add(callback); 18486 } 18487 18488 if (uss.mState != UserStartedState.STATE_STOPPING 18489 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18490 uss.mState = UserStartedState.STATE_STOPPING; 18491 updateStartedUserArrayLocked(); 18492 18493 long ident = Binder.clearCallingIdentity(); 18494 try { 18495 // We are going to broadcast ACTION_USER_STOPPING and then 18496 // once that is done send a final ACTION_SHUTDOWN and then 18497 // stop the user. 18498 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18499 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18500 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18501 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18502 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18503 // This is the result receiver for the final shutdown broadcast. 18504 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18505 @Override 18506 public void performReceive(Intent intent, int resultCode, String data, 18507 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18508 finishUserStop(uss); 18509 } 18510 }; 18511 // This is the result receiver for the initial stopping broadcast. 18512 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18513 @Override 18514 public void performReceive(Intent intent, int resultCode, String data, 18515 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18516 // On to the next. 18517 synchronized (ActivityManagerService.this) { 18518 if (uss.mState != UserStartedState.STATE_STOPPING) { 18519 // Whoops, we are being started back up. Abort, abort! 18520 return; 18521 } 18522 uss.mState = UserStartedState.STATE_SHUTDOWN; 18523 } 18524 mBatteryStatsService.noteEvent( 18525 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18526 Integer.toString(userId), userId); 18527 mSystemServiceManager.stopUser(userId); 18528 broadcastIntentLocked(null, null, shutdownIntent, 18529 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18530 true, false, MY_PID, Process.SYSTEM_UID, userId); 18531 } 18532 }; 18533 // Kick things off. 18534 broadcastIntentLocked(null, null, stoppingIntent, 18535 null, stoppingReceiver, 0, null, null, 18536 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18537 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18538 } finally { 18539 Binder.restoreCallingIdentity(ident); 18540 } 18541 } 18542 18543 return ActivityManager.USER_OP_SUCCESS; 18544 } 18545 18546 void finishUserStop(UserStartedState uss) { 18547 final int userId = uss.mHandle.getIdentifier(); 18548 boolean stopped; 18549 ArrayList<IStopUserCallback> callbacks; 18550 synchronized (this) { 18551 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18552 if (mStartedUsers.get(userId) != uss) { 18553 stopped = false; 18554 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18555 stopped = false; 18556 } else { 18557 stopped = true; 18558 // User can no longer run. 18559 mStartedUsers.remove(userId); 18560 mUserLru.remove(Integer.valueOf(userId)); 18561 updateStartedUserArrayLocked(); 18562 18563 // Clean up all state and processes associated with the user. 18564 // Kill all the processes for the user. 18565 forceStopUserLocked(userId, "finish user"); 18566 } 18567 18568 // Explicitly remove the old information in mRecentTasks. 18569 removeRecentTasksForUserLocked(userId); 18570 } 18571 18572 for (int i=0; i<callbacks.size(); i++) { 18573 try { 18574 if (stopped) callbacks.get(i).userStopped(userId); 18575 else callbacks.get(i).userStopAborted(userId); 18576 } catch (RemoteException e) { 18577 } 18578 } 18579 18580 if (stopped) { 18581 mSystemServiceManager.cleanupUser(userId); 18582 synchronized (this) { 18583 mStackSupervisor.removeUserLocked(userId); 18584 } 18585 } 18586 } 18587 18588 @Override 18589 public UserInfo getCurrentUser() { 18590 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18591 != PackageManager.PERMISSION_GRANTED) && ( 18592 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18593 != PackageManager.PERMISSION_GRANTED)) { 18594 String msg = "Permission Denial: getCurrentUser() from pid=" 18595 + Binder.getCallingPid() 18596 + ", uid=" + Binder.getCallingUid() 18597 + " requires " + INTERACT_ACROSS_USERS; 18598 Slog.w(TAG, msg); 18599 throw new SecurityException(msg); 18600 } 18601 synchronized (this) { 18602 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18603 return getUserManagerLocked().getUserInfo(userId); 18604 } 18605 } 18606 18607 int getCurrentUserIdLocked() { 18608 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18609 } 18610 18611 @Override 18612 public boolean isUserRunning(int userId, boolean orStopped) { 18613 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18614 != PackageManager.PERMISSION_GRANTED) { 18615 String msg = "Permission Denial: isUserRunning() from pid=" 18616 + Binder.getCallingPid() 18617 + ", uid=" + Binder.getCallingUid() 18618 + " requires " + INTERACT_ACROSS_USERS; 18619 Slog.w(TAG, msg); 18620 throw new SecurityException(msg); 18621 } 18622 synchronized (this) { 18623 return isUserRunningLocked(userId, orStopped); 18624 } 18625 } 18626 18627 boolean isUserRunningLocked(int userId, boolean orStopped) { 18628 UserStartedState state = mStartedUsers.get(userId); 18629 if (state == null) { 18630 return false; 18631 } 18632 if (orStopped) { 18633 return true; 18634 } 18635 return state.mState != UserStartedState.STATE_STOPPING 18636 && state.mState != UserStartedState.STATE_SHUTDOWN; 18637 } 18638 18639 @Override 18640 public int[] getRunningUserIds() { 18641 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18642 != PackageManager.PERMISSION_GRANTED) { 18643 String msg = "Permission Denial: isUserRunning() from pid=" 18644 + Binder.getCallingPid() 18645 + ", uid=" + Binder.getCallingUid() 18646 + " requires " + INTERACT_ACROSS_USERS; 18647 Slog.w(TAG, msg); 18648 throw new SecurityException(msg); 18649 } 18650 synchronized (this) { 18651 return mStartedUserArray; 18652 } 18653 } 18654 18655 private void updateStartedUserArrayLocked() { 18656 int num = 0; 18657 for (int i=0; i<mStartedUsers.size(); i++) { 18658 UserStartedState uss = mStartedUsers.valueAt(i); 18659 // This list does not include stopping users. 18660 if (uss.mState != UserStartedState.STATE_STOPPING 18661 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18662 num++; 18663 } 18664 } 18665 mStartedUserArray = new int[num]; 18666 num = 0; 18667 for (int i=0; i<mStartedUsers.size(); i++) { 18668 UserStartedState uss = mStartedUsers.valueAt(i); 18669 if (uss.mState != UserStartedState.STATE_STOPPING 18670 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18671 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18672 num++; 18673 } 18674 } 18675 } 18676 18677 @Override 18678 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18679 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18680 != PackageManager.PERMISSION_GRANTED) { 18681 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18682 + Binder.getCallingPid() 18683 + ", uid=" + Binder.getCallingUid() 18684 + " requires " + INTERACT_ACROSS_USERS_FULL; 18685 Slog.w(TAG, msg); 18686 throw new SecurityException(msg); 18687 } 18688 18689 mUserSwitchObservers.register(observer); 18690 } 18691 18692 @Override 18693 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18694 mUserSwitchObservers.unregister(observer); 18695 } 18696 18697 private boolean userExists(int userId) { 18698 if (userId == 0) { 18699 return true; 18700 } 18701 UserManagerService ums = getUserManagerLocked(); 18702 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18703 } 18704 18705 int[] getUsersLocked() { 18706 UserManagerService ums = getUserManagerLocked(); 18707 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18708 } 18709 18710 UserManagerService getUserManagerLocked() { 18711 if (mUserManager == null) { 18712 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18713 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18714 } 18715 return mUserManager; 18716 } 18717 18718 private int applyUserId(int uid, int userId) { 18719 return UserHandle.getUid(userId, uid); 18720 } 18721 18722 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18723 if (info == null) return null; 18724 ApplicationInfo newInfo = new ApplicationInfo(info); 18725 newInfo.uid = applyUserId(info.uid, userId); 18726 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18727 + info.packageName; 18728 return newInfo; 18729 } 18730 18731 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18732 if (aInfo == null 18733 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18734 return aInfo; 18735 } 18736 18737 ActivityInfo info = new ActivityInfo(aInfo); 18738 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18739 return info; 18740 } 18741 18742 private final class LocalService extends ActivityManagerInternal { 18743 @Override 18744 public void goingToSleep() { 18745 ActivityManagerService.this.goingToSleep(); 18746 } 18747 18748 @Override 18749 public void wakingUp() { 18750 ActivityManagerService.this.wakingUp(); 18751 } 18752 18753 @Override 18754 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18755 String processName, String abiOverride, int uid, Runnable crashHandler) { 18756 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18757 processName, abiOverride, uid, crashHandler); 18758 } 18759 } 18760 18761 /** 18762 * An implementation of IAppTask, that allows an app to manage its own tasks via 18763 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18764 * only the process that calls getAppTasks() can call the AppTask methods. 18765 */ 18766 class AppTaskImpl extends IAppTask.Stub { 18767 private int mTaskId; 18768 private int mCallingUid; 18769 18770 public AppTaskImpl(int taskId, int callingUid) { 18771 mTaskId = taskId; 18772 mCallingUid = callingUid; 18773 } 18774 18775 private void checkCaller() { 18776 if (mCallingUid != Binder.getCallingUid()) { 18777 throw new SecurityException("Caller " + mCallingUid 18778 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18779 } 18780 } 18781 18782 @Override 18783 public void finishAndRemoveTask() { 18784 checkCaller(); 18785 18786 synchronized (ActivityManagerService.this) { 18787 long origId = Binder.clearCallingIdentity(); 18788 try { 18789 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18790 if (tr == null) { 18791 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18792 } 18793 // Only kill the process if we are not a new document 18794 int flags = tr.getBaseIntent().getFlags(); 18795 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18796 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18797 removeTaskByIdLocked(mTaskId, 18798 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18799 } finally { 18800 Binder.restoreCallingIdentity(origId); 18801 } 18802 } 18803 } 18804 18805 @Override 18806 public ActivityManager.RecentTaskInfo getTaskInfo() { 18807 checkCaller(); 18808 18809 synchronized (ActivityManagerService.this) { 18810 long origId = Binder.clearCallingIdentity(); 18811 try { 18812 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18813 if (tr == null) { 18814 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18815 } 18816 return createRecentTaskInfoFromTaskRecord(tr); 18817 } finally { 18818 Binder.restoreCallingIdentity(origId); 18819 } 18820 } 18821 } 18822 18823 @Override 18824 public void moveToFront() { 18825 checkCaller(); 18826 18827 final TaskRecord tr; 18828 synchronized (ActivityManagerService.this) { 18829 tr = recentTaskForIdLocked(mTaskId); 18830 if (tr == null) { 18831 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18832 } 18833 if (tr.getRootActivity() != null) { 18834 long origId = Binder.clearCallingIdentity(); 18835 try { 18836 moveTaskToFrontLocked(tr.taskId, 0, null); 18837 return; 18838 } finally { 18839 Binder.restoreCallingIdentity(origId); 18840 } 18841 } 18842 } 18843 18844 startActivityFromRecentsInner(tr.taskId, null); 18845 } 18846 18847 @Override 18848 public int startActivity(IBinder whoThread, String callingPackage, 18849 Intent intent, String resolvedType, Bundle options) { 18850 checkCaller(); 18851 18852 int callingUser = UserHandle.getCallingUserId(); 18853 TaskRecord tr; 18854 IApplicationThread appThread; 18855 synchronized (ActivityManagerService.this) { 18856 tr = recentTaskForIdLocked(mTaskId); 18857 if (tr == null) { 18858 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18859 } 18860 appThread = ApplicationThreadNative.asInterface(whoThread); 18861 if (appThread == null) { 18862 throw new IllegalArgumentException("Bad app thread " + appThread); 18863 } 18864 } 18865 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18866 resolvedType, null, null, null, null, 0, 0, null, null, 18867 null, options, callingUser, null, tr); 18868 } 18869 18870 @Override 18871 public void setExcludeFromRecents(boolean exclude) { 18872 checkCaller(); 18873 18874 synchronized (ActivityManagerService.this) { 18875 long origId = Binder.clearCallingIdentity(); 18876 try { 18877 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18878 if (tr == null) { 18879 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18880 } 18881 Intent intent = tr.getBaseIntent(); 18882 if (exclude) { 18883 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18884 } else { 18885 intent.setFlags(intent.getFlags() 18886 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18887 } 18888 } finally { 18889 Binder.restoreCallingIdentity(origId); 18890 } 18891 } 18892 } 18893 } 18894} 18895