ActivityManagerService.java revision da0d07be7bc274e06797d6b943483df7b3d6625c
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.CHANGE_CONFIGURATION; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS; 21import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 22import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; 23import static android.Manifest.permission.READ_FRAME_BUFFER; 24import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 25import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; 26import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; 27import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW; 28import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 29import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 30import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 31import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 32import static android.app.ActivityManager.StackId.PINNED_STACK_ID; 33import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; 34import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY; 35import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; 36import static android.content.pm.PackageManager.GET_PROVIDERS; 37import static android.content.pm.PackageManager.MATCH_ANY_USER; 38import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 39import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 40import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 41import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 42import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 43import static android.content.pm.PackageManager.PERMISSION_GRANTED; 44import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION; 45import static android.os.Build.VERSION_CODES.N; 46import static android.os.Process.PROC_CHAR; 47import static android.os.Process.PROC_OUT_LONG; 48import static android.os.Process.PROC_PARENS; 49import static android.os.Process.PROC_SPACE_TERM; 50import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; 51import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; 52import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES; 53import static android.provider.Settings.Global.DEBUG_APP; 54import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; 55import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; 56import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL; 57import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER; 58import static android.provider.Settings.System.FONT_SCALE; 59import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION; 60import static android.view.Display.DEFAULT_DISPLAY; 61import static com.android.internal.util.XmlUtils.readBooleanAttribute; 62import static com.android.internal.util.XmlUtils.readIntAttribute; 63import static com.android.internal.util.XmlUtils.readLongAttribute; 64import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 65import static com.android.internal.util.XmlUtils.writeIntAttribute; 66import static com.android.internal.util.XmlUtils.writeLongAttribute; 67import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 68import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR; 69import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK; 70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP; 71import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST; 72import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND; 73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT; 74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP; 75import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; 76import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS; 77import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE; 78import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; 79import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU; 80import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; 81import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; 82import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; 83import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER; 84import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK; 85import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; 86import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS; 87import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER; 88import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; 89import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS; 90import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE; 91import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; 92import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; 93import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; 94import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; 95import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION; 96import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS; 97import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY; 98import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND; 99import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS; 100import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP; 101import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST; 102import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP; 103import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION; 104import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS; 105import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE; 106import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN; 107import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; 108import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU; 109import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU; 110import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ; 111import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER; 112import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES; 113import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS; 114import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER; 115import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS; 116import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; 117import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE; 118import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; 119import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; 120import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS; 121import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION; 122import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY; 123import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND; 124import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 125import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 126import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS; 127import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED; 128import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME; 129import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS; 130import static com.android.server.am.ActivityStackSupervisor.ON_TOP; 131import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; 132import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; 133import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS; 134import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 135import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; 136import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; 137import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; 138import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; 139import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE; 140import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN; 141import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH; 142import static com.android.server.wm.AppTransition.TRANSIT_NONE; 143import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE; 144import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN; 145import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT; 146import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 147import static org.xmlpull.v1.XmlPullParser.START_TAG; 148 149import static java.lang.Integer.MAX_VALUE; 150 151import android.Manifest; 152import android.Manifest.permission; 153import android.annotation.NonNull; 154import android.annotation.Nullable; 155import android.annotation.UserIdInt; 156import android.app.Activity; 157import android.app.ActivityManager; 158import android.app.ActivityManager.RunningTaskInfo; 159import android.app.ActivityManager.StackId; 160import android.app.ActivityManager.StackInfo; 161import android.app.ActivityManager.TaskSnapshot; 162import android.app.ActivityManager.TaskThumbnailInfo; 163import android.app.ActivityManagerInternal; 164import android.app.ActivityManagerInternal.SleepToken; 165import android.app.ActivityOptions; 166import android.app.ActivityThread; 167import android.app.AlertDialog; 168import android.app.AppGlobals; 169import android.app.AppOpsManager; 170import android.app.ApplicationErrorReport; 171import android.app.ApplicationThreadConstants; 172import android.app.BroadcastOptions; 173import android.app.ContentProviderHolder; 174import android.app.Dialog; 175import android.app.IActivityContainer; 176import android.app.IActivityContainerCallback; 177import android.app.IActivityController; 178import android.app.IActivityManager; 179import android.app.IAppTask; 180import android.app.IApplicationThread; 181import android.app.IInstrumentationWatcher; 182import android.app.INotificationManager; 183import android.app.IProcessObserver; 184import android.app.IServiceConnection; 185import android.app.IStopUserCallback; 186import android.app.ITaskStackListener; 187import android.app.IUiAutomationConnection; 188import android.app.IUidObserver; 189import android.app.IUserSwitchObserver; 190import android.app.Instrumentation; 191import android.app.Notification; 192import android.app.NotificationManager; 193import android.app.PendingIntent; 194import android.app.PictureInPictureArgs; 195import android.app.ProfilerInfo; 196import android.app.RemoteAction; 197import android.app.WaitResult; 198import android.app.admin.DevicePolicyManager; 199import android.app.assist.AssistContent; 200import android.app.assist.AssistStructure; 201import android.app.backup.IBackupManager; 202import android.app.usage.UsageEvents; 203import android.app.usage.UsageStatsManagerInternal; 204import android.appwidget.AppWidgetManager; 205import android.content.ActivityNotFoundException; 206import android.content.BroadcastReceiver; 207import android.content.ClipData; 208import android.content.ComponentCallbacks2; 209import android.content.ComponentName; 210import android.content.ContentProvider; 211import android.content.ContentResolver; 212import android.content.Context; 213import android.content.DialogInterface; 214import android.content.IContentProvider; 215import android.content.IIntentReceiver; 216import android.content.IIntentSender; 217import android.content.Intent; 218import android.content.IntentFilter; 219import android.content.IntentSender; 220import android.content.pm.ActivityInfo; 221import android.content.pm.ApplicationInfo; 222import android.content.pm.ConfigurationInfo; 223import android.content.pm.IPackageDataObserver; 224import android.content.pm.IPackageManager; 225import android.content.pm.InstrumentationInfo; 226import android.content.pm.PackageInfo; 227import android.content.pm.PackageManager; 228import android.content.pm.PackageManager.NameNotFoundException; 229import android.content.pm.PackageManagerInternal; 230import android.content.pm.ParceledListSlice; 231import android.content.pm.PathPermission; 232import android.content.pm.PermissionInfo; 233import android.content.pm.ProviderInfo; 234import android.content.pm.ResolveInfo; 235import android.content.pm.SELinuxUtil; 236import android.content.pm.ServiceInfo; 237import android.content.pm.UserInfo; 238import android.content.res.CompatibilityInfo; 239import android.content.res.Configuration; 240import android.content.res.Resources; 241import android.database.ContentObserver; 242import android.graphics.Bitmap; 243import android.graphics.Point; 244import android.graphics.Rect; 245import android.location.LocationManager; 246import android.media.audiofx.AudioEffect; 247import android.metrics.LogMaker; 248import android.net.Proxy; 249import android.net.ProxyInfo; 250import android.net.Uri; 251import android.os.BatteryStats; 252import android.os.Binder; 253import android.os.Build; 254import android.os.Bundle; 255import android.os.Debug; 256import android.os.DropBoxManager; 257import android.os.Environment; 258import android.os.FactoryTest; 259import android.os.FileObserver; 260import android.os.FileUtils; 261import android.os.Handler; 262import android.os.IBinder; 263import android.os.IDeviceIdentifiersPolicyService; 264import android.os.IPermissionController; 265import android.os.IProcessInfoService; 266import android.os.IProgressListener; 267import android.os.LocaleList; 268import android.os.Looper; 269import android.os.Message; 270import android.os.Parcel; 271import android.os.ParcelFileDescriptor; 272import android.os.PersistableBundle; 273import android.os.PowerManager; 274import android.os.PowerManagerInternal; 275import android.os.Process; 276import android.os.RemoteCallbackList; 277import android.os.RemoteException; 278import android.os.ResultReceiver; 279import android.os.ServiceManager; 280import android.os.ShellCallback; 281import android.os.StrictMode; 282import android.os.SystemClock; 283import android.os.SystemProperties; 284import android.os.Trace; 285import android.os.TransactionTooLargeException; 286import android.os.UpdateLock; 287import android.os.UserHandle; 288import android.os.UserManager; 289import android.os.WorkSource; 290import android.os.storage.IStorageManager; 291import android.os.storage.StorageManager; 292import android.os.storage.StorageManagerInternal; 293import android.provider.Downloads; 294import android.provider.Settings; 295import android.service.voice.IVoiceInteractionSession; 296import android.service.voice.VoiceInteractionManagerInternal; 297import android.service.voice.VoiceInteractionSession; 298import android.telecom.TelecomManager; 299import android.text.TextUtils; 300import android.text.format.DateUtils; 301import android.text.format.Time; 302import android.text.style.SuggestionSpan; 303import android.util.ArrayMap; 304import android.util.ArraySet; 305import android.util.AtomicFile; 306import android.util.BootTimingsTraceLog; 307import android.util.DebugUtils; 308import android.util.DisplayMetrics; 309import android.util.EventLog; 310import android.util.Log; 311import android.util.Pair; 312import android.util.PrintWriterPrinter; 313import android.util.Slog; 314import android.util.SparseArray; 315import android.util.SparseIntArray; 316import android.util.TimeUtils; 317import android.util.Xml; 318import android.view.Gravity; 319import android.view.LayoutInflater; 320import android.view.View; 321import android.view.WindowManager; 322 323import com.android.internal.notification.SystemNotificationChannels; 324import com.google.android.collect.Lists; 325import com.google.android.collect.Maps; 326 327import com.android.internal.R; 328import com.android.internal.annotations.GuardedBy; 329import com.android.internal.annotations.VisibleForTesting; 330import com.android.internal.app.AssistUtils; 331import com.android.internal.app.DumpHeapActivity; 332import com.android.internal.app.IAppOpsCallback; 333import com.android.internal.app.IAppOpsService; 334import com.android.internal.app.IVoiceInteractor; 335import com.android.internal.app.ProcessMap; 336import com.android.internal.app.SystemUserHomeActivity; 337import com.android.internal.app.procstats.ProcessStats; 338import com.android.internal.logging.MetricsLogger; 339import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 340import com.android.internal.os.BackgroundThread; 341import com.android.internal.os.BatteryStatsImpl; 342import com.android.internal.os.IResultReceiver; 343import com.android.internal.os.ProcessCpuTracker; 344import com.android.internal.os.TransferPipe; 345import com.android.internal.os.Zygote; 346import com.android.internal.policy.IKeyguardDismissCallback; 347import com.android.internal.telephony.TelephonyIntents; 348import com.android.internal.util.ArrayUtils; 349import com.android.internal.util.FastPrintWriter; 350import com.android.internal.util.FastXmlSerializer; 351import com.android.internal.util.MemInfoReader; 352import com.android.internal.util.Preconditions; 353import com.android.server.AppOpsService; 354import com.android.server.AttributeCache; 355import com.android.server.DeviceIdleController; 356import com.android.server.IntentResolver; 357import com.android.server.LocalServices; 358import com.android.server.LockGuard; 359import com.android.server.RescueParty; 360import com.android.server.ServiceThread; 361import com.android.server.SystemConfig; 362import com.android.server.SystemService; 363import com.android.server.SystemServiceManager; 364import com.android.server.Watchdog; 365import com.android.server.am.ActivityStack.ActivityState; 366import com.android.server.firewall.IntentFirewall; 367import com.android.server.pm.Installer; 368import com.android.server.pm.Installer.InstallerException; 369import com.android.server.statusbar.StatusBarManagerInternal; 370import com.android.server.vr.VrManagerInternal; 371import com.android.server.wm.WindowManagerService; 372 373import org.xmlpull.v1.XmlPullParser; 374import org.xmlpull.v1.XmlPullParserException; 375import org.xmlpull.v1.XmlSerializer; 376 377import java.io.File; 378import java.io.FileDescriptor; 379import java.io.FileInputStream; 380import java.io.FileNotFoundException; 381import java.io.FileOutputStream; 382import java.io.IOException; 383import java.io.InputStreamReader; 384import java.io.PrintWriter; 385import java.io.StringWriter; 386import java.lang.ref.WeakReference; 387import java.nio.charset.StandardCharsets; 388import java.util.ArrayList; 389import java.util.Arrays; 390import java.util.Collections; 391import java.util.Comparator; 392import java.util.HashMap; 393import java.util.HashSet; 394import java.util.Iterator; 395import java.util.List; 396import java.util.Locale; 397import java.util.Map; 398import java.util.Objects; 399import java.util.Set; 400import java.util.concurrent.CountDownLatch; 401import java.util.concurrent.atomic.AtomicBoolean; 402import java.util.concurrent.atomic.AtomicLong; 403 404import dalvik.system.VMRuntime; 405 406import libcore.io.IoUtils; 407import libcore.util.EmptyArray; 408 409public class ActivityManagerService extends IActivityManager.Stub 410 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 411 412 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM; 413 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP; 414 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST; 415 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP; 416 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; 417 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; 418 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE; 419 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN; 420 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; 421 private static final String TAG_LRU = TAG + POSTFIX_LRU; 422 private static final String TAG_MU = TAG + POSTFIX_MU; 423 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ; 424 private static final String TAG_POWER = TAG + POSTFIX_POWER; 425 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS; 426 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES; 427 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER; 428 private static final String TAG_PSS = TAG + POSTFIX_PSS; 429 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; 430 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE; 431 private static final String TAG_STACK = TAG + POSTFIX_STACK; 432 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; 433 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS; 434 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION; 435 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; 436 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND; 437 438 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared 439 // here so that while the job scheduler can depend on AMS, the other way around 440 // need not be the case. 441 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE"; 442 443 /** Control over CPU and battery monitoring */ 444 // write battery stats every 30 minutes. 445 static final long BATTERY_STATS_TIME = 30 * 60 * 1000; 446 static final boolean MONITOR_CPU_USAGE = true; 447 // don't sample cpu less than every 5 seconds. 448 static final long MONITOR_CPU_MIN_TIME = 5 * 1000; 449 // wait possibly forever for next cpu sample. 450 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; 451 static final boolean MONITOR_THREAD_CPU_USAGE = false; 452 453 // The flags that are set for all calls we make to the package manager. 454 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 455 456 static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 457 458 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 459 460 // Amount of time after a call to stopAppSwitches() during which we will 461 // prevent further untrusted switches from happening. 462 static final long APP_SWITCH_DELAY_TIME = 5*1000; 463 464 // How long we wait for a launched process to attach to the activity manager 465 // before we decide it's never going to come up for real. 466 static final int PROC_START_TIMEOUT = 10*1000; 467 // How long we wait for an attached process to publish its content providers 468 // before we decide it must be hung. 469 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000; 470 471 // How long we will retain processes hosting content providers in the "last activity" 472 // state before allowing them to drop down to the regular cached LRU list. This is 473 // to avoid thrashing of provider processes under low memory situations. 474 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000; 475 476 // How long we wait for a launched process to attach to the activity manager 477 // before we decide it's never going to come up for real, when the process was 478 // started with a wrapper for instrumentation (such as Valgrind) because it 479 // could take much longer than usual. 480 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 481 482 // How long to wait after going idle before forcing apps to GC. 483 static final int GC_TIMEOUT = 5*1000; 484 485 // The minimum amount of time between successive GC requests for a process. 486 static final int GC_MIN_INTERVAL = 60*1000; 487 488 // The minimum amount of time between successive PSS requests for a process. 489 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 490 491 // The minimum amount of time between successive PSS requests for a process 492 // when the request is due to the memory state being lowered. 493 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 494 495 // The rate at which we check for apps using excessive power -- 15 mins. 496 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 497 498 // The minimum sample duration we will allow before deciding we have 499 // enough data on wake locks to start killing things. 500 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 501 502 // The minimum sample duration we will allow before deciding we have 503 // enough data on CPU usage to start killing things. 504 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 505 506 // How long we allow a receiver to run before giving up on it. 507 static final int BROADCAST_FG_TIMEOUT = 10*1000; 508 static final int BROADCAST_BG_TIMEOUT = 60*1000; 509 510 // How long we wait until we timeout on key dispatching. 511 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 512 513 // How long we wait until we timeout on key dispatching during instrumentation. 514 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 515 516 // This is the amount of time an app needs to be running a foreground service before 517 // we will consider it to be doing interaction for usage stats. 518 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000; 519 520 // Maximum amount of time we will allow to elapse before re-reporting usage stats 521 // interaction with foreground processes. 522 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L; 523 524 // This is the amount of time we allow an app to settle after it goes into the background, 525 // before we start restricting what it can do. 526 static final int BACKGROUND_SETTLE_TIME = 1*60*1000; 527 528 // How long to wait in getAssistContextExtras for the activity and foreground services 529 // to respond with the result. 530 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 531 532 // How long top wait when going through the modern assist (which doesn't need to block 533 // on getting this result before starting to launch its UI). 534 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000; 535 536 // How long to wait in getAutoFillAssistStructure() for the activity to respond with the result. 537 static final int PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT = 2000; 538 539 // Maximum number of persisted Uri grants a package is allowed 540 static final int MAX_PERSISTED_URI_GRANTS = 128; 541 542 static final int MY_PID = Process.myPid(); 543 544 static final String[] EMPTY_STRING_ARRAY = new String[0]; 545 546 // How many bytes to write into the dropbox log before truncating 547 static final int DROPBOX_MAX_SIZE = 192 * 1024; 548 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count 549 // as one line, but close enough for now. 550 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100; 551 552 // Access modes for handleIncomingUser. 553 static final int ALLOW_NON_FULL = 0; 554 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 555 static final int ALLOW_FULL_ONLY = 2; 556 557 // Necessary ApplicationInfo flags to mark an app as persistent 558 private static final int PERSISTENT_MASK = 559 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT; 560 561 // Intent sent when remote bugreport collection has been completed 562 private static final String INTENT_REMOTE_BUGREPORT_FINISHED = 563 "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED"; 564 565 // Used to indicate that an app transition should be animated. 566 static final boolean ANIMATE = true; 567 568 // Determines whether to take full screen screenshots 569 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true; 570 571 /** All system services */ 572 SystemServiceManager mSystemServiceManager; 573 AssistUtils mAssistUtils; 574 575 private Installer mInstaller; 576 577 /** Run all ActivityStacks through this */ 578 final ActivityStackSupervisor mStackSupervisor; 579 private final KeyguardController mKeyguardController; 580 581 final ActivityStarter mActivityStarter; 582 583 final TaskChangeNotificationController mTaskChangeNotificationController; 584 585 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter(); 586 587 final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>(); 588 589 public final IntentFirewall mIntentFirewall; 590 591 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 592 // default action automatically. Important for devices without direct input 593 // devices. 594 private boolean mShowDialogs = true; 595 private boolean mInVrMode = false; 596 597 // Whether we should use SCHED_FIFO for UI and RenderThreads. 598 private boolean mUseFifoUiScheduling = false; 599 600 BroadcastQueue mFgBroadcastQueue; 601 BroadcastQueue mBgBroadcastQueue; 602 // Convenient for easy iteration over the queues. Foreground is first 603 // so that dispatch of foreground broadcasts gets precedence. 604 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 605 606 BroadcastStats mLastBroadcastStats; 607 BroadcastStats mCurBroadcastStats; 608 609 BroadcastQueue broadcastQueueForIntent(Intent intent) { 610 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 611 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST, 612 "Broadcast intent " + intent + " on " 613 + (isFg ? "foreground" : "background") + " queue"); 614 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 615 } 616 617 /** 618 * The last resumed activity. This is identical to the current resumed activity most 619 * of the time but could be different when we're pausing one activity before we resume 620 * another activity. 621 */ 622 private ActivityRecord mLastResumedActivity; 623 624 /** 625 * If non-null, we are tracking the time the user spends in the currently focused app. 626 */ 627 private AppTimeTracker mCurAppTimeTracker; 628 629 /** 630 * List of intents that were used to start the most recent tasks. 631 */ 632 final RecentTasks mRecentTasks; 633 634 /** 635 * For addAppTask: cached of the last activity component that was added. 636 */ 637 ComponentName mLastAddedTaskComponent; 638 639 /** 640 * For addAppTask: cached of the last activity uid that was added. 641 */ 642 int mLastAddedTaskUid; 643 644 /** 645 * For addAppTask: cached of the last ActivityInfo that was added. 646 */ 647 ActivityInfo mLastAddedTaskActivity; 648 649 /** 650 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId. 651 */ 652 SparseArray<String[]> mLockTaskPackages = new SparseArray<>(); 653 654 /** 655 * The package name of the DeviceOwner. This package is not permitted to have its data cleared. 656 */ 657 String mDeviceOwnerName; 658 659 final UserController mUserController; 660 661 final AppErrors mAppErrors; 662 663 public boolean canShowErrorDialogs() { 664 return mShowDialogs && !mSleeping && !mShuttingDown 665 && !mKeyguardController.isKeyguardShowing(); 666 } 667 668 private static final class PriorityState { 669 // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock 670 // the current thread is currently in. When it drops down to zero, we will no longer boost 671 // the thread's priority. 672 private int regionCounter = 0; 673 674 // The thread's previous priority before boosting. 675 private int prevPriority = Integer.MIN_VALUE; 676 } 677 678 static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() { 679 @Override protected PriorityState initialValue() { 680 return new PriorityState(); 681 } 682 }; 683 684 static void boostPriorityForLockedSection() { 685 int tid = Process.myTid(); 686 int prevPriority = Process.getThreadPriority(tid); 687 PriorityState state = sThreadPriorityState.get(); 688 if (state.regionCounter == 0 && prevPriority > -2) { 689 state.prevPriority = prevPriority; 690 Process.setThreadPriority(tid, -2); 691 } 692 state.regionCounter++; 693 } 694 695 static void resetPriorityAfterLockedSection() { 696 PriorityState state = sThreadPriorityState.get(); 697 state.regionCounter--; 698 if (state.regionCounter == 0 && state.prevPriority > -2) { 699 Process.setThreadPriority(Process.myTid(), state.prevPriority); 700 } 701 } 702 703 public class PendingAssistExtras extends Binder implements Runnable { 704 public final ActivityRecord activity; 705 public final Bundle extras; 706 public final Intent intent; 707 public final String hint; 708 public final IResultReceiver receiver; 709 public final int userHandle; 710 public boolean haveResult = false; 711 public Bundle result = null; 712 public AssistStructure structure = null; 713 public AssistContent content = null; 714 public Bundle receiverExtras; 715 716 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, 717 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) { 718 activity = _activity; 719 extras = _extras; 720 intent = _intent; 721 hint = _hint; 722 receiver = _receiver; 723 receiverExtras = _receiverExtras; 724 userHandle = _userHandle; 725 } 726 @Override 727 public void run() { 728 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 729 synchronized (this) { 730 haveResult = true; 731 notifyAll(); 732 } 733 pendingAssistExtrasTimedOut(this); 734 } 735 } 736 737 final ArrayList<PendingAssistExtras> mPendingAssistExtras 738 = new ArrayList<PendingAssistExtras>(); 739 740 /** 741 * Process management. 742 */ 743 final ProcessList mProcessList = new ProcessList(); 744 745 /** 746 * All of the applications we currently have running organized by name. 747 * The keys are strings of the application package name (as 748 * returned by the package manager), and the keys are ApplicationRecord 749 * objects. 750 */ 751 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 752 753 /** 754 * Tracking long-term execution of processes to look for abuse and other 755 * bad app behavior. 756 */ 757 final ProcessStatsService mProcessStats; 758 759 /** 760 * The currently running isolated processes. 761 */ 762 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 763 764 /** 765 * Counter for assigning isolated process uids, to avoid frequently reusing the 766 * same ones. 767 */ 768 int mNextIsolatedProcessUid = 0; 769 770 /** 771 * The currently running heavy-weight process, if any. 772 */ 773 ProcessRecord mHeavyWeightProcess = null; 774 775 /** 776 * Non-persistent app uid whitelist for background restrictions 777 */ 778 int[] mBackgroundUidWhitelist = new int[] { 779 Process.BLUETOOTH_UID 780 }; 781 782 /** 783 * Broadcast actions that will always be deliverable to unlaunched/background apps 784 */ 785 ArraySet<String> mBackgroundLaunchBroadcasts; 786 787 /** 788 * All of the processes we currently have running organized by pid. 789 * The keys are the pid running the application. 790 * 791 * <p>NOTE: This object is protected by its own lock, NOT the global 792 * activity manager lock! 793 */ 794 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 795 796 /** 797 * All of the processes that have been forced to be foreground. The key 798 * is the pid of the caller who requested it (we hold a death 799 * link on it). 800 */ 801 abstract class ForegroundToken implements IBinder.DeathRecipient { 802 int pid; 803 IBinder token; 804 } 805 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 806 807 /** 808 * List of records for processes that someone had tried to start before the 809 * system was ready. We don't start them at that point, but ensure they 810 * are started by the time booting is complete. 811 */ 812 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 813 814 /** 815 * List of persistent applications that are in the process 816 * of being started. 817 */ 818 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 819 820 /** 821 * Processes that are being forcibly torn down. 822 */ 823 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 824 825 /** 826 * List of running applications, sorted by recent usage. 827 * The first entry in the list is the least recently used. 828 */ 829 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 830 831 /** 832 * Where in mLruProcesses that the processes hosting activities start. 833 */ 834 int mLruProcessActivityStart = 0; 835 836 /** 837 * Where in mLruProcesses that the processes hosting services start. 838 * This is after (lower index) than mLruProcessesActivityStart. 839 */ 840 int mLruProcessServiceStart = 0; 841 842 /** 843 * List of processes that should gc as soon as things are idle. 844 */ 845 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 846 847 /** 848 * Processes we want to collect PSS data from. 849 */ 850 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 851 852 private boolean mBinderTransactionTrackingEnabled = false; 853 854 /** 855 * Last time we requested PSS data of all processes. 856 */ 857 long mLastFullPssTime = SystemClock.uptimeMillis(); 858 859 /** 860 * If set, the next time we collect PSS data we should do a full collection 861 * with data from native processes and the kernel. 862 */ 863 boolean mFullPssPending = false; 864 865 /** 866 * This is the process holding what we currently consider to be 867 * the "home" activity. 868 */ 869 ProcessRecord mHomeProcess; 870 871 /** 872 * This is the process holding the activity the user last visited that 873 * is in a different process from the one they are currently in. 874 */ 875 ProcessRecord mPreviousProcess; 876 877 /** 878 * The time at which the previous process was last visible. 879 */ 880 long mPreviousProcessVisibleTime; 881 882 /** 883 * Track all uids that have actively running processes. 884 */ 885 final SparseArray<UidRecord> mActiveUids = new SparseArray<>(); 886 887 /** 888 * This is for verifying the UID report flow. 889 */ 890 static final boolean VALIDATE_UID_STATES = true; 891 final SparseArray<UidRecord> mValidateUids = new SparseArray<>(); 892 893 /** 894 * Packages that the user has asked to have run in screen size 895 * compatibility mode instead of filling the screen. 896 */ 897 final CompatModePackages mCompatModePackages; 898 899 /** 900 * Set of IntentSenderRecord objects that are currently active. 901 */ 902 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 903 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 904 905 /** 906 * Fingerprints (hashCode()) of stack traces that we've 907 * already logged DropBox entries for. Guarded by itself. If 908 * something (rogue user app) forces this over 909 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 910 */ 911 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 912 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 913 914 /** 915 * Strict Mode background batched logging state. 916 * 917 * The string buffer is guarded by itself, and its lock is also 918 * used to determine if another batched write is already 919 * in-flight. 920 */ 921 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 922 923 /** 924 * Keeps track of all IIntentReceivers that have been registered for broadcasts. 925 * Hash keys are the receiver IBinder, hash value is a ReceiverList. 926 */ 927 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>(); 928 929 /** 930 * Resolver for broadcast intents to registered receivers. 931 * Holds BroadcastFilter (subclass of IntentFilter). 932 */ 933 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 934 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 935 @Override 936 protected boolean allowFilterResult( 937 BroadcastFilter filter, List<BroadcastFilter> dest) { 938 IBinder target = filter.receiverList.receiver.asBinder(); 939 for (int i = dest.size() - 1; i >= 0; i--) { 940 if (dest.get(i).receiverList.receiver.asBinder() == target) { 941 return false; 942 } 943 } 944 return true; 945 } 946 947 @Override 948 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 949 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 950 || userId == filter.owningUserId) { 951 return super.newResult(filter, match, userId); 952 } 953 return null; 954 } 955 956 @Override 957 protected BroadcastFilter[] newArray(int size) { 958 return new BroadcastFilter[size]; 959 } 960 961 @Override 962 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 963 return packageName.equals(filter.packageName); 964 } 965 }; 966 967 /** 968 * State of all active sticky broadcasts per user. Keys are the action of the 969 * sticky Intent, values are an ArrayList of all broadcasted intents with 970 * that action (which should usually be one). The SparseArray is keyed 971 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 972 * for stickies that are sent to all users. 973 */ 974 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 975 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 976 977 final ActiveServices mServices; 978 979 final static class Association { 980 final int mSourceUid; 981 final String mSourceProcess; 982 final int mTargetUid; 983 final ComponentName mTargetComponent; 984 final String mTargetProcess; 985 986 int mCount; 987 long mTime; 988 989 int mNesting; 990 long mStartTime; 991 992 // states of the source process when the bind occurred. 993 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1; 994 long mLastStateUptime; 995 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE 996 - ActivityManager.MIN_PROCESS_STATE+1]; 997 998 Association(int sourceUid, String sourceProcess, int targetUid, 999 ComponentName targetComponent, String targetProcess) { 1000 mSourceUid = sourceUid; 1001 mSourceProcess = sourceProcess; 1002 mTargetUid = targetUid; 1003 mTargetComponent = targetComponent; 1004 mTargetProcess = targetProcess; 1005 } 1006 } 1007 1008 /** 1009 * When service association tracking is enabled, this is all of the associations we 1010 * have seen. Mapping is target uid -> target component -> source uid -> source process name 1011 * -> association data. 1012 */ 1013 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>> 1014 mAssociations = new SparseArray<>(); 1015 boolean mTrackingAssociations; 1016 1017 /** 1018 * Backup/restore process management 1019 */ 1020 String mBackupAppName = null; 1021 BackupRecord mBackupTarget = null; 1022 1023 final ProviderMap mProviderMap; 1024 1025 /** 1026 * List of content providers who have clients waiting for them. The 1027 * application is currently being launched and the provider will be 1028 * removed from this list once it is published. 1029 */ 1030 final ArrayList<ContentProviderRecord> mLaunchingProviders 1031 = new ArrayList<ContentProviderRecord>(); 1032 1033 /** 1034 * File storing persisted {@link #mGrantedUriPermissions}. 1035 */ 1036 private final AtomicFile mGrantFile; 1037 1038 /** XML constants used in {@link #mGrantFile} */ 1039 private static final String TAG_URI_GRANTS = "uri-grants"; 1040 private static final String TAG_URI_GRANT = "uri-grant"; 1041 private static final String ATTR_USER_HANDLE = "userHandle"; 1042 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 1043 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 1044 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 1045 private static final String ATTR_TARGET_PKG = "targetPkg"; 1046 private static final String ATTR_URI = "uri"; 1047 private static final String ATTR_MODE_FLAGS = "modeFlags"; 1048 private static final String ATTR_CREATED_TIME = "createdTime"; 1049 private static final String ATTR_PREFIX = "prefix"; 1050 1051 /** 1052 * Global set of specific {@link Uri} permissions that have been granted. 1053 * This optimized lookup structure maps from {@link UriPermission#targetUid} 1054 * to {@link UriPermission#uri} to {@link UriPermission}. 1055 */ 1056 @GuardedBy("this") 1057 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 1058 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 1059 1060 public static class GrantUri { 1061 public final int sourceUserId; 1062 public final Uri uri; 1063 public boolean prefix; 1064 1065 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 1066 this.sourceUserId = sourceUserId; 1067 this.uri = uri; 1068 this.prefix = prefix; 1069 } 1070 1071 @Override 1072 public int hashCode() { 1073 int hashCode = 1; 1074 hashCode = 31 * hashCode + sourceUserId; 1075 hashCode = 31 * hashCode + uri.hashCode(); 1076 hashCode = 31 * hashCode + (prefix ? 1231 : 1237); 1077 return hashCode; 1078 } 1079 1080 @Override 1081 public boolean equals(Object o) { 1082 if (o instanceof GrantUri) { 1083 GrantUri other = (GrantUri) o; 1084 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 1085 && prefix == other.prefix; 1086 } 1087 return false; 1088 } 1089 1090 @Override 1091 public String toString() { 1092 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 1093 if (prefix) result += " [prefix]"; 1094 return result; 1095 } 1096 1097 public String toSafeString() { 1098 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 1099 if (prefix) result += " [prefix]"; 1100 return result; 1101 } 1102 1103 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 1104 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 1105 ContentProvider.getUriWithoutUserId(uri), false); 1106 } 1107 } 1108 1109 CoreSettingsObserver mCoreSettingsObserver; 1110 1111 FontScaleSettingObserver mFontScaleSettingObserver; 1112 1113 private final class FontScaleSettingObserver extends ContentObserver { 1114 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE); 1115 1116 public FontScaleSettingObserver() { 1117 super(mHandler); 1118 ContentResolver resolver = mContext.getContentResolver(); 1119 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL); 1120 } 1121 1122 @Override 1123 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) { 1124 if (mFontScaleUri.equals(uri)) { 1125 updateFontScaleIfNeeded(userId); 1126 } 1127 } 1128 } 1129 1130 /** 1131 * Thread-local storage used to carry caller permissions over through 1132 * indirect content-provider access. 1133 */ 1134 private class Identity { 1135 public final IBinder token; 1136 public final int pid; 1137 public final int uid; 1138 1139 Identity(IBinder _token, int _pid, int _uid) { 1140 token = _token; 1141 pid = _pid; 1142 uid = _uid; 1143 } 1144 } 1145 1146 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 1147 1148 /** 1149 * All information we have collected about the runtime performance of 1150 * any user id that can impact battery performance. 1151 */ 1152 final BatteryStatsService mBatteryStatsService; 1153 1154 /** 1155 * Information about component usage 1156 */ 1157 UsageStatsManagerInternal mUsageStatsService; 1158 1159 /** 1160 * Access to DeviceIdleController service. 1161 */ 1162 DeviceIdleController.LocalService mLocalDeviceIdleController; 1163 1164 /** 1165 * Set of app ids that are whitelisted for device idle and thus background check. 1166 */ 1167 int[] mDeviceIdleWhitelist = new int[0]; 1168 1169 /** 1170 * Set of app ids that are temporarily allowed to escape bg check due to high-pri message 1171 */ 1172 int[] mDeviceIdleTempWhitelist = new int[0]; 1173 1174 /** 1175 * Information about and control over application operations 1176 */ 1177 final AppOpsService mAppOpsService; 1178 1179 /** Current sequencing integer of the configuration, for skipping old configurations. */ 1180 private int mConfigurationSeq; 1181 1182 /** 1183 * Temp object used when global and/or display override configuration is updated. It is also 1184 * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust 1185 * anyone... 1186 */ 1187 private Configuration mTempConfig = new Configuration(); 1188 1189 private final UpdateConfigurationResult mTmpUpdateConfigurationResult = 1190 new UpdateConfigurationResult(); 1191 private static final class UpdateConfigurationResult { 1192 // Configuration changes that were updated. 1193 int changes; 1194 // If the activity was relaunched to match the new configuration. 1195 boolean activityRelaunched; 1196 1197 void reset() { 1198 changes = 0; 1199 activityRelaunched = false; 1200 } 1201 } 1202 1203 boolean mSuppressResizeConfigChanges; 1204 1205 /** 1206 * Hardware-reported OpenGLES version. 1207 */ 1208 final int GL_ES_VERSION; 1209 1210 /** 1211 * List of initialization arguments to pass to all processes when binding applications to them. 1212 * For example, references to the commonly used services. 1213 */ 1214 HashMap<String, IBinder> mAppBindArgs; 1215 HashMap<String, IBinder> mIsolatedAppBindArgs; 1216 1217 /** 1218 * Temporary to avoid allocations. Protected by main lock. 1219 */ 1220 final StringBuilder mStringBuilder = new StringBuilder(256); 1221 1222 /** 1223 * Used to control how we initialize the service. 1224 */ 1225 ComponentName mTopComponent; 1226 String mTopAction = Intent.ACTION_MAIN; 1227 String mTopData; 1228 1229 volatile boolean mProcessesReady = false; 1230 volatile boolean mSystemReady = false; 1231 volatile boolean mOnBattery = false; 1232 volatile int mFactoryTest; 1233 1234 @GuardedBy("this") boolean mBooting = false; 1235 @GuardedBy("this") boolean mCallFinishBooting = false; 1236 @GuardedBy("this") boolean mBootAnimationComplete = false; 1237 @GuardedBy("this") boolean mLaunchWarningShown = false; 1238 @GuardedBy("this") boolean mCheckedForSetup = false; 1239 1240 Context mContext; 1241 1242 /** 1243 * The time at which we will allow normal application switches again, 1244 * after a call to {@link #stopAppSwitches()}. 1245 */ 1246 long mAppSwitchesAllowedTime; 1247 1248 /** 1249 * This is set to true after the first switch after mAppSwitchesAllowedTime 1250 * is set; any switches after that will clear the time. 1251 */ 1252 boolean mDidAppSwitch; 1253 1254 /** 1255 * Last time (in realtime) at which we checked for power usage. 1256 */ 1257 long mLastPowerCheckRealtime; 1258 1259 /** 1260 * Last time (in uptime) at which we checked for power usage. 1261 */ 1262 long mLastPowerCheckUptime; 1263 1264 /** 1265 * Set while we are wanting to sleep, to prevent any 1266 * activities from being started/resumed. 1267 * 1268 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping. 1269 * 1270 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true 1271 * while in the sleep state until there is a pending transition out of sleep, in which case 1272 * mSleeping is set to false, and remains false while awake. 1273 * 1274 * Whether mSleeping can quickly toggled between true/false without the device actually 1275 * display changing states is undefined. 1276 */ 1277 private boolean mSleeping = false; 1278 1279 /** 1280 * The process state used for processes that are running the top activities. 1281 * This changes between TOP and TOP_SLEEPING to following mSleeping. 1282 */ 1283 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP; 1284 1285 /** 1286 * Set while we are running a voice interaction. This overrides 1287 * sleeping while it is active. 1288 */ 1289 private IVoiceInteractionSession mRunningVoice; 1290 1291 /** 1292 * For some direct access we need to power manager. 1293 */ 1294 PowerManagerInternal mLocalPowerManager; 1295 1296 /** 1297 * We want to hold a wake lock while running a voice interaction session, since 1298 * this may happen with the screen off and we need to keep the CPU running to 1299 * be able to continue to interact with the user. 1300 */ 1301 PowerManager.WakeLock mVoiceWakeLock; 1302 1303 /** 1304 * State of external calls telling us if the device is awake or asleep. 1305 */ 1306 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; 1307 1308 /** 1309 * A list of tokens that cause the top activity to be put to sleep. 1310 * They are used by components that may hide and block interaction with underlying 1311 * activities. 1312 */ 1313 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>(); 1314 1315 /** 1316 * Set if we are shutting down the system, similar to sleeping. 1317 */ 1318 boolean mShuttingDown = false; 1319 1320 /** 1321 * Current sequence id for oom_adj computation traversal. 1322 */ 1323 int mAdjSeq = 0; 1324 1325 /** 1326 * Current sequence id for process LRU updating. 1327 */ 1328 int mLruSeq = 0; 1329 1330 /** 1331 * Keep track of the non-cached/empty process we last found, to help 1332 * determine how to distribute cached/empty processes next time. 1333 */ 1334 int mNumNonCachedProcs = 0; 1335 1336 /** 1337 * Keep track of the number of cached hidden procs, to balance oom adj 1338 * distribution between those and empty procs. 1339 */ 1340 int mNumCachedHiddenProcs = 0; 1341 1342 /** 1343 * Keep track of the number of service processes we last found, to 1344 * determine on the next iteration which should be B services. 1345 */ 1346 int mNumServiceProcs = 0; 1347 int mNewNumAServiceProcs = 0; 1348 int mNewNumServiceProcs = 0; 1349 1350 /** 1351 * Allow the current computed overall memory level of the system to go down? 1352 * This is set to false when we are killing processes for reasons other than 1353 * memory management, so that the now smaller process list will not be taken as 1354 * an indication that memory is tighter. 1355 */ 1356 boolean mAllowLowerMemLevel = false; 1357 1358 /** 1359 * The last computed memory level, for holding when we are in a state that 1360 * processes are going away for other reasons. 1361 */ 1362 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 1363 1364 /** 1365 * The last total number of process we have, to determine if changes actually look 1366 * like a shrinking number of process due to lower RAM. 1367 */ 1368 int mLastNumProcesses; 1369 1370 /** 1371 * The uptime of the last time we performed idle maintenance. 1372 */ 1373 long mLastIdleTime = SystemClock.uptimeMillis(); 1374 1375 /** 1376 * Total time spent with RAM that has been added in the past since the last idle time. 1377 */ 1378 long mLowRamTimeSinceLastIdle = 0; 1379 1380 /** 1381 * If RAM is currently low, when that horrible situation started. 1382 */ 1383 long mLowRamStartTime = 0; 1384 1385 /** 1386 * For reporting to battery stats the current top application. 1387 */ 1388 private String mCurResumedPackage = null; 1389 private int mCurResumedUid = -1; 1390 1391 /** 1392 * For reporting to battery stats the apps currently running foreground 1393 * service. The ProcessMap is package/uid tuples; each of these contain 1394 * an array of the currently foreground processes. 1395 */ 1396 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1397 = new ProcessMap<ArrayList<ProcessRecord>>(); 1398 1399 /** 1400 * This is set if we had to do a delayed dexopt of an app before launching 1401 * it, to increase the ANR timeouts in that case. 1402 */ 1403 boolean mDidDexOpt; 1404 1405 /** 1406 * Set if the systemServer made a call to enterSafeMode. 1407 */ 1408 boolean mSafeMode; 1409 1410 /** 1411 * If true, we are running under a test environment so will sample PSS from processes 1412 * much more rapidly to try to collect better data when the tests are rapidly 1413 * running through apps. 1414 */ 1415 boolean mTestPssMode = false; 1416 1417 String mDebugApp = null; 1418 boolean mWaitForDebugger = false; 1419 boolean mDebugTransient = false; 1420 String mOrigDebugApp = null; 1421 boolean mOrigWaitForDebugger = false; 1422 boolean mAlwaysFinishActivities = false; 1423 boolean mForceResizableActivities; 1424 boolean mSupportsMultiWindow; 1425 boolean mSupportsSplitScreenMultiWindow; 1426 boolean mSupportsFreeformWindowManagement; 1427 boolean mSupportsPictureInPicture; 1428 boolean mSupportsLeanbackOnly; 1429 IActivityController mController = null; 1430 boolean mControllerIsAMonkey = false; 1431 String mProfileApp = null; 1432 ProcessRecord mProfileProc = null; 1433 String mProfileFile; 1434 ParcelFileDescriptor mProfileFd; 1435 int mSamplingInterval = 0; 1436 boolean mAutoStopProfiler = false; 1437 boolean mStreamingOutput = false; 1438 int mProfileType = 0; 1439 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>(); 1440 String mMemWatchDumpProcName; 1441 String mMemWatchDumpFile; 1442 int mMemWatchDumpPid; 1443 int mMemWatchDumpUid; 1444 String mTrackAllocationApp = null; 1445 String mNativeDebuggingApp = null; 1446 1447 final long[] mTmpLong = new long[2]; 1448 1449 private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet(); 1450 1451 /** 1452 * A global counter for generating sequence numbers. 1453 * This value will be used when incrementing sequence numbers in individual uidRecords. 1454 * 1455 * Having a global counter ensures that seq numbers are monotonically increasing for a 1456 * particular uid even when the uidRecord is re-created. 1457 */ 1458 @GuardedBy("this") 1459 @VisibleForTesting 1460 long mProcStateSeqCounter = 0; 1461 1462 static final class ProcessChangeItem { 1463 static final int CHANGE_ACTIVITIES = 1<<0; 1464 int changes; 1465 int uid; 1466 int pid; 1467 int processState; 1468 boolean foregroundActivities; 1469 } 1470 1471 static final class UidObserverRegistration { 1472 final int uid; 1473 final String pkg; 1474 final int which; 1475 final int cutpoint; 1476 1477 final SparseIntArray lastProcStates; 1478 1479 UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) { 1480 uid = _uid; 1481 pkg = _pkg; 1482 which = _which; 1483 cutpoint = _cutpoint; 1484 if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) { 1485 lastProcStates = new SparseIntArray(); 1486 } else { 1487 lastProcStates = null; 1488 } 1489 } 1490 } 1491 1492 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>(); 1493 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1494 1495 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>(); 1496 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>(); 1497 1498 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>(); 1499 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5]; 1500 1501 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>(); 1502 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>(); 1503 1504 /** 1505 * Runtime CPU use collection thread. This object's lock is used to 1506 * perform synchronization with the thread (notifying it to run). 1507 */ 1508 final Thread mProcessCpuThread; 1509 1510 /** 1511 * Used to collect per-process CPU use for ANRs, battery stats, etc. 1512 * Must acquire this object's lock when accessing it. 1513 * NOTE: this lock will be held while doing long operations (trawling 1514 * through all processes in /proc), so it should never be acquired by 1515 * any critical paths such as when holding the main activity manager lock. 1516 */ 1517 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1518 MONITOR_THREAD_CPU_USAGE); 1519 final AtomicLong mLastCpuTime = new AtomicLong(0); 1520 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1521 final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1); 1522 1523 long mLastWriteTime = 0; 1524 1525 /** 1526 * Used to retain an update lock when the foreground activity is in 1527 * immersive mode. 1528 */ 1529 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1530 1531 /** 1532 * Set to true after the system has finished booting. 1533 */ 1534 boolean mBooted = false; 1535 1536 WindowManagerService mWindowManager; 1537 final ActivityThread mSystemThread; 1538 1539 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1540 final ProcessRecord mApp; 1541 final int mPid; 1542 final IApplicationThread mAppThread; 1543 1544 AppDeathRecipient(ProcessRecord app, int pid, 1545 IApplicationThread thread) { 1546 if (DEBUG_ALL) Slog.v( 1547 TAG, "New death recipient " + this 1548 + " for thread " + thread.asBinder()); 1549 mApp = app; 1550 mPid = pid; 1551 mAppThread = thread; 1552 } 1553 1554 @Override 1555 public void binderDied() { 1556 if (DEBUG_ALL) Slog.v( 1557 TAG, "Death received in " + this 1558 + " for thread " + mAppThread.asBinder()); 1559 synchronized(ActivityManagerService.this) { 1560 appDiedLocked(mApp, mPid, mAppThread, true); 1561 } 1562 } 1563 } 1564 1565 static final int SHOW_ERROR_UI_MSG = 1; 1566 static final int SHOW_NOT_RESPONDING_UI_MSG = 2; 1567 static final int SHOW_FACTORY_ERROR_UI_MSG = 3; 1568 static final int UPDATE_CONFIGURATION_MSG = 4; 1569 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1570 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6; 1571 static final int SERVICE_TIMEOUT_MSG = 12; 1572 static final int UPDATE_TIME_ZONE = 13; 1573 static final int SHOW_UID_ERROR_UI_MSG = 14; 1574 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15; 1575 static final int PROC_START_TIMEOUT_MSG = 20; 1576 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1577 static final int KILL_APPLICATION_MSG = 22; 1578 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1579 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1580 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1581 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26; 1582 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1583 static final int CLEAR_DNS_CACHE_MSG = 28; 1584 static final int UPDATE_HTTP_PROXY_MSG = 29; 1585 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30; 1586 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31; 1587 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32; 1588 static final int REPORT_MEM_USAGE_MSG = 33; 1589 static final int REPORT_USER_SWITCH_MSG = 34; 1590 static final int CONTINUE_USER_SWITCH_MSG = 35; 1591 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1592 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1593 static final int PERSIST_URI_GRANTS_MSG = 38; 1594 static final int REQUEST_ALL_PSS_MSG = 39; 1595 static final int START_PROFILES_MSG = 40; 1596 static final int UPDATE_TIME_PREFERENCE_MSG = 41; 1597 static final int SYSTEM_USER_START_MSG = 42; 1598 static final int SYSTEM_USER_CURRENT_MSG = 43; 1599 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1600 static final int FINISH_BOOTING_MSG = 45; 1601 static final int START_USER_SWITCH_UI_MSG = 46; 1602 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47; 1603 static final int DISMISS_DIALOG_UI_MSG = 48; 1604 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49; 1605 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50; 1606 static final int DELETE_DUMPHEAP_MSG = 51; 1607 static final int FOREGROUND_PROFILE_CHANGED_MSG = 52; 1608 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53; 1609 static final int REPORT_TIME_TRACKER_MSG = 54; 1610 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55; 1611 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56; 1612 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57; 1613 static final int IDLE_UIDS_MSG = 58; 1614 static final int SYSTEM_USER_UNLOCK_MSG = 59; 1615 static final int LOG_STACK_STATE = 60; 1616 static final int VR_MODE_CHANGE_MSG = 61; 1617 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62; 1618 static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63; 1619 static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64; 1620 static final int NOTIFY_VR_SLEEPING_MSG = 65; 1621 static final int START_USER_SWITCH_FG_MSG = 712; 1622 1623 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1624 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1625 static final int FIRST_COMPAT_MODE_MSG = 300; 1626 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1627 1628 static ServiceThread sKillThread = null; 1629 static KillHandler sKillHandler = null; 1630 1631 CompatModeDialog mCompatModeDialog; 1632 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog; 1633 long mLastMemUsageReportTime = 0; 1634 1635 /** 1636 * Flag whether the current user is a "monkey", i.e. whether 1637 * the UI is driven by a UI automation tool. 1638 */ 1639 private boolean mUserIsMonkey; 1640 1641 /** Flag whether the device has a Recents UI */ 1642 boolean mHasRecents; 1643 1644 /** The dimensions of the thumbnails in the Recents UI. */ 1645 int mThumbnailWidth; 1646 int mThumbnailHeight; 1647 float mFullscreenThumbnailScale; 1648 1649 final ServiceThread mHandlerThread; 1650 final MainHandler mHandler; 1651 final UiHandler mUiHandler; 1652 1653 final ActivityManagerConstants mConstants; 1654 1655 PackageManagerInternal mPackageManagerInt; 1656 1657 // VoiceInteraction session ID that changes for each new request except when 1658 // being called for multiwindow assist in a single session. 1659 private int mViSessionId = 1000; 1660 1661 final boolean mPermissionReviewRequired; 1662 1663 /** 1664 * Current global configuration information. Contains general settings for the entire system, 1665 * also corresponds to the merged configuration of the default display. 1666 */ 1667 Configuration getGlobalConfiguration() { 1668 return mStackSupervisor.getConfiguration(); 1669 } 1670 1671 final class KillHandler extends Handler { 1672 static final int KILL_PROCESS_GROUP_MSG = 4000; 1673 1674 public KillHandler(Looper looper) { 1675 super(looper, null, true); 1676 } 1677 1678 @Override 1679 public void handleMessage(Message msg) { 1680 switch (msg.what) { 1681 case KILL_PROCESS_GROUP_MSG: 1682 { 1683 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup"); 1684 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */); 1685 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1686 } 1687 break; 1688 1689 default: 1690 super.handleMessage(msg); 1691 } 1692 } 1693 } 1694 1695 final class UiHandler extends Handler { 1696 public UiHandler() { 1697 super(com.android.server.UiThread.get().getLooper(), null, true); 1698 } 1699 1700 @Override 1701 public void handleMessage(Message msg) { 1702 switch (msg.what) { 1703 case SHOW_ERROR_UI_MSG: { 1704 mAppErrors.handleShowAppErrorUi(msg); 1705 ensureBootCompleted(); 1706 } break; 1707 case SHOW_NOT_RESPONDING_UI_MSG: { 1708 mAppErrors.handleShowAnrUi(msg); 1709 ensureBootCompleted(); 1710 } break; 1711 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: { 1712 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1713 synchronized (ActivityManagerService.this) { 1714 ProcessRecord proc = (ProcessRecord) data.get("app"); 1715 if (proc == null) { 1716 Slog.e(TAG, "App not found when showing strict mode dialog."); 1717 break; 1718 } 1719 if (proc.crashDialog != null) { 1720 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1721 return; 1722 } 1723 AppErrorResult res = (AppErrorResult) data.get("result"); 1724 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1725 Dialog d = new StrictModeViolationDialog(mContext, 1726 ActivityManagerService.this, res, proc); 1727 d.show(); 1728 proc.crashDialog = d; 1729 } else { 1730 // The device is asleep, so just pretend that the user 1731 // saw a crash dialog and hit "force quit". 1732 res.set(0); 1733 } 1734 } 1735 ensureBootCompleted(); 1736 } break; 1737 case SHOW_FACTORY_ERROR_UI_MSG: { 1738 Dialog d = new FactoryErrorDialog( 1739 mContext, msg.getData().getCharSequence("msg")); 1740 d.show(); 1741 ensureBootCompleted(); 1742 } break; 1743 case WAIT_FOR_DEBUGGER_UI_MSG: { 1744 synchronized (ActivityManagerService.this) { 1745 ProcessRecord app = (ProcessRecord)msg.obj; 1746 if (msg.arg1 != 0) { 1747 if (!app.waitedForDebugger) { 1748 Dialog d = new AppWaitingForDebuggerDialog( 1749 ActivityManagerService.this, 1750 mContext, app); 1751 app.waitDialog = d; 1752 app.waitedForDebugger = true; 1753 d.show(); 1754 } 1755 } else { 1756 if (app.waitDialog != null) { 1757 app.waitDialog.dismiss(); 1758 app.waitDialog = null; 1759 } 1760 } 1761 } 1762 } break; 1763 case SHOW_UID_ERROR_UI_MSG: { 1764 if (mShowDialogs) { 1765 AlertDialog d = new BaseErrorDialog(mContext); 1766 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1767 d.setCancelable(false); 1768 d.setTitle(mContext.getText(R.string.android_system_label)); 1769 d.setMessage(mContext.getText(R.string.system_error_wipe_data)); 1770 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1771 obtainMessage(DISMISS_DIALOG_UI_MSG, d)); 1772 d.show(); 1773 } 1774 } break; 1775 case SHOW_FINGERPRINT_ERROR_UI_MSG: { 1776 if (mShowDialogs) { 1777 AlertDialog d = new BaseErrorDialog(mContext); 1778 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1779 d.setCancelable(false); 1780 d.setTitle(mContext.getText(R.string.android_system_label)); 1781 d.setMessage(mContext.getText(R.string.system_error_manufacturer)); 1782 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok), 1783 obtainMessage(DISMISS_DIALOG_UI_MSG, d)); 1784 d.show(); 1785 } 1786 } break; 1787 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: { 1788 synchronized (ActivityManagerService.this) { 1789 ActivityRecord ar = (ActivityRecord) msg.obj; 1790 if (mCompatModeDialog != null) { 1791 if (mCompatModeDialog.mAppInfo.packageName.equals( 1792 ar.info.applicationInfo.packageName)) { 1793 return; 1794 } 1795 mCompatModeDialog.dismiss(); 1796 mCompatModeDialog = null; 1797 } 1798 if (ar != null && false) { 1799 if (mCompatModePackages.getPackageAskCompatModeLocked( 1800 ar.packageName)) { 1801 int mode = mCompatModePackages.computeCompatModeLocked( 1802 ar.info.applicationInfo); 1803 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1804 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1805 mCompatModeDialog = new CompatModeDialog( 1806 ActivityManagerService.this, mContext, 1807 ar.info.applicationInfo); 1808 mCompatModeDialog.show(); 1809 } 1810 } 1811 } 1812 } 1813 break; 1814 } 1815 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: { 1816 synchronized (ActivityManagerService.this) { 1817 final ActivityRecord ar = (ActivityRecord) msg.obj; 1818 if (mUnsupportedDisplaySizeDialog != null) { 1819 mUnsupportedDisplaySizeDialog.dismiss(); 1820 mUnsupportedDisplaySizeDialog = null; 1821 } 1822 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked( 1823 ar.packageName)) { 1824 // TODO(multi-display): Show dialog on appropriate display. 1825 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog( 1826 ActivityManagerService.this, mContext, ar.info.applicationInfo); 1827 mUnsupportedDisplaySizeDialog.show(); 1828 } 1829 } 1830 break; 1831 } 1832 case START_USER_SWITCH_UI_MSG: { 1833 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj); 1834 break; 1835 } 1836 case DISMISS_DIALOG_UI_MSG: { 1837 final Dialog d = (Dialog) msg.obj; 1838 d.dismiss(); 1839 break; 1840 } 1841 case DISPATCH_PROCESSES_CHANGED_UI_MSG: { 1842 dispatchProcessesChanged(); 1843 break; 1844 } 1845 case DISPATCH_PROCESS_DIED_UI_MSG: { 1846 final int pid = msg.arg1; 1847 final int uid = msg.arg2; 1848 dispatchProcessDied(pid, uid); 1849 break; 1850 } 1851 case DISPATCH_UIDS_CHANGED_UI_MSG: { 1852 dispatchUidsChanged(); 1853 } break; 1854 } 1855 } 1856 } 1857 1858 final class MainHandler extends Handler { 1859 public MainHandler(Looper looper) { 1860 super(looper, null, true); 1861 } 1862 1863 @Override 1864 public void handleMessage(Message msg) { 1865 switch (msg.what) { 1866 case UPDATE_CONFIGURATION_MSG: { 1867 final ContentResolver resolver = mContext.getContentResolver(); 1868 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj, 1869 msg.arg1); 1870 } break; 1871 case GC_BACKGROUND_PROCESSES_MSG: { 1872 synchronized (ActivityManagerService.this) { 1873 performAppGcsIfAppropriateLocked(); 1874 } 1875 } break; 1876 case SERVICE_TIMEOUT_MSG: { 1877 if (mDidDexOpt) { 1878 mDidDexOpt = false; 1879 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1880 nmsg.obj = msg.obj; 1881 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1882 return; 1883 } 1884 mServices.serviceTimeout((ProcessRecord)msg.obj); 1885 } break; 1886 case UPDATE_TIME_ZONE: { 1887 synchronized (ActivityManagerService.this) { 1888 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1889 ProcessRecord r = mLruProcesses.get(i); 1890 if (r.thread != null) { 1891 try { 1892 r.thread.updateTimeZone(); 1893 } catch (RemoteException ex) { 1894 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1895 } 1896 } 1897 } 1898 } 1899 } break; 1900 case CLEAR_DNS_CACHE_MSG: { 1901 synchronized (ActivityManagerService.this) { 1902 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1903 ProcessRecord r = mLruProcesses.get(i); 1904 if (r.thread != null) { 1905 try { 1906 r.thread.clearDnsCache(); 1907 } catch (RemoteException ex) { 1908 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1909 } 1910 } 1911 } 1912 } 1913 } break; 1914 case UPDATE_HTTP_PROXY_MSG: { 1915 ProxyInfo proxy = (ProxyInfo)msg.obj; 1916 String host = ""; 1917 String port = ""; 1918 String exclList = ""; 1919 Uri pacFileUrl = Uri.EMPTY; 1920 if (proxy != null) { 1921 host = proxy.getHost(); 1922 port = Integer.toString(proxy.getPort()); 1923 exclList = proxy.getExclusionListAsString(); 1924 pacFileUrl = proxy.getPacFileUrl(); 1925 } 1926 synchronized (ActivityManagerService.this) { 1927 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1928 ProcessRecord r = mLruProcesses.get(i); 1929 if (r.thread != null) { 1930 try { 1931 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1932 } catch (RemoteException ex) { 1933 Slog.w(TAG, "Failed to update http proxy for: " + 1934 r.info.processName); 1935 } 1936 } 1937 } 1938 } 1939 } break; 1940 case PROC_START_TIMEOUT_MSG: { 1941 if (mDidDexOpt) { 1942 mDidDexOpt = false; 1943 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1944 nmsg.obj = msg.obj; 1945 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1946 return; 1947 } 1948 ProcessRecord app = (ProcessRecord)msg.obj; 1949 synchronized (ActivityManagerService.this) { 1950 processStartTimedOutLocked(app); 1951 } 1952 } break; 1953 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: { 1954 ProcessRecord app = (ProcessRecord)msg.obj; 1955 synchronized (ActivityManagerService.this) { 1956 processContentProviderPublishTimedOutLocked(app); 1957 } 1958 } break; 1959 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1960 synchronized (ActivityManagerService.this) { 1961 mActivityStarter.doPendingActivityLaunchesLocked(true); 1962 } 1963 } break; 1964 case KILL_APPLICATION_MSG: { 1965 synchronized (ActivityManagerService.this) { 1966 final int appId = msg.arg1; 1967 final int userId = msg.arg2; 1968 Bundle bundle = (Bundle)msg.obj; 1969 String pkg = bundle.getString("pkg"); 1970 String reason = bundle.getString("reason"); 1971 forceStopPackageLocked(pkg, appId, false, false, true, false, 1972 false, userId, reason); 1973 } 1974 } break; 1975 case FINALIZE_PENDING_INTENT_MSG: { 1976 ((PendingIntentRecord)msg.obj).completeFinalize(); 1977 } break; 1978 case POST_HEAVY_NOTIFICATION_MSG: { 1979 INotificationManager inm = NotificationManager.getService(); 1980 if (inm == null) { 1981 return; 1982 } 1983 1984 ActivityRecord root = (ActivityRecord)msg.obj; 1985 ProcessRecord process = root.app; 1986 if (process == null) { 1987 return; 1988 } 1989 1990 try { 1991 Context context = mContext.createPackageContext(process.info.packageName, 0); 1992 String text = mContext.getString(R.string.heavy_weight_notification, 1993 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1994 Notification notification = 1995 new Notification.Builder(context, SystemNotificationChannels.DEVELOPER) 1996 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 1997 .setWhen(0) 1998 .setOngoing(true) 1999 .setTicker(text) 2000 .setColor(mContext.getColor( 2001 com.android.internal.R.color.system_notification_accent_color)) 2002 .setContentTitle(text) 2003 .setContentText( 2004 mContext.getText(R.string.heavy_weight_notification_detail)) 2005 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, 2006 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null, 2007 new UserHandle(root.userId))) 2008 .build(); 2009 try { 2010 int[] outId = new int[1]; 2011 inm.enqueueNotificationWithTag("android", "android", null, 2012 R.string.heavy_weight_notification, 2013 notification, outId, root.userId); 2014 } catch (RuntimeException e) { 2015 Slog.w(ActivityManagerService.TAG, 2016 "Error showing notification for heavy-weight app", e); 2017 } catch (RemoteException e) { 2018 } 2019 } catch (NameNotFoundException e) { 2020 Slog.w(TAG, "Unable to create context for heavy notification", e); 2021 } 2022 } break; 2023 case CANCEL_HEAVY_NOTIFICATION_MSG: { 2024 INotificationManager inm = NotificationManager.getService(); 2025 if (inm == null) { 2026 return; 2027 } 2028 try { 2029 inm.cancelNotificationWithTag("android", null, 2030 R.string.heavy_weight_notification, msg.arg1); 2031 } catch (RuntimeException e) { 2032 Slog.w(ActivityManagerService.TAG, 2033 "Error canceling notification for service", e); 2034 } catch (RemoteException e) { 2035 } 2036 } break; 2037 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 2038 synchronized (ActivityManagerService.this) { 2039 checkExcessivePowerUsageLocked(true); 2040 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 2041 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 2042 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 2043 } 2044 } break; 2045 case REPORT_MEM_USAGE_MSG: { 2046 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 2047 Thread thread = new Thread() { 2048 @Override public void run() { 2049 reportMemUsage(memInfos); 2050 } 2051 }; 2052 thread.start(); 2053 break; 2054 } 2055 case START_USER_SWITCH_FG_MSG: { 2056 mUserController.startUserInForeground(msg.arg1); 2057 break; 2058 } 2059 case REPORT_USER_SWITCH_MSG: { 2060 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2); 2061 break; 2062 } 2063 case CONTINUE_USER_SWITCH_MSG: { 2064 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2); 2065 break; 2066 } 2067 case USER_SWITCH_TIMEOUT_MSG: { 2068 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2); 2069 break; 2070 } 2071 case IMMERSIVE_MODE_LOCK_MSG: { 2072 final boolean nextState = (msg.arg1 != 0); 2073 if (mUpdateLock.isHeld() != nextState) { 2074 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, 2075 "Applying new update lock state '" + nextState 2076 + "' for " + (ActivityRecord)msg.obj); 2077 if (nextState) { 2078 mUpdateLock.acquire(); 2079 } else { 2080 mUpdateLock.release(); 2081 } 2082 } 2083 break; 2084 } 2085 case PERSIST_URI_GRANTS_MSG: { 2086 writeGrantedUriPermissions(); 2087 break; 2088 } 2089 case REQUEST_ALL_PSS_MSG: { 2090 synchronized (ActivityManagerService.this) { 2091 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 2092 } 2093 break; 2094 } 2095 case START_PROFILES_MSG: { 2096 synchronized (ActivityManagerService.this) { 2097 mUserController.startProfilesLocked(); 2098 } 2099 break; 2100 } 2101 case UPDATE_TIME_PREFERENCE_MSG: { 2102 // The user's time format preference might have changed. 2103 // For convenience we re-use the Intent extra values. 2104 synchronized (ActivityManagerService.this) { 2105 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2106 ProcessRecord r = mLruProcesses.get(i); 2107 if (r.thread != null) { 2108 try { 2109 r.thread.updateTimePrefs(msg.arg1); 2110 } catch (RemoteException ex) { 2111 Slog.w(TAG, "Failed to update preferences for: " 2112 + r.info.processName); 2113 } 2114 } 2115 } 2116 } 2117 break; 2118 } 2119 case SYSTEM_USER_START_MSG: { 2120 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 2121 Integer.toString(msg.arg1), msg.arg1); 2122 mSystemServiceManager.startUser(msg.arg1); 2123 break; 2124 } 2125 case SYSTEM_USER_UNLOCK_MSG: { 2126 final int userId = msg.arg1; 2127 mSystemServiceManager.unlockUser(userId); 2128 synchronized (ActivityManagerService.this) { 2129 mRecentTasks.loadUserRecentsLocked(userId); 2130 } 2131 if (userId == UserHandle.USER_SYSTEM) { 2132 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE); 2133 } 2134 installEncryptionUnawareProviders(userId); 2135 mUserController.finishUserUnlocked((UserState) msg.obj); 2136 break; 2137 } 2138 case SYSTEM_USER_CURRENT_MSG: { 2139 mBatteryStatsService.noteEvent( 2140 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 2141 Integer.toString(msg.arg2), msg.arg2); 2142 mBatteryStatsService.noteEvent( 2143 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 2144 Integer.toString(msg.arg1), msg.arg1); 2145 mSystemServiceManager.switchUser(msg.arg1); 2146 break; 2147 } 2148 case ENTER_ANIMATION_COMPLETE_MSG: { 2149 synchronized (ActivityManagerService.this) { 2150 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj); 2151 if (r != null && r.app != null && r.app.thread != null) { 2152 try { 2153 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 2154 } catch (RemoteException e) { 2155 } 2156 } 2157 } 2158 break; 2159 } 2160 case FINISH_BOOTING_MSG: { 2161 if (msg.arg1 != 0) { 2162 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); 2163 finishBooting(); 2164 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 2165 } 2166 if (msg.arg2 != 0) { 2167 enableScreenAfterBoot(); 2168 } 2169 break; 2170 } 2171 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: { 2172 try { 2173 Locale l = (Locale) msg.obj; 2174 IBinder service = ServiceManager.getService("mount"); 2175 IStorageManager storageManager = IStorageManager.Stub.asInterface(service); 2176 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI"); 2177 storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag()); 2178 } catch (RemoteException e) { 2179 Log.e(TAG, "Error storing locale for decryption UI", e); 2180 } 2181 break; 2182 } 2183 case NOTIFY_CLEARTEXT_NETWORK_MSG: { 2184 final int uid = msg.arg1; 2185 final byte[] firstPacket = (byte[]) msg.obj; 2186 2187 synchronized (mPidsSelfLocked) { 2188 for (int i = 0; i < mPidsSelfLocked.size(); i++) { 2189 final ProcessRecord p = mPidsSelfLocked.valueAt(i); 2190 if (p.uid == uid) { 2191 try { 2192 p.thread.notifyCleartextNetwork(firstPacket); 2193 } catch (RemoteException ignored) { 2194 } 2195 } 2196 } 2197 } 2198 break; 2199 } 2200 case POST_DUMP_HEAP_NOTIFICATION_MSG: { 2201 final String procName; 2202 final int uid; 2203 final long memLimit; 2204 final String reportPackage; 2205 synchronized (ActivityManagerService.this) { 2206 procName = mMemWatchDumpProcName; 2207 uid = mMemWatchDumpUid; 2208 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid); 2209 if (val == null) { 2210 val = mMemWatchProcesses.get(procName, 0); 2211 } 2212 if (val != null) { 2213 memLimit = val.first; 2214 reportPackage = val.second; 2215 } else { 2216 memLimit = 0; 2217 reportPackage = null; 2218 } 2219 } 2220 if (procName == null) { 2221 return; 2222 } 2223 2224 if (DEBUG_PSS) Slog.d(TAG_PSS, 2225 "Showing dump heap notification from " + procName + "/" + uid); 2226 2227 INotificationManager inm = NotificationManager.getService(); 2228 if (inm == null) { 2229 return; 2230 } 2231 2232 String text = mContext.getString(R.string.dump_heap_notification, procName); 2233 2234 2235 Intent deleteIntent = new Intent(); 2236 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP); 2237 Intent intent = new Intent(); 2238 intent.setClassName("android", DumpHeapActivity.class.getName()); 2239 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName); 2240 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit); 2241 if (reportPackage != null) { 2242 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage); 2243 } 2244 int userId = UserHandle.getUserId(uid); 2245 Notification notification = 2246 new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER) 2247 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) 2248 .setWhen(0) 2249 .setOngoing(true) 2250 .setAutoCancel(true) 2251 .setTicker(text) 2252 .setColor(mContext.getColor( 2253 com.android.internal.R.color.system_notification_accent_color)) 2254 .setContentTitle(text) 2255 .setContentText( 2256 mContext.getText(R.string.dump_heap_notification_detail)) 2257 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, 2258 intent, PendingIntent.FLAG_CANCEL_CURRENT, null, 2259 new UserHandle(userId))) 2260 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0, 2261 deleteIntent, 0, UserHandle.SYSTEM)) 2262 .build(); 2263 2264 try { 2265 int[] outId = new int[1]; 2266 inm.enqueueNotificationWithTag("android", "android", null, 2267 R.string.dump_heap_notification, 2268 notification, outId, userId); 2269 } catch (RuntimeException e) { 2270 Slog.w(ActivityManagerService.TAG, 2271 "Error showing notification for dump heap", e); 2272 } catch (RemoteException e) { 2273 } 2274 } break; 2275 case DELETE_DUMPHEAP_MSG: { 2276 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(), 2277 DumpHeapActivity.JAVA_URI, 2278 Intent.FLAG_GRANT_READ_URI_PERMISSION 2279 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 2280 UserHandle.myUserId()); 2281 synchronized (ActivityManagerService.this) { 2282 mMemWatchDumpFile = null; 2283 mMemWatchDumpProcName = null; 2284 mMemWatchDumpPid = -1; 2285 mMemWatchDumpUid = -1; 2286 } 2287 } break; 2288 case FOREGROUND_PROFILE_CHANGED_MSG: { 2289 mUserController.dispatchForegroundProfileChanged(msg.arg1); 2290 } break; 2291 case REPORT_TIME_TRACKER_MSG: { 2292 AppTimeTracker tracker = (AppTimeTracker)msg.obj; 2293 tracker.deliverResult(mContext); 2294 } break; 2295 case REPORT_USER_SWITCH_COMPLETE_MSG: { 2296 mUserController.dispatchUserSwitchComplete(msg.arg1); 2297 } break; 2298 case REPORT_LOCKED_BOOT_COMPLETE_MSG: { 2299 mUserController.dispatchLockedBootComplete(msg.arg1); 2300 } break; 2301 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: { 2302 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj; 2303 try { 2304 connection.shutdown(); 2305 } catch (RemoteException e) { 2306 Slog.w(TAG, "Error shutting down UiAutomationConnection"); 2307 } 2308 // Only a UiAutomation can set this flag and now that 2309 // it is finished we make sure it is reset to its default. 2310 mUserIsMonkey = false; 2311 } break; 2312 case IDLE_UIDS_MSG: { 2313 idleUids(); 2314 } break; 2315 case VR_MODE_CHANGE_MSG: { 2316 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 2317 if (vrService == null) { 2318 break; 2319 } 2320 final ActivityRecord r = (ActivityRecord) msg.obj; 2321 boolean vrMode; 2322 ComponentName requestedPackage; 2323 ComponentName callingPackage; 2324 int userId; 2325 synchronized (ActivityManagerService.this) { 2326 vrMode = r.requestedVrComponent != null; 2327 requestedPackage = r.requestedVrComponent; 2328 userId = r.userId; 2329 callingPackage = r.info.getComponentName(); 2330 if (mInVrMode != vrMode) { 2331 mInVrMode = vrMode; 2332 mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode); 2333 if (r.app != null) { 2334 ProcessRecord proc = r.app; 2335 if (proc.vrThreadTid > 0) { 2336 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { 2337 try { 2338 if (mInVrMode == true) { 2339 Process.setThreadScheduler(proc.vrThreadTid, 2340 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); 2341 } else { 2342 Process.setThreadScheduler(proc.vrThreadTid, 2343 Process.SCHED_OTHER, 0); 2344 } 2345 } catch (IllegalArgumentException e) { 2346 Slog.w(TAG, "Failed to set scheduling policy, thread does" 2347 + " not exist:\n" + e); 2348 } 2349 } 2350 } 2351 } 2352 } 2353 } 2354 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage); 2355 } break; 2356 case NOTIFY_VR_SLEEPING_MSG: { 2357 notifyVrManagerOfSleepState(msg.arg1 != 0); 2358 } break; 2359 case HANDLE_TRUST_STORAGE_UPDATE_MSG: { 2360 synchronized (ActivityManagerService.this) { 2361 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 2362 ProcessRecord r = mLruProcesses.get(i); 2363 if (r.thread != null) { 2364 try { 2365 r.thread.handleTrustStorageUpdate(); 2366 } catch (RemoteException ex) { 2367 Slog.w(TAG, "Failed to handle trust storage update for: " + 2368 r.info.processName); 2369 } 2370 } 2371 } 2372 } 2373 } break; 2374 } 2375 } 2376 }; 2377 2378 static final int COLLECT_PSS_BG_MSG = 1; 2379 2380 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 2381 @Override 2382 public void handleMessage(Message msg) { 2383 switch (msg.what) { 2384 case COLLECT_PSS_BG_MSG: { 2385 long start = SystemClock.uptimeMillis(); 2386 MemInfoReader memInfo = null; 2387 synchronized (ActivityManagerService.this) { 2388 if (mFullPssPending) { 2389 mFullPssPending = false; 2390 memInfo = new MemInfoReader(); 2391 } 2392 } 2393 if (memInfo != null) { 2394 updateCpuStatsNow(); 2395 long nativeTotalPss = 0; 2396 final List<ProcessCpuTracker.Stats> stats; 2397 synchronized (mProcessCpuTracker) { 2398 stats = mProcessCpuTracker.getStats( (st)-> { 2399 return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID; 2400 }); 2401 } 2402 final int N = stats.size(); 2403 for (int j = 0; j < N; j++) { 2404 synchronized (mPidsSelfLocked) { 2405 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) { 2406 // This is one of our own processes; skip it. 2407 continue; 2408 } 2409 } 2410 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null); 2411 } 2412 memInfo.readMemInfo(); 2413 synchronized (ActivityManagerService.this) { 2414 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in " 2415 + (SystemClock.uptimeMillis()-start) + "ms"); 2416 final long cachedKb = memInfo.getCachedSizeKb(); 2417 final long freeKb = memInfo.getFreeSizeKb(); 2418 final long zramKb = memInfo.getZramTotalSizeKb(); 2419 final long kernelKb = memInfo.getKernelUsedSizeKb(); 2420 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024, 2421 kernelKb*1024, nativeTotalPss*1024); 2422 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb, 2423 nativeTotalPss); 2424 } 2425 } 2426 2427 int num = 0; 2428 long[] tmp = new long[2]; 2429 do { 2430 ProcessRecord proc; 2431 int procState; 2432 int pid; 2433 long lastPssTime; 2434 synchronized (ActivityManagerService.this) { 2435 if (mPendingPssProcesses.size() <= 0) { 2436 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS, 2437 "Collected PSS of " + num + " processes in " 2438 + (SystemClock.uptimeMillis() - start) + "ms"); 2439 mPendingPssProcesses.clear(); 2440 return; 2441 } 2442 proc = mPendingPssProcesses.remove(0); 2443 procState = proc.pssProcState; 2444 lastPssTime = proc.lastPssTime; 2445 if (proc.thread != null && procState == proc.setProcState 2446 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE) 2447 < SystemClock.uptimeMillis()) { 2448 pid = proc.pid; 2449 } else { 2450 proc = null; 2451 pid = 0; 2452 } 2453 } 2454 if (proc != null) { 2455 long pss = Debug.getPss(pid, tmp, null); 2456 synchronized (ActivityManagerService.this) { 2457 if (pss != 0 && proc.thread != null && proc.setProcState == procState 2458 && proc.pid == pid && proc.lastPssTime == lastPssTime) { 2459 num++; 2460 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], 2461 SystemClock.uptimeMillis()); 2462 } 2463 } 2464 } 2465 } while (true); 2466 } 2467 } 2468 } 2469 }; 2470 2471 public void setSystemProcess() { 2472 try { 2473 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2474 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2475 ServiceManager.addService("meminfo", new MemBinder(this)); 2476 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2477 ServiceManager.addService("dbinfo", new DbBinder(this)); 2478 if (MONITOR_CPU_USAGE) { 2479 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2480 } 2481 ServiceManager.addService("permission", new PermissionController(this)); 2482 ServiceManager.addService("processinfo", new ProcessInfoService(this)); 2483 2484 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2485 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); 2486 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2487 2488 synchronized (this) { 2489 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2490 app.persistent = true; 2491 app.pid = MY_PID; 2492 app.maxAdj = ProcessList.SYSTEM_ADJ; 2493 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2494 synchronized (mPidsSelfLocked) { 2495 mPidsSelfLocked.put(app.pid, app); 2496 } 2497 updateLruProcessLocked(app, false, null); 2498 updateOomAdjLocked(); 2499 } 2500 } catch (PackageManager.NameNotFoundException e) { 2501 throw new RuntimeException( 2502 "Unable to find android system package", e); 2503 } 2504 } 2505 2506 public void setWindowManager(WindowManagerService wm) { 2507 mWindowManager = wm; 2508 mStackSupervisor.setWindowManager(wm); 2509 mActivityStarter.setWindowManager(wm); 2510 } 2511 2512 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2513 mUsageStatsService = usageStatsManager; 2514 } 2515 2516 public void startObservingNativeCrashes() { 2517 final NativeCrashListener ncl = new NativeCrashListener(this); 2518 ncl.start(); 2519 } 2520 2521 public IAppOpsService getAppOpsService() { 2522 return mAppOpsService; 2523 } 2524 2525 static class MemBinder extends Binder { 2526 ActivityManagerService mActivityManagerService; 2527 MemBinder(ActivityManagerService activityManagerService) { 2528 mActivityManagerService = activityManagerService; 2529 } 2530 2531 @Override 2532 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2533 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2534 != PackageManager.PERMISSION_GRANTED) { 2535 pw.println("Permission Denial: can't dump meminfo from from pid=" 2536 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2537 + " without permission " + android.Manifest.permission.DUMP); 2538 return; 2539 } 2540 2541 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2542 } 2543 } 2544 2545 static class GraphicsBinder extends Binder { 2546 ActivityManagerService mActivityManagerService; 2547 GraphicsBinder(ActivityManagerService activityManagerService) { 2548 mActivityManagerService = activityManagerService; 2549 } 2550 2551 @Override 2552 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2553 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2554 != PackageManager.PERMISSION_GRANTED) { 2555 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2556 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2557 + " without permission " + android.Manifest.permission.DUMP); 2558 return; 2559 } 2560 2561 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2562 } 2563 } 2564 2565 static class DbBinder extends Binder { 2566 ActivityManagerService mActivityManagerService; 2567 DbBinder(ActivityManagerService activityManagerService) { 2568 mActivityManagerService = activityManagerService; 2569 } 2570 2571 @Override 2572 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2573 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2574 != PackageManager.PERMISSION_GRANTED) { 2575 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2576 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2577 + " without permission " + android.Manifest.permission.DUMP); 2578 return; 2579 } 2580 2581 mActivityManagerService.dumpDbInfo(fd, pw, args); 2582 } 2583 } 2584 2585 static class CpuBinder extends Binder { 2586 ActivityManagerService mActivityManagerService; 2587 CpuBinder(ActivityManagerService activityManagerService) { 2588 mActivityManagerService = activityManagerService; 2589 } 2590 2591 @Override 2592 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2593 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2594 != PackageManager.PERMISSION_GRANTED) { 2595 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2596 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2597 + " without permission " + android.Manifest.permission.DUMP); 2598 return; 2599 } 2600 2601 synchronized (mActivityManagerService.mProcessCpuTracker) { 2602 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2603 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2604 SystemClock.uptimeMillis())); 2605 } 2606 } 2607 } 2608 2609 public static final class Lifecycle extends SystemService { 2610 private final ActivityManagerService mService; 2611 2612 public Lifecycle(Context context) { 2613 super(context); 2614 mService = new ActivityManagerService(context); 2615 } 2616 2617 @Override 2618 public void onStart() { 2619 mService.start(); 2620 } 2621 2622 public ActivityManagerService getService() { 2623 return mService; 2624 } 2625 } 2626 2627 @VisibleForTesting 2628 public ActivityManagerService() { 2629 GL_ES_VERSION = 0; 2630 mActivityStarter = null; 2631 mAppErrors = null; 2632 mAppOpsService = null; 2633 mBatteryStatsService = null; 2634 mCompatModePackages = null; 2635 mConstants = null; 2636 mGrantFile = null; 2637 mHandler = null; 2638 mHandlerThread = null; 2639 mIntentFirewall = null; 2640 mKeyguardController = null; 2641 mPermissionReviewRequired = false; 2642 mProcessCpuThread = null; 2643 mProcessStats = null; 2644 mProviderMap = null; 2645 mRecentTasks = null; 2646 mServices = null; 2647 mStackSupervisor = null; 2648 mSystemThread = null; 2649 mTaskChangeNotificationController = null; 2650 mUiHandler = null; 2651 mUserController = null; 2652 } 2653 2654 // Note: This method is invoked on the main thread but may need to attach various 2655 // handlers to other threads. So take care to be explicit about the looper. 2656 public ActivityManagerService(Context systemContext) { 2657 mContext = systemContext; 2658 mFactoryTest = FactoryTest.getMode(); 2659 mSystemThread = ActivityThread.currentActivityThread(); 2660 2661 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2662 2663 mPermissionReviewRequired = mContext.getResources().getBoolean( 2664 com.android.internal.R.bool.config_permissionReviewRequired); 2665 2666 mHandlerThread = new ServiceThread(TAG, 2667 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2668 mHandlerThread.start(); 2669 mHandler = new MainHandler(mHandlerThread.getLooper()); 2670 mUiHandler = new UiHandler(); 2671 2672 mConstants = new ActivityManagerConstants(this, mHandler); 2673 2674 if (DEBUG_BACKGROUND_CHECK) { 2675 Slog.d(TAG, "Enforcing O+ bg restrictions: " + mConstants.ENFORCE_BG_CHECK); 2676 StringBuilder sb = new StringBuilder(200); 2677 sb.append(" "); 2678 for (String a : getBackgroundLaunchBroadcasts()) { 2679 sb.append(' '); sb.append(a); 2680 } 2681 Slog.d(TAG, "Background implicit broadcasts:"); 2682 Slog.d(TAG, sb.toString()); 2683 } 2684 2685 /* static; one-time init here */ 2686 if (sKillHandler == null) { 2687 sKillThread = new ServiceThread(TAG + ":kill", 2688 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */); 2689 sKillThread.start(); 2690 sKillHandler = new KillHandler(sKillThread.getLooper()); 2691 } 2692 2693 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2694 "foreground", BROADCAST_FG_TIMEOUT, false); 2695 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2696 "background", BROADCAST_BG_TIMEOUT, true); 2697 mBroadcastQueues[0] = mFgBroadcastQueue; 2698 mBroadcastQueues[1] = mBgBroadcastQueue; 2699 2700 mServices = new ActiveServices(this); 2701 mProviderMap = new ProviderMap(this); 2702 mAppErrors = new AppErrors(mContext, this); 2703 2704 // TODO: Move creation of battery stats service outside of activity manager service. 2705 File dataDir = Environment.getDataDirectory(); 2706 File systemDir = new File(dataDir, "system"); 2707 systemDir.mkdirs(); 2708 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2709 mBatteryStatsService.getActiveStatistics().readLocked(); 2710 mBatteryStatsService.scheduleWriteToDisk(); 2711 mOnBattery = DEBUG_POWER ? true 2712 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2713 mBatteryStatsService.getActiveStatistics().setCallback(this); 2714 2715 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2716 2717 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2718 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null, 2719 new IAppOpsCallback.Stub() { 2720 @Override public void opChanged(int op, int uid, String packageName) { 2721 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) { 2722 if (mAppOpsService.checkOperation(op, uid, packageName) 2723 != AppOpsManager.MODE_ALLOWED) { 2724 runInBackgroundDisabled(uid); 2725 } 2726 } 2727 } 2728 }); 2729 2730 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2731 2732 mUserController = new UserController(this); 2733 2734 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2735 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2736 2737 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) { 2738 mUseFifoUiScheduling = true; 2739 } 2740 2741 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations")); 2742 mTempConfig.setToDefaults(); 2743 mTempConfig.setLocales(LocaleList.getDefault()); 2744 mConfigurationSeq = mTempConfig.seq = 1; 2745 mStackSupervisor = new ActivityStackSupervisor(this); 2746 mStackSupervisor.onConfigurationChanged(mTempConfig); 2747 mKeyguardController = mStackSupervisor.mKeyguardController; 2748 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2749 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2750 mTaskChangeNotificationController = 2751 new TaskChangeNotificationController(this, mStackSupervisor, mHandler); 2752 mActivityStarter = new ActivityStarter(this, mStackSupervisor); 2753 mRecentTasks = new RecentTasks(this, mStackSupervisor); 2754 2755 mProcessCpuThread = new Thread("CpuTracker") { 2756 @Override 2757 public void run() { 2758 synchronized (mProcessCpuTracker) { 2759 mProcessCpuInitLatch.countDown(); 2760 mProcessCpuTracker.init(); 2761 } 2762 while (true) { 2763 try { 2764 try { 2765 synchronized(this) { 2766 final long now = SystemClock.uptimeMillis(); 2767 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2768 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2769 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2770 // + ", write delay=" + nextWriteDelay); 2771 if (nextWriteDelay < nextCpuDelay) { 2772 nextCpuDelay = nextWriteDelay; 2773 } 2774 if (nextCpuDelay > 0) { 2775 mProcessCpuMutexFree.set(true); 2776 this.wait(nextCpuDelay); 2777 } 2778 } 2779 } catch (InterruptedException e) { 2780 } 2781 updateCpuStatsNow(); 2782 } catch (Exception e) { 2783 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2784 } 2785 } 2786 } 2787 }; 2788 2789 Watchdog.getInstance().addMonitor(this); 2790 Watchdog.getInstance().addThread(mHandler); 2791 } 2792 2793 public void setSystemServiceManager(SystemServiceManager mgr) { 2794 mSystemServiceManager = mgr; 2795 } 2796 2797 public void setInstaller(Installer installer) { 2798 mInstaller = installer; 2799 } 2800 2801 private void start() { 2802 Process.removeAllProcessGroups(); 2803 mProcessCpuThread.start(); 2804 2805 mBatteryStatsService.publish(mContext); 2806 mAppOpsService.publish(mContext); 2807 Slog.d("AppOps", "AppOpsService published"); 2808 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2809 // Wait for the synchronized block started in mProcessCpuThread, 2810 // so that any other acccess to mProcessCpuTracker from main thread 2811 // will be blocked during mProcessCpuTracker initialization. 2812 try { 2813 mProcessCpuInitLatch.await(); 2814 } catch (InterruptedException e) { 2815 Slog.wtf(TAG, "Interrupted wait during start", e); 2816 Thread.currentThread().interrupt(); 2817 throw new IllegalStateException("Interrupted wait during start"); 2818 } 2819 } 2820 2821 void onUserStoppedLocked(int userId) { 2822 mRecentTasks.unloadUserDataFromMemoryLocked(userId); 2823 } 2824 2825 public void initPowerManagement() { 2826 mStackSupervisor.initPowerManagement(); 2827 mBatteryStatsService.initPowerManagement(); 2828 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class); 2829 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); 2830 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*"); 2831 mVoiceWakeLock.setReferenceCounted(false); 2832 } 2833 2834 private ArraySet<String> getBackgroundLaunchBroadcasts() { 2835 if (mBackgroundLaunchBroadcasts == null) { 2836 mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts(); 2837 } 2838 return mBackgroundLaunchBroadcasts; 2839 } 2840 2841 @Override 2842 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2843 throws RemoteException { 2844 if (code == SYSPROPS_TRANSACTION) { 2845 // We need to tell all apps about the system property change. 2846 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2847 synchronized(this) { 2848 final int NP = mProcessNames.getMap().size(); 2849 for (int ip=0; ip<NP; ip++) { 2850 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2851 final int NA = apps.size(); 2852 for (int ia=0; ia<NA; ia++) { 2853 ProcessRecord app = apps.valueAt(ia); 2854 if (app.thread != null) { 2855 procs.add(app.thread.asBinder()); 2856 } 2857 } 2858 } 2859 } 2860 2861 int N = procs.size(); 2862 for (int i=0; i<N; i++) { 2863 Parcel data2 = Parcel.obtain(); 2864 try { 2865 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 2866 Binder.FLAG_ONEWAY); 2867 } catch (RemoteException e) { 2868 } 2869 data2.recycle(); 2870 } 2871 } 2872 try { 2873 return super.onTransact(code, data, reply, flags); 2874 } catch (RuntimeException e) { 2875 // The activity manager only throws security exceptions, so let's 2876 // log all others. 2877 if (!(e instanceof SecurityException)) { 2878 Slog.wtf(TAG, "Activity Manager Crash", e); 2879 } 2880 throw e; 2881 } 2882 } 2883 2884 void updateCpuStats() { 2885 final long now = SystemClock.uptimeMillis(); 2886 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2887 return; 2888 } 2889 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2890 synchronized (mProcessCpuThread) { 2891 mProcessCpuThread.notify(); 2892 } 2893 } 2894 } 2895 2896 void updateCpuStatsNow() { 2897 synchronized (mProcessCpuTracker) { 2898 mProcessCpuMutexFree.set(false); 2899 final long now = SystemClock.uptimeMillis(); 2900 boolean haveNewCpuStats = false; 2901 2902 if (MONITOR_CPU_USAGE && 2903 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2904 mLastCpuTime.set(now); 2905 mProcessCpuTracker.update(); 2906 if (mProcessCpuTracker.hasGoodLastStats()) { 2907 haveNewCpuStats = true; 2908 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2909 //Slog.i(TAG, "Total CPU usage: " 2910 // + mProcessCpu.getTotalCpuPercent() + "%"); 2911 2912 // Slog the cpu usage if the property is set. 2913 if ("true".equals(SystemProperties.get("events.cpu"))) { 2914 int user = mProcessCpuTracker.getLastUserTime(); 2915 int system = mProcessCpuTracker.getLastSystemTime(); 2916 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2917 int irq = mProcessCpuTracker.getLastIrqTime(); 2918 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2919 int idle = mProcessCpuTracker.getLastIdleTime(); 2920 2921 int total = user + system + iowait + irq + softIrq + idle; 2922 if (total == 0) total = 1; 2923 2924 EventLog.writeEvent(EventLogTags.CPU, 2925 ((user+system+iowait+irq+softIrq) * 100) / total, 2926 (user * 100) / total, 2927 (system * 100) / total, 2928 (iowait * 100) / total, 2929 (irq * 100) / total, 2930 (softIrq * 100) / total); 2931 } 2932 } 2933 } 2934 2935 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2936 synchronized(bstats) { 2937 synchronized(mPidsSelfLocked) { 2938 if (haveNewCpuStats) { 2939 if (bstats.startAddingCpuLocked()) { 2940 int totalUTime = 0; 2941 int totalSTime = 0; 2942 final int N = mProcessCpuTracker.countStats(); 2943 for (int i=0; i<N; i++) { 2944 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2945 if (!st.working) { 2946 continue; 2947 } 2948 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2949 totalUTime += st.rel_utime; 2950 totalSTime += st.rel_stime; 2951 if (pr != null) { 2952 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2953 if (ps == null || !ps.isActive()) { 2954 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2955 pr.info.uid, pr.processName); 2956 } 2957 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 2958 pr.curCpuTime += st.rel_utime + st.rel_stime; 2959 } else { 2960 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2961 if (ps == null || !ps.isActive()) { 2962 st.batteryStats = ps = bstats.getProcessStatsLocked( 2963 bstats.mapUid(st.uid), st.name); 2964 } 2965 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); 2966 } 2967 } 2968 final int userTime = mProcessCpuTracker.getLastUserTime(); 2969 final int systemTime = mProcessCpuTracker.getLastSystemTime(); 2970 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime(); 2971 final int irqTime = mProcessCpuTracker.getLastIrqTime(); 2972 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime(); 2973 final int idleTime = mProcessCpuTracker.getLastIdleTime(); 2974 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime, 2975 systemTime, iowaitTime, irqTime, softIrqTime, idleTime); 2976 } 2977 } 2978 } 2979 2980 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2981 mLastWriteTime = now; 2982 mBatteryStatsService.scheduleWriteToDisk(); 2983 } 2984 } 2985 } 2986 } 2987 2988 @Override 2989 public void batteryNeedsCpuUpdate() { 2990 updateCpuStatsNow(); 2991 } 2992 2993 @Override 2994 public void batteryPowerChanged(boolean onBattery) { 2995 // When plugging in, update the CPU stats first before changing 2996 // the plug state. 2997 updateCpuStatsNow(); 2998 synchronized (this) { 2999 synchronized(mPidsSelfLocked) { 3000 mOnBattery = DEBUG_POWER ? true : onBattery; 3001 } 3002 } 3003 } 3004 3005 @Override 3006 public void batterySendBroadcast(Intent intent) { 3007 synchronized (this) { 3008 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 3009 AppOpsManager.OP_NONE, null, false, false, 3010 -1, Process.SYSTEM_UID, UserHandle.USER_ALL); 3011 } 3012 } 3013 3014 /** 3015 * Initialize the application bind args. These are passed to each 3016 * process when the bindApplication() IPC is sent to the process. They're 3017 * lazily setup to make sure the services are running when they're asked for. 3018 */ 3019 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { 3020 // Isolated processes won't get this optimization, so that we don't 3021 // violate the rules about which services they have access to. 3022 if (isolated) { 3023 if (mIsolatedAppBindArgs == null) { 3024 mIsolatedAppBindArgs = new HashMap<>(); 3025 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package")); 3026 } 3027 return mIsolatedAppBindArgs; 3028 } 3029 3030 if (mAppBindArgs == null) { 3031 mAppBindArgs = new HashMap<>(); 3032 3033 // Setup the application init args 3034 mAppBindArgs.put("package", ServiceManager.getService("package")); 3035 mAppBindArgs.put("window", ServiceManager.getService("window")); 3036 mAppBindArgs.put(Context.ALARM_SERVICE, 3037 ServiceManager.getService(Context.ALARM_SERVICE)); 3038 } 3039 return mAppBindArgs; 3040 } 3041 3042 /** 3043 * Update AMS states when an activity is resumed. This should only be called by 3044 * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed. 3045 */ 3046 void setResumedActivityUncheckLocked(ActivityRecord r, String reason) { 3047 if (r.task.isApplicationTask()) { 3048 if (mCurAppTimeTracker != r.appTimeTracker) { 3049 // We are switching app tracking. Complete the current one. 3050 if (mCurAppTimeTracker != null) { 3051 mCurAppTimeTracker.stop(); 3052 mHandler.obtainMessage( 3053 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget(); 3054 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker); 3055 mCurAppTimeTracker = null; 3056 } 3057 if (r.appTimeTracker != null) { 3058 mCurAppTimeTracker = r.appTimeTracker; 3059 startTimeTrackingFocusedActivityLocked(); 3060 } 3061 } else { 3062 startTimeTrackingFocusedActivityLocked(); 3063 } 3064 } else { 3065 r.appTimeTracker = null; 3066 } 3067 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null 3068 // TODO: Probably not, because we don't want to resume voice on switching 3069 // back to this activity 3070 if (r.task.voiceInteractor != null) { 3071 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid); 3072 } else { 3073 finishRunningVoiceLocked(); 3074 3075 if (mLastResumedActivity != null) { 3076 final IVoiceInteractionSession session; 3077 3078 if (mLastResumedActivity.task != null 3079 && mLastResumedActivity.task.voiceSession != null) { 3080 session = mLastResumedActivity.task.voiceSession; 3081 } else { 3082 session = mLastResumedActivity.voiceSession; 3083 } 3084 3085 if (session != null) { 3086 // We had been in a voice interaction session, but now focused has 3087 // move to something different. Just finish the session, we can't 3088 // return to it and retain the proper state and synchronization with 3089 // the voice interaction service. 3090 finishVoiceTask(session); 3091 } 3092 } 3093 } 3094 3095 mWindowManager.setFocusedApp(r.appToken, true); 3096 3097 applyUpdateLockStateLocked(r); 3098 applyUpdateVrModeLocked(r); 3099 if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) { 3100 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG); 3101 mHandler.obtainMessage( 3102 FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget(); 3103 } 3104 3105 mLastResumedActivity = r; 3106 3107 EventLogTags.writeAmSetResumedActivity( 3108 r == null ? -1 : r.userId, 3109 r == null ? "NULL" : r.shortComponentName, 3110 reason); 3111 } 3112 3113 @Override 3114 public void setFocusedStack(int stackId) { 3115 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()"); 3116 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId); 3117 final long callingId = Binder.clearCallingIdentity(); 3118 try { 3119 synchronized (this) { 3120 final ActivityStack stack = mStackSupervisor.getStack(stackId); 3121 if (stack == null) { 3122 return; 3123 } 3124 final ActivityRecord r = stack.topRunningActivityLocked(); 3125 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) { 3126 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 3127 } 3128 } 3129 } finally { 3130 Binder.restoreCallingIdentity(callingId); 3131 } 3132 } 3133 3134 @Override 3135 public void setFocusedTask(int taskId) { 3136 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()"); 3137 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId); 3138 final long callingId = Binder.clearCallingIdentity(); 3139 try { 3140 synchronized (this) { 3141 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 3142 if (task == null) { 3143 return; 3144 } 3145 final ActivityRecord r = task.topRunningActivityLocked(); 3146 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) { 3147 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 3148 } 3149 } 3150 } finally { 3151 Binder.restoreCallingIdentity(callingId); 3152 } 3153 } 3154 3155 /** Sets the task stack listener that gets callbacks when a task stack changes. */ 3156 @Override 3157 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException { 3158 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()"); 3159 mTaskChangeNotificationController.registerTaskStackListener(listener); 3160 } 3161 3162 /** 3163 * Unregister a task stack listener so that it stops receiving callbacks. 3164 */ 3165 @Override 3166 public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException { 3167 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()"); 3168 mTaskChangeNotificationController.unregisterTaskStackListener(listener); 3169 } 3170 3171 @Override 3172 public void notifyActivityDrawn(IBinder token) { 3173 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token); 3174 synchronized (this) { 3175 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token); 3176 if (r != null) { 3177 r.getStack().notifyActivityDrawnLocked(r); 3178 } 3179 } 3180 } 3181 3182 final void applyUpdateLockStateLocked(ActivityRecord r) { 3183 // Modifications to the UpdateLock state are done on our handler, outside 3184 // the activity manager's locks. The new state is determined based on the 3185 // state *now* of the relevant activity record. The object is passed to 3186 // the handler solely for logging detail, not to be consulted/modified. 3187 final boolean nextState = r != null && r.immersive; 3188 mHandler.sendMessage( 3189 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 3190 } 3191 3192 final void applyUpdateVrModeLocked(ActivityRecord r) { 3193 mHandler.sendMessage( 3194 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r)); 3195 } 3196 3197 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) { 3198 mHandler.sendMessage( 3199 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0)); 3200 } 3201 3202 private void notifyVrManagerOfSleepState(boolean isSleeping) { 3203 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 3204 if (vrService == null) { 3205 return; 3206 } 3207 vrService.onSleepStateChanged(isSleeping); 3208 } 3209 3210 final void showAskCompatModeDialogLocked(ActivityRecord r) { 3211 Message msg = Message.obtain(); 3212 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG; 3213 msg.obj = r.task.askedCompatMode ? null : r; 3214 mUiHandler.sendMessage(msg); 3215 } 3216 3217 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) { 3218 final Configuration globalConfig = getGlobalConfiguration(); 3219 if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE 3220 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) { 3221 final Message msg = Message.obtain(); 3222 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG; 3223 msg.obj = r; 3224 mUiHandler.sendMessage(msg); 3225 } 3226 } 3227 3228 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 3229 String what, Object obj, ProcessRecord srcApp) { 3230 app.lastActivityTime = now; 3231 3232 if (app.activities.size() > 0) { 3233 // Don't want to touch dependent processes that are hosting activities. 3234 return index; 3235 } 3236 3237 int lrui = mLruProcesses.lastIndexOf(app); 3238 if (lrui < 0) { 3239 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 3240 + what + " " + obj + " from " + srcApp); 3241 return index; 3242 } 3243 3244 if (lrui >= index) { 3245 // Don't want to cause this to move dependent processes *back* in the 3246 // list as if they were less frequently used. 3247 return index; 3248 } 3249 3250 if (lrui >= mLruProcessActivityStart) { 3251 // Don't want to touch dependent processes that are hosting activities. 3252 return index; 3253 } 3254 3255 mLruProcesses.remove(lrui); 3256 if (index > 0) { 3257 index--; 3258 } 3259 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index 3260 + " in LRU list: " + app); 3261 mLruProcesses.add(index, app); 3262 return index; 3263 } 3264 3265 static void killProcessGroup(int uid, int pid) { 3266 if (sKillHandler != null) { 3267 sKillHandler.sendMessage( 3268 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid)); 3269 } else { 3270 Slog.w(TAG, "Asked to kill process group before system bringup!"); 3271 Process.killProcessGroup(uid, pid); 3272 } 3273 } 3274 3275 final void removeLruProcessLocked(ProcessRecord app) { 3276 int lrui = mLruProcesses.lastIndexOf(app); 3277 if (lrui >= 0) { 3278 if (!app.killed) { 3279 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 3280 Process.killProcessQuiet(app.pid); 3281 killProcessGroup(app.uid, app.pid); 3282 } 3283 if (lrui <= mLruProcessActivityStart) { 3284 mLruProcessActivityStart--; 3285 } 3286 if (lrui <= mLruProcessServiceStart) { 3287 mLruProcessServiceStart--; 3288 } 3289 mLruProcesses.remove(lrui); 3290 } 3291 } 3292 3293 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 3294 ProcessRecord client) { 3295 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 3296 || app.treatLikeActivity; 3297 final boolean hasService = false; // not impl yet. app.services.size() > 0; 3298 if (!activityChange && hasActivity) { 3299 // The process has activities, so we are only allowing activity-based adjustments 3300 // to move it. It should be kept in the front of the list with other 3301 // processes that have activities, and we don't want those to change their 3302 // order except due to activity operations. 3303 return; 3304 } 3305 3306 mLruSeq++; 3307 final long now = SystemClock.uptimeMillis(); 3308 app.lastActivityTime = now; 3309 3310 // First a quick reject: if the app is already at the position we will 3311 // put it, then there is nothing to do. 3312 if (hasActivity) { 3313 final int N = mLruProcesses.size(); 3314 if (N > 0 && mLruProcesses.get(N-1) == app) { 3315 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app); 3316 return; 3317 } 3318 } else { 3319 if (mLruProcessServiceStart > 0 3320 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 3321 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app); 3322 return; 3323 } 3324 } 3325 3326 int lrui = mLruProcesses.lastIndexOf(app); 3327 3328 if (app.persistent && lrui >= 0) { 3329 // We don't care about the position of persistent processes, as long as 3330 // they are in the list. 3331 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app); 3332 return; 3333 } 3334 3335 /* In progress: compute new position first, so we can avoid doing work 3336 if the process is not actually going to move. Not yet working. 3337 int addIndex; 3338 int nextIndex; 3339 boolean inActivity = false, inService = false; 3340 if (hasActivity) { 3341 // Process has activities, put it at the very tipsy-top. 3342 addIndex = mLruProcesses.size(); 3343 nextIndex = mLruProcessServiceStart; 3344 inActivity = true; 3345 } else if (hasService) { 3346 // Process has services, put it at the top of the service list. 3347 addIndex = mLruProcessActivityStart; 3348 nextIndex = mLruProcessServiceStart; 3349 inActivity = true; 3350 inService = true; 3351 } else { 3352 // Process not otherwise of interest, it goes to the top of the non-service area. 3353 addIndex = mLruProcessServiceStart; 3354 if (client != null) { 3355 int clientIndex = mLruProcesses.lastIndexOf(client); 3356 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 3357 + app); 3358 if (clientIndex >= 0 && addIndex > clientIndex) { 3359 addIndex = clientIndex; 3360 } 3361 } 3362 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 3363 } 3364 3365 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 3366 + mLruProcessActivityStart + "): " + app); 3367 */ 3368 3369 if (lrui >= 0) { 3370 if (lrui < mLruProcessActivityStart) { 3371 mLruProcessActivityStart--; 3372 } 3373 if (lrui < mLruProcessServiceStart) { 3374 mLruProcessServiceStart--; 3375 } 3376 /* 3377 if (addIndex > lrui) { 3378 addIndex--; 3379 } 3380 if (nextIndex > lrui) { 3381 nextIndex--; 3382 } 3383 */ 3384 mLruProcesses.remove(lrui); 3385 } 3386 3387 /* 3388 mLruProcesses.add(addIndex, app); 3389 if (inActivity) { 3390 mLruProcessActivityStart++; 3391 } 3392 if (inService) { 3393 mLruProcessActivityStart++; 3394 } 3395 */ 3396 3397 int nextIndex; 3398 if (hasActivity) { 3399 final int N = mLruProcesses.size(); 3400 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) { 3401 // Process doesn't have activities, but has clients with 3402 // activities... move it up, but one below the top (the top 3403 // should always have a real activity). 3404 if (DEBUG_LRU) Slog.d(TAG_LRU, 3405 "Adding to second-top of LRU activity list: " + app); 3406 mLruProcesses.add(N - 1, app); 3407 // To keep it from spamming the LRU list (by making a bunch of clients), 3408 // we will push down any other entries owned by the app. 3409 final int uid = app.info.uid; 3410 for (int i = N - 2; i > mLruProcessActivityStart; i--) { 3411 ProcessRecord subProc = mLruProcesses.get(i); 3412 if (subProc.info.uid == uid) { 3413 // We want to push this one down the list. If the process after 3414 // it is for the same uid, however, don't do so, because we don't 3415 // want them internally to be re-ordered. 3416 if (mLruProcesses.get(i - 1).info.uid != uid) { 3417 if (DEBUG_LRU) Slog.d(TAG_LRU, 3418 "Pushing uid " + uid + " swapping at " + i + ": " 3419 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1)); 3420 ProcessRecord tmp = mLruProcesses.get(i); 3421 mLruProcesses.set(i, mLruProcesses.get(i - 1)); 3422 mLruProcesses.set(i - 1, tmp); 3423 i--; 3424 } 3425 } else { 3426 // A gap, we can stop here. 3427 break; 3428 } 3429 } 3430 } else { 3431 // Process has activities, put it at the very tipsy-top. 3432 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app); 3433 mLruProcesses.add(app); 3434 } 3435 nextIndex = mLruProcessServiceStart; 3436 } else if (hasService) { 3437 // Process has services, put it at the top of the service list. 3438 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app); 3439 mLruProcesses.add(mLruProcessActivityStart, app); 3440 nextIndex = mLruProcessServiceStart; 3441 mLruProcessActivityStart++; 3442 } else { 3443 // Process not otherwise of interest, it goes to the top of the non-service area. 3444 int index = mLruProcessServiceStart; 3445 if (client != null) { 3446 // If there is a client, don't allow the process to be moved up higher 3447 // in the list than that client. 3448 int clientIndex = mLruProcesses.lastIndexOf(client); 3449 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client 3450 + " when updating " + app); 3451 if (clientIndex <= lrui) { 3452 // Don't allow the client index restriction to push it down farther in the 3453 // list than it already is. 3454 clientIndex = lrui; 3455 } 3456 if (clientIndex >= 0 && index > clientIndex) { 3457 index = clientIndex; 3458 } 3459 } 3460 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app); 3461 mLruProcesses.add(index, app); 3462 nextIndex = index-1; 3463 mLruProcessActivityStart++; 3464 mLruProcessServiceStart++; 3465 } 3466 3467 // If the app is currently using a content provider or service, 3468 // bump those processes as well. 3469 for (int j=app.connections.size()-1; j>=0; j--) { 3470 ConnectionRecord cr = app.connections.valueAt(j); 3471 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 3472 && cr.binding.service.app != null 3473 && cr.binding.service.app.lruSeq != mLruSeq 3474 && !cr.binding.service.app.persistent) { 3475 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 3476 "service connection", cr, app); 3477 } 3478 } 3479 for (int j=app.conProviders.size()-1; j>=0; j--) { 3480 ContentProviderRecord cpr = app.conProviders.get(j).provider; 3481 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 3482 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 3483 "provider reference", cpr, app); 3484 } 3485 } 3486 } 3487 3488 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 3489 if (uid == Process.SYSTEM_UID) { 3490 // The system gets to run in any process. If there are multiple 3491 // processes with the same uid, just pick the first (this 3492 // should never happen). 3493 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 3494 if (procs == null) return null; 3495 final int procCount = procs.size(); 3496 for (int i = 0; i < procCount; i++) { 3497 final int procUid = procs.keyAt(i); 3498 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) { 3499 // Don't use an app process or different user process for system component. 3500 continue; 3501 } 3502 return procs.valueAt(i); 3503 } 3504 } 3505 ProcessRecord proc = mProcessNames.get(processName, uid); 3506 if (false && proc != null && !keepIfLarge 3507 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 3508 && proc.lastCachedPss >= 4000) { 3509 // Turn this condition on to cause killing to happen regularly, for testing. 3510 if (proc.baseProcessTracker != null) { 3511 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 3512 } 3513 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 3514 } else if (proc != null && !keepIfLarge 3515 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 3516 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 3517 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 3518 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 3519 if (proc.baseProcessTracker != null) { 3520 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 3521 } 3522 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 3523 } 3524 } 3525 return proc; 3526 } 3527 3528 void notifyPackageUse(String packageName, int reason) { 3529 IPackageManager pm = AppGlobals.getPackageManager(); 3530 try { 3531 pm.notifyPackageUse(packageName, reason); 3532 } catch (RemoteException e) { 3533 } 3534 } 3535 3536 boolean isNextTransitionForward() { 3537 int transit = mWindowManager.getPendingAppTransition(); 3538 return transit == TRANSIT_ACTIVITY_OPEN 3539 || transit == TRANSIT_TASK_OPEN 3540 || transit == TRANSIT_TASK_TO_FRONT; 3541 } 3542 3543 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 3544 String processName, String abiOverride, int uid, Runnable crashHandler) { 3545 synchronized(this) { 3546 ApplicationInfo info = new ApplicationInfo(); 3547 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 3548 // For isolated processes, the former contains the parent's uid and the latter the 3549 // actual uid of the isolated process. 3550 // In the special case introduced by this method (which is, starting an isolated 3551 // process directly from the SystemServer without an actual parent app process) the 3552 // closest thing to a parent's uid is SYSTEM_UID. 3553 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 3554 // the |isolated| logic in the ProcessRecord constructor. 3555 info.uid = Process.SYSTEM_UID; 3556 info.processName = processName; 3557 info.className = entryPoint; 3558 info.packageName = "android"; 3559 info.seInfoUser = SELinuxUtil.COMPLETE_STR; 3560 ProcessRecord proc = startProcessLocked(processName, info /* info */, 3561 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 3562 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 3563 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 3564 crashHandler); 3565 return proc != null ? proc.pid : 0; 3566 } 3567 } 3568 3569 final ProcessRecord startProcessLocked(String processName, 3570 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 3571 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 3572 boolean isolated, boolean keepIfLarge) { 3573 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 3574 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 3575 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 3576 null /* crashHandler */); 3577 } 3578 3579 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 3580 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 3581 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 3582 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 3583 long startTime = SystemClock.elapsedRealtime(); 3584 ProcessRecord app; 3585 if (!isolated) { 3586 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 3587 checkTime(startTime, "startProcess: after getProcessRecord"); 3588 3589 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) { 3590 // If we are in the background, then check to see if this process 3591 // is bad. If so, we will just silently fail. 3592 if (mAppErrors.isBadProcessLocked(info)) { 3593 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 3594 + "/" + info.processName); 3595 return null; 3596 } 3597 } else { 3598 // When the user is explicitly starting a process, then clear its 3599 // crash count so that we won't make it bad until they see at 3600 // least one crash dialog again, and make the process good again 3601 // if it had been bad. 3602 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 3603 + "/" + info.processName); 3604 mAppErrors.resetProcessCrashTimeLocked(info); 3605 if (mAppErrors.isBadProcessLocked(info)) { 3606 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 3607 UserHandle.getUserId(info.uid), info.uid, 3608 info.processName); 3609 mAppErrors.clearBadProcessLocked(info); 3610 if (app != null) { 3611 app.bad = false; 3612 } 3613 } 3614 } 3615 } else { 3616 // If this is an isolated process, it can't re-use an existing process. 3617 app = null; 3618 } 3619 3620 // We don't have to do anything more if: 3621 // (1) There is an existing application record; and 3622 // (2) The caller doesn't think it is dead, OR there is no thread 3623 // object attached to it so we know it couldn't have crashed; and 3624 // (3) There is a pid assigned to it, so it is either starting or 3625 // already running. 3626 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName 3627 + " app=" + app + " knownToBeDead=" + knownToBeDead 3628 + " thread=" + (app != null ? app.thread : null) 3629 + " pid=" + (app != null ? app.pid : -1)); 3630 if (app != null && app.pid > 0) { 3631 if ((!knownToBeDead && !app.killed) || app.thread == null) { 3632 // We already have the app running, or are waiting for it to 3633 // come up (we have a pid but not yet its thread), so keep it. 3634 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app); 3635 // If this is a new package in the process, add the package to the list 3636 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3637 checkTime(startTime, "startProcess: done, added package to proc"); 3638 return app; 3639 } 3640 3641 // An application record is attached to a previous process, 3642 // clean it up now. 3643 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app); 3644 checkTime(startTime, "startProcess: bad proc running, killing"); 3645 killProcessGroup(app.uid, app.pid); 3646 handleAppDiedLocked(app, true, true); 3647 checkTime(startTime, "startProcess: done killing old proc"); 3648 } 3649 3650 String hostingNameStr = hostingName != null 3651 ? hostingName.flattenToShortString() : null; 3652 3653 if (app == null) { 3654 checkTime(startTime, "startProcess: creating new process record"); 3655 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 3656 if (app == null) { 3657 Slog.w(TAG, "Failed making new process record for " 3658 + processName + "/" + info.uid + " isolated=" + isolated); 3659 return null; 3660 } 3661 app.crashHandler = crashHandler; 3662 checkTime(startTime, "startProcess: done creating new process record"); 3663 } else { 3664 // If this is a new package in the process, add the package to the list 3665 app.addPackage(info.packageName, info.versionCode, mProcessStats); 3666 checkTime(startTime, "startProcess: added package to existing proc"); 3667 } 3668 3669 // If the system is not ready yet, then hold off on starting this 3670 // process until it is. 3671 if (!mProcessesReady 3672 && !isAllowedWhileBooting(info) 3673 && !allowWhileBooting) { 3674 if (!mProcessesOnHold.contains(app)) { 3675 mProcessesOnHold.add(app); 3676 } 3677 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, 3678 "System not ready, putting on hold: " + app); 3679 checkTime(startTime, "startProcess: returning with proc on hold"); 3680 return app; 3681 } 3682 3683 checkTime(startTime, "startProcess: stepping in to startProcess"); 3684 startProcessLocked( 3685 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3686 checkTime(startTime, "startProcess: done starting proc!"); 3687 return (app.pid != 0) ? app : null; 3688 } 3689 3690 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3691 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3692 } 3693 3694 private final void startProcessLocked(ProcessRecord app, 3695 String hostingType, String hostingNameStr) { 3696 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3697 null /* entryPoint */, null /* entryPointArgs */); 3698 } 3699 3700 private final void startProcessLocked(ProcessRecord app, String hostingType, 3701 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3702 long startTime = SystemClock.elapsedRealtime(); 3703 if (app.pid > 0 && app.pid != MY_PID) { 3704 checkTime(startTime, "startProcess: removing from pids map"); 3705 synchronized (mPidsSelfLocked) { 3706 mPidsSelfLocked.remove(app.pid); 3707 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3708 } 3709 checkTime(startTime, "startProcess: done removing from pids map"); 3710 app.setPid(0); 3711 } 3712 3713 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES, 3714 "startProcessLocked removing on hold: " + app); 3715 mProcessesOnHold.remove(app); 3716 3717 checkTime(startTime, "startProcess: starting to update cpu stats"); 3718 updateCpuStats(); 3719 checkTime(startTime, "startProcess: done updating cpu stats"); 3720 3721 try { 3722 try { 3723 final int userId = UserHandle.getUserId(app.uid); 3724 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId); 3725 } catch (RemoteException e) { 3726 throw e.rethrowAsRuntimeException(); 3727 } 3728 3729 int uid = app.uid; 3730 int[] gids = null; 3731 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3732 if (!app.isolated) { 3733 int[] permGids = null; 3734 try { 3735 checkTime(startTime, "startProcess: getting gids from package manager"); 3736 final IPackageManager pm = AppGlobals.getPackageManager(); 3737 permGids = pm.getPackageGids(app.info.packageName, 3738 MATCH_DEBUG_TRIAGED_MISSING, app.userId); 3739 StorageManagerInternal storageManagerInternal = LocalServices.getService( 3740 StorageManagerInternal.class); 3741 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, 3742 app.info.packageName); 3743 } catch (RemoteException e) { 3744 throw e.rethrowAsRuntimeException(); 3745 } 3746 3747 /* 3748 * Add shared application and profile GIDs so applications can share some 3749 * resources like shared libraries and access user-wide resources 3750 */ 3751 if (ArrayUtils.isEmpty(permGids)) { 3752 gids = new int[3]; 3753 } else { 3754 gids = new int[permGids.length + 3]; 3755 System.arraycopy(permGids, 0, gids, 3, permGids.length); 3756 } 3757 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3758 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid)); 3759 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3760 } 3761 checkTime(startTime, "startProcess: building args"); 3762 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3763 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3764 && mTopComponent != null 3765 && app.processName.equals(mTopComponent.getPackageName())) { 3766 uid = 0; 3767 } 3768 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3769 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3770 uid = 0; 3771 } 3772 } 3773 int debugFlags = 0; 3774 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3775 debugFlags |= Zygote.DEBUG_ENABLE_JDWP; 3776 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE; 3777 // Also turn on CheckJNI for debuggable apps. It's quite 3778 // awkward to turn on otherwise. 3779 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3780 } 3781 // Run the app in safe mode if its manifest requests so or the 3782 // system is booted in safe mode. 3783 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3784 mSafeMode == true) { 3785 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3786 } 3787 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3788 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3789 } 3790 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info"); 3791 if ("true".equals(genDebugInfoProperty)) { 3792 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; 3793 } 3794 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3795 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3796 } 3797 if ("1".equals(SystemProperties.get("debug.assert"))) { 3798 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3799 } 3800 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) { 3801 // Enable all debug flags required by the native debugger. 3802 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything 3803 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info 3804 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations 3805 mNativeDebuggingApp = null; 3806 } 3807 3808 String invokeWith = null; 3809 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3810 // Debuggable apps may include a wrapper script with their library directory. 3811 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; 3812 if (new File(wrapperFileName).exists()) { 3813 invokeWith = "/system/bin/logwrapper " + wrapperFileName; 3814 } 3815 } 3816 3817 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3818 if (requiredAbi == null) { 3819 requiredAbi = Build.SUPPORTED_ABIS[0]; 3820 } 3821 3822 String instructionSet = null; 3823 if (app.info.primaryCpuAbi != null) { 3824 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 3825 } 3826 3827 app.gids = gids; 3828 app.requiredAbi = requiredAbi; 3829 app.instructionSet = instructionSet; 3830 3831 // the per-user SELinux context must be set 3832 if (TextUtils.isEmpty(app.info.seInfoUser)) { 3833 Slog.wtf(TAG, "SELinux tag not defined", 3834 new IllegalStateException("SELinux tag not defined")); 3835 } 3836 final String seInfo = app.info.seInfo 3837 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser); 3838 // Start the process. It will either succeed and return a result containing 3839 // the PID of the new process, or else throw a RuntimeException. 3840 boolean isActivityProcess = (entryPoint == null); 3841 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3842 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + 3843 app.processName); 3844 checkTime(startTime, "startProcess: asking zygote to start proc"); 3845 Process.ProcessStartResult startResult; 3846 if (hostingType.equals("webview_service")) { 3847 startResult = Process.startWebView(entryPoint, 3848 app.processName, uid, uid, gids, debugFlags, mountExternal, 3849 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 3850 app.info.dataDir, null, entryPointArgs); 3851 } else { 3852 startResult = Process.start(entryPoint, 3853 app.processName, uid, uid, gids, debugFlags, mountExternal, 3854 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 3855 app.info.dataDir, invokeWith, entryPointArgs); 3856 } 3857 checkTime(startTime, "startProcess: returned from zygote!"); 3858 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 3859 3860 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3861 checkTime(startTime, "startProcess: done updating battery stats"); 3862 3863 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3864 UserHandle.getUserId(uid), startResult.pid, uid, 3865 app.processName, hostingType, 3866 hostingNameStr != null ? hostingNameStr : ""); 3867 3868 try { 3869 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid, 3870 seInfo, app.info.sourceDir, startResult.pid); 3871 } catch (RemoteException ex) { 3872 // Ignore 3873 } 3874 3875 if (app.persistent) { 3876 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3877 } 3878 3879 checkTime(startTime, "startProcess: building log message"); 3880 StringBuilder buf = mStringBuilder; 3881 buf.setLength(0); 3882 buf.append("Start proc "); 3883 buf.append(startResult.pid); 3884 buf.append(':'); 3885 buf.append(app.processName); 3886 buf.append('/'); 3887 UserHandle.formatUid(buf, uid); 3888 if (!isActivityProcess) { 3889 buf.append(" ["); 3890 buf.append(entryPoint); 3891 buf.append("]"); 3892 } 3893 buf.append(" for "); 3894 buf.append(hostingType); 3895 if (hostingNameStr != null) { 3896 buf.append(" "); 3897 buf.append(hostingNameStr); 3898 } 3899 Slog.i(TAG, buf.toString()); 3900 app.setPid(startResult.pid); 3901 app.usingWrapper = startResult.usingWrapper; 3902 app.removed = false; 3903 app.killed = false; 3904 app.killedByAm = false; 3905 checkTime(startTime, "startProcess: starting to update pids map"); 3906 ProcessRecord oldApp; 3907 synchronized (mPidsSelfLocked) { 3908 oldApp = mPidsSelfLocked.get(startResult.pid); 3909 } 3910 // If there is already an app occupying that pid that hasn't been cleaned up 3911 if (oldApp != null && !app.isolated) { 3912 // Clean up anything relating to this pid first 3913 Slog.w(TAG, "Reusing pid " + startResult.pid 3914 + " while app is still mapped to it"); 3915 cleanUpApplicationRecordLocked(oldApp, false, false, -1, 3916 true /*replacingPid*/); 3917 } 3918 synchronized (mPidsSelfLocked) { 3919 this.mPidsSelfLocked.put(startResult.pid, app); 3920 if (isActivityProcess) { 3921 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3922 msg.obj = app; 3923 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3924 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3925 } 3926 } 3927 checkTime(startTime, "startProcess: done updating pids map"); 3928 } catch (RuntimeException e) { 3929 Slog.e(TAG, "Failure starting process " + app.processName, e); 3930 3931 // Something went very wrong while trying to start this process; one 3932 // common case is when the package is frozen due to an active 3933 // upgrade. To recover, clean up any active bookkeeping related to 3934 // starting this process. (We already invoked this method once when 3935 // the package was initially frozen through KILL_APPLICATION_MSG, so 3936 // it doesn't hurt to use it again.) 3937 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false, 3938 false, true, false, false, UserHandle.getUserId(app.userId), "start failure"); 3939 } 3940 } 3941 3942 void updateUsageStats(ActivityRecord component, boolean resumed) { 3943 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, 3944 "updateUsageStats: comp=" + component + "res=" + resumed); 3945 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3946 if (resumed) { 3947 if (mUsageStatsService != null) { 3948 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3949 UsageEvents.Event.MOVE_TO_FOREGROUND); 3950 } 3951 synchronized (stats) { 3952 stats.noteActivityResumedLocked(component.app.uid); 3953 } 3954 } else { 3955 if (mUsageStatsService != null) { 3956 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3957 UsageEvents.Event.MOVE_TO_BACKGROUND); 3958 } 3959 synchronized (stats) { 3960 stats.noteActivityPausedLocked(component.app.uid); 3961 } 3962 } 3963 } 3964 3965 Intent getHomeIntent() { 3966 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3967 intent.setComponent(mTopComponent); 3968 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); 3969 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3970 intent.addCategory(Intent.CATEGORY_HOME); 3971 } 3972 return intent; 3973 } 3974 3975 boolean startHomeActivityLocked(int userId, String reason) { 3976 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3977 && mTopAction == null) { 3978 // We are running in factory test mode, but unable to find 3979 // the factory test app, so just sit around displaying the 3980 // error message and don't try to start anything. 3981 return false; 3982 } 3983 Intent intent = getHomeIntent(); 3984 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3985 if (aInfo != null) { 3986 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); 3987 // Don't do this if the home app is currently being 3988 // instrumented. 3989 aInfo = new ActivityInfo(aInfo); 3990 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3991 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3992 aInfo.applicationInfo.uid, true); 3993 if (app == null || app.instr == null) { 3994 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3995 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason); 3996 } 3997 } else { 3998 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable()); 3999 } 4000 4001 return true; 4002 } 4003 4004 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 4005 ActivityInfo ai = null; 4006 ComponentName comp = intent.getComponent(); 4007 try { 4008 if (comp != null) { 4009 // Factory test. 4010 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 4011 } else { 4012 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 4013 intent, 4014 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 4015 flags, userId); 4016 4017 if (info != null) { 4018 ai = info.activityInfo; 4019 } 4020 } 4021 } catch (RemoteException e) { 4022 // ignore 4023 } 4024 4025 return ai; 4026 } 4027 4028 /** 4029 * Starts the "new version setup screen" if appropriate. 4030 */ 4031 void startSetupActivityLocked() { 4032 // Only do this once per boot. 4033 if (mCheckedForSetup) { 4034 return; 4035 } 4036 4037 // We will show this screen if the current one is a different 4038 // version than the last one shown, and we are not running in 4039 // low-level factory test mode. 4040 final ContentResolver resolver = mContext.getContentResolver(); 4041 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 4042 Settings.Global.getInt(resolver, 4043 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 4044 mCheckedForSetup = true; 4045 4046 // See if we should be showing the platform update setup UI. 4047 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 4048 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent, 4049 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA); 4050 if (!ris.isEmpty()) { 4051 final ResolveInfo ri = ris.get(0); 4052 String vers = ri.activityInfo.metaData != null 4053 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 4054 : null; 4055 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 4056 vers = ri.activityInfo.applicationInfo.metaData.getString( 4057 Intent.METADATA_SETUP_VERSION); 4058 } 4059 String lastVers = Settings.Secure.getString( 4060 resolver, Settings.Secure.LAST_SETUP_SHOWN); 4061 if (vers != null && !vers.equals(lastVers)) { 4062 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 4063 intent.setComponent(new ComponentName( 4064 ri.activityInfo.packageName, ri.activityInfo.name)); 4065 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/, 4066 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0, 4067 null, 0, 0, 0, null, false, false, null, null, null); 4068 } 4069 } 4070 } 4071 } 4072 4073 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 4074 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 4075 } 4076 4077 void enforceNotIsolatedCaller(String caller) { 4078 if (UserHandle.isIsolated(Binder.getCallingUid())) { 4079 throw new SecurityException("Isolated process not allowed to call " + caller); 4080 } 4081 } 4082 4083 void enforceShellRestriction(String restriction, int userHandle) { 4084 if (Binder.getCallingUid() == Process.SHELL_UID) { 4085 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) { 4086 throw new SecurityException("Shell does not have permission to access user " 4087 + userHandle); 4088 } 4089 } 4090 } 4091 4092 @Override 4093 public int getFrontActivityScreenCompatMode() { 4094 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 4095 synchronized (this) { 4096 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 4097 } 4098 } 4099 4100 @Override 4101 public void setFrontActivityScreenCompatMode(int mode) { 4102 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 4103 "setFrontActivityScreenCompatMode"); 4104 synchronized (this) { 4105 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 4106 } 4107 } 4108 4109 @Override 4110 public int getPackageScreenCompatMode(String packageName) { 4111 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 4112 synchronized (this) { 4113 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 4114 } 4115 } 4116 4117 @Override 4118 public void setPackageScreenCompatMode(String packageName, int mode) { 4119 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 4120 "setPackageScreenCompatMode"); 4121 synchronized (this) { 4122 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 4123 } 4124 } 4125 4126 @Override 4127 public boolean getPackageAskScreenCompat(String packageName) { 4128 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 4129 synchronized (this) { 4130 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 4131 } 4132 } 4133 4134 @Override 4135 public void setPackageAskScreenCompat(String packageName, boolean ask) { 4136 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 4137 "setPackageAskScreenCompat"); 4138 synchronized (this) { 4139 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 4140 } 4141 } 4142 4143 private boolean hasUsageStatsPermission(String callingPackage) { 4144 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS, 4145 Binder.getCallingUid(), callingPackage); 4146 if (mode == AppOpsManager.MODE_DEFAULT) { 4147 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS) 4148 == PackageManager.PERMISSION_GRANTED; 4149 } 4150 return mode == AppOpsManager.MODE_ALLOWED; 4151 } 4152 4153 @Override 4154 public int getPackageProcessState(String packageName, String callingPackage) { 4155 if (!hasUsageStatsPermission(callingPackage)) { 4156 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, 4157 "getPackageProcessState"); 4158 } 4159 4160 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT; 4161 synchronized (this) { 4162 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4163 final ProcessRecord proc = mLruProcesses.get(i); 4164 if (procState > proc.setProcState) { 4165 if (proc.pkgList.containsKey(packageName) || 4166 (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) { 4167 procState = proc.setProcState; 4168 } 4169 } 4170 } 4171 } 4172 return procState; 4173 } 4174 4175 @Override 4176 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) 4177 throws RemoteException { 4178 synchronized (this) { 4179 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel"); 4180 if (app == null) { 4181 throw new IllegalArgumentException("Unknown process: " + process); 4182 } 4183 if (app.thread == null) { 4184 throw new IllegalArgumentException("Process has no app thread"); 4185 } 4186 if (app.trimMemoryLevel >= level) { 4187 throw new IllegalArgumentException( 4188 "Unable to set a higher trim level than current level"); 4189 } 4190 if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN || 4191 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) { 4192 throw new IllegalArgumentException("Unable to set a background trim level " 4193 + "on a foreground process"); 4194 } 4195 app.thread.scheduleTrimMemory(level); 4196 app.trimMemoryLevel = level; 4197 return true; 4198 } 4199 } 4200 4201 private void dispatchProcessesChanged() { 4202 int N; 4203 synchronized (this) { 4204 N = mPendingProcessChanges.size(); 4205 if (mActiveProcessChanges.length < N) { 4206 mActiveProcessChanges = new ProcessChangeItem[N]; 4207 } 4208 mPendingProcessChanges.toArray(mActiveProcessChanges); 4209 mPendingProcessChanges.clear(); 4210 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 4211 "*** Delivering " + N + " process changes"); 4212 } 4213 4214 int i = mProcessObservers.beginBroadcast(); 4215 while (i > 0) { 4216 i--; 4217 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 4218 if (observer != null) { 4219 try { 4220 for (int j=0; j<N; j++) { 4221 ProcessChangeItem item = mActiveProcessChanges[j]; 4222 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 4223 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 4224 "ACTIVITIES CHANGED pid=" + item.pid + " uid=" 4225 + item.uid + ": " + item.foregroundActivities); 4226 observer.onForegroundActivitiesChanged(item.pid, item.uid, 4227 item.foregroundActivities); 4228 } 4229 } 4230 } catch (RemoteException e) { 4231 } 4232 } 4233 } 4234 mProcessObservers.finishBroadcast(); 4235 4236 synchronized (this) { 4237 for (int j=0; j<N; j++) { 4238 mAvailProcessChanges.add(mActiveProcessChanges[j]); 4239 } 4240 } 4241 } 4242 4243 private void dispatchProcessDied(int pid, int uid) { 4244 int i = mProcessObservers.beginBroadcast(); 4245 while (i > 0) { 4246 i--; 4247 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 4248 if (observer != null) { 4249 try { 4250 observer.onProcessDied(pid, uid); 4251 } catch (RemoteException e) { 4252 } 4253 } 4254 } 4255 mProcessObservers.finishBroadcast(); 4256 } 4257 4258 private void dispatchUidsChanged() { 4259 int N; 4260 synchronized (this) { 4261 N = mPendingUidChanges.size(); 4262 if (mActiveUidChanges.length < N) { 4263 mActiveUidChanges = new UidRecord.ChangeItem[N]; 4264 } 4265 for (int i=0; i<N; i++) { 4266 final UidRecord.ChangeItem change = mPendingUidChanges.get(i); 4267 mActiveUidChanges[i] = change; 4268 if (change.uidRecord != null) { 4269 change.uidRecord.pendingChange = null; 4270 change.uidRecord = null; 4271 } 4272 } 4273 mPendingUidChanges.clear(); 4274 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4275 "*** Delivering " + N + " uid changes"); 4276 } 4277 4278 int i = mUidObservers.beginBroadcast(); 4279 while (i > 0) { 4280 i--; 4281 final IUidObserver observer = mUidObservers.getBroadcastItem(i); 4282 final UidObserverRegistration reg = (UidObserverRegistration) 4283 mUidObservers.getBroadcastCookie(i); 4284 if (observer != null) { 4285 try { 4286 for (int j=0; j<N; j++) { 4287 UidRecord.ChangeItem item = mActiveUidChanges[j]; 4288 final int change = item.change; 4289 UidRecord validateUid = null; 4290 if (VALIDATE_UID_STATES && i == 0) { 4291 validateUid = mValidateUids.get(item.uid); 4292 if (validateUid == null && change != UidRecord.CHANGE_GONE 4293 && change != UidRecord.CHANGE_GONE_IDLE) { 4294 validateUid = new UidRecord(item.uid); 4295 mValidateUids.put(item.uid, validateUid); 4296 } 4297 } 4298 if (change == UidRecord.CHANGE_IDLE 4299 || change == UidRecord.CHANGE_GONE_IDLE) { 4300 if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) { 4301 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4302 "UID idle uid=" + item.uid); 4303 observer.onUidIdle(item.uid, item.ephemeral); 4304 } 4305 if (VALIDATE_UID_STATES && i == 0) { 4306 if (validateUid != null) { 4307 validateUid.idle = true; 4308 } 4309 } 4310 } else if (change == UidRecord.CHANGE_ACTIVE) { 4311 if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) { 4312 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4313 "UID active uid=" + item.uid); 4314 observer.onUidActive(item.uid); 4315 } 4316 if (VALIDATE_UID_STATES && i == 0) { 4317 validateUid.idle = false; 4318 } 4319 } 4320 if (change == UidRecord.CHANGE_GONE 4321 || change == UidRecord.CHANGE_GONE_IDLE) { 4322 if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) { 4323 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4324 "UID gone uid=" + item.uid); 4325 observer.onUidGone(item.uid, item.ephemeral); 4326 } 4327 if (reg.lastProcStates != null) { 4328 reg.lastProcStates.delete(item.uid); 4329 } 4330 if (VALIDATE_UID_STATES && i == 0) { 4331 if (validateUid != null) { 4332 mValidateUids.remove(item.uid); 4333 } 4334 } 4335 } else { 4336 if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { 4337 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 4338 "UID CHANGED uid=" + item.uid 4339 + ": " + item.processState); 4340 boolean doReport = true; 4341 if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) { 4342 final int lastState = reg.lastProcStates.get(item.uid, 4343 ActivityManager.PROCESS_STATE_UNKNOWN); 4344 if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) { 4345 final boolean lastAboveCut = lastState <= reg.cutpoint; 4346 final boolean newAboveCut = item.processState <= reg.cutpoint; 4347 doReport = lastAboveCut != newAboveCut; 4348 } else { 4349 doReport = item.processState 4350 != ActivityManager.PROCESS_STATE_NONEXISTENT; 4351 } 4352 } 4353 if (doReport) { 4354 if (reg.lastProcStates != null) { 4355 reg.lastProcStates.put(item.uid, item.processState); 4356 } 4357 observer.onUidStateChanged(item.uid, item.processState); 4358 } 4359 } 4360 if (VALIDATE_UID_STATES && i == 0) { 4361 validateUid.curProcState = validateUid.setProcState 4362 = item.processState; 4363 } 4364 } 4365 } 4366 } catch (RemoteException e) { 4367 } 4368 } 4369 } 4370 mUidObservers.finishBroadcast(); 4371 4372 synchronized (this) { 4373 for (int j=0; j<N; j++) { 4374 mAvailUidChanges.add(mActiveUidChanges[j]); 4375 } 4376 } 4377 } 4378 4379 @Override 4380 public final int startActivity(IApplicationThread caller, String callingPackage, 4381 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4382 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { 4383 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 4384 resultWho, requestCode, startFlags, profilerInfo, bOptions, 4385 UserHandle.getCallingUserId()); 4386 } 4387 4388 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) { 4389 enforceNotIsolatedCaller("ActivityContainer.startActivity"); 4390 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(), 4391 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false, 4392 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null); 4393 4394 // TODO: Switch to user app stacks here. 4395 String mimeType = intent.getType(); 4396 final Uri data = intent.getData(); 4397 if (mimeType == null && data != null && "content".equals(data.getScheme())) { 4398 mimeType = getProviderMimeType(data, userId); 4399 } 4400 container.checkEmbeddedAllowedInner(userId, intent, mimeType); 4401 4402 intent.addFlags(FORCE_NEW_TASK_FLAGS); 4403 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, 4404 null, 0, 0, null, null, null, null, false, userId, container, null); 4405 } 4406 4407 @Override 4408 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 4409 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4410 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { 4411 enforceNotIsolatedCaller("startActivity"); 4412 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4413 userId, false, ALLOW_FULL_ONLY, "startActivity", null); 4414 // TODO: Switch to user app stacks here. 4415 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, 4416 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4417 profilerInfo, null, null, bOptions, false, userId, null, null); 4418 } 4419 4420 @Override 4421 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 4422 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4423 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity, 4424 int userId) { 4425 4426 // This is very dangerous -- it allows you to perform a start activity (including 4427 // permission grants) as any app that may launch one of your own activities. So 4428 // we will only allow this to be done from activities that are part of the core framework, 4429 // and then only when they are running as the system. 4430 final ActivityRecord sourceRecord; 4431 final int targetUid; 4432 final String targetPackage; 4433 synchronized (this) { 4434 if (resultTo == null) { 4435 throw new SecurityException("Must be called from an activity"); 4436 } 4437 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 4438 if (sourceRecord == null) { 4439 throw new SecurityException("Called with bad activity token: " + resultTo); 4440 } 4441 if (!sourceRecord.info.packageName.equals("android")) { 4442 throw new SecurityException( 4443 "Must be called from an activity that is declared in the android package"); 4444 } 4445 if (sourceRecord.app == null) { 4446 throw new SecurityException("Called without a process attached to activity"); 4447 } 4448 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 4449 // This is still okay, as long as this activity is running under the 4450 // uid of the original calling activity. 4451 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 4452 throw new SecurityException( 4453 "Calling activity in uid " + sourceRecord.app.uid 4454 + " must be system uid or original calling uid " 4455 + sourceRecord.launchedFromUid); 4456 } 4457 } 4458 if (ignoreTargetSecurity) { 4459 if (intent.getComponent() == null) { 4460 throw new SecurityException( 4461 "Component must be specified with ignoreTargetSecurity"); 4462 } 4463 if (intent.getSelector() != null) { 4464 throw new SecurityException( 4465 "Selector not allowed with ignoreTargetSecurity"); 4466 } 4467 } 4468 targetUid = sourceRecord.launchedFromUid; 4469 targetPackage = sourceRecord.launchedFromPackage; 4470 } 4471 4472 if (userId == UserHandle.USER_NULL) { 4473 userId = UserHandle.getUserId(sourceRecord.app.uid); 4474 } 4475 4476 // TODO: Switch to user app stacks here. 4477 try { 4478 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent, 4479 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 4480 null, null, bOptions, ignoreTargetSecurity, userId, null, null); 4481 return ret; 4482 } catch (SecurityException e) { 4483 // XXX need to figure out how to propagate to original app. 4484 // A SecurityException here is generally actually a fault of the original 4485 // calling activity (such as a fairly granting permissions), so propagate it 4486 // back to them. 4487 /* 4488 StringBuilder msg = new StringBuilder(); 4489 msg.append("While launching"); 4490 msg.append(intent.toString()); 4491 msg.append(": "); 4492 msg.append(e.getMessage()); 4493 */ 4494 throw e; 4495 } 4496 } 4497 4498 @Override 4499 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 4500 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4501 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { 4502 enforceNotIsolatedCaller("startActivityAndWait"); 4503 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4504 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 4505 WaitResult res = new WaitResult(); 4506 // TODO: Switch to user app stacks here. 4507 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 4508 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 4509 bOptions, false, userId, null, null); 4510 return res; 4511 } 4512 4513 @Override 4514 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 4515 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4516 int startFlags, Configuration config, Bundle bOptions, int userId) { 4517 enforceNotIsolatedCaller("startActivityWithConfig"); 4518 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4519 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 4520 // TODO: Switch to user app stacks here. 4521 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, 4522 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4523 null, null, config, bOptions, false, userId, null, null); 4524 return ret; 4525 } 4526 4527 @Override 4528 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent, 4529 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, 4530 int requestCode, int flagsMask, int flagsValues, Bundle bOptions) 4531 throws TransactionTooLargeException { 4532 enforceNotIsolatedCaller("startActivityIntentSender"); 4533 // Refuse possible leaked file descriptors 4534 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 4535 throw new IllegalArgumentException("File descriptors passed in Intent"); 4536 } 4537 4538 IIntentSender sender = intent.getTarget(); 4539 if (!(sender instanceof PendingIntentRecord)) { 4540 throw new IllegalArgumentException("Bad PendingIntent object"); 4541 } 4542 4543 PendingIntentRecord pir = (PendingIntentRecord)sender; 4544 4545 synchronized (this) { 4546 // If this is coming from the currently resumed activity, it is 4547 // effectively saying that app switches are allowed at this point. 4548 final ActivityStack stack = getFocusedStack(); 4549 if (stack.mResumedActivity != null && 4550 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 4551 mAppSwitchesAllowedTime = 0; 4552 } 4553 } 4554 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 4555 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null); 4556 return ret; 4557 } 4558 4559 @Override 4560 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 4561 Intent intent, String resolvedType, IVoiceInteractionSession session, 4562 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 4563 Bundle bOptions, int userId) { 4564 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 4565 != PackageManager.PERMISSION_GRANTED) { 4566 String msg = "Permission Denial: startVoiceActivity() from pid=" 4567 + Binder.getCallingPid() 4568 + ", uid=" + Binder.getCallingUid() 4569 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 4570 Slog.w(TAG, msg); 4571 throw new SecurityException(msg); 4572 } 4573 if (session == null || interactor == null) { 4574 throw new NullPointerException("null session or interactor"); 4575 } 4576 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, 4577 ALLOW_FULL_ONLY, "startVoiceActivity", null); 4578 // TODO: Switch to user app stacks here. 4579 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent, 4580 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 4581 null, bOptions, false, userId, null, null); 4582 } 4583 4584 @Override 4585 public int startAssistantActivity(String callingPackage, int callingPid, int callingUid, 4586 Intent intent, String resolvedType, Bundle bOptions, int userId) { 4587 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 4588 != PackageManager.PERMISSION_GRANTED) { 4589 final String msg = "Permission Denial: startAssistantActivity() from pid=" 4590 + Binder.getCallingPid() 4591 + ", uid=" + Binder.getCallingUid() 4592 + " requires " + Manifest.permission.BIND_VOICE_INTERACTION; 4593 Slog.w(TAG, msg); 4594 throw new SecurityException(msg); 4595 } 4596 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, 4597 ALLOW_FULL_ONLY, "startAssistantActivity", null); 4598 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent, 4599 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false, 4600 userId, null, null); 4601 } 4602 4603 @Override 4604 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) 4605 throws RemoteException { 4606 Slog.i(TAG, "Activity tried to startVoiceInteraction"); 4607 synchronized (this) { 4608 ActivityRecord activity = getFocusedStack().topActivity(); 4609 if (ActivityRecord.forTokenLocked(callingActivity) != activity) { 4610 throw new SecurityException("Only focused activity can call startVoiceInteraction"); 4611 } 4612 if (mRunningVoice != null || activity.task.voiceSession != null 4613 || activity.voiceSession != null) { 4614 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction"); 4615 return; 4616 } 4617 if (activity.pendingVoiceInteractionStart) { 4618 Slog.w(TAG, "Pending start of voice interaction already."); 4619 return; 4620 } 4621 activity.pendingVoiceInteractionStart = true; 4622 } 4623 LocalServices.getService(VoiceInteractionManagerInternal.class) 4624 .startLocalVoiceInteraction(callingActivity, options); 4625 } 4626 4627 @Override 4628 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException { 4629 LocalServices.getService(VoiceInteractionManagerInternal.class) 4630 .stopLocalVoiceInteraction(callingActivity); 4631 } 4632 4633 @Override 4634 public boolean supportsLocalVoiceInteraction() throws RemoteException { 4635 return LocalServices.getService(VoiceInteractionManagerInternal.class) 4636 .supportsLocalVoiceInteraction(); 4637 } 4638 4639 void onLocalVoiceInteractionStartedLocked(IBinder activity, 4640 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { 4641 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity); 4642 if (activityToCallback == null) return; 4643 activityToCallback.setVoiceSessionLocked(voiceSession); 4644 4645 // Inform the activity 4646 try { 4647 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity, 4648 voiceInteractor); 4649 long token = Binder.clearCallingIdentity(); 4650 try { 4651 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid); 4652 } finally { 4653 Binder.restoreCallingIdentity(token); 4654 } 4655 // TODO: VI Should we cache the activity so that it's easier to find later 4656 // rather than scan through all the stacks and activities? 4657 } catch (RemoteException re) { 4658 activityToCallback.clearVoiceSessionLocked(); 4659 // TODO: VI Should this terminate the voice session? 4660 } 4661 } 4662 4663 @Override 4664 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) { 4665 synchronized (this) { 4666 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) { 4667 if (keepAwake) { 4668 mVoiceWakeLock.acquire(); 4669 } else { 4670 mVoiceWakeLock.release(); 4671 } 4672 } 4673 } 4674 } 4675 4676 @Override 4677 public boolean startNextMatchingActivity(IBinder callingActivity, 4678 Intent intent, Bundle bOptions) { 4679 // Refuse possible leaked file descriptors 4680 if (intent != null && intent.hasFileDescriptors() == true) { 4681 throw new IllegalArgumentException("File descriptors passed in Intent"); 4682 } 4683 ActivityOptions options = ActivityOptions.fromBundle(bOptions); 4684 4685 synchronized (this) { 4686 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 4687 if (r == null) { 4688 ActivityOptions.abort(options); 4689 return false; 4690 } 4691 if (r.app == null || r.app.thread == null) { 4692 // The caller is not running... d'oh! 4693 ActivityOptions.abort(options); 4694 return false; 4695 } 4696 intent = new Intent(intent); 4697 // The caller is not allowed to change the data. 4698 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 4699 // And we are resetting to find the next component... 4700 intent.setComponent(null); 4701 4702 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4703 4704 ActivityInfo aInfo = null; 4705 try { 4706 List<ResolveInfo> resolves = 4707 AppGlobals.getPackageManager().queryIntentActivities( 4708 intent, r.resolvedType, 4709 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 4710 UserHandle.getCallingUserId()).getList(); 4711 4712 // Look for the original activity in the list... 4713 final int N = resolves != null ? resolves.size() : 0; 4714 for (int i=0; i<N; i++) { 4715 ResolveInfo rInfo = resolves.get(i); 4716 if (rInfo.activityInfo.packageName.equals(r.packageName) 4717 && rInfo.activityInfo.name.equals(r.info.name)) { 4718 // We found the current one... the next matching is 4719 // after it. 4720 i++; 4721 if (i<N) { 4722 aInfo = resolves.get(i).activityInfo; 4723 } 4724 if (debug) { 4725 Slog.v(TAG, "Next matching activity: found current " + r.packageName 4726 + "/" + r.info.name); 4727 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null) 4728 ? "null" : aInfo.packageName + "/" + aInfo.name)); 4729 } 4730 break; 4731 } 4732 } 4733 } catch (RemoteException e) { 4734 } 4735 4736 if (aInfo == null) { 4737 // Nobody who is next! 4738 ActivityOptions.abort(options); 4739 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 4740 return false; 4741 } 4742 4743 intent.setComponent(new ComponentName( 4744 aInfo.applicationInfo.packageName, aInfo.name)); 4745 intent.setFlags(intent.getFlags()&~( 4746 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 4747 Intent.FLAG_ACTIVITY_CLEAR_TOP| 4748 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 4749 Intent.FLAG_ACTIVITY_NEW_TASK)); 4750 4751 // Okay now we need to start the new activity, replacing the 4752 // currently running activity. This is a little tricky because 4753 // we want to start the new one as if the current one is finished, 4754 // but not finish the current one first so that there is no flicker. 4755 // And thus... 4756 final boolean wasFinishing = r.finishing; 4757 r.finishing = true; 4758 4759 // Propagate reply information over to the new activity. 4760 final ActivityRecord resultTo = r.resultTo; 4761 final String resultWho = r.resultWho; 4762 final int requestCode = r.requestCode; 4763 r.resultTo = null; 4764 if (resultTo != null) { 4765 resultTo.removeResultsLocked(r, resultWho, requestCode); 4766 } 4767 4768 final long origId = Binder.clearCallingIdentity(); 4769 int res = mActivityStarter.startActivityLocked(r.app.thread, intent, 4770 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null, 4771 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1, 4772 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options, 4773 false, false, null, null, null); 4774 Binder.restoreCallingIdentity(origId); 4775 4776 r.finishing = wasFinishing; 4777 if (res != ActivityManager.START_SUCCESS) { 4778 return false; 4779 } 4780 return true; 4781 } 4782 } 4783 4784 @Override 4785 public final int startActivityFromRecents(int taskId, Bundle bOptions) { 4786 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 4787 String msg = "Permission Denial: startActivityFromRecents called without " + 4788 START_TASKS_FROM_RECENTS; 4789 Slog.w(TAG, msg); 4790 throw new SecurityException(msg); 4791 } 4792 final long origId = Binder.clearCallingIdentity(); 4793 try { 4794 synchronized (this) { 4795 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions); 4796 } 4797 } finally { 4798 Binder.restoreCallingIdentity(origId); 4799 } 4800 } 4801 4802 final int startActivityInPackage(int uid, String callingPackage, 4803 Intent intent, String resolvedType, IBinder resultTo, 4804 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId, 4805 IActivityContainer container, TaskRecord inTask) { 4806 4807 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4808 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 4809 4810 // TODO: Switch to user app stacks here. 4811 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent, 4812 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4813 null, null, null, bOptions, false, userId, container, inTask); 4814 return ret; 4815 } 4816 4817 @Override 4818 public final int startActivities(IApplicationThread caller, String callingPackage, 4819 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions, 4820 int userId) { 4821 enforceNotIsolatedCaller("startActivities"); 4822 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4823 userId, false, ALLOW_FULL_ONLY, "startActivity", null); 4824 // TODO: Switch to user app stacks here. 4825 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents, 4826 resolvedTypes, resultTo, bOptions, userId); 4827 return ret; 4828 } 4829 4830 final int startActivitiesInPackage(int uid, String callingPackage, 4831 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 4832 Bundle bOptions, int userId) { 4833 4834 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4835 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 4836 // TODO: Switch to user app stacks here. 4837 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes, 4838 resultTo, bOptions, userId); 4839 return ret; 4840 } 4841 4842 @Override 4843 public void reportActivityFullyDrawn(IBinder token) { 4844 synchronized (this) { 4845 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4846 if (r == null) { 4847 return; 4848 } 4849 r.reportFullyDrawnLocked(); 4850 } 4851 } 4852 4853 @Override 4854 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4855 synchronized (this) { 4856 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4857 if (r == null) { 4858 return; 4859 } 4860 final long origId = Binder.clearCallingIdentity(); 4861 try { 4862 r.setRequestedOrientation(requestedOrientation); 4863 } finally { 4864 Binder.restoreCallingIdentity(origId); 4865 } 4866 } 4867 } 4868 4869 @Override 4870 public int getRequestedOrientation(IBinder token) { 4871 synchronized (this) { 4872 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4873 if (r == null) { 4874 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4875 } 4876 return r.getRequestedOrientation(); 4877 } 4878 } 4879 4880 @Override 4881 public final void requestActivityRelaunch(IBinder token) { 4882 synchronized(this) { 4883 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4884 if (r == null) { 4885 return; 4886 } 4887 final long origId = Binder.clearCallingIdentity(); 4888 try { 4889 r.forceNewConfig = true; 4890 r.ensureActivityConfigurationLocked(0 /* globalChanges */, 4891 false /* preserveWindow */); 4892 } finally { 4893 Binder.restoreCallingIdentity(origId); 4894 } 4895 } 4896 } 4897 4898 /** 4899 * This is the internal entry point for handling Activity.finish(). 4900 * 4901 * @param token The Binder token referencing the Activity we want to finish. 4902 * @param resultCode Result code, if any, from this Activity. 4903 * @param resultData Result data (Intent), if any, from this Activity. 4904 * @param finishTask Whether to finish the task associated with this Activity. 4905 * 4906 * @return Returns true if the activity successfully finished, or false if it is still running. 4907 */ 4908 @Override 4909 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4910 int finishTask) { 4911 // Refuse possible leaked file descriptors 4912 if (resultData != null && resultData.hasFileDescriptors() == true) { 4913 throw new IllegalArgumentException("File descriptors passed in Intent"); 4914 } 4915 4916 synchronized(this) { 4917 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4918 if (r == null) { 4919 return true; 4920 } 4921 // Keep track of the root activity of the task before we finish it 4922 TaskRecord tr = r.task; 4923 ActivityRecord rootR = tr.getRootActivity(); 4924 if (rootR == null) { 4925 Slog.w(TAG, "Finishing task with all activities already finished"); 4926 } 4927 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can 4928 // finish. 4929 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r && 4930 mStackSupervisor.isLastLockedTask(tr)) { 4931 Slog.i(TAG, "Not finishing task in lock task mode"); 4932 mStackSupervisor.showLockTaskToast(); 4933 return false; 4934 } 4935 if (mController != null) { 4936 // Find the first activity that is not finishing. 4937 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0); 4938 if (next != null) { 4939 // ask watcher if this is allowed 4940 boolean resumeOK = true; 4941 try { 4942 resumeOK = mController.activityResuming(next.packageName); 4943 } catch (RemoteException e) { 4944 mController = null; 4945 Watchdog.getInstance().setActivityController(null); 4946 } 4947 4948 if (!resumeOK) { 4949 Slog.i(TAG, "Not finishing activity because controller resumed"); 4950 return false; 4951 } 4952 } 4953 } 4954 final long origId = Binder.clearCallingIdentity(); 4955 try { 4956 boolean res; 4957 final boolean finishWithRootActivity = 4958 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; 4959 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY 4960 || (finishWithRootActivity && r == rootR)) { 4961 // If requested, remove the task that is associated to this activity only if it 4962 // was the root activity in the task. The result code and data is ignored 4963 // because we don't support returning them across task boundaries. Also, to 4964 // keep backwards compatibility we remove the task from recents when finishing 4965 // task with root activity. 4966 res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity); 4967 if (!res) { 4968 Slog.i(TAG, "Removing task failed to finish activity"); 4969 } 4970 } else { 4971 res = tr.getStack().requestFinishActivityLocked(token, resultCode, 4972 resultData, "app-request", true); 4973 if (!res) { 4974 Slog.i(TAG, "Failed to finish by app-request"); 4975 } 4976 } 4977 return res; 4978 } finally { 4979 Binder.restoreCallingIdentity(origId); 4980 } 4981 } 4982 } 4983 4984 @Override 4985 public final void finishHeavyWeightApp() { 4986 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4987 != PackageManager.PERMISSION_GRANTED) { 4988 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4989 + Binder.getCallingPid() 4990 + ", uid=" + Binder.getCallingUid() 4991 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4992 Slog.w(TAG, msg); 4993 throw new SecurityException(msg); 4994 } 4995 4996 synchronized(this) { 4997 if (mHeavyWeightProcess == null) { 4998 return; 4999 } 5000 5001 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities); 5002 for (int i = 0; i < activities.size(); i++) { 5003 ActivityRecord r = activities.get(i); 5004 if (!r.finishing && r.isInStackLocked()) { 5005 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED, 5006 null, "finish-heavy", true); 5007 } 5008 } 5009 5010 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5011 mHeavyWeightProcess.userId, 0)); 5012 mHeavyWeightProcess = null; 5013 } 5014 } 5015 5016 @Override 5017 public void crashApplication(int uid, int initialPid, String packageName, int userId, 5018 String message) { 5019 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5020 != PackageManager.PERMISSION_GRANTED) { 5021 String msg = "Permission Denial: crashApplication() from pid=" 5022 + Binder.getCallingPid() 5023 + ", uid=" + Binder.getCallingUid() 5024 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5025 Slog.w(TAG, msg); 5026 throw new SecurityException(msg); 5027 } 5028 5029 synchronized(this) { 5030 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message); 5031 } 5032 } 5033 5034 @Override 5035 public final void finishSubActivity(IBinder token, String resultWho, 5036 int requestCode) { 5037 synchronized(this) { 5038 final long origId = Binder.clearCallingIdentity(); 5039 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5040 if (r != null) { 5041 r.getStack().finishSubActivityLocked(r, resultWho, requestCode); 5042 } 5043 Binder.restoreCallingIdentity(origId); 5044 } 5045 } 5046 5047 @Override 5048 public boolean finishActivityAffinity(IBinder token) { 5049 synchronized(this) { 5050 final long origId = Binder.clearCallingIdentity(); 5051 try { 5052 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5053 if (r == null) { 5054 return false; 5055 } 5056 5057 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps 5058 // can finish. 5059 final TaskRecord task = r.task; 5060 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && 5061 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) { 5062 mStackSupervisor.showLockTaskToast(); 5063 return false; 5064 } 5065 return task.getStack().finishActivityAffinityLocked(r); 5066 } finally { 5067 Binder.restoreCallingIdentity(origId); 5068 } 5069 } 5070 } 5071 5072 @Override 5073 public void finishVoiceTask(IVoiceInteractionSession session) { 5074 synchronized (this) { 5075 final long origId = Binder.clearCallingIdentity(); 5076 try { 5077 // TODO: VI Consider treating local voice interactions and voice tasks 5078 // differently here 5079 mStackSupervisor.finishVoiceTask(session); 5080 } finally { 5081 Binder.restoreCallingIdentity(origId); 5082 } 5083 } 5084 5085 } 5086 5087 @Override 5088 public boolean releaseActivityInstance(IBinder token) { 5089 synchronized(this) { 5090 final long origId = Binder.clearCallingIdentity(); 5091 try { 5092 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5093 if (r == null) { 5094 return false; 5095 } 5096 return r.getStack().safelyDestroyActivityLocked(r, "app-req"); 5097 } finally { 5098 Binder.restoreCallingIdentity(origId); 5099 } 5100 } 5101 } 5102 5103 @Override 5104 public void releaseSomeActivities(IApplicationThread appInt) { 5105 synchronized(this) { 5106 final long origId = Binder.clearCallingIdentity(); 5107 try { 5108 ProcessRecord app = getRecordForAppLocked(appInt); 5109 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 5110 } finally { 5111 Binder.restoreCallingIdentity(origId); 5112 } 5113 } 5114 } 5115 5116 @Override 5117 public boolean willActivityBeVisible(IBinder token) { 5118 synchronized(this) { 5119 ActivityStack stack = ActivityRecord.getStackLocked(token); 5120 if (stack != null) { 5121 return stack.willActivityBeVisibleLocked(token); 5122 } 5123 return false; 5124 } 5125 } 5126 5127 @Override 5128 public void overridePendingTransition(IBinder token, String packageName, 5129 int enterAnim, int exitAnim) { 5130 synchronized(this) { 5131 ActivityRecord self = ActivityRecord.isInStackLocked(token); 5132 if (self == null) { 5133 return; 5134 } 5135 5136 final long origId = Binder.clearCallingIdentity(); 5137 5138 if (self.state == ActivityState.RESUMED 5139 || self.state == ActivityState.PAUSING) { 5140 mWindowManager.overridePendingAppTransition(packageName, 5141 enterAnim, exitAnim, null); 5142 } 5143 5144 Binder.restoreCallingIdentity(origId); 5145 } 5146 } 5147 5148 /** 5149 * Main function for removing an existing process from the activity manager 5150 * as a result of that process going away. Clears out all connections 5151 * to the process. 5152 */ 5153 private final void handleAppDiedLocked(ProcessRecord app, 5154 boolean restarting, boolean allowRestart) { 5155 int pid = app.pid; 5156 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1, 5157 false /*replacingPid*/); 5158 if (!kept && !restarting) { 5159 removeLruProcessLocked(app); 5160 if (pid > 0) { 5161 ProcessList.remove(pid); 5162 } 5163 } 5164 5165 if (mProfileProc == app) { 5166 clearProfilerLocked(); 5167 } 5168 5169 // Remove this application's activities from active lists. 5170 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 5171 5172 app.activities.clear(); 5173 5174 if (app.instr != null) { 5175 Slog.w(TAG, "Crash of app " + app.processName 5176 + " running instrumentation " + app.instr.mClass); 5177 Bundle info = new Bundle(); 5178 info.putString("shortMsg", "Process crashed."); 5179 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 5180 } 5181 5182 mWindowManager.deferSurfaceLayout(); 5183 try { 5184 if (!restarting && hasVisibleActivities 5185 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) { 5186 // If there was nothing to resume, and we are not already restarting this process, but 5187 // there is a visible activity that is hosted by the process... then make sure all 5188 // visible activities are running, taking care of restarting this process. 5189 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 5190 } 5191 } finally { 5192 mWindowManager.continueSurfaceLayout(); 5193 } 5194 } 5195 5196 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 5197 IBinder threadBinder = thread.asBinder(); 5198 // Find the application record. 5199 for (int i=mLruProcesses.size()-1; i>=0; i--) { 5200 ProcessRecord rec = mLruProcesses.get(i); 5201 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 5202 return i; 5203 } 5204 } 5205 return -1; 5206 } 5207 5208 final ProcessRecord getRecordForAppLocked( 5209 IApplicationThread thread) { 5210 if (thread == null) { 5211 return null; 5212 } 5213 5214 int appIndex = getLRURecordIndexForAppLocked(thread); 5215 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 5216 } 5217 5218 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 5219 // If there are no longer any background processes running, 5220 // and the app that died was not running instrumentation, 5221 // then tell everyone we are now low on memory. 5222 boolean haveBg = false; 5223 for (int i=mLruProcesses.size()-1; i>=0; i--) { 5224 ProcessRecord rec = mLruProcesses.get(i); 5225 if (rec.thread != null 5226 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 5227 haveBg = true; 5228 break; 5229 } 5230 } 5231 5232 if (!haveBg) { 5233 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 5234 if (doReport) { 5235 long now = SystemClock.uptimeMillis(); 5236 if (now < (mLastMemUsageReportTime+5*60*1000)) { 5237 doReport = false; 5238 } else { 5239 mLastMemUsageReportTime = now; 5240 } 5241 } 5242 final ArrayList<ProcessMemInfo> memInfos 5243 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 5244 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 5245 long now = SystemClock.uptimeMillis(); 5246 for (int i=mLruProcesses.size()-1; i>=0; i--) { 5247 ProcessRecord rec = mLruProcesses.get(i); 5248 if (rec == dyingProc || rec.thread == null) { 5249 continue; 5250 } 5251 if (doReport) { 5252 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 5253 rec.setProcState, rec.adjType, rec.makeAdjReason())); 5254 } 5255 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 5256 // The low memory report is overriding any current 5257 // state for a GC request. Make sure to do 5258 // heavy/important/visible/foreground processes first. 5259 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 5260 rec.lastRequestedGc = 0; 5261 } else { 5262 rec.lastRequestedGc = rec.lastLowMemory; 5263 } 5264 rec.reportLowMemory = true; 5265 rec.lastLowMemory = now; 5266 mProcessesToGc.remove(rec); 5267 addProcessToGcListLocked(rec); 5268 } 5269 } 5270 if (doReport) { 5271 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 5272 mHandler.sendMessage(msg); 5273 } 5274 scheduleAppGcsLocked(); 5275 } 5276 } 5277 5278 final void appDiedLocked(ProcessRecord app) { 5279 appDiedLocked(app, app.pid, app.thread, false); 5280 } 5281 5282 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread, 5283 boolean fromBinderDied) { 5284 // First check if this ProcessRecord is actually active for the pid. 5285 synchronized (mPidsSelfLocked) { 5286 ProcessRecord curProc = mPidsSelfLocked.get(pid); 5287 if (curProc != app) { 5288 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); 5289 return; 5290 } 5291 } 5292 5293 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 5294 synchronized (stats) { 5295 stats.noteProcessDiedLocked(app.info.uid, pid); 5296 } 5297 5298 if (!app.killed) { 5299 if (!fromBinderDied) { 5300 Process.killProcessQuiet(pid); 5301 } 5302 killProcessGroup(app.uid, pid); 5303 app.killed = true; 5304 } 5305 5306 // Clean up already done if the process has been re-started. 5307 if (app.pid == pid && app.thread != null && 5308 app.thread.asBinder() == thread.asBinder()) { 5309 boolean doLowMem = app.instr == null; 5310 boolean doOomAdj = doLowMem; 5311 if (!app.killedByAm) { 5312 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 5313 + ") has died"); 5314 mAllowLowerMemLevel = true; 5315 } else { 5316 // Note that we always want to do oom adj to update our state with the 5317 // new number of procs. 5318 mAllowLowerMemLevel = false; 5319 doLowMem = false; 5320 } 5321 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 5322 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 5323 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder()); 5324 handleAppDiedLocked(app, false, true); 5325 5326 if (doOomAdj) { 5327 updateOomAdjLocked(); 5328 } 5329 if (doLowMem) { 5330 doLowMemReportIfNeededLocked(app); 5331 } 5332 } else if (app.pid != pid) { 5333 // A new process has already been started. 5334 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 5335 + ") has died and restarted (pid " + app.pid + ")."); 5336 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 5337 } else if (DEBUG_PROCESSES) { 5338 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread " 5339 + thread.asBinder()); 5340 } 5341 } 5342 5343 /** 5344 * If a stack trace dump file is configured, dump process stack traces. 5345 * @param clearTraces causes the dump file to be erased prior to the new 5346 * traces being written, if true; when false, the new traces will be 5347 * appended to any existing file content. 5348 * @param firstPids of dalvik VM processes to dump stack traces for first 5349 * @param lastPids of dalvik VM processes to dump stack traces for last 5350 * @param nativeProcs optional list of native process names to dump stack crawls 5351 * @return file containing stack traces, or null if no dump file is configured 5352 */ 5353 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 5354 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 5355 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5356 if (tracesPath == null || tracesPath.length() == 0) { 5357 return null; 5358 } 5359 5360 File tracesFile = new File(tracesPath); 5361 try { 5362 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 5363 tracesFile.createNewFile(); 5364 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5365 } catch (IOException e) { 5366 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 5367 return null; 5368 } 5369 5370 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 5371 return tracesFile; 5372 } 5373 5374 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 5375 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 5376 // Use a FileObserver to detect when traces finish writing. 5377 // The order of traces is considered important to maintain for legibility. 5378 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 5379 @Override 5380 public synchronized void onEvent(int event, String path) { notify(); } 5381 }; 5382 5383 try { 5384 observer.startWatching(); 5385 5386 // First collect all of the stacks of the most important pids. 5387 if (firstPids != null) { 5388 try { 5389 int num = firstPids.size(); 5390 for (int i = 0; i < num; i++) { 5391 synchronized (observer) { 5392 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid " 5393 + firstPids.get(i)); 5394 final long sime = SystemClock.elapsedRealtime(); 5395 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 5396 observer.wait(1000); // Wait for write-close, give up after 1 sec 5397 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i) 5398 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms"); 5399 } 5400 } 5401 } catch (InterruptedException e) { 5402 Slog.wtf(TAG, e); 5403 } 5404 } 5405 5406 // Next collect the stacks of the native pids 5407 if (nativeProcs != null) { 5408 int[] pids = Process.getPidsForCommands(nativeProcs); 5409 if (pids != null) { 5410 for (int pid : pids) { 5411 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid); 5412 final long sime = SystemClock.elapsedRealtime(); 5413 5414 Debug.dumpNativeBacktraceToFileTimeout(pid, tracesPath, 10); 5415 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid 5416 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms"); 5417 } 5418 } 5419 } 5420 5421 // Lastly, measure CPU usage. 5422 if (processCpuTracker != null) { 5423 processCpuTracker.init(); 5424 System.gc(); 5425 processCpuTracker.update(); 5426 try { 5427 synchronized (processCpuTracker) { 5428 processCpuTracker.wait(500); // measure over 1/2 second. 5429 } 5430 } catch (InterruptedException e) { 5431 } 5432 processCpuTracker.update(); 5433 5434 // We'll take the stack crawls of just the top apps using CPU. 5435 final int N = processCpuTracker.countWorkingStats(); 5436 int numProcs = 0; 5437 for (int i=0; i<N && numProcs<5; i++) { 5438 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 5439 if (lastPids.indexOfKey(stats.pid) >= 0) { 5440 numProcs++; 5441 try { 5442 synchronized (observer) { 5443 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " 5444 + stats.pid); 5445 final long stime = SystemClock.elapsedRealtime(); 5446 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 5447 observer.wait(1000); // Wait for write-close, give up after 1 sec 5448 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid 5449 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms"); 5450 } 5451 } catch (InterruptedException e) { 5452 Slog.wtf(TAG, e); 5453 } 5454 } else if (DEBUG_ANR) { 5455 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: " 5456 + stats.pid); 5457 } 5458 } 5459 } 5460 } finally { 5461 observer.stopWatching(); 5462 } 5463 } 5464 5465 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 5466 if (true || IS_USER_BUILD) { 5467 return; 5468 } 5469 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 5470 if (tracesPath == null || tracesPath.length() == 0) { 5471 return; 5472 } 5473 5474 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 5475 StrictMode.allowThreadDiskWrites(); 5476 try { 5477 final File tracesFile = new File(tracesPath); 5478 final File tracesDir = tracesFile.getParentFile(); 5479 final File tracesTmp = new File(tracesDir, "__tmp__"); 5480 try { 5481 if (tracesFile.exists()) { 5482 tracesTmp.delete(); 5483 tracesFile.renameTo(tracesTmp); 5484 } 5485 StringBuilder sb = new StringBuilder(); 5486 Time tobj = new Time(); 5487 tobj.set(System.currentTimeMillis()); 5488 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 5489 sb.append(": "); 5490 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 5491 sb.append(" since "); 5492 sb.append(msg); 5493 FileOutputStream fos = new FileOutputStream(tracesFile); 5494 fos.write(sb.toString().getBytes()); 5495 if (app == null) { 5496 fos.write("\n*** No application process!".getBytes()); 5497 } 5498 fos.close(); 5499 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 5500 } catch (IOException e) { 5501 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 5502 return; 5503 } 5504 5505 if (app != null) { 5506 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 5507 firstPids.add(app.pid); 5508 dumpStackTraces(tracesPath, firstPids, null, null, null); 5509 } 5510 5511 File lastTracesFile = null; 5512 File curTracesFile = null; 5513 for (int i=9; i>=0; i--) { 5514 String name = String.format(Locale.US, "slow%02d.txt", i); 5515 curTracesFile = new File(tracesDir, name); 5516 if (curTracesFile.exists()) { 5517 if (lastTracesFile != null) { 5518 curTracesFile.renameTo(lastTracesFile); 5519 } else { 5520 curTracesFile.delete(); 5521 } 5522 } 5523 lastTracesFile = curTracesFile; 5524 } 5525 tracesFile.renameTo(curTracesFile); 5526 if (tracesTmp.exists()) { 5527 tracesTmp.renameTo(tracesFile); 5528 } 5529 } finally { 5530 StrictMode.setThreadPolicy(oldPolicy); 5531 } 5532 } 5533 5534 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5535 if (!mLaunchWarningShown) { 5536 mLaunchWarningShown = true; 5537 mUiHandler.post(new Runnable() { 5538 @Override 5539 public void run() { 5540 synchronized (ActivityManagerService.this) { 5541 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5542 d.show(); 5543 mUiHandler.postDelayed(new Runnable() { 5544 @Override 5545 public void run() { 5546 synchronized (ActivityManagerService.this) { 5547 d.dismiss(); 5548 mLaunchWarningShown = false; 5549 } 5550 } 5551 }, 4000); 5552 } 5553 } 5554 }); 5555 } 5556 } 5557 5558 @Override 5559 public boolean clearApplicationUserData(final String packageName, 5560 final IPackageDataObserver observer, int userId) { 5561 enforceNotIsolatedCaller("clearApplicationUserData"); 5562 int uid = Binder.getCallingUid(); 5563 int pid = Binder.getCallingPid(); 5564 userId = mUserController.handleIncomingUser(pid, uid, userId, false, 5565 ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5566 5567 5568 long callingId = Binder.clearCallingIdentity(); 5569 try { 5570 IPackageManager pm = AppGlobals.getPackageManager(); 5571 int pkgUid = -1; 5572 synchronized(this) { 5573 if (getPackageManagerInternalLocked().isPackageDataProtected( 5574 userId, packageName)) { 5575 throw new SecurityException( 5576 "Cannot clear data for a protected package: " + packageName); 5577 } 5578 5579 try { 5580 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId); 5581 } catch (RemoteException e) { 5582 } 5583 if (pkgUid == -1) { 5584 Slog.w(TAG, "Invalid packageName: " + packageName); 5585 if (observer != null) { 5586 try { 5587 observer.onRemoveCompleted(packageName, false); 5588 } catch (RemoteException e) { 5589 Slog.i(TAG, "Observer no longer exists."); 5590 } 5591 } 5592 return false; 5593 } 5594 if (uid == pkgUid || checkComponentPermission( 5595 android.Manifest.permission.CLEAR_APP_USER_DATA, 5596 pid, uid, -1, true) 5597 == PackageManager.PERMISSION_GRANTED) { 5598 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5599 } else { 5600 throw new SecurityException("PID " + pid + " does not have permission " 5601 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5602 + " of package " + packageName); 5603 } 5604 5605 // Remove all tasks match the cleared application package and user 5606 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5607 final TaskRecord tr = mRecentTasks.get(i); 5608 final String taskPackageName = 5609 tr.getBaseIntent().getComponent().getPackageName(); 5610 if (tr.userId != userId) continue; 5611 if (!taskPackageName.equals(packageName)) continue; 5612 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS); 5613 } 5614 } 5615 5616 final int pkgUidF = pkgUid; 5617 final int userIdF = userId; 5618 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() { 5619 @Override 5620 public void onRemoveCompleted(String packageName, boolean succeeded) 5621 throws RemoteException { 5622 synchronized (ActivityManagerService.this) { 5623 finishForceStopPackageLocked(packageName, pkgUidF); 5624 } 5625 5626 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5627 Uri.fromParts("package", packageName, null)); 5628 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 5629 intent.putExtra(Intent.EXTRA_UID, pkgUidF); 5630 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF)); 5631 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5632 null, null, 0, null, null, null, null, false, false, userIdF); 5633 5634 if (observer != null) { 5635 observer.onRemoveCompleted(packageName, succeeded); 5636 } 5637 } 5638 }; 5639 5640 try { 5641 // Clear application user data 5642 pm.clearApplicationUserData(packageName, localObserver, userId); 5643 5644 synchronized(this) { 5645 // Remove all permissions granted from/to this package 5646 removeUriPermissionsForPackageLocked(packageName, userId, true); 5647 } 5648 5649 // Reset notification settings. 5650 INotificationManager inm = NotificationManager.getService(); 5651 inm.clearData(packageName, pkgUidF, uid == pkgUidF); 5652 } catch (RemoteException e) { 5653 } 5654 } finally { 5655 Binder.restoreCallingIdentity(callingId); 5656 } 5657 return true; 5658 } 5659 5660 @Override 5661 public void killBackgroundProcesses(final String packageName, int userId) { 5662 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5663 != PackageManager.PERMISSION_GRANTED && 5664 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5665 != PackageManager.PERMISSION_GRANTED) { 5666 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5667 + Binder.getCallingPid() 5668 + ", uid=" + Binder.getCallingUid() 5669 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5670 Slog.w(TAG, msg); 5671 throw new SecurityException(msg); 5672 } 5673 5674 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5675 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5676 long callingId = Binder.clearCallingIdentity(); 5677 try { 5678 IPackageManager pm = AppGlobals.getPackageManager(); 5679 synchronized(this) { 5680 int appId = -1; 5681 try { 5682 appId = UserHandle.getAppId( 5683 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId)); 5684 } catch (RemoteException e) { 5685 } 5686 if (appId == -1) { 5687 Slog.w(TAG, "Invalid packageName: " + packageName); 5688 return; 5689 } 5690 killPackageProcessesLocked(packageName, appId, userId, 5691 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5692 } 5693 } finally { 5694 Binder.restoreCallingIdentity(callingId); 5695 } 5696 } 5697 5698 @Override 5699 public void killAllBackgroundProcesses() { 5700 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5701 != PackageManager.PERMISSION_GRANTED) { 5702 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5703 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 5704 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5705 Slog.w(TAG, msg); 5706 throw new SecurityException(msg); 5707 } 5708 5709 final long callingId = Binder.clearCallingIdentity(); 5710 try { 5711 synchronized (this) { 5712 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 5713 final int NP = mProcessNames.getMap().size(); 5714 for (int ip = 0; ip < NP; ip++) { 5715 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5716 final int NA = apps.size(); 5717 for (int ia = 0; ia < NA; ia++) { 5718 final ProcessRecord app = apps.valueAt(ia); 5719 if (app.persistent) { 5720 // We don't kill persistent processes. 5721 continue; 5722 } 5723 if (app.removed) { 5724 procs.add(app); 5725 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5726 app.removed = true; 5727 procs.add(app); 5728 } 5729 } 5730 } 5731 5732 final int N = procs.size(); 5733 for (int i = 0; i < N; i++) { 5734 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5735 } 5736 5737 mAllowLowerMemLevel = true; 5738 5739 updateOomAdjLocked(); 5740 doLowMemReportIfNeededLocked(null); 5741 } 5742 } finally { 5743 Binder.restoreCallingIdentity(callingId); 5744 } 5745 } 5746 5747 /** 5748 * Kills all background processes, except those matching any of the 5749 * specified properties. 5750 * 5751 * @param minTargetSdk the target SDK version at or above which to preserve 5752 * processes, or {@code -1} to ignore the target SDK 5753 * @param maxProcState the process state at or below which to preserve 5754 * processes, or {@code -1} to ignore the process state 5755 */ 5756 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) { 5757 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5758 != PackageManager.PERMISSION_GRANTED) { 5759 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid=" 5760 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 5761 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5762 Slog.w(TAG, msg); 5763 throw new SecurityException(msg); 5764 } 5765 5766 final long callingId = Binder.clearCallingIdentity(); 5767 try { 5768 synchronized (this) { 5769 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 5770 final int NP = mProcessNames.getMap().size(); 5771 for (int ip = 0; ip < NP; ip++) { 5772 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5773 final int NA = apps.size(); 5774 for (int ia = 0; ia < NA; ia++) { 5775 final ProcessRecord app = apps.valueAt(ia); 5776 if (app.removed) { 5777 procs.add(app); 5778 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk) 5779 && (maxProcState < 0 || app.setProcState > maxProcState)) { 5780 app.removed = true; 5781 procs.add(app); 5782 } 5783 } 5784 } 5785 5786 final int N = procs.size(); 5787 for (int i = 0; i < N; i++) { 5788 removeProcessLocked(procs.get(i), false, true, "kill all background except"); 5789 } 5790 } 5791 } finally { 5792 Binder.restoreCallingIdentity(callingId); 5793 } 5794 } 5795 5796 @Override 5797 public void forceStopPackage(final String packageName, int userId) { 5798 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5799 != PackageManager.PERMISSION_GRANTED) { 5800 String msg = "Permission Denial: forceStopPackage() from pid=" 5801 + Binder.getCallingPid() 5802 + ", uid=" + Binder.getCallingUid() 5803 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5804 Slog.w(TAG, msg); 5805 throw new SecurityException(msg); 5806 } 5807 final int callingPid = Binder.getCallingPid(); 5808 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(), 5809 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5810 long callingId = Binder.clearCallingIdentity(); 5811 try { 5812 IPackageManager pm = AppGlobals.getPackageManager(); 5813 synchronized(this) { 5814 int[] users = userId == UserHandle.USER_ALL 5815 ? mUserController.getUsers() : new int[] { userId }; 5816 for (int user : users) { 5817 int pkgUid = -1; 5818 try { 5819 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 5820 user); 5821 } catch (RemoteException e) { 5822 } 5823 if (pkgUid == -1) { 5824 Slog.w(TAG, "Invalid packageName: " + packageName); 5825 continue; 5826 } 5827 try { 5828 pm.setPackageStoppedState(packageName, true, user); 5829 } catch (RemoteException e) { 5830 } catch (IllegalArgumentException e) { 5831 Slog.w(TAG, "Failed trying to unstop package " 5832 + packageName + ": " + e); 5833 } 5834 if (mUserController.isUserRunningLocked(user, 0)) { 5835 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5836 finishForceStopPackageLocked(packageName, pkgUid); 5837 } 5838 } 5839 } 5840 } finally { 5841 Binder.restoreCallingIdentity(callingId); 5842 } 5843 } 5844 5845 @Override 5846 public void addPackageDependency(String packageName) { 5847 synchronized (this) { 5848 int callingPid = Binder.getCallingPid(); 5849 if (callingPid == Process.myPid()) { 5850 // Yeah, um, no. 5851 return; 5852 } 5853 ProcessRecord proc; 5854 synchronized (mPidsSelfLocked) { 5855 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5856 } 5857 if (proc != null) { 5858 if (proc.pkgDeps == null) { 5859 proc.pkgDeps = new ArraySet<String>(1); 5860 } 5861 proc.pkgDeps.add(packageName); 5862 } 5863 } 5864 } 5865 5866 /* 5867 * The pkg name and app id have to be specified. 5868 */ 5869 @Override 5870 public void killApplication(String pkg, int appId, int userId, String reason) { 5871 if (pkg == null) { 5872 return; 5873 } 5874 // Make sure the uid is valid. 5875 if (appId < 0) { 5876 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5877 return; 5878 } 5879 int callerUid = Binder.getCallingUid(); 5880 // Only the system server can kill an application 5881 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) { 5882 // Post an aysnc message to kill the application 5883 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5884 msg.arg1 = appId; 5885 msg.arg2 = userId; 5886 Bundle bundle = new Bundle(); 5887 bundle.putString("pkg", pkg); 5888 bundle.putString("reason", reason); 5889 msg.obj = bundle; 5890 mHandler.sendMessage(msg); 5891 } else { 5892 throw new SecurityException(callerUid + " cannot kill pkg: " + 5893 pkg); 5894 } 5895 } 5896 5897 @Override 5898 public void closeSystemDialogs(String reason) { 5899 enforceNotIsolatedCaller("closeSystemDialogs"); 5900 5901 final int pid = Binder.getCallingPid(); 5902 final int uid = Binder.getCallingUid(); 5903 final long origId = Binder.clearCallingIdentity(); 5904 try { 5905 synchronized (this) { 5906 // Only allow this from foreground processes, so that background 5907 // applications can't abuse it to prevent system UI from being shown. 5908 if (uid >= Process.FIRST_APPLICATION_UID) { 5909 ProcessRecord proc; 5910 synchronized (mPidsSelfLocked) { 5911 proc = mPidsSelfLocked.get(pid); 5912 } 5913 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5914 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5915 + " from background process " + proc); 5916 return; 5917 } 5918 } 5919 closeSystemDialogsLocked(reason); 5920 } 5921 } finally { 5922 Binder.restoreCallingIdentity(origId); 5923 } 5924 } 5925 5926 void closeSystemDialogsLocked(String reason) { 5927 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5928 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5929 | Intent.FLAG_RECEIVER_FOREGROUND); 5930 if (reason != null) { 5931 intent.putExtra("reason", reason); 5932 } 5933 mWindowManager.closeSystemDialogs(reason); 5934 5935 mStackSupervisor.closeSystemDialogsLocked(); 5936 5937 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 5938 AppOpsManager.OP_NONE, null, false, false, 5939 -1, Process.SYSTEM_UID, UserHandle.USER_ALL); 5940 } 5941 5942 @Override 5943 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5944 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5945 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5946 for (int i=pids.length-1; i>=0; i--) { 5947 ProcessRecord proc; 5948 int oomAdj; 5949 synchronized (this) { 5950 synchronized (mPidsSelfLocked) { 5951 proc = mPidsSelfLocked.get(pids[i]); 5952 oomAdj = proc != null ? proc.setAdj : 0; 5953 } 5954 } 5955 infos[i] = new Debug.MemoryInfo(); 5956 Debug.getMemoryInfo(pids[i], infos[i]); 5957 if (proc != null) { 5958 synchronized (this) { 5959 if (proc.thread != null && proc.setAdj == oomAdj) { 5960 // Record this for posterity if the process has been stable. 5961 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5962 infos[i].getTotalUss(), false, proc.pkgList); 5963 } 5964 } 5965 } 5966 } 5967 return infos; 5968 } 5969 5970 @Override 5971 public long[] getProcessPss(int[] pids) { 5972 enforceNotIsolatedCaller("getProcessPss"); 5973 long[] pss = new long[pids.length]; 5974 for (int i=pids.length-1; i>=0; i--) { 5975 ProcessRecord proc; 5976 int oomAdj; 5977 synchronized (this) { 5978 synchronized (mPidsSelfLocked) { 5979 proc = mPidsSelfLocked.get(pids[i]); 5980 oomAdj = proc != null ? proc.setAdj : 0; 5981 } 5982 } 5983 long[] tmpUss = new long[1]; 5984 pss[i] = Debug.getPss(pids[i], tmpUss, null); 5985 if (proc != null) { 5986 synchronized (this) { 5987 if (proc.thread != null && proc.setAdj == oomAdj) { 5988 // Record this for posterity if the process has been stable. 5989 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5990 } 5991 } 5992 } 5993 } 5994 return pss; 5995 } 5996 5997 @Override 5998 public void killApplicationProcess(String processName, int uid) { 5999 if (processName == null) { 6000 return; 6001 } 6002 6003 int callerUid = Binder.getCallingUid(); 6004 // Only the system server can kill an application 6005 if (callerUid == Process.SYSTEM_UID) { 6006 synchronized (this) { 6007 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 6008 if (app != null && app.thread != null) { 6009 try { 6010 app.thread.scheduleSuicide(); 6011 } catch (RemoteException e) { 6012 // If the other end already died, then our work here is done. 6013 } 6014 } else { 6015 Slog.w(TAG, "Process/uid not found attempting kill of " 6016 + processName + " / " + uid); 6017 } 6018 } 6019 } else { 6020 throw new SecurityException(callerUid + " cannot kill app process: " + 6021 processName); 6022 } 6023 } 6024 6025 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 6026 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 6027 false, true, false, false, UserHandle.getUserId(uid), reason); 6028 } 6029 6030 private void finishForceStopPackageLocked(final String packageName, int uid) { 6031 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 6032 Uri.fromParts("package", packageName, null)); 6033 if (!mProcessesReady) { 6034 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 6035 | Intent.FLAG_RECEIVER_FOREGROUND); 6036 } 6037 intent.putExtra(Intent.EXTRA_UID, uid); 6038 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 6039 broadcastIntentLocked(null, null, intent, 6040 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 6041 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 6042 } 6043 6044 6045 private final boolean killPackageProcessesLocked(String packageName, int appId, 6046 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 6047 boolean doit, boolean evenPersistent, String reason) { 6048 ArrayList<ProcessRecord> procs = new ArrayList<>(); 6049 6050 // Remove all processes this package may have touched: all with the 6051 // same UID (except for the system or root user), and all whose name 6052 // matches the package name. 6053 final int NP = mProcessNames.getMap().size(); 6054 for (int ip=0; ip<NP; ip++) { 6055 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 6056 final int NA = apps.size(); 6057 for (int ia=0; ia<NA; ia++) { 6058 ProcessRecord app = apps.valueAt(ia); 6059 if (app.persistent && !evenPersistent) { 6060 // we don't kill persistent processes 6061 continue; 6062 } 6063 if (app.removed) { 6064 if (doit) { 6065 procs.add(app); 6066 } 6067 continue; 6068 } 6069 6070 // Skip process if it doesn't meet our oom adj requirement. 6071 if (app.setAdj < minOomAdj) { 6072 continue; 6073 } 6074 6075 // If no package is specified, we call all processes under the 6076 // give user id. 6077 if (packageName == null) { 6078 if (userId != UserHandle.USER_ALL && app.userId != userId) { 6079 continue; 6080 } 6081 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 6082 continue; 6083 } 6084 // Package has been specified, we want to hit all processes 6085 // that match it. We need to qualify this by the processes 6086 // that are running under the specified app and user ID. 6087 } else { 6088 final boolean isDep = app.pkgDeps != null 6089 && app.pkgDeps.contains(packageName); 6090 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 6091 continue; 6092 } 6093 if (userId != UserHandle.USER_ALL && app.userId != userId) { 6094 continue; 6095 } 6096 if (!app.pkgList.containsKey(packageName) && !isDep) { 6097 continue; 6098 } 6099 } 6100 6101 // Process has passed all conditions, kill it! 6102 if (!doit) { 6103 return true; 6104 } 6105 app.removed = true; 6106 procs.add(app); 6107 } 6108 } 6109 6110 int N = procs.size(); 6111 for (int i=0; i<N; i++) { 6112 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 6113 } 6114 updateOomAdjLocked(); 6115 return N > 0; 6116 } 6117 6118 private void cleanupDisabledPackageComponentsLocked( 6119 String packageName, int userId, boolean killProcess, String[] changedClasses) { 6120 6121 Set<String> disabledClasses = null; 6122 boolean packageDisabled = false; 6123 IPackageManager pm = AppGlobals.getPackageManager(); 6124 6125 if (changedClasses == null) { 6126 // Nothing changed... 6127 return; 6128 } 6129 6130 // Determine enable/disable state of the package and its components. 6131 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 6132 for (int i = changedClasses.length - 1; i >= 0; i--) { 6133 final String changedClass = changedClasses[i]; 6134 6135 if (changedClass.equals(packageName)) { 6136 try { 6137 // Entire package setting changed 6138 enabled = pm.getApplicationEnabledSetting(packageName, 6139 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM); 6140 } catch (Exception e) { 6141 // No such package/component; probably racing with uninstall. In any 6142 // event it means we have nothing further to do here. 6143 return; 6144 } 6145 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED 6146 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 6147 if (packageDisabled) { 6148 // Entire package is disabled. 6149 // No need to continue to check component states. 6150 disabledClasses = null; 6151 break; 6152 } 6153 } else { 6154 try { 6155 enabled = pm.getComponentEnabledSetting( 6156 new ComponentName(packageName, changedClass), 6157 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM); 6158 } catch (Exception e) { 6159 // As above, probably racing with uninstall. 6160 return; 6161 } 6162 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED 6163 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { 6164 if (disabledClasses == null) { 6165 disabledClasses = new ArraySet<>(changedClasses.length); 6166 } 6167 disabledClasses.add(changedClass); 6168 } 6169 } 6170 } 6171 6172 if (!packageDisabled && disabledClasses == null) { 6173 // Nothing to do here... 6174 return; 6175 } 6176 6177 // Clean-up disabled activities. 6178 if (mStackSupervisor.finishDisabledPackageActivitiesLocked( 6179 packageName, disabledClasses, true, false, userId) && mBooted) { 6180 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 6181 mStackSupervisor.scheduleIdleLocked(); 6182 } 6183 6184 // Clean-up disabled tasks 6185 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId); 6186 6187 // Clean-up disabled services. 6188 mServices.bringDownDisabledPackageServicesLocked( 6189 packageName, disabledClasses, userId, false, killProcess, true); 6190 6191 // Clean-up disabled providers. 6192 ArrayList<ContentProviderRecord> providers = new ArrayList<>(); 6193 mProviderMap.collectPackageProvidersLocked( 6194 packageName, disabledClasses, true, false, userId, providers); 6195 for (int i = providers.size() - 1; i >= 0; i--) { 6196 removeDyingProviderLocked(null, providers.get(i), true); 6197 } 6198 6199 // Clean-up disabled broadcast receivers. 6200 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) { 6201 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked( 6202 packageName, disabledClasses, userId, true); 6203 } 6204 6205 } 6206 6207 final boolean clearBroadcastQueueForUserLocked(int userId) { 6208 boolean didSomething = false; 6209 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) { 6210 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked( 6211 null, null, userId, true); 6212 } 6213 return didSomething; 6214 } 6215 6216 final boolean forceStopPackageLocked(String packageName, int appId, 6217 boolean callerWillRestart, boolean purgeCache, boolean doit, 6218 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 6219 int i; 6220 6221 if (userId == UserHandle.USER_ALL && packageName == null) { 6222 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 6223 } 6224 6225 if (appId < 0 && packageName != null) { 6226 try { 6227 appId = UserHandle.getAppId(AppGlobals.getPackageManager() 6228 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0)); 6229 } catch (RemoteException e) { 6230 } 6231 } 6232 6233 if (doit) { 6234 if (packageName != null) { 6235 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId 6236 + " user=" + userId + ": " + reason); 6237 } else { 6238 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 6239 } 6240 6241 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId); 6242 } 6243 6244 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId, 6245 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent, 6246 packageName == null ? ("stop user " + userId) : ("stop " + packageName)); 6247 6248 didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName); 6249 6250 if (mStackSupervisor.finishDisabledPackageActivitiesLocked( 6251 packageName, null, doit, evenPersistent, userId)) { 6252 if (!doit) { 6253 return true; 6254 } 6255 didSomething = true; 6256 } 6257 6258 if (mServices.bringDownDisabledPackageServicesLocked( 6259 packageName, null, userId, evenPersistent, true, doit)) { 6260 if (!doit) { 6261 return true; 6262 } 6263 didSomething = true; 6264 } 6265 6266 if (packageName == null) { 6267 // Remove all sticky broadcasts from this user. 6268 mStickyBroadcasts.remove(userId); 6269 } 6270 6271 ArrayList<ContentProviderRecord> providers = new ArrayList<>(); 6272 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent, 6273 userId, providers)) { 6274 if (!doit) { 6275 return true; 6276 } 6277 didSomething = true; 6278 } 6279 for (i = providers.size() - 1; i >= 0; i--) { 6280 removeDyingProviderLocked(null, providers.get(i), true); 6281 } 6282 6283 // Remove transient permissions granted from/to this package/user 6284 removeUriPermissionsForPackageLocked(packageName, userId, false); 6285 6286 if (doit) { 6287 for (i = mBroadcastQueues.length - 1; i >= 0; i--) { 6288 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked( 6289 packageName, null, userId, doit); 6290 } 6291 } 6292 6293 if (packageName == null || uninstalling) { 6294 // Remove pending intents. For now we only do this when force 6295 // stopping users, because we have some problems when doing this 6296 // for packages -- app widgets are not currently cleaned up for 6297 // such packages, so they can be left with bad pending intents. 6298 if (mIntentSenderRecords.size() > 0) { 6299 Iterator<WeakReference<PendingIntentRecord>> it 6300 = mIntentSenderRecords.values().iterator(); 6301 while (it.hasNext()) { 6302 WeakReference<PendingIntentRecord> wpir = it.next(); 6303 if (wpir == null) { 6304 it.remove(); 6305 continue; 6306 } 6307 PendingIntentRecord pir = wpir.get(); 6308 if (pir == null) { 6309 it.remove(); 6310 continue; 6311 } 6312 if (packageName == null) { 6313 // Stopping user, remove all objects for the user. 6314 if (pir.key.userId != userId) { 6315 // Not the same user, skip it. 6316 continue; 6317 } 6318 } else { 6319 if (UserHandle.getAppId(pir.uid) != appId) { 6320 // Different app id, skip it. 6321 continue; 6322 } 6323 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 6324 // Different user, skip it. 6325 continue; 6326 } 6327 if (!pir.key.packageName.equals(packageName)) { 6328 // Different package, skip it. 6329 continue; 6330 } 6331 } 6332 if (!doit) { 6333 return true; 6334 } 6335 didSomething = true; 6336 it.remove(); 6337 pir.canceled = true; 6338 if (pir.key.activity != null && pir.key.activity.pendingResults != null) { 6339 pir.key.activity.pendingResults.remove(pir.ref); 6340 } 6341 } 6342 } 6343 } 6344 6345 if (doit) { 6346 if (purgeCache && packageName != null) { 6347 AttributeCache ac = AttributeCache.instance(); 6348 if (ac != null) { 6349 ac.removePackage(packageName); 6350 } 6351 } 6352 if (mBooted) { 6353 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 6354 mStackSupervisor.scheduleIdleLocked(); 6355 } 6356 } 6357 6358 return didSomething; 6359 } 6360 6361 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) { 6362 return removeProcessNameLocked(name, uid, null); 6363 } 6364 6365 private final ProcessRecord removeProcessNameLocked(final String name, final int uid, 6366 final ProcessRecord expecting) { 6367 ProcessRecord old = mProcessNames.get(name, uid); 6368 // Only actually remove when the currently recorded value matches the 6369 // record that we expected; if it doesn't match then we raced with a 6370 // newly created process and we don't want to destroy the new one. 6371 if ((expecting == null) || (old == expecting)) { 6372 mProcessNames.remove(name, uid); 6373 } 6374 if (old != null && old.uidRecord != null) { 6375 old.uidRecord.numProcs--; 6376 if (old.uidRecord.numProcs == 0) { 6377 // No more processes using this uid, tell clients it is gone. 6378 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 6379 "No more processes in " + old.uidRecord); 6380 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE); 6381 mActiveUids.remove(uid); 6382 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT); 6383 } 6384 old.uidRecord = null; 6385 } 6386 mIsolatedProcesses.remove(uid); 6387 return old; 6388 } 6389 6390 private final void addProcessNameLocked(ProcessRecord proc) { 6391 // We shouldn't already have a process under this name, but just in case we 6392 // need to clean up whatever may be there now. 6393 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid); 6394 if (old == proc && proc.persistent) { 6395 // We are re-adding a persistent process. Whatevs! Just leave it there. 6396 Slog.w(TAG, "Re-adding persistent process " + proc); 6397 } else if (old != null) { 6398 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc); 6399 } 6400 UidRecord uidRec = mActiveUids.get(proc.uid); 6401 if (uidRec == null) { 6402 uidRec = new UidRecord(proc.uid); 6403 // This is the first appearance of the uid, report it now! 6404 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 6405 "Creating new process uid: " + uidRec); 6406 if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0) { 6407 uidRec.setWhitelist = uidRec.curWhitelist = true; 6408 } 6409 mActiveUids.put(proc.uid, uidRec); 6410 noteUidProcessState(uidRec.uid, uidRec.curProcState); 6411 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE); 6412 } 6413 proc.uidRecord = uidRec; 6414 6415 // Reset render thread tid if it was already set, so new process can set it again. 6416 proc.renderThreadTid = 0; 6417 uidRec.numProcs++; 6418 mProcessNames.put(proc.processName, proc.uid, proc); 6419 if (proc.isolated) { 6420 mIsolatedProcesses.put(proc.uid, proc); 6421 } 6422 } 6423 6424 boolean removeProcessLocked(ProcessRecord app, 6425 boolean callerWillRestart, boolean allowRestart, String reason) { 6426 final String name = app.processName; 6427 final int uid = app.uid; 6428 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES, 6429 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")"); 6430 6431 ProcessRecord old = mProcessNames.get(name, uid); 6432 if (old != app) { 6433 // This process is no longer active, so nothing to do. 6434 Slog.w(TAG, "Ignoring remove of inactive process: " + app); 6435 return false; 6436 } 6437 removeProcessNameLocked(name, uid); 6438 if (mHeavyWeightProcess == app) { 6439 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6440 mHeavyWeightProcess.userId, 0)); 6441 mHeavyWeightProcess = null; 6442 } 6443 boolean needRestart = false; 6444 if (app.pid > 0 && app.pid != MY_PID) { 6445 int pid = app.pid; 6446 synchronized (mPidsSelfLocked) { 6447 mPidsSelfLocked.remove(pid); 6448 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6449 } 6450 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6451 if (app.isolated) { 6452 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6453 } 6454 boolean willRestart = false; 6455 if (app.persistent && !app.isolated) { 6456 if (!callerWillRestart) { 6457 willRestart = true; 6458 } else { 6459 needRestart = true; 6460 } 6461 } 6462 app.kill(reason, true); 6463 handleAppDiedLocked(app, willRestart, allowRestart); 6464 if (willRestart) { 6465 removeLruProcessLocked(app); 6466 addAppLocked(app.info, null, false, null /* ABI override */); 6467 } 6468 } else { 6469 mRemovedProcesses.add(app); 6470 } 6471 6472 return needRestart; 6473 } 6474 6475 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) { 6476 cleanupAppInLaunchingProvidersLocked(app, true); 6477 removeProcessLocked(app, false, true, "timeout publishing content providers"); 6478 } 6479 6480 private final void processStartTimedOutLocked(ProcessRecord app) { 6481 final int pid = app.pid; 6482 boolean gone = false; 6483 synchronized (mPidsSelfLocked) { 6484 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 6485 if (knownApp != null && knownApp.thread == null) { 6486 mPidsSelfLocked.remove(pid); 6487 gone = true; 6488 } 6489 } 6490 6491 if (gone) { 6492 Slog.w(TAG, "Process " + app + " failed to attach"); 6493 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 6494 pid, app.uid, app.processName); 6495 removeProcessNameLocked(app.processName, app.uid); 6496 if (mHeavyWeightProcess == app) { 6497 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 6498 mHeavyWeightProcess.userId, 0)); 6499 mHeavyWeightProcess = null; 6500 } 6501 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 6502 if (app.isolated) { 6503 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 6504 } 6505 // Take care of any launching providers waiting for this process. 6506 cleanupAppInLaunchingProvidersLocked(app, true); 6507 // Take care of any services that are waiting for the process. 6508 mServices.processStartTimedOutLocked(app); 6509 app.kill("start timeout", true); 6510 removeLruProcessLocked(app); 6511 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 6512 Slog.w(TAG, "Unattached app died before backup, skipping"); 6513 mHandler.post(new Runnable() { 6514 @Override 6515 public void run(){ 6516 try { 6517 IBackupManager bm = IBackupManager.Stub.asInterface( 6518 ServiceManager.getService(Context.BACKUP_SERVICE)); 6519 bm.agentDisconnected(app.info.packageName); 6520 } catch (RemoteException e) { 6521 // Can't happen; the backup manager is local 6522 } 6523 } 6524 }); 6525 } 6526 if (isPendingBroadcastProcessLocked(pid)) { 6527 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 6528 skipPendingBroadcastLocked(pid); 6529 } 6530 } else { 6531 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 6532 } 6533 } 6534 6535 private final boolean attachApplicationLocked(IApplicationThread thread, 6536 int pid) { 6537 6538 // Find the application record that is being attached... either via 6539 // the pid if we are running in multiple processes, or just pull the 6540 // next app record if we are emulating process with anonymous threads. 6541 ProcessRecord app; 6542 long startTime = SystemClock.uptimeMillis(); 6543 if (pid != MY_PID && pid >= 0) { 6544 synchronized (mPidsSelfLocked) { 6545 app = mPidsSelfLocked.get(pid); 6546 } 6547 } else { 6548 app = null; 6549 } 6550 6551 if (app == null) { 6552 Slog.w(TAG, "No pending application record for pid " + pid 6553 + " (IApplicationThread " + thread + "); dropping process"); 6554 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 6555 if (pid > 0 && pid != MY_PID) { 6556 Process.killProcessQuiet(pid); 6557 //TODO: killProcessGroup(app.info.uid, pid); 6558 } else { 6559 try { 6560 thread.scheduleExit(); 6561 } catch (Exception e) { 6562 // Ignore exceptions. 6563 } 6564 } 6565 return false; 6566 } 6567 6568 // If this application record is still attached to a previous 6569 // process, clean it up now. 6570 if (app.thread != null) { 6571 handleAppDiedLocked(app, true, true); 6572 } 6573 6574 // Tell the process all about itself. 6575 6576 if (DEBUG_ALL) Slog.v( 6577 TAG, "Binding process pid " + pid + " to record " + app); 6578 6579 final String processName = app.processName; 6580 try { 6581 AppDeathRecipient adr = new AppDeathRecipient( 6582 app, pid, thread); 6583 thread.asBinder().linkToDeath(adr, 0); 6584 app.deathRecipient = adr; 6585 } catch (RemoteException e) { 6586 app.resetPackageList(mProcessStats); 6587 startProcessLocked(app, "link fail", processName); 6588 return false; 6589 } 6590 6591 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 6592 6593 app.makeActive(thread, mProcessStats); 6594 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ; 6595 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; 6596 app.forcingToForeground = null; 6597 updateProcessForegroundLocked(app, false, false); 6598 app.hasShownUi = false; 6599 app.debugging = false; 6600 app.cached = false; 6601 app.killedByAm = false; 6602 app.killed = false; 6603 6604 6605 // We carefully use the same state that PackageManager uses for 6606 // filtering, since we use this flag to decide if we need to install 6607 // providers when user is unlocked later 6608 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId); 6609 6610 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 6611 6612 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 6613 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 6614 6615 if (providers != null && checkAppInLaunchingProvidersLocked(app)) { 6616 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG); 6617 msg.obj = app; 6618 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT); 6619 } 6620 6621 checkTime(startTime, "attachApplicationLocked: before bindApplication"); 6622 6623 if (!normalMode) { 6624 Slog.i(TAG, "Launching preboot mode app: " + app); 6625 } 6626 6627 if (DEBUG_ALL) Slog.v( 6628 TAG, "New app record " + app 6629 + " thread=" + thread.asBinder() + " pid=" + pid); 6630 try { 6631 int testMode = ApplicationThreadConstants.DEBUG_OFF; 6632 if (mDebugApp != null && mDebugApp.equals(processName)) { 6633 testMode = mWaitForDebugger 6634 ? ApplicationThreadConstants.DEBUG_WAIT 6635 : ApplicationThreadConstants.DEBUG_ON; 6636 app.debugging = true; 6637 if (mDebugTransient) { 6638 mDebugApp = mOrigDebugApp; 6639 mWaitForDebugger = mOrigWaitForDebugger; 6640 } 6641 } 6642 String profileFile = app.instr != null ? app.instr.mProfileFile : null; 6643 ParcelFileDescriptor profileFd = null; 6644 int samplingInterval = 0; 6645 boolean profileAutoStop = false; 6646 boolean profileStreamingOutput = false; 6647 if (mProfileApp != null && mProfileApp.equals(processName)) { 6648 mProfileProc = app; 6649 profileFile = mProfileFile; 6650 profileFd = mProfileFd; 6651 samplingInterval = mSamplingInterval; 6652 profileAutoStop = mAutoStopProfiler; 6653 profileStreamingOutput = mStreamingOutput; 6654 } 6655 boolean enableTrackAllocation = false; 6656 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) { 6657 enableTrackAllocation = true; 6658 mTrackAllocationApp = null; 6659 } 6660 6661 // If the app is being launched for restore or full backup, set it up specially 6662 boolean isRestrictedBackupMode = false; 6663 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6664 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID 6665 && ((mBackupTarget.backupMode == BackupRecord.RESTORE) 6666 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6667 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL)); 6668 } 6669 6670 if (app.instr != null) { 6671 notifyPackageUse(app.instr.mClass.getPackageName(), 6672 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION); 6673 } 6674 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc " 6675 + processName + " with config " + getGlobalConfiguration()); 6676 ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info; 6677 app.compat = compatibilityInfoForPackageLocked(appInfo); 6678 if (profileFd != null) { 6679 profileFd = profileFd.dup(); 6680 } 6681 ProfilerInfo profilerInfo = profileFile == null ? null 6682 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop, 6683 profileStreamingOutput); 6684 6685 // We deprecated Build.SERIAL and only apps that target pre NMR1 6686 // SDK can see it. Since access to the serial is now behind a 6687 // permission we push down the value. 6688 String buildSerial = Build.UNKNOWN; 6689 // TODO: SHTOPSHIP Uncomment the check when clients migrate 6690// if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) { 6691 buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface( 6692 ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE)) 6693 .getSerial(); 6694// } 6695 6696 // Check if this is a secondary process that should be incorporated into some 6697 // currently active instrumentation. (Note we do this AFTER all of the profiling 6698 // stuff above because profiling can currently happen only in the primary 6699 // instrumentation process.) 6700 if (mActiveInstrumentation.size() > 0 && app.instr == null) { 6701 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) { 6702 ActiveInstrumentation aInstr = mActiveInstrumentation.get(i); 6703 if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) { 6704 if (aInstr.mTargetProcesses.length == 0) { 6705 // This is the wildcard mode, where every process brought up for 6706 // the target instrumentation should be included. 6707 if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) { 6708 app.instr = aInstr; 6709 aInstr.mRunningProcesses.add(app); 6710 } 6711 } else { 6712 for (String proc : aInstr.mTargetProcesses) { 6713 if (proc.equals(app.processName)) { 6714 app.instr = aInstr; 6715 aInstr.mRunningProcesses.add(app); 6716 break; 6717 } 6718 } 6719 } 6720 } 6721 } 6722 } 6723 6724 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication"); 6725 if (app.instr != null) { 6726 thread.bindApplication(processName, appInfo, providers, 6727 app.instr.mClass, 6728 profilerInfo, app.instr.mArguments, 6729 app.instr.mWatcher, 6730 app.instr.mUiAutomationConnection, testMode, 6731 mBinderTransactionTrackingEnabled, enableTrackAllocation, 6732 isRestrictedBackupMode || !normalMode, app.persistent, 6733 new Configuration(getGlobalConfiguration()), app.compat, 6734 getCommonServicesLocked(app.isolated), 6735 mCoreSettingsObserver.getCoreSettingsLocked(), 6736 buildSerial); 6737 } else { 6738 thread.bindApplication(processName, appInfo, providers, null, profilerInfo, 6739 null, null, null, testMode, 6740 mBinderTransactionTrackingEnabled, enableTrackAllocation, 6741 isRestrictedBackupMode || !normalMode, app.persistent, 6742 new Configuration(getGlobalConfiguration()), app.compat, 6743 getCommonServicesLocked(app.isolated), 6744 mCoreSettingsObserver.getCoreSettingsLocked(), 6745 buildSerial); 6746 } 6747 6748 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication"); 6749 updateLruProcessLocked(app, false, null); 6750 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked"); 6751 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6752 } catch (Exception e) { 6753 // todo: Yikes! What should we do? For now we will try to 6754 // start another process, but that could easily get us in 6755 // an infinite loop of restarting processes... 6756 Slog.wtf(TAG, "Exception thrown during bind of " + app, e); 6757 6758 app.resetPackageList(mProcessStats); 6759 app.unlinkDeathRecipient(); 6760 startProcessLocked(app, "bind fail", processName); 6761 return false; 6762 } 6763 6764 // Remove this record from the list of starting applications. 6765 mPersistentStartingProcesses.remove(app); 6766 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES, 6767 "Attach application locked removing on hold: " + app); 6768 mProcessesOnHold.remove(app); 6769 6770 boolean badApp = false; 6771 boolean didSomething = false; 6772 6773 // See if the top visible activity is waiting to run in this process... 6774 if (normalMode) { 6775 try { 6776 if (mStackSupervisor.attachApplicationLocked(app)) { 6777 didSomething = true; 6778 } 6779 } catch (Exception e) { 6780 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); 6781 badApp = true; 6782 } 6783 } 6784 6785 // Find any services that should be running in this process... 6786 if (!badApp) { 6787 try { 6788 didSomething |= mServices.attachApplicationLocked(app, processName); 6789 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); 6790 } catch (Exception e) { 6791 Slog.wtf(TAG, "Exception thrown starting services in " + app, e); 6792 badApp = true; 6793 } 6794 } 6795 6796 // Check if a next-broadcast receiver is in this process... 6797 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6798 try { 6799 didSomething |= sendPendingBroadcastsLocked(app); 6800 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked"); 6801 } catch (Exception e) { 6802 // If the app died trying to launch the receiver we declare it 'bad' 6803 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e); 6804 badApp = true; 6805 } 6806 } 6807 6808 // Check whether the next backup agent is in this process... 6809 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6810 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, 6811 "New app is backup target, launching agent for " + app); 6812 notifyPackageUse(mBackupTarget.appInfo.packageName, 6813 PackageManager.NOTIFY_PACKAGE_USE_BACKUP); 6814 try { 6815 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6816 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6817 mBackupTarget.backupMode); 6818 } catch (Exception e) { 6819 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e); 6820 badApp = true; 6821 } 6822 } 6823 6824 if (badApp) { 6825 app.kill("error during init", true); 6826 handleAppDiedLocked(app, false, true); 6827 return false; 6828 } 6829 6830 if (!didSomething) { 6831 updateOomAdjLocked(); 6832 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked"); 6833 } 6834 6835 return true; 6836 } 6837 6838 @Override 6839 public final void attachApplication(IApplicationThread thread) { 6840 synchronized (this) { 6841 int callingPid = Binder.getCallingPid(); 6842 final long origId = Binder.clearCallingIdentity(); 6843 attachApplicationLocked(thread, callingPid); 6844 Binder.restoreCallingIdentity(origId); 6845 } 6846 } 6847 6848 @Override 6849 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6850 final long origId = Binder.clearCallingIdentity(); 6851 synchronized (this) { 6852 ActivityStack stack = ActivityRecord.getStackLocked(token); 6853 if (stack != null) { 6854 ActivityRecord r = 6855 mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */, 6856 false /* processPausingActivities */, config); 6857 if (stopProfiling) { 6858 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6859 try { 6860 mProfileFd.close(); 6861 } catch (IOException e) { 6862 } 6863 clearProfilerLocked(); 6864 } 6865 } 6866 } 6867 } 6868 Binder.restoreCallingIdentity(origId); 6869 } 6870 6871 void postFinishBooting(boolean finishBooting, boolean enableScreen) { 6872 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG, 6873 finishBooting ? 1 : 0, enableScreen ? 1 : 0)); 6874 } 6875 6876 void enableScreenAfterBoot() { 6877 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6878 SystemClock.uptimeMillis()); 6879 mWindowManager.enableScreenAfterBoot(); 6880 6881 synchronized (this) { 6882 updateEventDispatchingLocked(); 6883 } 6884 } 6885 6886 @Override 6887 public void showBootMessage(final CharSequence msg, final boolean always) { 6888 if (Binder.getCallingUid() != Process.myUid()) { 6889 throw new SecurityException(); 6890 } 6891 mWindowManager.showBootMessage(msg, always); 6892 } 6893 6894 @Override 6895 public void keyguardGoingAway(int flags) { 6896 enforceNotIsolatedCaller("keyguardGoingAway"); 6897 final long token = Binder.clearCallingIdentity(); 6898 try { 6899 synchronized (this) { 6900 mKeyguardController.keyguardGoingAway(flags); 6901 } 6902 } finally { 6903 Binder.restoreCallingIdentity(token); 6904 } 6905 } 6906 6907 /** 6908 * @return whther the keyguard is currently locked. 6909 */ 6910 boolean isKeyguardLocked() { 6911 return mKeyguardController.isKeyguardLocked(); 6912 } 6913 6914 final void finishBooting() { 6915 synchronized (this) { 6916 if (!mBootAnimationComplete) { 6917 mCallFinishBooting = true; 6918 return; 6919 } 6920 mCallFinishBooting = false; 6921 } 6922 6923 ArraySet<String> completedIsas = new ArraySet<String>(); 6924 for (String abi : Build.SUPPORTED_ABIS) { 6925 Process.zygoteProcess.establishZygoteConnectionForAbi(abi); 6926 final String instructionSet = VMRuntime.getInstructionSet(abi); 6927 if (!completedIsas.contains(instructionSet)) { 6928 try { 6929 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)); 6930 } catch (InstallerException e) { 6931 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" + 6932 e.getMessage() +")"); 6933 } 6934 completedIsas.add(instructionSet); 6935 } 6936 } 6937 6938 IntentFilter pkgFilter = new IntentFilter(); 6939 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 6940 pkgFilter.addDataScheme("package"); 6941 mContext.registerReceiver(new BroadcastReceiver() { 6942 @Override 6943 public void onReceive(Context context, Intent intent) { 6944 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 6945 if (pkgs != null) { 6946 for (String pkg : pkgs) { 6947 synchronized (ActivityManagerService.this) { 6948 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 6949 0, "query restart")) { 6950 setResultCode(Activity.RESULT_OK); 6951 return; 6952 } 6953 } 6954 } 6955 } 6956 } 6957 }, pkgFilter); 6958 6959 IntentFilter dumpheapFilter = new IntentFilter(); 6960 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP); 6961 mContext.registerReceiver(new BroadcastReceiver() { 6962 @Override 6963 public void onReceive(Context context, Intent intent) { 6964 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) { 6965 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000); 6966 } else { 6967 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG); 6968 } 6969 } 6970 }, dumpheapFilter); 6971 6972 // Let system services know. 6973 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6974 6975 synchronized (this) { 6976 // Ensure that any processes we had put on hold are now started 6977 // up. 6978 final int NP = mProcessesOnHold.size(); 6979 if (NP > 0) { 6980 ArrayList<ProcessRecord> procs = 6981 new ArrayList<ProcessRecord>(mProcessesOnHold); 6982 for (int ip=0; ip<NP; ip++) { 6983 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: " 6984 + procs.get(ip)); 6985 startProcessLocked(procs.get(ip), "on-hold", null); 6986 } 6987 } 6988 6989 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6990 // Start looking for apps that are abusing wake locks. 6991 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6992 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6993 // Tell anyone interested that we are done booting! 6994 SystemProperties.set("sys.boot_completed", "1"); 6995 6996 // And trigger dev.bootcomplete if we are not showing encryption progress 6997 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) 6998 || "".equals(SystemProperties.get("vold.encrypt_progress"))) { 6999 SystemProperties.set("dev.bootcomplete", "1"); 7000 } 7001 mUserController.sendBootCompletedLocked( 7002 new IIntentReceiver.Stub() { 7003 @Override 7004 public void performReceive(Intent intent, int resultCode, 7005 String data, Bundle extras, boolean ordered, 7006 boolean sticky, int sendingUser) { 7007 synchronized (ActivityManagerService.this) { 7008 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 7009 true, false); 7010 } 7011 } 7012 }); 7013 scheduleStartProfilesLocked(); 7014 } 7015 } 7016 } 7017 7018 @Override 7019 public void bootAnimationComplete() { 7020 final boolean callFinishBooting; 7021 synchronized (this) { 7022 callFinishBooting = mCallFinishBooting; 7023 mBootAnimationComplete = true; 7024 } 7025 if (callFinishBooting) { 7026 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); 7027 finishBooting(); 7028 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 7029 } 7030 } 7031 7032 final void ensureBootCompleted() { 7033 boolean booting; 7034 boolean enableScreen; 7035 synchronized (this) { 7036 booting = mBooting; 7037 mBooting = false; 7038 enableScreen = !mBooted; 7039 mBooted = true; 7040 } 7041 7042 if (booting) { 7043 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting"); 7044 finishBooting(); 7045 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 7046 } 7047 7048 if (enableScreen) { 7049 enableScreenAfterBoot(); 7050 } 7051 } 7052 7053 @Override 7054 public final void activityResumed(IBinder token) { 7055 final long origId = Binder.clearCallingIdentity(); 7056 synchronized(this) { 7057 ActivityRecord.activityResumedLocked(token); 7058 mWindowManager.notifyAppResumedFinished(token); 7059 } 7060 Binder.restoreCallingIdentity(origId); 7061 } 7062 7063 @Override 7064 public final void activityPaused(IBinder token) { 7065 final long origId = Binder.clearCallingIdentity(); 7066 synchronized(this) { 7067 ActivityStack stack = ActivityRecord.getStackLocked(token); 7068 if (stack != null) { 7069 stack.activityPausedLocked(token, false); 7070 } 7071 } 7072 Binder.restoreCallingIdentity(origId); 7073 } 7074 7075 @Override 7076 public final void activityStopped(IBinder token, Bundle icicle, 7077 PersistableBundle persistentState, CharSequence description) { 7078 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token); 7079 7080 // Refuse possible leaked file descriptors 7081 if (icicle != null && icicle.hasFileDescriptors()) { 7082 throw new IllegalArgumentException("File descriptors passed in Bundle"); 7083 } 7084 7085 final long origId = Binder.clearCallingIdentity(); 7086 7087 synchronized (this) { 7088 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 7089 if (r != null) { 7090 r.activityStoppedLocked(icicle, persistentState, description); 7091 } 7092 } 7093 7094 trimApplications(); 7095 7096 Binder.restoreCallingIdentity(origId); 7097 } 7098 7099 @Override 7100 public final void activityDestroyed(IBinder token) { 7101 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token); 7102 synchronized (this) { 7103 ActivityStack stack = ActivityRecord.getStackLocked(token); 7104 if (stack != null) { 7105 stack.activityDestroyedLocked(token, "activityDestroyed"); 7106 } 7107 } 7108 } 7109 7110 @Override 7111 public final void activityRelaunched(IBinder token) { 7112 final long origId = Binder.clearCallingIdentity(); 7113 synchronized (this) { 7114 mStackSupervisor.activityRelaunchedLocked(token); 7115 } 7116 Binder.restoreCallingIdentity(origId); 7117 } 7118 7119 @Override 7120 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration, 7121 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) { 7122 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " " 7123 + horizontalSizeConfiguration + " " + verticalSizeConfigurations); 7124 synchronized (this) { 7125 ActivityRecord record = ActivityRecord.isInStackLocked(token); 7126 if (record == null) { 7127 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not " 7128 + "found for: " + token); 7129 } 7130 record.setSizeConfigurations(horizontalSizeConfiguration, 7131 verticalSizeConfigurations, smallestSizeConfigurations); 7132 } 7133 } 7134 7135 @Override 7136 public final void backgroundResourcesReleased(IBinder token) { 7137 final long origId = Binder.clearCallingIdentity(); 7138 try { 7139 synchronized (this) { 7140 ActivityStack stack = ActivityRecord.getStackLocked(token); 7141 if (stack != null) { 7142 stack.backgroundResourcesReleased(); 7143 } 7144 } 7145 } finally { 7146 Binder.restoreCallingIdentity(origId); 7147 } 7148 } 7149 7150 @Override 7151 public final void notifyLaunchTaskBehindComplete(IBinder token) { 7152 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 7153 } 7154 7155 @Override 7156 public final void notifyEnterAnimationComplete(IBinder token) { 7157 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 7158 } 7159 7160 @Override 7161 public String getCallingPackage(IBinder token) { 7162 synchronized (this) { 7163 ActivityRecord r = getCallingRecordLocked(token); 7164 return r != null ? r.info.packageName : null; 7165 } 7166 } 7167 7168 @Override 7169 public ComponentName getCallingActivity(IBinder token) { 7170 synchronized (this) { 7171 ActivityRecord r = getCallingRecordLocked(token); 7172 return r != null ? r.intent.getComponent() : null; 7173 } 7174 } 7175 7176 private ActivityRecord getCallingRecordLocked(IBinder token) { 7177 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7178 if (r == null) { 7179 return null; 7180 } 7181 return r.resultTo; 7182 } 7183 7184 @Override 7185 public ComponentName getActivityClassForToken(IBinder token) { 7186 synchronized(this) { 7187 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7188 if (r == null) { 7189 return null; 7190 } 7191 return r.intent.getComponent(); 7192 } 7193 } 7194 7195 @Override 7196 public String getPackageForToken(IBinder token) { 7197 synchronized(this) { 7198 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7199 if (r == null) { 7200 return null; 7201 } 7202 return r.packageName; 7203 } 7204 } 7205 7206 @Override 7207 public boolean isRootVoiceInteraction(IBinder token) { 7208 synchronized(this) { 7209 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7210 if (r == null) { 7211 return false; 7212 } 7213 return r.rootVoiceInteraction; 7214 } 7215 } 7216 7217 @Override 7218 public IIntentSender getIntentSender(int type, 7219 String packageName, IBinder token, String resultWho, 7220 int requestCode, Intent[] intents, String[] resolvedTypes, 7221 int flags, Bundle bOptions, int userId) { 7222 enforceNotIsolatedCaller("getIntentSender"); 7223 // Refuse possible leaked file descriptors 7224 if (intents != null) { 7225 if (intents.length < 1) { 7226 throw new IllegalArgumentException("Intents array length must be >= 1"); 7227 } 7228 for (int i=0; i<intents.length; i++) { 7229 Intent intent = intents[i]; 7230 if (intent != null) { 7231 if (intent.hasFileDescriptors()) { 7232 throw new IllegalArgumentException("File descriptors passed in Intent"); 7233 } 7234 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 7235 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 7236 throw new IllegalArgumentException( 7237 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 7238 } 7239 intents[i] = new Intent(intent); 7240 } 7241 } 7242 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 7243 throw new IllegalArgumentException( 7244 "Intent array length does not match resolvedTypes length"); 7245 } 7246 } 7247 if (bOptions != null) { 7248 if (bOptions.hasFileDescriptors()) { 7249 throw new IllegalArgumentException("File descriptors passed in options"); 7250 } 7251 } 7252 7253 synchronized(this) { 7254 int callingUid = Binder.getCallingUid(); 7255 int origUserId = userId; 7256 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7257 type == ActivityManager.INTENT_SENDER_BROADCAST, 7258 ALLOW_NON_FULL, "getIntentSender", null); 7259 if (origUserId == UserHandle.USER_CURRENT) { 7260 // We don't want to evaluate this until the pending intent is 7261 // actually executed. However, we do want to always do the 7262 // security checking for it above. 7263 userId = UserHandle.USER_CURRENT; 7264 } 7265 try { 7266 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 7267 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName, 7268 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid)); 7269 if (!UserHandle.isSameApp(callingUid, uid)) { 7270 String msg = "Permission Denial: getIntentSender() from pid=" 7271 + Binder.getCallingPid() 7272 + ", uid=" + Binder.getCallingUid() 7273 + ", (need uid=" + uid + ")" 7274 + " is not allowed to send as package " + packageName; 7275 Slog.w(TAG, msg); 7276 throw new SecurityException(msg); 7277 } 7278 } 7279 7280 return getIntentSenderLocked(type, packageName, callingUid, userId, 7281 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions); 7282 7283 } catch (RemoteException e) { 7284 throw new SecurityException(e); 7285 } 7286 } 7287 } 7288 7289 IIntentSender getIntentSenderLocked(int type, String packageName, 7290 int callingUid, int userId, IBinder token, String resultWho, 7291 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 7292 Bundle bOptions) { 7293 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 7294 ActivityRecord activity = null; 7295 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 7296 activity = ActivityRecord.isInStackLocked(token); 7297 if (activity == null) { 7298 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack"); 7299 return null; 7300 } 7301 if (activity.finishing) { 7302 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing"); 7303 return null; 7304 } 7305 } 7306 7307 // We're going to be splicing together extras before sending, so we're 7308 // okay poking into any contained extras. 7309 if (intents != null) { 7310 for (int i = 0; i < intents.length; i++) { 7311 intents[i].setDefusable(true); 7312 } 7313 } 7314 Bundle.setDefusable(bOptions, true); 7315 7316 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 7317 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 7318 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 7319 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 7320 |PendingIntent.FLAG_UPDATE_CURRENT); 7321 7322 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 7323 type, packageName, activity, resultWho, 7324 requestCode, intents, resolvedTypes, flags, bOptions, userId); 7325 WeakReference<PendingIntentRecord> ref; 7326 ref = mIntentSenderRecords.get(key); 7327 PendingIntentRecord rec = ref != null ? ref.get() : null; 7328 if (rec != null) { 7329 if (!cancelCurrent) { 7330 if (updateCurrent) { 7331 if (rec.key.requestIntent != null) { 7332 rec.key.requestIntent.replaceExtras(intents != null ? 7333 intents[intents.length - 1] : null); 7334 } 7335 if (intents != null) { 7336 intents[intents.length-1] = rec.key.requestIntent; 7337 rec.key.allIntents = intents; 7338 rec.key.allResolvedTypes = resolvedTypes; 7339 } else { 7340 rec.key.allIntents = null; 7341 rec.key.allResolvedTypes = null; 7342 } 7343 } 7344 return rec; 7345 } 7346 rec.canceled = true; 7347 mIntentSenderRecords.remove(key); 7348 } 7349 if (noCreate) { 7350 return rec; 7351 } 7352 rec = new PendingIntentRecord(this, key, callingUid); 7353 mIntentSenderRecords.put(key, rec.ref); 7354 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 7355 if (activity.pendingResults == null) { 7356 activity.pendingResults 7357 = new HashSet<WeakReference<PendingIntentRecord>>(); 7358 } 7359 activity.pendingResults.add(rec.ref); 7360 } 7361 return rec; 7362 } 7363 7364 @Override 7365 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType, 7366 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 7367 if (target instanceof PendingIntentRecord) { 7368 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType, 7369 finishedReceiver, requiredPermission, options); 7370 } else { 7371 if (intent == null) { 7372 // Weird case: someone has given us their own custom IIntentSender, and now 7373 // they have someone else trying to send to it but of course this isn't 7374 // really a PendingIntent, so there is no base Intent, and the caller isn't 7375 // supplying an Intent... but we never want to dispatch a null Intent to 7376 // a receiver, so um... let's make something up. 7377 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call"); 7378 intent = new Intent(Intent.ACTION_MAIN); 7379 } 7380 try { 7381 target.send(code, intent, resolvedType, null, requiredPermission, options); 7382 } catch (RemoteException e) { 7383 } 7384 // Platform code can rely on getting a result back when the send is done, but if 7385 // this intent sender is from outside of the system we can't rely on it doing that. 7386 // So instead we don't give it the result receiver, and instead just directly 7387 // report the finish immediately. 7388 if (finishedReceiver != null) { 7389 try { 7390 finishedReceiver.performReceive(intent, 0, 7391 null, null, false, false, UserHandle.getCallingUserId()); 7392 } catch (RemoteException e) { 7393 } 7394 } 7395 return 0; 7396 } 7397 } 7398 7399 /** 7400 * Whitelists {@code targetUid} to temporarily bypass Power Save mode. 7401 */ 7402 void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) { 7403 if (DEBUG_WHITELISTS) { 7404 Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", " 7405 + targetUid + ", " + duration + ")"); 7406 } 7407 7408 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid) 7409 != PackageManager.PERMISSION_GRANTED) { 7410 synchronized (mPidsSelfLocked) { 7411 final ProcessRecord pr = mPidsSelfLocked.get(callerPid); 7412 if (pr == null) { 7413 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " 7414 + callerPid); 7415 return; 7416 } 7417 if (!pr.whitelistManager) { 7418 if (DEBUG_WHITELISTS) { 7419 Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid 7420 + ": pid " + callerPid + " is not allowed"); 7421 } 7422 return; 7423 } 7424 } 7425 } 7426 7427 final long token = Binder.clearCallingIdentity(); 7428 try { 7429 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration, 7430 true, "pe from uid:" + callerUid); 7431 } finally { 7432 Binder.restoreCallingIdentity(token); 7433 } 7434 } 7435 7436 @Override 7437 public void cancelIntentSender(IIntentSender sender) { 7438 if (!(sender instanceof PendingIntentRecord)) { 7439 return; 7440 } 7441 synchronized(this) { 7442 PendingIntentRecord rec = (PendingIntentRecord)sender; 7443 try { 7444 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName, 7445 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId()); 7446 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 7447 String msg = "Permission Denial: cancelIntentSender() from pid=" 7448 + Binder.getCallingPid() 7449 + ", uid=" + Binder.getCallingUid() 7450 + " is not allowed to cancel packges " 7451 + rec.key.packageName; 7452 Slog.w(TAG, msg); 7453 throw new SecurityException(msg); 7454 } 7455 } catch (RemoteException e) { 7456 throw new SecurityException(e); 7457 } 7458 cancelIntentSenderLocked(rec, true); 7459 } 7460 } 7461 7462 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 7463 rec.canceled = true; 7464 mIntentSenderRecords.remove(rec.key); 7465 if (cleanActivity && rec.key.activity != null) { 7466 rec.key.activity.pendingResults.remove(rec.ref); 7467 } 7468 } 7469 7470 @Override 7471 public String getPackageForIntentSender(IIntentSender pendingResult) { 7472 if (!(pendingResult instanceof PendingIntentRecord)) { 7473 return null; 7474 } 7475 try { 7476 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7477 return res.key.packageName; 7478 } catch (ClassCastException e) { 7479 } 7480 return null; 7481 } 7482 7483 @Override 7484 public int getUidForIntentSender(IIntentSender sender) { 7485 if (sender instanceof PendingIntentRecord) { 7486 try { 7487 PendingIntentRecord res = (PendingIntentRecord)sender; 7488 return res.uid; 7489 } catch (ClassCastException e) { 7490 } 7491 } 7492 return -1; 7493 } 7494 7495 @Override 7496 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 7497 if (!(pendingResult instanceof PendingIntentRecord)) { 7498 return false; 7499 } 7500 try { 7501 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7502 if (res.key.allIntents == null) { 7503 return false; 7504 } 7505 for (int i=0; i<res.key.allIntents.length; i++) { 7506 Intent intent = res.key.allIntents[i]; 7507 if (intent.getPackage() != null && intent.getComponent() != null) { 7508 return false; 7509 } 7510 } 7511 return true; 7512 } catch (ClassCastException e) { 7513 } 7514 return false; 7515 } 7516 7517 @Override 7518 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 7519 if (!(pendingResult instanceof PendingIntentRecord)) { 7520 return false; 7521 } 7522 try { 7523 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7524 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 7525 return true; 7526 } 7527 return false; 7528 } catch (ClassCastException e) { 7529 } 7530 return false; 7531 } 7532 7533 @Override 7534 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 7535 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT, 7536 "getIntentForIntentSender()"); 7537 if (!(pendingResult instanceof PendingIntentRecord)) { 7538 return null; 7539 } 7540 try { 7541 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7542 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 7543 } catch (ClassCastException e) { 7544 } 7545 return null; 7546 } 7547 7548 @Override 7549 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 7550 if (!(pendingResult instanceof PendingIntentRecord)) { 7551 return null; 7552 } 7553 try { 7554 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 7555 synchronized (this) { 7556 return getTagForIntentSenderLocked(res, prefix); 7557 } 7558 } catch (ClassCastException e) { 7559 } 7560 return null; 7561 } 7562 7563 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) { 7564 final Intent intent = res.key.requestIntent; 7565 if (intent != null) { 7566 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 7567 || res.lastTagPrefix.equals(prefix))) { 7568 return res.lastTag; 7569 } 7570 res.lastTagPrefix = prefix; 7571 final StringBuilder sb = new StringBuilder(128); 7572 if (prefix != null) { 7573 sb.append(prefix); 7574 } 7575 if (intent.getAction() != null) { 7576 sb.append(intent.getAction()); 7577 } else if (intent.getComponent() != null) { 7578 intent.getComponent().appendShortString(sb); 7579 } else { 7580 sb.append("?"); 7581 } 7582 return res.lastTag = sb.toString(); 7583 } 7584 return null; 7585 } 7586 7587 @Override 7588 public void setProcessLimit(int max) { 7589 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 7590 "setProcessLimit()"); 7591 synchronized (this) { 7592 mConstants.setOverrideMaxCachedProcesses(max); 7593 } 7594 trimApplications(); 7595 } 7596 7597 @Override 7598 public int getProcessLimit() { 7599 synchronized (this) { 7600 return mConstants.getOverrideMaxCachedProcesses(); 7601 } 7602 } 7603 7604 void foregroundTokenDied(ForegroundToken token) { 7605 synchronized (ActivityManagerService.this) { 7606 synchronized (mPidsSelfLocked) { 7607 ForegroundToken cur 7608 = mForegroundProcesses.get(token.pid); 7609 if (cur != token) { 7610 return; 7611 } 7612 mForegroundProcesses.remove(token.pid); 7613 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 7614 if (pr == null) { 7615 return; 7616 } 7617 pr.forcingToForeground = null; 7618 updateProcessForegroundLocked(pr, false, false); 7619 } 7620 updateOomAdjLocked(); 7621 } 7622 } 7623 7624 @Override 7625 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 7626 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 7627 "setProcessForeground()"); 7628 synchronized(this) { 7629 boolean changed = false; 7630 7631 synchronized (mPidsSelfLocked) { 7632 ProcessRecord pr = mPidsSelfLocked.get(pid); 7633 if (pr == null && isForeground) { 7634 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 7635 return; 7636 } 7637 ForegroundToken oldToken = mForegroundProcesses.get(pid); 7638 if (oldToken != null) { 7639 oldToken.token.unlinkToDeath(oldToken, 0); 7640 mForegroundProcesses.remove(pid); 7641 if (pr != null) { 7642 pr.forcingToForeground = null; 7643 } 7644 changed = true; 7645 } 7646 if (isForeground && token != null) { 7647 ForegroundToken newToken = new ForegroundToken() { 7648 @Override 7649 public void binderDied() { 7650 foregroundTokenDied(this); 7651 } 7652 }; 7653 newToken.pid = pid; 7654 newToken.token = token; 7655 try { 7656 token.linkToDeath(newToken, 0); 7657 mForegroundProcesses.put(pid, newToken); 7658 pr.forcingToForeground = token; 7659 changed = true; 7660 } catch (RemoteException e) { 7661 // If the process died while doing this, we will later 7662 // do the cleanup with the process death link. 7663 } 7664 } 7665 } 7666 7667 if (changed) { 7668 updateOomAdjLocked(); 7669 } 7670 } 7671 } 7672 7673 @Override 7674 public boolean isAppForeground(int uid) throws RemoteException { 7675 synchronized (this) { 7676 UidRecord uidRec = mActiveUids.get(uid); 7677 if (uidRec == null || uidRec.idle) { 7678 return false; 7679 } 7680 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 7681 } 7682 } 7683 7684 // NOTE: this is an internal method used by the OnShellCommand implementation only and should 7685 // be guarded by permission checking. 7686 int getUidState(int uid) { 7687 synchronized (this) { 7688 UidRecord uidRec = mActiveUids.get(uid); 7689 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState; 7690 } 7691 } 7692 7693 @Override 7694 public boolean isInMultiWindowMode(IBinder token) { 7695 final long origId = Binder.clearCallingIdentity(); 7696 try { 7697 synchronized(this) { 7698 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 7699 if (r == null) { 7700 return false; 7701 } 7702 // An activity is consider to be in multi-window mode if its task isn't fullscreen. 7703 return !r.task.mFullscreen; 7704 } 7705 } finally { 7706 Binder.restoreCallingIdentity(origId); 7707 } 7708 } 7709 7710 @Override 7711 public boolean isInPictureInPictureMode(IBinder token) { 7712 final long origId = Binder.clearCallingIdentity(); 7713 try { 7714 synchronized(this) { 7715 final ActivityStack stack = ActivityRecord.getStackLocked(token); 7716 if (stack == null) { 7717 return false; 7718 } 7719 return stack.mStackId == PINNED_STACK_ID; 7720 } 7721 } finally { 7722 Binder.restoreCallingIdentity(origId); 7723 } 7724 } 7725 7726 @Override 7727 public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureArgs args) { 7728 final long origId = Binder.clearCallingIdentity(); 7729 try { 7730 synchronized(this) { 7731 final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked( 7732 "enterPictureInPictureMode", token, args); 7733 7734 // Activity supports picture-in-picture, now check that we can enter PiP at this 7735 // point, if it is 7736 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode", 7737 false /* noThrow */)) { 7738 return false; 7739 } 7740 7741 final Runnable enterPipRunnable = () -> { 7742 // Only update the saved args from the args that are set 7743 r.pictureInPictureArgs.copyOnlySet(args); 7744 final float aspectRatio = r.pictureInPictureArgs.getAspectRatio(); 7745 final List<RemoteAction> actions = r.pictureInPictureArgs.getActions(); 7746 final Rect bounds = mWindowManager.getPictureInPictureBounds(DEFAULT_DISPLAY, 7747 aspectRatio); 7748 mStackSupervisor.moveActivityToPinnedStackLocked(r, "enterPictureInPictureMode", 7749 bounds, true /* moveHomeStackToFront */); 7750 final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID); 7751 stack.setPictureInPictureAspectRatio(aspectRatio); 7752 stack.setPictureInPictureActions(actions); 7753 7754 MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED, 7755 r.supportsPictureInPictureWhilePausing); 7756 logPictureInPictureArgs(args); 7757 }; 7758 7759 if (isKeyguardLocked()) { 7760 // If the keyguard is showing or occluded, then try and dismiss it before 7761 // entering picture-in-picture (this will prompt the user to authenticate if the 7762 // device is currently locked). 7763 try { 7764 dismissKeyguard(token, new IKeyguardDismissCallback.Stub() { 7765 @Override 7766 public void onDismissError() throws RemoteException { 7767 // Do nothing 7768 } 7769 7770 @Override 7771 public void onDismissSucceeded() throws RemoteException { 7772 mHandler.post(enterPipRunnable); 7773 } 7774 7775 @Override 7776 public void onDismissCancelled() throws RemoteException { 7777 // Do nothing 7778 } 7779 }); 7780 } catch (RemoteException e) { 7781 // Local call 7782 } 7783 } else { 7784 // Enter picture in picture immediately otherwise 7785 enterPipRunnable.run(); 7786 } 7787 return true; 7788 } 7789 } finally { 7790 Binder.restoreCallingIdentity(origId); 7791 } 7792 } 7793 7794 @Override 7795 public void setPictureInPictureArgs(IBinder token, final PictureInPictureArgs args) { 7796 final long origId = Binder.clearCallingIdentity(); 7797 try { 7798 synchronized(this) { 7799 final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked( 7800 "setPictureInPictureArgs", token, args); 7801 7802 // Only update the saved args from the args that are set 7803 r.pictureInPictureArgs.copyOnlySet(args); 7804 if (r.getStack().getStackId() == PINNED_STACK_ID) { 7805 // If the activity is already in picture-in-picture, update the pinned stack now 7806 final PinnedActivityStack stack = r.getStack(); 7807 stack.setPictureInPictureAspectRatio(r.pictureInPictureArgs.getAspectRatio()); 7808 stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions()); 7809 } 7810 logPictureInPictureArgs(args); 7811 } 7812 } finally { 7813 Binder.restoreCallingIdentity(origId); 7814 } 7815 } 7816 7817 private void logPictureInPictureArgs(PictureInPictureArgs args) { 7818 if (args.hasSetActions()) { 7819 MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count", 7820 args.getActions().size()); 7821 } 7822 if (args.hasSetAspectRatio()) { 7823 LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED); 7824 lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, args.getAspectRatio()); 7825 MetricsLogger.action(lm); 7826 } 7827 } 7828 7829 /** 7830 * Checks the state of the system and the activity associated with the given {@param token} to 7831 * verify that picture-in-picture is supported for that activity. 7832 * 7833 * @return the activity record for the given {@param token} if all the checks pass. 7834 */ 7835 private ActivityRecord ensureValidPictureInPictureActivityArgsLocked(String caller, 7836 IBinder token, PictureInPictureArgs args) { 7837 if (!mSupportsPictureInPicture) { 7838 throw new IllegalStateException(caller 7839 + ": Device doesn't support picture-in-picture mode."); 7840 } 7841 7842 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 7843 if (r == null) { 7844 throw new IllegalStateException(caller 7845 + ": Can't find activity for token=" + token); 7846 } 7847 7848 if (!r.supportsPictureInPicture()) { 7849 throw new IllegalStateException(caller 7850 + ": Current activity does not support picture-in-picture."); 7851 } 7852 7853 if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) { 7854 throw new IllegalStateException(caller 7855 + ": Activities on the home, assistant, or recents stack not supported"); 7856 } 7857 7858 if (args.hasSetAspectRatio() 7859 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId, 7860 args.getAspectRatio())) { 7861 final float minAspectRatio = mContext.getResources().getFloat( 7862 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); 7863 final float maxAspectRatio = mContext.getResources().getFloat( 7864 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio); 7865 throw new IllegalArgumentException(String.format(caller 7866 + ": Aspect ratio is too extreme (must be between %f and %f).", 7867 minAspectRatio, maxAspectRatio)); 7868 } 7869 7870 if (args.hasSetActions() 7871 && args.getActions().size() > ActivityManager.getMaxNumPictureInPictureActions()) { 7872 throw new IllegalArgumentException(String.format(caller + ": Invalid number of" 7873 + "picture-in-picture actions. Only a maximum of %d actions allowed", 7874 ActivityManager.getMaxNumPictureInPictureActions())); 7875 } 7876 7877 return r; 7878 } 7879 7880 // ========================================================= 7881 // PROCESS INFO 7882 // ========================================================= 7883 7884 static class ProcessInfoService extends IProcessInfoService.Stub { 7885 final ActivityManagerService mActivityManagerService; 7886 ProcessInfoService(ActivityManagerService activityManagerService) { 7887 mActivityManagerService = activityManagerService; 7888 } 7889 7890 @Override 7891 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) { 7892 mActivityManagerService.getProcessStatesAndOomScoresForPIDs( 7893 /*in*/ pids, /*out*/ states, null); 7894 } 7895 7896 @Override 7897 public void getProcessStatesAndOomScoresFromPids( 7898 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) { 7899 mActivityManagerService.getProcessStatesAndOomScoresForPIDs( 7900 /*in*/ pids, /*out*/ states, /*out*/ scores); 7901 } 7902 } 7903 7904 /** 7905 * For each PID in the given input array, write the current process state 7906 * for that process into the states array, or -1 to indicate that no 7907 * process with the given PID exists. If scores array is provided, write 7908 * the oom score for the process into the scores array, with INVALID_ADJ 7909 * indicating the PID doesn't exist. 7910 */ 7911 public void getProcessStatesAndOomScoresForPIDs( 7912 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) { 7913 if (scores != null) { 7914 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE, 7915 "getProcessStatesAndOomScoresForPIDs()"); 7916 } 7917 7918 if (pids == null) { 7919 throw new NullPointerException("pids"); 7920 } else if (states == null) { 7921 throw new NullPointerException("states"); 7922 } else if (pids.length != states.length) { 7923 throw new IllegalArgumentException("pids and states arrays have different lengths!"); 7924 } else if (scores != null && pids.length != scores.length) { 7925 throw new IllegalArgumentException("pids and scores arrays have different lengths!"); 7926 } 7927 7928 synchronized (mPidsSelfLocked) { 7929 for (int i = 0; i < pids.length; i++) { 7930 ProcessRecord pr = mPidsSelfLocked.get(pids[i]); 7931 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT : 7932 pr.curProcState; 7933 if (scores != null) { 7934 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj; 7935 } 7936 } 7937 } 7938 } 7939 7940 // ========================================================= 7941 // PERMISSIONS 7942 // ========================================================= 7943 7944 static class PermissionController extends IPermissionController.Stub { 7945 ActivityManagerService mActivityManagerService; 7946 PermissionController(ActivityManagerService activityManagerService) { 7947 mActivityManagerService = activityManagerService; 7948 } 7949 7950 @Override 7951 public boolean checkPermission(String permission, int pid, int uid) { 7952 return mActivityManagerService.checkPermission(permission, pid, 7953 uid) == PackageManager.PERMISSION_GRANTED; 7954 } 7955 7956 @Override 7957 public String[] getPackagesForUid(int uid) { 7958 return mActivityManagerService.mContext.getPackageManager() 7959 .getPackagesForUid(uid); 7960 } 7961 7962 @Override 7963 public boolean isRuntimePermission(String permission) { 7964 try { 7965 PermissionInfo info = mActivityManagerService.mContext.getPackageManager() 7966 .getPermissionInfo(permission, 0); 7967 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) 7968 == PermissionInfo.PROTECTION_DANGEROUS; 7969 } catch (NameNotFoundException nnfe) { 7970 Slog.e(TAG, "No such permission: "+ permission, nnfe); 7971 } 7972 return false; 7973 } 7974 } 7975 7976 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 7977 @Override 7978 public int checkComponentPermission(String permission, int pid, int uid, 7979 int owningUid, boolean exported) { 7980 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 7981 owningUid, exported); 7982 } 7983 7984 @Override 7985 public Object getAMSLock() { 7986 return ActivityManagerService.this; 7987 } 7988 } 7989 7990 /** 7991 * This can be called with or without the global lock held. 7992 */ 7993 int checkComponentPermission(String permission, int pid, int uid, 7994 int owningUid, boolean exported) { 7995 if (pid == MY_PID) { 7996 return PackageManager.PERMISSION_GRANTED; 7997 } 7998 return ActivityManager.checkComponentPermission(permission, uid, 7999 owningUid, exported); 8000 } 8001 8002 /** 8003 * As the only public entry point for permissions checking, this method 8004 * can enforce the semantic that requesting a check on a null global 8005 * permission is automatically denied. (Internally a null permission 8006 * string is used when calling {@link #checkComponentPermission} in cases 8007 * when only uid-based security is needed.) 8008 * 8009 * This can be called with or without the global lock held. 8010 */ 8011 @Override 8012 public int checkPermission(String permission, int pid, int uid) { 8013 if (permission == null) { 8014 return PackageManager.PERMISSION_DENIED; 8015 } 8016 return checkComponentPermission(permission, pid, uid, -1, true); 8017 } 8018 8019 @Override 8020 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { 8021 if (permission == null) { 8022 return PackageManager.PERMISSION_DENIED; 8023 } 8024 8025 // We might be performing an operation on behalf of an indirect binder 8026 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 8027 // client identity accordingly before proceeding. 8028 Identity tlsIdentity = sCallerIdentity.get(); 8029 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 8030 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 8031 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 8032 uid = tlsIdentity.uid; 8033 pid = tlsIdentity.pid; 8034 } 8035 8036 return checkComponentPermission(permission, pid, uid, -1, true); 8037 } 8038 8039 /** 8040 * Binder IPC calls go through the public entry point. 8041 * This can be called with or without the global lock held. 8042 */ 8043 int checkCallingPermission(String permission) { 8044 return checkPermission(permission, 8045 Binder.getCallingPid(), 8046 UserHandle.getAppId(Binder.getCallingUid())); 8047 } 8048 8049 /** 8050 * This can be called with or without the global lock held. 8051 */ 8052 void enforceCallingPermission(String permission, String func) { 8053 if (checkCallingPermission(permission) 8054 == PackageManager.PERMISSION_GRANTED) { 8055 return; 8056 } 8057 8058 String msg = "Permission Denial: " + func + " from pid=" 8059 + Binder.getCallingPid() 8060 + ", uid=" + Binder.getCallingUid() 8061 + " requires " + permission; 8062 Slog.w(TAG, msg); 8063 throw new SecurityException(msg); 8064 } 8065 8066 /** 8067 * Determine if UID is holding permissions required to access {@link Uri} in 8068 * the given {@link ProviderInfo}. Final permission checking is always done 8069 * in {@link ContentProvider}. 8070 */ 8071 private final boolean checkHoldingPermissionsLocked( 8072 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 8073 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8074 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 8075 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 8076 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 8077 != PERMISSION_GRANTED) { 8078 return false; 8079 } 8080 } 8081 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 8082 } 8083 8084 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 8085 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 8086 if (pi.applicationInfo.uid == uid) { 8087 return true; 8088 } else if (!pi.exported) { 8089 return false; 8090 } 8091 8092 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 8093 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 8094 try { 8095 // check if target holds top-level <provider> permissions 8096 if (!readMet && pi.readPermission != null && considerUidPermissions 8097 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 8098 readMet = true; 8099 } 8100 if (!writeMet && pi.writePermission != null && considerUidPermissions 8101 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 8102 writeMet = true; 8103 } 8104 8105 // track if unprotected read/write is allowed; any denied 8106 // <path-permission> below removes this ability 8107 boolean allowDefaultRead = pi.readPermission == null; 8108 boolean allowDefaultWrite = pi.writePermission == null; 8109 8110 // check if target holds any <path-permission> that match uri 8111 final PathPermission[] pps = pi.pathPermissions; 8112 if (pps != null) { 8113 final String path = grantUri.uri.getPath(); 8114 int i = pps.length; 8115 while (i > 0 && (!readMet || !writeMet)) { 8116 i--; 8117 PathPermission pp = pps[i]; 8118 if (pp.match(path)) { 8119 if (!readMet) { 8120 final String pprperm = pp.getReadPermission(); 8121 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8122 "Checking read perm for " + pprperm + " for " + pp.getPath() 8123 + ": match=" + pp.match(path) 8124 + " check=" + pm.checkUidPermission(pprperm, uid)); 8125 if (pprperm != null) { 8126 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 8127 == PERMISSION_GRANTED) { 8128 readMet = true; 8129 } else { 8130 allowDefaultRead = false; 8131 } 8132 } 8133 } 8134 if (!writeMet) { 8135 final String ppwperm = pp.getWritePermission(); 8136 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8137 "Checking write perm " + ppwperm + " for " + pp.getPath() 8138 + ": match=" + pp.match(path) 8139 + " check=" + pm.checkUidPermission(ppwperm, uid)); 8140 if (ppwperm != null) { 8141 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 8142 == PERMISSION_GRANTED) { 8143 writeMet = true; 8144 } else { 8145 allowDefaultWrite = false; 8146 } 8147 } 8148 } 8149 } 8150 } 8151 } 8152 8153 // grant unprotected <provider> read/write, if not blocked by 8154 // <path-permission> above 8155 if (allowDefaultRead) readMet = true; 8156 if (allowDefaultWrite) writeMet = true; 8157 8158 } catch (RemoteException e) { 8159 return false; 8160 } 8161 8162 return readMet && writeMet; 8163 } 8164 8165 public boolean isAppStartModeDisabled(int uid, String packageName) { 8166 synchronized (this) { 8167 return getAppStartModeLocked(uid, packageName, 0, -1, false, true) 8168 == ActivityManager.APP_START_MODE_DISABLED; 8169 } 8170 } 8171 8172 // Unified app-op and target sdk check 8173 int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) { 8174 // Apps that target O+ are always subject to background check 8175 if (mConstants.ENFORCE_BG_CHECK && packageTargetSdk >= Build.VERSION_CODES.O) { 8176 if (DEBUG_BACKGROUND_CHECK) { 8177 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted"); 8178 } 8179 return ActivityManager.APP_START_MODE_DELAYED_RIGID; 8180 } 8181 // ...and legacy apps get an AppOp check 8182 int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, 8183 uid, packageName); 8184 if (DEBUG_BACKGROUND_CHECK) { 8185 Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop); 8186 } 8187 switch (appop) { 8188 case AppOpsManager.MODE_ALLOWED: 8189 return ActivityManager.APP_START_MODE_NORMAL; 8190 case AppOpsManager.MODE_IGNORED: 8191 return ActivityManager.APP_START_MODE_DELAYED; 8192 default: 8193 return ActivityManager.APP_START_MODE_DELAYED_RIGID; 8194 } 8195 } 8196 8197 // Service launch is available to apps with run-in-background exemptions but 8198 // some other background operations are not. If we're doing a check 8199 // of service-launch policy, allow those callers to proceed unrestricted. 8200 int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) { 8201 // Persistent app? 8202 if (mPackageManagerInt.isPackagePersistent(packageName)) { 8203 if (DEBUG_BACKGROUND_CHECK) { 8204 Slog.i(TAG, "App " + uid + "/" + packageName 8205 + " is persistent; not restricted in background"); 8206 } 8207 return ActivityManager.APP_START_MODE_NORMAL; 8208 } 8209 8210 // Non-persistent but background whitelisted? 8211 if (uidOnBackgroundWhitelist(uid)) { 8212 if (DEBUG_BACKGROUND_CHECK) { 8213 Slog.i(TAG, "App " + uid + "/" + packageName 8214 + " on background whitelist; not restricted in background"); 8215 } 8216 return ActivityManager.APP_START_MODE_NORMAL; 8217 } 8218 8219 // Is this app on the battery whitelist? 8220 if (isOnDeviceIdleWhitelistLocked(uid)) { 8221 if (DEBUG_BACKGROUND_CHECK) { 8222 Slog.i(TAG, "App " + uid + "/" + packageName 8223 + " on idle whitelist; not restricted in background"); 8224 } 8225 return ActivityManager.APP_START_MODE_NORMAL; 8226 } 8227 8228 // None of the service-policy criteria apply, so we apply the common criteria 8229 return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk); 8230 } 8231 8232 int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk, 8233 int callingPid, boolean alwaysRestrict, boolean disabledOnly) { 8234 UidRecord uidRec = mActiveUids.get(uid); 8235 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg=" 8236 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle=" 8237 + (uidRec != null ? uidRec.idle : false)); 8238 if (uidRec == null || alwaysRestrict || uidRec.idle) { 8239 boolean ephemeral; 8240 if (uidRec == null) { 8241 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral( 8242 UserHandle.getUserId(uid), packageName); 8243 } else { 8244 ephemeral = uidRec.ephemeral; 8245 } 8246 8247 if (ephemeral) { 8248 // We are hard-core about ephemeral apps not running in the background. 8249 return ActivityManager.APP_START_MODE_DISABLED; 8250 } else { 8251 if (disabledOnly) { 8252 // The caller is only interested in whether app starts are completely 8253 // disabled for the given package (that is, it is an instant app). So 8254 // we don't need to go further, which is all just seeing if we should 8255 // apply a "delayed" mode for a regular app. 8256 return ActivityManager.APP_START_MODE_NORMAL; 8257 } 8258 final int startMode = (alwaysRestrict) 8259 ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk) 8260 : appServicesRestrictedInBackgroundLocked(uid, packageName, 8261 packageTargetSdk); 8262 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid 8263 + " pkg=" + packageName + " startMode=" + startMode 8264 + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid)); 8265 if (startMode == ActivityManager.APP_START_MODE_DELAYED) { 8266 // This is an old app that has been forced into a "compatible as possible" 8267 // mode of background check. To increase compatibility, we will allow other 8268 // foreground apps to cause its services to start. 8269 if (callingPid >= 0) { 8270 ProcessRecord proc; 8271 synchronized (mPidsSelfLocked) { 8272 proc = mPidsSelfLocked.get(callingPid); 8273 } 8274 if (proc != null && proc.curProcState 8275 < ActivityManager.PROCESS_STATE_RECEIVER) { 8276 // Whoever is instigating this is in the foreground, so we will allow it 8277 // to go through. 8278 return ActivityManager.APP_START_MODE_NORMAL; 8279 } 8280 } 8281 } 8282 return startMode; 8283 } 8284 } 8285 return ActivityManager.APP_START_MODE_NORMAL; 8286 } 8287 8288 boolean isOnDeviceIdleWhitelistLocked(int uid) { 8289 final int appId = UserHandle.getAppId(uid); 8290 return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0 8291 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0; 8292 } 8293 8294 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) { 8295 ProviderInfo pi = null; 8296 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 8297 if (cpr != null) { 8298 pi = cpr.info; 8299 } else { 8300 try { 8301 pi = AppGlobals.getPackageManager().resolveContentProvider( 8302 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags, 8303 userHandle); 8304 } catch (RemoteException ex) { 8305 } 8306 } 8307 return pi; 8308 } 8309 8310 void grantEphemeralAccessLocked(int userId, Intent intent, 8311 int targetAppId, int ephemeralAppId) { 8312 getPackageManagerInternalLocked(). 8313 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId); 8314 } 8315 8316 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 8317 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 8318 if (targetUris != null) { 8319 return targetUris.get(grantUri); 8320 } 8321 return null; 8322 } 8323 8324 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 8325 String targetPkg, int targetUid, GrantUri grantUri) { 8326 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 8327 if (targetUris == null) { 8328 targetUris = Maps.newArrayMap(); 8329 mGrantedUriPermissions.put(targetUid, targetUris); 8330 } 8331 8332 UriPermission perm = targetUris.get(grantUri); 8333 if (perm == null) { 8334 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 8335 targetUris.put(grantUri, perm); 8336 } 8337 8338 return perm; 8339 } 8340 8341 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 8342 final int modeFlags) { 8343 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 8344 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 8345 : UriPermission.STRENGTH_OWNED; 8346 8347 // Root gets to do everything. 8348 if (uid == 0) { 8349 return true; 8350 } 8351 8352 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 8353 if (perms == null) return false; 8354 8355 // First look for exact match 8356 final UriPermission exactPerm = perms.get(grantUri); 8357 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 8358 return true; 8359 } 8360 8361 // No exact match, look for prefixes 8362 final int N = perms.size(); 8363 for (int i = 0; i < N; i++) { 8364 final UriPermission perm = perms.valueAt(i); 8365 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 8366 && perm.getStrength(modeFlags) >= minStrength) { 8367 return true; 8368 } 8369 } 8370 8371 return false; 8372 } 8373 8374 /** 8375 * @param uri This uri must NOT contain an embedded userId. 8376 * @param userId The userId in which the uri is to be resolved. 8377 */ 8378 @Override 8379 public int checkUriPermission(Uri uri, int pid, int uid, 8380 final int modeFlags, int userId, IBinder callerToken) { 8381 enforceNotIsolatedCaller("checkUriPermission"); 8382 8383 // Another redirected-binder-call permissions check as in 8384 // {@link checkPermissionWithToken}. 8385 Identity tlsIdentity = sCallerIdentity.get(); 8386 if (tlsIdentity != null && tlsIdentity.token == callerToken) { 8387 uid = tlsIdentity.uid; 8388 pid = tlsIdentity.pid; 8389 } 8390 8391 // Our own process gets to do everything. 8392 if (pid == MY_PID) { 8393 return PackageManager.PERMISSION_GRANTED; 8394 } 8395 synchronized (this) { 8396 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 8397 ? PackageManager.PERMISSION_GRANTED 8398 : PackageManager.PERMISSION_DENIED; 8399 } 8400 } 8401 8402 /** 8403 * Check if the targetPkg can be granted permission to access uri by 8404 * the callingUid using the given modeFlags. Throws a security exception 8405 * if callingUid is not allowed to do this. Returns the uid of the target 8406 * if the URI permission grant should be performed; returns -1 if it is not 8407 * needed (for example targetPkg already has permission to access the URI). 8408 * If you already know the uid of the target, you can supply it in 8409 * lastTargetUid else set that to -1. 8410 */ 8411 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 8412 final int modeFlags, int lastTargetUid) { 8413 if (!Intent.isAccessUriMode(modeFlags)) { 8414 return -1; 8415 } 8416 8417 if (targetPkg != null) { 8418 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8419 "Checking grant " + targetPkg + " permission to " + grantUri); 8420 } 8421 8422 final IPackageManager pm = AppGlobals.getPackageManager(); 8423 8424 // If this is not a content: uri, we can't do anything with it. 8425 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 8426 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8427 "Can't grant URI permission for non-content URI: " + grantUri); 8428 return -1; 8429 } 8430 8431 final String authority = grantUri.uri.getAuthority(); 8432 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId, 8433 MATCH_DEBUG_TRIAGED_MISSING); 8434 if (pi == null) { 8435 Slog.w(TAG, "No content provider found for permission check: " + 8436 grantUri.uri.toSafeString()); 8437 return -1; 8438 } 8439 8440 int targetUid = lastTargetUid; 8441 if (targetUid < 0 && targetPkg != null) { 8442 try { 8443 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, 8444 UserHandle.getUserId(callingUid)); 8445 if (targetUid < 0) { 8446 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8447 "Can't grant URI permission no uid for: " + targetPkg); 8448 return -1; 8449 } 8450 } catch (RemoteException ex) { 8451 return -1; 8452 } 8453 } 8454 8455 // If we're extending a persistable grant, then we always need to create 8456 // the grant data structure so that take/release APIs work 8457 if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) { 8458 return targetUid; 8459 } 8460 8461 if (targetUid >= 0) { 8462 // First... does the target actually need this permission? 8463 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 8464 // No need to grant the target this permission. 8465 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8466 "Target " + targetPkg + " already has full permission to " + grantUri); 8467 return -1; 8468 } 8469 } else { 8470 // First... there is no target package, so can anyone access it? 8471 boolean allowed = pi.exported; 8472 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 8473 if (pi.readPermission != null) { 8474 allowed = false; 8475 } 8476 } 8477 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 8478 if (pi.writePermission != null) { 8479 allowed = false; 8480 } 8481 } 8482 if (allowed) { 8483 return -1; 8484 } 8485 } 8486 8487 /* There is a special cross user grant if: 8488 * - The target is on another user. 8489 * - Apps on the current user can access the uri without any uid permissions. 8490 * In this case, we grant a uri permission, even if the ContentProvider does not normally 8491 * grant uri permissions. 8492 */ 8493 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 8494 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 8495 modeFlags, false /*without considering the uid permissions*/); 8496 8497 // Second... is the provider allowing granting of URI permissions? 8498 if (!specialCrossUserGrant) { 8499 if (!pi.grantUriPermissions) { 8500 throw new SecurityException("Provider " + pi.packageName 8501 + "/" + pi.name 8502 + " does not allow granting of Uri permissions (uri " 8503 + grantUri + ")"); 8504 } 8505 if (pi.uriPermissionPatterns != null) { 8506 final int N = pi.uriPermissionPatterns.length; 8507 boolean allowed = false; 8508 for (int i=0; i<N; i++) { 8509 if (pi.uriPermissionPatterns[i] != null 8510 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 8511 allowed = true; 8512 break; 8513 } 8514 } 8515 if (!allowed) { 8516 throw new SecurityException("Provider " + pi.packageName 8517 + "/" + pi.name 8518 + " does not allow granting of permission to path of Uri " 8519 + grantUri); 8520 } 8521 } 8522 } 8523 8524 // Third... does the caller itself have permission to access 8525 // this uri? 8526 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 8527 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 8528 // Require they hold a strong enough Uri permission 8529 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 8530 throw new SecurityException("Uid " + callingUid 8531 + " does not have permission to uri " + grantUri); 8532 } 8533 } 8534 } 8535 return targetUid; 8536 } 8537 8538 /** 8539 * @param uri This uri must NOT contain an embedded userId. 8540 * @param userId The userId in which the uri is to be resolved. 8541 */ 8542 @Override 8543 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 8544 final int modeFlags, int userId) { 8545 enforceNotIsolatedCaller("checkGrantUriPermission"); 8546 synchronized(this) { 8547 return checkGrantUriPermissionLocked(callingUid, targetPkg, 8548 new GrantUri(userId, uri, false), modeFlags, -1); 8549 } 8550 } 8551 8552 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 8553 final int modeFlags, UriPermissionOwner owner) { 8554 if (!Intent.isAccessUriMode(modeFlags)) { 8555 return; 8556 } 8557 8558 // So here we are: the caller has the assumed permission 8559 // to the uri, and the target doesn't. Let's now give this to 8560 // the target. 8561 8562 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8563 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 8564 8565 final String authority = grantUri.uri.getAuthority(); 8566 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId, 8567 MATCH_DEBUG_TRIAGED_MISSING); 8568 if (pi == null) { 8569 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 8570 return; 8571 } 8572 8573 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 8574 grantUri.prefix = true; 8575 } 8576 final UriPermission perm = findOrCreateUriPermissionLocked( 8577 pi.packageName, targetPkg, targetUid, grantUri); 8578 perm.grantModes(modeFlags, owner); 8579 } 8580 8581 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 8582 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 8583 if (targetPkg == null) { 8584 throw new NullPointerException("targetPkg"); 8585 } 8586 int targetUid; 8587 final IPackageManager pm = AppGlobals.getPackageManager(); 8588 try { 8589 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId); 8590 } catch (RemoteException ex) { 8591 return; 8592 } 8593 8594 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 8595 targetUid); 8596 if (targetUid < 0) { 8597 return; 8598 } 8599 8600 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 8601 owner); 8602 } 8603 8604 static class NeededUriGrants extends ArrayList<GrantUri> { 8605 final String targetPkg; 8606 final int targetUid; 8607 final int flags; 8608 8609 NeededUriGrants(String targetPkg, int targetUid, int flags) { 8610 this.targetPkg = targetPkg; 8611 this.targetUid = targetUid; 8612 this.flags = flags; 8613 } 8614 } 8615 8616 /** 8617 * Like checkGrantUriPermissionLocked, but takes an Intent. 8618 */ 8619 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 8620 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 8621 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8622 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 8623 + " clip=" + (intent != null ? intent.getClipData() : null) 8624 + " from " + intent + "; flags=0x" 8625 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 8626 8627 if (targetPkg == null) { 8628 throw new NullPointerException("targetPkg"); 8629 } 8630 8631 if (intent == null) { 8632 return null; 8633 } 8634 Uri data = intent.getData(); 8635 ClipData clip = intent.getClipData(); 8636 if (data == null && clip == null) { 8637 return null; 8638 } 8639 // Default userId for uris in the intent (if they don't specify it themselves) 8640 int contentUserHint = intent.getContentUserHint(); 8641 if (contentUserHint == UserHandle.USER_CURRENT) { 8642 contentUserHint = UserHandle.getUserId(callingUid); 8643 } 8644 final IPackageManager pm = AppGlobals.getPackageManager(); 8645 int targetUid; 8646 if (needed != null) { 8647 targetUid = needed.targetUid; 8648 } else { 8649 try { 8650 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, 8651 targetUserId); 8652 } catch (RemoteException ex) { 8653 return null; 8654 } 8655 if (targetUid < 0) { 8656 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8657 "Can't grant URI permission no uid for: " + targetPkg 8658 + " on user " + targetUserId); 8659 return null; 8660 } 8661 } 8662 if (data != null) { 8663 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 8664 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 8665 targetUid); 8666 if (targetUid > 0) { 8667 if (needed == null) { 8668 needed = new NeededUriGrants(targetPkg, targetUid, mode); 8669 } 8670 needed.add(grantUri); 8671 } 8672 } 8673 if (clip != null) { 8674 for (int i=0; i<clip.getItemCount(); i++) { 8675 Uri uri = clip.getItemAt(i).getUri(); 8676 if (uri != null) { 8677 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 8678 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 8679 targetUid); 8680 if (targetUid > 0) { 8681 if (needed == null) { 8682 needed = new NeededUriGrants(targetPkg, targetUid, mode); 8683 } 8684 needed.add(grantUri); 8685 } 8686 } else { 8687 Intent clipIntent = clip.getItemAt(i).getIntent(); 8688 if (clipIntent != null) { 8689 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 8690 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 8691 if (newNeeded != null) { 8692 needed = newNeeded; 8693 } 8694 } 8695 } 8696 } 8697 } 8698 8699 return needed; 8700 } 8701 8702 /** 8703 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 8704 */ 8705 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 8706 UriPermissionOwner owner) { 8707 if (needed != null) { 8708 for (int i=0; i<needed.size(); i++) { 8709 GrantUri grantUri = needed.get(i); 8710 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 8711 grantUri, needed.flags, owner); 8712 } 8713 } 8714 } 8715 8716 void grantUriPermissionFromIntentLocked(int callingUid, 8717 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 8718 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 8719 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 8720 if (needed == null) { 8721 return; 8722 } 8723 8724 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 8725 } 8726 8727 /** 8728 * @param uri This uri must NOT contain an embedded userId. 8729 * @param userId The userId in which the uri is to be resolved. 8730 */ 8731 @Override 8732 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 8733 final int modeFlags, int userId) { 8734 enforceNotIsolatedCaller("grantUriPermission"); 8735 GrantUri grantUri = new GrantUri(userId, uri, false); 8736 synchronized(this) { 8737 final ProcessRecord r = getRecordForAppLocked(caller); 8738 if (r == null) { 8739 throw new SecurityException("Unable to find app for caller " 8740 + caller 8741 + " when granting permission to uri " + grantUri); 8742 } 8743 if (targetPkg == null) { 8744 throw new IllegalArgumentException("null target"); 8745 } 8746 if (grantUri == null) { 8747 throw new IllegalArgumentException("null uri"); 8748 } 8749 8750 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 8751 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 8752 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 8753 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 8754 8755 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 8756 UserHandle.getUserId(r.uid)); 8757 } 8758 } 8759 8760 void removeUriPermissionIfNeededLocked(UriPermission perm) { 8761 if (perm.modeFlags == 0) { 8762 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 8763 perm.targetUid); 8764 if (perms != null) { 8765 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8766 "Removing " + perm.targetUid + " permission to " + perm.uri); 8767 8768 perms.remove(perm.uri); 8769 if (perms.isEmpty()) { 8770 mGrantedUriPermissions.remove(perm.targetUid); 8771 } 8772 } 8773 } 8774 } 8775 8776 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 8777 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8778 "Revoking all granted permissions to " + grantUri); 8779 8780 final IPackageManager pm = AppGlobals.getPackageManager(); 8781 final String authority = grantUri.uri.getAuthority(); 8782 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId, 8783 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE); 8784 if (pi == null) { 8785 Slog.w(TAG, "No content provider found for permission revoke: " 8786 + grantUri.toSafeString()); 8787 return; 8788 } 8789 8790 // Does the caller have this permission on the URI? 8791 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 8792 // If they don't have direct access to the URI, then revoke any 8793 // ownerless URI permissions that have been granted to them. 8794 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8795 if (perms != null) { 8796 boolean persistChanged = false; 8797 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 8798 final UriPermission perm = it.next(); 8799 if (perm.uri.sourceUserId == grantUri.sourceUserId 8800 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 8801 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8802 "Revoking non-owned " + perm.targetUid 8803 + " permission to " + perm.uri); 8804 persistChanged |= perm.revokeModes( 8805 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false); 8806 if (perm.modeFlags == 0) { 8807 it.remove(); 8808 } 8809 } 8810 } 8811 if (perms.isEmpty()) { 8812 mGrantedUriPermissions.remove(callingUid); 8813 } 8814 if (persistChanged) { 8815 schedulePersistUriGrants(); 8816 } 8817 } 8818 return; 8819 } 8820 8821 boolean persistChanged = false; 8822 8823 // Go through all of the permissions and remove any that match. 8824 int N = mGrantedUriPermissions.size(); 8825 for (int i = 0; i < N; i++) { 8826 final int targetUid = mGrantedUriPermissions.keyAt(i); 8827 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 8828 8829 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 8830 final UriPermission perm = it.next(); 8831 if (perm.uri.sourceUserId == grantUri.sourceUserId 8832 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 8833 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 8834 "Revoking " + perm.targetUid + " permission to " + perm.uri); 8835 persistChanged |= perm.revokeModes( 8836 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 8837 if (perm.modeFlags == 0) { 8838 it.remove(); 8839 } 8840 } 8841 } 8842 8843 if (perms.isEmpty()) { 8844 mGrantedUriPermissions.remove(targetUid); 8845 N--; 8846 i--; 8847 } 8848 } 8849 8850 if (persistChanged) { 8851 schedulePersistUriGrants(); 8852 } 8853 } 8854 8855 /** 8856 * @param uri This uri must NOT contain an embedded userId. 8857 * @param userId The userId in which the uri is to be resolved. 8858 */ 8859 @Override 8860 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 8861 int userId) { 8862 enforceNotIsolatedCaller("revokeUriPermission"); 8863 synchronized(this) { 8864 final ProcessRecord r = getRecordForAppLocked(caller); 8865 if (r == null) { 8866 throw new SecurityException("Unable to find app for caller " 8867 + caller 8868 + " when revoking permission to uri " + uri); 8869 } 8870 if (uri == null) { 8871 Slog.w(TAG, "revokeUriPermission: null uri"); 8872 return; 8873 } 8874 8875 if (!Intent.isAccessUriMode(modeFlags)) { 8876 return; 8877 } 8878 8879 final String authority = uri.getAuthority(); 8880 final ProviderInfo pi = getProviderInfoLocked(authority, userId, 8881 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE); 8882 if (pi == null) { 8883 Slog.w(TAG, "No content provider found for permission revoke: " 8884 + uri.toSafeString()); 8885 return; 8886 } 8887 8888 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 8889 } 8890 } 8891 8892 /** 8893 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 8894 * given package. 8895 * 8896 * @param packageName Package name to match, or {@code null} to apply to all 8897 * packages. 8898 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 8899 * to all users. 8900 * @param persistable If persistable grants should be removed. 8901 */ 8902 private void removeUriPermissionsForPackageLocked( 8903 String packageName, int userHandle, boolean persistable) { 8904 if (userHandle == UserHandle.USER_ALL && packageName == null) { 8905 throw new IllegalArgumentException("Must narrow by either package or user"); 8906 } 8907 8908 boolean persistChanged = false; 8909 8910 int N = mGrantedUriPermissions.size(); 8911 for (int i = 0; i < N; i++) { 8912 final int targetUid = mGrantedUriPermissions.keyAt(i); 8913 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 8914 8915 // Only inspect grants matching user 8916 if (userHandle == UserHandle.USER_ALL 8917 || userHandle == UserHandle.getUserId(targetUid)) { 8918 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 8919 final UriPermission perm = it.next(); 8920 8921 // Only inspect grants matching package 8922 if (packageName == null || perm.sourcePkg.equals(packageName) 8923 || perm.targetPkg.equals(packageName)) { 8924 // Hacky solution as part of fixing a security bug; ignore 8925 // grants associated with DownloadManager so we don't have 8926 // to immediately launch it to regrant the permissions 8927 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority()) 8928 && !persistable) continue; 8929 8930 persistChanged |= perm.revokeModes(persistable 8931 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true); 8932 8933 // Only remove when no modes remain; any persisted grants 8934 // will keep this alive. 8935 if (perm.modeFlags == 0) { 8936 it.remove(); 8937 } 8938 } 8939 } 8940 8941 if (perms.isEmpty()) { 8942 mGrantedUriPermissions.remove(targetUid); 8943 N--; 8944 i--; 8945 } 8946 } 8947 } 8948 8949 if (persistChanged) { 8950 schedulePersistUriGrants(); 8951 } 8952 } 8953 8954 @Override 8955 public IBinder newUriPermissionOwner(String name) { 8956 enforceNotIsolatedCaller("newUriPermissionOwner"); 8957 synchronized(this) { 8958 UriPermissionOwner owner = new UriPermissionOwner(this, name); 8959 return owner.getExternalTokenLocked(); 8960 } 8961 } 8962 8963 @Override 8964 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) { 8965 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity"); 8966 synchronized(this) { 8967 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8968 if (r == null) { 8969 throw new IllegalArgumentException("Activity does not exist; token=" 8970 + activityToken); 8971 } 8972 return r.getUriPermissionsLocked().getExternalTokenLocked(); 8973 } 8974 } 8975 /** 8976 * @param uri This uri must NOT contain an embedded userId. 8977 * @param sourceUserId The userId in which the uri is to be resolved. 8978 * @param targetUserId The userId of the app that receives the grant. 8979 */ 8980 @Override 8981 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 8982 final int modeFlags, int sourceUserId, int targetUserId) { 8983 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(), 8984 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY, 8985 "grantUriPermissionFromOwner", null); 8986 synchronized(this) { 8987 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 8988 if (owner == null) { 8989 throw new IllegalArgumentException("Unknown owner: " + token); 8990 } 8991 if (fromUid != Binder.getCallingUid()) { 8992 if (Binder.getCallingUid() != Process.myUid()) { 8993 // Only system code can grant URI permissions on behalf 8994 // of other users. 8995 throw new SecurityException("nice try"); 8996 } 8997 } 8998 if (targetPkg == null) { 8999 throw new IllegalArgumentException("null target"); 9000 } 9001 if (uri == null) { 9002 throw new IllegalArgumentException("null uri"); 9003 } 9004 9005 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 9006 modeFlags, owner, targetUserId); 9007 } 9008 } 9009 9010 /** 9011 * @param uri This uri must NOT contain an embedded userId. 9012 * @param userId The userId in which the uri is to be resolved. 9013 */ 9014 @Override 9015 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 9016 synchronized(this) { 9017 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 9018 if (owner == null) { 9019 throw new IllegalArgumentException("Unknown owner: " + token); 9020 } 9021 9022 if (uri == null) { 9023 owner.removeUriPermissionsLocked(mode); 9024 } else { 9025 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 9026 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode); 9027 } 9028 } 9029 } 9030 9031 private void schedulePersistUriGrants() { 9032 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 9033 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 9034 10 * DateUtils.SECOND_IN_MILLIS); 9035 } 9036 } 9037 9038 private void writeGrantedUriPermissions() { 9039 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()"); 9040 9041 // Snapshot permissions so we can persist without lock 9042 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 9043 synchronized (this) { 9044 final int size = mGrantedUriPermissions.size(); 9045 for (int i = 0; i < size; i++) { 9046 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9047 for (UriPermission perm : perms.values()) { 9048 if (perm.persistedModeFlags != 0) { 9049 persist.add(perm.snapshot()); 9050 } 9051 } 9052 } 9053 } 9054 9055 FileOutputStream fos = null; 9056 try { 9057 fos = mGrantFile.startWrite(); 9058 9059 XmlSerializer out = new FastXmlSerializer(); 9060 out.setOutput(fos, StandardCharsets.UTF_8.name()); 9061 out.startDocument(null, true); 9062 out.startTag(null, TAG_URI_GRANTS); 9063 for (UriPermission.Snapshot perm : persist) { 9064 out.startTag(null, TAG_URI_GRANT); 9065 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 9066 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 9067 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 9068 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 9069 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 9070 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 9071 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 9072 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 9073 out.endTag(null, TAG_URI_GRANT); 9074 } 9075 out.endTag(null, TAG_URI_GRANTS); 9076 out.endDocument(); 9077 9078 mGrantFile.finishWrite(fos); 9079 } catch (IOException e) { 9080 if (fos != null) { 9081 mGrantFile.failWrite(fos); 9082 } 9083 } 9084 } 9085 9086 private void readGrantedUriPermissionsLocked() { 9087 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()"); 9088 9089 final long now = System.currentTimeMillis(); 9090 9091 FileInputStream fis = null; 9092 try { 9093 fis = mGrantFile.openRead(); 9094 final XmlPullParser in = Xml.newPullParser(); 9095 in.setInput(fis, StandardCharsets.UTF_8.name()); 9096 9097 int type; 9098 while ((type = in.next()) != END_DOCUMENT) { 9099 final String tag = in.getName(); 9100 if (type == START_TAG) { 9101 if (TAG_URI_GRANT.equals(tag)) { 9102 final int sourceUserId; 9103 final int targetUserId; 9104 final int userHandle = readIntAttribute(in, 9105 ATTR_USER_HANDLE, UserHandle.USER_NULL); 9106 if (userHandle != UserHandle.USER_NULL) { 9107 // For backwards compatibility. 9108 sourceUserId = userHandle; 9109 targetUserId = userHandle; 9110 } else { 9111 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 9112 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 9113 } 9114 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 9115 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 9116 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 9117 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 9118 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 9119 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 9120 9121 // Sanity check that provider still belongs to source package 9122 // Both direct boot aware and unaware packages are fine as we 9123 // will do filtering at query time to avoid multiple parsing. 9124 final ProviderInfo pi = getProviderInfoLocked( 9125 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE 9126 | MATCH_DIRECT_BOOT_UNAWARE); 9127 if (pi != null && sourcePkg.equals(pi.packageName)) { 9128 int targetUid = -1; 9129 try { 9130 targetUid = AppGlobals.getPackageManager().getPackageUid( 9131 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId); 9132 } catch (RemoteException e) { 9133 } 9134 if (targetUid != -1) { 9135 final UriPermission perm = findOrCreateUriPermissionLocked( 9136 sourcePkg, targetPkg, targetUid, 9137 new GrantUri(sourceUserId, uri, prefix)); 9138 perm.initPersistedModes(modeFlags, createdTime); 9139 } 9140 } else { 9141 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 9142 + " but instead found " + pi); 9143 } 9144 } 9145 } 9146 } 9147 } catch (FileNotFoundException e) { 9148 // Missing grants is okay 9149 } catch (IOException e) { 9150 Slog.wtf(TAG, "Failed reading Uri grants", e); 9151 } catch (XmlPullParserException e) { 9152 Slog.wtf(TAG, "Failed reading Uri grants", e); 9153 } finally { 9154 IoUtils.closeQuietly(fis); 9155 } 9156 } 9157 9158 /** 9159 * @param uri This uri must NOT contain an embedded userId. 9160 * @param userId The userId in which the uri is to be resolved. 9161 */ 9162 @Override 9163 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 9164 enforceNotIsolatedCaller("takePersistableUriPermission"); 9165 9166 Preconditions.checkFlagsArgument(modeFlags, 9167 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 9168 9169 synchronized (this) { 9170 final int callingUid = Binder.getCallingUid(); 9171 boolean persistChanged = false; 9172 GrantUri grantUri = new GrantUri(userId, uri, false); 9173 9174 UriPermission exactPerm = findUriPermissionLocked(callingUid, 9175 new GrantUri(userId, uri, false)); 9176 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 9177 new GrantUri(userId, uri, true)); 9178 9179 final boolean exactValid = (exactPerm != null) 9180 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 9181 final boolean prefixValid = (prefixPerm != null) 9182 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 9183 9184 if (!(exactValid || prefixValid)) { 9185 throw new SecurityException("No persistable permission grants found for UID " 9186 + callingUid + " and Uri " + grantUri.toSafeString()); 9187 } 9188 9189 if (exactValid) { 9190 persistChanged |= exactPerm.takePersistableModes(modeFlags); 9191 } 9192 if (prefixValid) { 9193 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 9194 } 9195 9196 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 9197 9198 if (persistChanged) { 9199 schedulePersistUriGrants(); 9200 } 9201 } 9202 } 9203 9204 /** 9205 * @param uri This uri must NOT contain an embedded userId. 9206 * @param userId The userId in which the uri is to be resolved. 9207 */ 9208 @Override 9209 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 9210 enforceNotIsolatedCaller("releasePersistableUriPermission"); 9211 9212 Preconditions.checkFlagsArgument(modeFlags, 9213 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 9214 9215 synchronized (this) { 9216 final int callingUid = Binder.getCallingUid(); 9217 boolean persistChanged = false; 9218 9219 UriPermission exactPerm = findUriPermissionLocked(callingUid, 9220 new GrantUri(userId, uri, false)); 9221 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 9222 new GrantUri(userId, uri, true)); 9223 if (exactPerm == null && prefixPerm == null) { 9224 throw new SecurityException("No permission grants found for UID " + callingUid 9225 + " and Uri " + uri.toSafeString()); 9226 } 9227 9228 if (exactPerm != null) { 9229 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 9230 removeUriPermissionIfNeededLocked(exactPerm); 9231 } 9232 if (prefixPerm != null) { 9233 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 9234 removeUriPermissionIfNeededLocked(prefixPerm); 9235 } 9236 9237 if (persistChanged) { 9238 schedulePersistUriGrants(); 9239 } 9240 } 9241 } 9242 9243 /** 9244 * Prune any older {@link UriPermission} for the given UID until outstanding 9245 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 9246 * 9247 * @return if any mutations occured that require persisting. 9248 */ 9249 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 9250 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 9251 if (perms == null) return false; 9252 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 9253 9254 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 9255 for (UriPermission perm : perms.values()) { 9256 if (perm.persistedModeFlags != 0) { 9257 persisted.add(perm); 9258 } 9259 } 9260 9261 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 9262 if (trimCount <= 0) return false; 9263 9264 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 9265 for (int i = 0; i < trimCount; i++) { 9266 final UriPermission perm = persisted.get(i); 9267 9268 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, 9269 "Trimming grant created at " + perm.persistedCreateTime); 9270 9271 perm.releasePersistableModes(~0); 9272 removeUriPermissionIfNeededLocked(perm); 9273 } 9274 9275 return true; 9276 } 9277 9278 @Override 9279 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 9280 String packageName, boolean incoming) { 9281 enforceNotIsolatedCaller("getPersistedUriPermissions"); 9282 Preconditions.checkNotNull(packageName, "packageName"); 9283 9284 final int callingUid = Binder.getCallingUid(); 9285 final int callingUserId = UserHandle.getUserId(callingUid); 9286 final IPackageManager pm = AppGlobals.getPackageManager(); 9287 try { 9288 final int packageUid = pm.getPackageUid(packageName, 9289 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId); 9290 if (packageUid != callingUid) { 9291 throw new SecurityException( 9292 "Package " + packageName + " does not belong to calling UID " + callingUid); 9293 } 9294 } catch (RemoteException e) { 9295 throw new SecurityException("Failed to verify package name ownership"); 9296 } 9297 9298 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 9299 synchronized (this) { 9300 if (incoming) { 9301 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 9302 callingUid); 9303 if (perms == null) { 9304 Slog.w(TAG, "No permission grants found for " + packageName); 9305 } else { 9306 for (UriPermission perm : perms.values()) { 9307 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 9308 result.add(perm.buildPersistedPublicApiObject()); 9309 } 9310 } 9311 } 9312 } else { 9313 final int size = mGrantedUriPermissions.size(); 9314 for (int i = 0; i < size; i++) { 9315 final ArrayMap<GrantUri, UriPermission> perms = 9316 mGrantedUriPermissions.valueAt(i); 9317 for (UriPermission perm : perms.values()) { 9318 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 9319 result.add(perm.buildPersistedPublicApiObject()); 9320 } 9321 } 9322 } 9323 } 9324 } 9325 return new ParceledListSlice<android.content.UriPermission>(result); 9326 } 9327 9328 @Override 9329 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions( 9330 String packageName, int userId) { 9331 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS, 9332 "getGrantedUriPermissions"); 9333 9334 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 9335 synchronized (this) { 9336 final int size = mGrantedUriPermissions.size(); 9337 for (int i = 0; i < size; i++) { 9338 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 9339 for (UriPermission perm : perms.values()) { 9340 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId 9341 && perm.persistedModeFlags != 0) { 9342 result.add(perm.buildPersistedPublicApiObject()); 9343 } 9344 } 9345 } 9346 } 9347 return new ParceledListSlice<android.content.UriPermission>(result); 9348 } 9349 9350 @Override 9351 public void clearGrantedUriPermissions(String packageName, int userId) { 9352 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS, 9353 "clearGrantedUriPermissions"); 9354 removeUriPermissionsForPackageLocked(packageName, userId, true); 9355 } 9356 9357 @Override 9358 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 9359 synchronized (this) { 9360 ProcessRecord app = 9361 who != null ? getRecordForAppLocked(who) : null; 9362 if (app == null) return; 9363 9364 Message msg = Message.obtain(); 9365 msg.what = WAIT_FOR_DEBUGGER_UI_MSG; 9366 msg.obj = app; 9367 msg.arg1 = waiting ? 1 : 0; 9368 mUiHandler.sendMessage(msg); 9369 } 9370 } 9371 9372 @Override 9373 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 9374 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 9375 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 9376 outInfo.availMem = Process.getFreeMemory(); 9377 outInfo.totalMem = Process.getTotalMemory(); 9378 outInfo.threshold = homeAppMem; 9379 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 9380 outInfo.hiddenAppThreshold = cachedAppMem; 9381 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 9382 ProcessList.SERVICE_ADJ); 9383 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 9384 ProcessList.VISIBLE_APP_ADJ); 9385 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 9386 ProcessList.FOREGROUND_APP_ADJ); 9387 } 9388 9389 // ========================================================= 9390 // TASK MANAGEMENT 9391 // ========================================================= 9392 9393 @Override 9394 public List<IBinder> getAppTasks(String callingPackage) { 9395 int callingUid = Binder.getCallingUid(); 9396 long ident = Binder.clearCallingIdentity(); 9397 9398 synchronized(this) { 9399 ArrayList<IBinder> list = new ArrayList<IBinder>(); 9400 try { 9401 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks"); 9402 9403 final int N = mRecentTasks.size(); 9404 for (int i = 0; i < N; i++) { 9405 TaskRecord tr = mRecentTasks.get(i); 9406 // Skip tasks that do not match the caller. We don't need to verify 9407 // callingPackage, because we are also limiting to callingUid and know 9408 // that will limit to the correct security sandbox. 9409 if (tr.effectiveUid != callingUid) { 9410 continue; 9411 } 9412 Intent intent = tr.getBaseIntent(); 9413 if (intent == null || 9414 !callingPackage.equals(intent.getComponent().getPackageName())) { 9415 continue; 9416 } 9417 ActivityManager.RecentTaskInfo taskInfo = 9418 createRecentTaskInfoFromTaskRecord(tr); 9419 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 9420 list.add(taskImpl.asBinder()); 9421 } 9422 } finally { 9423 Binder.restoreCallingIdentity(ident); 9424 } 9425 return list; 9426 } 9427 } 9428 9429 @Override 9430 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 9431 final int callingUid = Binder.getCallingUid(); 9432 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 9433 9434 synchronized(this) { 9435 if (DEBUG_ALL) Slog.v( 9436 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 9437 9438 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), 9439 callingUid); 9440 9441 // TODO: Improve with MRU list from all ActivityStacks. 9442 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 9443 } 9444 9445 return list; 9446 } 9447 9448 /** 9449 * Creates a new RecentTaskInfo from a TaskRecord. 9450 */ 9451 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 9452 // Update the task description to reflect any changes in the task stack 9453 tr.updateTaskDescription(); 9454 9455 // Compose the recent task info 9456 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 9457 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId; 9458 rti.persistentId = tr.taskId; 9459 rti.baseIntent = new Intent(tr.getBaseIntent()); 9460 rti.origActivity = tr.origActivity; 9461 rti.realActivity = tr.realActivity; 9462 rti.description = tr.lastDescription; 9463 rti.stackId = tr.getStackId(); 9464 rti.userId = tr.userId; 9465 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 9466 rti.firstActiveTime = tr.firstActiveTime; 9467 rti.lastActiveTime = tr.lastActiveTime; 9468 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 9469 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 9470 rti.numActivities = 0; 9471 if (tr.mBounds != null) { 9472 rti.bounds = new Rect(tr.mBounds); 9473 } 9474 rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen(); 9475 rti.resizeMode = tr.mResizeMode; 9476 9477 ActivityRecord base = null; 9478 ActivityRecord top = null; 9479 ActivityRecord tmp; 9480 9481 for (int i = tr.mActivities.size() - 1; i >= 0; --i) { 9482 tmp = tr.mActivities.get(i); 9483 if (tmp.finishing) { 9484 continue; 9485 } 9486 base = tmp; 9487 if (top == null || (top.state == ActivityState.INITIALIZING)) { 9488 top = base; 9489 } 9490 rti.numActivities++; 9491 } 9492 9493 rti.baseActivity = (base != null) ? base.intent.getComponent() : null; 9494 rti.topActivity = (top != null) ? top.intent.getComponent() : null; 9495 9496 return rti; 9497 } 9498 9499 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { 9500 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, 9501 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; 9502 if (!allowed) { 9503 if (checkPermission(android.Manifest.permission.GET_TASKS, 9504 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { 9505 // Temporary compatibility: some existing apps on the system image may 9506 // still be requesting the old permission and not switched to the new 9507 // one; if so, we'll still allow them full access. This means we need 9508 // to see if they are holding the old permission and are a system app. 9509 try { 9510 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { 9511 allowed = true; 9512 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid 9513 + " is using old GET_TASKS but privileged; allowing"); 9514 } 9515 } catch (RemoteException e) { 9516 } 9517 } 9518 } 9519 if (!allowed) { 9520 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid 9521 + " does not hold REAL_GET_TASKS; limiting output"); 9522 } 9523 return allowed; 9524 } 9525 9526 @Override 9527 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, 9528 int userId) { 9529 final int callingUid = Binder.getCallingUid(); 9530 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 9531 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 9532 9533 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 9534 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 9535 synchronized (this) { 9536 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), 9537 callingUid); 9538 final boolean detailed = checkCallingPermission( 9539 android.Manifest.permission.GET_DETAILED_TASKS) 9540 == PackageManager.PERMISSION_GRANTED; 9541 9542 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) { 9543 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents"); 9544 return ParceledListSlice.emptyList(); 9545 } 9546 mRecentTasks.loadUserRecentsLocked(userId); 9547 9548 final int recentsCount = mRecentTasks.size(); 9549 ArrayList<ActivityManager.RecentTaskInfo> res = 9550 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount); 9551 9552 final Set<Integer> includedUsers; 9553 if (includeProfiles) { 9554 includedUsers = mUserController.getProfileIds(userId); 9555 } else { 9556 includedUsers = new HashSet<>(); 9557 } 9558 includedUsers.add(Integer.valueOf(userId)); 9559 9560 for (int i = 0; i < recentsCount && maxNum > 0; i++) { 9561 TaskRecord tr = mRecentTasks.get(i); 9562 // Only add calling user or related users recent tasks 9563 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 9564 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr); 9565 continue; 9566 } 9567 9568 if (tr.realActivitySuspended) { 9569 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr); 9570 continue; 9571 } 9572 9573 // Return the entry if desired by the caller. We always return 9574 // the first entry, because callers always expect this to be the 9575 // foreground app. We may filter others if the caller has 9576 // not supplied RECENT_WITH_EXCLUDED and there is some reason 9577 // we should exclude the entry. 9578 9579 if (i == 0 9580 || withExcluded 9581 || (tr.intent == null) 9582 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 9583 == 0)) { 9584 if (!allowed) { 9585 // If the caller doesn't have the GET_TASKS permission, then only 9586 // allow them to see a small subset of tasks -- their own and home. 9587 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 9588 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr); 9589 continue; 9590 } 9591 } 9592 final ActivityStack stack = tr.getStack(); 9593 if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) { 9594 if (stack != null && stack.isHomeOrRecentsStack()) { 9595 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9596 "Skipping, home or recents stack task: " + tr); 9597 continue; 9598 } 9599 } 9600 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) { 9601 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) { 9602 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9603 "Skipping, top task in docked stack: " + tr); 9604 continue; 9605 } 9606 } 9607 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) { 9608 if (stack != null && stack.isPinnedStack()) { 9609 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9610 "Skipping, pinned stack task: " + tr); 9611 continue; 9612 } 9613 } 9614 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 9615 // Don't include auto remove tasks that are finished or finishing. 9616 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9617 "Skipping, auto-remove without activity: " + tr); 9618 continue; 9619 } 9620 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 9621 && !tr.isAvailable) { 9622 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9623 "Skipping, unavail real act: " + tr); 9624 continue; 9625 } 9626 9627 if (!tr.mUserSetupComplete) { 9628 // Don't include task launched while user is not done setting-up. 9629 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, 9630 "Skipping, user setup not complete: " + tr); 9631 continue; 9632 } 9633 9634 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 9635 if (!detailed) { 9636 rti.baseIntent.replaceExtras((Bundle)null); 9637 } 9638 9639 res.add(rti); 9640 maxNum--; 9641 } 9642 } 9643 return new ParceledListSlice<>(res); 9644 } 9645 } 9646 9647 @Override 9648 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 9649 synchronized (this) { 9650 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 9651 "getTaskThumbnail()"); 9652 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked( 9653 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID); 9654 if (tr != null) { 9655 return tr.getTaskThumbnailLocked(); 9656 } 9657 } 9658 return null; 9659 } 9660 9661 @Override 9662 public ActivityManager.TaskDescription getTaskDescription(int id) { 9663 synchronized (this) { 9664 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 9665 "getTaskDescription()"); 9666 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked( 9667 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID); 9668 if (tr != null) { 9669 return tr.lastTaskDescription; 9670 } 9671 } 9672 return null; 9673 } 9674 9675 @Override 9676 public int addAppTask(IBinder activityToken, Intent intent, 9677 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 9678 final int callingUid = Binder.getCallingUid(); 9679 final long callingIdent = Binder.clearCallingIdentity(); 9680 9681 try { 9682 synchronized (this) { 9683 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 9684 if (r == null) { 9685 throw new IllegalArgumentException("Activity does not exist; token=" 9686 + activityToken); 9687 } 9688 ComponentName comp = intent.getComponent(); 9689 if (comp == null) { 9690 throw new IllegalArgumentException("Intent " + intent 9691 + " must specify explicit component"); 9692 } 9693 if (thumbnail.getWidth() != mThumbnailWidth 9694 || thumbnail.getHeight() != mThumbnailHeight) { 9695 throw new IllegalArgumentException("Bad thumbnail size: got " 9696 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 9697 + mThumbnailWidth + "x" + mThumbnailHeight); 9698 } 9699 if (intent.getSelector() != null) { 9700 intent.setSelector(null); 9701 } 9702 if (intent.getSourceBounds() != null) { 9703 intent.setSourceBounds(null); 9704 } 9705 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 9706 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 9707 // The caller has added this as an auto-remove task... that makes no 9708 // sense, so turn off auto-remove. 9709 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 9710 } 9711 } 9712 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 9713 mLastAddedTaskActivity = null; 9714 } 9715 ActivityInfo ainfo = mLastAddedTaskActivity; 9716 if (ainfo == null) { 9717 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 9718 comp, 0, UserHandle.getUserId(callingUid)); 9719 if (ainfo.applicationInfo.uid != callingUid) { 9720 throw new SecurityException( 9721 "Can't add task for another application: target uid=" 9722 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 9723 } 9724 } 9725 9726 TaskRecord task = new TaskRecord(this, 9727 mStackSupervisor.getNextTaskIdForUserLocked(r.userId), 9728 ainfo, intent, description, new TaskThumbnailInfo()); 9729 9730 int trimIdx = mRecentTasks.trimForTaskLocked(task, false); 9731 if (trimIdx >= 0) { 9732 // If this would have caused a trim, then we'll abort because that 9733 // means it would be added at the end of the list but then just removed. 9734 return INVALID_TASK_ID; 9735 } 9736 9737 final int N = mRecentTasks.size(); 9738 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 9739 final TaskRecord tr = mRecentTasks.remove(N - 1); 9740 tr.removedFromRecents(); 9741 } 9742 9743 task.inRecents = true; 9744 mRecentTasks.add(task); 9745 r.getStack().addTask(task, false, "addAppTask"); 9746 9747 task.setLastThumbnailLocked(thumbnail); 9748 task.freeLastThumbnail(); 9749 return task.taskId; 9750 } 9751 } finally { 9752 Binder.restoreCallingIdentity(callingIdent); 9753 } 9754 } 9755 9756 @Override 9757 public Point getAppTaskThumbnailSize() { 9758 synchronized (this) { 9759 return new Point(mThumbnailWidth, mThumbnailHeight); 9760 } 9761 } 9762 9763 @Override 9764 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 9765 synchronized (this) { 9766 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9767 if (r != null) { 9768 r.setTaskDescription(td); 9769 r.task.updateTaskDescription(); 9770 mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td); 9771 } 9772 } 9773 } 9774 9775 @Override 9776 public void setTaskResizeable(int taskId, int resizeableMode) { 9777 synchronized (this) { 9778 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked( 9779 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID); 9780 if (task == null) { 9781 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found"); 9782 return; 9783 } 9784 task.setResizeMode(resizeableMode); 9785 } 9786 } 9787 9788 @Override 9789 public void resizeTask(int taskId, Rect bounds, int resizeMode) { 9790 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()"); 9791 long ident = Binder.clearCallingIdentity(); 9792 try { 9793 synchronized (this) { 9794 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 9795 if (task == null) { 9796 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found"); 9797 return; 9798 } 9799 // Place the task in the right stack if it isn't there already based on 9800 // the requested bounds. 9801 // The stack transition logic is: 9802 // - a null bounds on a freeform task moves that task to fullscreen 9803 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves 9804 // that task to freeform 9805 // - otherwise the task is not moved 9806 int stackId = task.getStackId(); 9807 if (!StackId.isTaskResizeAllowed(stackId)) { 9808 throw new IllegalArgumentException("resizeTask not allowed on task=" + task); 9809 } 9810 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) { 9811 stackId = FULLSCREEN_WORKSPACE_STACK_ID; 9812 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) { 9813 stackId = FREEFORM_WORKSPACE_STACK_ID; 9814 } 9815 9816 // Reparent the task to the right stack if necessary 9817 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0; 9818 if (stackId != task.getStackId()) { 9819 // Defer resume until the task is resized below 9820 task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, 9821 DEFER_RESUME, "resizeTask"); 9822 preserveWindow = false; 9823 } 9824 9825 // After reparenting (which only resizes the task to the stack bounds), resize the 9826 // task to the actual bounds provided 9827 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME); 9828 } 9829 } finally { 9830 Binder.restoreCallingIdentity(ident); 9831 } 9832 } 9833 9834 @Override 9835 public Rect getTaskBounds(int taskId) { 9836 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()"); 9837 long ident = Binder.clearCallingIdentity(); 9838 Rect rect = new Rect(); 9839 try { 9840 synchronized (this) { 9841 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked( 9842 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID); 9843 if (task == null) { 9844 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found"); 9845 return rect; 9846 } 9847 if (task.getStack() != null) { 9848 // Return the bounds from window manager since it will be adjusted for various 9849 // things like the presense of a docked stack for tasks that aren't resizeable. 9850 task.getWindowContainerBounds(rect); 9851 } else { 9852 // Task isn't in window manager yet since it isn't associated with a stack. 9853 // Return the persist value from activity manager 9854 if (task.mBounds != null) { 9855 rect.set(task.mBounds); 9856 } else if (task.mLastNonFullscreenBounds != null) { 9857 rect.set(task.mLastNonFullscreenBounds); 9858 } 9859 } 9860 } 9861 } finally { 9862 Binder.restoreCallingIdentity(ident); 9863 } 9864 return rect; 9865 } 9866 9867 @Override 9868 public void cancelTaskWindowTransition(int taskId) { 9869 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()"); 9870 final long ident = Binder.clearCallingIdentity(); 9871 try { 9872 synchronized (this) { 9873 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked( 9874 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID); 9875 if (task == null) { 9876 Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found"); 9877 return; 9878 } 9879 task.cancelWindowTransition(); 9880 } 9881 } finally { 9882 Binder.restoreCallingIdentity(ident); 9883 } 9884 } 9885 9886 @Override 9887 public void cancelTaskThumbnailTransition(int taskId) { 9888 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()"); 9889 final long ident = Binder.clearCallingIdentity(); 9890 try { 9891 synchronized (this) { 9892 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked( 9893 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID); 9894 if (task == null) { 9895 Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found"); 9896 return; 9897 } 9898 task.cancelThumbnailTransition(); 9899 } 9900 } finally { 9901 Binder.restoreCallingIdentity(ident); 9902 } 9903 } 9904 9905 @Override 9906 public TaskSnapshot getTaskSnapshot(int taskId) { 9907 enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()"); 9908 final long ident = Binder.clearCallingIdentity(); 9909 try { 9910 final TaskRecord task; 9911 synchronized (this) { 9912 task = mStackSupervisor.anyTaskForIdLocked( 9913 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID); 9914 if (task == null) { 9915 Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found"); 9916 return null; 9917 } 9918 } 9919 // Don't call this while holding the lock as this operation might hit the disk. 9920 return task.getSnapshot(); 9921 } finally { 9922 Binder.restoreCallingIdentity(ident); 9923 } 9924 } 9925 9926 @Override 9927 public Bitmap getTaskDescriptionIcon(String filePath, int userId) { 9928 if (userId != UserHandle.getCallingUserId()) { 9929 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 9930 "getTaskDescriptionIcon"); 9931 } 9932 final File passedIconFile = new File(filePath); 9933 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId), 9934 passedIconFile.getName()); 9935 if (!legitIconFile.getPath().equals(filePath) 9936 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { 9937 throw new IllegalArgumentException("Bad file path: " + filePath 9938 + " passed for userId " + userId); 9939 } 9940 return mRecentTasks.getTaskDescriptionIcon(filePath); 9941 } 9942 9943 @Override 9944 public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) 9945 throws RemoteException { 9946 final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts); 9947 if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || 9948 activityOptions.getCustomInPlaceResId() == 0) { 9949 throw new IllegalArgumentException("Expected in-place ActivityOption " + 9950 "with valid animation"); 9951 } 9952 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false); 9953 mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(), 9954 activityOptions.getCustomInPlaceResId()); 9955 mWindowManager.executeAppTransition(); 9956 } 9957 9958 private void removeTasksByPackageNameLocked(String packageName, int userId) { 9959 // Remove all tasks with activities in the specified package from the list of recent tasks 9960 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 9961 TaskRecord tr = mRecentTasks.get(i); 9962 if (tr.userId != userId) continue; 9963 9964 ComponentName cn = tr.intent.getComponent(); 9965 if (cn != null && cn.getPackageName().equals(packageName)) { 9966 // If the package name matches, remove the task. 9967 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS); 9968 } 9969 } 9970 } 9971 9972 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses, 9973 int userId) { 9974 9975 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 9976 TaskRecord tr = mRecentTasks.get(i); 9977 if (userId != UserHandle.USER_ALL && tr.userId != userId) { 9978 continue; 9979 } 9980 9981 ComponentName cn = tr.intent.getComponent(); 9982 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName) 9983 && (filterByClasses == null || filterByClasses.contains(cn.getClassName())); 9984 if (sameComponent) { 9985 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS); 9986 } 9987 } 9988 } 9989 9990 @Override 9991 public void removeStack(int stackId) { 9992 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()"); 9993 if (StackId.isHomeOrRecentsStack(stackId)) { 9994 throw new IllegalArgumentException("Removing home or recents stack is not allowed."); 9995 } 9996 9997 synchronized (this) { 9998 final long ident = Binder.clearCallingIdentity(); 9999 try { 10000 mStackSupervisor.removeStackLocked(stackId); 10001 } finally { 10002 Binder.restoreCallingIdentity(ident); 10003 } 10004 } 10005 } 10006 10007 @Override 10008 public void moveStackToDisplay(int stackId, int displayId) { 10009 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()"); 10010 10011 synchronized (this) { 10012 final long ident = Binder.clearCallingIdentity(); 10013 try { 10014 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId 10015 + " to displayId=" + displayId); 10016 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP); 10017 } finally { 10018 Binder.restoreCallingIdentity(ident); 10019 } 10020 } 10021 } 10022 10023 @Override 10024 public boolean removeTask(int taskId) { 10025 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()"); 10026 synchronized (this) { 10027 final long ident = Binder.clearCallingIdentity(); 10028 try { 10029 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS); 10030 } finally { 10031 Binder.restoreCallingIdentity(ident); 10032 } 10033 } 10034 } 10035 10036 /** 10037 * TODO: Add mController hook 10038 */ 10039 @Override 10040 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) { 10041 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()"); 10042 10043 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId); 10044 synchronized(this) { 10045 moveTaskToFrontLocked(taskId, flags, bOptions); 10046 } 10047 } 10048 10049 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) { 10050 ActivityOptions options = ActivityOptions.fromBundle(bOptions); 10051 10052 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 10053 Binder.getCallingUid(), -1, -1, "Task to front")) { 10054 ActivityOptions.abort(options); 10055 return; 10056 } 10057 final long origId = Binder.clearCallingIdentity(); 10058 try { 10059 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10060 if (task == null) { 10061 Slog.d(TAG, "Could not find task for id: "+ taskId); 10062 return; 10063 } 10064 if (mStackSupervisor.isLockTaskModeViolation(task)) { 10065 mStackSupervisor.showLockTaskToast(); 10066 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 10067 return; 10068 } 10069 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 10070 if (prev != null) { 10071 task.setTaskToReturnTo(prev); 10072 } 10073 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront", 10074 false /* forceNonResizable */); 10075 10076 final ActivityRecord topActivity = task.getTopActivity(); 10077 if (topActivity != null) { 10078 10079 // We are reshowing a task, use a starting window to hide the initial draw delay 10080 // so the transition can start earlier. 10081 topActivity.showStartingWindow(null /* prev */, false /* newTask */, 10082 true /* taskSwitch */); 10083 } 10084 } finally { 10085 Binder.restoreCallingIdentity(origId); 10086 } 10087 ActivityOptions.abort(options); 10088 } 10089 10090 /** 10091 * Moves an activity, and all of the other activities within the same task, to the bottom 10092 * of the history stack. The activity's order within the task is unchanged. 10093 * 10094 * @param token A reference to the activity we wish to move 10095 * @param nonRoot If false then this only works if the activity is the root 10096 * of a task; if true it will work for any activity in a task. 10097 * @return Returns true if the move completed, false if not. 10098 */ 10099 @Override 10100 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 10101 enforceNotIsolatedCaller("moveActivityTaskToBack"); 10102 synchronized(this) { 10103 final long origId = Binder.clearCallingIdentity(); 10104 try { 10105 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 10106 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10107 if (task != null) { 10108 if (mStackSupervisor.isLockedTask(task)) { 10109 mStackSupervisor.showLockTaskToast(); 10110 return false; 10111 } 10112 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId); 10113 } 10114 } finally { 10115 Binder.restoreCallingIdentity(origId); 10116 } 10117 } 10118 return false; 10119 } 10120 10121 @Override 10122 public void moveTaskBackwards(int task) { 10123 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 10124 "moveTaskBackwards()"); 10125 10126 synchronized(this) { 10127 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 10128 Binder.getCallingUid(), -1, -1, "Task backwards")) { 10129 return; 10130 } 10131 final long origId = Binder.clearCallingIdentity(); 10132 moveTaskBackwardsLocked(task); 10133 Binder.restoreCallingIdentity(origId); 10134 } 10135 } 10136 10137 private final void moveTaskBackwardsLocked(int task) { 10138 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 10139 } 10140 10141 @Override 10142 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken, 10143 IActivityContainerCallback callback) throws RemoteException { 10144 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()"); 10145 synchronized (this) { 10146 if (parentActivityToken == null) { 10147 throw new IllegalArgumentException("parent token must not be null"); 10148 } 10149 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken); 10150 if (r == null) { 10151 return null; 10152 } 10153 if (callback == null) { 10154 throw new IllegalArgumentException("callback must not be null"); 10155 } 10156 return mStackSupervisor.createVirtualActivityContainer(r, callback); 10157 } 10158 } 10159 10160 @Override 10161 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException { 10162 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()"); 10163 synchronized (this) { 10164 final int stackId = mStackSupervisor.getNextStackId(); 10165 final ActivityStack stack = 10166 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/); 10167 if (stack == null) { 10168 return null; 10169 } 10170 return stack.mActivityContainer; 10171 } 10172 } 10173 10174 @Override 10175 public int getActivityDisplayId(IBinder activityToken) throws RemoteException { 10176 synchronized (this) { 10177 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 10178 if (stack != null && stack.mActivityContainer.isAttachedLocked()) { 10179 return stack.mActivityContainer.getDisplayId(); 10180 } 10181 return DEFAULT_DISPLAY; 10182 } 10183 } 10184 10185 @Override 10186 public int getActivityStackId(IBinder token) throws RemoteException { 10187 synchronized (this) { 10188 ActivityStack stack = ActivityRecord.getStackLocked(token); 10189 if (stack == null) { 10190 return INVALID_STACK_ID; 10191 } 10192 return stack.mStackId; 10193 } 10194 } 10195 10196 @Override 10197 public void exitFreeformMode(IBinder token) throws RemoteException { 10198 synchronized (this) { 10199 long ident = Binder.clearCallingIdentity(); 10200 try { 10201 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 10202 if (r == null) { 10203 throw new IllegalArgumentException( 10204 "exitFreeformMode: No activity record matching token=" + token); 10205 } 10206 10207 final ActivityStack stack = r.getStack(); 10208 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) { 10209 throw new IllegalStateException( 10210 "exitFreeformMode: You can only go fullscreen from freeform."); 10211 } 10212 10213 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r); 10214 r.task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, 10215 ANIMATE, !DEFER_RESUME, "exitFreeformMode"); 10216 } finally { 10217 Binder.restoreCallingIdentity(ident); 10218 } 10219 } 10220 } 10221 10222 @Override 10223 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 10224 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); 10225 if (StackId.isHomeOrRecentsStack(stackId)) { 10226 throw new IllegalArgumentException( 10227 "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId); 10228 } 10229 synchronized (this) { 10230 long ident = Binder.clearCallingIdentity(); 10231 try { 10232 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10233 if (task == null) { 10234 Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId); 10235 return; 10236 } 10237 10238 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId 10239 + " to stackId=" + stackId + " toTop=" + toTop); 10240 if (stackId == DOCKED_STACK_ID) { 10241 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, 10242 null /* initialBounds */); 10243 } 10244 10245 final boolean successful = task.reparent(stackId, toTop, 10246 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack"); 10247 if (successful && stackId == DOCKED_STACK_ID) { 10248 // If task moved to docked stack - show recents if needed. 10249 mWindowManager.showRecentApps(false /* fromHome */); 10250 } 10251 } finally { 10252 Binder.restoreCallingIdentity(ident); 10253 } 10254 } 10255 } 10256 10257 @Override 10258 public void swapDockedAndFullscreenStack() throws RemoteException { 10259 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()"); 10260 synchronized (this) { 10261 long ident = Binder.clearCallingIdentity(); 10262 try { 10263 final ActivityStack fullscreenStack = mStackSupervisor.getStack( 10264 FULLSCREEN_WORKSPACE_STACK_ID); 10265 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask() 10266 : null; 10267 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID); 10268 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks() 10269 : null; 10270 if (topTask == null || tasks == null || tasks.size() == 0) { 10271 Slog.w(TAG, 10272 "Unable to swap tasks, either docked or fullscreen stack is empty."); 10273 return; 10274 } 10275 10276 // TODO: App transition 10277 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false); 10278 10279 // Defer the resume until we move all the docked tasks to the fullscreen stack below 10280 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, 10281 DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK"); 10282 final int size = tasks.size(); 10283 for (int i = 0; i < size; i++) { 10284 final int id = tasks.get(i).taskId; 10285 if (id == topTask.taskId) { 10286 continue; 10287 } 10288 10289 // Defer the resume until after all the tasks have been moved 10290 tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, 10291 REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME, 10292 "swapDockedAndFullscreenStack - FULLSCREEN_STACK"); 10293 } 10294 10295 // Because we deferred the resume to avoid conflicts with stack switches while 10296 // resuming, we need to do it after all the tasks are moved. 10297 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 10298 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 10299 10300 mWindowManager.executeAppTransition(); 10301 } finally { 10302 Binder.restoreCallingIdentity(ident); 10303 } 10304 } 10305 } 10306 10307 /** 10308 * Moves the input task to the docked stack. 10309 * 10310 * @param taskId Id of task to move. 10311 * @param createMode The mode the docked stack should be created in if it doesn't exist 10312 * already. See 10313 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT} 10314 * and 10315 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT} 10316 * @param toTop If the task and stack should be moved to the top. 10317 * @param animate Whether we should play an animation for the moving the task 10318 * @param initialBounds If the docked stack gets created, it will use these bounds for the 10319 * docked stack. Pass {@code null} to use default bounds. 10320 */ 10321 @Override 10322 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate, 10323 Rect initialBounds, boolean moveHomeStackFront) { 10324 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()"); 10325 synchronized (this) { 10326 long ident = Binder.clearCallingIdentity(); 10327 try { 10328 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10329 if (task == null) { 10330 Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId); 10331 return false; 10332 } 10333 10334 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId 10335 + " to createMode=" + createMode + " toTop=" + toTop); 10336 mWindowManager.setDockedStackCreateState(createMode, initialBounds); 10337 10338 // Defer resuming until we move the home stack to the front below 10339 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop, 10340 REPARENT_KEEP_STACK_AT_FRONT, animate, DEFER_RESUME, 10341 "moveTaskToDockedStack"); 10342 if (moved) { 10343 if (moveHomeStackFront) { 10344 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack"); 10345 } 10346 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 10347 } 10348 return moved; 10349 } finally { 10350 Binder.restoreCallingIdentity(ident); 10351 } 10352 } 10353 } 10354 10355 /** 10356 * Moves the top activity in the input stackId to the pinned stack. 10357 * 10358 * @param stackId Id of stack to move the top activity to pinned stack. 10359 * @param bounds Bounds to use for pinned stack. 10360 * 10361 * @return True if the top activity of the input stack was successfully moved to the pinned 10362 * stack. 10363 */ 10364 @Override 10365 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) { 10366 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()"); 10367 synchronized (this) { 10368 if (!mSupportsPictureInPicture) { 10369 throw new IllegalStateException("moveTopActivityToPinnedStack:" 10370 + "Device doesn't support picture-in-pciture mode"); 10371 } 10372 10373 long ident = Binder.clearCallingIdentity(); 10374 try { 10375 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds); 10376 } finally { 10377 Binder.restoreCallingIdentity(ident); 10378 } 10379 } 10380 } 10381 10382 @Override 10383 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode, 10384 boolean preserveWindows, boolean animate, int animationDuration) { 10385 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); 10386 long ident = Binder.clearCallingIdentity(); 10387 try { 10388 synchronized (this) { 10389 if (animate) { 10390 if (stackId == PINNED_STACK_ID) { 10391 final PinnedActivityStack pinnedStack = 10392 mStackSupervisor.getStack(PINNED_STACK_ID); 10393 pinnedStack.animateResizePinnedStack(bounds, animationDuration); 10394 } else { 10395 throw new IllegalArgumentException("Stack: " + stackId 10396 + " doesn't support animated resize."); 10397 } 10398 } else { 10399 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */, 10400 null /* tempTaskInsetBounds */, preserveWindows, 10401 allowResizeInDockedMode, !DEFER_RESUME); 10402 } 10403 } 10404 } finally { 10405 Binder.restoreCallingIdentity(ident); 10406 } 10407 } 10408 10409 @Override 10410 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds, 10411 Rect tempDockedTaskInsetBounds, 10412 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) { 10413 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 10414 "resizeDockedStack()"); 10415 long ident = Binder.clearCallingIdentity(); 10416 try { 10417 synchronized (this) { 10418 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds, 10419 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds, 10420 PRESERVE_WINDOWS); 10421 } 10422 } finally { 10423 Binder.restoreCallingIdentity(ident); 10424 } 10425 } 10426 10427 @Override 10428 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) { 10429 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 10430 "resizePinnedStack()"); 10431 final long ident = Binder.clearCallingIdentity(); 10432 try { 10433 synchronized (this) { 10434 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds); 10435 } 10436 } finally { 10437 Binder.restoreCallingIdentity(ident); 10438 } 10439 } 10440 10441 /** 10442 * Try to place task to provided position. The final position might be different depending on 10443 * current user and stacks state. The task will be moved to target stack if it's currently in 10444 * different stack. 10445 */ 10446 @Override 10447 public void positionTaskInStack(int taskId, int stackId, int position) { 10448 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()"); 10449 if (StackId.isHomeOrRecentsStack(stackId)) { 10450 throw new IllegalArgumentException( 10451 "positionTaskInStack: Attempt to change the position of task " 10452 + taskId + " in/to home/recents stack"); 10453 } 10454 synchronized (this) { 10455 long ident = Binder.clearCallingIdentity(); 10456 try { 10457 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task=" 10458 + taskId + " in stackId=" + stackId + " at position=" + position); 10459 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10460 if (task == null) { 10461 throw new IllegalArgumentException("positionTaskInStack: no task for id=" 10462 + taskId); 10463 } 10464 10465 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED, 10466 !ON_TOP); 10467 10468 // TODO: Have the callers of this API call a separate reparent method if that is 10469 // what they intended to do vs. having this method also do reparenting. 10470 if (task.getStack() == stack) { 10471 // Change position in current stack. 10472 stack.positionChildAt(task, position); 10473 } else { 10474 // Reparent to new stack. 10475 task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE, 10476 !ANIMATE, !DEFER_RESUME, "positionTaskInStack"); 10477 } 10478 } finally { 10479 Binder.restoreCallingIdentity(ident); 10480 } 10481 } 10482 } 10483 10484 @Override 10485 public List<StackInfo> getAllStackInfos() { 10486 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()"); 10487 long ident = Binder.clearCallingIdentity(); 10488 try { 10489 synchronized (this) { 10490 return mStackSupervisor.getAllStackInfosLocked(); 10491 } 10492 } finally { 10493 Binder.restoreCallingIdentity(ident); 10494 } 10495 } 10496 10497 @Override 10498 public StackInfo getStackInfo(int stackId) { 10499 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); 10500 long ident = Binder.clearCallingIdentity(); 10501 try { 10502 synchronized (this) { 10503 return mStackSupervisor.getStackInfoLocked(stackId); 10504 } 10505 } finally { 10506 Binder.restoreCallingIdentity(ident); 10507 } 10508 } 10509 10510 @Override 10511 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 10512 synchronized(this) { 10513 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 10514 } 10515 } 10516 10517 @Override 10518 public void updateDeviceOwner(String packageName) { 10519 final int callingUid = Binder.getCallingUid(); 10520 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10521 throw new SecurityException("updateDeviceOwner called from non-system process"); 10522 } 10523 synchronized (this) { 10524 mDeviceOwnerName = packageName; 10525 } 10526 } 10527 10528 @Override 10529 public void updateLockTaskPackages(int userId, String[] packages) { 10530 final int callingUid = Binder.getCallingUid(); 10531 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 10532 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES, 10533 "updateLockTaskPackages()"); 10534 } 10535 synchronized (this) { 10536 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + 10537 Arrays.toString(packages)); 10538 mLockTaskPackages.put(userId, packages); 10539 mStackSupervisor.onLockTaskPackagesUpdatedLocked(); 10540 } 10541 } 10542 10543 10544 void startLockTaskModeLocked(TaskRecord task) { 10545 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task); 10546 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { 10547 return; 10548 } 10549 10550 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode 10551 // is initiated by system after the pinning request was shown and locked mode is initiated 10552 // by an authorized app directly 10553 final int callingUid = Binder.getCallingUid(); 10554 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID; 10555 long ident = Binder.clearCallingIdentity(); 10556 try { 10557 if (!isSystemInitiated) { 10558 task.mLockTaskUid = callingUid; 10559 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) { 10560 // startLockTask() called by app and task mode is lockTaskModeDefault. 10561 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user"); 10562 StatusBarManagerInternal statusBarManager = 10563 LocalServices.getService(StatusBarManagerInternal.class); 10564 if (statusBarManager != null) { 10565 statusBarManager.showScreenPinningRequest(task.taskId); 10566 } 10567 return; 10568 } 10569 10570 final ActivityStack stack = mStackSupervisor.getFocusedStack(); 10571 if (stack == null || task != stack.topTask()) { 10572 throw new IllegalArgumentException("Invalid task, not in foreground"); 10573 } 10574 } 10575 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" : 10576 "Locking fully"); 10577 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ? 10578 ActivityManager.LOCK_TASK_MODE_PINNED : 10579 ActivityManager.LOCK_TASK_MODE_LOCKED, 10580 "startLockTask", true); 10581 } finally { 10582 Binder.restoreCallingIdentity(ident); 10583 } 10584 } 10585 10586 @Override 10587 public void startLockTaskModeById(int taskId) { 10588 synchronized (this) { 10589 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 10590 if (task != null) { 10591 startLockTaskModeLocked(task); 10592 } 10593 } 10594 } 10595 10596 @Override 10597 public void startLockTaskModeByToken(IBinder token) { 10598 synchronized (this) { 10599 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 10600 if (r == null) { 10601 return; 10602 } 10603 final TaskRecord task = r.task; 10604 if (task != null) { 10605 startLockTaskModeLocked(task); 10606 } 10607 } 10608 } 10609 10610 @Override 10611 public void startSystemLockTaskMode(int taskId) throws RemoteException { 10612 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode"); 10613 // This makes inner call to look as if it was initiated by system. 10614 long ident = Binder.clearCallingIdentity(); 10615 try { 10616 synchronized (this) { 10617 startLockTaskModeById(taskId); 10618 } 10619 } finally { 10620 Binder.restoreCallingIdentity(ident); 10621 } 10622 } 10623 10624 @Override 10625 public void stopLockTaskMode() { 10626 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked(); 10627 if (lockTask == null) { 10628 // Our work here is done. 10629 return; 10630 } 10631 10632 final int callingUid = Binder.getCallingUid(); 10633 final int lockTaskUid = lockTask.mLockTaskUid; 10634 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState(); 10635 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) { 10636 // Done. 10637 return; 10638 } else { 10639 // Ensure the same caller for startLockTaskMode and stopLockTaskMode. 10640 // It is possible lockTaskMode was started by the system process because 10641 // android:lockTaskMode is set to a locking value in the application manifest 10642 // instead of the app calling startLockTaskMode. In this case 10643 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the 10644 // {@link TaskRecord.effectiveUid} instead. Also caller with 10645 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task. 10646 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED 10647 && callingUid != lockTaskUid 10648 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) { 10649 throw new SecurityException("Invalid uid, expected " + lockTaskUid 10650 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid); 10651 } 10652 } 10653 long ident = Binder.clearCallingIdentity(); 10654 try { 10655 Log.d(TAG, "stopLockTaskMode"); 10656 // Stop lock task 10657 synchronized (this) { 10658 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE, 10659 "stopLockTask", true); 10660 } 10661 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE); 10662 if (tm != null) { 10663 tm.showInCallScreen(false); 10664 } 10665 } finally { 10666 Binder.restoreCallingIdentity(ident); 10667 } 10668 } 10669 10670 /** 10671 * This API should be called by SystemUI only when user perform certain action to dismiss 10672 * lock task mode. We should only dismiss pinned lock task mode in this case. 10673 */ 10674 @Override 10675 public void stopSystemLockTaskMode() throws RemoteException { 10676 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) { 10677 stopLockTaskMode(); 10678 } else { 10679 mStackSupervisor.showLockTaskToast(); 10680 } 10681 } 10682 10683 @Override 10684 public boolean isInLockTaskMode() { 10685 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE; 10686 } 10687 10688 @Override 10689 public int getLockTaskModeState() { 10690 synchronized (this) { 10691 return mStackSupervisor.getLockTaskModeState(); 10692 } 10693 } 10694 10695 @Override 10696 public void showLockTaskEscapeMessage(IBinder token) { 10697 synchronized (this) { 10698 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 10699 if (r == null) { 10700 return; 10701 } 10702 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task); 10703 } 10704 } 10705 10706 // ========================================================= 10707 // CONTENT PROVIDERS 10708 // ========================================================= 10709 10710 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 10711 List<ProviderInfo> providers = null; 10712 try { 10713 providers = AppGlobals.getPackageManager() 10714 .queryContentProviders(app.processName, app.uid, 10715 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS 10716 | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null) 10717 .getList(); 10718 } catch (RemoteException ex) { 10719 } 10720 if (DEBUG_MU) Slog.v(TAG_MU, 10721 "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 10722 int userId = app.userId; 10723 if (providers != null) { 10724 int N = providers.size(); 10725 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 10726 for (int i=0; i<N; i++) { 10727 // TODO: keep logic in sync with installEncryptionUnawareProviders 10728 ProviderInfo cpi = 10729 (ProviderInfo)providers.get(i); 10730 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 10731 cpi.name, cpi.flags); 10732 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) { 10733 // This is a singleton provider, but a user besides the 10734 // default user is asking to initialize a process it runs 10735 // in... well, no, it doesn't actually run in this process, 10736 // it runs in the process of the default user. Get rid of it. 10737 providers.remove(i); 10738 N--; 10739 i--; 10740 continue; 10741 } 10742 10743 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 10744 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 10745 if (cpr == null) { 10746 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 10747 mProviderMap.putProviderByClass(comp, cpr); 10748 } 10749 if (DEBUG_MU) Slog.v(TAG_MU, 10750 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 10751 app.pubProviders.put(cpi.name, cpr); 10752 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 10753 // Don't add this if it is a platform component that is marked 10754 // to run in multiple processes, because this is actually 10755 // part of the framework so doesn't make sense to track as a 10756 // separate apk in the process. 10757 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 10758 mProcessStats); 10759 } 10760 notifyPackageUse(cpi.applicationInfo.packageName, 10761 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER); 10762 } 10763 } 10764 return providers; 10765 } 10766 10767 /** 10768 * Check if the calling UID has a possible chance at accessing the provider 10769 * at the given authority and user. 10770 */ 10771 public String checkContentProviderAccess(String authority, int userId) { 10772 if (userId == UserHandle.USER_ALL) { 10773 mContext.enforceCallingOrSelfPermission( 10774 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG); 10775 userId = UserHandle.getCallingUserId(); 10776 } 10777 10778 ProviderInfo cpi = null; 10779 try { 10780 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority, 10781 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS 10782 | PackageManager.MATCH_DISABLED_COMPONENTS 10783 | PackageManager.MATCH_DIRECT_BOOT_AWARE 10784 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 10785 userId); 10786 } catch (RemoteException ignored) { 10787 } 10788 if (cpi == null) { 10789 return "Failed to find provider " + authority + " for user " + userId; 10790 } 10791 10792 ProcessRecord r = null; 10793 synchronized (mPidsSelfLocked) { 10794 r = mPidsSelfLocked.get(Binder.getCallingPid()); 10795 } 10796 if (r == null) { 10797 return "Failed to find PID " + Binder.getCallingPid(); 10798 } 10799 10800 synchronized (this) { 10801 return checkContentProviderPermissionLocked(cpi, r, userId, true); 10802 } 10803 } 10804 10805 /** 10806 * Check if {@link ProcessRecord} has a possible chance at accessing the 10807 * given {@link ProviderInfo}. Final permission checking is always done 10808 * in {@link ContentProvider}. 10809 */ 10810 private final String checkContentProviderPermissionLocked( 10811 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 10812 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 10813 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 10814 boolean checkedGrants = false; 10815 if (checkUser) { 10816 // Looking for cross-user grants before enforcing the typical cross-users permissions 10817 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId); 10818 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 10819 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 10820 return null; 10821 } 10822 checkedGrants = true; 10823 } 10824 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false, 10825 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null); 10826 if (userId != tmpTargetUserId) { 10827 // When we actually went to determine the final targer user ID, this ended 10828 // up different than our initial check for the authority. This is because 10829 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 10830 // SELF. So we need to re-check the grants again. 10831 checkedGrants = false; 10832 } 10833 } 10834 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 10835 cpi.applicationInfo.uid, cpi.exported) 10836 == PackageManager.PERMISSION_GRANTED) { 10837 return null; 10838 } 10839 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 10840 cpi.applicationInfo.uid, cpi.exported) 10841 == PackageManager.PERMISSION_GRANTED) { 10842 return null; 10843 } 10844 10845 PathPermission[] pps = cpi.pathPermissions; 10846 if (pps != null) { 10847 int i = pps.length; 10848 while (i > 0) { 10849 i--; 10850 PathPermission pp = pps[i]; 10851 String pprperm = pp.getReadPermission(); 10852 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 10853 cpi.applicationInfo.uid, cpi.exported) 10854 == PackageManager.PERMISSION_GRANTED) { 10855 return null; 10856 } 10857 String ppwperm = pp.getWritePermission(); 10858 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 10859 cpi.applicationInfo.uid, cpi.exported) 10860 == PackageManager.PERMISSION_GRANTED) { 10861 return null; 10862 } 10863 } 10864 } 10865 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 10866 return null; 10867 } 10868 10869 String msg; 10870 if (!cpi.exported) { 10871 msg = "Permission Denial: opening provider " + cpi.name 10872 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 10873 + ", uid=" + callingUid + ") that is not exported from uid " 10874 + cpi.applicationInfo.uid; 10875 } else { 10876 msg = "Permission Denial: opening provider " + cpi.name 10877 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 10878 + ", uid=" + callingUid + ") requires " 10879 + cpi.readPermission + " or " + cpi.writePermission; 10880 } 10881 Slog.w(TAG, msg); 10882 return msg; 10883 } 10884 10885 /** 10886 * Returns if the ContentProvider has granted a uri to callingUid 10887 */ 10888 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 10889 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 10890 if (perms != null) { 10891 for (int i=perms.size()-1; i>=0; i--) { 10892 GrantUri grantUri = perms.keyAt(i); 10893 if (grantUri.sourceUserId == userId || !checkUser) { 10894 if (matchesProvider(grantUri.uri, cpi)) { 10895 return true; 10896 } 10897 } 10898 } 10899 } 10900 return false; 10901 } 10902 10903 /** 10904 * Returns true if the uri authority is one of the authorities specified in the provider. 10905 */ 10906 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 10907 String uriAuth = uri.getAuthority(); 10908 String cpiAuth = cpi.authority; 10909 if (cpiAuth.indexOf(';') == -1) { 10910 return cpiAuth.equals(uriAuth); 10911 } 10912 String[] cpiAuths = cpiAuth.split(";"); 10913 int length = cpiAuths.length; 10914 for (int i = 0; i < length; i++) { 10915 if (cpiAuths[i].equals(uriAuth)) return true; 10916 } 10917 return false; 10918 } 10919 10920 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 10921 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 10922 if (r != null) { 10923 for (int i=0; i<r.conProviders.size(); i++) { 10924 ContentProviderConnection conn = r.conProviders.get(i); 10925 if (conn.provider == cpr) { 10926 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER, 10927 "Adding provider requested by " 10928 + r.processName + " from process " 10929 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 10930 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 10931 if (stable) { 10932 conn.stableCount++; 10933 conn.numStableIncs++; 10934 } else { 10935 conn.unstableCount++; 10936 conn.numUnstableIncs++; 10937 } 10938 return conn; 10939 } 10940 } 10941 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 10942 if (stable) { 10943 conn.stableCount = 1; 10944 conn.numStableIncs = 1; 10945 } else { 10946 conn.unstableCount = 1; 10947 conn.numUnstableIncs = 1; 10948 } 10949 cpr.connections.add(conn); 10950 r.conProviders.add(conn); 10951 startAssociationLocked(r.uid, r.processName, r.curProcState, 10952 cpr.uid, cpr.name, cpr.info.processName); 10953 return conn; 10954 } 10955 cpr.addExternalProcessHandleLocked(externalProcessToken); 10956 return null; 10957 } 10958 10959 boolean decProviderCountLocked(ContentProviderConnection conn, 10960 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 10961 if (conn != null) { 10962 cpr = conn.provider; 10963 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER, 10964 "Removing provider requested by " 10965 + conn.client.processName + " from process " 10966 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 10967 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 10968 if (stable) { 10969 conn.stableCount--; 10970 } else { 10971 conn.unstableCount--; 10972 } 10973 if (conn.stableCount == 0 && conn.unstableCount == 0) { 10974 cpr.connections.remove(conn); 10975 conn.client.conProviders.remove(conn); 10976 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 10977 // The client is more important than last activity -- note the time this 10978 // is happening, so we keep the old provider process around a bit as last 10979 // activity to avoid thrashing it. 10980 if (cpr.proc != null) { 10981 cpr.proc.lastProviderTime = SystemClock.uptimeMillis(); 10982 } 10983 } 10984 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name); 10985 return true; 10986 } 10987 return false; 10988 } 10989 cpr.removeExternalProcessHandleLocked(externalProcessToken); 10990 return false; 10991 } 10992 10993 private void checkTime(long startTime, String where) { 10994 long now = SystemClock.uptimeMillis(); 10995 if ((now-startTime) > 50) { 10996 // If we are taking more than 50ms, log about it. 10997 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 10998 } 10999 } 11000 11001 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] { 11002 PROC_SPACE_TERM, 11003 PROC_SPACE_TERM|PROC_PARENS, 11004 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state 11005 }; 11006 11007 private final long[] mProcessStateStatsLongs = new long[1]; 11008 11009 boolean isProcessAliveLocked(ProcessRecord proc) { 11010 if (proc.procStatFile == null) { 11011 proc.procStatFile = "/proc/" + proc.pid + "/stat"; 11012 } 11013 mProcessStateStatsLongs[0] = 0; 11014 if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null, 11015 mProcessStateStatsLongs, null)) { 11016 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile); 11017 return false; 11018 } 11019 final long state = mProcessStateStatsLongs[0]; 11020 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": " 11021 + (char)state); 11022 return state != 'Z' && state != 'X' && state != 'x' && state != 'K'; 11023 } 11024 11025 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 11026 String name, IBinder token, boolean stable, int userId) { 11027 ContentProviderRecord cpr; 11028 ContentProviderConnection conn = null; 11029 ProviderInfo cpi = null; 11030 11031 synchronized(this) { 11032 long startTime = SystemClock.uptimeMillis(); 11033 11034 ProcessRecord r = null; 11035 if (caller != null) { 11036 r = getRecordForAppLocked(caller); 11037 if (r == null) { 11038 throw new SecurityException( 11039 "Unable to find app for caller " + caller 11040 + " (pid=" + Binder.getCallingPid() 11041 + ") when getting content provider " + name); 11042 } 11043 } 11044 11045 boolean checkCrossUser = true; 11046 11047 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 11048 11049 // First check if this content provider has been published... 11050 cpr = mProviderMap.getProviderByName(name, userId); 11051 // If that didn't work, check if it exists for user 0 and then 11052 // verify that it's a singleton provider before using it. 11053 if (cpr == null && userId != UserHandle.USER_SYSTEM) { 11054 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM); 11055 if (cpr != null) { 11056 cpi = cpr.info; 11057 if (isSingleton(cpi.processName, cpi.applicationInfo, 11058 cpi.name, cpi.flags) 11059 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 11060 userId = UserHandle.USER_SYSTEM; 11061 checkCrossUser = false; 11062 } else { 11063 cpr = null; 11064 cpi = null; 11065 } 11066 } 11067 } 11068 11069 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed; 11070 if (providerRunning) { 11071 cpi = cpr.info; 11072 String msg; 11073 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 11074 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 11075 != null) { 11076 throw new SecurityException(msg); 11077 } 11078 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 11079 11080 if (r != null && cpr.canRunHere(r)) { 11081 // This provider has been published or is in the process 11082 // of being published... but it is also allowed to run 11083 // in the caller's process, so don't make a connection 11084 // and just let the caller instantiate its own instance. 11085 ContentProviderHolder holder = cpr.newHolder(null); 11086 // don't give caller the provider object, it needs 11087 // to make its own. 11088 holder.provider = null; 11089 return holder; 11090 } 11091 11092 final long origId = Binder.clearCallingIdentity(); 11093 11094 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 11095 11096 // In this case the provider instance already exists, so we can 11097 // return it right away. 11098 conn = incProviderCountLocked(r, cpr, token, stable); 11099 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 11100 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 11101 // If this is a perceptible app accessing the provider, 11102 // make sure to count it as being accessed and thus 11103 // back up on the LRU list. This is good because 11104 // content providers are often expensive to start. 11105 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 11106 updateLruProcessLocked(cpr.proc, false, null); 11107 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 11108 } 11109 } 11110 11111 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 11112 final int verifiedAdj = cpr.proc.verifiedAdj; 11113 boolean success = updateOomAdjLocked(cpr.proc); 11114 // XXX things have changed so updateOomAdjLocked doesn't actually tell us 11115 // if the process has been successfully adjusted. So to reduce races with 11116 // it, we will check whether the process still exists. Note that this doesn't 11117 // completely get rid of races with LMK killing the process, but should make 11118 // them much smaller. 11119 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) { 11120 success = false; 11121 } 11122 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name); 11123 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 11124 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success); 11125 // NOTE: there is still a race here where a signal could be 11126 // pending on the process even though we managed to update its 11127 // adj level. Not sure what to do about this, but at least 11128 // the race is now smaller. 11129 if (!success) { 11130 // Uh oh... it looks like the provider's process 11131 // has been killed on us. We need to wait for a new 11132 // process to be started, and make sure its death 11133 // doesn't kill our process. 11134 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString() 11135 + " is crashing; detaching " + r); 11136 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 11137 checkTime(startTime, "getContentProviderImpl: before appDied"); 11138 appDiedLocked(cpr.proc); 11139 checkTime(startTime, "getContentProviderImpl: after appDied"); 11140 if (!lastRef) { 11141 // This wasn't the last ref our process had on 11142 // the provider... we have now been killed, bail. 11143 return null; 11144 } 11145 providerRunning = false; 11146 conn = null; 11147 } else { 11148 cpr.proc.verifiedAdj = cpr.proc.setAdj; 11149 } 11150 11151 Binder.restoreCallingIdentity(origId); 11152 } 11153 11154 if (!providerRunning) { 11155 try { 11156 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 11157 cpi = AppGlobals.getPackageManager(). 11158 resolveContentProvider(name, 11159 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 11160 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 11161 } catch (RemoteException ex) { 11162 } 11163 if (cpi == null) { 11164 return null; 11165 } 11166 // If the provider is a singleton AND 11167 // (it's a call within the same user || the provider is a 11168 // privileged app) 11169 // Then allow connecting to the singleton provider 11170 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 11171 cpi.name, cpi.flags) 11172 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 11173 if (singleton) { 11174 userId = UserHandle.USER_SYSTEM; 11175 } 11176 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 11177 checkTime(startTime, "getContentProviderImpl: got app info for user"); 11178 11179 String msg; 11180 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 11181 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 11182 != null) { 11183 throw new SecurityException(msg); 11184 } 11185 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 11186 11187 if (!mProcessesReady 11188 && !cpi.processName.equals("system")) { 11189 // If this content provider does not run in the system 11190 // process, and the system is not yet ready to run other 11191 // processes, then fail fast instead of hanging. 11192 throw new IllegalArgumentException( 11193 "Attempt to launch content provider before system ready"); 11194 } 11195 11196 // Make sure that the user who owns this provider is running. If not, 11197 // we don't want to allow it to run. 11198 if (!mUserController.isUserRunningLocked(userId, 0)) { 11199 Slog.w(TAG, "Unable to launch app " 11200 + cpi.applicationInfo.packageName + "/" 11201 + cpi.applicationInfo.uid + " for provider " 11202 + name + ": user " + userId + " is stopped"); 11203 return null; 11204 } 11205 11206 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 11207 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 11208 cpr = mProviderMap.getProviderByClass(comp, userId); 11209 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 11210 final boolean firstClass = cpr == null; 11211 if (firstClass) { 11212 final long ident = Binder.clearCallingIdentity(); 11213 11214 // If permissions need a review before any of the app components can run, 11215 // we return no provider and launch a review activity if the calling app 11216 // is in the foreground. 11217 if (mPermissionReviewRequired) { 11218 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) { 11219 return null; 11220 } 11221 } 11222 11223 try { 11224 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 11225 ApplicationInfo ai = 11226 AppGlobals.getPackageManager(). 11227 getApplicationInfo( 11228 cpi.applicationInfo.packageName, 11229 STOCK_PM_FLAGS, userId); 11230 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 11231 if (ai == null) { 11232 Slog.w(TAG, "No package info for content provider " 11233 + cpi.name); 11234 return null; 11235 } 11236 ai = getAppInfoForUser(ai, userId); 11237 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 11238 } catch (RemoteException ex) { 11239 // pm is in same process, this will never happen. 11240 } finally { 11241 Binder.restoreCallingIdentity(ident); 11242 } 11243 } 11244 11245 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 11246 11247 if (r != null && cpr.canRunHere(r)) { 11248 // If this is a multiprocess provider, then just return its 11249 // info and allow the caller to instantiate it. Only do 11250 // this if the provider is the same user as the caller's 11251 // process, or can run as root (so can be in any process). 11252 return cpr.newHolder(null); 11253 } 11254 11255 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid " 11256 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): " 11257 + cpr.info.name + " callers=" + Debug.getCallers(6)); 11258 11259 // This is single process, and our app is now connecting to it. 11260 // See if we are already in the process of launching this 11261 // provider. 11262 final int N = mLaunchingProviders.size(); 11263 int i; 11264 for (i = 0; i < N; i++) { 11265 if (mLaunchingProviders.get(i) == cpr) { 11266 break; 11267 } 11268 } 11269 11270 // If the provider is not already being launched, then get it 11271 // started. 11272 if (i >= N) { 11273 final long origId = Binder.clearCallingIdentity(); 11274 11275 try { 11276 // Content provider is now in use, its package can't be stopped. 11277 try { 11278 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 11279 AppGlobals.getPackageManager().setPackageStoppedState( 11280 cpr.appInfo.packageName, false, userId); 11281 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 11282 } catch (RemoteException e) { 11283 } catch (IllegalArgumentException e) { 11284 Slog.w(TAG, "Failed trying to unstop package " 11285 + cpr.appInfo.packageName + ": " + e); 11286 } 11287 11288 // Use existing process if already started 11289 checkTime(startTime, "getContentProviderImpl: looking for process record"); 11290 ProcessRecord proc = getProcessRecordLocked( 11291 cpi.processName, cpr.appInfo.uid, false); 11292 if (proc != null && proc.thread != null && !proc.killed) { 11293 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER, 11294 "Installing in existing process " + proc); 11295 if (!proc.pubProviders.containsKey(cpi.name)) { 11296 checkTime(startTime, "getContentProviderImpl: scheduling install"); 11297 proc.pubProviders.put(cpi.name, cpr); 11298 try { 11299 proc.thread.scheduleInstallProvider(cpi); 11300 } catch (RemoteException e) { 11301 } 11302 } 11303 } else { 11304 checkTime(startTime, "getContentProviderImpl: before start process"); 11305 proc = startProcessLocked(cpi.processName, 11306 cpr.appInfo, false, 0, "content provider", 11307 new ComponentName(cpi.applicationInfo.packageName, 11308 cpi.name), false, false, false); 11309 checkTime(startTime, "getContentProviderImpl: after start process"); 11310 if (proc == null) { 11311 Slog.w(TAG, "Unable to launch app " 11312 + cpi.applicationInfo.packageName + "/" 11313 + cpi.applicationInfo.uid + " for provider " 11314 + name + ": process is bad"); 11315 return null; 11316 } 11317 } 11318 cpr.launchingApp = proc; 11319 mLaunchingProviders.add(cpr); 11320 } finally { 11321 Binder.restoreCallingIdentity(origId); 11322 } 11323 } 11324 11325 checkTime(startTime, "getContentProviderImpl: updating data structures"); 11326 11327 // Make sure the provider is published (the same provider class 11328 // may be published under multiple names). 11329 if (firstClass) { 11330 mProviderMap.putProviderByClass(comp, cpr); 11331 } 11332 11333 mProviderMap.putProviderByName(name, cpr); 11334 conn = incProviderCountLocked(r, cpr, token, stable); 11335 if (conn != null) { 11336 conn.waiting = true; 11337 } 11338 } 11339 checkTime(startTime, "getContentProviderImpl: done!"); 11340 } 11341 11342 // Wait for the provider to be published... 11343 synchronized (cpr) { 11344 while (cpr.provider == null) { 11345 if (cpr.launchingApp == null) { 11346 Slog.w(TAG, "Unable to launch app " 11347 + cpi.applicationInfo.packageName + "/" 11348 + cpi.applicationInfo.uid + " for provider " 11349 + name + ": launching app became null"); 11350 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 11351 UserHandle.getUserId(cpi.applicationInfo.uid), 11352 cpi.applicationInfo.packageName, 11353 cpi.applicationInfo.uid, name); 11354 return null; 11355 } 11356 try { 11357 if (DEBUG_MU) Slog.v(TAG_MU, 11358 "Waiting to start provider " + cpr 11359 + " launchingApp=" + cpr.launchingApp); 11360 if (conn != null) { 11361 conn.waiting = true; 11362 } 11363 cpr.wait(); 11364 } catch (InterruptedException ex) { 11365 } finally { 11366 if (conn != null) { 11367 conn.waiting = false; 11368 } 11369 } 11370 } 11371 } 11372 return cpr != null ? cpr.newHolder(conn) : null; 11373 } 11374 11375 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi, 11376 ProcessRecord r, final int userId) { 11377 if (getPackageManagerInternalLocked().isPermissionsReviewRequired( 11378 cpi.packageName, userId)) { 11379 11380 final boolean callerForeground = r == null || r.setSchedGroup 11381 != ProcessList.SCHED_GROUP_BACKGROUND; 11382 11383 // Show a permission review UI only for starting from a foreground app 11384 if (!callerForeground) { 11385 Slog.w(TAG, "u" + userId + " Instantiating a provider in package" 11386 + cpi.packageName + " requires a permissions review"); 11387 return false; 11388 } 11389 11390 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS); 11391 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 11392 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 11393 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName); 11394 11395 if (DEBUG_PERMISSIONS_REVIEW) { 11396 Slog.i(TAG, "u" + userId + " Launching permission review " 11397 + "for package " + cpi.packageName); 11398 } 11399 11400 final UserHandle userHandle = new UserHandle(userId); 11401 mHandler.post(new Runnable() { 11402 @Override 11403 public void run() { 11404 mContext.startActivityAsUser(intent, userHandle); 11405 } 11406 }); 11407 11408 return false; 11409 } 11410 11411 return true; 11412 } 11413 11414 PackageManagerInternal getPackageManagerInternalLocked() { 11415 if (mPackageManagerInt == null) { 11416 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class); 11417 } 11418 return mPackageManagerInt; 11419 } 11420 11421 @Override 11422 public final ContentProviderHolder getContentProvider( 11423 IApplicationThread caller, String name, int userId, boolean stable) { 11424 enforceNotIsolatedCaller("getContentProvider"); 11425 if (caller == null) { 11426 String msg = "null IApplicationThread when getting content provider " 11427 + name; 11428 Slog.w(TAG, msg); 11429 throw new SecurityException(msg); 11430 } 11431 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 11432 // with cross-user grant. 11433 return getContentProviderImpl(caller, name, null, stable, userId); 11434 } 11435 11436 public ContentProviderHolder getContentProviderExternal( 11437 String name, int userId, IBinder token) { 11438 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 11439 "Do not have permission in call getContentProviderExternal()"); 11440 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 11441 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null); 11442 return getContentProviderExternalUnchecked(name, token, userId); 11443 } 11444 11445 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 11446 IBinder token, int userId) { 11447 return getContentProviderImpl(null, name, token, true, userId); 11448 } 11449 11450 /** 11451 * Drop a content provider from a ProcessRecord's bookkeeping 11452 */ 11453 public void removeContentProvider(IBinder connection, boolean stable) { 11454 enforceNotIsolatedCaller("removeContentProvider"); 11455 long ident = Binder.clearCallingIdentity(); 11456 try { 11457 synchronized (this) { 11458 ContentProviderConnection conn; 11459 try { 11460 conn = (ContentProviderConnection)connection; 11461 } catch (ClassCastException e) { 11462 String msg ="removeContentProvider: " + connection 11463 + " not a ContentProviderConnection"; 11464 Slog.w(TAG, msg); 11465 throw new IllegalArgumentException(msg); 11466 } 11467 if (conn == null) { 11468 throw new NullPointerException("connection is null"); 11469 } 11470 if (decProviderCountLocked(conn, null, null, stable)) { 11471 updateOomAdjLocked(); 11472 } 11473 } 11474 } finally { 11475 Binder.restoreCallingIdentity(ident); 11476 } 11477 } 11478 11479 public void removeContentProviderExternal(String name, IBinder token) { 11480 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 11481 "Do not have permission in call removeContentProviderExternal()"); 11482 int userId = UserHandle.getCallingUserId(); 11483 long ident = Binder.clearCallingIdentity(); 11484 try { 11485 removeContentProviderExternalUnchecked(name, token, userId); 11486 } finally { 11487 Binder.restoreCallingIdentity(ident); 11488 } 11489 } 11490 11491 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 11492 synchronized (this) { 11493 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 11494 if(cpr == null) { 11495 //remove from mProvidersByClass 11496 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list"); 11497 return; 11498 } 11499 11500 //update content provider record entry info 11501 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 11502 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 11503 if (localCpr.hasExternalProcessHandles()) { 11504 if (localCpr.removeExternalProcessHandleLocked(token)) { 11505 updateOomAdjLocked(); 11506 } else { 11507 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 11508 + " with no external reference for token: " 11509 + token + "."); 11510 } 11511 } else { 11512 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 11513 + " with no external references."); 11514 } 11515 } 11516 } 11517 11518 public final void publishContentProviders(IApplicationThread caller, 11519 List<ContentProviderHolder> providers) { 11520 if (providers == null) { 11521 return; 11522 } 11523 11524 enforceNotIsolatedCaller("publishContentProviders"); 11525 synchronized (this) { 11526 final ProcessRecord r = getRecordForAppLocked(caller); 11527 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 11528 if (r == null) { 11529 throw new SecurityException( 11530 "Unable to find app for caller " + caller 11531 + " (pid=" + Binder.getCallingPid() 11532 + ") when publishing content providers"); 11533 } 11534 11535 final long origId = Binder.clearCallingIdentity(); 11536 11537 final int N = providers.size(); 11538 for (int i = 0; i < N; i++) { 11539 ContentProviderHolder src = providers.get(i); 11540 if (src == null || src.info == null || src.provider == null) { 11541 continue; 11542 } 11543 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 11544 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 11545 if (dst != null) { 11546 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 11547 mProviderMap.putProviderByClass(comp, dst); 11548 String names[] = dst.info.authority.split(";"); 11549 for (int j = 0; j < names.length; j++) { 11550 mProviderMap.putProviderByName(names[j], dst); 11551 } 11552 11553 int launchingCount = mLaunchingProviders.size(); 11554 int j; 11555 boolean wasInLaunchingProviders = false; 11556 for (j = 0; j < launchingCount; j++) { 11557 if (mLaunchingProviders.get(j) == dst) { 11558 mLaunchingProviders.remove(j); 11559 wasInLaunchingProviders = true; 11560 j--; 11561 launchingCount--; 11562 } 11563 } 11564 if (wasInLaunchingProviders) { 11565 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r); 11566 } 11567 synchronized (dst) { 11568 dst.provider = src.provider; 11569 dst.proc = r; 11570 dst.notifyAll(); 11571 } 11572 updateOomAdjLocked(r); 11573 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName, 11574 src.info.authority); 11575 } 11576 } 11577 11578 Binder.restoreCallingIdentity(origId); 11579 } 11580 } 11581 11582 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 11583 ContentProviderConnection conn; 11584 try { 11585 conn = (ContentProviderConnection)connection; 11586 } catch (ClassCastException e) { 11587 String msg ="refContentProvider: " + connection 11588 + " not a ContentProviderConnection"; 11589 Slog.w(TAG, msg); 11590 throw new IllegalArgumentException(msg); 11591 } 11592 if (conn == null) { 11593 throw new NullPointerException("connection is null"); 11594 } 11595 11596 synchronized (this) { 11597 if (stable > 0) { 11598 conn.numStableIncs += stable; 11599 } 11600 stable = conn.stableCount + stable; 11601 if (stable < 0) { 11602 throw new IllegalStateException("stableCount < 0: " + stable); 11603 } 11604 11605 if (unstable > 0) { 11606 conn.numUnstableIncs += unstable; 11607 } 11608 unstable = conn.unstableCount + unstable; 11609 if (unstable < 0) { 11610 throw new IllegalStateException("unstableCount < 0: " + unstable); 11611 } 11612 11613 if ((stable+unstable) <= 0) { 11614 throw new IllegalStateException("ref counts can't go to zero here: stable=" 11615 + stable + " unstable=" + unstable); 11616 } 11617 conn.stableCount = stable; 11618 conn.unstableCount = unstable; 11619 return !conn.dead; 11620 } 11621 } 11622 11623 public void unstableProviderDied(IBinder connection) { 11624 ContentProviderConnection conn; 11625 try { 11626 conn = (ContentProviderConnection)connection; 11627 } catch (ClassCastException e) { 11628 String msg ="refContentProvider: " + connection 11629 + " not a ContentProviderConnection"; 11630 Slog.w(TAG, msg); 11631 throw new IllegalArgumentException(msg); 11632 } 11633 if (conn == null) { 11634 throw new NullPointerException("connection is null"); 11635 } 11636 11637 // Safely retrieve the content provider associated with the connection. 11638 IContentProvider provider; 11639 synchronized (this) { 11640 provider = conn.provider.provider; 11641 } 11642 11643 if (provider == null) { 11644 // Um, yeah, we're way ahead of you. 11645 return; 11646 } 11647 11648 // Make sure the caller is being honest with us. 11649 if (provider.asBinder().pingBinder()) { 11650 // Er, no, still looks good to us. 11651 synchronized (this) { 11652 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 11653 + " says " + conn + " died, but we don't agree"); 11654 return; 11655 } 11656 } 11657 11658 // Well look at that! It's dead! 11659 synchronized (this) { 11660 if (conn.provider.provider != provider) { 11661 // But something changed... good enough. 11662 return; 11663 } 11664 11665 ProcessRecord proc = conn.provider.proc; 11666 if (proc == null || proc.thread == null) { 11667 // Seems like the process is already cleaned up. 11668 return; 11669 } 11670 11671 // As far as we're concerned, this is just like receiving a 11672 // death notification... just a bit prematurely. 11673 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 11674 + ") early provider death"); 11675 final long ident = Binder.clearCallingIdentity(); 11676 try { 11677 appDiedLocked(proc); 11678 } finally { 11679 Binder.restoreCallingIdentity(ident); 11680 } 11681 } 11682 } 11683 11684 @Override 11685 public void appNotRespondingViaProvider(IBinder connection) { 11686 enforceCallingPermission( 11687 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 11688 11689 final ContentProviderConnection conn = (ContentProviderConnection) connection; 11690 if (conn == null) { 11691 Slog.w(TAG, "ContentProviderConnection is null"); 11692 return; 11693 } 11694 11695 final ProcessRecord host = conn.provider.proc; 11696 if (host == null) { 11697 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 11698 return; 11699 } 11700 11701 mHandler.post(new Runnable() { 11702 @Override 11703 public void run() { 11704 mAppErrors.appNotResponding(host, null, null, false, 11705 "ContentProvider not responding"); 11706 } 11707 }); 11708 } 11709 11710 public final void installSystemProviders() { 11711 List<ProviderInfo> providers; 11712 synchronized (this) { 11713 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 11714 providers = generateApplicationProvidersLocked(app); 11715 if (providers != null) { 11716 for (int i=providers.size()-1; i>=0; i--) { 11717 ProviderInfo pi = (ProviderInfo)providers.get(i); 11718 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 11719 Slog.w(TAG, "Not installing system proc provider " + pi.name 11720 + ": not system .apk"); 11721 providers.remove(i); 11722 } 11723 } 11724 } 11725 } 11726 if (providers != null) { 11727 mSystemThread.installSystemProviders(providers); 11728 } 11729 11730 mConstants.start(mContext.getContentResolver()); 11731 mCoreSettingsObserver = new CoreSettingsObserver(this); 11732 mFontScaleSettingObserver = new FontScaleSettingObserver(); 11733 11734 // Now that the settings provider is published we can consider sending 11735 // in a rescue party. 11736 RescueParty.onSettingsProviderPublished(mContext); 11737 11738 //mUsageStatsService.monitorPackages(); 11739 } 11740 11741 private void startPersistentApps(int matchFlags) { 11742 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return; 11743 11744 synchronized (this) { 11745 try { 11746 final List<ApplicationInfo> apps = AppGlobals.getPackageManager() 11747 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList(); 11748 for (ApplicationInfo app : apps) { 11749 if (!"android".equals(app.packageName)) { 11750 addAppLocked(app, null, false, null /* ABI override */); 11751 } 11752 } 11753 } catch (RemoteException ex) { 11754 } 11755 } 11756 } 11757 11758 /** 11759 * When a user is unlocked, we need to install encryption-unaware providers 11760 * belonging to any running apps. 11761 */ 11762 private void installEncryptionUnawareProviders(int userId) { 11763 // We're only interested in providers that are encryption unaware, and 11764 // we don't care about uninstalled apps, since there's no way they're 11765 // running at this point. 11766 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE; 11767 11768 synchronized (this) { 11769 final int NP = mProcessNames.getMap().size(); 11770 for (int ip = 0; ip < NP; ip++) { 11771 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11772 final int NA = apps.size(); 11773 for (int ia = 0; ia < NA; ia++) { 11774 final ProcessRecord app = apps.valueAt(ia); 11775 if (app.userId != userId || app.thread == null || app.unlocked) continue; 11776 11777 final int NG = app.pkgList.size(); 11778 for (int ig = 0; ig < NG; ig++) { 11779 try { 11780 final String pkgName = app.pkgList.keyAt(ig); 11781 final PackageInfo pkgInfo = AppGlobals.getPackageManager() 11782 .getPackageInfo(pkgName, matchFlags, userId); 11783 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) { 11784 for (ProviderInfo pi : pkgInfo.providers) { 11785 // TODO: keep in sync with generateApplicationProvidersLocked 11786 final boolean processMatch = Objects.equals(pi.processName, 11787 app.processName) || pi.multiprocess; 11788 final boolean userMatch = isSingleton(pi.processName, 11789 pi.applicationInfo, pi.name, pi.flags) 11790 ? (app.userId == UserHandle.USER_SYSTEM) : true; 11791 if (processMatch && userMatch) { 11792 Log.v(TAG, "Installing " + pi); 11793 app.thread.scheduleInstallProvider(pi); 11794 } else { 11795 Log.v(TAG, "Skipping " + pi); 11796 } 11797 } 11798 } 11799 } catch (RemoteException ignored) { 11800 } 11801 } 11802 } 11803 } 11804 } 11805 } 11806 11807 /** 11808 * Allows apps to retrieve the MIME type of a URI. 11809 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 11810 * users, then it does not need permission to access the ContentProvider. 11811 * Either, it needs cross-user uri grants. 11812 * 11813 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 11814 * 11815 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 11816 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 11817 */ 11818 public String getProviderMimeType(Uri uri, int userId) { 11819 enforceNotIsolatedCaller("getProviderMimeType"); 11820 final String name = uri.getAuthority(); 11821 int callingUid = Binder.getCallingUid(); 11822 int callingPid = Binder.getCallingPid(); 11823 long ident = 0; 11824 boolean clearedIdentity = false; 11825 synchronized (this) { 11826 userId = mUserController.unsafeConvertIncomingUserLocked(userId); 11827 } 11828 if (canClearIdentity(callingPid, callingUid, userId)) { 11829 clearedIdentity = true; 11830 ident = Binder.clearCallingIdentity(); 11831 } 11832 ContentProviderHolder holder = null; 11833 try { 11834 holder = getContentProviderExternalUnchecked(name, null, userId); 11835 if (holder != null) { 11836 return holder.provider.getType(uri); 11837 } 11838 } catch (RemoteException e) { 11839 Log.w(TAG, "Content provider dead retrieving " + uri, e); 11840 return null; 11841 } catch (Exception e) { 11842 Log.w(TAG, "Exception while determining type of " + uri, e); 11843 return null; 11844 } finally { 11845 // We need to clear the identity to call removeContentProviderExternalUnchecked 11846 if (!clearedIdentity) { 11847 ident = Binder.clearCallingIdentity(); 11848 } 11849 try { 11850 if (holder != null) { 11851 removeContentProviderExternalUnchecked(name, null, userId); 11852 } 11853 } finally { 11854 Binder.restoreCallingIdentity(ident); 11855 } 11856 } 11857 11858 return null; 11859 } 11860 11861 private boolean canClearIdentity(int callingPid, int callingUid, int userId) { 11862 if (UserHandle.getUserId(callingUid) == userId) { 11863 return true; 11864 } 11865 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 11866 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 11867 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 11868 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 11869 return true; 11870 } 11871 return false; 11872 } 11873 11874 // ========================================================= 11875 // GLOBAL MANAGEMENT 11876 // ========================================================= 11877 11878 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 11879 boolean isolated, int isolatedUid) { 11880 String proc = customProcess != null ? customProcess : info.processName; 11881 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 11882 final int userId = UserHandle.getUserId(info.uid); 11883 int uid = info.uid; 11884 if (isolated) { 11885 if (isolatedUid == 0) { 11886 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 11887 while (true) { 11888 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 11889 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 11890 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 11891 } 11892 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 11893 mNextIsolatedProcessUid++; 11894 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 11895 // No process for this uid, use it. 11896 break; 11897 } 11898 stepsLeft--; 11899 if (stepsLeft <= 0) { 11900 return null; 11901 } 11902 } 11903 } else { 11904 // Special case for startIsolatedProcess (internal only), where 11905 // the uid of the isolated process is specified by the caller. 11906 uid = isolatedUid; 11907 } 11908 11909 // Register the isolated UID with this application so BatteryStats knows to 11910 // attribute resource usage to the application. 11911 // 11912 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats 11913 // about the process state of the isolated UID *before* it is registered with the 11914 // owning application. 11915 mBatteryStatsService.addIsolatedUid(uid, info.uid); 11916 } 11917 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid); 11918 if (!mBooted && !mBooting 11919 && userId == UserHandle.USER_SYSTEM 11920 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { 11921 r.persistent = true; 11922 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 11923 } 11924 addProcessNameLocked(r); 11925 return r; 11926 } 11927 11928 private boolean uidOnBackgroundWhitelist(final int uid) { 11929 final int N = mBackgroundUidWhitelist.length; 11930 for (int i = 0; i < N; i++) { 11931 if (uid == mBackgroundUidWhitelist[i]) { 11932 return true; 11933 } 11934 } 11935 return false; 11936 } 11937 11938 final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated, 11939 String abiOverride) { 11940 ProcessRecord app; 11941 if (!isolated) { 11942 app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName, 11943 info.uid, true); 11944 } else { 11945 app = null; 11946 } 11947 11948 if (app == null) { 11949 app = newProcessRecordLocked(info, customProcess, isolated, 0); 11950 updateLruProcessLocked(app, false, null); 11951 updateOomAdjLocked(); 11952 } 11953 11954 // This package really, really can not be stopped. 11955 try { 11956 AppGlobals.getPackageManager().setPackageStoppedState( 11957 info.packageName, false, UserHandle.getUserId(app.uid)); 11958 } catch (RemoteException e) { 11959 } catch (IllegalArgumentException e) { 11960 Slog.w(TAG, "Failed trying to unstop package " 11961 + info.packageName + ": " + e); 11962 } 11963 11964 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { 11965 app.persistent = true; 11966 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 11967 } 11968 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 11969 mPersistentStartingProcesses.add(app); 11970 startProcessLocked(app, "added application", 11971 customProcess != null ? customProcess : app.processName, abiOverride, 11972 null /* entryPoint */, null /* entryPointArgs */); 11973 } 11974 11975 return app; 11976 } 11977 11978 public void unhandledBack() { 11979 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 11980 "unhandledBack()"); 11981 11982 synchronized(this) { 11983 final long origId = Binder.clearCallingIdentity(); 11984 try { 11985 getFocusedStack().unhandledBackLocked(); 11986 } finally { 11987 Binder.restoreCallingIdentity(origId); 11988 } 11989 } 11990 } 11991 11992 public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException { 11993 enforceNotIsolatedCaller("openContentUri"); 11994 final int userId = UserHandle.getCallingUserId(); 11995 final Uri uri = Uri.parse(uriString); 11996 String name = uri.getAuthority(); 11997 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 11998 ParcelFileDescriptor pfd = null; 11999 if (cph != null) { 12000 // We record the binder invoker's uid in thread-local storage before 12001 // going to the content provider to open the file. Later, in the code 12002 // that handles all permissions checks, we look for this uid and use 12003 // that rather than the Activity Manager's own uid. The effect is that 12004 // we do the check against the caller's permissions even though it looks 12005 // to the content provider like the Activity Manager itself is making 12006 // the request. 12007 Binder token = new Binder(); 12008 sCallerIdentity.set(new Identity( 12009 token, Binder.getCallingPid(), Binder.getCallingUid())); 12010 try { 12011 pfd = cph.provider.openFile(null, uri, "r", null, token); 12012 } catch (FileNotFoundException e) { 12013 // do nothing; pfd will be returned null 12014 } finally { 12015 // Ensure that whatever happens, we clean up the identity state 12016 sCallerIdentity.remove(); 12017 // Ensure we're done with the provider. 12018 removeContentProviderExternalUnchecked(name, null, userId); 12019 } 12020 } else { 12021 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 12022 } 12023 return pfd; 12024 } 12025 12026 // Actually is sleeping or shutting down or whatever else in the future 12027 // is an inactive state. 12028 boolean isSleepingOrShuttingDownLocked() { 12029 return isSleepingLocked() || mShuttingDown; 12030 } 12031 12032 boolean isShuttingDownLocked() { 12033 return mShuttingDown; 12034 } 12035 12036 boolean isSleepingLocked() { 12037 return mSleeping; 12038 } 12039 12040 void onWakefulnessChanged(int wakefulness) { 12041 synchronized(this) { 12042 mWakefulness = wakefulness; 12043 updateSleepIfNeededLocked(); 12044 } 12045 } 12046 12047 void finishRunningVoiceLocked() { 12048 if (mRunningVoice != null) { 12049 mRunningVoice = null; 12050 mVoiceWakeLock.release(); 12051 updateSleepIfNeededLocked(); 12052 } 12053 } 12054 12055 void startTimeTrackingFocusedActivityLocked() { 12056 final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked(); 12057 if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) { 12058 mCurAppTimeTracker.start(resumedActivity.packageName); 12059 } 12060 } 12061 12062 void updateSleepIfNeededLocked() { 12063 if (mSleeping && !shouldSleepLocked()) { 12064 mSleeping = false; 12065 startTimeTrackingFocusedActivityLocked(); 12066 mTopProcessState = ActivityManager.PROCESS_STATE_TOP; 12067 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 12068 sendNotifyVrManagerOfSleepState(false); 12069 updateOomAdjLocked(); 12070 } else if (!mSleeping && shouldSleepLocked()) { 12071 mSleeping = true; 12072 if (mCurAppTimeTracker != null) { 12073 mCurAppTimeTracker.stop(); 12074 } 12075 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING; 12076 mStackSupervisor.goingToSleepLocked(); 12077 sendNotifyVrManagerOfSleepState(true); 12078 updateOomAdjLocked(); 12079 12080 // Initialize the wake times of all processes. 12081 checkExcessivePowerUsageLocked(false); 12082 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 12083 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 12084 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 12085 } 12086 } 12087 12088 private boolean shouldSleepLocked() { 12089 // Resume applications while running a voice interactor. 12090 if (mRunningVoice != null) { 12091 return false; 12092 } 12093 12094 // TODO: Transform the lock screen state into a sleep token instead. 12095 switch (mWakefulness) { 12096 case PowerManagerInternal.WAKEFULNESS_AWAKE: 12097 case PowerManagerInternal.WAKEFULNESS_DREAMING: 12098 case PowerManagerInternal.WAKEFULNESS_DOZING: 12099 // Pause applications whenever the lock screen is shown or any sleep 12100 // tokens have been acquired. 12101 return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty(); 12102 case PowerManagerInternal.WAKEFULNESS_ASLEEP: 12103 default: 12104 // If we're asleep then pause applications unconditionally. 12105 return true; 12106 } 12107 } 12108 12109 /** Pokes the task persister. */ 12110 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 12111 mRecentTasks.notifyTaskPersisterLocked(task, flush); 12112 } 12113 12114 /** Notifies all listeners when the pinned stack animation starts. */ 12115 @Override 12116 public void notifyPinnedStackAnimationStarted() { 12117 mTaskChangeNotificationController.notifyPinnedStackAnimationStarted(); 12118 } 12119 12120 /** Notifies all listeners when the pinned stack animation ends. */ 12121 @Override 12122 public void notifyPinnedStackAnimationEnded() { 12123 mTaskChangeNotificationController.notifyPinnedStackAnimationEnded(); 12124 } 12125 12126 @Override 12127 public void notifyCleartextNetwork(int uid, byte[] firstPacket) { 12128 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget(); 12129 } 12130 12131 @Override 12132 public boolean shutdown(int timeout) { 12133 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 12134 != PackageManager.PERMISSION_GRANTED) { 12135 throw new SecurityException("Requires permission " 12136 + android.Manifest.permission.SHUTDOWN); 12137 } 12138 12139 boolean timedout = false; 12140 12141 synchronized(this) { 12142 mShuttingDown = true; 12143 updateEventDispatchingLocked(); 12144 timedout = mStackSupervisor.shutdownLocked(timeout); 12145 } 12146 12147 mAppOpsService.shutdown(); 12148 if (mUsageStatsService != null) { 12149 mUsageStatsService.prepareShutdown(); 12150 } 12151 mBatteryStatsService.shutdown(); 12152 synchronized (this) { 12153 mProcessStats.shutdownLocked(); 12154 notifyTaskPersisterLocked(null, true); 12155 } 12156 12157 return timedout; 12158 } 12159 12160 public final void activitySlept(IBinder token) { 12161 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token); 12162 12163 final long origId = Binder.clearCallingIdentity(); 12164 12165 synchronized (this) { 12166 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 12167 if (r != null) { 12168 mStackSupervisor.activitySleptLocked(r); 12169 } 12170 } 12171 12172 Binder.restoreCallingIdentity(origId); 12173 } 12174 12175 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) { 12176 Slog.d(TAG, "<<< startRunningVoiceLocked()"); 12177 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid)); 12178 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) { 12179 boolean wasRunningVoice = mRunningVoice != null; 12180 mRunningVoice = session; 12181 if (!wasRunningVoice) { 12182 mVoiceWakeLock.acquire(); 12183 updateSleepIfNeededLocked(); 12184 } 12185 } 12186 } 12187 12188 private void updateEventDispatchingLocked() { 12189 mWindowManager.setEventDispatching(mBooted && !mShuttingDown); 12190 } 12191 12192 @Override 12193 public void setLockScreenShown(boolean showing) { 12194 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 12195 != PackageManager.PERMISSION_GRANTED) { 12196 throw new SecurityException("Requires permission " 12197 + android.Manifest.permission.DEVICE_POWER); 12198 } 12199 12200 synchronized(this) { 12201 long ident = Binder.clearCallingIdentity(); 12202 try { 12203 mKeyguardController.setKeyguardShown(showing); 12204 } finally { 12205 Binder.restoreCallingIdentity(ident); 12206 } 12207 } 12208 } 12209 12210 @Override 12211 public void notifyLockedProfile(@UserIdInt int userId) { 12212 try { 12213 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) { 12214 throw new SecurityException("Only privileged app can call notifyLockedProfile"); 12215 } 12216 } catch (RemoteException ex) { 12217 throw new SecurityException("Fail to check is caller a privileged app", ex); 12218 } 12219 12220 synchronized (this) { 12221 final long ident = Binder.clearCallingIdentity(); 12222 try { 12223 if (mUserController.shouldConfirmCredentials(userId)) { 12224 if (mKeyguardController.isKeyguardLocked()) { 12225 // Showing launcher to avoid user entering credential twice. 12226 final int currentUserId = mUserController.getCurrentUserIdLocked(); 12227 startHomeActivityLocked(currentUserId, "notifyLockedProfile"); 12228 } 12229 mStackSupervisor.lockAllProfileTasks(userId); 12230 } 12231 } finally { 12232 Binder.restoreCallingIdentity(ident); 12233 } 12234 } 12235 } 12236 12237 @Override 12238 public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) { 12239 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent"); 12240 synchronized (this) { 12241 final long ident = Binder.clearCallingIdentity(); 12242 try { 12243 mActivityStarter.startConfirmCredentialIntent(intent, options); 12244 } finally { 12245 Binder.restoreCallingIdentity(ident); 12246 } 12247 } 12248 } 12249 12250 @Override 12251 public void stopAppSwitches() { 12252 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 12253 != PackageManager.PERMISSION_GRANTED) { 12254 throw new SecurityException("viewquires permission " 12255 + android.Manifest.permission.STOP_APP_SWITCHES); 12256 } 12257 12258 synchronized(this) { 12259 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 12260 + APP_SWITCH_DELAY_TIME; 12261 mDidAppSwitch = false; 12262 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 12263 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 12264 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 12265 } 12266 } 12267 12268 public void resumeAppSwitches() { 12269 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 12270 != PackageManager.PERMISSION_GRANTED) { 12271 throw new SecurityException("Requires permission " 12272 + android.Manifest.permission.STOP_APP_SWITCHES); 12273 } 12274 12275 synchronized(this) { 12276 // Note that we don't execute any pending app switches... we will 12277 // let those wait until either the timeout, or the next start 12278 // activity request. 12279 mAppSwitchesAllowedTime = 0; 12280 } 12281 } 12282 12283 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, 12284 int callingPid, int callingUid, String name) { 12285 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 12286 return true; 12287 } 12288 12289 int perm = checkComponentPermission( 12290 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid, 12291 sourceUid, -1, true); 12292 if (perm == PackageManager.PERMISSION_GRANTED) { 12293 return true; 12294 } 12295 12296 // If the actual IPC caller is different from the logical source, then 12297 // also see if they are allowed to control app switches. 12298 if (callingUid != -1 && callingUid != sourceUid) { 12299 perm = checkComponentPermission( 12300 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 12301 callingUid, -1, true); 12302 if (perm == PackageManager.PERMISSION_GRANTED) { 12303 return true; 12304 } 12305 } 12306 12307 Slog.w(TAG, name + " request from " + sourceUid + " stopped"); 12308 return false; 12309 } 12310 12311 public void setDebugApp(String packageName, boolean waitForDebugger, 12312 boolean persistent) { 12313 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 12314 "setDebugApp()"); 12315 12316 long ident = Binder.clearCallingIdentity(); 12317 try { 12318 // Note that this is not really thread safe if there are multiple 12319 // callers into it at the same time, but that's not a situation we 12320 // care about. 12321 if (persistent) { 12322 final ContentResolver resolver = mContext.getContentResolver(); 12323 Settings.Global.putString( 12324 resolver, Settings.Global.DEBUG_APP, 12325 packageName); 12326 Settings.Global.putInt( 12327 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 12328 waitForDebugger ? 1 : 0); 12329 } 12330 12331 synchronized (this) { 12332 if (!persistent) { 12333 mOrigDebugApp = mDebugApp; 12334 mOrigWaitForDebugger = mWaitForDebugger; 12335 } 12336 mDebugApp = packageName; 12337 mWaitForDebugger = waitForDebugger; 12338 mDebugTransient = !persistent; 12339 if (packageName != null) { 12340 forceStopPackageLocked(packageName, -1, false, false, true, true, 12341 false, UserHandle.USER_ALL, "set debug app"); 12342 } 12343 } 12344 } finally { 12345 Binder.restoreCallingIdentity(ident); 12346 } 12347 } 12348 12349 void setTrackAllocationApp(ApplicationInfo app, String processName) { 12350 synchronized (this) { 12351 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 12352 if (!isDebuggable) { 12353 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12354 throw new SecurityException("Process not debuggable: " + app.packageName); 12355 } 12356 } 12357 12358 mTrackAllocationApp = processName; 12359 } 12360 } 12361 12362 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 12363 synchronized (this) { 12364 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 12365 if (!isDebuggable) { 12366 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12367 throw new SecurityException("Process not debuggable: " + app.packageName); 12368 } 12369 } 12370 mProfileApp = processName; 12371 mProfileFile = profilerInfo.profileFile; 12372 if (mProfileFd != null) { 12373 try { 12374 mProfileFd.close(); 12375 } catch (IOException e) { 12376 } 12377 mProfileFd = null; 12378 } 12379 mProfileFd = profilerInfo.profileFd; 12380 mSamplingInterval = profilerInfo.samplingInterval; 12381 mAutoStopProfiler = profilerInfo.autoStopProfiler; 12382 mStreamingOutput = profilerInfo.streamingOutput; 12383 mProfileType = 0; 12384 } 12385 } 12386 12387 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) { 12388 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 12389 if (!isDebuggable) { 12390 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 12391 throw new SecurityException("Process not debuggable: " + app.packageName); 12392 } 12393 } 12394 mNativeDebuggingApp = processName; 12395 } 12396 12397 @Override 12398 public void setAlwaysFinish(boolean enabled) { 12399 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 12400 "setAlwaysFinish()"); 12401 12402 long ident = Binder.clearCallingIdentity(); 12403 try { 12404 Settings.Global.putInt( 12405 mContext.getContentResolver(), 12406 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 12407 12408 synchronized (this) { 12409 mAlwaysFinishActivities = enabled; 12410 } 12411 } finally { 12412 Binder.restoreCallingIdentity(ident); 12413 } 12414 } 12415 12416 @Override 12417 public void setActivityController(IActivityController controller, boolean imAMonkey) { 12418 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 12419 "setActivityController()"); 12420 synchronized (this) { 12421 mController = controller; 12422 mControllerIsAMonkey = imAMonkey; 12423 Watchdog.getInstance().setActivityController(controller); 12424 } 12425 } 12426 12427 @Override 12428 public void setUserIsMonkey(boolean userIsMonkey) { 12429 synchronized (this) { 12430 synchronized (mPidsSelfLocked) { 12431 final int callingPid = Binder.getCallingPid(); 12432 ProcessRecord proc = mPidsSelfLocked.get(callingPid); 12433 if (proc == null) { 12434 throw new SecurityException("Unknown process: " + callingPid); 12435 } 12436 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) { 12437 throw new SecurityException("Only an instrumentation process " 12438 + "with a UiAutomation can call setUserIsMonkey"); 12439 } 12440 } 12441 mUserIsMonkey = userIsMonkey; 12442 } 12443 } 12444 12445 @Override 12446 public boolean isUserAMonkey() { 12447 synchronized (this) { 12448 // If there is a controller also implies the user is a monkey. 12449 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey)); 12450 } 12451 } 12452 12453 /** 12454 * @deprecated This method is only used by a few internal components and it will soon be 12455 * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps). 12456 * No new code should be calling it. 12457 */ 12458 @Deprecated 12459 public void requestBugReport(int bugreportType) { 12460 String extraOptions = null; 12461 switch (bugreportType) { 12462 case ActivityManager.BUGREPORT_OPTION_FULL: 12463 // Default options. 12464 break; 12465 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE: 12466 extraOptions = "bugreportplus"; 12467 break; 12468 case ActivityManager.BUGREPORT_OPTION_REMOTE: 12469 extraOptions = "bugreportremote"; 12470 break; 12471 case ActivityManager.BUGREPORT_OPTION_WEAR: 12472 extraOptions = "bugreportwear"; 12473 break; 12474 case ActivityManager.BUGREPORT_OPTION_TELEPHONY: 12475 extraOptions = "bugreporttelephony"; 12476 break; 12477 default: 12478 throw new IllegalArgumentException("Provided bugreport type is not correct, value: " 12479 + bugreportType); 12480 } 12481 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 12482 if (extraOptions != null) { 12483 SystemProperties.set("dumpstate.options", extraOptions); 12484 } 12485 SystemProperties.set("ctl.start", "bugreport"); 12486 } 12487 12488 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 12489 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 12490 } 12491 12492 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 12493 if (r != null && (r.instr != null || r.usingWrapper)) { 12494 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 12495 } 12496 return KEY_DISPATCHING_TIMEOUT; 12497 } 12498 12499 @Override 12500 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 12501 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 12502 != PackageManager.PERMISSION_GRANTED) { 12503 throw new SecurityException("Requires permission " 12504 + android.Manifest.permission.FILTER_EVENTS); 12505 } 12506 ProcessRecord proc; 12507 long timeout; 12508 synchronized (this) { 12509 synchronized (mPidsSelfLocked) { 12510 proc = mPidsSelfLocked.get(pid); 12511 } 12512 timeout = getInputDispatchingTimeoutLocked(proc); 12513 } 12514 12515 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 12516 return -1; 12517 } 12518 12519 return timeout; 12520 } 12521 12522 /** 12523 * Handle input dispatching timeouts. 12524 * Returns whether input dispatching should be aborted or not. 12525 */ 12526 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 12527 final ActivityRecord activity, final ActivityRecord parent, 12528 final boolean aboveSystem, String reason) { 12529 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 12530 != PackageManager.PERMISSION_GRANTED) { 12531 throw new SecurityException("Requires permission " 12532 + android.Manifest.permission.FILTER_EVENTS); 12533 } 12534 12535 final String annotation; 12536 if (reason == null) { 12537 annotation = "Input dispatching timed out"; 12538 } else { 12539 annotation = "Input dispatching timed out (" + reason + ")"; 12540 } 12541 12542 if (proc != null) { 12543 synchronized (this) { 12544 if (proc.debugging) { 12545 return false; 12546 } 12547 12548 if (mDidDexOpt) { 12549 // Give more time since we were dexopting. 12550 mDidDexOpt = false; 12551 return false; 12552 } 12553 12554 if (proc.instr != null) { 12555 Bundle info = new Bundle(); 12556 info.putString("shortMsg", "keyDispatchingTimedOut"); 12557 info.putString("longMsg", annotation); 12558 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 12559 return true; 12560 } 12561 } 12562 mHandler.post(new Runnable() { 12563 @Override 12564 public void run() { 12565 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation); 12566 } 12567 }); 12568 } 12569 12570 return true; 12571 } 12572 12573 @Override 12574 public Bundle getAssistContextExtras(int requestType) { 12575 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null, 12576 null, null, true /* focused */, true /* newSessionId */, 12577 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT); 12578 if (pae == null) { 12579 return null; 12580 } 12581 synchronized (pae) { 12582 while (!pae.haveResult) { 12583 try { 12584 pae.wait(); 12585 } catch (InterruptedException e) { 12586 } 12587 } 12588 } 12589 synchronized (this) { 12590 buildAssistBundleLocked(pae, pae.result); 12591 mPendingAssistExtras.remove(pae); 12592 mUiHandler.removeCallbacks(pae); 12593 } 12594 return pae.extras; 12595 } 12596 12597 @Override 12598 public boolean isAssistDataAllowedOnCurrentActivity() { 12599 int userId; 12600 synchronized (this) { 12601 final ActivityStack focusedStack = getFocusedStack(); 12602 if (focusedStack == null || focusedStack.isAssistantStack()) { 12603 return false; 12604 } 12605 12606 final ActivityRecord activity = focusedStack.topActivity(); 12607 if (activity == null) { 12608 return false; 12609 } 12610 userId = activity.userId; 12611 } 12612 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( 12613 Context.DEVICE_POLICY_SERVICE); 12614 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId)); 12615 } 12616 12617 @Override 12618 public boolean showAssistFromActivity(IBinder token, Bundle args) { 12619 long ident = Binder.clearCallingIdentity(); 12620 try { 12621 synchronized (this) { 12622 ActivityRecord caller = ActivityRecord.forTokenLocked(token); 12623 ActivityRecord top = getFocusedStack().topActivity(); 12624 if (top != caller) { 12625 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller 12626 + " is not current top " + top); 12627 return false; 12628 } 12629 if (!top.nowVisible) { 12630 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller 12631 + " is not visible"); 12632 return false; 12633 } 12634 } 12635 return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null, 12636 token); 12637 } finally { 12638 Binder.restoreCallingIdentity(ident); 12639 } 12640 } 12641 12642 @Override 12643 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver, 12644 Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) { 12645 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras, 12646 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null, 12647 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null; 12648 } 12649 12650 @Override 12651 public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras, 12652 IBinder activityToken) { 12653 // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread 12654 // rely on the flags to decide whether the handleRequestAssistContextExtras() is for 12655 // auto-fill, but it's safer to explicitly use new AutoFill types, in case the Assist 12656 // requests use flags in the future as well (since their flags value might collide with the 12657 // auto-fill flag values). 12658 return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTO_FILL, null, null, 12659 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(), 12660 null, PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT) != null; 12661 } 12662 12663 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, 12664 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, 12665 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) { 12666 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 12667 "enqueueAssistContext()"); 12668 12669 synchronized (this) { 12670 ActivityRecord activity = getFocusedStack().topActivity(); 12671 if (activity == null) { 12672 Slog.w(TAG, "getAssistContextExtras failed: no top activity"); 12673 return null; 12674 } 12675 if (activity.app == null || activity.app.thread == null) { 12676 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 12677 return null; 12678 } 12679 if (focused) { 12680 if (activityToken != null) { 12681 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken); 12682 if (activity != caller) { 12683 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller 12684 + " is not current top " + activity); 12685 return null; 12686 } 12687 } 12688 } else { 12689 activity = ActivityRecord.forTokenLocked(activityToken); 12690 if (activity == null) { 12691 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken 12692 + " couldn't be found"); 12693 return null; 12694 } 12695 } 12696 12697 PendingAssistExtras pae; 12698 Bundle extras = new Bundle(); 12699 if (args != null) { 12700 extras.putAll(args); 12701 } 12702 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 12703 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid); 12704 12705 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras, 12706 userHandle); 12707 12708 // Increment the sessionId if necessary 12709 if (newSessionId) { 12710 mViSessionId++; 12711 } 12712 try { 12713 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType, 12714 mViSessionId); 12715 mPendingAssistExtras.add(pae); 12716 mUiHandler.postDelayed(pae, timeout); 12717 } catch (RemoteException e) { 12718 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 12719 return null; 12720 } 12721 return pae; 12722 } 12723 } 12724 12725 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) { 12726 IResultReceiver receiver; 12727 synchronized (this) { 12728 mPendingAssistExtras.remove(pae); 12729 receiver = pae.receiver; 12730 } 12731 if (receiver != null) { 12732 // Caller wants result sent back to them. 12733 Bundle sendBundle = new Bundle(); 12734 // At least return the receiver extras 12735 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS, 12736 pae.receiverExtras); 12737 try { 12738 pae.receiver.send(0, sendBundle); 12739 } catch (RemoteException e) { 12740 } 12741 } 12742 } 12743 12744 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) { 12745 if (result != null) { 12746 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result); 12747 } 12748 if (pae.hint != null) { 12749 pae.extras.putBoolean(pae.hint, true); 12750 } 12751 } 12752 12753 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure, 12754 AssistContent content, Uri referrer) { 12755 PendingAssistExtras pae = (PendingAssistExtras)token; 12756 synchronized (pae) { 12757 pae.result = extras; 12758 pae.structure = structure; 12759 pae.content = content; 12760 if (referrer != null) { 12761 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer); 12762 } 12763 pae.haveResult = true; 12764 pae.notifyAll(); 12765 if (pae.intent == null && pae.receiver == null) { 12766 // Caller is just waiting for the result. 12767 return; 12768 } 12769 } 12770 12771 // We are now ready to launch the assist activity. 12772 IResultReceiver sendReceiver = null; 12773 Bundle sendBundle = null; 12774 synchronized (this) { 12775 buildAssistBundleLocked(pae, extras); 12776 boolean exists = mPendingAssistExtras.remove(pae); 12777 mUiHandler.removeCallbacks(pae); 12778 if (!exists) { 12779 // Timed out. 12780 return; 12781 } 12782 if ((sendReceiver=pae.receiver) != null) { 12783 // Caller wants result sent back to them. 12784 sendBundle = new Bundle(); 12785 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras); 12786 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure); 12787 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content); 12788 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS, 12789 pae.receiverExtras); 12790 } 12791 } 12792 if (sendReceiver != null) { 12793 try { 12794 sendReceiver.send(0, sendBundle); 12795 } catch (RemoteException e) { 12796 } 12797 return; 12798 } 12799 12800 long ident = Binder.clearCallingIdentity(); 12801 try { 12802 pae.intent.replaceExtras(pae.extras); 12803 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 12804 | Intent.FLAG_ACTIVITY_SINGLE_TOP 12805 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 12806 closeSystemDialogs("assist"); 12807 try { 12808 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); 12809 } catch (ActivityNotFoundException e) { 12810 Slog.w(TAG, "No activity to handle assist action.", e); 12811 } 12812 } finally { 12813 Binder.restoreCallingIdentity(ident); 12814 } 12815 } 12816 12817 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle, 12818 Bundle args) { 12819 return enqueueAssistContext(requestType, intent, hint, null, null, null, 12820 true /* focused */, true /* newSessionId */, userHandle, args, 12821 PENDING_ASSIST_EXTRAS_TIMEOUT) != null; 12822 } 12823 12824 public void registerProcessObserver(IProcessObserver observer) { 12825 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 12826 "registerProcessObserver()"); 12827 synchronized (this) { 12828 mProcessObservers.register(observer); 12829 } 12830 } 12831 12832 @Override 12833 public void unregisterProcessObserver(IProcessObserver observer) { 12834 synchronized (this) { 12835 mProcessObservers.unregister(observer); 12836 } 12837 } 12838 12839 @Override 12840 public void registerUidObserver(IUidObserver observer, int which, int cutpoint, 12841 String callingPackage) { 12842 if (!hasUsageStatsPermission(callingPackage)) { 12843 enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, 12844 "registerUidObserver"); 12845 } 12846 synchronized (this) { 12847 mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(), 12848 callingPackage, which, cutpoint)); 12849 } 12850 } 12851 12852 @Override 12853 public void unregisterUidObserver(IUidObserver observer) { 12854 synchronized (this) { 12855 mUidObservers.unregister(observer); 12856 } 12857 } 12858 12859 @Override 12860 public boolean convertFromTranslucent(IBinder token) { 12861 final long origId = Binder.clearCallingIdentity(); 12862 try { 12863 synchronized (this) { 12864 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 12865 if (r == null) { 12866 return false; 12867 } 12868 final boolean translucentChanged = r.changeWindowTranslucency(true); 12869 if (translucentChanged) { 12870 r.getStack().releaseBackgroundResources(r); 12871 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 12872 } 12873 mWindowManager.setAppFullscreen(token, true); 12874 return translucentChanged; 12875 } 12876 } finally { 12877 Binder.restoreCallingIdentity(origId); 12878 } 12879 } 12880 12881 @Override 12882 public boolean convertToTranslucent(IBinder token, Bundle options) { 12883 final long origId = Binder.clearCallingIdentity(); 12884 try { 12885 synchronized (this) { 12886 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 12887 if (r == null) { 12888 return false; 12889 } 12890 int index = r.task.mActivities.lastIndexOf(r); 12891 if (index > 0) { 12892 ActivityRecord under = r.task.mActivities.get(index - 1); 12893 under.returningOptions = ActivityOptions.fromBundle(options); 12894 } 12895 final boolean translucentChanged = r.changeWindowTranslucency(false); 12896 if (translucentChanged) { 12897 r.getStack().convertActivityToTranslucent(r); 12898 } 12899 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 12900 mWindowManager.setAppFullscreen(token, false); 12901 return translucentChanged; 12902 } 12903 } finally { 12904 Binder.restoreCallingIdentity(origId); 12905 } 12906 } 12907 12908 @Override 12909 public boolean requestVisibleBehind(IBinder token, boolean visible) { 12910 final long origId = Binder.clearCallingIdentity(); 12911 try { 12912 synchronized (this) { 12913 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 12914 if (r != null) { 12915 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 12916 } 12917 } 12918 return false; 12919 } finally { 12920 Binder.restoreCallingIdentity(origId); 12921 } 12922 } 12923 12924 @Override 12925 public boolean isBackgroundVisibleBehind(IBinder token) { 12926 final long origId = Binder.clearCallingIdentity(); 12927 try { 12928 synchronized (this) { 12929 final ActivityStack stack = ActivityRecord.getStackLocked(token); 12930 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 12931 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND, 12932 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 12933 return visible; 12934 } 12935 } finally { 12936 Binder.restoreCallingIdentity(origId); 12937 } 12938 } 12939 12940 @Override 12941 public Bundle getActivityOptions(IBinder token) { 12942 final long origId = Binder.clearCallingIdentity(); 12943 try { 12944 synchronized (this) { 12945 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 12946 if (r != null) { 12947 final ActivityOptions activityOptions = r.pendingOptions; 12948 r.pendingOptions = null; 12949 return activityOptions == null ? null : activityOptions.toBundle(); 12950 } 12951 return null; 12952 } 12953 } finally { 12954 Binder.restoreCallingIdentity(origId); 12955 } 12956 } 12957 12958 @Override 12959 public void setImmersive(IBinder token, boolean immersive) { 12960 synchronized(this) { 12961 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 12962 if (r == null) { 12963 throw new IllegalArgumentException(); 12964 } 12965 r.immersive = immersive; 12966 12967 // update associated state if we're frontmost 12968 if (r == mStackSupervisor.getResumedActivityLocked()) { 12969 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r); 12970 applyUpdateLockStateLocked(r); 12971 } 12972 } 12973 } 12974 12975 @Override 12976 public boolean isImmersive(IBinder token) { 12977 synchronized (this) { 12978 ActivityRecord r = ActivityRecord.isInStackLocked(token); 12979 if (r == null) { 12980 throw new IllegalArgumentException(); 12981 } 12982 return r.immersive; 12983 } 12984 } 12985 12986 public void setVrThread(int tid) { 12987 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { 12988 throw new UnsupportedOperationException("VR mode not supported on this device!"); 12989 } 12990 12991 synchronized (this) { 12992 ProcessRecord proc; 12993 synchronized (mPidsSelfLocked) { 12994 final int pid = Binder.getCallingPid(); 12995 proc = mPidsSelfLocked.get(pid); 12996 12997 if (proc != null && mInVrMode && tid >= 0) { 12998 // ensure the tid belongs to the process 12999 if (!Process.isThreadInProcess(pid, tid)) { 13000 throw new IllegalArgumentException("VR thread does not belong to process"); 13001 } 13002 13003 // reset existing VR thread to CFS if this thread still exists and belongs to 13004 // the calling process 13005 if (proc.vrThreadTid != 0 13006 && Process.isThreadInProcess(pid, proc.vrThreadTid)) { 13007 try { 13008 Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0); 13009 } catch (IllegalArgumentException e) { 13010 // Ignore this. Only occurs in race condition where previous VR thread 13011 // was destroyed during this method call. 13012 } 13013 } 13014 13015 proc.vrThreadTid = tid; 13016 13017 // promote to FIFO now if the tid is non-zero 13018 try { 13019 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && 13020 proc.vrThreadTid > 0) { 13021 Process.setThreadScheduler(proc.vrThreadTid, 13022 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); 13023 } 13024 } catch (IllegalArgumentException e) { 13025 Slog.e(TAG, "Failed to set scheduling policy, thread does" 13026 + " not exist:\n" + e); 13027 } 13028 } 13029 } 13030 } 13031 } 13032 13033 @Override 13034 public void setRenderThread(int tid) { 13035 synchronized (this) { 13036 ProcessRecord proc; 13037 synchronized (mPidsSelfLocked) { 13038 int pid = Binder.getCallingPid(); 13039 proc = mPidsSelfLocked.get(pid); 13040 if (proc != null && proc.renderThreadTid == 0 && tid > 0) { 13041 // ensure the tid belongs to the process 13042 if (!Process.isThreadInProcess(pid, tid)) { 13043 throw new IllegalArgumentException( 13044 "Render thread does not belong to process"); 13045 } 13046 proc.renderThreadTid = tid; 13047 if (DEBUG_OOM_ADJ) { 13048 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid); 13049 } 13050 // promote to FIFO now 13051 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { 13052 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band"); 13053 if (mUseFifoUiScheduling) { 13054 Process.setThreadScheduler(proc.renderThreadTid, 13055 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); 13056 } else { 13057 Process.setThreadPriority(proc.renderThreadTid, -10); 13058 } 13059 } 13060 } else { 13061 if (DEBUG_OOM_ADJ) { 13062 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " + 13063 "PID: " + pid + ", TID: " + tid + " FIFO: " + 13064 mUseFifoUiScheduling); 13065 } 13066 } 13067 } 13068 } 13069 } 13070 13071 @Override 13072 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) { 13073 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { 13074 throw new UnsupportedOperationException("VR mode not supported on this device!"); 13075 } 13076 13077 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 13078 13079 ActivityRecord r; 13080 synchronized (this) { 13081 r = ActivityRecord.isInStackLocked(token); 13082 } 13083 13084 if (r == null) { 13085 throw new IllegalArgumentException(); 13086 } 13087 13088 int err; 13089 if ((err = vrService.hasVrPackage(packageName, r.userId)) != 13090 VrManagerInternal.NO_ERROR) { 13091 return err; 13092 } 13093 13094 synchronized(this) { 13095 r.requestedVrComponent = (enabled) ? packageName : null; 13096 13097 // Update associated state if this activity is currently focused 13098 if (r == mStackSupervisor.getResumedActivityLocked()) { 13099 applyUpdateVrModeLocked(r); 13100 } 13101 return 0; 13102 } 13103 } 13104 13105 @Override 13106 public boolean isVrModePackageEnabled(ComponentName packageName) { 13107 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { 13108 throw new UnsupportedOperationException("VR mode not supported on this device!"); 13109 } 13110 13111 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 13112 13113 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) == 13114 VrManagerInternal.NO_ERROR; 13115 } 13116 13117 public boolean isTopActivityImmersive() { 13118 enforceNotIsolatedCaller("startActivity"); 13119 synchronized (this) { 13120 ActivityRecord r = getFocusedStack().topRunningActivityLocked(); 13121 return (r != null) ? r.immersive : false; 13122 } 13123 } 13124 13125 @Override 13126 public boolean isTopOfTask(IBinder token) { 13127 synchronized (this) { 13128 ActivityRecord r = ActivityRecord.isInStackLocked(token); 13129 if (r == null) { 13130 throw new IllegalArgumentException(); 13131 } 13132 return r.task.getTopActivity() == r; 13133 } 13134 } 13135 13136 @Override 13137 public void setHasTopUi(boolean hasTopUi) throws RemoteException { 13138 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) { 13139 String msg = "Permission Denial: setHasTopUi() from pid=" 13140 + Binder.getCallingPid() 13141 + ", uid=" + Binder.getCallingUid() 13142 + " requires " + permission.INTERNAL_SYSTEM_WINDOW; 13143 Slog.w(TAG, msg); 13144 throw new SecurityException(msg); 13145 } 13146 final int pid = Binder.getCallingPid(); 13147 final long origId = Binder.clearCallingIdentity(); 13148 try { 13149 synchronized (this) { 13150 boolean changed = false; 13151 ProcessRecord pr; 13152 synchronized (mPidsSelfLocked) { 13153 pr = mPidsSelfLocked.get(pid); 13154 if (pr == null) { 13155 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid); 13156 return; 13157 } 13158 if (pr.hasTopUi != hasTopUi) { 13159 Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid); 13160 pr.hasTopUi = hasTopUi; 13161 changed = true; 13162 } 13163 } 13164 if (changed) { 13165 updateOomAdjLocked(pr); 13166 } 13167 } 13168 } finally { 13169 Binder.restoreCallingIdentity(origId); 13170 } 13171 } 13172 13173 public final void enterSafeMode() { 13174 synchronized(this) { 13175 // It only makes sense to do this before the system is ready 13176 // and started launching other packages. 13177 if (!mSystemReady) { 13178 try { 13179 AppGlobals.getPackageManager().enterSafeMode(); 13180 } catch (RemoteException e) { 13181 } 13182 } 13183 13184 mSafeMode = true; 13185 } 13186 } 13187 13188 public final void showSafeModeOverlay() { 13189 View v = LayoutInflater.from(mContext).inflate( 13190 com.android.internal.R.layout.safe_mode, null); 13191 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 13192 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 13193 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 13194 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 13195 lp.gravity = Gravity.BOTTOM | Gravity.START; 13196 lp.format = v.getBackground().getOpacity(); 13197 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 13198 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 13199 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 13200 ((WindowManager)mContext.getSystemService( 13201 Context.WINDOW_SERVICE)).addView(v, lp); 13202 } 13203 13204 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) { 13205 if (sender != null && !(sender instanceof PendingIntentRecord)) { 13206 return; 13207 } 13208 final PendingIntentRecord rec = (PendingIntentRecord)sender; 13209 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13210 synchronized (stats) { 13211 if (mBatteryStatsService.isOnBattery()) { 13212 mBatteryStatsService.enforceCallingPermission(); 13213 int MY_UID = Binder.getCallingUid(); 13214 final int uid; 13215 if (sender == null) { 13216 uid = sourceUid; 13217 } else { 13218 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 13219 } 13220 BatteryStatsImpl.Uid.Pkg pkg = 13221 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 13222 sourcePkg != null ? sourcePkg : rec.key.packageName); 13223 pkg.noteWakeupAlarmLocked(tag); 13224 } 13225 } 13226 } 13227 13228 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) { 13229 if (sender != null && !(sender instanceof PendingIntentRecord)) { 13230 return; 13231 } 13232 final PendingIntentRecord rec = (PendingIntentRecord)sender; 13233 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13234 synchronized (stats) { 13235 mBatteryStatsService.enforceCallingPermission(); 13236 int MY_UID = Binder.getCallingUid(); 13237 final int uid; 13238 if (sender == null) { 13239 uid = sourceUid; 13240 } else { 13241 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 13242 } 13243 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid); 13244 } 13245 } 13246 13247 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) { 13248 if (sender != null && !(sender instanceof PendingIntentRecord)) { 13249 return; 13250 } 13251 final PendingIntentRecord rec = (PendingIntentRecord)sender; 13252 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13253 synchronized (stats) { 13254 mBatteryStatsService.enforceCallingPermission(); 13255 int MY_UID = Binder.getCallingUid(); 13256 final int uid; 13257 if (sender == null) { 13258 uid = sourceUid; 13259 } else { 13260 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 13261 } 13262 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid); 13263 } 13264 } 13265 13266 public boolean killPids(int[] pids, String pReason, boolean secure) { 13267 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 13268 throw new SecurityException("killPids only available to the system"); 13269 } 13270 String reason = (pReason == null) ? "Unknown" : pReason; 13271 // XXX Note: don't acquire main activity lock here, because the window 13272 // manager calls in with its locks held. 13273 13274 boolean killed = false; 13275 synchronized (mPidsSelfLocked) { 13276 int worstType = 0; 13277 for (int i=0; i<pids.length; i++) { 13278 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 13279 if (proc != null) { 13280 int type = proc.setAdj; 13281 if (type > worstType) { 13282 worstType = type; 13283 } 13284 } 13285 } 13286 13287 // If the worst oom_adj is somewhere in the cached proc LRU range, 13288 // then constrain it so we will kill all cached procs. 13289 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 13290 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 13291 worstType = ProcessList.CACHED_APP_MIN_ADJ; 13292 } 13293 13294 // If this is not a secure call, don't let it kill processes that 13295 // are important. 13296 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 13297 worstType = ProcessList.SERVICE_ADJ; 13298 } 13299 13300 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 13301 for (int i=0; i<pids.length; i++) { 13302 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 13303 if (proc == null) { 13304 continue; 13305 } 13306 int adj = proc.setAdj; 13307 if (adj >= worstType && !proc.killedByAm) { 13308 proc.kill(reason, true); 13309 killed = true; 13310 } 13311 } 13312 } 13313 return killed; 13314 } 13315 13316 @Override 13317 public void killUid(int appId, int userId, String reason) { 13318 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid"); 13319 synchronized (this) { 13320 final long identity = Binder.clearCallingIdentity(); 13321 try { 13322 killPackageProcessesLocked(null, appId, userId, 13323 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true, 13324 reason != null ? reason : "kill uid"); 13325 } finally { 13326 Binder.restoreCallingIdentity(identity); 13327 } 13328 } 13329 } 13330 13331 @Override 13332 public boolean killProcessesBelowForeground(String reason) { 13333 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 13334 throw new SecurityException("killProcessesBelowForeground() only available to system"); 13335 } 13336 13337 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 13338 } 13339 13340 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 13341 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 13342 throw new SecurityException("killProcessesBelowAdj() only available to system"); 13343 } 13344 13345 boolean killed = false; 13346 synchronized (mPidsSelfLocked) { 13347 final int size = mPidsSelfLocked.size(); 13348 for (int i = 0; i < size; i++) { 13349 final int pid = mPidsSelfLocked.keyAt(i); 13350 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 13351 if (proc == null) continue; 13352 13353 final int adj = proc.setAdj; 13354 if (adj > belowAdj && !proc.killedByAm) { 13355 proc.kill(reason, true); 13356 killed = true; 13357 } 13358 } 13359 } 13360 return killed; 13361 } 13362 13363 @Override 13364 public void hang(final IBinder who, boolean allowRestart) { 13365 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13366 != PackageManager.PERMISSION_GRANTED) { 13367 throw new SecurityException("Requires permission " 13368 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13369 } 13370 13371 final IBinder.DeathRecipient death = new DeathRecipient() { 13372 @Override 13373 public void binderDied() { 13374 synchronized (this) { 13375 notifyAll(); 13376 } 13377 } 13378 }; 13379 13380 try { 13381 who.linkToDeath(death, 0); 13382 } catch (RemoteException e) { 13383 Slog.w(TAG, "hang: given caller IBinder is already dead."); 13384 return; 13385 } 13386 13387 synchronized (this) { 13388 Watchdog.getInstance().setAllowRestart(allowRestart); 13389 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 13390 synchronized (death) { 13391 while (who.isBinderAlive()) { 13392 try { 13393 death.wait(); 13394 } catch (InterruptedException e) { 13395 } 13396 } 13397 } 13398 Watchdog.getInstance().setAllowRestart(true); 13399 } 13400 } 13401 13402 @Override 13403 public void restart() { 13404 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13405 != PackageManager.PERMISSION_GRANTED) { 13406 throw new SecurityException("Requires permission " 13407 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13408 } 13409 13410 Log.i(TAG, "Sending shutdown broadcast..."); 13411 13412 BroadcastReceiver br = new BroadcastReceiver() { 13413 @Override public void onReceive(Context context, Intent intent) { 13414 // Now the broadcast is done, finish up the low-level shutdown. 13415 Log.i(TAG, "Shutting down activity manager..."); 13416 shutdown(10000); 13417 Log.i(TAG, "Shutdown complete, restarting!"); 13418 Process.killProcess(Process.myPid()); 13419 System.exit(10); 13420 } 13421 }; 13422 13423 // First send the high-level shut down broadcast. 13424 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 13425 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 13426 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 13427 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 13428 mContext.sendOrderedBroadcastAsUser(intent, 13429 UserHandle.ALL, null, br, mHandler, 0, null, null); 13430 */ 13431 br.onReceive(mContext, intent); 13432 } 13433 13434 private long getLowRamTimeSinceIdle(long now) { 13435 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 13436 } 13437 13438 @Override 13439 public void performIdleMaintenance() { 13440 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13441 != PackageManager.PERMISSION_GRANTED) { 13442 throw new SecurityException("Requires permission " 13443 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13444 } 13445 13446 synchronized (this) { 13447 final long now = SystemClock.uptimeMillis(); 13448 final long timeSinceLastIdle = now - mLastIdleTime; 13449 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 13450 mLastIdleTime = now; 13451 mLowRamTimeSinceLastIdle = 0; 13452 if (mLowRamStartTime != 0) { 13453 mLowRamStartTime = now; 13454 } 13455 13456 StringBuilder sb = new StringBuilder(128); 13457 sb.append("Idle maintenance over "); 13458 TimeUtils.formatDuration(timeSinceLastIdle, sb); 13459 sb.append(" low RAM for "); 13460 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 13461 Slog.i(TAG, sb.toString()); 13462 13463 // If at least 1/3 of our time since the last idle period has been spent 13464 // with RAM low, then we want to kill processes. 13465 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 13466 13467 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13468 ProcessRecord proc = mLruProcesses.get(i); 13469 if (proc.notCachedSinceIdle) { 13470 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING 13471 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 13472 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 13473 if (doKilling && proc.initialIdlePss != 0 13474 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 13475 sb = new StringBuilder(128); 13476 sb.append("Kill"); 13477 sb.append(proc.processName); 13478 sb.append(" in idle maint: pss="); 13479 sb.append(proc.lastPss); 13480 sb.append(", swapPss="); 13481 sb.append(proc.lastSwapPss); 13482 sb.append(", initialPss="); 13483 sb.append(proc.initialIdlePss); 13484 sb.append(", period="); 13485 TimeUtils.formatDuration(timeSinceLastIdle, sb); 13486 sb.append(", lowRamPeriod="); 13487 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 13488 Slog.wtfQuiet(TAG, sb.toString()); 13489 proc.kill("idle maint (pss " + proc.lastPss 13490 + " from " + proc.initialIdlePss + ")", true); 13491 } 13492 } 13493 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME 13494 && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) { 13495 proc.notCachedSinceIdle = true; 13496 proc.initialIdlePss = 0; 13497 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true, 13498 mTestPssMode, isSleepingLocked(), now); 13499 } 13500 } 13501 13502 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 13503 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 13504 } 13505 } 13506 13507 @Override 13508 public void sendIdleJobTrigger() { 13509 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 13510 != PackageManager.PERMISSION_GRANTED) { 13511 throw new SecurityException("Requires permission " 13512 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 13513 } 13514 13515 final long ident = Binder.clearCallingIdentity(); 13516 try { 13517 Intent intent = new Intent(ACTION_TRIGGER_IDLE) 13518 .setPackage("android") 13519 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13520 broadcastIntent(null, intent, null, null, 0, null, null, null, 13521 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL); 13522 } finally { 13523 Binder.restoreCallingIdentity(ident); 13524 } 13525 } 13526 13527 private void retrieveSettings() { 13528 final ContentResolver resolver = mContext.getContentResolver(); 13529 final boolean freeformWindowManagement = 13530 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT) 13531 || Settings.Global.getInt( 13532 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0; 13533 final boolean supportsPictureInPicture = 13534 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); 13535 13536 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(); 13537 final boolean supportsSplitScreenMultiWindow = 13538 ActivityManager.supportsSplitScreenMultiWindow(); 13539 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP); 13540 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0; 13541 final boolean alwaysFinishActivities = 13542 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0; 13543 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0; 13544 final boolean forceResizable = Settings.Global.getInt( 13545 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0; 13546 final boolean supportsLeanbackOnly = 13547 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY); 13548 13549 // Transfer any global setting for forcing RTL layout, into a System Property 13550 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 13551 13552 final Configuration configuration = new Configuration(); 13553 Settings.System.getConfiguration(resolver, configuration); 13554 if (forceRtl) { 13555 // This will take care of setting the correct layout direction flags 13556 configuration.setLayoutDirection(configuration.locale); 13557 } 13558 13559 synchronized (this) { 13560 mDebugApp = mOrigDebugApp = debugApp; 13561 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 13562 mAlwaysFinishActivities = alwaysFinishActivities; 13563 mSupportsLeanbackOnly = supportsLeanbackOnly; 13564 mForceResizableActivities = forceResizable; 13565 if (supportsMultiWindow || forceResizable) { 13566 mSupportsMultiWindow = true; 13567 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable; 13568 } else { 13569 mSupportsMultiWindow = false; 13570 mSupportsFreeformWindowManagement = false; 13571 } 13572 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow; 13573 mSupportsPictureInPicture = supportsPictureInPicture; 13574 mWindowManager.setForceResizableTasks(mForceResizableActivities); 13575 mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture); 13576 // This happens before any activities are started, so we can change global configuration 13577 // in-place. 13578 updateConfigurationLocked(configuration, null, true); 13579 final Configuration globalConfig = getGlobalConfiguration(); 13580 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig); 13581 13582 // Load resources only after the current configuration has been set. 13583 final Resources res = mContext.getResources(); 13584 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 13585 mThumbnailWidth = res.getDimensionPixelSize( 13586 com.android.internal.R.dimen.thumbnail_width); 13587 mThumbnailHeight = res.getDimensionPixelSize( 13588 com.android.internal.R.dimen.thumbnail_height); 13589 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString( 13590 com.android.internal.R.string.config_appsNotReportingCrashes)); 13591 mUserController.mUserSwitchUiEnabled = !res.getBoolean( 13592 com.android.internal.R.bool.config_customUserSwitchUi); 13593 if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) { 13594 mFullscreenThumbnailScale = (float) res 13595 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) / 13596 (float) globalConfig.screenWidthDp; 13597 } else { 13598 mFullscreenThumbnailScale = res.getFraction( 13599 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1); 13600 } 13601 } 13602 } 13603 13604 public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) { 13605 traceLog.traceBegin("PhaseActivityManagerReady"); 13606 synchronized(this) { 13607 if (mSystemReady) { 13608 // If we're done calling all the receivers, run the next "boot phase" passed in 13609 // by the SystemServer 13610 if (goingCallback != null) { 13611 goingCallback.run(); 13612 } 13613 return; 13614 } 13615 13616 mLocalDeviceIdleController 13617 = LocalServices.getService(DeviceIdleController.LocalService.class); 13618 mAssistUtils = new AssistUtils(mContext); 13619 13620 // Make sure we have the current profile info, since it is needed for security checks. 13621 mUserController.onSystemReady(); 13622 mRecentTasks.onSystemReadyLocked(); 13623 mAppOpsService.systemReady(); 13624 mSystemReady = true; 13625 } 13626 13627 ArrayList<ProcessRecord> procsToKill = null; 13628 synchronized(mPidsSelfLocked) { 13629 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 13630 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 13631 if (!isAllowedWhileBooting(proc.info)){ 13632 if (procsToKill == null) { 13633 procsToKill = new ArrayList<ProcessRecord>(); 13634 } 13635 procsToKill.add(proc); 13636 } 13637 } 13638 } 13639 13640 synchronized(this) { 13641 if (procsToKill != null) { 13642 for (int i=procsToKill.size()-1; i>=0; i--) { 13643 ProcessRecord proc = procsToKill.get(i); 13644 Slog.i(TAG, "Removing system update proc: " + proc); 13645 removeProcessLocked(proc, true, false, "system update done"); 13646 } 13647 } 13648 13649 // Now that we have cleaned up any update processes, we 13650 // are ready to start launching real processes and know that 13651 // we won't trample on them any more. 13652 mProcessesReady = true; 13653 } 13654 13655 Slog.i(TAG, "System now ready"); 13656 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 13657 SystemClock.uptimeMillis()); 13658 13659 synchronized(this) { 13660 // Make sure we have no pre-ready processes sitting around. 13661 13662 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 13663 ResolveInfo ri = mContext.getPackageManager() 13664 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 13665 STOCK_PM_FLAGS); 13666 CharSequence errorMsg = null; 13667 if (ri != null) { 13668 ActivityInfo ai = ri.activityInfo; 13669 ApplicationInfo app = ai.applicationInfo; 13670 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 13671 mTopAction = Intent.ACTION_FACTORY_TEST; 13672 mTopData = null; 13673 mTopComponent = new ComponentName(app.packageName, 13674 ai.name); 13675 } else { 13676 errorMsg = mContext.getResources().getText( 13677 com.android.internal.R.string.factorytest_not_system); 13678 } 13679 } else { 13680 errorMsg = mContext.getResources().getText( 13681 com.android.internal.R.string.factorytest_no_action); 13682 } 13683 if (errorMsg != null) { 13684 mTopAction = null; 13685 mTopData = null; 13686 mTopComponent = null; 13687 Message msg = Message.obtain(); 13688 msg.what = SHOW_FACTORY_ERROR_UI_MSG; 13689 msg.getData().putCharSequence("msg", errorMsg); 13690 mUiHandler.sendMessage(msg); 13691 } 13692 } 13693 } 13694 13695 retrieveSettings(); 13696 final int currentUserId; 13697 synchronized (this) { 13698 currentUserId = mUserController.getCurrentUserIdLocked(); 13699 readGrantedUriPermissionsLocked(); 13700 } 13701 13702 if (goingCallback != null) goingCallback.run(); 13703 traceLog.traceBegin("ActivityManagerStartApps"); 13704 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 13705 Integer.toString(currentUserId), currentUserId); 13706 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 13707 Integer.toString(currentUserId), currentUserId); 13708 mSystemServiceManager.startUser(currentUserId); 13709 13710 synchronized (this) { 13711 // Only start up encryption-aware persistent apps; once user is 13712 // unlocked we'll come back around and start unaware apps 13713 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); 13714 13715 // Start up initial activity. 13716 mBooting = true; 13717 // Enable home activity for system user, so that the system can always boot. We don't 13718 // do this when the system user is not setup since the setup wizard should be the one 13719 // to handle home activity in this case. 13720 if (UserManager.isSplitSystemUser() && 13721 Settings.Secure.getInt(mContext.getContentResolver(), 13722 Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) { 13723 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class); 13724 try { 13725 AppGlobals.getPackageManager().setComponentEnabledSetting(cName, 13726 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0, 13727 UserHandle.USER_SYSTEM); 13728 } catch (RemoteException e) { 13729 throw e.rethrowAsRuntimeException(); 13730 } 13731 } 13732 startHomeActivityLocked(currentUserId, "systemReady"); 13733 13734 try { 13735 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 13736 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" 13737 + " data partition or your device will be unstable."); 13738 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget(); 13739 } 13740 } catch (RemoteException e) { 13741 } 13742 13743 if (!Build.isBuildConsistent()) { 13744 Slog.e(TAG, "Build fingerprint is not consistent, warning user"); 13745 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget(); 13746 } 13747 13748 long ident = Binder.clearCallingIdentity(); 13749 try { 13750 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 13751 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 13752 | Intent.FLAG_RECEIVER_FOREGROUND); 13753 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); 13754 broadcastIntentLocked(null, null, intent, 13755 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 13756 null, false, false, MY_PID, Process.SYSTEM_UID, 13757 currentUserId); 13758 intent = new Intent(Intent.ACTION_USER_STARTING); 13759 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13760 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); 13761 broadcastIntentLocked(null, null, intent, 13762 null, new IIntentReceiver.Stub() { 13763 @Override 13764 public void performReceive(Intent intent, int resultCode, String data, 13765 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 13766 throws RemoteException { 13767 } 13768 }, 0, null, null, 13769 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE, 13770 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 13771 } catch (Throwable t) { 13772 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 13773 } finally { 13774 Binder.restoreCallingIdentity(ident); 13775 } 13776 mStackSupervisor.resumeFocusedStackTopActivityLocked(); 13777 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId); 13778 traceLog.traceEnd(); // ActivityManagerStartApps 13779 traceLog.traceEnd(); // PhaseActivityManagerReady 13780 } 13781 } 13782 13783 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 13784 synchronized (this) { 13785 mAppErrors.killAppAtUserRequestLocked(app, fromDialog); 13786 } 13787 } 13788 13789 void skipCurrentReceiverLocked(ProcessRecord app) { 13790 for (BroadcastQueue queue : mBroadcastQueues) { 13791 queue.skipCurrentReceiverLocked(app); 13792 } 13793 } 13794 13795 /** 13796 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 13797 * The application process will exit immediately after this call returns. 13798 * @param app object of the crashing app, null for the system server 13799 * @param crashInfo describing the exception 13800 */ 13801 public void handleApplicationCrash(IBinder app, 13802 ApplicationErrorReport.ParcelableCrashInfo crashInfo) { 13803 ProcessRecord r = findAppProcess(app, "Crash"); 13804 final String processName = app == null ? "system_server" 13805 : (r == null ? "unknown" : r.processName); 13806 13807 handleApplicationCrashInner("crash", r, processName, crashInfo); 13808 } 13809 13810 /* Native crash reporting uses this inner version because it needs to be somewhat 13811 * decoupled from the AM-managed cleanup lifecycle 13812 */ 13813 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 13814 ApplicationErrorReport.CrashInfo crashInfo) { 13815 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 13816 UserHandle.getUserId(Binder.getCallingUid()), processName, 13817 r == null ? -1 : r.info.flags, 13818 crashInfo.exceptionClassName, 13819 crashInfo.exceptionMessage, 13820 crashInfo.throwFileName, 13821 crashInfo.throwLineNumber); 13822 13823 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 13824 13825 mAppErrors.crashApplication(r, crashInfo); 13826 } 13827 13828 public void handleApplicationStrictModeViolation( 13829 IBinder app, 13830 int violationMask, 13831 StrictMode.ViolationInfo info) { 13832 ProcessRecord r = findAppProcess(app, "StrictMode"); 13833 if (r == null) { 13834 return; 13835 } 13836 13837 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 13838 Integer stackFingerprint = info.hashCode(); 13839 boolean logIt = true; 13840 synchronized (mAlreadyLoggedViolatedStacks) { 13841 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 13842 logIt = false; 13843 // TODO: sub-sample into EventLog for these, with 13844 // the info.durationMillis? Then we'd get 13845 // the relative pain numbers, without logging all 13846 // the stack traces repeatedly. We'd want to do 13847 // likewise in the client code, which also does 13848 // dup suppression, before the Binder call. 13849 } else { 13850 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 13851 mAlreadyLoggedViolatedStacks.clear(); 13852 } 13853 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 13854 } 13855 } 13856 if (logIt) { 13857 logStrictModeViolationToDropBox(r, info); 13858 } 13859 } 13860 13861 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 13862 AppErrorResult result = new AppErrorResult(); 13863 synchronized (this) { 13864 final long origId = Binder.clearCallingIdentity(); 13865 13866 Message msg = Message.obtain(); 13867 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG; 13868 HashMap<String, Object> data = new HashMap<String, Object>(); 13869 data.put("result", result); 13870 data.put("app", r); 13871 data.put("violationMask", violationMask); 13872 data.put("info", info); 13873 msg.obj = data; 13874 mUiHandler.sendMessage(msg); 13875 13876 Binder.restoreCallingIdentity(origId); 13877 } 13878 int res = result.get(); 13879 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 13880 } 13881 } 13882 13883 // Depending on the policy in effect, there could be a bunch of 13884 // these in quick succession so we try to batch these together to 13885 // minimize disk writes, number of dropbox entries, and maximize 13886 // compression, by having more fewer, larger records. 13887 private void logStrictModeViolationToDropBox( 13888 ProcessRecord process, 13889 StrictMode.ViolationInfo info) { 13890 if (info == null) { 13891 return; 13892 } 13893 final boolean isSystemApp = process == null || 13894 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 13895 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 13896 final String processName = process == null ? "unknown" : process.processName; 13897 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 13898 final DropBoxManager dbox = (DropBoxManager) 13899 mContext.getSystemService(Context.DROPBOX_SERVICE); 13900 13901 // Exit early if the dropbox isn't configured to accept this report type. 13902 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 13903 13904 boolean bufferWasEmpty; 13905 boolean needsFlush; 13906 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 13907 synchronized (sb) { 13908 bufferWasEmpty = sb.length() == 0; 13909 appendDropBoxProcessHeaders(process, processName, sb); 13910 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 13911 sb.append("System-App: ").append(isSystemApp).append("\n"); 13912 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 13913 if (info.violationNumThisLoop != 0) { 13914 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 13915 } 13916 if (info.numAnimationsRunning != 0) { 13917 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 13918 } 13919 if (info.broadcastIntentAction != null) { 13920 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 13921 } 13922 if (info.durationMillis != -1) { 13923 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 13924 } 13925 if (info.numInstances != -1) { 13926 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 13927 } 13928 if (info.tags != null) { 13929 for (String tag : info.tags) { 13930 sb.append("Span-Tag: ").append(tag).append("\n"); 13931 } 13932 } 13933 sb.append("\n"); 13934 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 13935 sb.append(info.crashInfo.stackTrace); 13936 sb.append("\n"); 13937 } 13938 if (info.message != null) { 13939 sb.append(info.message); 13940 sb.append("\n"); 13941 } 13942 13943 // Only buffer up to ~64k. Various logging bits truncate 13944 // things at 128k. 13945 needsFlush = (sb.length() > 64 * 1024); 13946 } 13947 13948 // Flush immediately if the buffer's grown too large, or this 13949 // is a non-system app. Non-system apps are isolated with a 13950 // different tag & policy and not batched. 13951 // 13952 // Batching is useful during internal testing with 13953 // StrictMode settings turned up high. Without batching, 13954 // thousands of separate files could be created on boot. 13955 if (!isSystemApp || needsFlush) { 13956 new Thread("Error dump: " + dropboxTag) { 13957 @Override 13958 public void run() { 13959 String report; 13960 synchronized (sb) { 13961 report = sb.toString(); 13962 sb.delete(0, sb.length()); 13963 sb.trimToSize(); 13964 } 13965 if (report.length() != 0) { 13966 dbox.addText(dropboxTag, report); 13967 } 13968 } 13969 }.start(); 13970 return; 13971 } 13972 13973 // System app batching: 13974 if (!bufferWasEmpty) { 13975 // An existing dropbox-writing thread is outstanding, so 13976 // we don't need to start it up. The existing thread will 13977 // catch the buffer appends we just did. 13978 return; 13979 } 13980 13981 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 13982 // (After this point, we shouldn't access AMS internal data structures.) 13983 new Thread("Error dump: " + dropboxTag) { 13984 @Override 13985 public void run() { 13986 // 5 second sleep to let stacks arrive and be batched together 13987 try { 13988 Thread.sleep(5000); // 5 seconds 13989 } catch (InterruptedException e) {} 13990 13991 String errorReport; 13992 synchronized (mStrictModeBuffer) { 13993 errorReport = mStrictModeBuffer.toString(); 13994 if (errorReport.length() == 0) { 13995 return; 13996 } 13997 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 13998 mStrictModeBuffer.trimToSize(); 13999 } 14000 dbox.addText(dropboxTag, errorReport); 14001 } 14002 }.start(); 14003 } 14004 14005 /** 14006 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 14007 * @param app object of the crashing app, null for the system server 14008 * @param tag reported by the caller 14009 * @param system whether this wtf is coming from the system 14010 * @param crashInfo describing the context of the error 14011 * @return true if the process should exit immediately (WTF is fatal) 14012 */ 14013 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 14014 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) { 14015 final int callingUid = Binder.getCallingUid(); 14016 final int callingPid = Binder.getCallingPid(); 14017 14018 if (system) { 14019 // If this is coming from the system, we could very well have low-level 14020 // system locks held, so we want to do this all asynchronously. And we 14021 // never want this to become fatal, so there is that too. 14022 mHandler.post(new Runnable() { 14023 @Override public void run() { 14024 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 14025 } 14026 }); 14027 return false; 14028 } 14029 14030 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 14031 crashInfo); 14032 14033 final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global 14034 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0; 14035 final boolean isSystem = (r == null) || r.persistent; 14036 14037 if (isFatal && !isSystem) { 14038 mAppErrors.crashApplication(r, crashInfo); 14039 return true; 14040 } else { 14041 return false; 14042 } 14043 } 14044 14045 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 14046 final ApplicationErrorReport.CrashInfo crashInfo) { 14047 final ProcessRecord r = findAppProcess(app, "WTF"); 14048 final String processName = app == null ? "system_server" 14049 : (r == null ? "unknown" : r.processName); 14050 14051 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 14052 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 14053 14054 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 14055 14056 return r; 14057 } 14058 14059 /** 14060 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 14061 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 14062 */ 14063 private ProcessRecord findAppProcess(IBinder app, String reason) { 14064 if (app == null) { 14065 return null; 14066 } 14067 14068 synchronized (this) { 14069 final int NP = mProcessNames.getMap().size(); 14070 for (int ip=0; ip<NP; ip++) { 14071 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 14072 final int NA = apps.size(); 14073 for (int ia=0; ia<NA; ia++) { 14074 ProcessRecord p = apps.valueAt(ia); 14075 if (p.thread != null && p.thread.asBinder() == app) { 14076 return p; 14077 } 14078 } 14079 } 14080 14081 Slog.w(TAG, "Can't find mystery application for " + reason 14082 + " from pid=" + Binder.getCallingPid() 14083 + " uid=" + Binder.getCallingUid() + ": " + app); 14084 return null; 14085 } 14086 } 14087 14088 /** 14089 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 14090 * to append various headers to the dropbox log text. 14091 */ 14092 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 14093 StringBuilder sb) { 14094 // Watchdog thread ends up invoking this function (with 14095 // a null ProcessRecord) to add the stack file to dropbox. 14096 // Do not acquire a lock on this (am) in such cases, as it 14097 // could cause a potential deadlock, if and when watchdog 14098 // is invoked due to unavailability of lock on am and it 14099 // would prevent watchdog from killing system_server. 14100 if (process == null) { 14101 sb.append("Process: ").append(processName).append("\n"); 14102 return; 14103 } 14104 // Note: ProcessRecord 'process' is guarded by the service 14105 // instance. (notably process.pkgList, which could otherwise change 14106 // concurrently during execution of this method) 14107 synchronized (this) { 14108 sb.append("Process: ").append(processName).append("\n"); 14109 int flags = process.info.flags; 14110 IPackageManager pm = AppGlobals.getPackageManager(); 14111 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n"); 14112 for (int ip=0; ip<process.pkgList.size(); ip++) { 14113 String pkg = process.pkgList.keyAt(ip); 14114 sb.append("Package: ").append(pkg); 14115 try { 14116 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 14117 if (pi != null) { 14118 sb.append(" v").append(pi.versionCode); 14119 if (pi.versionName != null) { 14120 sb.append(" (").append(pi.versionName).append(")"); 14121 } 14122 } 14123 } catch (RemoteException e) { 14124 Slog.e(TAG, "Error getting package info: " + pkg, e); 14125 } 14126 sb.append("\n"); 14127 } 14128 } 14129 } 14130 14131 private static String processClass(ProcessRecord process) { 14132 if (process == null || process.pid == MY_PID) { 14133 return "system_server"; 14134 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 14135 return "system_app"; 14136 } else { 14137 return "data_app"; 14138 } 14139 } 14140 14141 private volatile long mWtfClusterStart; 14142 private volatile int mWtfClusterCount; 14143 14144 /** 14145 * Write a description of an error (crash, WTF, ANR) to the drop box. 14146 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 14147 * @param process which caused the error, null means the system server 14148 * @param activity which triggered the error, null if unknown 14149 * @param parent activity related to the error, null if unknown 14150 * @param subject line related to the error, null if absent 14151 * @param report in long form describing the error, null if absent 14152 * @param dataFile text file to include in the report, null if none 14153 * @param crashInfo giving an application stack trace, null if absent 14154 */ 14155 public void addErrorToDropBox(String eventType, 14156 ProcessRecord process, String processName, ActivityRecord activity, 14157 ActivityRecord parent, String subject, 14158 final String report, final File dataFile, 14159 final ApplicationErrorReport.CrashInfo crashInfo) { 14160 // NOTE -- this must never acquire the ActivityManagerService lock, 14161 // otherwise the watchdog may be prevented from resetting the system. 14162 14163 // Bail early if not published yet 14164 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return; 14165 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class); 14166 14167 // Exit early if the dropbox isn't configured to accept this report type. 14168 final String dropboxTag = processClass(process) + "_" + eventType; 14169 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 14170 14171 // Rate-limit how often we're willing to do the heavy lifting below to 14172 // collect and record logs; currently 5 logs per 10 second period. 14173 final long now = SystemClock.elapsedRealtime(); 14174 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) { 14175 mWtfClusterStart = now; 14176 mWtfClusterCount = 1; 14177 } else { 14178 if (mWtfClusterCount++ >= 5) return; 14179 } 14180 14181 final StringBuilder sb = new StringBuilder(1024); 14182 appendDropBoxProcessHeaders(process, processName, sb); 14183 if (process != null) { 14184 sb.append("Foreground: ") 14185 .append(process.isInterestingToUserLocked() ? "Yes" : "No") 14186 .append("\n"); 14187 } 14188 if (activity != null) { 14189 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 14190 } 14191 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 14192 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 14193 } 14194 if (parent != null && parent != activity) { 14195 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 14196 } 14197 if (subject != null) { 14198 sb.append("Subject: ").append(subject).append("\n"); 14199 } 14200 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 14201 if (Debug.isDebuggerConnected()) { 14202 sb.append("Debugger: Connected\n"); 14203 } 14204 sb.append("\n"); 14205 14206 // Do the rest in a worker thread to avoid blocking the caller on I/O 14207 // (After this point, we shouldn't access AMS internal data structures.) 14208 Thread worker = new Thread("Error dump: " + dropboxTag) { 14209 @Override 14210 public void run() { 14211 if (report != null) { 14212 sb.append(report); 14213 } 14214 14215 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 14216 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 14217 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length() 14218 - lines * RESERVED_BYTES_PER_LOGCAT_LINE; 14219 14220 if (dataFile != null && maxDataFileSize > 0) { 14221 try { 14222 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize, 14223 "\n\n[[TRUNCATED]]")); 14224 } catch (IOException e) { 14225 Slog.e(TAG, "Error reading " + dataFile, e); 14226 } 14227 } 14228 if (crashInfo != null && crashInfo.stackTrace != null) { 14229 sb.append(crashInfo.stackTrace); 14230 } 14231 14232 if (lines > 0) { 14233 sb.append("\n"); 14234 14235 // Merge several logcat streams, and take the last N lines 14236 InputStreamReader input = null; 14237 try { 14238 java.lang.Process logcat = new ProcessBuilder( 14239 "/system/bin/timeout", "-k", "15s", "10s", 14240 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system", 14241 "-b", "main", "-b", "crash", "-t", String.valueOf(lines)) 14242 .redirectErrorStream(true).start(); 14243 14244 try { logcat.getOutputStream().close(); } catch (IOException e) {} 14245 try { logcat.getErrorStream().close(); } catch (IOException e) {} 14246 input = new InputStreamReader(logcat.getInputStream()); 14247 14248 int num; 14249 char[] buf = new char[8192]; 14250 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 14251 } catch (IOException e) { 14252 Slog.e(TAG, "Error running logcat", e); 14253 } finally { 14254 if (input != null) try { input.close(); } catch (IOException e) {} 14255 } 14256 } 14257 14258 dbox.addText(dropboxTag, sb.toString()); 14259 } 14260 }; 14261 14262 if (process == null) { 14263 // If process is null, we are being called from some internal code 14264 // and may be about to die -- run this synchronously. 14265 worker.run(); 14266 } else { 14267 worker.start(); 14268 } 14269 } 14270 14271 @Override 14272 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 14273 enforceNotIsolatedCaller("getProcessesInErrorState"); 14274 // assume our apps are happy - lazy create the list 14275 List<ActivityManager.ProcessErrorStateInfo> errList = null; 14276 14277 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 14278 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 14279 int userId = UserHandle.getUserId(Binder.getCallingUid()); 14280 14281 synchronized (this) { 14282 14283 // iterate across all processes 14284 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14285 ProcessRecord app = mLruProcesses.get(i); 14286 if (!allUsers && app.userId != userId) { 14287 continue; 14288 } 14289 if ((app.thread != null) && (app.crashing || app.notResponding)) { 14290 // This one's in trouble, so we'll generate a report for it 14291 // crashes are higher priority (in case there's a crash *and* an anr) 14292 ActivityManager.ProcessErrorStateInfo report = null; 14293 if (app.crashing) { 14294 report = app.crashingReport; 14295 } else if (app.notResponding) { 14296 report = app.notRespondingReport; 14297 } 14298 14299 if (report != null) { 14300 if (errList == null) { 14301 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 14302 } 14303 errList.add(report); 14304 } else { 14305 Slog.w(TAG, "Missing app error report, app = " + app.processName + 14306 " crashing = " + app.crashing + 14307 " notResponding = " + app.notResponding); 14308 } 14309 } 14310 } 14311 } 14312 14313 return errList; 14314 } 14315 14316 static int procStateToImportance(int procState, int memAdj, 14317 ActivityManager.RunningAppProcessInfo currApp) { 14318 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 14319 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 14320 currApp.lru = memAdj; 14321 } else { 14322 currApp.lru = 0; 14323 } 14324 return imp; 14325 } 14326 14327 private void fillInProcMemInfo(ProcessRecord app, 14328 ActivityManager.RunningAppProcessInfo outInfo) { 14329 outInfo.pid = app.pid; 14330 outInfo.uid = app.info.uid; 14331 if (mHeavyWeightProcess == app) { 14332 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 14333 } 14334 if (app.persistent) { 14335 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 14336 } 14337 if (app.activities.size() > 0) { 14338 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 14339 } 14340 outInfo.lastTrimLevel = app.trimMemoryLevel; 14341 int adj = app.curAdj; 14342 int procState = app.curProcState; 14343 outInfo.importance = procStateToImportance(procState, adj, outInfo); 14344 outInfo.importanceReasonCode = app.adjTypeCode; 14345 outInfo.processState = app.curProcState; 14346 } 14347 14348 @Override 14349 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 14350 enforceNotIsolatedCaller("getRunningAppProcesses"); 14351 14352 final int callingUid = Binder.getCallingUid(); 14353 14354 // Lazy instantiation of list 14355 List<ActivityManager.RunningAppProcessInfo> runList = null; 14356 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 14357 callingUid) == PackageManager.PERMISSION_GRANTED; 14358 final int userId = UserHandle.getUserId(callingUid); 14359 final boolean allUids = isGetTasksAllowed( 14360 "getRunningAppProcesses", Binder.getCallingPid(), callingUid); 14361 14362 synchronized (this) { 14363 // Iterate across all processes 14364 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 14365 ProcessRecord app = mLruProcesses.get(i); 14366 if ((!allUsers && app.userId != userId) 14367 || (!allUids && app.uid != callingUid)) { 14368 continue; 14369 } 14370 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 14371 // Generate process state info for running application 14372 ActivityManager.RunningAppProcessInfo currApp = 14373 new ActivityManager.RunningAppProcessInfo(app.processName, 14374 app.pid, app.getPackageList()); 14375 fillInProcMemInfo(app, currApp); 14376 if (app.adjSource instanceof ProcessRecord) { 14377 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 14378 currApp.importanceReasonImportance = 14379 ActivityManager.RunningAppProcessInfo.procStateToImportance( 14380 app.adjSourceProcState); 14381 } else if (app.adjSource instanceof ActivityRecord) { 14382 ActivityRecord r = (ActivityRecord)app.adjSource; 14383 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 14384 } 14385 if (app.adjTarget instanceof ComponentName) { 14386 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 14387 } 14388 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 14389 // + " lru=" + currApp.lru); 14390 if (runList == null) { 14391 runList = new ArrayList<>(); 14392 } 14393 runList.add(currApp); 14394 } 14395 } 14396 } 14397 return runList; 14398 } 14399 14400 @Override 14401 public List<ApplicationInfo> getRunningExternalApplications() { 14402 enforceNotIsolatedCaller("getRunningExternalApplications"); 14403 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 14404 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 14405 if (runningApps != null && runningApps.size() > 0) { 14406 Set<String> extList = new HashSet<String>(); 14407 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 14408 if (app.pkgList != null) { 14409 for (String pkg : app.pkgList) { 14410 extList.add(pkg); 14411 } 14412 } 14413 } 14414 IPackageManager pm = AppGlobals.getPackageManager(); 14415 for (String pkg : extList) { 14416 try { 14417 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 14418 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 14419 retList.add(info); 14420 } 14421 } catch (RemoteException e) { 14422 } 14423 } 14424 } 14425 return retList; 14426 } 14427 14428 @Override 14429 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 14430 enforceNotIsolatedCaller("getMyMemoryState"); 14431 synchronized (this) { 14432 ProcessRecord proc; 14433 synchronized (mPidsSelfLocked) { 14434 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 14435 } 14436 fillInProcMemInfo(proc, outInfo); 14437 } 14438 } 14439 14440 @Override 14441 public int getMemoryTrimLevel() { 14442 enforceNotIsolatedCaller("getMyMemoryState"); 14443 synchronized (this) { 14444 return mLastMemoryLevel; 14445 } 14446 } 14447 14448 @Override 14449 public void onShellCommand(FileDescriptor in, FileDescriptor out, 14450 FileDescriptor err, String[] args, ShellCallback callback, 14451 ResultReceiver resultReceiver) { 14452 (new ActivityManagerShellCommand(this, false)).exec( 14453 this, in, out, err, args, callback, resultReceiver); 14454 } 14455 14456 @Override 14457 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 14458 if (checkCallingPermission(android.Manifest.permission.DUMP) 14459 != PackageManager.PERMISSION_GRANTED) { 14460 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 14461 + Binder.getCallingPid() 14462 + ", uid=" + Binder.getCallingUid() 14463 + " without permission " 14464 + android.Manifest.permission.DUMP); 14465 return; 14466 } 14467 14468 boolean dumpAll = false; 14469 boolean dumpClient = false; 14470 boolean dumpCheckin = false; 14471 boolean dumpCheckinFormat = false; 14472 boolean dumpVisibleStacksOnly = false; 14473 boolean dumpFocusedStackOnly = false; 14474 String dumpPackage = null; 14475 14476 int opti = 0; 14477 while (opti < args.length) { 14478 String opt = args[opti]; 14479 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 14480 break; 14481 } 14482 opti++; 14483 if ("-a".equals(opt)) { 14484 dumpAll = true; 14485 } else if ("-c".equals(opt)) { 14486 dumpClient = true; 14487 } else if ("-v".equals(opt)) { 14488 dumpVisibleStacksOnly = true; 14489 } else if ("-f".equals(opt)) { 14490 dumpFocusedStackOnly = true; 14491 } else if ("-p".equals(opt)) { 14492 if (opti < args.length) { 14493 dumpPackage = args[opti]; 14494 opti++; 14495 } else { 14496 pw.println("Error: -p option requires package argument"); 14497 return; 14498 } 14499 dumpClient = true; 14500 } else if ("--checkin".equals(opt)) { 14501 dumpCheckin = dumpCheckinFormat = true; 14502 } else if ("-C".equals(opt)) { 14503 dumpCheckinFormat = true; 14504 } else if ("-h".equals(opt)) { 14505 ActivityManagerShellCommand.dumpHelp(pw, true); 14506 return; 14507 } else { 14508 pw.println("Unknown argument: " + opt + "; use -h for help"); 14509 } 14510 } 14511 14512 long origId = Binder.clearCallingIdentity(); 14513 boolean more = false; 14514 // Is the caller requesting to dump a particular piece of data? 14515 if (opti < args.length) { 14516 String cmd = args[opti]; 14517 opti++; 14518 if ("activities".equals(cmd) || "a".equals(cmd)) { 14519 synchronized (this) { 14520 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 14521 } 14522 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 14523 synchronized (this) { 14524 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 14525 } 14526 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 14527 String[] newArgs; 14528 String name; 14529 if (opti >= args.length) { 14530 name = null; 14531 newArgs = EMPTY_STRING_ARRAY; 14532 } else { 14533 dumpPackage = args[opti]; 14534 opti++; 14535 newArgs = new String[args.length - opti]; 14536 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 14537 args.length - opti); 14538 } 14539 synchronized (this) { 14540 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 14541 } 14542 } else if ("broadcast-stats".equals(cmd)) { 14543 String[] newArgs; 14544 String name; 14545 if (opti >= args.length) { 14546 name = null; 14547 newArgs = EMPTY_STRING_ARRAY; 14548 } else { 14549 dumpPackage = args[opti]; 14550 opti++; 14551 newArgs = new String[args.length - opti]; 14552 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 14553 args.length - opti); 14554 } 14555 synchronized (this) { 14556 if (dumpCheckinFormat) { 14557 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, 14558 dumpPackage); 14559 } else { 14560 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage); 14561 } 14562 } 14563 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 14564 String[] newArgs; 14565 String name; 14566 if (opti >= args.length) { 14567 name = null; 14568 newArgs = EMPTY_STRING_ARRAY; 14569 } else { 14570 dumpPackage = args[opti]; 14571 opti++; 14572 newArgs = new String[args.length - opti]; 14573 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 14574 args.length - opti); 14575 } 14576 synchronized (this) { 14577 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 14578 } 14579 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 14580 String[] newArgs; 14581 String name; 14582 if (opti >= args.length) { 14583 name = null; 14584 newArgs = EMPTY_STRING_ARRAY; 14585 } else { 14586 dumpPackage = args[opti]; 14587 opti++; 14588 newArgs = new String[args.length - opti]; 14589 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 14590 args.length - opti); 14591 } 14592 synchronized (this) { 14593 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 14594 } 14595 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 14596 synchronized (this) { 14597 dumpOomLocked(fd, pw, args, opti, true); 14598 } 14599 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) { 14600 synchronized (this) { 14601 dumpPermissionsLocked(fd, pw, args, opti, true, null); 14602 } 14603 } else if ("provider".equals(cmd)) { 14604 String[] newArgs; 14605 String name; 14606 if (opti >= args.length) { 14607 name = null; 14608 newArgs = EMPTY_STRING_ARRAY; 14609 } else { 14610 name = args[opti]; 14611 opti++; 14612 newArgs = new String[args.length - opti]; 14613 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 14614 } 14615 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 14616 pw.println("No providers match: " + name); 14617 pw.println("Use -h for help."); 14618 } 14619 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 14620 synchronized (this) { 14621 dumpProvidersLocked(fd, pw, args, opti, true, null); 14622 } 14623 } else if ("service".equals(cmd)) { 14624 String[] newArgs; 14625 String name; 14626 if (opti >= args.length) { 14627 name = null; 14628 newArgs = EMPTY_STRING_ARRAY; 14629 } else { 14630 name = args[opti]; 14631 opti++; 14632 newArgs = new String[args.length - opti]; 14633 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 14634 args.length - opti); 14635 } 14636 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 14637 pw.println("No services match: " + name); 14638 pw.println("Use -h for help."); 14639 } 14640 } else if ("package".equals(cmd)) { 14641 String[] newArgs; 14642 if (opti >= args.length) { 14643 pw.println("package: no package name specified"); 14644 pw.println("Use -h for help."); 14645 } else { 14646 dumpPackage = args[opti]; 14647 opti++; 14648 newArgs = new String[args.length - opti]; 14649 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 14650 args.length - opti); 14651 args = newArgs; 14652 opti = 0; 14653 more = true; 14654 } 14655 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 14656 synchronized (this) { 14657 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 14658 } 14659 } else if ("settings".equals(cmd)) { 14660 synchronized (this) { 14661 mConstants.dump(pw); 14662 } 14663 } else if ("services".equals(cmd) || "s".equals(cmd)) { 14664 if (dumpClient) { 14665 ActiveServices.ServiceDumper dumper; 14666 synchronized (this) { 14667 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true, 14668 dumpPackage); 14669 } 14670 dumper.dumpWithClient(); 14671 } else { 14672 synchronized (this) { 14673 mServices.newServiceDumperLocked(fd, pw, args, opti, true, 14674 dumpPackage).dumpLocked(); 14675 } 14676 } 14677 } else if ("locks".equals(cmd)) { 14678 LockGuard.dump(fd, pw, args); 14679 } else { 14680 // Dumping a single activity? 14681 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly, 14682 dumpFocusedStackOnly)) { 14683 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true); 14684 int res = shell.exec(this, null, fd, null, args, null, 14685 new ResultReceiver(null)); 14686 if (res < 0) { 14687 pw.println("Bad activity command, or no activities match: " + cmd); 14688 pw.println("Use -h for help."); 14689 } 14690 } 14691 } 14692 if (!more) { 14693 Binder.restoreCallingIdentity(origId); 14694 return; 14695 } 14696 } 14697 14698 // No piece of data specified, dump everything. 14699 if (dumpCheckinFormat) { 14700 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage); 14701 } else if (dumpClient) { 14702 ActiveServices.ServiceDumper sdumper; 14703 synchronized (this) { 14704 mConstants.dump(pw); 14705 pw.println(); 14706 if (dumpAll) { 14707 pw.println("-------------------------------------------------------------------------------"); 14708 } 14709 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14710 pw.println(); 14711 if (dumpAll) { 14712 pw.println("-------------------------------------------------------------------------------"); 14713 } 14714 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14715 pw.println(); 14716 if (dumpAll) { 14717 pw.println("-------------------------------------------------------------------------------"); 14718 } 14719 if (dumpAll || dumpPackage != null) { 14720 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14721 pw.println(); 14722 if (dumpAll) { 14723 pw.println("-------------------------------------------------------------------------------"); 14724 } 14725 } 14726 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14727 pw.println(); 14728 if (dumpAll) { 14729 pw.println("-------------------------------------------------------------------------------"); 14730 } 14731 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14732 pw.println(); 14733 if (dumpAll) { 14734 pw.println("-------------------------------------------------------------------------------"); 14735 } 14736 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, 14737 dumpPackage); 14738 } 14739 sdumper.dumpWithClient(); 14740 pw.println(); 14741 synchronized (this) { 14742 if (dumpAll) { 14743 pw.println("-------------------------------------------------------------------------------"); 14744 } 14745 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14746 pw.println(); 14747 if (dumpAll) { 14748 pw.println("-------------------------------------------------------------------------------"); 14749 } 14750 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 14751 if (mAssociations.size() > 0) { 14752 pw.println(); 14753 if (dumpAll) { 14754 pw.println("-------------------------------------------------------------------------------"); 14755 } 14756 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 14757 } 14758 pw.println(); 14759 if (dumpAll) { 14760 pw.println("-------------------------------------------------------------------------------"); 14761 } 14762 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14763 } 14764 14765 } else { 14766 synchronized (this) { 14767 mConstants.dump(pw); 14768 pw.println(); 14769 if (dumpAll) { 14770 pw.println("-------------------------------------------------------------------------------"); 14771 } 14772 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14773 pw.println(); 14774 if (dumpAll) { 14775 pw.println("-------------------------------------------------------------------------------"); 14776 } 14777 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14778 pw.println(); 14779 if (dumpAll) { 14780 pw.println("-------------------------------------------------------------------------------"); 14781 } 14782 if (dumpAll || dumpPackage != null) { 14783 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14784 pw.println(); 14785 if (dumpAll) { 14786 pw.println("-------------------------------------------------------------------------------"); 14787 } 14788 } 14789 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14790 pw.println(); 14791 if (dumpAll) { 14792 pw.println("-------------------------------------------------------------------------------"); 14793 } 14794 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14795 pw.println(); 14796 if (dumpAll) { 14797 pw.println("-------------------------------------------------------------------------------"); 14798 } 14799 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage) 14800 .dumpLocked(); 14801 pw.println(); 14802 if (dumpAll) { 14803 pw.println("-------------------------------------------------------------------------------"); 14804 } 14805 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14806 pw.println(); 14807 if (dumpAll) { 14808 pw.println("-------------------------------------------------------------------------------"); 14809 } 14810 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 14811 if (mAssociations.size() > 0) { 14812 pw.println(); 14813 if (dumpAll) { 14814 pw.println("-------------------------------------------------------------------------------"); 14815 } 14816 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 14817 } 14818 pw.println(); 14819 if (dumpAll) { 14820 pw.println("-------------------------------------------------------------------------------"); 14821 } 14822 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 14823 } 14824 } 14825 Binder.restoreCallingIdentity(origId); 14826 } 14827 14828 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 14829 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 14830 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 14831 14832 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 14833 dumpPackage); 14834 boolean needSep = printedAnything; 14835 14836 boolean printed = ActivityStackSupervisor.printThisActivity(pw, 14837 mStackSupervisor.getResumedActivityLocked(), 14838 dumpPackage, needSep, " ResumedActivity: "); 14839 if (printed) { 14840 printedAnything = true; 14841 needSep = false; 14842 } 14843 14844 if (dumpPackage == null) { 14845 if (needSep) { 14846 pw.println(); 14847 } 14848 needSep = true; 14849 printedAnything = true; 14850 mStackSupervisor.dump(pw, " "); 14851 } 14852 14853 if (!printedAnything) { 14854 pw.println(" (nothing)"); 14855 } 14856 } 14857 14858 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 14859 int opti, boolean dumpAll, String dumpPackage) { 14860 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 14861 14862 boolean printedAnything = false; 14863 14864 if (mRecentTasks != null && mRecentTasks.size() > 0) { 14865 boolean printedHeader = false; 14866 14867 final int N = mRecentTasks.size(); 14868 for (int i=0; i<N; i++) { 14869 TaskRecord tr = mRecentTasks.get(i); 14870 if (dumpPackage != null) { 14871 if (tr.realActivity == null || 14872 !dumpPackage.equals(tr.realActivity.getPackageName())) { 14873 continue; 14874 } 14875 } 14876 if (!printedHeader) { 14877 pw.println(" Recent tasks:"); 14878 printedHeader = true; 14879 printedAnything = true; 14880 } 14881 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 14882 pw.println(tr); 14883 if (dumpAll) { 14884 mRecentTasks.get(i).dump(pw, " "); 14885 } 14886 } 14887 } 14888 14889 if (!printedAnything) { 14890 pw.println(" (nothing)"); 14891 } 14892 } 14893 14894 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 14895 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 14896 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 14897 14898 int dumpUid = 0; 14899 if (dumpPackage != null) { 14900 IPackageManager pm = AppGlobals.getPackageManager(); 14901 try { 14902 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0); 14903 } catch (RemoteException e) { 14904 } 14905 } 14906 14907 boolean printedAnything = false; 14908 14909 final long now = SystemClock.uptimeMillis(); 14910 14911 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 14912 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 14913 = mAssociations.valueAt(i1); 14914 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 14915 SparseArray<ArrayMap<String, Association>> sourceUids 14916 = targetComponents.valueAt(i2); 14917 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 14918 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 14919 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 14920 Association ass = sourceProcesses.valueAt(i4); 14921 if (dumpPackage != null) { 14922 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 14923 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 14924 continue; 14925 } 14926 } 14927 printedAnything = true; 14928 pw.print(" "); 14929 pw.print(ass.mTargetProcess); 14930 pw.print("/"); 14931 UserHandle.formatUid(pw, ass.mTargetUid); 14932 pw.print(" <- "); 14933 pw.print(ass.mSourceProcess); 14934 pw.print("/"); 14935 UserHandle.formatUid(pw, ass.mSourceUid); 14936 pw.println(); 14937 pw.print(" via "); 14938 pw.print(ass.mTargetComponent.flattenToShortString()); 14939 pw.println(); 14940 pw.print(" "); 14941 long dur = ass.mTime; 14942 if (ass.mNesting > 0) { 14943 dur += now - ass.mStartTime; 14944 } 14945 TimeUtils.formatDuration(dur, pw); 14946 pw.print(" ("); 14947 pw.print(ass.mCount); 14948 pw.print(" times)"); 14949 pw.print(" "); 14950 for (int i=0; i<ass.mStateTimes.length; i++) { 14951 long amt = ass.mStateTimes[i]; 14952 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { 14953 amt += now - ass.mLastStateUptime; 14954 } 14955 if (amt != 0) { 14956 pw.print(" "); 14957 pw.print(ProcessList.makeProcStateString( 14958 i + ActivityManager.MIN_PROCESS_STATE)); 14959 pw.print("="); 14960 TimeUtils.formatDuration(amt, pw); 14961 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { 14962 pw.print("*"); 14963 } 14964 } 14965 } 14966 pw.println(); 14967 if (ass.mNesting > 0) { 14968 pw.print(" Currently active: "); 14969 TimeUtils.formatDuration(now - ass.mStartTime, pw); 14970 pw.println(); 14971 } 14972 } 14973 } 14974 } 14975 14976 } 14977 14978 if (!printedAnything) { 14979 pw.println(" (nothing)"); 14980 } 14981 } 14982 14983 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids, 14984 String header, boolean needSep) { 14985 boolean printed = false; 14986 int whichAppId = -1; 14987 if (dumpPackage != null) { 14988 try { 14989 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 14990 dumpPackage, 0); 14991 whichAppId = UserHandle.getAppId(info.uid); 14992 } catch (NameNotFoundException e) { 14993 e.printStackTrace(); 14994 } 14995 } 14996 for (int i=0; i<uids.size(); i++) { 14997 UidRecord uidRec = uids.valueAt(i); 14998 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) { 14999 continue; 15000 } 15001 if (!printed) { 15002 printed = true; 15003 if (needSep) { 15004 pw.println(); 15005 } 15006 pw.print(" "); 15007 pw.println(header); 15008 needSep = true; 15009 } 15010 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid); 15011 pw.print(": "); pw.println(uidRec); 15012 } 15013 return printed; 15014 } 15015 15016 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15017 int opti, boolean dumpAll, String dumpPackage) { 15018 boolean needSep = false; 15019 boolean printedAnything = false; 15020 int numPers = 0; 15021 15022 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 15023 15024 if (dumpAll) { 15025 final int NP = mProcessNames.getMap().size(); 15026 for (int ip=0; ip<NP; ip++) { 15027 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 15028 final int NA = procs.size(); 15029 for (int ia=0; ia<NA; ia++) { 15030 ProcessRecord r = procs.valueAt(ia); 15031 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 15032 continue; 15033 } 15034 if (!needSep) { 15035 pw.println(" All known processes:"); 15036 needSep = true; 15037 printedAnything = true; 15038 } 15039 pw.print(r.persistent ? " *PERS*" : " *APP*"); 15040 pw.print(" UID "); pw.print(procs.keyAt(ia)); 15041 pw.print(" "); pw.println(r); 15042 r.dump(pw, " "); 15043 if (r.persistent) { 15044 numPers++; 15045 } 15046 } 15047 } 15048 } 15049 15050 if (mIsolatedProcesses.size() > 0) { 15051 boolean printed = false; 15052 for (int i=0; i<mIsolatedProcesses.size(); i++) { 15053 ProcessRecord r = mIsolatedProcesses.valueAt(i); 15054 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 15055 continue; 15056 } 15057 if (!printed) { 15058 if (needSep) { 15059 pw.println(); 15060 } 15061 pw.println(" Isolated process list (sorted by uid):"); 15062 printedAnything = true; 15063 printed = true; 15064 needSep = true; 15065 } 15066 pw.print(" Isolated #"); pw.print(i); pw.print(": "); 15067 pw.println(r); 15068 } 15069 } 15070 15071 if (mActiveInstrumentation.size() > 0) { 15072 boolean printed = false; 15073 for (int i=0; i<mActiveInstrumentation.size(); i++) { 15074 ActiveInstrumentation ai = mActiveInstrumentation.get(i); 15075 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage) 15076 && !ai.mTargetInfo.packageName.equals(dumpPackage)) { 15077 continue; 15078 } 15079 if (!printed) { 15080 if (needSep) { 15081 pw.println(); 15082 } 15083 pw.println(" Active instrumentation:"); 15084 printedAnything = true; 15085 printed = true; 15086 needSep = true; 15087 } 15088 pw.print(" Instrumentation #"); pw.print(i); pw.print(": "); 15089 pw.println(ai); 15090 ai.dump(pw, " "); 15091 } 15092 } 15093 15094 if (mActiveUids.size() > 0) { 15095 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) { 15096 printedAnything = needSep = true; 15097 } 15098 } 15099 if (mValidateUids.size() > 0) { 15100 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) { 15101 printedAnything = needSep = true; 15102 } 15103 } 15104 15105 if (mLruProcesses.size() > 0) { 15106 if (needSep) { 15107 pw.println(); 15108 } 15109 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 15110 pw.print(" total, non-act at "); 15111 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 15112 pw.print(", non-svc at "); 15113 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 15114 pw.println("):"); 15115 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 15116 needSep = true; 15117 printedAnything = true; 15118 } 15119 15120 if (dumpAll || dumpPackage != null) { 15121 synchronized (mPidsSelfLocked) { 15122 boolean printed = false; 15123 for (int i=0; i<mPidsSelfLocked.size(); i++) { 15124 ProcessRecord r = mPidsSelfLocked.valueAt(i); 15125 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 15126 continue; 15127 } 15128 if (!printed) { 15129 if (needSep) pw.println(); 15130 needSep = true; 15131 pw.println(" PID mappings:"); 15132 printed = true; 15133 printedAnything = true; 15134 } 15135 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 15136 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 15137 } 15138 } 15139 } 15140 15141 if (mForegroundProcesses.size() > 0) { 15142 synchronized (mPidsSelfLocked) { 15143 boolean printed = false; 15144 for (int i=0; i<mForegroundProcesses.size(); i++) { 15145 ProcessRecord r = mPidsSelfLocked.get( 15146 mForegroundProcesses.valueAt(i).pid); 15147 if (dumpPackage != null && (r == null 15148 || !r.pkgList.containsKey(dumpPackage))) { 15149 continue; 15150 } 15151 if (!printed) { 15152 if (needSep) pw.println(); 15153 needSep = true; 15154 pw.println(" Foreground Processes:"); 15155 printed = true; 15156 printedAnything = true; 15157 } 15158 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 15159 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 15160 } 15161 } 15162 } 15163 15164 if (mPersistentStartingProcesses.size() > 0) { 15165 if (needSep) pw.println(); 15166 needSep = true; 15167 printedAnything = true; 15168 pw.println(" Persisent processes that are starting:"); 15169 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 15170 "Starting Norm", "Restarting PERS", dumpPackage); 15171 } 15172 15173 if (mRemovedProcesses.size() > 0) { 15174 if (needSep) pw.println(); 15175 needSep = true; 15176 printedAnything = true; 15177 pw.println(" Processes that are being removed:"); 15178 dumpProcessList(pw, this, mRemovedProcesses, " ", 15179 "Removed Norm", "Removed PERS", dumpPackage); 15180 } 15181 15182 if (mProcessesOnHold.size() > 0) { 15183 if (needSep) pw.println(); 15184 needSep = true; 15185 printedAnything = true; 15186 pw.println(" Processes that are on old until the system is ready:"); 15187 dumpProcessList(pw, this, mProcessesOnHold, " ", 15188 "OnHold Norm", "OnHold PERS", dumpPackage); 15189 } 15190 15191 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 15192 15193 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage); 15194 if (needSep) { 15195 printedAnything = true; 15196 } 15197 15198 if (dumpPackage == null) { 15199 pw.println(); 15200 needSep = false; 15201 mUserController.dump(pw, dumpAll); 15202 } 15203 if (mHomeProcess != null && (dumpPackage == null 15204 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 15205 if (needSep) { 15206 pw.println(); 15207 needSep = false; 15208 } 15209 pw.println(" mHomeProcess: " + mHomeProcess); 15210 } 15211 if (mPreviousProcess != null && (dumpPackage == null 15212 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 15213 if (needSep) { 15214 pw.println(); 15215 needSep = false; 15216 } 15217 pw.println(" mPreviousProcess: " + mPreviousProcess); 15218 } 15219 if (dumpAll) { 15220 StringBuilder sb = new StringBuilder(128); 15221 sb.append(" mPreviousProcessVisibleTime: "); 15222 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 15223 pw.println(sb); 15224 } 15225 if (mHeavyWeightProcess != null && (dumpPackage == null 15226 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 15227 if (needSep) { 15228 pw.println(); 15229 needSep = false; 15230 } 15231 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 15232 } 15233 if (dumpPackage == null) { 15234 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration()); 15235 mStackSupervisor.dumpDisplayConfigs(pw, " "); 15236 } 15237 if (dumpAll) { 15238 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 15239 if (mCompatModePackages.getPackages().size() > 0) { 15240 boolean printed = false; 15241 for (Map.Entry<String, Integer> entry 15242 : mCompatModePackages.getPackages().entrySet()) { 15243 String pkg = entry.getKey(); 15244 int mode = entry.getValue(); 15245 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 15246 continue; 15247 } 15248 if (!printed) { 15249 pw.println(" mScreenCompatPackages:"); 15250 printed = true; 15251 } 15252 pw.print(" "); pw.print(pkg); pw.print(": "); 15253 pw.print(mode); pw.println(); 15254 } 15255 } 15256 final int NI = mUidObservers.getRegisteredCallbackCount(); 15257 boolean printed = false; 15258 for (int i=0; i<NI; i++) { 15259 final UidObserverRegistration reg = (UidObserverRegistration) 15260 mUidObservers.getRegisteredCallbackCookie(i); 15261 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) { 15262 if (!printed) { 15263 pw.println(" mUidObservers:"); 15264 printed = true; 15265 } 15266 pw.print(" "); UserHandle.formatUid(pw, reg.uid); 15267 pw.print(" "); pw.print(reg.pkg); pw.print(":"); 15268 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) { 15269 pw.print(" IDLE"); 15270 } 15271 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) { 15272 pw.print(" ACT" ); 15273 } 15274 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) { 15275 pw.print(" GONE"); 15276 } 15277 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { 15278 pw.print(" STATE"); 15279 pw.print(" (cut="); pw.print(reg.cutpoint); 15280 pw.print(")"); 15281 } 15282 pw.println(); 15283 if (reg.lastProcStates != null) { 15284 final int NJ = reg.lastProcStates.size(); 15285 for (int j=0; j<NJ; j++) { 15286 pw.print(" Last "); 15287 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j)); 15288 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j)); 15289 } 15290 } 15291 } 15292 } 15293 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist)); 15294 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist)); 15295 } 15296 if (dumpPackage == null) { 15297 pw.println(" mWakefulness=" 15298 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 15299 pw.println(" mSleepTokens=" + mSleepTokens); 15300 pw.println(" mSleeping=" + mSleeping); 15301 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode); 15302 if (mRunningVoice != null) { 15303 pw.println(" mRunningVoice=" + mRunningVoice); 15304 pw.println(" mVoiceWakeLock" + mVoiceWakeLock); 15305 } 15306 } 15307 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 15308 || mOrigWaitForDebugger) { 15309 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 15310 || dumpPackage.equals(mOrigDebugApp)) { 15311 if (needSep) { 15312 pw.println(); 15313 needSep = false; 15314 } 15315 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 15316 + " mDebugTransient=" + mDebugTransient 15317 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 15318 } 15319 } 15320 if (mCurAppTimeTracker != null) { 15321 mCurAppTimeTracker.dumpWithHeader(pw, " ", true); 15322 } 15323 if (mMemWatchProcesses.getMap().size() > 0) { 15324 pw.println(" Mem watch processes:"); 15325 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs 15326 = mMemWatchProcesses.getMap(); 15327 for (int i=0; i<procs.size(); i++) { 15328 final String proc = procs.keyAt(i); 15329 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i); 15330 for (int j=0; j<uids.size(); j++) { 15331 if (needSep) { 15332 pw.println(); 15333 needSep = false; 15334 } 15335 StringBuilder sb = new StringBuilder(); 15336 sb.append(" ").append(proc).append('/'); 15337 UserHandle.formatUid(sb, uids.keyAt(j)); 15338 Pair<Long, String> val = uids.valueAt(j); 15339 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb); 15340 if (val.second != null) { 15341 sb.append(", report to ").append(val.second); 15342 } 15343 pw.println(sb.toString()); 15344 } 15345 } 15346 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName); 15347 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile); 15348 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid); 15349 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid); 15350 } 15351 if (mTrackAllocationApp != null) { 15352 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) { 15353 if (needSep) { 15354 pw.println(); 15355 needSep = false; 15356 } 15357 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp); 15358 } 15359 } 15360 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 15361 || mProfileFd != null) { 15362 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 15363 if (needSep) { 15364 pw.println(); 15365 needSep = false; 15366 } 15367 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 15368 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 15369 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 15370 + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput); 15371 pw.println(" mProfileType=" + mProfileType); 15372 } 15373 } 15374 if (mNativeDebuggingApp != null) { 15375 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) { 15376 if (needSep) { 15377 pw.println(); 15378 needSep = false; 15379 } 15380 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp); 15381 } 15382 } 15383 if (dumpPackage == null) { 15384 if (mAlwaysFinishActivities) { 15385 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities); 15386 } 15387 if (mController != null) { 15388 pw.println(" mController=" + mController 15389 + " mControllerIsAMonkey=" + mControllerIsAMonkey); 15390 } 15391 if (dumpAll) { 15392 pw.println(" Total persistent processes: " + numPers); 15393 pw.println(" mProcessesReady=" + mProcessesReady 15394 + " mSystemReady=" + mSystemReady 15395 + " mBooted=" + mBooted 15396 + " mFactoryTest=" + mFactoryTest); 15397 pw.println(" mBooting=" + mBooting 15398 + " mCallFinishBooting=" + mCallFinishBooting 15399 + " mBootAnimationComplete=" + mBootAnimationComplete); 15400 pw.print(" mLastPowerCheckRealtime="); 15401 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 15402 pw.println(""); 15403 pw.print(" mLastPowerCheckUptime="); 15404 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 15405 pw.println(""); 15406 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 15407 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 15408 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 15409 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 15410 + " (" + mLruProcesses.size() + " total)" 15411 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 15412 + " mNumServiceProcs=" + mNumServiceProcs 15413 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 15414 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 15415 + " mLastMemoryLevel=" + mLastMemoryLevel 15416 + " mLastNumProcesses=" + mLastNumProcesses); 15417 long now = SystemClock.uptimeMillis(); 15418 pw.print(" mLastIdleTime="); 15419 TimeUtils.formatDuration(now, mLastIdleTime, pw); 15420 pw.print(" mLowRamSinceLastIdle="); 15421 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 15422 pw.println(); 15423 } 15424 } 15425 15426 if (!printedAnything) { 15427 pw.println(" (nothing)"); 15428 } 15429 } 15430 15431 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 15432 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 15433 if (mProcessesToGc.size() > 0) { 15434 boolean printed = false; 15435 long now = SystemClock.uptimeMillis(); 15436 for (int i=0; i<mProcessesToGc.size(); i++) { 15437 ProcessRecord proc = mProcessesToGc.get(i); 15438 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 15439 continue; 15440 } 15441 if (!printed) { 15442 if (needSep) pw.println(); 15443 needSep = true; 15444 pw.println(" Processes that are waiting to GC:"); 15445 printed = true; 15446 } 15447 pw.print(" Process "); pw.println(proc); 15448 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 15449 pw.print(", last gced="); 15450 pw.print(now-proc.lastRequestedGc); 15451 pw.print(" ms ago, last lowMem="); 15452 pw.print(now-proc.lastLowMemory); 15453 pw.println(" ms ago"); 15454 15455 } 15456 } 15457 return needSep; 15458 } 15459 15460 void printOomLevel(PrintWriter pw, String name, int adj) { 15461 pw.print(" "); 15462 if (adj >= 0) { 15463 pw.print(' '); 15464 if (adj < 10) pw.print(' '); 15465 } else { 15466 if (adj > -10) pw.print(' '); 15467 } 15468 pw.print(adj); 15469 pw.print(": "); 15470 pw.print(name); 15471 pw.print(" ("); 15472 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024)); 15473 pw.println(")"); 15474 } 15475 15476 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15477 int opti, boolean dumpAll) { 15478 boolean needSep = false; 15479 15480 if (mLruProcesses.size() > 0) { 15481 if (needSep) pw.println(); 15482 needSep = true; 15483 pw.println(" OOM levels:"); 15484 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 15485 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 15486 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 15487 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 15488 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 15489 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 15490 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 15491 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 15492 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 15493 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 15494 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 15495 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 15496 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 15497 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 15498 15499 if (needSep) pw.println(); 15500 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 15501 pw.print(" total, non-act at "); 15502 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 15503 pw.print(", non-svc at "); 15504 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 15505 pw.println("):"); 15506 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 15507 needSep = true; 15508 } 15509 15510 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 15511 15512 pw.println(); 15513 pw.println(" mHomeProcess: " + mHomeProcess); 15514 pw.println(" mPreviousProcess: " + mPreviousProcess); 15515 if (mHeavyWeightProcess != null) { 15516 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 15517 } 15518 15519 return true; 15520 } 15521 15522 /** 15523 * There are three ways to call this: 15524 * - no provider specified: dump all the providers 15525 * - a flattened component name that matched an existing provider was specified as the 15526 * first arg: dump that one provider 15527 * - the first arg isn't the flattened component name of an existing provider: 15528 * dump all providers whose component contains the first arg as a substring 15529 */ 15530 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 15531 int opti, boolean dumpAll) { 15532 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 15533 } 15534 15535 static class ItemMatcher { 15536 ArrayList<ComponentName> components; 15537 ArrayList<String> strings; 15538 ArrayList<Integer> objects; 15539 boolean all; 15540 15541 ItemMatcher() { 15542 all = true; 15543 } 15544 15545 void build(String name) { 15546 ComponentName componentName = ComponentName.unflattenFromString(name); 15547 if (componentName != null) { 15548 if (components == null) { 15549 components = new ArrayList<ComponentName>(); 15550 } 15551 components.add(componentName); 15552 all = false; 15553 } else { 15554 int objectId = 0; 15555 // Not a '/' separated full component name; maybe an object ID? 15556 try { 15557 objectId = Integer.parseInt(name, 16); 15558 if (objects == null) { 15559 objects = new ArrayList<Integer>(); 15560 } 15561 objects.add(objectId); 15562 all = false; 15563 } catch (RuntimeException e) { 15564 // Not an integer; just do string match. 15565 if (strings == null) { 15566 strings = new ArrayList<String>(); 15567 } 15568 strings.add(name); 15569 all = false; 15570 } 15571 } 15572 } 15573 15574 int build(String[] args, int opti) { 15575 for (; opti<args.length; opti++) { 15576 String name = args[opti]; 15577 if ("--".equals(name)) { 15578 return opti+1; 15579 } 15580 build(name); 15581 } 15582 return opti; 15583 } 15584 15585 boolean match(Object object, ComponentName comp) { 15586 if (all) { 15587 return true; 15588 } 15589 if (components != null) { 15590 for (int i=0; i<components.size(); i++) { 15591 if (components.get(i).equals(comp)) { 15592 return true; 15593 } 15594 } 15595 } 15596 if (objects != null) { 15597 for (int i=0; i<objects.size(); i++) { 15598 if (System.identityHashCode(object) == objects.get(i)) { 15599 return true; 15600 } 15601 } 15602 } 15603 if (strings != null) { 15604 String flat = comp.flattenToString(); 15605 for (int i=0; i<strings.size(); i++) { 15606 if (flat.contains(strings.get(i))) { 15607 return true; 15608 } 15609 } 15610 } 15611 return false; 15612 } 15613 } 15614 15615 /** 15616 * There are three things that cmd can be: 15617 * - a flattened component name that matches an existing activity 15618 * - the cmd arg isn't the flattened component name of an existing activity: 15619 * dump all activity whose component contains the cmd as a substring 15620 * - A hex number of the ActivityRecord object instance. 15621 * 15622 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack 15623 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack 15624 */ 15625 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 15626 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) { 15627 ArrayList<ActivityRecord> activities; 15628 15629 synchronized (this) { 15630 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly, 15631 dumpFocusedStackOnly); 15632 } 15633 15634 if (activities.size() <= 0) { 15635 return false; 15636 } 15637 15638 String[] newArgs = new String[args.length - opti]; 15639 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 15640 15641 TaskRecord lastTask = null; 15642 boolean needSep = false; 15643 for (int i=activities.size()-1; i>=0; i--) { 15644 ActivityRecord r = activities.get(i); 15645 if (needSep) { 15646 pw.println(); 15647 } 15648 needSep = true; 15649 synchronized (this) { 15650 if (lastTask != r.task) { 15651 lastTask = r.task; 15652 pw.print("TASK "); pw.print(lastTask.affinity); 15653 pw.print(" id="); pw.print(lastTask.taskId); 15654 pw.print(" userId="); pw.println(lastTask.userId); 15655 if (dumpAll) { 15656 lastTask.dump(pw, " "); 15657 } 15658 } 15659 } 15660 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 15661 } 15662 return true; 15663 } 15664 15665 /** 15666 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 15667 * there is a thread associated with the activity. 15668 */ 15669 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 15670 final ActivityRecord r, String[] args, boolean dumpAll) { 15671 String innerPrefix = prefix + " "; 15672 synchronized (this) { 15673 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 15674 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 15675 pw.print(" pid="); 15676 if (r.app != null) pw.println(r.app.pid); 15677 else pw.println("(not running)"); 15678 if (dumpAll) { 15679 r.dump(pw, innerPrefix); 15680 } 15681 } 15682 if (r.app != null && r.app.thread != null) { 15683 // flush anything that is already in the PrintWriter since the thread is going 15684 // to write to the file descriptor directly 15685 pw.flush(); 15686 try { 15687 TransferPipe tp = new TransferPipe(); 15688 try { 15689 r.app.thread.dumpActivity(tp.getWriteFd(), 15690 r.appToken, innerPrefix, args); 15691 tp.go(fd); 15692 } finally { 15693 tp.kill(); 15694 } 15695 } catch (IOException e) { 15696 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 15697 } catch (RemoteException e) { 15698 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 15699 } 15700 } 15701 } 15702 15703 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15704 int opti, boolean dumpAll, String dumpPackage) { 15705 boolean needSep = false; 15706 boolean onlyHistory = false; 15707 boolean printedAnything = false; 15708 15709 if ("history".equals(dumpPackage)) { 15710 if (opti < args.length && "-s".equals(args[opti])) { 15711 dumpAll = false; 15712 } 15713 onlyHistory = true; 15714 dumpPackage = null; 15715 } 15716 15717 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 15718 if (!onlyHistory && dumpAll) { 15719 if (mRegisteredReceivers.size() > 0) { 15720 boolean printed = false; 15721 Iterator it = mRegisteredReceivers.values().iterator(); 15722 while (it.hasNext()) { 15723 ReceiverList r = (ReceiverList)it.next(); 15724 if (dumpPackage != null && (r.app == null || 15725 !dumpPackage.equals(r.app.info.packageName))) { 15726 continue; 15727 } 15728 if (!printed) { 15729 pw.println(" Registered Receivers:"); 15730 needSep = true; 15731 printed = true; 15732 printedAnything = true; 15733 } 15734 pw.print(" * "); pw.println(r); 15735 r.dump(pw, " "); 15736 } 15737 } 15738 15739 if (mReceiverResolver.dump(pw, needSep ? 15740 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 15741 " ", dumpPackage, false, false)) { 15742 needSep = true; 15743 printedAnything = true; 15744 } 15745 } 15746 15747 for (BroadcastQueue q : mBroadcastQueues) { 15748 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 15749 printedAnything |= needSep; 15750 } 15751 15752 needSep = true; 15753 15754 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 15755 for (int user=0; user<mStickyBroadcasts.size(); user++) { 15756 if (needSep) { 15757 pw.println(); 15758 } 15759 needSep = true; 15760 printedAnything = true; 15761 pw.print(" Sticky broadcasts for user "); 15762 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 15763 StringBuilder sb = new StringBuilder(128); 15764 for (Map.Entry<String, ArrayList<Intent>> ent 15765 : mStickyBroadcasts.valueAt(user).entrySet()) { 15766 pw.print(" * Sticky action "); pw.print(ent.getKey()); 15767 if (dumpAll) { 15768 pw.println(":"); 15769 ArrayList<Intent> intents = ent.getValue(); 15770 final int N = intents.size(); 15771 for (int i=0; i<N; i++) { 15772 sb.setLength(0); 15773 sb.append(" Intent: "); 15774 intents.get(i).toShortString(sb, false, true, false, false); 15775 pw.println(sb.toString()); 15776 Bundle bundle = intents.get(i).getExtras(); 15777 if (bundle != null) { 15778 pw.print(" "); 15779 pw.println(bundle.toString()); 15780 } 15781 } 15782 } else { 15783 pw.println(""); 15784 } 15785 } 15786 } 15787 } 15788 15789 if (!onlyHistory && dumpAll) { 15790 pw.println(); 15791 for (BroadcastQueue queue : mBroadcastQueues) { 15792 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 15793 + queue.mBroadcastsScheduled); 15794 } 15795 pw.println(" mHandler:"); 15796 mHandler.dump(new PrintWriterPrinter(pw), " "); 15797 needSep = true; 15798 printedAnything = true; 15799 } 15800 15801 if (!printedAnything) { 15802 pw.println(" (nothing)"); 15803 } 15804 } 15805 15806 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15807 int opti, boolean dumpAll, String dumpPackage) { 15808 if (mCurBroadcastStats == null) { 15809 return; 15810 } 15811 15812 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)"); 15813 final long now = SystemClock.elapsedRealtime(); 15814 if (mLastBroadcastStats != null) { 15815 pw.print(" Last stats (from "); 15816 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw); 15817 pw.print(" to "); 15818 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw); 15819 pw.print(", "); 15820 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime 15821 - mLastBroadcastStats.mStartUptime, pw); 15822 pw.println(" uptime):"); 15823 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) { 15824 pw.println(" (nothing)"); 15825 } 15826 pw.println(); 15827 } 15828 pw.print(" Current stats (from "); 15829 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw); 15830 pw.print(" to now, "); 15831 TimeUtils.formatDuration(SystemClock.uptimeMillis() 15832 - mCurBroadcastStats.mStartUptime, pw); 15833 pw.println(" uptime):"); 15834 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) { 15835 pw.println(" (nothing)"); 15836 } 15837 } 15838 15839 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15840 int opti, boolean fullCheckin, String dumpPackage) { 15841 if (mCurBroadcastStats == null) { 15842 return; 15843 } 15844 15845 if (mLastBroadcastStats != null) { 15846 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage); 15847 if (fullCheckin) { 15848 mLastBroadcastStats = null; 15849 return; 15850 } 15851 } 15852 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage); 15853 if (fullCheckin) { 15854 mCurBroadcastStats = null; 15855 } 15856 } 15857 15858 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15859 int opti, boolean dumpAll, String dumpPackage) { 15860 boolean needSep; 15861 boolean printedAnything = false; 15862 15863 ItemMatcher matcher = new ItemMatcher(); 15864 matcher.build(args, opti); 15865 15866 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 15867 15868 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 15869 printedAnything |= needSep; 15870 15871 if (mLaunchingProviders.size() > 0) { 15872 boolean printed = false; 15873 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 15874 ContentProviderRecord r = mLaunchingProviders.get(i); 15875 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 15876 continue; 15877 } 15878 if (!printed) { 15879 if (needSep) pw.println(); 15880 needSep = true; 15881 pw.println(" Launching content providers:"); 15882 printed = true; 15883 printedAnything = true; 15884 } 15885 pw.print(" Launching #"); pw.print(i); pw.print(": "); 15886 pw.println(r); 15887 } 15888 } 15889 15890 if (!printedAnything) { 15891 pw.println(" (nothing)"); 15892 } 15893 } 15894 15895 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15896 int opti, boolean dumpAll, String dumpPackage) { 15897 boolean needSep = false; 15898 boolean printedAnything = false; 15899 15900 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)"); 15901 15902 if (mGrantedUriPermissions.size() > 0) { 15903 boolean printed = false; 15904 int dumpUid = -2; 15905 if (dumpPackage != null) { 15906 try { 15907 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage, 15908 MATCH_ANY_USER, 0); 15909 } catch (NameNotFoundException e) { 15910 dumpUid = -1; 15911 } 15912 } 15913 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 15914 int uid = mGrantedUriPermissions.keyAt(i); 15915 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 15916 continue; 15917 } 15918 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 15919 if (!printed) { 15920 if (needSep) pw.println(); 15921 needSep = true; 15922 pw.println(" Granted Uri Permissions:"); 15923 printed = true; 15924 printedAnything = true; 15925 } 15926 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 15927 for (UriPermission perm : perms.values()) { 15928 pw.print(" "); pw.println(perm); 15929 if (dumpAll) { 15930 perm.dump(pw, " "); 15931 } 15932 } 15933 } 15934 } 15935 15936 if (!printedAnything) { 15937 pw.println(" (nothing)"); 15938 } 15939 } 15940 15941 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 15942 int opti, boolean dumpAll, String dumpPackage) { 15943 boolean printed = false; 15944 15945 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 15946 15947 if (mIntentSenderRecords.size() > 0) { 15948 Iterator<WeakReference<PendingIntentRecord>> it 15949 = mIntentSenderRecords.values().iterator(); 15950 while (it.hasNext()) { 15951 WeakReference<PendingIntentRecord> ref = it.next(); 15952 PendingIntentRecord rec = ref != null ? ref.get(): null; 15953 if (dumpPackage != null && (rec == null 15954 || !dumpPackage.equals(rec.key.packageName))) { 15955 continue; 15956 } 15957 printed = true; 15958 if (rec != null) { 15959 pw.print(" * "); pw.println(rec); 15960 if (dumpAll) { 15961 rec.dump(pw, " "); 15962 } 15963 } else { 15964 pw.print(" * "); pw.println(ref); 15965 } 15966 } 15967 } 15968 15969 if (!printed) { 15970 pw.println(" (nothing)"); 15971 } 15972 } 15973 15974 private static final int dumpProcessList(PrintWriter pw, 15975 ActivityManagerService service, List list, 15976 String prefix, String normalLabel, String persistentLabel, 15977 String dumpPackage) { 15978 int numPers = 0; 15979 final int N = list.size()-1; 15980 for (int i=N; i>=0; i--) { 15981 ProcessRecord r = (ProcessRecord)list.get(i); 15982 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 15983 continue; 15984 } 15985 pw.println(String.format("%s%s #%2d: %s", 15986 prefix, (r.persistent ? persistentLabel : normalLabel), 15987 i, r.toString())); 15988 if (r.persistent) { 15989 numPers++; 15990 } 15991 } 15992 return numPers; 15993 } 15994 15995 private static final boolean dumpProcessOomList(PrintWriter pw, 15996 ActivityManagerService service, List<ProcessRecord> origList, 15997 String prefix, String normalLabel, String persistentLabel, 15998 boolean inclDetails, String dumpPackage) { 15999 16000 ArrayList<Pair<ProcessRecord, Integer>> list 16001 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 16002 for (int i=0; i<origList.size(); i++) { 16003 ProcessRecord r = origList.get(i); 16004 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 16005 continue; 16006 } 16007 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 16008 } 16009 16010 if (list.size() <= 0) { 16011 return false; 16012 } 16013 16014 Comparator<Pair<ProcessRecord, Integer>> comparator 16015 = new Comparator<Pair<ProcessRecord, Integer>>() { 16016 @Override 16017 public int compare(Pair<ProcessRecord, Integer> object1, 16018 Pair<ProcessRecord, Integer> object2) { 16019 if (object1.first.setAdj != object2.first.setAdj) { 16020 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 16021 } 16022 if (object1.first.setProcState != object2.first.setProcState) { 16023 return object1.first.setProcState > object2.first.setProcState ? -1 : 1; 16024 } 16025 if (object1.second.intValue() != object2.second.intValue()) { 16026 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 16027 } 16028 return 0; 16029 } 16030 }; 16031 16032 Collections.sort(list, comparator); 16033 16034 final long curRealtime = SystemClock.elapsedRealtime(); 16035 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 16036 final long curUptime = SystemClock.uptimeMillis(); 16037 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 16038 16039 for (int i=list.size()-1; i>=0; i--) { 16040 ProcessRecord r = list.get(i).first; 16041 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 16042 char schedGroup; 16043 switch (r.setSchedGroup) { 16044 case ProcessList.SCHED_GROUP_BACKGROUND: 16045 schedGroup = 'B'; 16046 break; 16047 case ProcessList.SCHED_GROUP_DEFAULT: 16048 schedGroup = 'F'; 16049 break; 16050 case ProcessList.SCHED_GROUP_TOP_APP: 16051 schedGroup = 'T'; 16052 break; 16053 default: 16054 schedGroup = '?'; 16055 break; 16056 } 16057 char foreground; 16058 if (r.foregroundActivities) { 16059 foreground = 'A'; 16060 } else if (r.foregroundServices) { 16061 foreground = 'S'; 16062 } else { 16063 foreground = ' '; 16064 } 16065 String procState = ProcessList.makeProcStateString(r.curProcState); 16066 pw.print(prefix); 16067 pw.print(r.persistent ? persistentLabel : normalLabel); 16068 pw.print(" #"); 16069 int num = (origList.size()-1)-list.get(i).second; 16070 if (num < 10) pw.print(' '); 16071 pw.print(num); 16072 pw.print(": "); 16073 pw.print(oomAdj); 16074 pw.print(' '); 16075 pw.print(schedGroup); 16076 pw.print('/'); 16077 pw.print(foreground); 16078 pw.print('/'); 16079 pw.print(procState); 16080 pw.print(" trm:"); 16081 if (r.trimMemoryLevel < 10) pw.print(' '); 16082 pw.print(r.trimMemoryLevel); 16083 pw.print(' '); 16084 pw.print(r.toShortString()); 16085 pw.print(" ("); 16086 pw.print(r.adjType); 16087 pw.println(')'); 16088 if (r.adjSource != null || r.adjTarget != null) { 16089 pw.print(prefix); 16090 pw.print(" "); 16091 if (r.adjTarget instanceof ComponentName) { 16092 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 16093 } else if (r.adjTarget != null) { 16094 pw.print(r.adjTarget.toString()); 16095 } else { 16096 pw.print("{null}"); 16097 } 16098 pw.print("<="); 16099 if (r.adjSource instanceof ProcessRecord) { 16100 pw.print("Proc{"); 16101 pw.print(((ProcessRecord)r.adjSource).toShortString()); 16102 pw.println("}"); 16103 } else if (r.adjSource != null) { 16104 pw.println(r.adjSource.toString()); 16105 } else { 16106 pw.println("{null}"); 16107 } 16108 } 16109 if (inclDetails) { 16110 pw.print(prefix); 16111 pw.print(" "); 16112 pw.print("oom: max="); pw.print(r.maxAdj); 16113 pw.print(" curRaw="); pw.print(r.curRawAdj); 16114 pw.print(" setRaw="); pw.print(r.setRawAdj); 16115 pw.print(" cur="); pw.print(r.curAdj); 16116 pw.print(" set="); pw.println(r.setAdj); 16117 pw.print(prefix); 16118 pw.print(" "); 16119 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 16120 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 16121 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024); 16122 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024); 16123 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024); 16124 pw.println(); 16125 pw.print(prefix); 16126 pw.print(" "); 16127 pw.print("cached="); pw.print(r.cached); 16128 pw.print(" empty="); pw.print(r.empty); 16129 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 16130 16131 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 16132 if (r.lastWakeTime != 0) { 16133 long wtime; 16134 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 16135 synchronized (stats) { 16136 wtime = stats.getProcessWakeTime(r.info.uid, 16137 r.pid, curRealtime); 16138 } 16139 long timeUsed = wtime - r.lastWakeTime; 16140 pw.print(prefix); 16141 pw.print(" "); 16142 pw.print("keep awake over "); 16143 TimeUtils.formatDuration(realtimeSince, pw); 16144 pw.print(" used "); 16145 TimeUtils.formatDuration(timeUsed, pw); 16146 pw.print(" ("); 16147 pw.print((timeUsed*100)/realtimeSince); 16148 pw.println("%)"); 16149 } 16150 if (r.lastCpuTime != 0) { 16151 long timeUsed = r.curCpuTime - r.lastCpuTime; 16152 pw.print(prefix); 16153 pw.print(" "); 16154 pw.print("run cpu over "); 16155 TimeUtils.formatDuration(uptimeSince, pw); 16156 pw.print(" used "); 16157 TimeUtils.formatDuration(timeUsed, pw); 16158 pw.print(" ("); 16159 pw.print((timeUsed*100)/uptimeSince); 16160 pw.println("%)"); 16161 } 16162 } 16163 } 16164 } 16165 return true; 16166 } 16167 16168 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 16169 String[] args) { 16170 ArrayList<ProcessRecord> procs; 16171 synchronized (this) { 16172 if (args != null && args.length > start 16173 && args[start].charAt(0) != '-') { 16174 procs = new ArrayList<ProcessRecord>(); 16175 int pid = -1; 16176 try { 16177 pid = Integer.parseInt(args[start]); 16178 } catch (NumberFormatException e) { 16179 } 16180 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16181 ProcessRecord proc = mLruProcesses.get(i); 16182 if (proc.pid == pid) { 16183 procs.add(proc); 16184 } else if (allPkgs && proc.pkgList != null 16185 && proc.pkgList.containsKey(args[start])) { 16186 procs.add(proc); 16187 } else if (proc.processName.equals(args[start])) { 16188 procs.add(proc); 16189 } 16190 } 16191 if (procs.size() <= 0) { 16192 return null; 16193 } 16194 } else { 16195 procs = new ArrayList<ProcessRecord>(mLruProcesses); 16196 } 16197 } 16198 return procs; 16199 } 16200 16201 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 16202 PrintWriter pw, String[] args) { 16203 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 16204 if (procs == null) { 16205 pw.println("No process found for: " + args[0]); 16206 return; 16207 } 16208 16209 long uptime = SystemClock.uptimeMillis(); 16210 long realtime = SystemClock.elapsedRealtime(); 16211 pw.println("Applications Graphics Acceleration Info:"); 16212 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 16213 16214 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 16215 ProcessRecord r = procs.get(i); 16216 if (r.thread != null) { 16217 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 16218 pw.flush(); 16219 try { 16220 TransferPipe tp = new TransferPipe(); 16221 try { 16222 r.thread.dumpGfxInfo(tp.getWriteFd(), args); 16223 tp.go(fd); 16224 } finally { 16225 tp.kill(); 16226 } 16227 } catch (IOException e) { 16228 pw.println("Failure while dumping the app: " + r); 16229 pw.flush(); 16230 } catch (RemoteException e) { 16231 pw.println("Got a RemoteException while dumping the app " + r); 16232 pw.flush(); 16233 } 16234 } 16235 } 16236 } 16237 16238 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 16239 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 16240 if (procs == null) { 16241 pw.println("No process found for: " + args[0]); 16242 return; 16243 } 16244 16245 pw.println("Applications Database Info:"); 16246 16247 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 16248 ProcessRecord r = procs.get(i); 16249 if (r.thread != null) { 16250 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 16251 pw.flush(); 16252 try { 16253 TransferPipe tp = new TransferPipe(); 16254 try { 16255 r.thread.dumpDbInfo(tp.getWriteFd(), args); 16256 tp.go(fd); 16257 } finally { 16258 tp.kill(); 16259 } 16260 } catch (IOException e) { 16261 pw.println("Failure while dumping the app: " + r); 16262 pw.flush(); 16263 } catch (RemoteException e) { 16264 pw.println("Got a RemoteException while dumping the app " + r); 16265 pw.flush(); 16266 } 16267 } 16268 } 16269 } 16270 16271 final static class MemItem { 16272 final boolean isProc; 16273 final String label; 16274 final String shortLabel; 16275 final long pss; 16276 final long swapPss; 16277 final int id; 16278 final boolean hasActivities; 16279 ArrayList<MemItem> subitems; 16280 16281 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id, 16282 boolean _hasActivities) { 16283 isProc = true; 16284 label = _label; 16285 shortLabel = _shortLabel; 16286 pss = _pss; 16287 swapPss = _swapPss; 16288 id = _id; 16289 hasActivities = _hasActivities; 16290 } 16291 16292 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) { 16293 isProc = false; 16294 label = _label; 16295 shortLabel = _shortLabel; 16296 pss = _pss; 16297 swapPss = _swapPss; 16298 id = _id; 16299 hasActivities = false; 16300 } 16301 } 16302 16303 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 16304 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) { 16305 if (sort && !isCompact) { 16306 Collections.sort(items, new Comparator<MemItem>() { 16307 @Override 16308 public int compare(MemItem lhs, MemItem rhs) { 16309 if (lhs.pss < rhs.pss) { 16310 return 1; 16311 } else if (lhs.pss > rhs.pss) { 16312 return -1; 16313 } 16314 return 0; 16315 } 16316 }); 16317 } 16318 16319 for (int i=0; i<items.size(); i++) { 16320 MemItem mi = items.get(i); 16321 if (!isCompact) { 16322 if (dumpSwapPss) { 16323 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss), 16324 mi.label, stringifyKBSize(mi.swapPss)); 16325 } else { 16326 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label); 16327 } 16328 } else if (mi.isProc) { 16329 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 16330 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(","); 16331 pw.print(dumpSwapPss ? mi.swapPss : "N/A"); 16332 pw.println(mi.hasActivities ? ",a" : ",e"); 16333 } else { 16334 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 16335 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A"); 16336 } 16337 if (mi.subitems != null) { 16338 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 16339 true, isCompact, dumpSwapPss); 16340 } 16341 } 16342 } 16343 16344 // These are in KB. 16345 static final long[] DUMP_MEM_BUCKETS = new long[] { 16346 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 16347 120*1024, 160*1024, 200*1024, 16348 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 16349 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 16350 }; 16351 16352 static final void appendMemBucket(StringBuilder out, long memKB, String label, 16353 boolean stackLike) { 16354 int start = label.lastIndexOf('.'); 16355 if (start >= 0) start++; 16356 else start = 0; 16357 int end = label.length(); 16358 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 16359 if (DUMP_MEM_BUCKETS[i] >= memKB) { 16360 long bucket = DUMP_MEM_BUCKETS[i]/1024; 16361 out.append(bucket); 16362 out.append(stackLike ? "MB." : "MB "); 16363 out.append(label, start, end); 16364 return; 16365 } 16366 } 16367 out.append(memKB/1024); 16368 out.append(stackLike ? "MB." : "MB "); 16369 out.append(label, start, end); 16370 } 16371 16372 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 16373 ProcessList.NATIVE_ADJ, 16374 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 16375 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 16376 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 16377 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 16378 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 16379 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ 16380 }; 16381 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 16382 "Native", 16383 "System", "Persistent", "Persistent Service", "Foreground", 16384 "Visible", "Perceptible", 16385 "Heavy Weight", "Backup", 16386 "A Services", "Home", 16387 "Previous", "B Services", "Cached" 16388 }; 16389 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 16390 "native", 16391 "sys", "pers", "persvc", "fore", 16392 "vis", "percept", 16393 "heavy", "backup", 16394 "servicea", "home", 16395 "prev", "serviceb", "cached" 16396 }; 16397 16398 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 16399 long realtime, boolean isCheckinRequest, boolean isCompact) { 16400 if (isCompact) { 16401 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION); 16402 } 16403 if (isCheckinRequest || isCompact) { 16404 // short checkin version 16405 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 16406 } else { 16407 pw.println("Applications Memory Usage (in Kilobytes):"); 16408 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 16409 } 16410 } 16411 16412 private static final int KSM_SHARED = 0; 16413 private static final int KSM_SHARING = 1; 16414 private static final int KSM_UNSHARED = 2; 16415 private static final int KSM_VOLATILE = 3; 16416 16417 private final long[] getKsmInfo() { 16418 long[] longOut = new long[4]; 16419 final int[] SINGLE_LONG_FORMAT = new int[] { 16420 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 16421 }; 16422 long[] longTmp = new long[1]; 16423 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 16424 SINGLE_LONG_FORMAT, null, longTmp, null); 16425 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 16426 longTmp[0] = 0; 16427 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 16428 SINGLE_LONG_FORMAT, null, longTmp, null); 16429 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 16430 longTmp[0] = 0; 16431 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 16432 SINGLE_LONG_FORMAT, null, longTmp, null); 16433 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 16434 longTmp[0] = 0; 16435 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 16436 SINGLE_LONG_FORMAT, null, longTmp, null); 16437 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 16438 return longOut; 16439 } 16440 16441 private static String stringifySize(long size, int order) { 16442 Locale locale = Locale.US; 16443 switch (order) { 16444 case 1: 16445 return String.format(locale, "%,13d", size); 16446 case 1024: 16447 return String.format(locale, "%,9dK", size / 1024); 16448 case 1024 * 1024: 16449 return String.format(locale, "%,5dM", size / 1024 / 1024); 16450 case 1024 * 1024 * 1024: 16451 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024); 16452 default: 16453 throw new IllegalArgumentException("Invalid size order"); 16454 } 16455 } 16456 16457 private static String stringifyKBSize(long size) { 16458 return stringifySize(size * 1024, 1024); 16459 } 16460 16461 // Update this version number in case you change the 'compact' format 16462 private static final int MEMINFO_COMPACT_VERSION = 1; 16463 16464 final void dumpApplicationMemoryUsage(FileDescriptor fd, 16465 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 16466 boolean dumpDetails = false; 16467 boolean dumpFullDetails = false; 16468 boolean dumpDalvik = false; 16469 boolean dumpSummaryOnly = false; 16470 boolean dumpUnreachable = false; 16471 boolean oomOnly = false; 16472 boolean isCompact = false; 16473 boolean localOnly = false; 16474 boolean packages = false; 16475 boolean isCheckinRequest = false; 16476 boolean dumpSwapPss = false; 16477 16478 int opti = 0; 16479 while (opti < args.length) { 16480 String opt = args[opti]; 16481 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 16482 break; 16483 } 16484 opti++; 16485 if ("-a".equals(opt)) { 16486 dumpDetails = true; 16487 dumpFullDetails = true; 16488 dumpDalvik = true; 16489 dumpSwapPss = true; 16490 } else if ("-d".equals(opt)) { 16491 dumpDalvik = true; 16492 } else if ("-c".equals(opt)) { 16493 isCompact = true; 16494 } else if ("-s".equals(opt)) { 16495 dumpDetails = true; 16496 dumpSummaryOnly = true; 16497 } else if ("-S".equals(opt)) { 16498 dumpSwapPss = true; 16499 } else if ("--unreachable".equals(opt)) { 16500 dumpUnreachable = true; 16501 } else if ("--oom".equals(opt)) { 16502 oomOnly = true; 16503 } else if ("--local".equals(opt)) { 16504 localOnly = true; 16505 } else if ("--package".equals(opt)) { 16506 packages = true; 16507 } else if ("--checkin".equals(opt)) { 16508 isCheckinRequest = true; 16509 16510 } else if ("-h".equals(opt)) { 16511 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]"); 16512 pw.println(" -a: include all available information for each process."); 16513 pw.println(" -d: include dalvik details."); 16514 pw.println(" -c: dump in a compact machine-parseable representation."); 16515 pw.println(" -s: dump only summary of application memory usage."); 16516 pw.println(" -S: dump also SwapPss."); 16517 pw.println(" --oom: only show processes organized by oom adj."); 16518 pw.println(" --local: only collect details locally, don't call process."); 16519 pw.println(" --package: interpret process arg as package, dumping all"); 16520 pw.println(" processes that have loaded that package."); 16521 pw.println(" --checkin: dump data for a checkin"); 16522 pw.println("If [process] is specified it can be the name or "); 16523 pw.println("pid of a specific process to dump."); 16524 return; 16525 } else { 16526 pw.println("Unknown argument: " + opt + "; use -h for help"); 16527 } 16528 } 16529 16530 long uptime = SystemClock.uptimeMillis(); 16531 long realtime = SystemClock.elapsedRealtime(); 16532 final long[] tmpLong = new long[1]; 16533 16534 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 16535 if (procs == null) { 16536 // No Java processes. Maybe they want to print a native process. 16537 if (args != null && args.length > opti 16538 && args[opti].charAt(0) != '-') { 16539 ArrayList<ProcessCpuTracker.Stats> nativeProcs 16540 = new ArrayList<ProcessCpuTracker.Stats>(); 16541 updateCpuStatsNow(); 16542 int findPid = -1; 16543 try { 16544 findPid = Integer.parseInt(args[opti]); 16545 } catch (NumberFormatException e) { 16546 } 16547 synchronized (mProcessCpuTracker) { 16548 final int N = mProcessCpuTracker.countStats(); 16549 for (int i=0; i<N; i++) { 16550 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 16551 if (st.pid == findPid || (st.baseName != null 16552 && st.baseName.equals(args[opti]))) { 16553 nativeProcs.add(st); 16554 } 16555 } 16556 } 16557 if (nativeProcs.size() > 0) { 16558 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 16559 isCompact); 16560 Debug.MemoryInfo mi = null; 16561 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 16562 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 16563 final int pid = r.pid; 16564 if (!isCheckinRequest && dumpDetails) { 16565 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 16566 } 16567 if (mi == null) { 16568 mi = new Debug.MemoryInfo(); 16569 } 16570 if (dumpDetails || (!brief && !oomOnly)) { 16571 Debug.getMemoryInfo(pid, mi); 16572 } else { 16573 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 16574 mi.dalvikPrivateDirty = (int)tmpLong[0]; 16575 } 16576 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 16577 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0); 16578 if (isCheckinRequest) { 16579 pw.println(); 16580 } 16581 } 16582 return; 16583 } 16584 } 16585 pw.println("No process found for: " + args[opti]); 16586 return; 16587 } 16588 16589 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 16590 dumpDetails = true; 16591 } 16592 16593 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 16594 16595 String[] innerArgs = new String[args.length-opti]; 16596 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 16597 16598 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 16599 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 16600 long nativePss = 0; 16601 long nativeSwapPss = 0; 16602 long dalvikPss = 0; 16603 long dalvikSwapPss = 0; 16604 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] : 16605 EmptyArray.LONG; 16606 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] : 16607 EmptyArray.LONG; 16608 long otherPss = 0; 16609 long otherSwapPss = 0; 16610 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 16611 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 16612 16613 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 16614 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 16615 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 16616 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 16617 16618 long totalPss = 0; 16619 long totalSwapPss = 0; 16620 long cachedPss = 0; 16621 long cachedSwapPss = 0; 16622 boolean hasSwapPss = false; 16623 16624 Debug.MemoryInfo mi = null; 16625 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 16626 final ProcessRecord r = procs.get(i); 16627 final IApplicationThread thread; 16628 final int pid; 16629 final int oomAdj; 16630 final boolean hasActivities; 16631 synchronized (this) { 16632 thread = r.thread; 16633 pid = r.pid; 16634 oomAdj = r.getSetAdjWithServices(); 16635 hasActivities = r.activities.size() > 0; 16636 } 16637 if (thread != null) { 16638 if (!isCheckinRequest && dumpDetails) { 16639 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 16640 } 16641 if (mi == null) { 16642 mi = new Debug.MemoryInfo(); 16643 } 16644 if (dumpDetails || (!brief && !oomOnly)) { 16645 Debug.getMemoryInfo(pid, mi); 16646 hasSwapPss = mi.hasSwappedOutPss; 16647 } else { 16648 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 16649 mi.dalvikPrivateDirty = (int)tmpLong[0]; 16650 } 16651 if (dumpDetails) { 16652 if (localOnly) { 16653 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 16654 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0); 16655 if (isCheckinRequest) { 16656 pw.println(); 16657 } 16658 } else { 16659 pw.flush(); 16660 try { 16661 TransferPipe tp = new TransferPipe(); 16662 try { 16663 thread.dumpMemInfo(tp.getWriteFd(), 16664 mi, isCheckinRequest, dumpFullDetails, 16665 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs); 16666 tp.go(fd); 16667 } finally { 16668 tp.kill(); 16669 } 16670 } catch (IOException e) { 16671 if (!isCheckinRequest) { 16672 pw.println("Got IoException!"); 16673 pw.flush(); 16674 } 16675 } catch (RemoteException e) { 16676 if (!isCheckinRequest) { 16677 pw.println("Got RemoteException!"); 16678 pw.flush(); 16679 } 16680 } 16681 } 16682 } 16683 16684 final long myTotalPss = mi.getTotalPss(); 16685 final long myTotalUss = mi.getTotalUss(); 16686 final long myTotalSwapPss = mi.getTotalSwappedOutPss(); 16687 16688 synchronized (this) { 16689 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 16690 // Record this for posterity if the process has been stable. 16691 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 16692 } 16693 } 16694 16695 if (!isCheckinRequest && mi != null) { 16696 totalPss += myTotalPss; 16697 totalSwapPss += myTotalSwapPss; 16698 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 16699 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss, 16700 myTotalSwapPss, pid, hasActivities); 16701 procMems.add(pssItem); 16702 procMemsMap.put(pid, pssItem); 16703 16704 nativePss += mi.nativePss; 16705 nativeSwapPss += mi.nativeSwappedOutPss; 16706 dalvikPss += mi.dalvikPss; 16707 dalvikSwapPss += mi.dalvikSwappedOutPss; 16708 for (int j=0; j<dalvikSubitemPss.length; j++) { 16709 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 16710 dalvikSubitemSwapPss[j] += 16711 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 16712 } 16713 otherPss += mi.otherPss; 16714 otherSwapPss += mi.otherSwappedOutPss; 16715 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 16716 long mem = mi.getOtherPss(j); 16717 miscPss[j] += mem; 16718 otherPss -= mem; 16719 mem = mi.getOtherSwappedOutPss(j); 16720 miscSwapPss[j] += mem; 16721 otherSwapPss -= mem; 16722 } 16723 16724 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 16725 cachedPss += myTotalPss; 16726 cachedSwapPss += myTotalSwapPss; 16727 } 16728 16729 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 16730 if (oomIndex == (oomPss.length - 1) 16731 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex] 16732 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) { 16733 oomPss[oomIndex] += myTotalPss; 16734 oomSwapPss[oomIndex] += myTotalSwapPss; 16735 if (oomProcs[oomIndex] == null) { 16736 oomProcs[oomIndex] = new ArrayList<MemItem>(); 16737 } 16738 oomProcs[oomIndex].add(pssItem); 16739 break; 16740 } 16741 } 16742 } 16743 } 16744 } 16745 16746 long nativeProcTotalPss = 0; 16747 16748 if (!isCheckinRequest && procs.size() > 1 && !packages) { 16749 // If we are showing aggregations, also look for native processes to 16750 // include so that our aggregations are more accurate. 16751 updateCpuStatsNow(); 16752 mi = null; 16753 synchronized (mProcessCpuTracker) { 16754 final int N = mProcessCpuTracker.countStats(); 16755 for (int i=0; i<N; i++) { 16756 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 16757 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 16758 if (mi == null) { 16759 mi = new Debug.MemoryInfo(); 16760 } 16761 if (!brief && !oomOnly) { 16762 Debug.getMemoryInfo(st.pid, mi); 16763 } else { 16764 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 16765 mi.nativePrivateDirty = (int)tmpLong[0]; 16766 } 16767 16768 final long myTotalPss = mi.getTotalPss(); 16769 final long myTotalSwapPss = mi.getTotalSwappedOutPss(); 16770 totalPss += myTotalPss; 16771 nativeProcTotalPss += myTotalPss; 16772 16773 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 16774 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false); 16775 procMems.add(pssItem); 16776 16777 nativePss += mi.nativePss; 16778 nativeSwapPss += mi.nativeSwappedOutPss; 16779 dalvikPss += mi.dalvikPss; 16780 dalvikSwapPss += mi.dalvikSwappedOutPss; 16781 for (int j=0; j<dalvikSubitemPss.length; j++) { 16782 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 16783 dalvikSubitemSwapPss[j] += 16784 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 16785 } 16786 otherPss += mi.otherPss; 16787 otherSwapPss += mi.otherSwappedOutPss; 16788 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 16789 long mem = mi.getOtherPss(j); 16790 miscPss[j] += mem; 16791 otherPss -= mem; 16792 mem = mi.getOtherSwappedOutPss(j); 16793 miscSwapPss[j] += mem; 16794 otherSwapPss -= mem; 16795 } 16796 oomPss[0] += myTotalPss; 16797 oomSwapPss[0] += myTotalSwapPss; 16798 if (oomProcs[0] == null) { 16799 oomProcs[0] = new ArrayList<MemItem>(); 16800 } 16801 oomProcs[0].add(pssItem); 16802 } 16803 } 16804 } 16805 16806 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 16807 16808 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1)); 16809 final MemItem dalvikItem = 16810 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2); 16811 if (dalvikSubitemPss.length > 0) { 16812 dalvikItem.subitems = new ArrayList<MemItem>(); 16813 for (int j=0; j<dalvikSubitemPss.length; j++) { 16814 final String name = Debug.MemoryInfo.getOtherLabel( 16815 Debug.MemoryInfo.NUM_OTHER_STATS + j); 16816 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], 16817 dalvikSubitemSwapPss[j], j)); 16818 } 16819 } 16820 catMems.add(dalvikItem); 16821 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3)); 16822 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 16823 String label = Debug.MemoryInfo.getOtherLabel(j); 16824 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j)); 16825 } 16826 16827 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 16828 for (int j=0; j<oomPss.length; j++) { 16829 if (oomPss[j] != 0) { 16830 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 16831 : DUMP_MEM_OOM_LABEL[j]; 16832 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j], 16833 DUMP_MEM_OOM_ADJ[j]); 16834 item.subitems = oomProcs[j]; 16835 oomMems.add(item); 16836 } 16837 } 16838 16839 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0; 16840 if (!brief && !oomOnly && !isCompact) { 16841 pw.println(); 16842 pw.println("Total PSS by process:"); 16843 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss); 16844 pw.println(); 16845 } 16846 if (!isCompact) { 16847 pw.println("Total PSS by OOM adjustment:"); 16848 } 16849 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss); 16850 if (!brief && !oomOnly) { 16851 PrintWriter out = categoryPw != null ? categoryPw : pw; 16852 if (!isCompact) { 16853 out.println(); 16854 out.println("Total PSS by category:"); 16855 } 16856 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss); 16857 } 16858 if (!isCompact) { 16859 pw.println(); 16860 } 16861 MemInfoReader memInfo = new MemInfoReader(); 16862 memInfo.readMemInfo(); 16863 if (nativeProcTotalPss > 0) { 16864 synchronized (this) { 16865 final long cachedKb = memInfo.getCachedSizeKb(); 16866 final long freeKb = memInfo.getFreeSizeKb(); 16867 final long zramKb = memInfo.getZramTotalSizeKb(); 16868 final long kernelKb = memInfo.getKernelUsedSizeKb(); 16869 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024, 16870 kernelKb*1024, nativeProcTotalPss*1024); 16871 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb, 16872 nativeProcTotalPss); 16873 } 16874 } 16875 if (!brief) { 16876 if (!isCompact) { 16877 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb())); 16878 pw.print(" (status "); 16879 switch (mLastMemoryLevel) { 16880 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 16881 pw.println("normal)"); 16882 break; 16883 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 16884 pw.println("moderate)"); 16885 break; 16886 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16887 pw.println("low)"); 16888 break; 16889 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16890 pw.println("critical)"); 16891 break; 16892 default: 16893 pw.print(mLastMemoryLevel); 16894 pw.println(")"); 16895 break; 16896 } 16897 pw.print(" Free RAM: "); 16898 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() 16899 + memInfo.getFreeSizeKb())); 16900 pw.print(" ("); 16901 pw.print(stringifyKBSize(cachedPss)); 16902 pw.print(" cached pss + "); 16903 pw.print(stringifyKBSize(memInfo.getCachedSizeKb())); 16904 pw.print(" cached kernel + "); 16905 pw.print(stringifyKBSize(memInfo.getFreeSizeKb())); 16906 pw.println(" free)"); 16907 } else { 16908 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 16909 pw.print(cachedPss + memInfo.getCachedSizeKb() 16910 + memInfo.getFreeSizeKb()); pw.print(","); 16911 pw.println(totalPss - cachedPss); 16912 } 16913 } 16914 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss) 16915 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 16916 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb(); 16917 if (!isCompact) { 16918 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss 16919 + memInfo.getKernelUsedSizeKb())); pw.print(" ("); 16920 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + "); 16921 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n"); 16922 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM)); 16923 } else { 16924 pw.print("lostram,"); pw.println(lostRAM); 16925 } 16926 if (!brief) { 16927 if (memInfo.getZramTotalSizeKb() != 0) { 16928 if (!isCompact) { 16929 pw.print(" ZRAM: "); 16930 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb())); 16931 pw.print(" physical used for "); 16932 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb() 16933 - memInfo.getSwapFreeSizeKb())); 16934 pw.print(" in swap ("); 16935 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb())); 16936 pw.println(" total swap)"); 16937 } else { 16938 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 16939 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 16940 pw.println(memInfo.getSwapFreeSizeKb()); 16941 } 16942 } 16943 final long[] ksm = getKsmInfo(); 16944 if (!isCompact) { 16945 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 16946 || ksm[KSM_VOLATILE] != 0) { 16947 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING])); 16948 pw.print(" saved from shared "); 16949 pw.print(stringifyKBSize(ksm[KSM_SHARED])); 16950 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED])); 16951 pw.print(" unshared; "); 16952 pw.print(stringifyKBSize( 16953 ksm[KSM_VOLATILE])); pw.println(" volatile"); 16954 } 16955 pw.print(" Tuning: "); 16956 pw.print(ActivityManager.staticGetMemoryClass()); 16957 pw.print(" (large "); 16958 pw.print(ActivityManager.staticGetLargeMemoryClass()); 16959 pw.print("), oom "); 16960 pw.print(stringifySize( 16961 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024)); 16962 pw.print(", restore limit "); 16963 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb())); 16964 if (ActivityManager.isLowRamDeviceStatic()) { 16965 pw.print(" (low-ram)"); 16966 } 16967 if (ActivityManager.isHighEndGfx()) { 16968 pw.print(" (high-end-gfx)"); 16969 } 16970 pw.println(); 16971 } else { 16972 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 16973 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 16974 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 16975 pw.print("tuning,"); 16976 pw.print(ActivityManager.staticGetMemoryClass()); 16977 pw.print(','); 16978 pw.print(ActivityManager.staticGetLargeMemoryClass()); 16979 pw.print(','); 16980 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 16981 if (ActivityManager.isLowRamDeviceStatic()) { 16982 pw.print(",low-ram"); 16983 } 16984 if (ActivityManager.isHighEndGfx()) { 16985 pw.print(",high-end-gfx"); 16986 } 16987 pw.println(); 16988 } 16989 } 16990 } 16991 } 16992 16993 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 16994 long memtrack, String name) { 16995 sb.append(" "); 16996 sb.append(ProcessList.makeOomAdjString(oomAdj)); 16997 sb.append(' '); 16998 sb.append(ProcessList.makeProcStateString(procState)); 16999 sb.append(' '); 17000 ProcessList.appendRamKb(sb, pss); 17001 sb.append(": "); 17002 sb.append(name); 17003 if (memtrack > 0) { 17004 sb.append(" ("); 17005 sb.append(stringifyKBSize(memtrack)); 17006 sb.append(" memtrack)"); 17007 } 17008 } 17009 17010 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 17011 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 17012 sb.append(" (pid "); 17013 sb.append(mi.pid); 17014 sb.append(") "); 17015 sb.append(mi.adjType); 17016 sb.append('\n'); 17017 if (mi.adjReason != null) { 17018 sb.append(" "); 17019 sb.append(mi.adjReason); 17020 sb.append('\n'); 17021 } 17022 } 17023 17024 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 17025 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 17026 for (int i=0, N=memInfos.size(); i<N; i++) { 17027 ProcessMemInfo mi = memInfos.get(i); 17028 infoMap.put(mi.pid, mi); 17029 } 17030 updateCpuStatsNow(); 17031 long[] memtrackTmp = new long[1]; 17032 final List<ProcessCpuTracker.Stats> stats; 17033 // Get a list of Stats that have vsize > 0 17034 synchronized (mProcessCpuTracker) { 17035 stats = mProcessCpuTracker.getStats((st) -> { 17036 return st.vsize > 0; 17037 }); 17038 } 17039 final int statsCount = stats.size(); 17040 for (int i = 0; i < statsCount; i++) { 17041 ProcessCpuTracker.Stats st = stats.get(i); 17042 long pss = Debug.getPss(st.pid, null, memtrackTmp); 17043 if (pss > 0) { 17044 if (infoMap.indexOfKey(st.pid) < 0) { 17045 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 17046 ProcessList.NATIVE_ADJ, -1, "native", null); 17047 mi.pss = pss; 17048 mi.memtrack = memtrackTmp[0]; 17049 memInfos.add(mi); 17050 } 17051 } 17052 } 17053 17054 long totalPss = 0; 17055 long totalMemtrack = 0; 17056 for (int i=0, N=memInfos.size(); i<N; i++) { 17057 ProcessMemInfo mi = memInfos.get(i); 17058 if (mi.pss == 0) { 17059 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 17060 mi.memtrack = memtrackTmp[0]; 17061 } 17062 totalPss += mi.pss; 17063 totalMemtrack += mi.memtrack; 17064 } 17065 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 17066 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 17067 if (lhs.oomAdj != rhs.oomAdj) { 17068 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 17069 } 17070 if (lhs.pss != rhs.pss) { 17071 return lhs.pss < rhs.pss ? 1 : -1; 17072 } 17073 return 0; 17074 } 17075 }); 17076 17077 StringBuilder tag = new StringBuilder(128); 17078 StringBuilder stack = new StringBuilder(128); 17079 tag.append("Low on memory -- "); 17080 appendMemBucket(tag, totalPss, "total", false); 17081 appendMemBucket(stack, totalPss, "total", true); 17082 17083 StringBuilder fullNativeBuilder = new StringBuilder(1024); 17084 StringBuilder shortNativeBuilder = new StringBuilder(1024); 17085 StringBuilder fullJavaBuilder = new StringBuilder(1024); 17086 17087 boolean firstLine = true; 17088 int lastOomAdj = Integer.MIN_VALUE; 17089 long extraNativeRam = 0; 17090 long extraNativeMemtrack = 0; 17091 long cachedPss = 0; 17092 for (int i=0, N=memInfos.size(); i<N; i++) { 17093 ProcessMemInfo mi = memInfos.get(i); 17094 17095 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 17096 cachedPss += mi.pss; 17097 } 17098 17099 if (mi.oomAdj != ProcessList.NATIVE_ADJ 17100 && (mi.oomAdj < ProcessList.SERVICE_ADJ 17101 || mi.oomAdj == ProcessList.HOME_APP_ADJ 17102 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 17103 if (lastOomAdj != mi.oomAdj) { 17104 lastOomAdj = mi.oomAdj; 17105 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 17106 tag.append(" / "); 17107 } 17108 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 17109 if (firstLine) { 17110 stack.append(":"); 17111 firstLine = false; 17112 } 17113 stack.append("\n\t at "); 17114 } else { 17115 stack.append("$"); 17116 } 17117 } else { 17118 tag.append(" "); 17119 stack.append("$"); 17120 } 17121 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 17122 appendMemBucket(tag, mi.pss, mi.name, false); 17123 } 17124 appendMemBucket(stack, mi.pss, mi.name, true); 17125 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 17126 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 17127 stack.append("("); 17128 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 17129 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 17130 stack.append(DUMP_MEM_OOM_LABEL[k]); 17131 stack.append(":"); 17132 stack.append(DUMP_MEM_OOM_ADJ[k]); 17133 } 17134 } 17135 stack.append(")"); 17136 } 17137 } 17138 17139 appendMemInfo(fullNativeBuilder, mi); 17140 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 17141 // The short form only has native processes that are >= 512K. 17142 if (mi.pss >= 512) { 17143 appendMemInfo(shortNativeBuilder, mi); 17144 } else { 17145 extraNativeRam += mi.pss; 17146 extraNativeMemtrack += mi.memtrack; 17147 } 17148 } else { 17149 // Short form has all other details, but if we have collected RAM 17150 // from smaller native processes let's dump a summary of that. 17151 if (extraNativeRam > 0) { 17152 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 17153 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 17154 shortNativeBuilder.append('\n'); 17155 extraNativeRam = 0; 17156 } 17157 appendMemInfo(fullJavaBuilder, mi); 17158 } 17159 } 17160 17161 fullJavaBuilder.append(" "); 17162 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 17163 fullJavaBuilder.append(": TOTAL"); 17164 if (totalMemtrack > 0) { 17165 fullJavaBuilder.append(" ("); 17166 fullJavaBuilder.append(stringifyKBSize(totalMemtrack)); 17167 fullJavaBuilder.append(" memtrack)"); 17168 } else { 17169 } 17170 fullJavaBuilder.append("\n"); 17171 17172 MemInfoReader memInfo = new MemInfoReader(); 17173 memInfo.readMemInfo(); 17174 final long[] infos = memInfo.getRawInfo(); 17175 17176 StringBuilder memInfoBuilder = new StringBuilder(1024); 17177 Debug.getMemInfo(infos); 17178 memInfoBuilder.append(" MemInfo: "); 17179 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, "); 17180 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, "); 17181 memInfoBuilder.append(stringifyKBSize( 17182 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, "); 17183 memInfoBuilder.append(stringifyKBSize( 17184 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables "); 17185 memInfoBuilder.append(stringifyKBSize( 17186 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n"); 17187 memInfoBuilder.append(" "); 17188 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, "); 17189 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, "); 17190 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, "); 17191 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n"); 17192 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 17193 memInfoBuilder.append(" ZRAM: "); 17194 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL])); 17195 memInfoBuilder.append(" RAM, "); 17196 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL])); 17197 memInfoBuilder.append(" swap total, "); 17198 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE])); 17199 memInfoBuilder.append(" swap free\n"); 17200 } 17201 final long[] ksm = getKsmInfo(); 17202 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 17203 || ksm[KSM_VOLATILE] != 0) { 17204 memInfoBuilder.append(" KSM: "); 17205 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING])); 17206 memInfoBuilder.append(" saved from shared "); 17207 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED])); 17208 memInfoBuilder.append("\n "); 17209 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED])); 17210 memInfoBuilder.append(" unshared; "); 17211 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE])); 17212 memInfoBuilder.append(" volatile\n"); 17213 } 17214 memInfoBuilder.append(" Free RAM: "); 17215 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() 17216 + memInfo.getFreeSizeKb())); 17217 memInfoBuilder.append("\n"); 17218 memInfoBuilder.append(" Used RAM: "); 17219 memInfoBuilder.append(stringifyKBSize( 17220 totalPss - cachedPss + memInfo.getKernelUsedSizeKb())); 17221 memInfoBuilder.append("\n"); 17222 memInfoBuilder.append(" Lost RAM: "); 17223 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb() 17224 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 17225 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb())); 17226 memInfoBuilder.append("\n"); 17227 Slog.i(TAG, "Low on memory:"); 17228 Slog.i(TAG, shortNativeBuilder.toString()); 17229 Slog.i(TAG, fullJavaBuilder.toString()); 17230 Slog.i(TAG, memInfoBuilder.toString()); 17231 17232 StringBuilder dropBuilder = new StringBuilder(1024); 17233 /* 17234 StringWriter oomSw = new StringWriter(); 17235 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 17236 StringWriter catSw = new StringWriter(); 17237 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 17238 String[] emptyArgs = new String[] { }; 17239 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 17240 oomPw.flush(); 17241 String oomString = oomSw.toString(); 17242 */ 17243 dropBuilder.append("Low on memory:"); 17244 dropBuilder.append(stack); 17245 dropBuilder.append('\n'); 17246 dropBuilder.append(fullNativeBuilder); 17247 dropBuilder.append(fullJavaBuilder); 17248 dropBuilder.append('\n'); 17249 dropBuilder.append(memInfoBuilder); 17250 dropBuilder.append('\n'); 17251 /* 17252 dropBuilder.append(oomString); 17253 dropBuilder.append('\n'); 17254 */ 17255 StringWriter catSw = new StringWriter(); 17256 synchronized (ActivityManagerService.this) { 17257 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 17258 String[] emptyArgs = new String[] { }; 17259 catPw.println(); 17260 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 17261 catPw.println(); 17262 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, 17263 false, null).dumpLocked(); 17264 catPw.println(); 17265 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 17266 catPw.flush(); 17267 } 17268 dropBuilder.append(catSw.toString()); 17269 addErrorToDropBox("lowmem", null, "system_server", null, 17270 null, tag.toString(), dropBuilder.toString(), null, null); 17271 //Slog.i(TAG, "Sent to dropbox:"); 17272 //Slog.i(TAG, dropBuilder.toString()); 17273 synchronized (ActivityManagerService.this) { 17274 long now = SystemClock.uptimeMillis(); 17275 if (mLastMemUsageReportTime < now) { 17276 mLastMemUsageReportTime = now; 17277 } 17278 } 17279 } 17280 17281 /** 17282 * Searches array of arguments for the specified string 17283 * @param args array of argument strings 17284 * @param value value to search for 17285 * @return true if the value is contained in the array 17286 */ 17287 private static boolean scanArgs(String[] args, String value) { 17288 if (args != null) { 17289 for (String arg : args) { 17290 if (value.equals(arg)) { 17291 return true; 17292 } 17293 } 17294 } 17295 return false; 17296 } 17297 17298 private final boolean removeDyingProviderLocked(ProcessRecord proc, 17299 ContentProviderRecord cpr, boolean always) { 17300 final boolean inLaunching = mLaunchingProviders.contains(cpr); 17301 17302 if (!inLaunching || always) { 17303 synchronized (cpr) { 17304 cpr.launchingApp = null; 17305 cpr.notifyAll(); 17306 } 17307 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 17308 String names[] = cpr.info.authority.split(";"); 17309 for (int j = 0; j < names.length; j++) { 17310 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 17311 } 17312 } 17313 17314 for (int i = cpr.connections.size() - 1; i >= 0; i--) { 17315 ContentProviderConnection conn = cpr.connections.get(i); 17316 if (conn.waiting) { 17317 // If this connection is waiting for the provider, then we don't 17318 // need to mess with its process unless we are always removing 17319 // or for some reason the provider is not currently launching. 17320 if (inLaunching && !always) { 17321 continue; 17322 } 17323 } 17324 ProcessRecord capp = conn.client; 17325 conn.dead = true; 17326 if (conn.stableCount > 0) { 17327 if (!capp.persistent && capp.thread != null 17328 && capp.pid != 0 17329 && capp.pid != MY_PID) { 17330 capp.kill("depends on provider " 17331 + cpr.name.flattenToShortString() 17332 + " in dying proc " + (proc != null ? proc.processName : "??") 17333 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true); 17334 } 17335 } else if (capp.thread != null && conn.provider.provider != null) { 17336 try { 17337 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 17338 } catch (RemoteException e) { 17339 } 17340 // In the protocol here, we don't expect the client to correctly 17341 // clean up this connection, we'll just remove it. 17342 cpr.connections.remove(i); 17343 if (conn.client.conProviders.remove(conn)) { 17344 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 17345 } 17346 } 17347 } 17348 17349 if (inLaunching && always) { 17350 mLaunchingProviders.remove(cpr); 17351 } 17352 return inLaunching; 17353 } 17354 17355 /** 17356 * Main code for cleaning up a process when it has gone away. This is 17357 * called both as a result of the process dying, or directly when stopping 17358 * a process when running in single process mode. 17359 * 17360 * @return Returns true if the given process has been restarted, so the 17361 * app that was passed in must remain on the process lists. 17362 */ 17363 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 17364 boolean restarting, boolean allowRestart, int index, boolean replacingPid) { 17365 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid); 17366 if (index >= 0) { 17367 removeLruProcessLocked(app); 17368 ProcessList.remove(app.pid); 17369 } 17370 17371 mProcessesToGc.remove(app); 17372 mPendingPssProcesses.remove(app); 17373 17374 // Dismiss any open dialogs. 17375 if (app.crashDialog != null && !app.forceCrashReport) { 17376 app.crashDialog.dismiss(); 17377 app.crashDialog = null; 17378 } 17379 if (app.anrDialog != null) { 17380 app.anrDialog.dismiss(); 17381 app.anrDialog = null; 17382 } 17383 if (app.waitDialog != null) { 17384 app.waitDialog.dismiss(); 17385 app.waitDialog = null; 17386 } 17387 17388 app.crashing = false; 17389 app.notResponding = false; 17390 17391 app.resetPackageList(mProcessStats); 17392 app.unlinkDeathRecipient(); 17393 app.makeInactive(mProcessStats); 17394 app.waitingToKill = null; 17395 app.forcingToForeground = null; 17396 updateProcessForegroundLocked(app, false, false); 17397 app.foregroundActivities = false; 17398 app.hasShownUi = false; 17399 app.treatLikeActivity = false; 17400 app.hasAboveClient = false; 17401 app.hasClientActivities = false; 17402 17403 mServices.killServicesLocked(app, allowRestart); 17404 17405 boolean restart = false; 17406 17407 // Remove published content providers. 17408 for (int i = app.pubProviders.size() - 1; i >= 0; i--) { 17409 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 17410 final boolean always = app.bad || !allowRestart; 17411 boolean inLaunching = removeDyingProviderLocked(app, cpr, always); 17412 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) { 17413 // We left the provider in the launching list, need to 17414 // restart it. 17415 restart = true; 17416 } 17417 17418 cpr.provider = null; 17419 cpr.proc = null; 17420 } 17421 app.pubProviders.clear(); 17422 17423 // Take care of any launching providers waiting for this process. 17424 if (cleanupAppInLaunchingProvidersLocked(app, false)) { 17425 restart = true; 17426 } 17427 17428 // Unregister from connected content providers. 17429 if (!app.conProviders.isEmpty()) { 17430 for (int i = app.conProviders.size() - 1; i >= 0; i--) { 17431 ContentProviderConnection conn = app.conProviders.get(i); 17432 conn.provider.connections.remove(conn); 17433 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 17434 conn.provider.name); 17435 } 17436 app.conProviders.clear(); 17437 } 17438 17439 // At this point there may be remaining entries in mLaunchingProviders 17440 // where we were the only one waiting, so they are no longer of use. 17441 // Look for these and clean up if found. 17442 // XXX Commented out for now. Trying to figure out a way to reproduce 17443 // the actual situation to identify what is actually going on. 17444 if (false) { 17445 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 17446 ContentProviderRecord cpr = mLaunchingProviders.get(i); 17447 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 17448 synchronized (cpr) { 17449 cpr.launchingApp = null; 17450 cpr.notifyAll(); 17451 } 17452 } 17453 } 17454 } 17455 17456 skipCurrentReceiverLocked(app); 17457 17458 // Unregister any receivers. 17459 for (int i = app.receivers.size() - 1; i >= 0; i--) { 17460 removeReceiverLocked(app.receivers.valueAt(i)); 17461 } 17462 app.receivers.clear(); 17463 17464 // If the app is undergoing backup, tell the backup manager about it 17465 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 17466 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App " 17467 + mBackupTarget.appInfo + " died during backup"); 17468 mHandler.post(new Runnable() { 17469 @Override 17470 public void run(){ 17471 try { 17472 IBackupManager bm = IBackupManager.Stub.asInterface( 17473 ServiceManager.getService(Context.BACKUP_SERVICE)); 17474 bm.agentDisconnected(app.info.packageName); 17475 } catch (RemoteException e) { 17476 // can't happen; backup manager is local 17477 } 17478 } 17479 }); 17480 } 17481 17482 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) { 17483 ProcessChangeItem item = mPendingProcessChanges.get(i); 17484 if (item.pid == app.pid) { 17485 mPendingProcessChanges.remove(i); 17486 mAvailProcessChanges.add(item); 17487 } 17488 } 17489 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid, 17490 null).sendToTarget(); 17491 17492 // If the caller is restarting this app, then leave it in its 17493 // current lists and let the caller take care of it. 17494 if (restarting) { 17495 return false; 17496 } 17497 17498 if (!app.persistent || app.isolated) { 17499 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 17500 "Removing non-persistent process during cleanup: " + app); 17501 if (!replacingPid) { 17502 removeProcessNameLocked(app.processName, app.uid, app); 17503 } 17504 if (mHeavyWeightProcess == app) { 17505 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 17506 mHeavyWeightProcess.userId, 0)); 17507 mHeavyWeightProcess = null; 17508 } 17509 } else if (!app.removed) { 17510 // This app is persistent, so we need to keep its record around. 17511 // If it is not already on the pending app list, add it there 17512 // and start a new process for it. 17513 if (mPersistentStartingProcesses.indexOf(app) < 0) { 17514 mPersistentStartingProcesses.add(app); 17515 restart = true; 17516 } 17517 } 17518 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v( 17519 TAG_CLEANUP, "Clean-up removing on hold: " + app); 17520 mProcessesOnHold.remove(app); 17521 17522 if (app == mHomeProcess) { 17523 mHomeProcess = null; 17524 } 17525 if (app == mPreviousProcess) { 17526 mPreviousProcess = null; 17527 } 17528 17529 if (restart && !app.isolated) { 17530 // We have components that still need to be running in the 17531 // process, so re-launch it. 17532 if (index < 0) { 17533 ProcessList.remove(app.pid); 17534 } 17535 addProcessNameLocked(app); 17536 startProcessLocked(app, "restart", app.processName); 17537 return true; 17538 } else if (app.pid > 0 && app.pid != MY_PID) { 17539 // Goodbye! 17540 boolean removed; 17541 synchronized (mPidsSelfLocked) { 17542 mPidsSelfLocked.remove(app.pid); 17543 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 17544 } 17545 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 17546 if (app.isolated) { 17547 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 17548 } 17549 app.setPid(0); 17550 } 17551 return false; 17552 } 17553 17554 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) { 17555 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 17556 ContentProviderRecord cpr = mLaunchingProviders.get(i); 17557 if (cpr.launchingApp == app) { 17558 return true; 17559 } 17560 } 17561 return false; 17562 } 17563 17564 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 17565 // Look through the content providers we are waiting to have launched, 17566 // and if any run in this process then either schedule a restart of 17567 // the process or kill the client waiting for it if this process has 17568 // gone bad. 17569 boolean restart = false; 17570 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 17571 ContentProviderRecord cpr = mLaunchingProviders.get(i); 17572 if (cpr.launchingApp == app) { 17573 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) { 17574 restart = true; 17575 } else { 17576 removeDyingProviderLocked(app, cpr, true); 17577 } 17578 } 17579 } 17580 return restart; 17581 } 17582 17583 // ========================================================= 17584 // SERVICES 17585 // ========================================================= 17586 17587 @Override 17588 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 17589 int flags) { 17590 enforceNotIsolatedCaller("getServices"); 17591 17592 final int callingUid = Binder.getCallingUid(); 17593 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission( 17594 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED); 17595 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(), 17596 callingUid); 17597 synchronized (this) { 17598 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, 17599 allowed, canInteractAcrossUsers); 17600 } 17601 } 17602 17603 @Override 17604 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 17605 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 17606 synchronized (this) { 17607 return mServices.getRunningServiceControlPanelLocked(name); 17608 } 17609 } 17610 17611 @Override 17612 public ComponentName startService(IApplicationThread caller, Intent service, 17613 String resolvedType, int id, Notification notification, 17614 String callingPackage, int userId) 17615 throws TransactionTooLargeException { 17616 enforceNotIsolatedCaller("startService"); 17617 // Refuse possible leaked file descriptors 17618 if (service != null && service.hasFileDescriptors() == true) { 17619 throw new IllegalArgumentException("File descriptors passed in Intent"); 17620 } 17621 17622 if (callingPackage == null) { 17623 throw new IllegalArgumentException("callingPackage cannot be null"); 17624 } 17625 17626 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, 17627 "startService: " + service + " type=" + resolvedType); 17628 synchronized(this) { 17629 final int callingPid = Binder.getCallingPid(); 17630 final int callingUid = Binder.getCallingUid(); 17631 final long origId = Binder.clearCallingIdentity(); 17632 ComponentName res = mServices.startServiceLocked(caller, service, 17633 resolvedType, id, notification, 17634 callingPid, callingUid, callingPackage, userId); 17635 Binder.restoreCallingIdentity(origId); 17636 return res; 17637 } 17638 } 17639 17640 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, 17641 String callingPackage, int userId) 17642 throws TransactionTooLargeException { 17643 synchronized(this) { 17644 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, 17645 "startServiceInPackage: " + service + " type=" + resolvedType); 17646 final long origId = Binder.clearCallingIdentity(); 17647 ComponentName res = mServices.startServiceLocked(null, service, 17648 resolvedType, 0, null, -1, uid, callingPackage, userId); 17649 Binder.restoreCallingIdentity(origId); 17650 return res; 17651 } 17652 } 17653 17654 @Override 17655 public int stopService(IApplicationThread caller, Intent service, 17656 String resolvedType, int userId) { 17657 enforceNotIsolatedCaller("stopService"); 17658 // Refuse possible leaked file descriptors 17659 if (service != null && service.hasFileDescriptors() == true) { 17660 throw new IllegalArgumentException("File descriptors passed in Intent"); 17661 } 17662 17663 synchronized(this) { 17664 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 17665 } 17666 } 17667 17668 @Override 17669 public IBinder peekService(Intent service, String resolvedType, String callingPackage) { 17670 enforceNotIsolatedCaller("peekService"); 17671 // Refuse possible leaked file descriptors 17672 if (service != null && service.hasFileDescriptors() == true) { 17673 throw new IllegalArgumentException("File descriptors passed in Intent"); 17674 } 17675 17676 if (callingPackage == null) { 17677 throw new IllegalArgumentException("callingPackage cannot be null"); 17678 } 17679 17680 synchronized(this) { 17681 return mServices.peekServiceLocked(service, resolvedType, callingPackage); 17682 } 17683 } 17684 17685 @Override 17686 public boolean stopServiceToken(ComponentName className, IBinder token, 17687 int startId) { 17688 synchronized(this) { 17689 return mServices.stopServiceTokenLocked(className, token, startId); 17690 } 17691 } 17692 17693 @Override 17694 public void setServiceForeground(ComponentName className, IBinder token, 17695 int id, Notification notification, int flags) { 17696 synchronized(this) { 17697 mServices.setServiceForegroundLocked(className, token, id, notification, flags); 17698 } 17699 } 17700 17701 @Override 17702 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 17703 boolean requireFull, String name, String callerPackage) { 17704 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll, 17705 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 17706 } 17707 17708 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 17709 String className, int flags) { 17710 boolean result = false; 17711 // For apps that don't have pre-defined UIDs, check for permission 17712 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 17713 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 17714 if (ActivityManager.checkUidPermission( 17715 INTERACT_ACROSS_USERS, 17716 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 17717 ComponentName comp = new ComponentName(aInfo.packageName, className); 17718 String msg = "Permission Denial: Component " + comp.flattenToShortString() 17719 + " requests FLAG_SINGLE_USER, but app does not hold " 17720 + INTERACT_ACROSS_USERS; 17721 Slog.w(TAG, msg); 17722 throw new SecurityException(msg); 17723 } 17724 // Permission passed 17725 result = true; 17726 } 17727 } else if ("system".equals(componentProcessName)) { 17728 result = true; 17729 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 17730 // Phone app and persistent apps are allowed to export singleuser providers. 17731 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 17732 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 17733 } 17734 if (DEBUG_MU) Slog.v(TAG_MU, 17735 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x" 17736 + Integer.toHexString(flags) + ") = " + result); 17737 return result; 17738 } 17739 17740 /** 17741 * Checks to see if the caller is in the same app as the singleton 17742 * component, or the component is in a special app. It allows special apps 17743 * to export singleton components but prevents exporting singleton 17744 * components for regular apps. 17745 */ 17746 boolean isValidSingletonCall(int callingUid, int componentUid) { 17747 int componentAppId = UserHandle.getAppId(componentUid); 17748 return UserHandle.isSameApp(callingUid, componentUid) 17749 || componentAppId == Process.SYSTEM_UID 17750 || componentAppId == Process.PHONE_UID 17751 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 17752 == PackageManager.PERMISSION_GRANTED; 17753 } 17754 17755 public int bindService(IApplicationThread caller, IBinder token, Intent service, 17756 String resolvedType, IServiceConnection connection, int flags, String callingPackage, 17757 int userId) throws TransactionTooLargeException { 17758 enforceNotIsolatedCaller("bindService"); 17759 17760 // Refuse possible leaked file descriptors 17761 if (service != null && service.hasFileDescriptors() == true) { 17762 throw new IllegalArgumentException("File descriptors passed in Intent"); 17763 } 17764 17765 if (callingPackage == null) { 17766 throw new IllegalArgumentException("callingPackage cannot be null"); 17767 } 17768 17769 synchronized(this) { 17770 return mServices.bindServiceLocked(caller, token, service, 17771 resolvedType, connection, flags, callingPackage, userId); 17772 } 17773 } 17774 17775 public boolean unbindService(IServiceConnection connection) { 17776 synchronized (this) { 17777 return mServices.unbindServiceLocked(connection); 17778 } 17779 } 17780 17781 public void publishService(IBinder token, Intent intent, IBinder service) { 17782 // Refuse possible leaked file descriptors 17783 if (intent != null && intent.hasFileDescriptors() == true) { 17784 throw new IllegalArgumentException("File descriptors passed in Intent"); 17785 } 17786 17787 synchronized(this) { 17788 if (!(token instanceof ServiceRecord)) { 17789 throw new IllegalArgumentException("Invalid service token"); 17790 } 17791 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 17792 } 17793 } 17794 17795 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 17796 // Refuse possible leaked file descriptors 17797 if (intent != null && intent.hasFileDescriptors() == true) { 17798 throw new IllegalArgumentException("File descriptors passed in Intent"); 17799 } 17800 17801 synchronized(this) { 17802 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 17803 } 17804 } 17805 17806 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 17807 synchronized(this) { 17808 if (!(token instanceof ServiceRecord)) { 17809 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 17810 throw new IllegalArgumentException("Invalid service token"); 17811 } 17812 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 17813 } 17814 } 17815 17816 // ========================================================= 17817 // BACKUP AND RESTORE 17818 // ========================================================= 17819 17820 // Cause the target app to be launched if necessary and its backup agent 17821 // instantiated. The backup agent will invoke backupAgentCreated() on the 17822 // activity manager to announce its creation. 17823 public boolean bindBackupAgent(String packageName, int backupMode, int userId) { 17824 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode); 17825 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 17826 17827 IPackageManager pm = AppGlobals.getPackageManager(); 17828 ApplicationInfo app = null; 17829 try { 17830 app = pm.getApplicationInfo(packageName, 0, userId); 17831 } catch (RemoteException e) { 17832 // can't happen; package manager is process-local 17833 } 17834 if (app == null) { 17835 Slog.w(TAG, "Unable to bind backup agent for " + packageName); 17836 return false; 17837 } 17838 17839 synchronized(this) { 17840 // !!! TODO: currently no check here that we're already bound 17841 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 17842 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17843 synchronized (stats) { 17844 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 17845 } 17846 17847 // Backup agent is now in use, its package can't be stopped. 17848 try { 17849 AppGlobals.getPackageManager().setPackageStoppedState( 17850 app.packageName, false, UserHandle.getUserId(app.uid)); 17851 } catch (RemoteException e) { 17852 } catch (IllegalArgumentException e) { 17853 Slog.w(TAG, "Failed trying to unstop package " 17854 + app.packageName + ": " + e); 17855 } 17856 17857 BackupRecord r = new BackupRecord(ss, app, backupMode); 17858 ComponentName hostingName = 17859 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL) 17860 ? new ComponentName(app.packageName, app.backupAgentName) 17861 : new ComponentName("android", "FullBackupAgent"); 17862 // startProcessLocked() returns existing proc's record if it's already running 17863 ProcessRecord proc = startProcessLocked(app.processName, app, 17864 false, 0, "backup", hostingName, false, false, false); 17865 if (proc == null) { 17866 Slog.e(TAG, "Unable to start backup agent process " + r); 17867 return false; 17868 } 17869 17870 // If the app is a regular app (uid >= 10000) and not the system server or phone 17871 // process, etc, then mark it as being in full backup so that certain calls to the 17872 // process can be blocked. This is not reset to false anywhere because we kill the 17873 // process after the full backup is done and the ProcessRecord will vaporize anyway. 17874 if (UserHandle.isApp(app.uid) && 17875 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) { 17876 proc.inFullBackup = true; 17877 } 17878 r.app = proc; 17879 mBackupTarget = r; 17880 mBackupAppName = app.packageName; 17881 17882 // Try not to kill the process during backup 17883 updateOomAdjLocked(proc); 17884 17885 // If the process is already attached, schedule the creation of the backup agent now. 17886 // If it is not yet live, this will be done when it attaches to the framework. 17887 if (proc.thread != null) { 17888 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc); 17889 try { 17890 proc.thread.scheduleCreateBackupAgent(app, 17891 compatibilityInfoForPackageLocked(app), backupMode); 17892 } catch (RemoteException e) { 17893 // Will time out on the backup manager side 17894 } 17895 } else { 17896 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach"); 17897 } 17898 // Invariants: at this point, the target app process exists and the application 17899 // is either already running or in the process of coming up. mBackupTarget and 17900 // mBackupAppName describe the app, so that when it binds back to the AM we 17901 // know that it's scheduled for a backup-agent operation. 17902 } 17903 17904 return true; 17905 } 17906 17907 @Override 17908 public void clearPendingBackup() { 17909 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup"); 17910 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 17911 17912 synchronized (this) { 17913 mBackupTarget = null; 17914 mBackupAppName = null; 17915 } 17916 } 17917 17918 // A backup agent has just come up 17919 public void backupAgentCreated(String agentPackageName, IBinder agent) { 17920 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName 17921 + " = " + agent); 17922 17923 synchronized(this) { 17924 if (!agentPackageName.equals(mBackupAppName)) { 17925 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 17926 return; 17927 } 17928 } 17929 17930 long oldIdent = Binder.clearCallingIdentity(); 17931 try { 17932 IBackupManager bm = IBackupManager.Stub.asInterface( 17933 ServiceManager.getService(Context.BACKUP_SERVICE)); 17934 bm.agentConnected(agentPackageName, agent); 17935 } catch (RemoteException e) { 17936 // can't happen; the backup manager service is local 17937 } catch (Exception e) { 17938 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 17939 e.printStackTrace(); 17940 } finally { 17941 Binder.restoreCallingIdentity(oldIdent); 17942 } 17943 } 17944 17945 // done with this agent 17946 public void unbindBackupAgent(ApplicationInfo appInfo) { 17947 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo); 17948 if (appInfo == null) { 17949 Slog.w(TAG, "unbind backup agent for null app"); 17950 return; 17951 } 17952 17953 synchronized(this) { 17954 try { 17955 if (mBackupAppName == null) { 17956 Slog.w(TAG, "Unbinding backup agent with no active backup"); 17957 return; 17958 } 17959 17960 if (!mBackupAppName.equals(appInfo.packageName)) { 17961 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 17962 return; 17963 } 17964 17965 // Not backing this app up any more; reset its OOM adjustment 17966 final ProcessRecord proc = mBackupTarget.app; 17967 updateOomAdjLocked(proc); 17968 proc.inFullBackup = false; 17969 17970 // If the app crashed during backup, 'thread' will be null here 17971 if (proc.thread != null) { 17972 try { 17973 proc.thread.scheduleDestroyBackupAgent(appInfo, 17974 compatibilityInfoForPackageLocked(appInfo)); 17975 } catch (Exception e) { 17976 Slog.e(TAG, "Exception when unbinding backup agent:"); 17977 e.printStackTrace(); 17978 } 17979 } 17980 } finally { 17981 mBackupTarget = null; 17982 mBackupAppName = null; 17983 } 17984 } 17985 } 17986 // ========================================================= 17987 // BROADCASTS 17988 // ========================================================= 17989 17990 boolean isPendingBroadcastProcessLocked(int pid) { 17991 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 17992 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 17993 } 17994 17995 void skipPendingBroadcastLocked(int pid) { 17996 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 17997 for (BroadcastQueue queue : mBroadcastQueues) { 17998 queue.skipPendingBroadcastLocked(pid); 17999 } 18000 } 18001 18002 // The app just attached; send any pending broadcasts that it should receive 18003 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 18004 boolean didSomething = false; 18005 for (BroadcastQueue queue : mBroadcastQueues) { 18006 didSomething |= queue.sendPendingBroadcastsLocked(app); 18007 } 18008 return didSomething; 18009 } 18010 18011 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 18012 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 18013 enforceNotIsolatedCaller("registerReceiver"); 18014 ArrayList<Intent> stickyIntents = null; 18015 ProcessRecord callerApp = null; 18016 int callingUid; 18017 int callingPid; 18018 synchronized(this) { 18019 if (caller != null) { 18020 callerApp = getRecordForAppLocked(caller); 18021 if (callerApp == null) { 18022 throw new SecurityException( 18023 "Unable to find app for caller " + caller 18024 + " (pid=" + Binder.getCallingPid() 18025 + ") when registering receiver " + receiver); 18026 } 18027 if (callerApp.info.uid != Process.SYSTEM_UID && 18028 !callerApp.pkgList.containsKey(callerPackage) && 18029 !"android".equals(callerPackage)) { 18030 throw new SecurityException("Given caller package " + callerPackage 18031 + " is not running in process " + callerApp); 18032 } 18033 callingUid = callerApp.info.uid; 18034 callingPid = callerApp.pid; 18035 } else { 18036 callerPackage = null; 18037 callingUid = Binder.getCallingUid(); 18038 callingPid = Binder.getCallingPid(); 18039 } 18040 18041 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, 18042 ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 18043 18044 Iterator<String> actions = filter.actionsIterator(); 18045 if (actions == null) { 18046 ArrayList<String> noAction = new ArrayList<String>(1); 18047 noAction.add(null); 18048 actions = noAction.iterator(); 18049 } 18050 18051 // Collect stickies of users 18052 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) }; 18053 while (actions.hasNext()) { 18054 String action = actions.next(); 18055 for (int id : userIds) { 18056 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id); 18057 if (stickies != null) { 18058 ArrayList<Intent> intents = stickies.get(action); 18059 if (intents != null) { 18060 if (stickyIntents == null) { 18061 stickyIntents = new ArrayList<Intent>(); 18062 } 18063 stickyIntents.addAll(intents); 18064 } 18065 } 18066 } 18067 } 18068 } 18069 18070 ArrayList<Intent> allSticky = null; 18071 if (stickyIntents != null) { 18072 final ContentResolver resolver = mContext.getContentResolver(); 18073 // Look for any matching sticky broadcasts... 18074 for (int i = 0, N = stickyIntents.size(); i < N; i++) { 18075 Intent intent = stickyIntents.get(i); 18076 // If intent has scheme "content", it will need to acccess 18077 // provider that needs to lock mProviderMap in ActivityThread 18078 // and also it may need to wait application response, so we 18079 // cannot lock ActivityManagerService here. 18080 if (filter.match(resolver, intent, true, TAG) >= 0) { 18081 if (allSticky == null) { 18082 allSticky = new ArrayList<Intent>(); 18083 } 18084 allSticky.add(intent); 18085 } 18086 } 18087 } 18088 18089 // The first sticky in the list is returned directly back to the client. 18090 Intent sticky = allSticky != null ? allSticky.get(0) : null; 18091 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky); 18092 if (receiver == null) { 18093 return sticky; 18094 } 18095 18096 synchronized (this) { 18097 if (callerApp != null && (callerApp.thread == null 18098 || callerApp.thread.asBinder() != caller.asBinder())) { 18099 // Original caller already died 18100 return null; 18101 } 18102 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 18103 if (rl == null) { 18104 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 18105 userId, receiver); 18106 if (rl.app != null) { 18107 rl.app.receivers.add(rl); 18108 } else { 18109 try { 18110 receiver.asBinder().linkToDeath(rl, 0); 18111 } catch (RemoteException e) { 18112 return sticky; 18113 } 18114 rl.linkedToDeath = true; 18115 } 18116 mRegisteredReceivers.put(receiver.asBinder(), rl); 18117 } else if (rl.uid != callingUid) { 18118 throw new IllegalArgumentException( 18119 "Receiver requested to register for uid " + callingUid 18120 + " was previously registered for uid " + rl.uid 18121 + " callerPackage is " + callerPackage); 18122 } else if (rl.pid != callingPid) { 18123 throw new IllegalArgumentException( 18124 "Receiver requested to register for pid " + callingPid 18125 + " was previously registered for pid " + rl.pid 18126 + " callerPackage is " + callerPackage); 18127 } else if (rl.userId != userId) { 18128 throw new IllegalArgumentException( 18129 "Receiver requested to register for user " + userId 18130 + " was previously registered for user " + rl.userId 18131 + " callerPackage is " + callerPackage); 18132 } 18133 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 18134 permission, callingUid, userId); 18135 rl.add(bf); 18136 if (!bf.debugCheck()) { 18137 Slog.w(TAG, "==> For Dynamic broadcast"); 18138 } 18139 mReceiverResolver.addFilter(bf); 18140 18141 // Enqueue broadcasts for all existing stickies that match 18142 // this filter. 18143 if (allSticky != null) { 18144 ArrayList receivers = new ArrayList(); 18145 receivers.add(bf); 18146 18147 final int stickyCount = allSticky.size(); 18148 for (int i = 0; i < stickyCount; i++) { 18149 Intent intent = allSticky.get(i); 18150 BroadcastQueue queue = broadcastQueueForIntent(intent); 18151 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 18152 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers, 18153 null, 0, null, null, false, true, true, -1); 18154 queue.enqueueParallelBroadcastLocked(r); 18155 queue.scheduleBroadcastsLocked(); 18156 } 18157 } 18158 18159 return sticky; 18160 } 18161 } 18162 18163 public void unregisterReceiver(IIntentReceiver receiver) { 18164 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver); 18165 18166 final long origId = Binder.clearCallingIdentity(); 18167 try { 18168 boolean doTrim = false; 18169 18170 synchronized(this) { 18171 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 18172 if (rl != null) { 18173 final BroadcastRecord r = rl.curBroadcast; 18174 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) { 18175 final boolean doNext = r.queue.finishReceiverLocked( 18176 r, r.resultCode, r.resultData, r.resultExtras, 18177 r.resultAbort, false); 18178 if (doNext) { 18179 doTrim = true; 18180 r.queue.processNextBroadcast(false); 18181 } 18182 } 18183 18184 if (rl.app != null) { 18185 rl.app.receivers.remove(rl); 18186 } 18187 removeReceiverLocked(rl); 18188 if (rl.linkedToDeath) { 18189 rl.linkedToDeath = false; 18190 rl.receiver.asBinder().unlinkToDeath(rl, 0); 18191 } 18192 } 18193 } 18194 18195 // If we actually concluded any broadcasts, we might now be able 18196 // to trim the recipients' apps from our working set 18197 if (doTrim) { 18198 trimApplications(); 18199 return; 18200 } 18201 18202 } finally { 18203 Binder.restoreCallingIdentity(origId); 18204 } 18205 } 18206 18207 void removeReceiverLocked(ReceiverList rl) { 18208 mRegisteredReceivers.remove(rl.receiver.asBinder()); 18209 for (int i = rl.size() - 1; i >= 0; i--) { 18210 mReceiverResolver.removeFilter(rl.get(i)); 18211 } 18212 } 18213 18214 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 18215 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 18216 ProcessRecord r = mLruProcesses.get(i); 18217 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 18218 try { 18219 r.thread.dispatchPackageBroadcast(cmd, packages); 18220 } catch (RemoteException ex) { 18221 } 18222 } 18223 } 18224 } 18225 18226 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 18227 int callingUid, int[] users) { 18228 // TODO: come back and remove this assumption to triage all broadcasts 18229 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING; 18230 18231 List<ResolveInfo> receivers = null; 18232 try { 18233 HashSet<ComponentName> singleUserReceivers = null; 18234 boolean scannedFirstReceivers = false; 18235 for (int user : users) { 18236 // Skip users that have Shell restrictions, with exception of always permitted 18237 // Shell broadcasts 18238 if (callingUid == Process.SHELL_UID 18239 && mUserController.hasUserRestriction( 18240 UserManager.DISALLOW_DEBUGGING_FEATURES, user) 18241 && !isPermittedShellBroadcast(intent)) { 18242 continue; 18243 } 18244 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 18245 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList(); 18246 if (user != UserHandle.USER_SYSTEM && newReceivers != null) { 18247 // If this is not the system user, we need to check for 18248 // any receivers that should be filtered out. 18249 for (int i=0; i<newReceivers.size(); i++) { 18250 ResolveInfo ri = newReceivers.get(i); 18251 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 18252 newReceivers.remove(i); 18253 i--; 18254 } 18255 } 18256 } 18257 if (newReceivers != null && newReceivers.size() == 0) { 18258 newReceivers = null; 18259 } 18260 if (receivers == null) { 18261 receivers = newReceivers; 18262 } else if (newReceivers != null) { 18263 // We need to concatenate the additional receivers 18264 // found with what we have do far. This would be easy, 18265 // but we also need to de-dup any receivers that are 18266 // singleUser. 18267 if (!scannedFirstReceivers) { 18268 // Collect any single user receivers we had already retrieved. 18269 scannedFirstReceivers = true; 18270 for (int i=0; i<receivers.size(); i++) { 18271 ResolveInfo ri = receivers.get(i); 18272 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 18273 ComponentName cn = new ComponentName( 18274 ri.activityInfo.packageName, ri.activityInfo.name); 18275 if (singleUserReceivers == null) { 18276 singleUserReceivers = new HashSet<ComponentName>(); 18277 } 18278 singleUserReceivers.add(cn); 18279 } 18280 } 18281 } 18282 // Add the new results to the existing results, tracking 18283 // and de-dupping single user receivers. 18284 for (int i=0; i<newReceivers.size(); i++) { 18285 ResolveInfo ri = newReceivers.get(i); 18286 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 18287 ComponentName cn = new ComponentName( 18288 ri.activityInfo.packageName, ri.activityInfo.name); 18289 if (singleUserReceivers == null) { 18290 singleUserReceivers = new HashSet<ComponentName>(); 18291 } 18292 if (!singleUserReceivers.contains(cn)) { 18293 singleUserReceivers.add(cn); 18294 receivers.add(ri); 18295 } 18296 } else { 18297 receivers.add(ri); 18298 } 18299 } 18300 } 18301 } 18302 } catch (RemoteException ex) { 18303 // pm is in same process, this will never happen. 18304 } 18305 return receivers; 18306 } 18307 18308 private boolean isPermittedShellBroadcast(Intent intent) { 18309 // remote bugreport should always be allowed to be taken 18310 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction()); 18311 } 18312 18313 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp, 18314 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) { 18315 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) { 18316 // Don't yell about broadcasts sent via shell 18317 return; 18318 } 18319 18320 final String action = intent.getAction(); 18321 if (isProtectedBroadcast 18322 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) 18323 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action) 18324 || Intent.ACTION_MEDIA_BUTTON.equals(action) 18325 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action) 18326 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action) 18327 || Intent.ACTION_MASTER_CLEAR.equals(action) 18328 || Intent.ACTION_FACTORY_RESET.equals(action) 18329 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) 18330 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action) 18331 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action) 18332 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action) 18333 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action) 18334 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action) 18335 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) { 18336 // Broadcast is either protected, or it's a public action that 18337 // we've relaxed, so it's fine for system internals to send. 18338 return; 18339 } 18340 18341 // This broadcast may be a problem... but there are often system components that 18342 // want to send an internal broadcast to themselves, which is annoying to have to 18343 // explicitly list each action as a protected broadcast, so we will check for that 18344 // one safe case and allow it: an explicit broadcast, only being received by something 18345 // that has protected itself. 18346 if (receivers != null && receivers.size() > 0 18347 && (intent.getPackage() != null || intent.getComponent() != null)) { 18348 boolean allProtected = true; 18349 for (int i = receivers.size()-1; i >= 0; i--) { 18350 Object target = receivers.get(i); 18351 if (target instanceof ResolveInfo) { 18352 ResolveInfo ri = (ResolveInfo)target; 18353 if (ri.activityInfo.exported && ri.activityInfo.permission == null) { 18354 allProtected = false; 18355 break; 18356 } 18357 } else { 18358 BroadcastFilter bf = (BroadcastFilter)target; 18359 if (bf.requiredPermission == null) { 18360 allProtected = false; 18361 break; 18362 } 18363 } 18364 } 18365 if (allProtected) { 18366 // All safe! 18367 return; 18368 } 18369 } 18370 18371 // The vast majority of broadcasts sent from system internals 18372 // should be protected to avoid security holes, so yell loudly 18373 // to ensure we examine these cases. 18374 if (callerApp != null) { 18375 Log.wtf(TAG, "Sending non-protected broadcast " + action 18376 + " from system " + callerApp.toShortString() + " pkg " + callerPackage, 18377 new Throwable()); 18378 } else { 18379 Log.wtf(TAG, "Sending non-protected broadcast " + action 18380 + " from system uid " + UserHandle.formatUid(callingUid) 18381 + " pkg " + callerPackage, 18382 new Throwable()); 18383 } 18384 } 18385 18386 final int broadcastIntentLocked(ProcessRecord callerApp, 18387 String callerPackage, Intent intent, String resolvedType, 18388 IIntentReceiver resultTo, int resultCode, String resultData, 18389 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, 18390 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) { 18391 intent = new Intent(intent); 18392 18393 // By default broadcasts do not go to stopped apps. 18394 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 18395 18396 // If we have not finished booting, don't allow this to launch new processes. 18397 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 18398 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18399 } 18400 18401 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, 18402 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 18403 + " ordered=" + ordered + " userid=" + userId); 18404 if ((resultTo != null) && !ordered) { 18405 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 18406 } 18407 18408 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, 18409 ALLOW_NON_FULL, "broadcast", callerPackage); 18410 18411 // Make sure that the user who is receiving this broadcast is running. 18412 // If not, we will just skip it. Make an exception for shutdown broadcasts 18413 // and upgrade steps. 18414 18415 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) { 18416 if ((callingUid != Process.SYSTEM_UID 18417 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 18418 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 18419 Slog.w(TAG, "Skipping broadcast of " + intent 18420 + ": user " + userId + " is stopped"); 18421 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 18422 } 18423 } 18424 18425 BroadcastOptions brOptions = null; 18426 if (bOptions != null) { 18427 brOptions = new BroadcastOptions(bOptions); 18428 if (brOptions.getTemporaryAppWhitelistDuration() > 0) { 18429 // See if the caller is allowed to do this. Note we are checking against 18430 // the actual real caller (not whoever provided the operation as say a 18431 // PendingIntent), because that who is actually supplied the arguments. 18432 if (checkComponentPermission( 18433 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 18434 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 18435 != PackageManager.PERMISSION_GRANTED) { 18436 String msg = "Permission Denial: " + intent.getAction() 18437 + " broadcast from " + callerPackage + " (pid=" + callingPid 18438 + ", uid=" + callingUid + ")" 18439 + " requires " 18440 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; 18441 Slog.w(TAG, msg); 18442 throw new SecurityException(msg); 18443 } 18444 } 18445 } 18446 18447 // Verify that protected broadcasts are only being sent by system code, 18448 // and that system code is only sending protected broadcasts. 18449 final String action = intent.getAction(); 18450 final boolean isProtectedBroadcast; 18451 try { 18452 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action); 18453 } catch (RemoteException e) { 18454 Slog.w(TAG, "Remote exception", e); 18455 return ActivityManager.BROADCAST_SUCCESS; 18456 } 18457 18458 final boolean isCallerSystem; 18459 switch (UserHandle.getAppId(callingUid)) { 18460 case Process.ROOT_UID: 18461 case Process.SYSTEM_UID: 18462 case Process.PHONE_UID: 18463 case Process.BLUETOOTH_UID: 18464 case Process.NFC_UID: 18465 isCallerSystem = true; 18466 break; 18467 default: 18468 isCallerSystem = (callerApp != null) && callerApp.persistent; 18469 break; 18470 } 18471 18472 // First line security check before anything else: stop non-system apps from 18473 // sending protected broadcasts. 18474 if (!isCallerSystem) { 18475 if (isProtectedBroadcast) { 18476 String msg = "Permission Denial: not allowed to send broadcast " 18477 + action + " from pid=" 18478 + callingPid + ", uid=" + callingUid; 18479 Slog.w(TAG, msg); 18480 throw new SecurityException(msg); 18481 18482 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) 18483 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { 18484 // Special case for compatibility: we don't want apps to send this, 18485 // but historically it has not been protected and apps may be using it 18486 // to poke their own app widget. So, instead of making it protected, 18487 // just limit it to the caller. 18488 if (callerPackage == null) { 18489 String msg = "Permission Denial: not allowed to send broadcast " 18490 + action + " from unknown caller."; 18491 Slog.w(TAG, msg); 18492 throw new SecurityException(msg); 18493 } else if (intent.getComponent() != null) { 18494 // They are good enough to send to an explicit component... verify 18495 // it is being sent to the calling app. 18496 if (!intent.getComponent().getPackageName().equals( 18497 callerPackage)) { 18498 String msg = "Permission Denial: not allowed to send broadcast " 18499 + action + " to " 18500 + intent.getComponent().getPackageName() + " from " 18501 + callerPackage; 18502 Slog.w(TAG, msg); 18503 throw new SecurityException(msg); 18504 } 18505 } else { 18506 // Limit broadcast to their own package. 18507 intent.setPackage(callerPackage); 18508 } 18509 } 18510 } 18511 18512 if (action != null) { 18513 if (getBackgroundLaunchBroadcasts().contains(action)) { 18514 if (DEBUG_BACKGROUND_CHECK) { 18515 Slog.i(TAG, "Broadcast action " + action + " forcing include-background"); 18516 } 18517 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 18518 } 18519 18520 switch (action) { 18521 case Intent.ACTION_UID_REMOVED: 18522 case Intent.ACTION_PACKAGE_REMOVED: 18523 case Intent.ACTION_PACKAGE_CHANGED: 18524 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 18525 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 18526 case Intent.ACTION_PACKAGES_SUSPENDED: 18527 case Intent.ACTION_PACKAGES_UNSUSPENDED: 18528 // Handle special intents: if this broadcast is from the package 18529 // manager about a package being removed, we need to remove all of 18530 // its activities from the history stack. 18531 if (checkComponentPermission( 18532 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 18533 callingPid, callingUid, -1, true) 18534 != PackageManager.PERMISSION_GRANTED) { 18535 String msg = "Permission Denial: " + intent.getAction() 18536 + " broadcast from " + callerPackage + " (pid=" + callingPid 18537 + ", uid=" + callingUid + ")" 18538 + " requires " 18539 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 18540 Slog.w(TAG, msg); 18541 throw new SecurityException(msg); 18542 } 18543 switch (action) { 18544 case Intent.ACTION_UID_REMOVED: 18545 final Bundle intentExtras = intent.getExtras(); 18546 final int uid = intentExtras != null 18547 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 18548 if (uid >= 0) { 18549 mBatteryStatsService.removeUid(uid); 18550 mAppOpsService.uidRemoved(uid); 18551 } 18552 break; 18553 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 18554 // If resources are unavailable just force stop all those packages 18555 // and flush the attribute cache as well. 18556 String list[] = 18557 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 18558 if (list != null && list.length > 0) { 18559 for (int i = 0; i < list.length; i++) { 18560 forceStopPackageLocked(list[i], -1, false, true, true, 18561 false, false, userId, "storage unmount"); 18562 } 18563 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 18564 sendPackageBroadcastLocked( 18565 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE, 18566 list, userId); 18567 } 18568 break; 18569 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 18570 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 18571 break; 18572 case Intent.ACTION_PACKAGE_REMOVED: 18573 case Intent.ACTION_PACKAGE_CHANGED: 18574 Uri data = intent.getData(); 18575 String ssp; 18576 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 18577 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 18578 final boolean replacing = 18579 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 18580 final boolean killProcess = 18581 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false); 18582 final boolean fullUninstall = removed && !replacing; 18583 if (removed) { 18584 if (killProcess) { 18585 forceStopPackageLocked(ssp, UserHandle.getAppId( 18586 intent.getIntExtra(Intent.EXTRA_UID, -1)), 18587 false, true, true, false, fullUninstall, userId, 18588 removed ? "pkg removed" : "pkg changed"); 18589 } 18590 final int cmd = killProcess 18591 ? ApplicationThreadConstants.PACKAGE_REMOVED 18592 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL; 18593 sendPackageBroadcastLocked(cmd, 18594 new String[] {ssp}, userId); 18595 if (fullUninstall) { 18596 mAppOpsService.packageRemoved( 18597 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 18598 18599 // Remove all permissions granted from/to this package 18600 removeUriPermissionsForPackageLocked(ssp, userId, true); 18601 18602 removeTasksByPackageNameLocked(ssp, userId); 18603 18604 // Hide the "unsupported display" dialog if necessary. 18605 if (mUnsupportedDisplaySizeDialog != null && ssp.equals( 18606 mUnsupportedDisplaySizeDialog.getPackageName())) { 18607 mUnsupportedDisplaySizeDialog.dismiss(); 18608 mUnsupportedDisplaySizeDialog = null; 18609 } 18610 mCompatModePackages.handlePackageUninstalledLocked(ssp); 18611 mBatteryStatsService.notePackageUninstalled(ssp); 18612 } 18613 } else { 18614 if (killProcess) { 18615 killPackageProcessesLocked(ssp, UserHandle.getAppId( 18616 intent.getIntExtra(Intent.EXTRA_UID, -1)), 18617 userId, ProcessList.INVALID_ADJ, 18618 false, true, true, false, "change " + ssp); 18619 } 18620 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess, 18621 intent.getStringArrayExtra( 18622 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST)); 18623 } 18624 } 18625 break; 18626 case Intent.ACTION_PACKAGES_SUSPENDED: 18627 case Intent.ACTION_PACKAGES_UNSUSPENDED: 18628 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals( 18629 intent.getAction()); 18630 final String[] packageNames = intent.getStringArrayExtra( 18631 Intent.EXTRA_CHANGED_PACKAGE_LIST); 18632 final int userHandle = intent.getIntExtra( 18633 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 18634 18635 synchronized(ActivityManagerService.this) { 18636 mRecentTasks.onPackagesSuspendedChanged( 18637 packageNames, suspended, userHandle); 18638 } 18639 break; 18640 } 18641 break; 18642 case Intent.ACTION_PACKAGE_REPLACED: 18643 { 18644 final Uri data = intent.getData(); 18645 final String ssp; 18646 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 18647 final ApplicationInfo aInfo = 18648 getPackageManagerInternalLocked().getApplicationInfo( 18649 ssp, 18650 userId); 18651 if (aInfo == null) { 18652 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:" 18653 + " ssp=" + ssp + " data=" + data); 18654 return ActivityManager.BROADCAST_SUCCESS; 18655 } 18656 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo); 18657 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED, 18658 new String[] {ssp}, userId); 18659 } 18660 break; 18661 } 18662 case Intent.ACTION_PACKAGE_ADDED: 18663 { 18664 // Special case for adding a package: by default turn on compatibility mode. 18665 Uri data = intent.getData(); 18666 String ssp; 18667 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 18668 final boolean replacing = 18669 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 18670 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 18671 18672 try { 18673 ApplicationInfo ai = AppGlobals.getPackageManager(). 18674 getApplicationInfo(ssp, 0, 0); 18675 mBatteryStatsService.notePackageInstalled(ssp, 18676 ai != null ? ai.versionCode : 0); 18677 } catch (RemoteException e) { 18678 } 18679 } 18680 break; 18681 } 18682 case Intent.ACTION_PACKAGE_DATA_CLEARED: 18683 { 18684 Uri data = intent.getData(); 18685 String ssp; 18686 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 18687 // Hide the "unsupported display" dialog if necessary. 18688 if (mUnsupportedDisplaySizeDialog != null && ssp.equals( 18689 mUnsupportedDisplaySizeDialog.getPackageName())) { 18690 mUnsupportedDisplaySizeDialog.dismiss(); 18691 mUnsupportedDisplaySizeDialog = null; 18692 } 18693 mCompatModePackages.handlePackageDataClearedLocked(ssp); 18694 } 18695 break; 18696 } 18697 case Intent.ACTION_TIMEZONE_CHANGED: 18698 // If this is the time zone changed action, queue up a message that will reset 18699 // the timezone of all currently running processes. This message will get 18700 // queued up before the broadcast happens. 18701 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 18702 break; 18703 case Intent.ACTION_TIME_CHANGED: 18704 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between 18705 // the tri-state value it may contain and "unknown". 18706 // For convenience we re-use the Intent extra values. 18707 final int NO_EXTRA_VALUE_FOUND = -1; 18708 final int timeFormatPreferenceMsgValue = intent.getIntExtra( 18709 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, 18710 NO_EXTRA_VALUE_FOUND /* defaultValue */); 18711 // Only send a message if the time preference is available. 18712 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) { 18713 Message updateTimePreferenceMsg = 18714 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG, 18715 timeFormatPreferenceMsgValue, 0); 18716 mHandler.sendMessage(updateTimePreferenceMsg); 18717 } 18718 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 18719 synchronized (stats) { 18720 stats.noteCurrentTimeChangedLocked(); 18721 } 18722 break; 18723 case Intent.ACTION_CLEAR_DNS_CACHE: 18724 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 18725 break; 18726 case Proxy.PROXY_CHANGE_ACTION: 18727 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 18728 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 18729 break; 18730 case android.hardware.Camera.ACTION_NEW_PICTURE: 18731 case android.hardware.Camera.ACTION_NEW_VIDEO: 18732 // These broadcasts are no longer allowed by the system, since they can 18733 // cause significant thrashing at a crictical point (using the camera). 18734 // Apps should use JobScehduler to monitor for media provider changes. 18735 Slog.w(TAG, action + " no longer allowed; dropping from " 18736 + UserHandle.formatUid(callingUid)); 18737 if (resultTo != null) { 18738 final BroadcastQueue queue = broadcastQueueForIntent(intent); 18739 try { 18740 queue.performReceiveLocked(callerApp, resultTo, intent, 18741 Activity.RESULT_CANCELED, null, null, 18742 false, false, userId); 18743 } catch (RemoteException e) { 18744 Slog.w(TAG, "Failure [" 18745 + queue.mQueueName + "] sending broadcast result of " 18746 + intent, e); 18747 18748 } 18749 } 18750 // Lie; we don't want to crash the app. 18751 return ActivityManager.BROADCAST_SUCCESS; 18752 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED: 18753 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG); 18754 break; 18755 } 18756 } 18757 18758 // Add to the sticky list if requested. 18759 if (sticky) { 18760 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 18761 callingPid, callingUid) 18762 != PackageManager.PERMISSION_GRANTED) { 18763 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 18764 + callingPid + ", uid=" + callingUid 18765 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 18766 Slog.w(TAG, msg); 18767 throw new SecurityException(msg); 18768 } 18769 if (requiredPermissions != null && requiredPermissions.length > 0) { 18770 Slog.w(TAG, "Can't broadcast sticky intent " + intent 18771 + " and enforce permissions " + Arrays.toString(requiredPermissions)); 18772 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 18773 } 18774 if (intent.getComponent() != null) { 18775 throw new SecurityException( 18776 "Sticky broadcasts can't target a specific component"); 18777 } 18778 // We use userId directly here, since the "all" target is maintained 18779 // as a separate set of sticky broadcasts. 18780 if (userId != UserHandle.USER_ALL) { 18781 // But first, if this is not a broadcast to all users, then 18782 // make sure it doesn't conflict with an existing broadcast to 18783 // all users. 18784 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 18785 UserHandle.USER_ALL); 18786 if (stickies != null) { 18787 ArrayList<Intent> list = stickies.get(intent.getAction()); 18788 if (list != null) { 18789 int N = list.size(); 18790 int i; 18791 for (i=0; i<N; i++) { 18792 if (intent.filterEquals(list.get(i))) { 18793 throw new IllegalArgumentException( 18794 "Sticky broadcast " + intent + " for user " 18795 + userId + " conflicts with existing global broadcast"); 18796 } 18797 } 18798 } 18799 } 18800 } 18801 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 18802 if (stickies == null) { 18803 stickies = new ArrayMap<>(); 18804 mStickyBroadcasts.put(userId, stickies); 18805 } 18806 ArrayList<Intent> list = stickies.get(intent.getAction()); 18807 if (list == null) { 18808 list = new ArrayList<>(); 18809 stickies.put(intent.getAction(), list); 18810 } 18811 final int stickiesCount = list.size(); 18812 int i; 18813 for (i = 0; i < stickiesCount; i++) { 18814 if (intent.filterEquals(list.get(i))) { 18815 // This sticky already exists, replace it. 18816 list.set(i, new Intent(intent)); 18817 break; 18818 } 18819 } 18820 if (i >= stickiesCount) { 18821 list.add(new Intent(intent)); 18822 } 18823 } 18824 18825 int[] users; 18826 if (userId == UserHandle.USER_ALL) { 18827 // Caller wants broadcast to go to all started users. 18828 users = mUserController.getStartedUserArrayLocked(); 18829 } else { 18830 // Caller wants broadcast to go to one specific user. 18831 users = new int[] {userId}; 18832 } 18833 18834 // Figure out who all will receive this broadcast. 18835 List receivers = null; 18836 List<BroadcastFilter> registeredReceivers = null; 18837 // Need to resolve the intent to interested receivers... 18838 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 18839 == 0) { 18840 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 18841 } 18842 if (intent.getComponent() == null) { 18843 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) { 18844 // Query one target user at a time, excluding shell-restricted users 18845 for (int i = 0; i < users.length; i++) { 18846 if (mUserController.hasUserRestriction( 18847 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 18848 continue; 18849 } 18850 List<BroadcastFilter> registeredReceiversForUser = 18851 mReceiverResolver.queryIntent(intent, 18852 resolvedType, false /*defaultOnly*/, users[i]); 18853 if (registeredReceivers == null) { 18854 registeredReceivers = registeredReceiversForUser; 18855 } else if (registeredReceiversForUser != null) { 18856 registeredReceivers.addAll(registeredReceiversForUser); 18857 } 18858 } 18859 } else { 18860 registeredReceivers = mReceiverResolver.queryIntent(intent, 18861 resolvedType, false /*defaultOnly*/, userId); 18862 } 18863 } 18864 18865 final boolean replacePending = 18866 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 18867 18868 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction() 18869 + " replacePending=" + replacePending); 18870 18871 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 18872 if (!ordered && NR > 0) { 18873 // If we are not serializing this broadcast, then send the 18874 // registered receivers separately so they don't wait for the 18875 // components to be launched. 18876 if (isCallerSystem) { 18877 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, 18878 isProtectedBroadcast, registeredReceivers); 18879 } 18880 final BroadcastQueue queue = broadcastQueueForIntent(intent); 18881 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 18882 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions, 18883 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData, 18884 resultExtras, ordered, sticky, false, userId); 18885 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r); 18886 final boolean replaced = replacePending 18887 && (queue.replaceParallelBroadcastLocked(r) != null); 18888 // Note: We assume resultTo is null for non-ordered broadcasts. 18889 if (!replaced) { 18890 queue.enqueueParallelBroadcastLocked(r); 18891 queue.scheduleBroadcastsLocked(); 18892 } 18893 registeredReceivers = null; 18894 NR = 0; 18895 } 18896 18897 // Merge into one list. 18898 int ir = 0; 18899 if (receivers != null) { 18900 // A special case for PACKAGE_ADDED: do not allow the package 18901 // being added to see this broadcast. This prevents them from 18902 // using this as a back door to get run as soon as they are 18903 // installed. Maybe in the future we want to have a special install 18904 // broadcast or such for apps, but we'd like to deliberately make 18905 // this decision. 18906 String skipPackages[] = null; 18907 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 18908 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 18909 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 18910 Uri data = intent.getData(); 18911 if (data != null) { 18912 String pkgName = data.getSchemeSpecificPart(); 18913 if (pkgName != null) { 18914 skipPackages = new String[] { pkgName }; 18915 } 18916 } 18917 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 18918 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 18919 } 18920 if (skipPackages != null && (skipPackages.length > 0)) { 18921 for (String skipPackage : skipPackages) { 18922 if (skipPackage != null) { 18923 int NT = receivers.size(); 18924 for (int it=0; it<NT; it++) { 18925 ResolveInfo curt = (ResolveInfo)receivers.get(it); 18926 if (curt.activityInfo.packageName.equals(skipPackage)) { 18927 receivers.remove(it); 18928 it--; 18929 NT--; 18930 } 18931 } 18932 } 18933 } 18934 } 18935 18936 int NT = receivers != null ? receivers.size() : 0; 18937 int it = 0; 18938 ResolveInfo curt = null; 18939 BroadcastFilter curr = null; 18940 while (it < NT && ir < NR) { 18941 if (curt == null) { 18942 curt = (ResolveInfo)receivers.get(it); 18943 } 18944 if (curr == null) { 18945 curr = registeredReceivers.get(ir); 18946 } 18947 if (curr.getPriority() >= curt.priority) { 18948 // Insert this broadcast record into the final list. 18949 receivers.add(it, curr); 18950 ir++; 18951 curr = null; 18952 it++; 18953 NT++; 18954 } else { 18955 // Skip to the next ResolveInfo in the final list. 18956 it++; 18957 curt = null; 18958 } 18959 } 18960 } 18961 while (ir < NR) { 18962 if (receivers == null) { 18963 receivers = new ArrayList(); 18964 } 18965 receivers.add(registeredReceivers.get(ir)); 18966 ir++; 18967 } 18968 18969 if (isCallerSystem) { 18970 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, 18971 isProtectedBroadcast, receivers); 18972 } 18973 18974 if ((receivers != null && receivers.size() > 0) 18975 || resultTo != null) { 18976 BroadcastQueue queue = broadcastQueueForIntent(intent); 18977 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 18978 callerPackage, callingPid, callingUid, resolvedType, 18979 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, 18980 resultData, resultExtras, ordered, sticky, false, userId); 18981 18982 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r 18983 + ": prev had " + queue.mOrderedBroadcasts.size()); 18984 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST, 18985 "Enqueueing broadcast " + r.intent.getAction()); 18986 18987 final BroadcastRecord oldRecord = 18988 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null; 18989 if (oldRecord != null) { 18990 // Replaced, fire the result-to receiver. 18991 if (oldRecord.resultTo != null) { 18992 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent); 18993 try { 18994 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo, 18995 oldRecord.intent, 18996 Activity.RESULT_CANCELED, null, null, 18997 false, false, oldRecord.userId); 18998 } catch (RemoteException e) { 18999 Slog.w(TAG, "Failure [" 19000 + queue.mQueueName + "] sending broadcast result of " 19001 + intent, e); 19002 19003 } 19004 } 19005 } else { 19006 queue.enqueueOrderedBroadcastLocked(r); 19007 queue.scheduleBroadcastsLocked(); 19008 } 19009 } else { 19010 // There was nobody interested in the broadcast, but we still want to record 19011 // that it happened. 19012 if (intent.getComponent() == null && intent.getPackage() == null 19013 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 19014 // This was an implicit broadcast... let's record it for posterity. 19015 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0); 19016 } 19017 } 19018 19019 return ActivityManager.BROADCAST_SUCCESS; 19020 } 19021 19022 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount, 19023 int skipCount, long dispatchTime) { 19024 final long now = SystemClock.elapsedRealtime(); 19025 if (mCurBroadcastStats == null || 19026 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) { 19027 mLastBroadcastStats = mCurBroadcastStats; 19028 if (mLastBroadcastStats != null) { 19029 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime(); 19030 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis(); 19031 } 19032 mCurBroadcastStats = new BroadcastStats(); 19033 } 19034 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime); 19035 } 19036 19037 final Intent verifyBroadcastLocked(Intent intent) { 19038 // Refuse possible leaked file descriptors 19039 if (intent != null && intent.hasFileDescriptors() == true) { 19040 throw new IllegalArgumentException("File descriptors passed in Intent"); 19041 } 19042 19043 int flags = intent.getFlags(); 19044 19045 if (!mProcessesReady) { 19046 // if the caller really truly claims to know what they're doing, go 19047 // ahead and allow the broadcast without launching any receivers 19048 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 19049 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed. 19050 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 19051 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 19052 + " before boot completion"); 19053 throw new IllegalStateException("Cannot broadcast before boot completed"); 19054 } 19055 } 19056 19057 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 19058 throw new IllegalArgumentException( 19059 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 19060 } 19061 19062 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) { 19063 switch (Binder.getCallingUid()) { 19064 case Process.ROOT_UID: 19065 case Process.SHELL_UID: 19066 break; 19067 default: 19068 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID " 19069 + Binder.getCallingUid()); 19070 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL); 19071 break; 19072 } 19073 } 19074 19075 return intent; 19076 } 19077 19078 public final int broadcastIntent(IApplicationThread caller, 19079 Intent intent, String resolvedType, IIntentReceiver resultTo, 19080 int resultCode, String resultData, Bundle resultExtras, 19081 String[] requiredPermissions, int appOp, Bundle bOptions, 19082 boolean serialized, boolean sticky, int userId) { 19083 enforceNotIsolatedCaller("broadcastIntent"); 19084 synchronized(this) { 19085 intent = verifyBroadcastLocked(intent); 19086 19087 final ProcessRecord callerApp = getRecordForAppLocked(caller); 19088 final int callingPid = Binder.getCallingPid(); 19089 final int callingUid = Binder.getCallingUid(); 19090 final long origId = Binder.clearCallingIdentity(); 19091 int res = broadcastIntentLocked(callerApp, 19092 callerApp != null ? callerApp.info.packageName : null, 19093 intent, resolvedType, resultTo, resultCode, resultData, resultExtras, 19094 requiredPermissions, appOp, bOptions, serialized, sticky, 19095 callingPid, callingUid, userId); 19096 Binder.restoreCallingIdentity(origId); 19097 return res; 19098 } 19099 } 19100 19101 19102 int broadcastIntentInPackage(String packageName, int uid, 19103 Intent intent, String resolvedType, IIntentReceiver resultTo, 19104 int resultCode, String resultData, Bundle resultExtras, 19105 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, 19106 int userId) { 19107 synchronized(this) { 19108 intent = verifyBroadcastLocked(intent); 19109 19110 final long origId = Binder.clearCallingIdentity(); 19111 String[] requiredPermissions = requiredPermission == null ? null 19112 : new String[] {requiredPermission}; 19113 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 19114 resultTo, resultCode, resultData, resultExtras, 19115 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized, 19116 sticky, -1, uid, userId); 19117 Binder.restoreCallingIdentity(origId); 19118 return res; 19119 } 19120 } 19121 19122 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 19123 // Refuse possible leaked file descriptors 19124 if (intent != null && intent.hasFileDescriptors() == true) { 19125 throw new IllegalArgumentException("File descriptors passed in Intent"); 19126 } 19127 19128 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 19129 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 19130 19131 synchronized(this) { 19132 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 19133 != PackageManager.PERMISSION_GRANTED) { 19134 String msg = "Permission Denial: unbroadcastIntent() from pid=" 19135 + Binder.getCallingPid() 19136 + ", uid=" + Binder.getCallingUid() 19137 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 19138 Slog.w(TAG, msg); 19139 throw new SecurityException(msg); 19140 } 19141 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 19142 if (stickies != null) { 19143 ArrayList<Intent> list = stickies.get(intent.getAction()); 19144 if (list != null) { 19145 int N = list.size(); 19146 int i; 19147 for (i=0; i<N; i++) { 19148 if (intent.filterEquals(list.get(i))) { 19149 list.remove(i); 19150 break; 19151 } 19152 } 19153 if (list.size() <= 0) { 19154 stickies.remove(intent.getAction()); 19155 } 19156 } 19157 if (stickies.size() <= 0) { 19158 mStickyBroadcasts.remove(userId); 19159 } 19160 } 19161 } 19162 } 19163 19164 void backgroundServicesFinishedLocked(int userId) { 19165 for (BroadcastQueue queue : mBroadcastQueues) { 19166 queue.backgroundServicesFinishedLocked(userId); 19167 } 19168 } 19169 19170 public void finishReceiver(IBinder who, int resultCode, String resultData, 19171 Bundle resultExtras, boolean resultAbort, int flags) { 19172 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who); 19173 19174 // Refuse possible leaked file descriptors 19175 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 19176 throw new IllegalArgumentException("File descriptors passed in Bundle"); 19177 } 19178 19179 final long origId = Binder.clearCallingIdentity(); 19180 try { 19181 boolean doNext = false; 19182 BroadcastRecord r; 19183 19184 synchronized(this) { 19185 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0 19186 ? mFgBroadcastQueue : mBgBroadcastQueue; 19187 r = queue.getMatchingOrderedReceiver(who); 19188 if (r != null) { 19189 doNext = r.queue.finishReceiverLocked(r, resultCode, 19190 resultData, resultExtras, resultAbort, true); 19191 } 19192 } 19193 19194 if (doNext) { 19195 r.queue.processNextBroadcast(false); 19196 } 19197 trimApplications(); 19198 } finally { 19199 Binder.restoreCallingIdentity(origId); 19200 } 19201 } 19202 19203 // ========================================================= 19204 // INSTRUMENTATION 19205 // ========================================================= 19206 19207 public boolean startInstrumentation(ComponentName className, 19208 String profileFile, int flags, Bundle arguments, 19209 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 19210 int userId, String abiOverride) { 19211 enforceNotIsolatedCaller("startInstrumentation"); 19212 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 19213 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 19214 // Refuse possible leaked file descriptors 19215 if (arguments != null && arguments.hasFileDescriptors()) { 19216 throw new IllegalArgumentException("File descriptors passed in Bundle"); 19217 } 19218 19219 synchronized(this) { 19220 InstrumentationInfo ii = null; 19221 ApplicationInfo ai = null; 19222 try { 19223 ii = mContext.getPackageManager().getInstrumentationInfo( 19224 className, STOCK_PM_FLAGS); 19225 ai = AppGlobals.getPackageManager().getApplicationInfo( 19226 ii.targetPackage, STOCK_PM_FLAGS, userId); 19227 } catch (PackageManager.NameNotFoundException e) { 19228 } catch (RemoteException e) { 19229 } 19230 if (ii == null) { 19231 reportStartInstrumentationFailureLocked(watcher, className, 19232 "Unable to find instrumentation info for: " + className); 19233 return false; 19234 } 19235 if (ai == null) { 19236 reportStartInstrumentationFailureLocked(watcher, className, 19237 "Unable to find instrumentation target package: " + ii.targetPackage); 19238 return false; 19239 } 19240 if (!ai.hasCode()) { 19241 reportStartInstrumentationFailureLocked(watcher, className, 19242 "Instrumentation target has no code: " + ii.targetPackage); 19243 return false; 19244 } 19245 19246 int match = mContext.getPackageManager().checkSignatures( 19247 ii.targetPackage, ii.packageName); 19248 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 19249 String msg = "Permission Denial: starting instrumentation " 19250 + className + " from pid=" 19251 + Binder.getCallingPid() 19252 + ", uid=" + Binder.getCallingPid() 19253 + " not allowed because package " + ii.packageName 19254 + " does not have a signature matching the target " 19255 + ii.targetPackage; 19256 reportStartInstrumentationFailureLocked(watcher, className, msg); 19257 throw new SecurityException(msg); 19258 } 19259 19260 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this); 19261 activeInstr.mClass = className; 19262 String defProcess = ai.processName;; 19263 if (ii.targetProcess == null) { 19264 activeInstr.mTargetProcesses = new String[]{ai.processName}; 19265 } else if (ii.targetProcess.equals("*")) { 19266 activeInstr.mTargetProcesses = new String[0]; 19267 } else { 19268 activeInstr.mTargetProcesses = ii.targetProcess.split(","); 19269 defProcess = activeInstr.mTargetProcesses[0]; 19270 } 19271 activeInstr.mTargetInfo = ai; 19272 activeInstr.mProfileFile = profileFile; 19273 activeInstr.mArguments = arguments; 19274 activeInstr.mWatcher = watcher; 19275 activeInstr.mUiAutomationConnection = uiAutomationConnection; 19276 activeInstr.mResultClass = className; 19277 19278 final long origId = Binder.clearCallingIdentity(); 19279 // Instrumentation can kill and relaunch even persistent processes 19280 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 19281 "start instr"); 19282 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride); 19283 app.instr = activeInstr; 19284 activeInstr.mFinished = false; 19285 activeInstr.mRunningProcesses.add(app); 19286 if (!mActiveInstrumentation.contains(activeInstr)) { 19287 mActiveInstrumentation.add(activeInstr); 19288 } 19289 Binder.restoreCallingIdentity(origId); 19290 } 19291 19292 return true; 19293 } 19294 19295 /** 19296 * Report errors that occur while attempting to start Instrumentation. Always writes the 19297 * error to the logs, but if somebody is watching, send the report there too. This enables 19298 * the "am" command to report errors with more information. 19299 * 19300 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 19301 * @param cn The component name of the instrumentation. 19302 * @param report The error report. 19303 */ 19304 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher, 19305 ComponentName cn, String report) { 19306 Slog.w(TAG, report); 19307 if (watcher != null) { 19308 Bundle results = new Bundle(); 19309 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 19310 results.putString("Error", report); 19311 mInstrumentationReporter.reportStatus(watcher, cn, -1, results); 19312 } 19313 } 19314 19315 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) { 19316 if (app.instr == null) { 19317 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app); 19318 return; 19319 } 19320 19321 if (!app.instr.mFinished && results != null) { 19322 if (app.instr.mCurResults == null) { 19323 app.instr.mCurResults = new Bundle(results); 19324 } else { 19325 app.instr.mCurResults.putAll(results); 19326 } 19327 } 19328 } 19329 19330 public void addInstrumentationResults(IApplicationThread target, Bundle results) { 19331 int userId = UserHandle.getCallingUserId(); 19332 // Refuse possible leaked file descriptors 19333 if (results != null && results.hasFileDescriptors()) { 19334 throw new IllegalArgumentException("File descriptors passed in Intent"); 19335 } 19336 19337 synchronized(this) { 19338 ProcessRecord app = getRecordForAppLocked(target); 19339 if (app == null) { 19340 Slog.w(TAG, "addInstrumentationResults: no app for " + target); 19341 return; 19342 } 19343 final long origId = Binder.clearCallingIdentity(); 19344 addInstrumentationResultsLocked(app, results); 19345 Binder.restoreCallingIdentity(origId); 19346 } 19347 } 19348 19349 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 19350 if (app.instr == null) { 19351 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app); 19352 return; 19353 } 19354 19355 if (!app.instr.mFinished) { 19356 if (app.instr.mWatcher != null) { 19357 Bundle finalResults = app.instr.mCurResults; 19358 if (finalResults != null) { 19359 if (app.instr.mCurResults != null && results != null) { 19360 finalResults.putAll(results); 19361 } 19362 } else { 19363 finalResults = results; 19364 } 19365 mInstrumentationReporter.reportFinished(app.instr.mWatcher, 19366 app.instr.mClass, resultCode, finalResults); 19367 } 19368 19369 // Can't call out of the system process with a lock held, so post a message. 19370 if (app.instr.mUiAutomationConnection != null) { 19371 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG, 19372 app.instr.mUiAutomationConnection).sendToTarget(); 19373 } 19374 app.instr.mFinished = true; 19375 } 19376 19377 app.instr.removeProcess(app); 19378 app.instr = null; 19379 19380 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 19381 "finished inst"); 19382 } 19383 19384 public void finishInstrumentation(IApplicationThread target, 19385 int resultCode, Bundle results) { 19386 int userId = UserHandle.getCallingUserId(); 19387 // Refuse possible leaked file descriptors 19388 if (results != null && results.hasFileDescriptors()) { 19389 throw new IllegalArgumentException("File descriptors passed in Intent"); 19390 } 19391 19392 synchronized(this) { 19393 ProcessRecord app = getRecordForAppLocked(target); 19394 if (app == null) { 19395 Slog.w(TAG, "finishInstrumentation: no app for " + target); 19396 return; 19397 } 19398 final long origId = Binder.clearCallingIdentity(); 19399 finishInstrumentationLocked(app, resultCode, results); 19400 Binder.restoreCallingIdentity(origId); 19401 } 19402 } 19403 19404 // ========================================================= 19405 // CONFIGURATION 19406 // ========================================================= 19407 19408 public ConfigurationInfo getDeviceConfigurationInfo() { 19409 ConfigurationInfo config = new ConfigurationInfo(); 19410 synchronized (this) { 19411 final Configuration globalConfig = getGlobalConfiguration(); 19412 config.reqTouchScreen = globalConfig.touchscreen; 19413 config.reqKeyboardType = globalConfig.keyboard; 19414 config.reqNavigation = globalConfig.navigation; 19415 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD 19416 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) { 19417 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 19418 } 19419 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED 19420 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) { 19421 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 19422 } 19423 config.reqGlEsVersion = GL_ES_VERSION; 19424 } 19425 return config; 19426 } 19427 19428 ActivityStack getFocusedStack() { 19429 return mStackSupervisor.getFocusedStack(); 19430 } 19431 19432 @Override 19433 public int getFocusedStackId() throws RemoteException { 19434 ActivityStack focusedStack = getFocusedStack(); 19435 if (focusedStack != null) { 19436 return focusedStack.getStackId(); 19437 } 19438 return -1; 19439 } 19440 19441 public Configuration getConfiguration() { 19442 Configuration ci; 19443 synchronized(this) { 19444 ci = new Configuration(getGlobalConfiguration()); 19445 ci.userSetLocale = false; 19446 } 19447 return ci; 19448 } 19449 19450 @Override 19451 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { 19452 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()"); 19453 synchronized (this) { 19454 mSuppressResizeConfigChanges = suppress; 19455 } 19456 } 19457 19458 @Override 19459 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) { 19460 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()"); 19461 if (StackId.isHomeOrRecentsStack(fromStackId)) { 19462 throw new IllegalArgumentException("You can't move tasks from the home/recents stack."); 19463 } 19464 synchronized (this) { 19465 final long origId = Binder.clearCallingIdentity(); 19466 try { 19467 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop); 19468 } finally { 19469 Binder.restoreCallingIdentity(origId); 19470 } 19471 } 19472 } 19473 19474 @Override 19475 public void updatePersistentConfiguration(Configuration values) { 19476 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()"); 19477 enforceWriteSettingsPermission("updatePersistentConfiguration()"); 19478 if (values == null) { 19479 throw new NullPointerException("Configuration must not be null"); 19480 } 19481 19482 int userId = UserHandle.getCallingUserId(); 19483 19484 synchronized(this) { 19485 updatePersistentConfigurationLocked(values, userId); 19486 } 19487 } 19488 19489 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) { 19490 final long origId = Binder.clearCallingIdentity(); 19491 try { 19492 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */); 19493 } finally { 19494 Binder.restoreCallingIdentity(origId); 19495 } 19496 } 19497 19498 private void updateFontScaleIfNeeded(@UserIdInt int userId) { 19499 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(), 19500 FONT_SCALE, 1.0f, userId); 19501 19502 synchronized (this) { 19503 if (getGlobalConfiguration().fontScale == scaleFactor) { 19504 return; 19505 } 19506 19507 final Configuration configuration 19508 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); 19509 configuration.fontScale = scaleFactor; 19510 updatePersistentConfigurationLocked(configuration, userId); 19511 } 19512 } 19513 19514 private void enforceWriteSettingsPermission(String func) { 19515 int uid = Binder.getCallingUid(); 19516 if (uid == Process.ROOT_UID) { 19517 return; 19518 } 19519 19520 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid, 19521 Settings.getPackageNameForUid(mContext, uid), false)) { 19522 return; 19523 } 19524 19525 String msg = "Permission Denial: " + func + " from pid=" 19526 + Binder.getCallingPid() 19527 + ", uid=" + uid 19528 + " requires " + android.Manifest.permission.WRITE_SETTINGS; 19529 Slog.w(TAG, msg); 19530 throw new SecurityException(msg); 19531 } 19532 19533 @Override 19534 public boolean updateConfiguration(Configuration values) { 19535 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()"); 19536 19537 synchronized(this) { 19538 if (values == null && mWindowManager != null) { 19539 // sentinel: fetch the current configuration from the window manager 19540 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); 19541 } 19542 19543 if (mWindowManager != null) { 19544 // Update OOM levels based on display size. 19545 mProcessList.applyDisplaySize(mWindowManager); 19546 } 19547 19548 final long origId = Binder.clearCallingIdentity(); 19549 try { 19550 if (values != null) { 19551 Settings.System.clearConfiguration(values); 19552 } 19553 updateConfigurationLocked(values, null, false, false /* persistent */, 19554 UserHandle.USER_NULL, false /* deferResume */, 19555 mTmpUpdateConfigurationResult); 19556 return mTmpUpdateConfigurationResult.changes != 0; 19557 } finally { 19558 Binder.restoreCallingIdentity(origId); 19559 } 19560 } 19561 } 19562 19563 void updateUserConfigurationLocked() { 19564 final Configuration configuration = new Configuration(getGlobalConfiguration()); 19565 final int currentUserId = mUserController.getCurrentUserIdLocked(); 19566 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration, 19567 currentUserId, Settings.System.canWrite(mContext)); 19568 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */, 19569 false /* persistent */, currentUserId, false /* deferResume */); 19570 } 19571 19572 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 19573 boolean initLocale) { 19574 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */); 19575 } 19576 19577 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 19578 boolean initLocale, boolean deferResume) { 19579 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user 19580 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */, 19581 UserHandle.USER_NULL, deferResume); 19582 } 19583 19584 // To cache the list of supported system locales 19585 private String[] mSupportedSystemLocales = null; 19586 19587 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 19588 boolean initLocale, boolean persistent, int userId, boolean deferResume) { 19589 return updateConfigurationLocked(values, starting, initLocale, persistent, userId, 19590 deferResume, null /* result */); 19591 } 19592 19593 /** 19594 * Do either or both things: (1) change the current configuration, and (2) 19595 * make sure the given activity is running with the (now) current 19596 * configuration. Returns true if the activity has been left running, or 19597 * false if <var>starting</var> is being destroyed to match the new 19598 * configuration. 19599 * 19600 * @param userId is only used when persistent parameter is set to true to persist configuration 19601 * for that particular user 19602 */ 19603 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 19604 boolean initLocale, boolean persistent, int userId, boolean deferResume, 19605 UpdateConfigurationResult result) { 19606 int changes = 0; 19607 boolean kept = true; 19608 19609 if (mWindowManager != null) { 19610 mWindowManager.deferSurfaceLayout(); 19611 } 19612 try { 19613 if (values != null) { 19614 changes = updateGlobalConfiguration(values, initLocale, persistent, userId, 19615 deferResume); 19616 } 19617 19618 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); 19619 } finally { 19620 if (mWindowManager != null) { 19621 mWindowManager.continueSurfaceLayout(); 19622 } 19623 } 19624 19625 if (result != null) { 19626 result.changes = changes; 19627 result.activityRelaunched = !kept; 19628 } 19629 return kept; 19630 } 19631 19632 /** Update default (global) configuration and notify listeners about changes. */ 19633 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale, 19634 boolean persistent, int userId, boolean deferResume) { 19635 mTempConfig.setTo(getGlobalConfiguration()); 19636 final int changes = mTempConfig.updateFrom(values); 19637 if (changes == 0) { 19638 return 0; 19639 } 19640 19641 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION, 19642 "Updating global configuration to: " + values); 19643 19644 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 19645 19646 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) { 19647 final LocaleList locales = values.getLocales(); 19648 int bestLocaleIndex = 0; 19649 if (locales.size() > 1) { 19650 if (mSupportedSystemLocales == null) { 19651 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales(); 19652 } 19653 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales)); 19654 } 19655 SystemProperties.set("persist.sys.locale", 19656 locales.get(bestLocaleIndex).toLanguageTag()); 19657 LocaleList.setDefault(locales, bestLocaleIndex); 19658 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, 19659 locales.get(bestLocaleIndex))); 19660 } 19661 19662 mConfigurationSeq = Math.max(++mConfigurationSeq, 1); 19663 mTempConfig.seq = mConfigurationSeq; 19664 19665 // Update stored global config and notify everyone about the change. 19666 mStackSupervisor.onConfigurationChanged(mTempConfig); 19667 19668 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig); 19669 // TODO(multi-display): Update UsageEvents#Event to include displayId. 19670 mUsageStatsService.reportConfigurationChange(mTempConfig, 19671 mUserController.getCurrentUserIdLocked()); 19672 19673 // TODO: If our config changes, should we auto dismiss any currently showing dialogs? 19674 mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode); 19675 19676 AttributeCache ac = AttributeCache.instance(); 19677 if (ac != null) { 19678 ac.updateConfiguration(mTempConfig); 19679 } 19680 19681 // Make sure all resources in our process are updated right now, so that anyone who is going 19682 // to retrieve resource values after we return will be sure to get the new ones. This is 19683 // especially important during boot, where the first config change needs to guarantee all 19684 // resources have that config before following boot code is executed. 19685 mSystemThread.applyConfigurationToResources(mTempConfig); 19686 19687 // We need another copy of global config because we're scheduling some calls instead of 19688 // running them in place. We need to be sure that object we send will be handled unchanged. 19689 final Configuration configCopy = new Configuration(mTempConfig); 19690 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 19691 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 19692 msg.obj = configCopy; 19693 msg.arg1 = userId; 19694 mHandler.sendMessage(msg); 19695 } 19696 19697 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 19698 ProcessRecord app = mLruProcesses.get(i); 19699 try { 19700 if (app.thread != null) { 19701 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc " 19702 + app.processName + " new config " + configCopy); 19703 app.thread.scheduleConfigurationChanged(configCopy); 19704 } 19705 } catch (Exception e) { 19706 } 19707 } 19708 19709 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 19710 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING 19711 | Intent.FLAG_RECEIVER_FOREGROUND); 19712 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 19713 AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, 19714 UserHandle.USER_ALL); 19715 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) { 19716 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 19717 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND 19718 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 19719 if (initLocale || !mProcessesReady) { 19720 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 19721 } 19722 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 19723 AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, 19724 UserHandle.USER_ALL); 19725 } 19726 19727 // Override configuration of the default display duplicates global config, so we need to 19728 // update it also. This will also notify WindowManager about changes. 19729 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume, 19730 DEFAULT_DISPLAY); 19731 19732 return changes; 19733 } 19734 19735 @Override 19736 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) { 19737 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()"); 19738 19739 synchronized (this) { 19740 // Check if display is initialized in AM. 19741 if (!mStackSupervisor.isDisplayAdded(displayId)) { 19742 // Call might come when display is not yet added or has already been removed. 19743 if (DEBUG_CONFIGURATION) { 19744 Slog.w(TAG, "Trying to update display configuration for non-existing displayId=" 19745 + displayId); 19746 } 19747 return false; 19748 } 19749 19750 if (values == null && mWindowManager != null) { 19751 // sentinel: fetch the current configuration from the window manager 19752 values = mWindowManager.computeNewConfiguration(displayId); 19753 } 19754 19755 if (mWindowManager != null) { 19756 // Update OOM levels based on display size. 19757 mProcessList.applyDisplaySize(mWindowManager); 19758 } 19759 19760 final long origId = Binder.clearCallingIdentity(); 19761 try { 19762 if (values != null) { 19763 Settings.System.clearConfiguration(values); 19764 } 19765 updateDisplayOverrideConfigurationLocked(values, null /* starting */, 19766 false /* deferResume */, displayId, mTmpUpdateConfigurationResult); 19767 return mTmpUpdateConfigurationResult.changes != 0; 19768 } finally { 19769 Binder.restoreCallingIdentity(origId); 19770 } 19771 } 19772 } 19773 19774 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting, 19775 boolean deferResume, int displayId) { 19776 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */, 19777 displayId, null /* result */); 19778 } 19779 19780 /** 19781 * Updates override configuration specific for the selected display. If no config is provided, 19782 * new one will be computed in WM based on current display info. 19783 */ 19784 private boolean updateDisplayOverrideConfigurationLocked(Configuration values, 19785 ActivityRecord starting, boolean deferResume, int displayId, 19786 UpdateConfigurationResult result) { 19787 int changes = 0; 19788 boolean kept = true; 19789 19790 if (mWindowManager != null) { 19791 mWindowManager.deferSurfaceLayout(); 19792 } 19793 try { 19794 if (values != null) { 19795 if (displayId == DEFAULT_DISPLAY) { 19796 // Override configuration of the default display duplicates global config, so 19797 // we're calling global config update instead for default display. It will also 19798 // apply the correct override config. 19799 changes = updateGlobalConfiguration(values, false /* initLocale */, 19800 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume); 19801 } else { 19802 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId); 19803 } 19804 } 19805 19806 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); 19807 } finally { 19808 if (mWindowManager != null) { 19809 mWindowManager.continueSurfaceLayout(); 19810 } 19811 } 19812 19813 if (result != null) { 19814 result.changes = changes; 19815 result.activityRelaunched = !kept; 19816 } 19817 return kept; 19818 } 19819 19820 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume, 19821 int displayId) { 19822 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId)); 19823 final int changes = mTempConfig.updateFrom(values); 19824 if (changes == 0) { 19825 return 0; 19826 } 19827 19828 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig 19829 + " for displayId=" + displayId); 19830 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId); 19831 19832 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; 19833 if (isDensityChange && displayId == DEFAULT_DISPLAY) { 19834 // Reset the unsupported display size dialog. 19835 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG); 19836 19837 killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 19838 } 19839 19840 // Update the configuration with WM first and check if any of the stacks need to be resized 19841 // due to the configuration change. If so, resize the stacks now and do any relaunches if 19842 // necessary. This way we don't need to relaunch again afterwards in 19843 // ensureActivityConfigurationLocked(). 19844 if (mWindowManager != null) { 19845 final int[] resizedStacks = 19846 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId); 19847 if (resizedStacks != null) { 19848 for (int stackId : resizedStacks) { 19849 resizeStackWithBoundsFromWindowManager(stackId, deferResume); 19850 } 19851 } 19852 } 19853 19854 return changes; 19855 } 19856 19857 /** Applies latest configuration and/or visibility updates if needed. */ 19858 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) { 19859 boolean kept = true; 19860 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 19861 // mainStack is null during startup. 19862 if (mainStack != null) { 19863 if (changes != 0 && starting == null) { 19864 // If the configuration changed, and the caller is not already 19865 // in the process of starting an activity, then find the top 19866 // activity to check if its configuration needs to change. 19867 starting = mainStack.topRunningActivityLocked(); 19868 } 19869 19870 if (starting != null) { 19871 kept = starting.ensureActivityConfigurationLocked(changes, 19872 false /* preserveWindow */); 19873 // And we need to make sure at this point that all other activities 19874 // are made visible with the correct configuration. 19875 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes, 19876 !PRESERVE_WINDOWS); 19877 } 19878 } 19879 19880 return kept; 19881 } 19882 19883 /** Helper method that requests bounds from WM and applies them to stack. */ 19884 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) { 19885 final Rect newStackBounds = new Rect(); 19886 final Rect newTempTaskBounds = new Rect(); 19887 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds, 19888 newTempTaskBounds); 19889 mStackSupervisor.resizeStackLocked( 19890 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */, 19891 !newTempTaskBounds.isEmpty() ? newTempTaskBounds : null /* tempTaskBounds */, 19892 null /* tempTaskInsetBounds */, false /* preserveWindows */, 19893 false /* allowResizeInDockedMode */, deferResume); 19894 } 19895 19896 /** 19897 * Decide based on the configuration whether we should show the ANR, 19898 * crash, etc dialogs. The idea is that if there is no affordance to 19899 * press the on-screen buttons, or the user experience would be more 19900 * greatly impacted than the crash itself, we shouldn't show the dialog. 19901 * 19902 * A thought: SystemUI might also want to get told about this, the Power 19903 * dialog / global actions also might want different behaviors. 19904 */ 19905 private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) { 19906 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS 19907 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH 19908 && config.navigation == Configuration.NAVIGATION_NONAV); 19909 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK; 19910 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR 19911 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)) 19912 && modeType != Configuration.UI_MODE_TYPE_TELEVISION); 19913 return inputMethodExists && uiModeSupportsDialogs && !inVrMode; 19914 } 19915 19916 @Override 19917 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 19918 synchronized (this) { 19919 ActivityRecord srec = ActivityRecord.forTokenLocked(token); 19920 if (srec != null) { 19921 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity); 19922 } 19923 } 19924 return false; 19925 } 19926 19927 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 19928 Intent resultData) { 19929 19930 synchronized (this) { 19931 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 19932 if (r != null) { 19933 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData); 19934 } 19935 return false; 19936 } 19937 } 19938 19939 public int getLaunchedFromUid(IBinder activityToken) { 19940 ActivityRecord srec; 19941 synchronized (this) { 19942 srec = ActivityRecord.forTokenLocked(activityToken); 19943 } 19944 if (srec == null) { 19945 return -1; 19946 } 19947 return srec.launchedFromUid; 19948 } 19949 19950 public String getLaunchedFromPackage(IBinder activityToken) { 19951 ActivityRecord srec; 19952 synchronized (this) { 19953 srec = ActivityRecord.forTokenLocked(activityToken); 19954 } 19955 if (srec == null) { 19956 return null; 19957 } 19958 return srec.launchedFromPackage; 19959 } 19960 19961 // ========================================================= 19962 // LIFETIME MANAGEMENT 19963 // ========================================================= 19964 19965 // Returns whether the app is receiving broadcast. 19966 // If receiving, fetch all broadcast queues which the app is 19967 // the current [or imminent] receiver on. 19968 private boolean isReceivingBroadcastLocked(ProcessRecord app, 19969 ArraySet<BroadcastQueue> receivingQueues) { 19970 if (!app.curReceivers.isEmpty()) { 19971 for (BroadcastRecord r : app.curReceivers) { 19972 receivingQueues.add(r.queue); 19973 } 19974 return true; 19975 } 19976 19977 // It's not the current receiver, but it might be starting up to become one 19978 for (BroadcastQueue queue : mBroadcastQueues) { 19979 final BroadcastRecord r = queue.mPendingBroadcast; 19980 if (r != null && r.curApp == app) { 19981 // found it; report which queue it's in 19982 receivingQueues.add(queue); 19983 } 19984 } 19985 19986 return !receivingQueues.isEmpty(); 19987 } 19988 19989 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState, 19990 int targetUid, ComponentName targetComponent, String targetProcess) { 19991 if (!mTrackingAssociations) { 19992 return null; 19993 } 19994 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 19995 = mAssociations.get(targetUid); 19996 if (components == null) { 19997 components = new ArrayMap<>(); 19998 mAssociations.put(targetUid, components); 19999 } 20000 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 20001 if (sourceUids == null) { 20002 sourceUids = new SparseArray<>(); 20003 components.put(targetComponent, sourceUids); 20004 } 20005 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 20006 if (sourceProcesses == null) { 20007 sourceProcesses = new ArrayMap<>(); 20008 sourceUids.put(sourceUid, sourceProcesses); 20009 } 20010 Association ass = sourceProcesses.get(sourceProcess); 20011 if (ass == null) { 20012 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 20013 targetProcess); 20014 sourceProcesses.put(sourceProcess, ass); 20015 } 20016 ass.mCount++; 20017 ass.mNesting++; 20018 if (ass.mNesting == 1) { 20019 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis(); 20020 ass.mLastState = sourceState; 20021 } 20022 return ass; 20023 } 20024 20025 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 20026 ComponentName targetComponent) { 20027 if (!mTrackingAssociations) { 20028 return; 20029 } 20030 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 20031 = mAssociations.get(targetUid); 20032 if (components == null) { 20033 return; 20034 } 20035 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 20036 if (sourceUids == null) { 20037 return; 20038 } 20039 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 20040 if (sourceProcesses == null) { 20041 return; 20042 } 20043 Association ass = sourceProcesses.get(sourceProcess); 20044 if (ass == null || ass.mNesting <= 0) { 20045 return; 20046 } 20047 ass.mNesting--; 20048 if (ass.mNesting == 0) { 20049 long uptime = SystemClock.uptimeMillis(); 20050 ass.mTime += uptime - ass.mStartTime; 20051 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] 20052 += uptime - ass.mLastStateUptime; 20053 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2; 20054 } 20055 } 20056 20057 private void noteUidProcessState(final int uid, final int state) { 20058 mBatteryStatsService.noteUidProcessState(uid, state); 20059 if (mTrackingAssociations) { 20060 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 20061 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 20062 = mAssociations.valueAt(i1); 20063 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 20064 SparseArray<ArrayMap<String, Association>> sourceUids 20065 = targetComponents.valueAt(i2); 20066 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid); 20067 if (sourceProcesses != null) { 20068 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 20069 Association ass = sourceProcesses.valueAt(i4); 20070 if (ass.mNesting >= 1) { 20071 // currently associated 20072 long uptime = SystemClock.uptimeMillis(); 20073 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] 20074 += uptime - ass.mLastStateUptime; 20075 ass.mLastState = state; 20076 ass.mLastStateUptime = uptime; 20077 } 20078 } 20079 } 20080 } 20081 } 20082 } 20083 } 20084 20085 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 20086 boolean doingAll, long now) { 20087 if (mAdjSeq == app.adjSeq) { 20088 // This adjustment has already been computed. 20089 return app.curRawAdj; 20090 } 20091 20092 if (app.thread == null) { 20093 app.adjSeq = mAdjSeq; 20094 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20095 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20096 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 20097 } 20098 20099 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 20100 app.adjSource = null; 20101 app.adjTarget = null; 20102 app.empty = false; 20103 app.cached = false; 20104 20105 final int activitiesSize = app.activities.size(); 20106 20107 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 20108 // The max adjustment doesn't allow this app to be anything 20109 // below foreground, so it is not worth doing work for it. 20110 app.adjType = "fixed"; 20111 app.adjSeq = mAdjSeq; 20112 app.curRawAdj = app.maxAdj; 20113 app.foregroundActivities = false; 20114 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20115 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 20116 // System processes can do UI, and when they do we want to have 20117 // them trim their memory after the user leaves the UI. To 20118 // facilitate this, here we need to determine whether or not it 20119 // is currently showing UI. 20120 app.systemNoUi = true; 20121 if (app == TOP_APP) { 20122 app.systemNoUi = false; 20123 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; 20124 app.adjType = "pers-top-activity"; 20125 } else if (app.hasTopUi) { 20126 app.systemNoUi = false; 20127 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; 20128 app.adjType = "pers-top-ui"; 20129 } else if (activitiesSize > 0) { 20130 for (int j = 0; j < activitiesSize; j++) { 20131 final ActivityRecord r = app.activities.get(j); 20132 if (r.visible) { 20133 app.systemNoUi = false; 20134 } 20135 } 20136 } 20137 if (!app.systemNoUi) { 20138 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 20139 } 20140 return (app.curAdj=app.maxAdj); 20141 } 20142 20143 app.systemNoUi = false; 20144 20145 final int PROCESS_STATE_CUR_TOP = mTopProcessState; 20146 20147 // Determine the importance of the process, starting with most 20148 // important to least, and assign an appropriate OOM adjustment. 20149 int adj; 20150 int schedGroup; 20151 int procState; 20152 boolean foregroundActivities = false; 20153 mTmpBroadcastQueue.clear(); 20154 if (app == TOP_APP) { 20155 // The last app on the list is the foreground app. 20156 adj = ProcessList.FOREGROUND_APP_ADJ; 20157 schedGroup = ProcessList.SCHED_GROUP_TOP_APP; 20158 app.adjType = "top-activity"; 20159 foregroundActivities = true; 20160 procState = PROCESS_STATE_CUR_TOP; 20161 } else if (app.instr != null) { 20162 // Don't want to kill running instrumentation. 20163 adj = ProcessList.FOREGROUND_APP_ADJ; 20164 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20165 app.adjType = "instrumentation"; 20166 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 20167 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) { 20168 // An app that is currently receiving a broadcast also 20169 // counts as being in the foreground for OOM killer purposes. 20170 // It's placed in a sched group based on the nature of the 20171 // broadcast as reflected by which queue it's active in. 20172 adj = ProcessList.FOREGROUND_APP_ADJ; 20173 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue)) 20174 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; 20175 app.adjType = "broadcast"; 20176 procState = ActivityManager.PROCESS_STATE_RECEIVER; 20177 } else if (app.executingServices.size() > 0) { 20178 // An app that is currently executing a service callback also 20179 // counts as being in the foreground. 20180 adj = ProcessList.FOREGROUND_APP_ADJ; 20181 schedGroup = app.execServicesFg ? 20182 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; 20183 app.adjType = "exec-service"; 20184 procState = ActivityManager.PROCESS_STATE_SERVICE; 20185 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 20186 } else { 20187 // As far as we know the process is empty. We may change our mind later. 20188 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20189 // At this point we don't actually know the adjustment. Use the cached adj 20190 // value that the caller wants us to. 20191 adj = cachedAdj; 20192 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20193 app.cached = true; 20194 app.empty = true; 20195 app.adjType = "cch-empty"; 20196 } 20197 20198 // Examine all activities if not already foreground. 20199 if (!foregroundActivities && activitiesSize > 0) { 20200 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX; 20201 for (int j = 0; j < activitiesSize; j++) { 20202 final ActivityRecord r = app.activities.get(j); 20203 if (r.app != app) { 20204 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app 20205 + " instead of expected " + app); 20206 if (r.app == null || (r.app.uid == app.uid)) { 20207 // Only fix things up when they look sane 20208 r.app = app; 20209 } else { 20210 continue; 20211 } 20212 } 20213 if (r.visible) { 20214 // App has a visible activity; only upgrade adjustment. 20215 if (adj > ProcessList.VISIBLE_APP_ADJ) { 20216 adj = ProcessList.VISIBLE_APP_ADJ; 20217 app.adjType = "visible"; 20218 } 20219 if (procState > PROCESS_STATE_CUR_TOP) { 20220 procState = PROCESS_STATE_CUR_TOP; 20221 } 20222 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20223 app.cached = false; 20224 app.empty = false; 20225 foregroundActivities = true; 20226 if (r.task != null && minLayer > 0) { 20227 final int layer = r.task.mLayerRank; 20228 if (layer >= 0 && minLayer > layer) { 20229 minLayer = layer; 20230 } 20231 } 20232 break; 20233 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 20234 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 20235 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 20236 app.adjType = "pausing"; 20237 } 20238 if (procState > PROCESS_STATE_CUR_TOP) { 20239 procState = PROCESS_STATE_CUR_TOP; 20240 } 20241 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20242 app.cached = false; 20243 app.empty = false; 20244 foregroundActivities = true; 20245 } else if (r.state == ActivityState.STOPPING) { 20246 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 20247 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 20248 app.adjType = "stopping"; 20249 } 20250 // For the process state, we will at this point consider the 20251 // process to be cached. It will be cached either as an activity 20252 // or empty depending on whether the activity is finishing. We do 20253 // this so that we can treat the process as cached for purposes of 20254 // memory trimming (determing current memory level, trim command to 20255 // send to process) since there can be an arbitrary number of stopping 20256 // processes and they should soon all go into the cached state. 20257 if (!r.finishing) { 20258 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 20259 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 20260 } 20261 } 20262 app.cached = false; 20263 app.empty = false; 20264 foregroundActivities = true; 20265 } else { 20266 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 20267 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 20268 app.adjType = "cch-act"; 20269 } 20270 } 20271 } 20272 if (adj == ProcessList.VISIBLE_APP_ADJ) { 20273 adj += minLayer; 20274 } 20275 } 20276 20277 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ 20278 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 20279 if (app.foregroundServices) { 20280 // The user is aware of this app, so make it visible. 20281 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 20282 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 20283 app.cached = false; 20284 app.adjType = "fg-service"; 20285 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20286 } else if (app.forcingToForeground != null) { 20287 // The user is aware of this app, so make it visible. 20288 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 20289 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 20290 app.cached = false; 20291 app.adjType = "force-fg"; 20292 app.adjSource = app.forcingToForeground; 20293 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20294 } else if (app.hasOverlayUi) { 20295 // The process is display an overlay UI. 20296 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 20297 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 20298 app.cached = false; 20299 app.adjType = "has-overlay-ui"; 20300 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20301 } 20302 } 20303 20304 if (app == mHeavyWeightProcess) { 20305 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 20306 // We don't want to kill the current heavy-weight process. 20307 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 20308 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20309 app.cached = false; 20310 app.adjType = "heavy"; 20311 } 20312 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 20313 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 20314 } 20315 } 20316 20317 if (app == mHomeProcess) { 20318 if (adj > ProcessList.HOME_APP_ADJ) { 20319 // This process is hosting what we currently consider to be the 20320 // home app, so we don't want to let it go into the background. 20321 adj = ProcessList.HOME_APP_ADJ; 20322 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20323 app.cached = false; 20324 app.adjType = "home"; 20325 } 20326 if (procState > ActivityManager.PROCESS_STATE_HOME) { 20327 procState = ActivityManager.PROCESS_STATE_HOME; 20328 } 20329 } 20330 20331 if (app == mPreviousProcess && app.activities.size() > 0) { 20332 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 20333 // This was the previous process that showed UI to the user. 20334 // We want to try to keep it around more aggressively, to give 20335 // a good experience around switching between two apps. 20336 adj = ProcessList.PREVIOUS_APP_ADJ; 20337 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20338 app.cached = false; 20339 app.adjType = "previous"; 20340 } 20341 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 20342 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 20343 } 20344 } 20345 20346 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 20347 + " reason=" + app.adjType); 20348 20349 // By default, we use the computed adjustment. It may be changed if 20350 // there are applications dependent on our services or providers, but 20351 // this gives us a baseline and makes sure we don't get into an 20352 // infinite recursion. 20353 app.adjSeq = mAdjSeq; 20354 app.curRawAdj = adj; 20355 app.hasStartedServices = false; 20356 20357 if (mBackupTarget != null && app == mBackupTarget.app) { 20358 // If possible we want to avoid killing apps while they're being backed up 20359 if (adj > ProcessList.BACKUP_APP_ADJ) { 20360 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app); 20361 adj = ProcessList.BACKUP_APP_ADJ; 20362 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 20363 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 20364 } 20365 app.adjType = "backup"; 20366 app.cached = false; 20367 } 20368 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 20369 procState = ActivityManager.PROCESS_STATE_BACKUP; 20370 } 20371 } 20372 20373 boolean mayBeTop = false; 20374 20375 for (int is = app.services.size()-1; 20376 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 20377 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 20378 || procState > ActivityManager.PROCESS_STATE_TOP); 20379 is--) { 20380 ServiceRecord s = app.services.valueAt(is); 20381 if (s.startRequested) { 20382 app.hasStartedServices = true; 20383 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 20384 procState = ActivityManager.PROCESS_STATE_SERVICE; 20385 } 20386 if (app.hasShownUi && app != mHomeProcess) { 20387 // If this process has shown some UI, let it immediately 20388 // go to the LRU list because it may be pretty heavy with 20389 // UI stuff. We'll tag it with a label just to help 20390 // debug and understand what is going on. 20391 if (adj > ProcessList.SERVICE_ADJ) { 20392 app.adjType = "cch-started-ui-services"; 20393 } 20394 } else { 20395 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 20396 // This service has seen some activity within 20397 // recent memory, so we will keep its process ahead 20398 // of the background processes. 20399 if (adj > ProcessList.SERVICE_ADJ) { 20400 adj = ProcessList.SERVICE_ADJ; 20401 app.adjType = "started-services"; 20402 app.cached = false; 20403 } 20404 } 20405 // If we have let the service slide into the background 20406 // state, still have some text describing what it is doing 20407 // even though the service no longer has an impact. 20408 if (adj > ProcessList.SERVICE_ADJ) { 20409 app.adjType = "cch-started-services"; 20410 } 20411 } 20412 } 20413 20414 for (int conni = s.connections.size()-1; 20415 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 20416 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 20417 || procState > ActivityManager.PROCESS_STATE_TOP); 20418 conni--) { 20419 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 20420 for (int i = 0; 20421 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 20422 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 20423 || procState > ActivityManager.PROCESS_STATE_TOP); 20424 i++) { 20425 // XXX should compute this based on the max of 20426 // all connected clients. 20427 ConnectionRecord cr = clist.get(i); 20428 if (cr.binding.client == app) { 20429 // Binding to ourself is not interesting. 20430 continue; 20431 } 20432 20433 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 20434 ProcessRecord client = cr.binding.client; 20435 int clientAdj = computeOomAdjLocked(client, cachedAdj, 20436 TOP_APP, doingAll, now); 20437 int clientProcState = client.curProcState; 20438 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 20439 // If the other app is cached for any reason, for purposes here 20440 // we are going to consider it empty. The specific cached state 20441 // doesn't propagate except under certain conditions. 20442 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20443 } 20444 String adjType = null; 20445 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 20446 // Not doing bind OOM management, so treat 20447 // this guy more like a started service. 20448 if (app.hasShownUi && app != mHomeProcess) { 20449 // If this process has shown some UI, let it immediately 20450 // go to the LRU list because it may be pretty heavy with 20451 // UI stuff. We'll tag it with a label just to help 20452 // debug and understand what is going on. 20453 if (adj > clientAdj) { 20454 adjType = "cch-bound-ui-services"; 20455 } 20456 app.cached = false; 20457 clientAdj = adj; 20458 clientProcState = procState; 20459 } else { 20460 if (now >= (s.lastActivity 20461 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 20462 // This service has not seen activity within 20463 // recent memory, so allow it to drop to the 20464 // LRU list if there is no other reason to keep 20465 // it around. We'll also tag it with a label just 20466 // to help debug and undertand what is going on. 20467 if (adj > clientAdj) { 20468 adjType = "cch-bound-services"; 20469 } 20470 clientAdj = adj; 20471 } 20472 } 20473 } 20474 if (adj > clientAdj) { 20475 // If this process has recently shown UI, and 20476 // the process that is binding to it is less 20477 // important than being visible, then we don't 20478 // care about the binding as much as we care 20479 // about letting this process get into the LRU 20480 // list to be killed and restarted if needed for 20481 // memory. 20482 if (app.hasShownUi && app != mHomeProcess 20483 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 20484 adjType = "cch-bound-ui-services"; 20485 } else { 20486 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 20487 |Context.BIND_IMPORTANT)) != 0) { 20488 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 20489 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 20490 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 20491 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 20492 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 20493 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 20494 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 20495 adj = clientAdj; 20496 } else { 20497 if (adj > ProcessList.VISIBLE_APP_ADJ) { 20498 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ); 20499 } 20500 } 20501 if (!client.cached) { 20502 app.cached = false; 20503 } 20504 adjType = "service"; 20505 } 20506 } 20507 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 20508 // This will treat important bound services identically to 20509 // the top app, which may behave differently than generic 20510 // foreground work. 20511 if (client.curSchedGroup > schedGroup) { 20512 if ((cr.flags&Context.BIND_IMPORTANT) != 0) { 20513 schedGroup = client.curSchedGroup; 20514 } else { 20515 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20516 } 20517 } 20518 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 20519 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 20520 // Special handling of clients who are in the top state. 20521 // We *may* want to consider this process to be in the 20522 // top state as well, but only if there is not another 20523 // reason for it to be running. Being on the top is a 20524 // special state, meaning you are specifically running 20525 // for the current top app. If the process is already 20526 // running in the background for some other reason, it 20527 // is more important to continue considering it to be 20528 // in the background state. 20529 mayBeTop = true; 20530 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20531 } else { 20532 // Special handling for above-top states (persistent 20533 // processes). These should not bring the current process 20534 // into the top state, since they are not on top. Instead 20535 // give them the best state after that. 20536 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) { 20537 clientProcState = 20538 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 20539 } else if (mWakefulness 20540 == PowerManagerInternal.WAKEFULNESS_AWAKE && 20541 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) 20542 != 0) { 20543 clientProcState = 20544 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 20545 } else { 20546 clientProcState = 20547 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 20548 } 20549 } 20550 } 20551 } else { 20552 if (clientProcState < 20553 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 20554 clientProcState = 20555 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 20556 } 20557 } 20558 if (procState > clientProcState) { 20559 procState = clientProcState; 20560 } 20561 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 20562 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 20563 app.pendingUiClean = true; 20564 } 20565 if (adjType != null) { 20566 app.adjType = adjType; 20567 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 20568 .REASON_SERVICE_IN_USE; 20569 app.adjSource = cr.binding.client; 20570 app.adjSourceProcState = clientProcState; 20571 app.adjTarget = s.name; 20572 } 20573 } 20574 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 20575 app.treatLikeActivity = true; 20576 } 20577 final ActivityRecord a = cr.activity; 20578 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 20579 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 20580 (a.visible || a.state == ActivityState.RESUMED || 20581 a.state == ActivityState.PAUSING)) { 20582 adj = ProcessList.FOREGROUND_APP_ADJ; 20583 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 20584 if ((cr.flags&Context.BIND_IMPORTANT) != 0) { 20585 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND; 20586 } else { 20587 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20588 } 20589 } 20590 app.cached = false; 20591 app.adjType = "service"; 20592 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 20593 .REASON_SERVICE_IN_USE; 20594 app.adjSource = a; 20595 app.adjSourceProcState = procState; 20596 app.adjTarget = s.name; 20597 } 20598 } 20599 } 20600 } 20601 } 20602 20603 for (int provi = app.pubProviders.size()-1; 20604 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 20605 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 20606 || procState > ActivityManager.PROCESS_STATE_TOP); 20607 provi--) { 20608 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 20609 for (int i = cpr.connections.size()-1; 20610 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 20611 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 20612 || procState > ActivityManager.PROCESS_STATE_TOP); 20613 i--) { 20614 ContentProviderConnection conn = cpr.connections.get(i); 20615 ProcessRecord client = conn.client; 20616 if (client == app) { 20617 // Being our own client is not interesting. 20618 continue; 20619 } 20620 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 20621 int clientProcState = client.curProcState; 20622 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 20623 // If the other app is cached for any reason, for purposes here 20624 // we are going to consider it empty. 20625 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20626 } 20627 if (adj > clientAdj) { 20628 if (app.hasShownUi && app != mHomeProcess 20629 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 20630 app.adjType = "cch-ui-provider"; 20631 } else { 20632 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 20633 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 20634 app.adjType = "provider"; 20635 } 20636 app.cached &= client.cached; 20637 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 20638 .REASON_PROVIDER_IN_USE; 20639 app.adjSource = client; 20640 app.adjSourceProcState = clientProcState; 20641 app.adjTarget = cpr.name; 20642 } 20643 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 20644 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 20645 // Special handling of clients who are in the top state. 20646 // We *may* want to consider this process to be in the 20647 // top state as well, but only if there is not another 20648 // reason for it to be running. Being on the top is a 20649 // special state, meaning you are specifically running 20650 // for the current top app. If the process is already 20651 // running in the background for some other reason, it 20652 // is more important to continue considering it to be 20653 // in the background state. 20654 mayBeTop = true; 20655 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 20656 } else { 20657 // Special handling for above-top states (persistent 20658 // processes). These should not bring the current process 20659 // into the top state, since they are not on top. Instead 20660 // give them the best state after that. 20661 clientProcState = 20662 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 20663 } 20664 } 20665 if (procState > clientProcState) { 20666 procState = clientProcState; 20667 } 20668 if (client.curSchedGroup > schedGroup) { 20669 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20670 } 20671 } 20672 // If the provider has external (non-framework) process 20673 // dependencies, ensure that its adjustment is at least 20674 // FOREGROUND_APP_ADJ. 20675 if (cpr.hasExternalProcessHandles()) { 20676 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 20677 adj = ProcessList.FOREGROUND_APP_ADJ; 20678 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20679 app.cached = false; 20680 app.adjType = "provider"; 20681 app.adjTarget = cpr.name; 20682 } 20683 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 20684 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 20685 } 20686 } 20687 } 20688 20689 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) { 20690 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 20691 adj = ProcessList.PREVIOUS_APP_ADJ; 20692 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 20693 app.cached = false; 20694 app.adjType = "provider"; 20695 } 20696 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 20697 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 20698 } 20699 } 20700 20701 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 20702 // A client of one of our services or providers is in the top state. We 20703 // *may* want to be in the top state, but not if we are already running in 20704 // the background for some other reason. For the decision here, we are going 20705 // to pick out a few specific states that we want to remain in when a client 20706 // is top (states that tend to be longer-term) and otherwise allow it to go 20707 // to the top state. 20708 switch (procState) { 20709 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 20710 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 20711 case ActivityManager.PROCESS_STATE_SERVICE: 20712 // These all are longer-term states, so pull them up to the top 20713 // of the background states, but not all the way to the top state. 20714 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 20715 break; 20716 default: 20717 // Otherwise, top is a better choice, so take it. 20718 procState = ActivityManager.PROCESS_STATE_TOP; 20719 break; 20720 } 20721 } 20722 20723 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 20724 if (app.hasClientActivities) { 20725 // This is a cached process, but with client activities. Mark it so. 20726 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 20727 app.adjType = "cch-client-act"; 20728 } else if (app.treatLikeActivity) { 20729 // This is a cached process, but somebody wants us to treat it like it has 20730 // an activity, okay! 20731 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 20732 app.adjType = "cch-as-act"; 20733 } 20734 } 20735 20736 if (adj == ProcessList.SERVICE_ADJ) { 20737 if (doingAll) { 20738 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 20739 mNewNumServiceProcs++; 20740 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 20741 if (!app.serviceb) { 20742 // This service isn't far enough down on the LRU list to 20743 // normally be a B service, but if we are low on RAM and it 20744 // is large we want to force it down since we would prefer to 20745 // keep launcher over it. 20746 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 20747 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 20748 app.serviceHighRam = true; 20749 app.serviceb = true; 20750 //Slog.i(TAG, "ADJ " + app + " high ram!"); 20751 } else { 20752 mNewNumAServiceProcs++; 20753 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 20754 } 20755 } else { 20756 app.serviceHighRam = false; 20757 } 20758 } 20759 if (app.serviceb) { 20760 adj = ProcessList.SERVICE_B_ADJ; 20761 } 20762 } 20763 20764 app.curRawAdj = adj; 20765 20766 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 20767 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 20768 if (adj > app.maxAdj) { 20769 adj = app.maxAdj; 20770 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 20771 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 20772 } 20773 } 20774 20775 // Do final modification to adj. Everything we do between here and applying 20776 // the final setAdj must be done in this function, because we will also use 20777 // it when computing the final cached adj later. Note that we don't need to 20778 // worry about this for max adj above, since max adj will always be used to 20779 // keep it out of the cached vaues. 20780 app.curAdj = app.modifyRawOomAdj(adj); 20781 app.curSchedGroup = schedGroup; 20782 app.curProcState = procState; 20783 app.foregroundActivities = foregroundActivities; 20784 20785 return app.curRawAdj; 20786 } 20787 20788 /** 20789 * Record new PSS sample for a process. 20790 */ 20791 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss, 20792 long now) { 20793 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024, 20794 swapPss * 1024); 20795 proc.lastPssTime = now; 20796 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 20797 if (DEBUG_PSS) Slog.d(TAG_PSS, 20798 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss 20799 + " state=" + ProcessList.makeProcStateString(procState)); 20800 if (proc.initialIdlePss == 0) { 20801 proc.initialIdlePss = pss; 20802 } 20803 proc.lastPss = pss; 20804 proc.lastSwapPss = swapPss; 20805 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 20806 proc.lastCachedPss = pss; 20807 proc.lastCachedSwapPss = swapPss; 20808 } 20809 20810 final SparseArray<Pair<Long, String>> watchUids 20811 = mMemWatchProcesses.getMap().get(proc.processName); 20812 Long check = null; 20813 if (watchUids != null) { 20814 Pair<Long, String> val = watchUids.get(proc.uid); 20815 if (val == null) { 20816 val = watchUids.get(0); 20817 } 20818 if (val != null) { 20819 check = val.first; 20820 } 20821 } 20822 if (check != null) { 20823 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) { 20824 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 20825 if (!isDebuggable) { 20826 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 20827 isDebuggable = true; 20828 } 20829 } 20830 if (isDebuggable) { 20831 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting"); 20832 final ProcessRecord myProc = proc; 20833 final File heapdumpFile = DumpHeapProvider.getJavaFile(); 20834 mMemWatchDumpProcName = proc.processName; 20835 mMemWatchDumpFile = heapdumpFile.toString(); 20836 mMemWatchDumpPid = proc.pid; 20837 mMemWatchDumpUid = proc.uid; 20838 BackgroundThread.getHandler().post(new Runnable() { 20839 @Override 20840 public void run() { 20841 revokeUriPermission(ActivityThread.currentActivityThread() 20842 .getApplicationThread(), 20843 DumpHeapActivity.JAVA_URI, 20844 Intent.FLAG_GRANT_READ_URI_PERMISSION 20845 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 20846 UserHandle.myUserId()); 20847 ParcelFileDescriptor fd = null; 20848 try { 20849 heapdumpFile.delete(); 20850 fd = ParcelFileDescriptor.open(heapdumpFile, 20851 ParcelFileDescriptor.MODE_CREATE | 20852 ParcelFileDescriptor.MODE_TRUNCATE | 20853 ParcelFileDescriptor.MODE_WRITE_ONLY | 20854 ParcelFileDescriptor.MODE_APPEND); 20855 IApplicationThread thread = myProc.thread; 20856 if (thread != null) { 20857 try { 20858 if (DEBUG_PSS) Slog.d(TAG_PSS, 20859 "Requesting dump heap from " 20860 + myProc + " to " + heapdumpFile); 20861 thread.dumpHeap(true, heapdumpFile.toString(), fd); 20862 } catch (RemoteException e) { 20863 } 20864 } 20865 } catch (FileNotFoundException e) { 20866 e.printStackTrace(); 20867 } finally { 20868 if (fd != null) { 20869 try { 20870 fd.close(); 20871 } catch (IOException e) { 20872 } 20873 } 20874 } 20875 } 20876 }); 20877 } else { 20878 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check 20879 + ", but debugging not enabled"); 20880 } 20881 } 20882 } 20883 } 20884 20885 /** 20886 * Schedule PSS collection of a process. 20887 */ 20888 void requestPssLocked(ProcessRecord proc, int procState) { 20889 if (mPendingPssProcesses.contains(proc)) { 20890 return; 20891 } 20892 if (mPendingPssProcesses.size() == 0) { 20893 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 20894 } 20895 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc); 20896 proc.pssProcState = procState; 20897 mPendingPssProcesses.add(proc); 20898 } 20899 20900 /** 20901 * Schedule PSS collection of all processes. 20902 */ 20903 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 20904 if (!always) { 20905 if (now < (mLastFullPssTime + 20906 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 20907 return; 20908 } 20909 } 20910 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered); 20911 mLastFullPssTime = now; 20912 mFullPssPending = true; 20913 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 20914 mPendingPssProcesses.clear(); 20915 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 20916 ProcessRecord app = mLruProcesses.get(i); 20917 if (app.thread == null 20918 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 20919 continue; 20920 } 20921 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 20922 app.pssProcState = app.setProcState; 20923 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 20924 mTestPssMode, isSleepingLocked(), now); 20925 mPendingPssProcesses.add(app); 20926 } 20927 } 20928 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 20929 } 20930 20931 public void setTestPssMode(boolean enabled) { 20932 synchronized (this) { 20933 mTestPssMode = enabled; 20934 if (enabled) { 20935 // Whenever we enable the mode, we want to take a snapshot all of current 20936 // process mem use. 20937 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 20938 } 20939 } 20940 } 20941 20942 /** 20943 * Ask a given process to GC right now. 20944 */ 20945 final void performAppGcLocked(ProcessRecord app) { 20946 try { 20947 app.lastRequestedGc = SystemClock.uptimeMillis(); 20948 if (app.thread != null) { 20949 if (app.reportLowMemory) { 20950 app.reportLowMemory = false; 20951 app.thread.scheduleLowMemory(); 20952 } else { 20953 app.thread.processInBackground(); 20954 } 20955 } 20956 } catch (Exception e) { 20957 // whatever. 20958 } 20959 } 20960 20961 /** 20962 * Returns true if things are idle enough to perform GCs. 20963 */ 20964 private final boolean canGcNowLocked() { 20965 boolean processingBroadcasts = false; 20966 for (BroadcastQueue q : mBroadcastQueues) { 20967 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 20968 processingBroadcasts = true; 20969 } 20970 } 20971 return !processingBroadcasts 20972 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle()); 20973 } 20974 20975 /** 20976 * Perform GCs on all processes that are waiting for it, but only 20977 * if things are idle. 20978 */ 20979 final void performAppGcsLocked() { 20980 final int N = mProcessesToGc.size(); 20981 if (N <= 0) { 20982 return; 20983 } 20984 if (canGcNowLocked()) { 20985 while (mProcessesToGc.size() > 0) { 20986 ProcessRecord proc = mProcessesToGc.remove(0); 20987 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 20988 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 20989 <= SystemClock.uptimeMillis()) { 20990 // To avoid spamming the system, we will GC processes one 20991 // at a time, waiting a few seconds between each. 20992 performAppGcLocked(proc); 20993 scheduleAppGcsLocked(); 20994 return; 20995 } else { 20996 // It hasn't been long enough since we last GCed this 20997 // process... put it in the list to wait for its time. 20998 addProcessToGcListLocked(proc); 20999 break; 21000 } 21001 } 21002 } 21003 21004 scheduleAppGcsLocked(); 21005 } 21006 } 21007 21008 /** 21009 * If all looks good, perform GCs on all processes waiting for them. 21010 */ 21011 final void performAppGcsIfAppropriateLocked() { 21012 if (canGcNowLocked()) { 21013 performAppGcsLocked(); 21014 return; 21015 } 21016 // Still not idle, wait some more. 21017 scheduleAppGcsLocked(); 21018 } 21019 21020 /** 21021 * Schedule the execution of all pending app GCs. 21022 */ 21023 final void scheduleAppGcsLocked() { 21024 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 21025 21026 if (mProcessesToGc.size() > 0) { 21027 // Schedule a GC for the time to the next process. 21028 ProcessRecord proc = mProcessesToGc.get(0); 21029 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 21030 21031 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 21032 long now = SystemClock.uptimeMillis(); 21033 if (when < (now+GC_TIMEOUT)) { 21034 when = now + GC_TIMEOUT; 21035 } 21036 mHandler.sendMessageAtTime(msg, when); 21037 } 21038 } 21039 21040 /** 21041 * Add a process to the array of processes waiting to be GCed. Keeps the 21042 * list in sorted order by the last GC time. The process can't already be 21043 * on the list. 21044 */ 21045 final void addProcessToGcListLocked(ProcessRecord proc) { 21046 boolean added = false; 21047 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 21048 if (mProcessesToGc.get(i).lastRequestedGc < 21049 proc.lastRequestedGc) { 21050 added = true; 21051 mProcessesToGc.add(i+1, proc); 21052 break; 21053 } 21054 } 21055 if (!added) { 21056 mProcessesToGc.add(0, proc); 21057 } 21058 } 21059 21060 /** 21061 * Set up to ask a process to GC itself. This will either do it 21062 * immediately, or put it on the list of processes to gc the next 21063 * time things are idle. 21064 */ 21065 final void scheduleAppGcLocked(ProcessRecord app) { 21066 long now = SystemClock.uptimeMillis(); 21067 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 21068 return; 21069 } 21070 if (!mProcessesToGc.contains(app)) { 21071 addProcessToGcListLocked(app); 21072 scheduleAppGcsLocked(); 21073 } 21074 } 21075 21076 final void checkExcessivePowerUsageLocked(boolean doKills) { 21077 updateCpuStatsNow(); 21078 21079 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 21080 boolean doWakeKills = doKills; 21081 boolean doCpuKills = doKills; 21082 if (mLastPowerCheckRealtime == 0) { 21083 doWakeKills = false; 21084 } 21085 if (mLastPowerCheckUptime == 0) { 21086 doCpuKills = false; 21087 } 21088 if (stats.isScreenOn()) { 21089 doWakeKills = false; 21090 } 21091 final long curRealtime = SystemClock.elapsedRealtime(); 21092 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 21093 final long curUptime = SystemClock.uptimeMillis(); 21094 final long uptimeSince = curUptime - mLastPowerCheckUptime; 21095 mLastPowerCheckRealtime = curRealtime; 21096 mLastPowerCheckUptime = curUptime; 21097 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 21098 doWakeKills = false; 21099 } 21100 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 21101 doCpuKills = false; 21102 } 21103 int i = mLruProcesses.size(); 21104 while (i > 0) { 21105 i--; 21106 ProcessRecord app = mLruProcesses.get(i); 21107 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 21108 long wtime; 21109 synchronized (stats) { 21110 wtime = stats.getProcessWakeTime(app.info.uid, 21111 app.pid, curRealtime); 21112 } 21113 long wtimeUsed = wtime - app.lastWakeTime; 21114 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 21115 if (DEBUG_POWER) { 21116 StringBuilder sb = new StringBuilder(128); 21117 sb.append("Wake for "); 21118 app.toShortString(sb); 21119 sb.append(": over "); 21120 TimeUtils.formatDuration(realtimeSince, sb); 21121 sb.append(" used "); 21122 TimeUtils.formatDuration(wtimeUsed, sb); 21123 sb.append(" ("); 21124 sb.append((wtimeUsed*100)/realtimeSince); 21125 sb.append("%)"); 21126 Slog.i(TAG_POWER, sb.toString()); 21127 sb.setLength(0); 21128 sb.append("CPU for "); 21129 app.toShortString(sb); 21130 sb.append(": over "); 21131 TimeUtils.formatDuration(uptimeSince, sb); 21132 sb.append(" used "); 21133 TimeUtils.formatDuration(cputimeUsed, sb); 21134 sb.append(" ("); 21135 sb.append((cputimeUsed*100)/uptimeSince); 21136 sb.append("%)"); 21137 Slog.i(TAG_POWER, sb.toString()); 21138 } 21139 // If a process has held a wake lock for more 21140 // than 50% of the time during this period, 21141 // that sounds bad. Kill! 21142 if (doWakeKills && realtimeSince > 0 21143 && ((wtimeUsed*100)/realtimeSince) >= 50) { 21144 synchronized (stats) { 21145 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 21146 realtimeSince, wtimeUsed); 21147 } 21148 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 21149 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 21150 } else if (doCpuKills && uptimeSince > 0 21151 && ((cputimeUsed*100)/uptimeSince) >= 25) { 21152 synchronized (stats) { 21153 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 21154 uptimeSince, cputimeUsed); 21155 } 21156 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 21157 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 21158 } else { 21159 app.lastWakeTime = wtime; 21160 app.lastCpuTime = app.curCpuTime; 21161 } 21162 } 21163 } 21164 } 21165 21166 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now, 21167 long nowElapsed) { 21168 boolean success = true; 21169 21170 if (app.curRawAdj != app.setRawAdj) { 21171 app.setRawAdj = app.curRawAdj; 21172 } 21173 21174 int changes = 0; 21175 21176 if (app.curAdj != app.setAdj) { 21177 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 21178 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 21179 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": " 21180 + app.adjType); 21181 app.setAdj = app.curAdj; 21182 app.verifiedAdj = ProcessList.INVALID_ADJ; 21183 } 21184 21185 if (app.setSchedGroup != app.curSchedGroup) { 21186 int oldSchedGroup = app.setSchedGroup; 21187 app.setSchedGroup = app.curSchedGroup; 21188 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 21189 "Setting sched group of " + app.processName 21190 + " to " + app.curSchedGroup); 21191 if (app.waitingToKill != null && app.curReceivers.isEmpty() 21192 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) { 21193 app.kill(app.waitingToKill, true); 21194 success = false; 21195 } else { 21196 int processGroup; 21197 switch (app.curSchedGroup) { 21198 case ProcessList.SCHED_GROUP_BACKGROUND: 21199 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 21200 break; 21201 case ProcessList.SCHED_GROUP_TOP_APP: 21202 case ProcessList.SCHED_GROUP_TOP_APP_BOUND: 21203 processGroup = Process.THREAD_GROUP_TOP_APP; 21204 break; 21205 default: 21206 processGroup = Process.THREAD_GROUP_DEFAULT; 21207 break; 21208 } 21209 long oldId = Binder.clearCallingIdentity(); 21210 try { 21211 Process.setProcessGroup(app.pid, processGroup); 21212 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { 21213 // do nothing if we already switched to RT 21214 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { 21215 // Switch VR thread for app to SCHED_FIFO 21216 if (mInVrMode && app.vrThreadTid != 0) { 21217 try { 21218 Process.setThreadScheduler(app.vrThreadTid, 21219 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); 21220 } catch (IllegalArgumentException e) { 21221 // thread died, ignore 21222 } 21223 } 21224 if (mUseFifoUiScheduling) { 21225 // Switch UI pipeline for app to SCHED_FIFO 21226 app.savedPriority = Process.getThreadPriority(app.pid); 21227 try { 21228 Process.setThreadScheduler(app.pid, 21229 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); 21230 } catch (IllegalArgumentException e) { 21231 // thread died, ignore 21232 } 21233 if (app.renderThreadTid != 0) { 21234 try { 21235 Process.setThreadScheduler(app.renderThreadTid, 21236 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); 21237 } catch (IllegalArgumentException e) { 21238 // thread died, ignore 21239 } 21240 if (DEBUG_OOM_ADJ) { 21241 Slog.d("UI_FIFO", "Set RenderThread (TID " + 21242 app.renderThreadTid + ") to FIFO"); 21243 } 21244 } else { 21245 if (DEBUG_OOM_ADJ) { 21246 Slog.d("UI_FIFO", "Not setting RenderThread TID"); 21247 } 21248 } 21249 } else { 21250 // Boost priority for top app UI and render threads 21251 Process.setThreadPriority(app.pid, -10); 21252 if (app.renderThreadTid != 0) { 21253 try { 21254 Process.setThreadPriority(app.renderThreadTid, -10); 21255 } catch (IllegalArgumentException e) { 21256 // thread died, ignore 21257 } 21258 } 21259 } 21260 } 21261 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && 21262 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { 21263 // Reset VR thread to SCHED_OTHER 21264 // Safe to do even if we're not in VR mode 21265 if (app.vrThreadTid != 0) { 21266 Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0); 21267 } 21268 if (mUseFifoUiScheduling) { 21269 // Reset UI pipeline to SCHED_OTHER 21270 Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0); 21271 Process.setThreadPriority(app.pid, app.savedPriority); 21272 if (app.renderThreadTid != 0) { 21273 Process.setThreadScheduler(app.renderThreadTid, 21274 Process.SCHED_OTHER, 0); 21275 Process.setThreadPriority(app.renderThreadTid, -4); 21276 } 21277 } else { 21278 // Reset priority for top app UI and render threads 21279 Process.setThreadPriority(app.pid, 0); 21280 if (app.renderThreadTid != 0) { 21281 Process.setThreadPriority(app.renderThreadTid, 0); 21282 } 21283 } 21284 } 21285 } catch (Exception e) { 21286 Slog.w(TAG, "Failed setting process group of " + app.pid 21287 + " to " + app.curSchedGroup); 21288 e.printStackTrace(); 21289 } finally { 21290 Binder.restoreCallingIdentity(oldId); 21291 } 21292 } 21293 } 21294 if (app.repForegroundActivities != app.foregroundActivities) { 21295 app.repForegroundActivities = app.foregroundActivities; 21296 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 21297 } 21298 if (app.repProcState != app.curProcState) { 21299 app.repProcState = app.curProcState; 21300 if (app.thread != null) { 21301 try { 21302 if (false) { 21303 //RuntimeException h = new RuntimeException("here"); 21304 Slog.i(TAG, "Sending new process state " + app.repProcState 21305 + " to " + app /*, h*/); 21306 } 21307 app.thread.setProcessState(app.repProcState); 21308 } catch (RemoteException e) { 21309 } 21310 } 21311 } 21312 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT 21313 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) { 21314 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 21315 // Experimental code to more aggressively collect pss while 21316 // running test... the problem is that this tends to collect 21317 // the data right when a process is transitioning between process 21318 // states, which well tend to give noisy data. 21319 long start = SystemClock.uptimeMillis(); 21320 long pss = Debug.getPss(app.pid, mTmpLong, null); 21321 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now); 21322 mPendingPssProcesses.remove(app); 21323 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 21324 + " to " + app.curProcState + ": " 21325 + (SystemClock.uptimeMillis()-start) + "ms"); 21326 } 21327 app.lastStateTime = now; 21328 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 21329 mTestPssMode, isSleepingLocked(), now); 21330 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from " 21331 + ProcessList.makeProcStateString(app.setProcState) + " to " 21332 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 21333 + (app.nextPssTime-now) + ": " + app); 21334 } else { 21335 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 21336 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 21337 mTestPssMode)))) { 21338 requestPssLocked(app, app.setProcState); 21339 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 21340 mTestPssMode, isSleepingLocked(), now); 21341 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS, 21342 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 21343 } 21344 if (app.setProcState != app.curProcState) { 21345 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 21346 "Proc state change of " + app.processName 21347 + " to " + app.curProcState); 21348 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 21349 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 21350 if (setImportant && !curImportant) { 21351 // This app is no longer something we consider important enough to allow to 21352 // use arbitrary amounts of battery power. Note 21353 // its current wake lock time to later know to kill it if 21354 // it is not behaving well. 21355 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 21356 synchronized (stats) { 21357 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 21358 app.pid, nowElapsed); 21359 } 21360 app.lastCpuTime = app.curCpuTime; 21361 21362 } 21363 // Inform UsageStats of important process state change 21364 // Must be called before updating setProcState 21365 maybeUpdateUsageStatsLocked(app, nowElapsed); 21366 21367 app.setProcState = app.curProcState; 21368 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 21369 app.notCachedSinceIdle = false; 21370 } 21371 if (!doingAll) { 21372 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 21373 } else { 21374 app.procStateChanged = true; 21375 } 21376 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime) 21377 > USAGE_STATS_INTERACTION_INTERVAL) { 21378 // For apps that sit around for a long time in the interactive state, we need 21379 // to report this at least once a day so they don't go idle. 21380 maybeUpdateUsageStatsLocked(app, nowElapsed); 21381 } 21382 21383 if (changes != 0) { 21384 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 21385 "Changes in " + app + ": " + changes); 21386 int i = mPendingProcessChanges.size()-1; 21387 ProcessChangeItem item = null; 21388 while (i >= 0) { 21389 item = mPendingProcessChanges.get(i); 21390 if (item.pid == app.pid) { 21391 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 21392 "Re-using existing item: " + item); 21393 break; 21394 } 21395 i--; 21396 } 21397 if (i < 0) { 21398 // No existing item in pending changes; need a new one. 21399 final int NA = mAvailProcessChanges.size(); 21400 if (NA > 0) { 21401 item = mAvailProcessChanges.remove(NA-1); 21402 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 21403 "Retrieving available item: " + item); 21404 } else { 21405 item = new ProcessChangeItem(); 21406 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 21407 "Allocating new item: " + item); 21408 } 21409 item.changes = 0; 21410 item.pid = app.pid; 21411 item.uid = app.info.uid; 21412 if (mPendingProcessChanges.size() == 0) { 21413 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 21414 "*** Enqueueing dispatch processes changed!"); 21415 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget(); 21416 } 21417 mPendingProcessChanges.add(item); 21418 } 21419 item.changes |= changes; 21420 item.foregroundActivities = app.repForegroundActivities; 21421 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 21422 "Item " + Integer.toHexString(System.identityHashCode(item)) 21423 + " " + app.toShortString() + ": changes=" + item.changes 21424 + " foreground=" + item.foregroundActivities 21425 + " type=" + app.adjType + " source=" + app.adjSource 21426 + " target=" + app.adjTarget); 21427 } 21428 21429 return success; 21430 } 21431 21432 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) { 21433 final UidRecord.ChangeItem pendingChange; 21434 if (uidRec == null || uidRec.pendingChange == null) { 21435 if (mPendingUidChanges.size() == 0) { 21436 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 21437 "*** Enqueueing dispatch uid changed!"); 21438 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget(); 21439 } 21440 final int NA = mAvailUidChanges.size(); 21441 if (NA > 0) { 21442 pendingChange = mAvailUidChanges.remove(NA-1); 21443 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 21444 "Retrieving available item: " + pendingChange); 21445 } else { 21446 pendingChange = new UidRecord.ChangeItem(); 21447 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 21448 "Allocating new item: " + pendingChange); 21449 } 21450 if (uidRec != null) { 21451 uidRec.pendingChange = pendingChange; 21452 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) { 21453 // If this uid is going away, and we haven't yet reported it is gone, 21454 // then do so now. 21455 change = UidRecord.CHANGE_GONE_IDLE; 21456 } 21457 } else if (uid < 0) { 21458 throw new IllegalArgumentException("No UidRecord or uid"); 21459 } 21460 pendingChange.uidRecord = uidRec; 21461 pendingChange.uid = uidRec != null ? uidRec.uid : uid; 21462 mPendingUidChanges.add(pendingChange); 21463 } else { 21464 pendingChange = uidRec.pendingChange; 21465 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) { 21466 change = UidRecord.CHANGE_GONE_IDLE; 21467 } 21468 } 21469 pendingChange.change = change; 21470 pendingChange.processState = uidRec != null 21471 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT; 21472 pendingChange.ephemeral = uidRec.ephemeral; 21473 21474 // Directly update the power manager, since we sit on top of it and it is critical 21475 // it be kept in sync (so wake locks will be held as soon as appropriate). 21476 if (mLocalPowerManager != null) { 21477 switch (change) { 21478 case UidRecord.CHANGE_GONE: 21479 case UidRecord.CHANGE_GONE_IDLE: 21480 mLocalPowerManager.uidGone(pendingChange.uid); 21481 break; 21482 case UidRecord.CHANGE_IDLE: 21483 mLocalPowerManager.uidIdle(pendingChange.uid); 21484 break; 21485 case UidRecord.CHANGE_ACTIVE: 21486 mLocalPowerManager.uidActive(pendingChange.uid); 21487 break; 21488 default: 21489 mLocalPowerManager.updateUidProcState(pendingChange.uid, 21490 pendingChange.processState); 21491 break; 21492 } 21493 } 21494 } 21495 21496 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName, 21497 String authority) { 21498 if (app == null) return; 21499 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 21500 UserState userState = mUserController.getStartedUserStateLocked(app.userId); 21501 if (userState == null) return; 21502 final long now = SystemClock.elapsedRealtime(); 21503 Long lastReported = userState.mProviderLastReportedFg.get(authority); 21504 if (lastReported == null || lastReported < now - 60 * 1000L) { 21505 if (mSystemReady) { 21506 // Cannot touch the user stats if not system ready 21507 mUsageStatsService.reportContentProviderUsage( 21508 authority, providerPkgName, app.userId); 21509 } 21510 userState.mProviderLastReportedFg.put(authority, now); 21511 } 21512 } 21513 } 21514 21515 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) { 21516 if (DEBUG_USAGE_STATS) { 21517 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList()) 21518 + "] state changes: old = " + app.setProcState + ", new = " 21519 + app.curProcState); 21520 } 21521 if (mUsageStatsService == null) { 21522 return; 21523 } 21524 boolean isInteraction; 21525 // To avoid some abuse patterns, we are going to be careful about what we consider 21526 // to be an app interaction. Being the top activity doesn't count while the display 21527 // is sleeping, nor do short foreground services. 21528 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { 21529 isInteraction = true; 21530 app.fgInteractionTime = 0; 21531 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) { 21532 if (app.fgInteractionTime == 0) { 21533 app.fgInteractionTime = nowElapsed; 21534 isInteraction = false; 21535 } else { 21536 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME; 21537 } 21538 } else { 21539 // If the app was being forced to the foreground, by say a Toast, then 21540 // no need to treat it as an interaction 21541 isInteraction = app.forcingToForeground == null 21542 && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 21543 app.fgInteractionTime = 0; 21544 } 21545 if (isInteraction && (!app.reportedInteraction 21546 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) { 21547 app.interactionEventTime = nowElapsed; 21548 String[] packages = app.getPackageList(); 21549 if (packages != null) { 21550 for (int i = 0; i < packages.length; i++) { 21551 mUsageStatsService.reportEvent(packages[i], app.userId, 21552 UsageEvents.Event.SYSTEM_INTERACTION); 21553 } 21554 } 21555 } 21556 app.reportedInteraction = isInteraction; 21557 if (!isInteraction) { 21558 app.interactionEventTime = 0; 21559 } 21560 } 21561 21562 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 21563 if (proc.thread != null) { 21564 if (proc.baseProcessTracker != null) { 21565 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 21566 } 21567 } 21568 } 21569 21570 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 21571 ProcessRecord TOP_APP, boolean doingAll, long now) { 21572 if (app.thread == null) { 21573 return false; 21574 } 21575 21576 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 21577 21578 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime()); 21579 } 21580 21581 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 21582 boolean oomAdj) { 21583 if (isForeground != proc.foregroundServices) { 21584 proc.foregroundServices = isForeground; 21585 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 21586 proc.info.uid); 21587 if (isForeground) { 21588 if (curProcs == null) { 21589 curProcs = new ArrayList<ProcessRecord>(); 21590 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 21591 } 21592 if (!curProcs.contains(proc)) { 21593 curProcs.add(proc); 21594 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 21595 proc.info.packageName, proc.info.uid); 21596 } 21597 } else { 21598 if (curProcs != null) { 21599 if (curProcs.remove(proc)) { 21600 mBatteryStatsService.noteEvent( 21601 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 21602 proc.info.packageName, proc.info.uid); 21603 if (curProcs.size() <= 0) { 21604 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 21605 } 21606 } 21607 } 21608 } 21609 if (oomAdj) { 21610 updateOomAdjLocked(); 21611 } 21612 } 21613 } 21614 21615 private final ActivityRecord resumedAppLocked() { 21616 ActivityRecord act = mStackSupervisor.getResumedActivityLocked(); 21617 String pkg; 21618 int uid; 21619 if (act != null) { 21620 pkg = act.packageName; 21621 uid = act.info.applicationInfo.uid; 21622 } else { 21623 pkg = null; 21624 uid = -1; 21625 } 21626 // Has the UID or resumed package name changed? 21627 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 21628 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 21629 if (mCurResumedPackage != null) { 21630 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 21631 mCurResumedPackage, mCurResumedUid); 21632 } 21633 mCurResumedPackage = pkg; 21634 mCurResumedUid = uid; 21635 if (mCurResumedPackage != null) { 21636 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 21637 mCurResumedPackage, mCurResumedUid); 21638 } 21639 } 21640 return act; 21641 } 21642 21643 final boolean updateOomAdjLocked(ProcessRecord app) { 21644 final ActivityRecord TOP_ACT = resumedAppLocked(); 21645 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 21646 final boolean wasCached = app.cached; 21647 21648 mAdjSeq++; 21649 21650 // This is the desired cached adjusment we want to tell it to use. 21651 // If our app is currently cached, we know it, and that is it. Otherwise, 21652 // we don't know it yet, and it needs to now be cached we will then 21653 // need to do a complete oom adj. 21654 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 21655 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 21656 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 21657 SystemClock.uptimeMillis()); 21658 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 21659 // Changed to/from cached state, so apps after it in the LRU 21660 // list may also be changed. 21661 updateOomAdjLocked(); 21662 } 21663 return success; 21664 } 21665 21666 final void updateOomAdjLocked() { 21667 final ActivityRecord TOP_ACT = resumedAppLocked(); 21668 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 21669 final long now = SystemClock.uptimeMillis(); 21670 final long nowElapsed = SystemClock.elapsedRealtime(); 21671 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 21672 final int N = mLruProcesses.size(); 21673 21674 if (false) { 21675 RuntimeException e = new RuntimeException(); 21676 e.fillInStackTrace(); 21677 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 21678 } 21679 21680 // Reset state in all uid records. 21681 for (int i=mActiveUids.size()-1; i>=0; i--) { 21682 final UidRecord uidRec = mActiveUids.valueAt(i); 21683 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 21684 "Starting update of " + uidRec); 21685 uidRec.reset(); 21686 } 21687 21688 mStackSupervisor.rankTaskLayersIfNeeded(); 21689 21690 mAdjSeq++; 21691 mNewNumServiceProcs = 0; 21692 mNewNumAServiceProcs = 0; 21693 21694 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES; 21695 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit; 21696 21697 // Let's determine how many processes we have running vs. 21698 // how many slots we have for background processes; we may want 21699 // to put multiple processes in a slot of there are enough of 21700 // them. 21701 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 21702 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 21703 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 21704 if (numEmptyProcs > cachedProcessLimit) { 21705 // If there are more empty processes than our limit on cached 21706 // processes, then use the cached process limit for the factor. 21707 // This ensures that the really old empty processes get pushed 21708 // down to the bottom, so if we are running low on memory we will 21709 // have a better chance at keeping around more cached processes 21710 // instead of a gazillion empty processes. 21711 numEmptyProcs = cachedProcessLimit; 21712 } 21713 int emptyFactor = numEmptyProcs/numSlots; 21714 if (emptyFactor < 1) emptyFactor = 1; 21715 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 21716 if (cachedFactor < 1) cachedFactor = 1; 21717 int stepCached = 0; 21718 int stepEmpty = 0; 21719 int numCached = 0; 21720 int numEmpty = 0; 21721 int numTrimming = 0; 21722 21723 mNumNonCachedProcs = 0; 21724 mNumCachedHiddenProcs = 0; 21725 21726 // First update the OOM adjustment for each of the 21727 // application processes based on their current state. 21728 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 21729 int nextCachedAdj = curCachedAdj+1; 21730 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 21731 int nextEmptyAdj = curEmptyAdj+2; 21732 for (int i=N-1; i>=0; i--) { 21733 ProcessRecord app = mLruProcesses.get(i); 21734 if (!app.killedByAm && app.thread != null) { 21735 app.procStateChanged = false; 21736 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 21737 21738 // If we haven't yet assigned the final cached adj 21739 // to the process, do that now. 21740 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 21741 switch (app.curProcState) { 21742 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 21743 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 21744 // This process is a cached process holding activities... 21745 // assign it the next cached value for that type, and then 21746 // step that cached level. 21747 app.curRawAdj = curCachedAdj; 21748 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 21749 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i 21750 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 21751 + ")"); 21752 if (curCachedAdj != nextCachedAdj) { 21753 stepCached++; 21754 if (stepCached >= cachedFactor) { 21755 stepCached = 0; 21756 curCachedAdj = nextCachedAdj; 21757 nextCachedAdj += 2; 21758 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 21759 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 21760 } 21761 } 21762 } 21763 break; 21764 default: 21765 // For everything else, assign next empty cached process 21766 // level and bump that up. Note that this means that 21767 // long-running services that have dropped down to the 21768 // cached level will be treated as empty (since their process 21769 // state is still as a service), which is what we want. 21770 app.curRawAdj = curEmptyAdj; 21771 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 21772 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i 21773 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 21774 + ")"); 21775 if (curEmptyAdj != nextEmptyAdj) { 21776 stepEmpty++; 21777 if (stepEmpty >= emptyFactor) { 21778 stepEmpty = 0; 21779 curEmptyAdj = nextEmptyAdj; 21780 nextEmptyAdj += 2; 21781 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 21782 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 21783 } 21784 } 21785 } 21786 break; 21787 } 21788 } 21789 21790 applyOomAdjLocked(app, true, now, nowElapsed); 21791 21792 // Count the number of process types. 21793 switch (app.curProcState) { 21794 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 21795 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 21796 mNumCachedHiddenProcs++; 21797 numCached++; 21798 if (numCached > cachedProcessLimit) { 21799 app.kill("cached #" + numCached, true); 21800 } 21801 break; 21802 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 21803 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES 21804 && app.lastActivityTime < oldTime) { 21805 app.kill("empty for " 21806 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 21807 / 1000) + "s", true); 21808 } else { 21809 numEmpty++; 21810 if (numEmpty > emptyProcessLimit) { 21811 app.kill("empty #" + numEmpty, true); 21812 } 21813 } 21814 break; 21815 default: 21816 mNumNonCachedProcs++; 21817 break; 21818 } 21819 21820 if (app.isolated && app.services.size() <= 0) { 21821 // If this is an isolated process, and there are no 21822 // services running in it, then the process is no longer 21823 // needed. We agressively kill these because we can by 21824 // definition not re-use the same process again, and it is 21825 // good to avoid having whatever code was running in them 21826 // left sitting around after no longer needed. 21827 app.kill("isolated not needed", true); 21828 } else { 21829 // Keeping this process, update its uid. 21830 final UidRecord uidRec = app.uidRecord; 21831 if (uidRec != null) { 21832 uidRec.ephemeral = app.info.isInstantApp(); 21833 if (uidRec.curProcState > app.curProcState) { 21834 uidRec.curProcState = app.curProcState; 21835 } 21836 } 21837 } 21838 21839 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 21840 && !app.killedByAm) { 21841 numTrimming++; 21842 } 21843 } 21844 } 21845 21846 for (int i = mActiveUids.size() - 1; i >= 0; --i) { 21847 incrementProcStateSeqIfNeeded(mActiveUids.valueAt(i)); 21848 } 21849 21850 mNumServiceProcs = mNewNumServiceProcs; 21851 21852 // Now determine the memory trimming level of background processes. 21853 // Unfortunately we need to start at the back of the list to do this 21854 // properly. We only do this if the number of background apps we 21855 // are managing to keep around is less than half the maximum we desire; 21856 // if we are keeping a good number around, we'll let them use whatever 21857 // memory they want. 21858 final int numCachedAndEmpty = numCached + numEmpty; 21859 int memFactor; 21860 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES 21861 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) { 21862 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 21863 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 21864 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 21865 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 21866 } else { 21867 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 21868 } 21869 } else { 21870 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 21871 } 21872 // We always allow the memory level to go up (better). We only allow it to go 21873 // down if we are in a state where that is allowed, *and* the total number of processes 21874 // has gone down since last time. 21875 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor 21876 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel 21877 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses); 21878 if (memFactor > mLastMemoryLevel) { 21879 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 21880 memFactor = mLastMemoryLevel; 21881 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!"); 21882 } 21883 } 21884 if (memFactor != mLastMemoryLevel) { 21885 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel); 21886 } 21887 mLastMemoryLevel = memFactor; 21888 mLastNumProcesses = mLruProcesses.size(); 21889 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now); 21890 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 21891 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 21892 if (mLowRamStartTime == 0) { 21893 mLowRamStartTime = now; 21894 } 21895 int step = 0; 21896 int fgTrimLevel; 21897 switch (memFactor) { 21898 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 21899 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 21900 break; 21901 case ProcessStats.ADJ_MEM_FACTOR_LOW: 21902 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 21903 break; 21904 default: 21905 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 21906 break; 21907 } 21908 int factor = numTrimming/3; 21909 int minFactor = 2; 21910 if (mHomeProcess != null) minFactor++; 21911 if (mPreviousProcess != null) minFactor++; 21912 if (factor < minFactor) factor = minFactor; 21913 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 21914 for (int i=N-1; i>=0; i--) { 21915 ProcessRecord app = mLruProcesses.get(i); 21916 if (allChanged || app.procStateChanged) { 21917 setProcessTrackerStateLocked(app, trackerMemFactor, now); 21918 app.procStateChanged = false; 21919 } 21920 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 21921 && !app.killedByAm) { 21922 if (app.trimMemoryLevel < curLevel && app.thread != null) { 21923 try { 21924 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 21925 "Trimming memory of " + app.processName + " to " + curLevel); 21926 app.thread.scheduleTrimMemory(curLevel); 21927 } catch (RemoteException e) { 21928 } 21929 if (false) { 21930 // For now we won't do this; our memory trimming seems 21931 // to be good enough at this point that destroying 21932 // activities causes more harm than good. 21933 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 21934 && app != mHomeProcess && app != mPreviousProcess) { 21935 // Need to do this on its own message because the stack may not 21936 // be in a consistent state at this point. 21937 // For these apps we will also finish their activities 21938 // to help them free memory. 21939 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 21940 } 21941 } 21942 } 21943 app.trimMemoryLevel = curLevel; 21944 step++; 21945 if (step >= factor) { 21946 step = 0; 21947 switch (curLevel) { 21948 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 21949 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 21950 break; 21951 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 21952 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 21953 break; 21954 } 21955 } 21956 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 21957 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 21958 && app.thread != null) { 21959 try { 21960 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 21961 "Trimming memory of heavy-weight " + app.processName 21962 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 21963 app.thread.scheduleTrimMemory( 21964 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 21965 } catch (RemoteException e) { 21966 } 21967 } 21968 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 21969 } else { 21970 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 21971 || app.systemNoUi) && app.pendingUiClean) { 21972 // If this application is now in the background and it 21973 // had done UI, then give it the special trim level to 21974 // have it free UI resources. 21975 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 21976 if (app.trimMemoryLevel < level && app.thread != null) { 21977 try { 21978 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 21979 "Trimming memory of bg-ui " + app.processName 21980 + " to " + level); 21981 app.thread.scheduleTrimMemory(level); 21982 } catch (RemoteException e) { 21983 } 21984 } 21985 app.pendingUiClean = false; 21986 } 21987 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 21988 try { 21989 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 21990 "Trimming memory of fg " + app.processName 21991 + " to " + fgTrimLevel); 21992 app.thread.scheduleTrimMemory(fgTrimLevel); 21993 } catch (RemoteException e) { 21994 } 21995 } 21996 app.trimMemoryLevel = fgTrimLevel; 21997 } 21998 } 21999 } else { 22000 if (mLowRamStartTime != 0) { 22001 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 22002 mLowRamStartTime = 0; 22003 } 22004 for (int i=N-1; i>=0; i--) { 22005 ProcessRecord app = mLruProcesses.get(i); 22006 if (allChanged || app.procStateChanged) { 22007 setProcessTrackerStateLocked(app, trackerMemFactor, now); 22008 app.procStateChanged = false; 22009 } 22010 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 22011 || app.systemNoUi) && app.pendingUiClean) { 22012 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 22013 && app.thread != null) { 22014 try { 22015 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 22016 "Trimming memory of ui hidden " + app.processName 22017 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 22018 app.thread.scheduleTrimMemory( 22019 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 22020 } catch (RemoteException e) { 22021 } 22022 } 22023 app.pendingUiClean = false; 22024 } 22025 app.trimMemoryLevel = 0; 22026 } 22027 } 22028 22029 if (mAlwaysFinishActivities) { 22030 // Need to do this on its own message because the stack may not 22031 // be in a consistent state at this point. 22032 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 22033 } 22034 22035 if (allChanged) { 22036 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 22037 } 22038 22039 // Update from any uid changes. 22040 if (mLocalPowerManager != null) { 22041 mLocalPowerManager.startUidChanges(); 22042 } 22043 for (int i=mActiveUids.size()-1; i>=0; i--) { 22044 final UidRecord uidRec = mActiveUids.valueAt(i); 22045 int uidChange = UidRecord.CHANGE_PROCSTATE; 22046 if (uidRec.setProcState != uidRec.curProcState 22047 || uidRec.setWhitelist != uidRec.curWhitelist) { 22048 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 22049 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState 22050 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist 22051 + " to " + uidRec.curWhitelist); 22052 if (ActivityManager.isProcStateBackground(uidRec.curProcState) 22053 && !uidRec.curWhitelist) { 22054 // UID is now in the background (and not on the temp whitelist). Was it 22055 // previously in the foreground (or on the temp whitelist)? 22056 if (!ActivityManager.isProcStateBackground(uidRec.setProcState) 22057 || uidRec.setWhitelist) { 22058 uidRec.lastBackgroundTime = nowElapsed; 22059 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) { 22060 // Note: the background settle time is in elapsed realtime, while 22061 // the handler time base is uptime. All this means is that we may 22062 // stop background uids later than we had intended, but that only 22063 // happens because the device was sleeping so we are okay anyway. 22064 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME); 22065 } 22066 } 22067 } else { 22068 if (uidRec.idle) { 22069 uidChange = UidRecord.CHANGE_ACTIVE; 22070 uidRec.idle = false; 22071 } 22072 uidRec.lastBackgroundTime = 0; 22073 } 22074 uidRec.setProcState = uidRec.curProcState; 22075 uidRec.setWhitelist = uidRec.curWhitelist; 22076 enqueueUidChangeLocked(uidRec, -1, uidChange); 22077 noteUidProcessState(uidRec.uid, uidRec.curProcState); 22078 } 22079 } 22080 if (mLocalPowerManager != null) { 22081 mLocalPowerManager.finishUidChanges(); 22082 } 22083 22084 if (mProcessStats.shouldWriteNowLocked(now)) { 22085 mHandler.post(new Runnable() { 22086 @Override public void run() { 22087 synchronized (ActivityManagerService.this) { 22088 mProcessStats.writeStateAsyncLocked(); 22089 } 22090 } 22091 }); 22092 } 22093 22094 if (DEBUG_OOM_ADJ) { 22095 final long duration = SystemClock.uptimeMillis() - now; 22096 if (false) { 22097 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms", 22098 new RuntimeException("here").fillInStackTrace()); 22099 } else { 22100 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); 22101 } 22102 } 22103 } 22104 22105 @Override 22106 public void makePackageIdle(String packageName, int userId) { 22107 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 22108 != PackageManager.PERMISSION_GRANTED) { 22109 String msg = "Permission Denial: makePackageIdle() from pid=" 22110 + Binder.getCallingPid() 22111 + ", uid=" + Binder.getCallingUid() 22112 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 22113 Slog.w(TAG, msg); 22114 throw new SecurityException(msg); 22115 } 22116 final int callingPid = Binder.getCallingPid(); 22117 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(), 22118 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null); 22119 long callingId = Binder.clearCallingIdentity(); 22120 synchronized(this) { 22121 try { 22122 IPackageManager pm = AppGlobals.getPackageManager(); 22123 int pkgUid = -1; 22124 try { 22125 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES 22126 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM); 22127 } catch (RemoteException e) { 22128 } 22129 if (pkgUid == -1) { 22130 throw new IllegalArgumentException("Unknown package name " + packageName); 22131 } 22132 22133 if (mLocalPowerManager != null) { 22134 mLocalPowerManager.startUidChanges(); 22135 } 22136 final int appId = UserHandle.getAppId(pkgUid); 22137 final int N = mActiveUids.size(); 22138 for (int i=N-1; i>=0; i--) { 22139 final UidRecord uidRec = mActiveUids.valueAt(i); 22140 final long bgTime = uidRec.lastBackgroundTime; 22141 if (bgTime > 0 && !uidRec.idle) { 22142 if (UserHandle.getAppId(uidRec.uid) == appId) { 22143 if (userId == UserHandle.USER_ALL || 22144 userId == UserHandle.getUserId(uidRec.uid)) { 22145 uidRec.idle = true; 22146 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid) 22147 + " from package " + packageName + " user " + userId); 22148 doStopUidLocked(uidRec.uid, uidRec); 22149 } 22150 } 22151 } 22152 } 22153 } finally { 22154 if (mLocalPowerManager != null) { 22155 mLocalPowerManager.finishUidChanges(); 22156 } 22157 Binder.restoreCallingIdentity(callingId); 22158 } 22159 } 22160 } 22161 22162 final void idleUids() { 22163 synchronized (this) { 22164 final int N = mActiveUids.size(); 22165 if (N <= 0) { 22166 return; 22167 } 22168 final long nowElapsed = SystemClock.elapsedRealtime(); 22169 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME; 22170 long nextTime = 0; 22171 if (mLocalPowerManager != null) { 22172 mLocalPowerManager.startUidChanges(); 22173 } 22174 for (int i=N-1; i>=0; i--) { 22175 final UidRecord uidRec = mActiveUids.valueAt(i); 22176 final long bgTime = uidRec.lastBackgroundTime; 22177 if (bgTime > 0 && !uidRec.idle) { 22178 if (bgTime <= maxBgTime) { 22179 uidRec.idle = true; 22180 doStopUidLocked(uidRec.uid, uidRec); 22181 } else { 22182 if (nextTime == 0 || nextTime > bgTime) { 22183 nextTime = bgTime; 22184 } 22185 } 22186 } 22187 } 22188 if (mLocalPowerManager != null) { 22189 mLocalPowerManager.finishUidChanges(); 22190 } 22191 if (nextTime > 0) { 22192 mHandler.removeMessages(IDLE_UIDS_MSG); 22193 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 22194 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed); 22195 } 22196 } 22197 } 22198 22199 /** 22200 * If {@link UidRecord#curProcStateSeq} needs to be updated, then increments the global seq 22201 * counter {@link #mProcStateSeqCounter} and uses that value for {@param uidRec}. 22202 */ 22203 @VisibleForTesting 22204 void incrementProcStateSeqIfNeeded(UidRecord uidRec) { 22205 if (uidRec.curProcState != uidRec.setProcState && shouldIncrementProcStateSeq(uidRec)) { 22206 uidRec.curProcStateSeq = ++mProcStateSeqCounter; 22207 } 22208 } 22209 22210 /** 22211 * Checks if {@link UidRecord#curProcStateSeq} needs to be incremented depending on whether 22212 * the uid is coming from background to foreground state or vice versa. 22213 * 22214 * @return Returns true if the uid is coming from background to foreground state or vice versa, 22215 * false otherwise. 22216 */ 22217 @VisibleForTesting 22218 boolean shouldIncrementProcStateSeq(UidRecord uidRec) { 22219 final boolean isAllowedOnRestrictBackground 22220 = isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState); 22221 final boolean isAllowedOnDeviceIdleOrPowerSaveMode 22222 = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState); 22223 22224 final boolean wasAllowedOnRestrictBackground 22225 = isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState); 22226 final boolean wasAllowedOnDeviceIdleOrPowerSaveMode 22227 = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState); 22228 22229 // If the uid is coming from background to foreground or vice versa, 22230 // then return true. Otherwise false. 22231 return (wasAllowedOnDeviceIdleOrPowerSaveMode != isAllowedOnDeviceIdleOrPowerSaveMode) 22232 || (wasAllowedOnRestrictBackground != isAllowedOnRestrictBackground); 22233 } 22234 22235 final void runInBackgroundDisabled(int uid) { 22236 synchronized (this) { 22237 UidRecord uidRec = mActiveUids.get(uid); 22238 if (uidRec != null) { 22239 // This uid is actually running... should it be considered background now? 22240 if (uidRec.idle) { 22241 doStopUidLocked(uidRec.uid, uidRec); 22242 } 22243 } else { 22244 // This uid isn't actually running... still send a report about it being "stopped". 22245 doStopUidLocked(uid, null); 22246 } 22247 } 22248 } 22249 22250 final void doStopUidLocked(int uid, final UidRecord uidRec) { 22251 mServices.stopInBackgroundLocked(uid); 22252 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE); 22253 } 22254 22255 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) { 22256 boolean changed = false; 22257 for (int i=mActiveUids.size()-1; i>=0; i--) { 22258 final UidRecord uidRec = mActiveUids.valueAt(i); 22259 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) { 22260 uidRec.curWhitelist = onWhitelist; 22261 changed = true; 22262 } 22263 } 22264 if (changed) { 22265 updateOomAdjLocked(); 22266 } 22267 } 22268 22269 final void trimApplications() { 22270 synchronized (this) { 22271 int i; 22272 22273 // First remove any unused application processes whose package 22274 // has been removed. 22275 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 22276 final ProcessRecord app = mRemovedProcesses.get(i); 22277 if (app.activities.size() == 0 22278 && app.curReceivers.isEmpty() && app.services.size() == 0) { 22279 Slog.i( 22280 TAG, "Exiting empty application process " 22281 + app.toShortString() + " (" 22282 + (app.thread != null ? app.thread.asBinder() : null) 22283 + ")\n"); 22284 if (app.pid > 0 && app.pid != MY_PID) { 22285 app.kill("empty", false); 22286 } else { 22287 try { 22288 app.thread.scheduleExit(); 22289 } catch (Exception e) { 22290 // Ignore exceptions. 22291 } 22292 } 22293 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/); 22294 mRemovedProcesses.remove(i); 22295 22296 if (app.persistent) { 22297 addAppLocked(app.info, null, false, null /* ABI override */); 22298 } 22299 } 22300 } 22301 22302 // Now update the oom adj for all processes. 22303 updateOomAdjLocked(); 22304 } 22305 } 22306 22307 /** This method sends the specified signal to each of the persistent apps */ 22308 public void signalPersistentProcesses(int sig) throws RemoteException { 22309 if (sig != Process.SIGNAL_USR1) { 22310 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 22311 } 22312 22313 synchronized (this) { 22314 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 22315 != PackageManager.PERMISSION_GRANTED) { 22316 throw new SecurityException("Requires permission " 22317 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 22318 } 22319 22320 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 22321 ProcessRecord r = mLruProcesses.get(i); 22322 if (r.thread != null && r.persistent) { 22323 Process.sendSignal(r.pid, sig); 22324 } 22325 } 22326 } 22327 } 22328 22329 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 22330 if (proc == null || proc == mProfileProc) { 22331 proc = mProfileProc; 22332 profileType = mProfileType; 22333 clearProfilerLocked(); 22334 } 22335 if (proc == null) { 22336 return; 22337 } 22338 try { 22339 proc.thread.profilerControl(false, null, profileType); 22340 } catch (RemoteException e) { 22341 throw new IllegalStateException("Process disappeared"); 22342 } 22343 } 22344 22345 private void clearProfilerLocked() { 22346 if (mProfileFd != null) { 22347 try { 22348 mProfileFd.close(); 22349 } catch (IOException e) { 22350 } 22351 } 22352 mProfileApp = null; 22353 mProfileProc = null; 22354 mProfileFile = null; 22355 mProfileType = 0; 22356 mAutoStopProfiler = false; 22357 mStreamingOutput = false; 22358 mSamplingInterval = 0; 22359 } 22360 22361 public boolean profileControl(String process, int userId, boolean start, 22362 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 22363 22364 try { 22365 synchronized (this) { 22366 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 22367 // its own permission. 22368 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 22369 != PackageManager.PERMISSION_GRANTED) { 22370 throw new SecurityException("Requires permission " 22371 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 22372 } 22373 22374 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 22375 throw new IllegalArgumentException("null profile info or fd"); 22376 } 22377 22378 ProcessRecord proc = null; 22379 if (process != null) { 22380 proc = findProcessLocked(process, userId, "profileControl"); 22381 } 22382 22383 if (start && (proc == null || proc.thread == null)) { 22384 throw new IllegalArgumentException("Unknown process: " + process); 22385 } 22386 22387 if (start) { 22388 stopProfilerLocked(null, 0); 22389 setProfileApp(proc.info, proc.processName, profilerInfo); 22390 mProfileProc = proc; 22391 mProfileType = profileType; 22392 ParcelFileDescriptor fd = profilerInfo.profileFd; 22393 try { 22394 fd = fd.dup(); 22395 } catch (IOException e) { 22396 fd = null; 22397 } 22398 profilerInfo.profileFd = fd; 22399 proc.thread.profilerControl(start, profilerInfo, profileType); 22400 fd = null; 22401 try { 22402 mProfileFd.close(); 22403 } catch (IOException e) { 22404 } 22405 mProfileFd = null; 22406 } else { 22407 stopProfilerLocked(proc, profileType); 22408 if (profilerInfo != null && profilerInfo.profileFd != null) { 22409 try { 22410 profilerInfo.profileFd.close(); 22411 } catch (IOException e) { 22412 } 22413 } 22414 } 22415 22416 return true; 22417 } 22418 } catch (RemoteException e) { 22419 throw new IllegalStateException("Process disappeared"); 22420 } finally { 22421 if (profilerInfo != null && profilerInfo.profileFd != null) { 22422 try { 22423 profilerInfo.profileFd.close(); 22424 } catch (IOException e) { 22425 } 22426 } 22427 } 22428 } 22429 22430 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 22431 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 22432 userId, true, ALLOW_FULL_ONLY, callName, null); 22433 ProcessRecord proc = null; 22434 try { 22435 int pid = Integer.parseInt(process); 22436 synchronized (mPidsSelfLocked) { 22437 proc = mPidsSelfLocked.get(pid); 22438 } 22439 } catch (NumberFormatException e) { 22440 } 22441 22442 if (proc == null) { 22443 ArrayMap<String, SparseArray<ProcessRecord>> all 22444 = mProcessNames.getMap(); 22445 SparseArray<ProcessRecord> procs = all.get(process); 22446 if (procs != null && procs.size() > 0) { 22447 proc = procs.valueAt(0); 22448 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 22449 for (int i=1; i<procs.size(); i++) { 22450 ProcessRecord thisProc = procs.valueAt(i); 22451 if (thisProc.userId == userId) { 22452 proc = thisProc; 22453 break; 22454 } 22455 } 22456 } 22457 } 22458 } 22459 22460 return proc; 22461 } 22462 22463 public boolean dumpHeap(String process, int userId, boolean managed, 22464 String path, ParcelFileDescriptor fd) throws RemoteException { 22465 22466 try { 22467 synchronized (this) { 22468 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 22469 // its own permission (same as profileControl). 22470 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 22471 != PackageManager.PERMISSION_GRANTED) { 22472 throw new SecurityException("Requires permission " 22473 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 22474 } 22475 22476 if (fd == null) { 22477 throw new IllegalArgumentException("null fd"); 22478 } 22479 22480 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 22481 if (proc == null || proc.thread == null) { 22482 throw new IllegalArgumentException("Unknown process: " + process); 22483 } 22484 22485 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 22486 if (!isDebuggable) { 22487 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 22488 throw new SecurityException("Process not debuggable: " + proc); 22489 } 22490 } 22491 22492 proc.thread.dumpHeap(managed, path, fd); 22493 fd = null; 22494 return true; 22495 } 22496 } catch (RemoteException e) { 22497 throw new IllegalStateException("Process disappeared"); 22498 } finally { 22499 if (fd != null) { 22500 try { 22501 fd.close(); 22502 } catch (IOException e) { 22503 } 22504 } 22505 } 22506 } 22507 22508 @Override 22509 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize, 22510 String reportPackage) { 22511 if (processName != null) { 22512 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 22513 "setDumpHeapDebugLimit()"); 22514 } else { 22515 synchronized (mPidsSelfLocked) { 22516 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid()); 22517 if (proc == null) { 22518 throw new SecurityException("No process found for calling pid " 22519 + Binder.getCallingPid()); 22520 } 22521 if (!Build.IS_DEBUGGABLE 22522 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 22523 throw new SecurityException("Not running a debuggable build"); 22524 } 22525 processName = proc.processName; 22526 uid = proc.uid; 22527 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) { 22528 throw new SecurityException("Package " + reportPackage + " is not running in " 22529 + proc); 22530 } 22531 } 22532 } 22533 synchronized (this) { 22534 if (maxMemSize > 0) { 22535 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage)); 22536 } else { 22537 if (uid != 0) { 22538 mMemWatchProcesses.remove(processName, uid); 22539 } else { 22540 mMemWatchProcesses.getMap().remove(processName); 22541 } 22542 } 22543 } 22544 } 22545 22546 @Override 22547 public void dumpHeapFinished(String path) { 22548 synchronized (this) { 22549 if (Binder.getCallingPid() != mMemWatchDumpPid) { 22550 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid() 22551 + " does not match last pid " + mMemWatchDumpPid); 22552 return; 22553 } 22554 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) { 22555 Slog.w(TAG, "dumpHeapFinished: Calling path " + path 22556 + " does not match last path " + mMemWatchDumpFile); 22557 return; 22558 } 22559 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path); 22560 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG); 22561 } 22562 } 22563 22564 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 22565 public void monitor() { 22566 synchronized (this) { } 22567 } 22568 22569 void onCoreSettingsChange(Bundle settings) { 22570 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 22571 ProcessRecord processRecord = mLruProcesses.get(i); 22572 try { 22573 if (processRecord.thread != null) { 22574 processRecord.thread.setCoreSettings(settings); 22575 } 22576 } catch (RemoteException re) { 22577 /* ignore */ 22578 } 22579 } 22580 } 22581 22582 // Multi-user methods 22583 22584 /** 22585 * Start user, if its not already running, but don't bring it to foreground. 22586 */ 22587 @Override 22588 public boolean startUserInBackground(final int userId) { 22589 return mUserController.startUser(userId, /* foreground */ false); 22590 } 22591 22592 @Override 22593 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) { 22594 return mUserController.unlockUser(userId, token, secret, listener); 22595 } 22596 22597 @Override 22598 public boolean switchUser(final int targetUserId) { 22599 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId); 22600 int currentUserId; 22601 UserInfo targetUserInfo; 22602 synchronized (this) { 22603 currentUserId = mUserController.getCurrentUserIdLocked(); 22604 targetUserInfo = mUserController.getUserInfo(targetUserId); 22605 if (targetUserId == currentUserId) { 22606 Slog.i(TAG, "user #" + targetUserId + " is already the current user"); 22607 return true; 22608 } 22609 if (targetUserInfo == null) { 22610 Slog.w(TAG, "No user info for user #" + targetUserId); 22611 return false; 22612 } 22613 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) { 22614 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId 22615 + " when device is in demo mode"); 22616 return false; 22617 } 22618 if (!targetUserInfo.supportsSwitchTo()) { 22619 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported"); 22620 return false; 22621 } 22622 if (targetUserInfo.isManagedProfile()) { 22623 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user"); 22624 return false; 22625 } 22626 mUserController.setTargetUserIdLocked(targetUserId); 22627 } 22628 if (mUserController.mUserSwitchUiEnabled) { 22629 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId); 22630 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo); 22631 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG); 22632 mUiHandler.sendMessage(mHandler.obtainMessage( 22633 START_USER_SWITCH_UI_MSG, userNames)); 22634 } else { 22635 mHandler.removeMessages(START_USER_SWITCH_FG_MSG); 22636 mHandler.sendMessage(mHandler.obtainMessage( 22637 START_USER_SWITCH_FG_MSG, targetUserId, 0)); 22638 } 22639 return true; 22640 } 22641 22642 void scheduleStartProfilesLocked() { 22643 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 22644 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 22645 DateUtils.SECOND_IN_MILLIS); 22646 } 22647 } 22648 22649 @Override 22650 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) { 22651 return mUserController.stopUser(userId, force, callback); 22652 } 22653 22654 @Override 22655 public UserInfo getCurrentUser() { 22656 return mUserController.getCurrentUser(); 22657 } 22658 22659 String getStartedUserState(int userId) { 22660 synchronized (this) { 22661 final UserState userState = mUserController.getStartedUserStateLocked(userId); 22662 return UserState.stateToString(userState.state); 22663 } 22664 } 22665 22666 @Override 22667 public boolean isUserRunning(int userId, int flags) { 22668 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId()) 22669 && checkCallingPermission(INTERACT_ACROSS_USERS) 22670 != PackageManager.PERMISSION_GRANTED) { 22671 String msg = "Permission Denial: isUserRunning() from pid=" 22672 + Binder.getCallingPid() 22673 + ", uid=" + Binder.getCallingUid() 22674 + " requires " + INTERACT_ACROSS_USERS; 22675 Slog.w(TAG, msg); 22676 throw new SecurityException(msg); 22677 } 22678 synchronized (this) { 22679 return mUserController.isUserRunningLocked(userId, flags); 22680 } 22681 } 22682 22683 @Override 22684 public int[] getRunningUserIds() { 22685 if (checkCallingPermission(INTERACT_ACROSS_USERS) 22686 != PackageManager.PERMISSION_GRANTED) { 22687 String msg = "Permission Denial: isUserRunning() from pid=" 22688 + Binder.getCallingPid() 22689 + ", uid=" + Binder.getCallingUid() 22690 + " requires " + INTERACT_ACROSS_USERS; 22691 Slog.w(TAG, msg); 22692 throw new SecurityException(msg); 22693 } 22694 synchronized (this) { 22695 return mUserController.getStartedUserArrayLocked(); 22696 } 22697 } 22698 22699 @Override 22700 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) { 22701 mUserController.registerUserSwitchObserver(observer, name); 22702 } 22703 22704 @Override 22705 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 22706 mUserController.unregisterUserSwitchObserver(observer); 22707 } 22708 22709 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 22710 if (info == null) return null; 22711 ApplicationInfo newInfo = new ApplicationInfo(info); 22712 newInfo.initForUser(userId); 22713 return newInfo; 22714 } 22715 22716 public boolean isUserStopped(int userId) { 22717 synchronized (this) { 22718 return mUserController.getStartedUserStateLocked(userId) == null; 22719 } 22720 } 22721 22722 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 22723 if (aInfo == null 22724 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 22725 return aInfo; 22726 } 22727 22728 ActivityInfo info = new ActivityInfo(aInfo); 22729 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 22730 return info; 22731 } 22732 22733 private boolean processSanityChecksLocked(ProcessRecord process) { 22734 if (process == null || process.thread == null) { 22735 return false; 22736 } 22737 22738 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 22739 if (!isDebuggable) { 22740 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 22741 return false; 22742 } 22743 } 22744 22745 return true; 22746 } 22747 22748 public boolean startBinderTracking() throws RemoteException { 22749 synchronized (this) { 22750 mBinderTransactionTrackingEnabled = true; 22751 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own 22752 // permission (same as profileControl). 22753 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 22754 != PackageManager.PERMISSION_GRANTED) { 22755 throw new SecurityException("Requires permission " 22756 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 22757 } 22758 22759 for (int i = 0; i < mLruProcesses.size(); i++) { 22760 ProcessRecord process = mLruProcesses.get(i); 22761 if (!processSanityChecksLocked(process)) { 22762 continue; 22763 } 22764 try { 22765 process.thread.startBinderTracking(); 22766 } catch (RemoteException e) { 22767 Log.v(TAG, "Process disappared"); 22768 } 22769 } 22770 return true; 22771 } 22772 } 22773 22774 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException { 22775 try { 22776 synchronized (this) { 22777 mBinderTransactionTrackingEnabled = false; 22778 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own 22779 // permission (same as profileControl). 22780 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 22781 != PackageManager.PERMISSION_GRANTED) { 22782 throw new SecurityException("Requires permission " 22783 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 22784 } 22785 22786 if (fd == null) { 22787 throw new IllegalArgumentException("null fd"); 22788 } 22789 22790 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor())); 22791 pw.println("Binder transaction traces for all processes.\n"); 22792 for (ProcessRecord process : mLruProcesses) { 22793 if (!processSanityChecksLocked(process)) { 22794 continue; 22795 } 22796 22797 pw.println("Traces for process: " + process.processName); 22798 pw.flush(); 22799 try { 22800 TransferPipe tp = new TransferPipe(); 22801 try { 22802 process.thread.stopBinderTrackingAndDump(tp.getWriteFd()); 22803 tp.go(fd.getFileDescriptor()); 22804 } finally { 22805 tp.kill(); 22806 } 22807 } catch (IOException e) { 22808 pw.println("Failure while dumping IPC traces from " + process + 22809 ". Exception: " + e); 22810 pw.flush(); 22811 } catch (RemoteException e) { 22812 pw.println("Got a RemoteException while dumping IPC traces from " + 22813 process + ". Exception: " + e); 22814 pw.flush(); 22815 } 22816 } 22817 fd = null; 22818 return true; 22819 } 22820 } finally { 22821 if (fd != null) { 22822 try { 22823 fd.close(); 22824 } catch (IOException e) { 22825 } 22826 } 22827 } 22828 } 22829 22830 private final class LocalService extends ActivityManagerInternal { 22831 @Override 22832 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent, 22833 int targetUserId) { 22834 synchronized (ActivityManagerService.this) { 22835 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid, 22836 targetPkg, intent, null, targetUserId); 22837 } 22838 } 22839 22840 @Override 22841 public String checkContentProviderAccess(String authority, int userId) { 22842 return ActivityManagerService.this.checkContentProviderAccess(authority, userId); 22843 } 22844 22845 @Override 22846 public void onWakefulnessChanged(int wakefulness) { 22847 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 22848 } 22849 22850 @Override 22851 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 22852 String processName, String abiOverride, int uid, Runnable crashHandler) { 22853 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 22854 processName, abiOverride, uid, crashHandler); 22855 } 22856 22857 @Override 22858 public SleepToken acquireSleepToken(String tag) { 22859 Preconditions.checkNotNull(tag); 22860 22861 synchronized (ActivityManagerService.this) { 22862 SleepTokenImpl token = new SleepTokenImpl(tag); 22863 mSleepTokens.add(token); 22864 updateSleepIfNeededLocked(); 22865 return token; 22866 } 22867 } 22868 22869 @Override 22870 public ComponentName getHomeActivityForUser(int userId) { 22871 synchronized (ActivityManagerService.this) { 22872 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId); 22873 return homeActivity == null ? null : homeActivity.realActivity; 22874 } 22875 } 22876 22877 @Override 22878 public void onUserRemoved(int userId) { 22879 synchronized (ActivityManagerService.this) { 22880 ActivityManagerService.this.onUserStoppedLocked(userId); 22881 } 22882 } 22883 22884 @Override 22885 public void onLocalVoiceInteractionStarted(IBinder activity, 22886 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { 22887 synchronized (ActivityManagerService.this) { 22888 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity, 22889 voiceSession, voiceInteractor); 22890 } 22891 } 22892 22893 @Override 22894 public void notifyStartingWindowDrawn() { 22895 synchronized (ActivityManagerService.this) { 22896 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn(); 22897 } 22898 } 22899 22900 @Override 22901 public void notifyAppTransitionStarting(int reason) { 22902 synchronized (ActivityManagerService.this) { 22903 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason); 22904 } 22905 } 22906 22907 @Override 22908 public void notifyAppTransitionFinished() { 22909 synchronized (ActivityManagerService.this) { 22910 mStackSupervisor.notifyAppTransitionDone(); 22911 } 22912 } 22913 22914 @Override 22915 public void notifyAppTransitionCancelled() { 22916 synchronized (ActivityManagerService.this) { 22917 mStackSupervisor.notifyAppTransitionDone(); 22918 } 22919 } 22920 22921 @Override 22922 public List<IBinder> getTopVisibleActivities() { 22923 synchronized (ActivityManagerService.this) { 22924 return mStackSupervisor.getTopVisibleActivities(); 22925 } 22926 } 22927 22928 @Override 22929 public void notifyDockedStackMinimizedChanged(boolean minimized) { 22930 synchronized (ActivityManagerService.this) { 22931 mStackSupervisor.setDockedStackMinimized(minimized); 22932 } 22933 } 22934 22935 @Override 22936 public void killForegroundAppsForUser(int userHandle) { 22937 synchronized (ActivityManagerService.this) { 22938 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 22939 final int NP = mProcessNames.getMap().size(); 22940 for (int ip = 0; ip < NP; ip++) { 22941 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 22942 final int NA = apps.size(); 22943 for (int ia = 0; ia < NA; ia++) { 22944 final ProcessRecord app = apps.valueAt(ia); 22945 if (app.persistent) { 22946 // We don't kill persistent processes. 22947 continue; 22948 } 22949 if (app.removed) { 22950 procs.add(app); 22951 } else if (app.userId == userHandle && app.foregroundActivities) { 22952 app.removed = true; 22953 procs.add(app); 22954 } 22955 } 22956 } 22957 22958 final int N = procs.size(); 22959 for (int i = 0; i < N; i++) { 22960 removeProcessLocked(procs.get(i), false, true, "kill all fg"); 22961 } 22962 } 22963 } 22964 22965 @Override 22966 public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) { 22967 if (!(target instanceof PendingIntentRecord)) { 22968 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target); 22969 return; 22970 } 22971 ((PendingIntentRecord) target).setWhitelistDuration(duration); 22972 } 22973 22974 @Override 22975 public void setDeviceIdleWhitelist(int[] appids) { 22976 synchronized (ActivityManagerService.this) { 22977 mDeviceIdleWhitelist = appids; 22978 } 22979 } 22980 22981 @Override 22982 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) { 22983 synchronized (ActivityManagerService.this) { 22984 mDeviceIdleTempWhitelist = appids; 22985 setAppIdTempWhitelistStateLocked(changingAppId, adding); 22986 } 22987 } 22988 22989 @Override 22990 public void updatePersistentConfigurationForUser(@NonNull Configuration values, 22991 int userId) { 22992 Preconditions.checkNotNull(values, "Configuration must not be null"); 22993 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported"); 22994 synchronized (ActivityManagerService.this) { 22995 updateConfigurationLocked(values, null, false, true, userId, 22996 false /* deferResume */); 22997 } 22998 } 22999 23000 @Override 23001 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents, 23002 Bundle bOptions) { 23003 Preconditions.checkNotNull(intents, "intents"); 23004 final String[] resolvedTypes = new String[intents.length]; 23005 for (int i = 0; i < intents.length; i++) { 23006 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver()); 23007 } 23008 23009 // UID of the package on user userId. 23010 // "= 0" is needed because otherwise catch(RemoteException) would make it look like 23011 // packageUid may not be initialized. 23012 int packageUid = 0; 23013 try { 23014 packageUid = AppGlobals.getPackageManager().getPackageUid( 23015 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId); 23016 } catch (RemoteException e) { 23017 // Shouldn't happen. 23018 } 23019 23020 synchronized (ActivityManagerService.this) { 23021 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes, 23022 /*resultTo*/ null, bOptions, userId); 23023 } 23024 } 23025 23026 @Override 23027 public int getUidProcessState(int uid) { 23028 return getUidState(uid); 23029 } 23030 23031 @Override 23032 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) { 23033 synchronized (ActivityManagerService.this) { 23034 23035 // We might change the visibilities here, so prepare an empty app transition which 23036 // might be overridden later if we actually change visibilities. 23037 mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */); 23038 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 23039 mWindowManager.executeAppTransition(); 23040 } 23041 if (callback != null) { 23042 callback.run(); 23043 } 23044 } 23045 23046 @Override 23047 public boolean isSystemReady() { 23048 // no need to synchronize(this) just to read & return the value 23049 return mSystemReady; 23050 } 23051 23052 @Override 23053 public void notifyKeyguardTrustedChanged() { 23054 synchronized (ActivityManagerService.this) { 23055 if (mKeyguardController.isKeyguardShowing()) { 23056 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 23057 } 23058 } 23059 } 23060 23061 /** 23062 * Sets if the given pid has an overlay UI or not. 23063 * 23064 * @param pid The pid we are setting overlay UI for. 23065 * @param hasOverlayUi True if the process has overlay UI. 23066 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY 23067 */ 23068 @Override 23069 public void setHasOverlayUi(int pid, boolean hasOverlayUi) { 23070 synchronized (ActivityManagerService.this) { 23071 final ProcessRecord pr; 23072 synchronized (mPidsSelfLocked) { 23073 pr = mPidsSelfLocked.get(pid); 23074 if (pr == null) { 23075 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid); 23076 return; 23077 } 23078 } 23079 if (pr.hasOverlayUi == hasOverlayUi) { 23080 return; 23081 } 23082 pr.hasOverlayUi = hasOverlayUi; 23083 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid); 23084 updateOomAdjLocked(pr); 23085 } 23086 } 23087 } 23088 23089 private final class SleepTokenImpl extends SleepToken { 23090 private final String mTag; 23091 private final long mAcquireTime; 23092 23093 public SleepTokenImpl(String tag) { 23094 mTag = tag; 23095 mAcquireTime = SystemClock.uptimeMillis(); 23096 } 23097 23098 @Override 23099 public void release() { 23100 synchronized (ActivityManagerService.this) { 23101 if (mSleepTokens.remove(this)) { 23102 updateSleepIfNeededLocked(); 23103 } 23104 } 23105 } 23106 23107 @Override 23108 public String toString() { 23109 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}"; 23110 } 23111 } 23112 23113 /** 23114 * An implementation of IAppTask, that allows an app to manage its own tasks via 23115 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 23116 * only the process that calls getAppTasks() can call the AppTask methods. 23117 */ 23118 class AppTaskImpl extends IAppTask.Stub { 23119 private int mTaskId; 23120 private int mCallingUid; 23121 23122 public AppTaskImpl(int taskId, int callingUid) { 23123 mTaskId = taskId; 23124 mCallingUid = callingUid; 23125 } 23126 23127 private void checkCaller() { 23128 if (mCallingUid != Binder.getCallingUid()) { 23129 throw new SecurityException("Caller " + mCallingUid 23130 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 23131 } 23132 } 23133 23134 @Override 23135 public void finishAndRemoveTask() { 23136 checkCaller(); 23137 23138 synchronized (ActivityManagerService.this) { 23139 long origId = Binder.clearCallingIdentity(); 23140 try { 23141 // We remove the task from recents to preserve backwards 23142 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false, 23143 REMOVE_FROM_RECENTS)) { 23144 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 23145 } 23146 } finally { 23147 Binder.restoreCallingIdentity(origId); 23148 } 23149 } 23150 } 23151 23152 @Override 23153 public ActivityManager.RecentTaskInfo getTaskInfo() { 23154 checkCaller(); 23155 23156 synchronized (ActivityManagerService.this) { 23157 long origId = Binder.clearCallingIdentity(); 23158 try { 23159 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 23160 if (tr == null) { 23161 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 23162 } 23163 return createRecentTaskInfoFromTaskRecord(tr); 23164 } finally { 23165 Binder.restoreCallingIdentity(origId); 23166 } 23167 } 23168 } 23169 23170 @Override 23171 public void moveToFront() { 23172 checkCaller(); 23173 // Will bring task to front if it already has a root activity. 23174 final long origId = Binder.clearCallingIdentity(); 23175 try { 23176 synchronized (this) { 23177 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null); 23178 } 23179 } finally { 23180 Binder.restoreCallingIdentity(origId); 23181 } 23182 } 23183 23184 @Override 23185 public int startActivity(IBinder whoThread, String callingPackage, 23186 Intent intent, String resolvedType, Bundle bOptions) { 23187 checkCaller(); 23188 23189 int callingUser = UserHandle.getCallingUserId(); 23190 TaskRecord tr; 23191 IApplicationThread appThread; 23192 synchronized (ActivityManagerService.this) { 23193 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 23194 if (tr == null) { 23195 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 23196 } 23197 appThread = IApplicationThread.Stub.asInterface(whoThread); 23198 if (appThread == null) { 23199 throw new IllegalArgumentException("Bad app thread " + appThread); 23200 } 23201 } 23202 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent, 23203 resolvedType, null, null, null, null, 0, 0, null, null, 23204 null, bOptions, false, callingUser, null, tr); 23205 } 23206 23207 @Override 23208 public void setExcludeFromRecents(boolean exclude) { 23209 checkCaller(); 23210 23211 synchronized (ActivityManagerService.this) { 23212 long origId = Binder.clearCallingIdentity(); 23213 try { 23214 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 23215 if (tr == null) { 23216 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 23217 } 23218 Intent intent = tr.getBaseIntent(); 23219 if (exclude) { 23220 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 23221 } else { 23222 intent.setFlags(intent.getFlags() 23223 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 23224 } 23225 } finally { 23226 Binder.restoreCallingIdentity(origId); 23227 } 23228 } 23229 } 23230 } 23231 23232 /** 23233 * Kill processes for the user with id userId and that depend on the package named packageName 23234 */ 23235 @Override 23236 public void killPackageDependents(String packageName, int userId) { 23237 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()"); 23238 if (packageName == null) { 23239 throw new NullPointerException( 23240 "Cannot kill the dependents of a package without its name."); 23241 } 23242 23243 long callingId = Binder.clearCallingIdentity(); 23244 IPackageManager pm = AppGlobals.getPackageManager(); 23245 int pkgUid = -1; 23246 try { 23247 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 23248 } catch (RemoteException e) { 23249 } 23250 if (userId != UserHandle.USER_ALL && pkgUid == -1) { 23251 throw new IllegalArgumentException( 23252 "Cannot kill dependents of non-existing package " + packageName); 23253 } 23254 try { 23255 synchronized(this) { 23256 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId, 23257 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false, 23258 "dep: " + packageName); 23259 } 23260 } finally { 23261 Binder.restoreCallingIdentity(callingId); 23262 } 23263 } 23264 23265 @Override 23266 public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException { 23267 final int userId = intent.getCreatorUserHandle().getIdentifier(); 23268 if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) { 23269 return false; 23270 } 23271 IIntentSender target = intent.getTarget(); 23272 if (!(target instanceof PendingIntentRecord)) { 23273 return false; 23274 } 23275 final PendingIntentRecord record = (PendingIntentRecord) target; 23276 final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent, 23277 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE); 23278 // For direct boot aware activities, they can be shown without triggering a work challenge 23279 // before the profile user is unlocked. 23280 return rInfo != null && rInfo.activityInfo != null; 23281 } 23282 23283 @Override 23284 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback) 23285 throws RemoteException { 23286 final long callingId = Binder.clearCallingIdentity(); 23287 try { 23288 mKeyguardController.dismissKeyguard(token, callback); 23289 } finally { 23290 Binder.restoreCallingIdentity(callingId); 23291 } 23292 } 23293 23294 @Override 23295 public int restartUserInBackground(final int userId) { 23296 return mUserController.restartUser(userId, /* foreground */ false); 23297 } 23298 23299 @Override 23300 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) { 23301 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 23302 "scheduleApplicationInfoChanged()"); 23303 23304 synchronized (this) { 23305 final long origId = Binder.clearCallingIdentity(); 23306 try { 23307 updateApplicationInfoLocked(packageNames, userId); 23308 } finally { 23309 Binder.restoreCallingIdentity(origId); 23310 } 23311 } 23312 } 23313 23314 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) { 23315 final PackageManagerInternal packageManager = getPackageManagerInternalLocked(); 23316 final boolean updateFrameworkRes = packagesToUpdate.contains("android"); 23317 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 23318 final ProcessRecord app = mLruProcesses.get(i); 23319 if (app.thread == null || app.pid == Process.myPid()) { 23320 continue; 23321 } 23322 23323 if (userId != UserHandle.USER_ALL && app.userId != userId) { 23324 continue; 23325 } 23326 23327 final int packageCount = app.pkgList.size(); 23328 for (int j = 0; j < packageCount; j++) { 23329 final String packageName = app.pkgList.keyAt(j); 23330 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) { 23331 try { 23332 final ApplicationInfo ai = packageManager.getApplicationInfo( 23333 packageName, app.userId); 23334 if (ai != null) { 23335 app.thread.scheduleApplicationInfoChanged(ai); 23336 } 23337 } catch (RemoteException e) { 23338 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", 23339 packageName, app)); 23340 } 23341 } 23342 } 23343 } 23344 } 23345 23346 /** 23347 * Attach an agent to the specified process (proces name or PID) 23348 */ 23349 public void attachAgent(String process, String path) { 23350 try { 23351 synchronized (this) { 23352 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent"); 23353 if (proc == null || proc.thread == null) { 23354 throw new IllegalArgumentException("Unknown process: " + process); 23355 } 23356 23357 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 23358 if (!isDebuggable) { 23359 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 23360 throw new SecurityException("Process not debuggable: " + proc); 23361 } 23362 } 23363 23364 proc.thread.attachAgent(path); 23365 } 23366 } catch (RemoteException e) { 23367 throw new IllegalStateException("Process disappeared"); 23368 } 23369 } 23370} 23371