diff options
21 files changed, 520 insertions, 77 deletions
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 76efce56dcf0..21e4ab195f28 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -1762,6 +1762,15 @@ public final class DisplayManager { * 123,1,critical,0.8,default;123,1,moderate,0.6,id_2;456,2,moderate,0.9,critical,0.7 */ String KEY_BRIGHTNESS_THROTTLING_DATA = "brightness_throttling_data"; + + /** + * Key for disabling screen wake locks while apps are in cached state. + * Read value via {@link android.provider.DeviceConfig#getBoolean(String, String, boolean)} + * with {@link android.provider.DeviceConfig#NAMESPACE_DISPLAY_MANAGER} as the namespace. + * @hide + */ + String KEY_DISABLE_SCREEN_WAKE_LOCKS_WHILE_CACHED = + "disable_screen_wake_locks_while_cached"; } /** diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING index 01e6bf00a664..3af7a4502856 100644 --- a/packages/SystemUI/TEST_MAPPING +++ b/packages/SystemUI/TEST_MAPPING @@ -35,6 +35,9 @@ }, { "exclude-annotation": "android.platform.test.annotations.FlakyTest" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" } ] } @@ -128,6 +131,9 @@ }, { "exclude-annotation": "android.platform.test.annotations.FlakyTest" + }, + { + "exclude-annotation": "androidx.test.filters.FlakyTest" } ] } diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt index 3eb58bba1ca4..ec76f433b23b 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt @@ -38,6 +38,7 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.recyclerview.widget.RecyclerView import com.android.systemui.R import com.android.systemui.controls.ControlInterface +import com.android.systemui.controls.ui.CanUseIconPredicate import com.android.systemui.controls.ui.RenderInfo private typealias ModelFavoriteChanger = (String, Boolean) -> Unit @@ -51,7 +52,8 @@ private typealias ModelFavoriteChanger = (String, Boolean) -> Unit * @property elevation elevation of each control view */ class ControlAdapter( - private val elevation: Float + private val elevation: Float, + private val currentUserId: Int, ) : RecyclerView.Adapter<Holder>() { companion object { @@ -107,7 +109,8 @@ class ControlAdapter( background = parent.context.getDrawable( R.drawable.control_background_ripple) }, - model?.moveHelper // Indicates that position information is needed + currentUserId, + model?.moveHelper, // Indicates that position information is needed ) { id, favorite -> model?.changeFavoriteStatus(id, favorite) } @@ -212,8 +215,9 @@ private class ZoneHolder(view: View) : Holder(view) { */ internal class ControlHolder( view: View, + currentUserId: Int, val moveHelper: ControlsModel.MoveHelper?, - val favoriteCallback: ModelFavoriteChanger + val favoriteCallback: ModelFavoriteChanger, ) : Holder(view) { private val favoriteStateDescription = itemView.context.getString(R.string.accessibility_control_favorite) @@ -228,6 +232,7 @@ internal class ControlHolder( visibility = View.VISIBLE } + private val canUseIconPredicate = CanUseIconPredicate(currentUserId) private val accessibilityDelegate = ControlHolderAccessibilityDelegate( this::stateDescription, this::getLayoutPosition, @@ -287,7 +292,9 @@ internal class ControlHolder( val fg = context.getResources().getColorStateList(ri.foreground, context.getTheme()) icon.imageTintList = null - ci.customIcon?.let { + ci.customIcon + ?.takeIf(canUseIconPredicate) + ?.let { icon.setImageIcon(it) } ?: run { icon.setImageDrawable(ri.icon) diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt index d629e3ea365e..773f42375a08 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt @@ -250,7 +250,7 @@ open class ControlsEditingActivity @Inject constructor( val elevation = resources.getFloat(R.dimen.control_card_elevation) val recyclerView = requireViewById<RecyclerView>(R.id.list) recyclerView.alpha = 0.0f - val adapter = ControlAdapter(elevation).apply { + val adapter = ControlAdapter(elevation, userTracker.userId).apply { registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { var hasAnimated = false override fun onChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt index d3ffc9585335..d4713d287945 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt @@ -197,7 +197,7 @@ open class ControlsFavoritingActivity @Inject constructor( } executor.execute { - structurePager.adapter = StructureAdapter(listOfStructures) + structurePager.adapter = StructureAdapter(listOfStructures, userTracker.userId) structurePager.setCurrentItem(structureIndex) if (error) { statusText.text = resources.getString(R.string.controls_favorite_load_error, @@ -243,7 +243,7 @@ open class ControlsFavoritingActivity @Inject constructor( structurePager.alpha = 0.0f pageIndicator.alpha = 0.0f structurePager.apply { - adapter = StructureAdapter(emptyList()) + adapter = StructureAdapter(emptyList(), userTracker.userId) registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { super.onPageSelected(position) diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt index 747bcbe1c229..5977d379acde 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt @@ -24,13 +24,15 @@ import androidx.recyclerview.widget.RecyclerView import com.android.systemui.R class StructureAdapter( - private val models: List<StructureContainer> + private val models: List<StructureContainer>, + private val currentUserId: Int, ) : RecyclerView.Adapter<StructureAdapter.StructureHolder>() { override fun onCreateViewHolder(parent: ViewGroup, p1: Int): StructureHolder { val layoutInflater = LayoutInflater.from(parent.context) return StructureHolder( - layoutInflater.inflate(R.layout.controls_structure_page, parent, false) + layoutInflater.inflate(R.layout.controls_structure_page, parent, false), + currentUserId, ) } @@ -40,7 +42,8 @@ class StructureAdapter( holder.bind(models[index].model) } - class StructureHolder(view: View) : RecyclerView.ViewHolder(view) { + class StructureHolder(view: View, currentUserId: Int) : + RecyclerView.ViewHolder(view) { private val recyclerView: RecyclerView private val controlAdapter: ControlAdapter @@ -48,7 +51,7 @@ class StructureAdapter( init { recyclerView = itemView.requireViewById<RecyclerView>(R.id.listAll) val elevation = itemView.context.resources.getFloat(R.dimen.control_card_elevation) - controlAdapter = ControlAdapter(elevation) + controlAdapter = ControlAdapter(elevation, currentUserId) setUpRecyclerView() } diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/CanUseIconPredicate.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/CanUseIconPredicate.kt new file mode 100644 index 000000000000..61c21237144d --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/CanUseIconPredicate.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.controls.ui + +import android.content.ContentProvider +import android.graphics.drawable.Icon + +class CanUseIconPredicate(private val currentUserId: Int) : (Icon) -> Boolean { + + override fun invoke(icon: Icon): Boolean = + if (icon.type == Icon.TYPE_URI || icon.type == Icon.TYPE_URI_ADAPTIVE_BITMAP) { + ContentProvider.getUserIdFromUri(icon.uri, currentUserId) == currentUserId + } else { + true + } +} diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt index e6361f46c8ad..c04bc8792223 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt @@ -68,7 +68,8 @@ class ControlViewHolder( val bgExecutor: DelayableExecutor, val controlActionCoordinator: ControlActionCoordinator, val controlsMetricsLogger: ControlsMetricsLogger, - val uid: Int + val uid: Int, + val currentUserId: Int, ) { companion object { @@ -85,29 +86,9 @@ class ControlViewHolder( private val ATTR_DISABLED = intArrayOf(-android.R.attr.state_enabled) const val MIN_LEVEL = 0 const val MAX_LEVEL = 10000 - - fun findBehaviorClass( - status: Int, - template: ControlTemplate, - deviceType: Int - ): Supplier<out Behavior> { - return when { - status != Control.STATUS_OK -> Supplier { StatusBehavior() } - template == ControlTemplate.NO_TEMPLATE -> Supplier { TouchBehavior() } - template is ThumbnailTemplate -> Supplier { ThumbnailBehavior() } - - // Required for legacy support, or where cameras do not use the new template - deviceType == DeviceTypes.TYPE_CAMERA -> Supplier { TouchBehavior() } - template is ToggleTemplate -> Supplier { ToggleBehavior() } - template is StatelessTemplate -> Supplier { TouchBehavior() } - template is ToggleRangeTemplate -> Supplier { ToggleRangeBehavior() } - template is RangeTemplate -> Supplier { ToggleRangeBehavior() } - template is TemperatureControlTemplate -> Supplier { TemperatureControlBehavior() } - else -> Supplier { DefaultBehavior() } - } - } } + private val canUseIconPredicate = CanUseIconPredicate(currentUserId) private val toggleBackgroundIntensity: Float = layout.context.resources .getFraction(R.fraction.controls_toggle_bg_intensity, 1, 1) private var stateAnimator: ValueAnimator? = null @@ -147,6 +128,27 @@ class ControlViewHolder( status.setSelected(true) } + fun findBehaviorClass( + status: Int, + template: ControlTemplate, + deviceType: Int + ): Supplier<out Behavior> { + return when { + status != Control.STATUS_OK -> Supplier { StatusBehavior() } + template == ControlTemplate.NO_TEMPLATE -> Supplier { TouchBehavior() } + template is ThumbnailTemplate -> Supplier { ThumbnailBehavior(currentUserId) } + + // Required for legacy support, or where cameras do not use the new template + deviceType == DeviceTypes.TYPE_CAMERA -> Supplier { TouchBehavior() } + template is ToggleTemplate -> Supplier { ToggleBehavior() } + template is StatelessTemplate -> Supplier { TouchBehavior() } + template is ToggleRangeTemplate -> Supplier { ToggleRangeBehavior() } + template is RangeTemplate -> Supplier { ToggleRangeBehavior() } + template is TemperatureControlTemplate -> Supplier { TemperatureControlBehavior() } + else -> Supplier { DefaultBehavior() } + } + } + fun bindData(cws: ControlWithState, isLocked: Boolean) { // If an interaction is in progress, the update may visually interfere with the action the // action the user wants to make. Don't apply the update, and instead assume a new update @@ -473,7 +475,9 @@ class ControlViewHolder( status.setTextColor(color) - control?.getCustomIcon()?.let { + control?.customIcon + ?.takeIf(canUseIconPredicate) + ?.let { icon.setImageIcon(it) icon.imageTintList = it.tintList } ?: run { diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index 776b336e7b61..631ed3c26496 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -690,7 +690,8 @@ class ControlsUiControllerImpl @Inject constructor ( bgExecutor, controlActionCoordinator, controlsMetricsLogger, - selected.uid + selected.uid, + controlsController.get().currentUserId, ) cvh.bindData(it, false /* isLocked, will be ignored on initial load */) controlViewsById.put(key, cvh) diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt index a7dc09bb17e5..39d69704d817 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt @@ -63,7 +63,7 @@ class TemperatureControlBehavior : Behavior { // interactions (touch, range) subBehavior = cvh.bindBehavior( subBehavior, - ControlViewHolder.findBehaviorClass( + cvh.findBehaviorClass( control.status, subTemplate, control.deviceType diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt index c2168aa8d9d9..0b57e792f9f7 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt @@ -33,7 +33,7 @@ import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL * Supports display of static images on the background of the tile. When marked active, the title * and subtitle will not be visible. To be used with {@link Thumbnailtemplate} only. */ -class ThumbnailBehavior : Behavior { +class ThumbnailBehavior(currentUserId: Int) : Behavior { lateinit var template: ThumbnailTemplate lateinit var control: Control lateinit var cvh: ControlViewHolder @@ -42,6 +42,7 @@ class ThumbnailBehavior : Behavior { private var shadowRadius: Float = 0f private var shadowColor: Int = 0 + private val canUseIconPredicate = CanUseIconPredicate(currentUserId) private val enabled: Boolean get() = template.isActive() @@ -80,11 +81,16 @@ class ThumbnailBehavior : Behavior { cvh.status.setShadowLayer(shadowOffsetX, shadowOffsetY, shadowRadius, shadowColor) cvh.bgExecutor.execute { - val drawable = template.getThumbnail().loadDrawable(cvh.context) + val drawable = template.thumbnail + ?.takeIf(canUseIconPredicate) + ?.loadDrawable(cvh.context) cvh.uiExecutor.execute { val radius = cvh.context.getResources() .getDimensionPixelSize(R.dimen.control_corner_radius).toFloat() - clipLayer.setDrawable(CornerDrawable(drawable, radius)) + // TODO(b/290037843): Add a placeholder + drawable?.let { + clipLayer.drawable = CornerDrawable(it, radius) + } clipLayer.setColorFilter(BlendModeColorFilter(cvh.context.resources .getColor(R.color.control_thumbnail_tint), BlendMode.LUMINOSITY)) cvh.applyRenderInfo(enabled, colorOffset) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt index 62a0d138fd05..5c2f9a8d28ec 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt @@ -39,7 +39,10 @@ class StackCoordinator @Inject internal constructor( override fun attach(pipeline: NotifPipeline) { pipeline.addOnAfterRenderListListener(::onAfterRenderList) - groupExpansionManagerImpl.attach(pipeline) + // TODO(b/282865576): This has an issue where it makes changes to some groups without + // notifying listeners. To be fixed in QPR, but for now let's comment it out to avoid the + // group expansion bug. + // groupExpansionManagerImpl.attach(pipeline) } fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) = diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt index 592d1aa8f43f..135307accd13 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt @@ -182,7 +182,7 @@ class UnlockedScreenOffAnimationController @Inject constructor( // Cancel any existing CUJs before starting the animation interactionJankMonitor.cancel(CUJ_SCREEN_OFF_SHOW_AOD) - + PropertyAnimator.cancelAnimation(keyguardView, AnimatableProperty.ALPHA) PropertyAnimator.setProperty( keyguardView, AnimatableProperty.ALPHA, 1f, AnimationProperties() diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/CanUseIconPredicateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/CanUseIconPredicateTest.kt new file mode 100644 index 000000000000..bfdb9231a9f8 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/CanUseIconPredicateTest.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.controls.ui + +import android.content.ContentProvider +import android.graphics.Bitmap +import android.graphics.drawable.Icon +import android.net.Uri +import android.os.UserHandle +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class CanUseIconPredicateTest : SysuiTestCase() { + + private companion object { + const val USER_ID_1 = 1 + const val USER_ID_2 = 2 + } + + val underTest: CanUseIconPredicate = CanUseIconPredicate(USER_ID_1) + + @Test + fun testReturnsFalseForDifferentUser() { + val user2Icon = + Icon.createWithContentUri( + ContentProvider.createContentUriForUser( + Uri.parse("content://test"), + UserHandle.of(USER_ID_2) + ) + ) + + assertThat(underTest.invoke(user2Icon)).isFalse() + } + + @Test + fun testReturnsTrueForCorrectUser() { + val user1Icon = + Icon.createWithContentUri( + ContentProvider.createContentUriForUser( + Uri.parse("content://test"), + UserHandle.of(USER_ID_1) + ) + ) + + assertThat(underTest.invoke(user1Icon)).isTrue() + } + + @Test + fun testReturnsTrueForUriWithoutUser() { + val uriIcon = Icon.createWithContentUri(Uri.parse("content://test")) + + assertThat(underTest.invoke(uriIcon)).isTrue() + } + + @Test + fun testReturnsTrueForNonUriIcon() { + val bitmapIcon = Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)) + + assertThat(underTest.invoke(bitmapIcon)).isTrue() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt index d3c465dab438..42f28c8c6043 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt @@ -66,7 +66,8 @@ class ControlViewHolderTest : SysuiTestCase() { FakeExecutor(clock), mock(ControlActionCoordinator::class.java), mock(ControlsMetricsLogger::class.java), - uid = 100 + uid = 100, + 0, ) val cws = ControlWithState( diff --git a/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java b/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java new file mode 100644 index 000000000000..03103834f325 --- /dev/null +++ b/services/core/java/com/android/server/display/feature/DeviceConfigParameterProvider.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display.feature; + +import android.hardware.display.DisplayManager; +import android.provider.DeviceConfig; +import android.provider.DeviceConfigInterface; + +import java.util.concurrent.Executor; + +/** + * Helper class to access all DeviceConfig features for display_manager namespace + * + **/ +public class DeviceConfigParameterProvider { + + private static final String TAG = "DisplayFeatureProvider"; + + private final DeviceConfigInterface mDeviceConfig; + + public DeviceConfigParameterProvider(DeviceConfigInterface deviceConfig) { + mDeviceConfig = deviceConfig; + } + + public boolean isDisableScreenWakeLocksWhileCachedFeatureEnabled() { + return mDeviceConfig.getBoolean(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + DisplayManager.DeviceConfig.KEY_DISABLE_SCREEN_WAKE_LOCKS_WHILE_CACHED, true); + } + + /** add property change listener to DeviceConfig */ + public void addOnPropertiesChangedListener(Executor executor, + DeviceConfig.OnPropertiesChangedListener listener) { + mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + executor, listener); + } +} diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index a53b831d55c1..d82f7a56a830 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -92,6 +92,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; import android.os.WorkSource.WorkChain; +import android.provider.DeviceConfigInterface; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.service.dreams.DreamManagerInternal; @@ -128,6 +129,7 @@ import com.android.server.UiThread; import com.android.server.UserspaceRebootLogger; import com.android.server.Watchdog; import com.android.server.am.BatteryStatsService; +import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.lights.LightsManager; import com.android.server.lights.LogicalLight; import com.android.server.policy.WindowManagerPolicy; @@ -323,6 +325,9 @@ public final class PowerManagerService extends SystemService private final Injector mInjector; private final PermissionCheckerWrapper mPermissionCheckerWrapper; private final PowerPropertiesWrapper mPowerPropertiesWrapper; + private final DeviceConfigParameterProvider mDeviceConfigProvider; + + private boolean mDisableScreenWakeLocksWhileCached; private LightsManager mLightsManager; private BatteryManagerInternal mBatteryManagerInternal; @@ -1065,6 +1070,10 @@ public final class PowerManagerService extends SystemService } }; } + + DeviceConfigParameterProvider createDeviceConfigParameterProvider() { + return new DeviceConfigParameterProvider(DeviceConfigInterface.REAL); + } } /** Interface for checking an app op permission */ @@ -1161,6 +1170,7 @@ public final class PowerManagerService extends SystemService mInjector.createInattentiveSleepWarningController(); mPermissionCheckerWrapper = mInjector.createPermissionCheckerWrapper(); mPowerPropertiesWrapper = mInjector.createPowerPropertiesWrapper(); + mDeviceConfigProvider = mInjector.createDeviceConfigParameterProvider(); mPowerGroupWakefulnessChangeListener = new PowerGroupWakefulnessChangeListener(); @@ -1346,6 +1356,14 @@ public final class PowerManagerService extends SystemService mLightsManager = getLocalService(LightsManager.class); mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION); + updateDeviceConfigLocked(); + mDeviceConfigProvider.addOnPropertiesChangedListener(BackgroundThread.getExecutor(), + properties -> { + synchronized (mLock) { + updateDeviceConfigLocked(); + updateWakeLockDisabledStatesLocked(); + } + }); // Initialize display power management. mDisplayManagerInternal.initPowerManagement( @@ -1545,6 +1563,12 @@ public final class PowerManagerService extends SystemService updatePowerStateLocked(); } + @GuardedBy("mLock") + private void updateDeviceConfigLocked() { + mDisableScreenWakeLocksWhileCached = mDeviceConfigProvider + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + } + @RequiresPermission(value = android.Manifest.permission.TURN_SCREEN_ON, conditional = true) private void acquireWakeLockInternal(IBinder lock, int displayId, int flags, String tag, String packageName, WorkSource ws, String historyTag, int uid, int pid, @@ -2760,13 +2784,13 @@ public final class PowerManagerService extends SystemService /** Get wake lock summary flags that correspond to the given wake lock. */ @SuppressWarnings("deprecation") private int getWakeLockSummaryFlags(WakeLock wakeLock) { + if (wakeLock.mDisabled) { + // We only respect this if the wake lock is not disabled. + return 0; + } switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) { case PowerManager.PARTIAL_WAKE_LOCK: - if (!wakeLock.mDisabled) { - // We only respect this if the wake lock is not disabled. - return WAKE_LOCK_CPU; - } - break; + return WAKE_LOCK_CPU; case PowerManager.FULL_WAKE_LOCK: return WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT; case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: @@ -4151,7 +4175,7 @@ public final class PowerManagerService extends SystemService for (int i = 0; i < numWakeLocks; i++) { final WakeLock wakeLock = mWakeLocks.get(i); if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) - == PowerManager.PARTIAL_WAKE_LOCK) { + == PowerManager.PARTIAL_WAKE_LOCK || isScreenLock(wakeLock)) { if (setWakeLockDisabledStateLocked(wakeLock)) { changed = true; if (wakeLock.mDisabled) { @@ -4205,6 +4229,22 @@ public final class PowerManagerService extends SystemService } } return wakeLock.setDisabled(disabled); + } else if (mDisableScreenWakeLocksWhileCached && isScreenLock(wakeLock)) { + boolean disabled = false; + final int appid = UserHandle.getAppId(wakeLock.mOwnerUid); + final UidState state = wakeLock.mUidState; + // Cached inactive processes are never allowed to hold wake locks. + if (mConstants.NO_CACHED_WAKE_LOCKS + && appid >= Process.FIRST_APPLICATION_UID + && !state.mActive + && state.mProcState != ActivityManager.PROCESS_STATE_NONEXISTENT + && state.mProcState >= ActivityManager.PROCESS_STATE_TOP_SLEEPING) { + if (DEBUG_SPEW) { + Slog.d(TAG, "disabling full wakelock " + wakeLock); + } + disabled = true; + } + return wakeLock.setDisabled(disabled); } return false; } diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java index 89f044bdd163..d7667d8ce7a8 100644 --- a/services/core/java/com/android/server/wm/Dimmer.java +++ b/services/core/java/com/android/server/wm/Dimmer.java @@ -215,8 +215,7 @@ class Dimmer { return mDimState; } - private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer, - float alpha, int blurRadius) { + private void dim(WindowContainer container, int relativeLayer, float alpha, int blurRadius) { final DimState d = getDimState(container); if (d == null) { @@ -226,6 +225,7 @@ class Dimmer { // The dim method is called from WindowState.prepareSurfaces(), which is always called // in the correct Z from lowest Z to highest. This ensures that the dim layer is always // relative to the highest Z layer with a dim. + SurfaceControl.Transaction t = mHost.getPendingTransaction(); t.setRelativeLayer(d.mDimLayer, container.getSurfaceControl(), relativeLayer); t.setAlpha(d.mDimLayer, alpha); t.setBackgroundBlurRadius(d.mDimLayer, blurRadius); @@ -238,26 +238,23 @@ class Dimmer { * for each call to {@link WindowContainer#prepareSurfaces} the Dim state will be reset * and the child should call dimAbove again to request the Dim to continue. * - * @param t A transaction in which to apply the Dim. * @param container The container which to dim above. Should be a child of our host. * @param alpha The alpha at which to Dim. */ - void dimAbove(SurfaceControl.Transaction t, WindowContainer container, float alpha) { - dim(t, container, 1, alpha, 0); + void dimAbove(WindowContainer container, float alpha) { + dim(container, 1, alpha, 0); } /** * Like {@link #dimAbove} but places the dim below the given container. * - * @param t A transaction in which to apply the Dim. * @param container The container which to dim below. Should be a child of our host. * @param alpha The alpha at which to Dim. * @param blurRadius The amount of blur added to the Dim. */ - void dimBelow(SurfaceControl.Transaction t, WindowContainer container, float alpha, - int blurRadius) { - dim(t, container, -1, alpha, blurRadius); + void dimBelow(WindowContainer container, float alpha, int blurRadius) { + dim(container, -1, alpha, blurRadius); } /** diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 5de5babd9e8a..06978a5338ea 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5128,7 +5128,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP private void applyDims() { if (((mAttrs.flags & FLAG_DIM_BEHIND) != 0 || shouldDrawBlurBehind()) - && isVisibleNow() && !mHidden && mTransitionController.canApplyDim(getTask())) { + && mToken.isVisibleRequested() && isVisibleNow() && !mHidden + && mTransitionController.canApplyDim(getTask())) { // Only show the Dimmer when the following is satisfied: // 1. The window has the flag FLAG_DIM_BEHIND or blur behind is requested // 2. The WindowToken is not hidden so dims aren't shown when the window is exiting. @@ -5138,7 +5139,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mIsDimming = true; final float dimAmount = (mAttrs.flags & FLAG_DIM_BEHIND) != 0 ? mAttrs.dimAmount : 0; final int blurRadius = shouldDrawBlurBehind() ? mAttrs.getBlurBehindRadius() : 0; - getDimmer().dimBelow(getSyncTransaction(), this, dimAmount, blurRadius); + getDimmer().dimBelow(this, dimAmount, blurRadius); } } diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java index 5c6164efb3b6..431d3a61de51 100644 --- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java @@ -18,6 +18,8 @@ package com.android.server.power; import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; +import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; +import static android.app.ActivityManager.PROCESS_STATE_TOP_SLEEPING; import static android.os.PowerManager.USER_ACTIVITY_EVENT_BUTTON; import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP; import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; @@ -78,6 +80,7 @@ import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.UserHandle; import android.os.test.TestLooper; +import android.provider.DeviceConfig; import android.provider.Settings; import android.service.dreams.DreamManagerInternal; import android.sysprop.PowerProperties; @@ -91,6 +94,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.util.test.FakeSettingsProvider; import com.android.server.LocalServices; import com.android.server.SystemService; +import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.lights.LightsManager; import com.android.server.policy.WindowManagerPolicy; import com.android.server.power.PowerManagerService.BatteryReceiver; @@ -159,6 +163,7 @@ public class PowerManagerServiceTest { @Mock private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock; @Mock private PowerManagerService.PermissionCheckerWrapper mPermissionCheckerWrapperMock; @Mock private PowerManagerService.PowerPropertiesWrapper mPowerPropertiesWrapper; + @Mock private DeviceConfigParameterProvider mDeviceParameterProvider; @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); @@ -340,6 +345,11 @@ public class PowerManagerServiceTest { PowerManagerService.PowerPropertiesWrapper createPowerPropertiesWrapper() { return mPowerPropertiesWrapper; } + + @Override + DeviceConfigParameterProvider createDeviceConfigParameterProvider() { + return mDeviceParameterProvider; + } }); return mService; } @@ -2680,4 +2690,197 @@ public class PowerManagerServiceTest { verify(mNotifierMock, never()).onUserActivity(anyInt(), anyInt(), anyInt()); } + @Test + public void testFeatureEnabledProcStateUncachedToCached_fullWakeLockDisabled() { + doReturn(true).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK); + setUncachedUidProcState(wakeLock.mOwnerUid); + + setCachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isTrue(); + } + + @Test + public void testFeatureDisabledProcStateUncachedToCached_fullWakeLockEnabled() { + doReturn(false).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK); + setUncachedUidProcState(wakeLock.mOwnerUid); + + setCachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + @Test + public void testFeatureEnabledProcStateUncachedToCached_screenBrightWakeLockDisabled() { + doReturn(true).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("screenBrightWakeLock", + PowerManager.SCREEN_BRIGHT_WAKE_LOCK); + setUncachedUidProcState(wakeLock.mOwnerUid); + + setCachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isTrue(); + } + + @Test + public void testFeatureDisabledProcStateUncachedToCached_screenBrightWakeLockEnabled() { + doReturn(false).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("screenBrightWakeLock", + PowerManager.SCREEN_BRIGHT_WAKE_LOCK); + setUncachedUidProcState(wakeLock.mOwnerUid); + + setCachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + @Test + public void testFeatureEnabledProcStateUncachedToCached_screenDimWakeLockDisabled() { + doReturn(true).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("screenDimWakeLock", + PowerManager.SCREEN_DIM_WAKE_LOCK); + setUncachedUidProcState(wakeLock.mOwnerUid); + + setCachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isTrue(); + } + + @Test + public void testFeatureDisabledProcStateUncachedToCached_screenDimWakeLockEnabled() { + doReturn(false).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("screenDimWakeLock", + PowerManager.SCREEN_DIM_WAKE_LOCK); + setUncachedUidProcState(wakeLock.mOwnerUid); + + setCachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + @Test + public void testFeatureEnabledProcStateCachedToUncached_fullWakeLockEnabled() { + doReturn(true).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK); + setCachedUidProcState(wakeLock.mOwnerUid); + + setUncachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + @Test + public void testFeatureDisabledProcStateCachedToUncached_fullWakeLockEnabled() { + doReturn(false).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK); + setCachedUidProcState(wakeLock.mOwnerUid); + + setUncachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + @Test + public void testFeatureEnabledProcStateCachedToUncached_screenBrightWakeLockEnabled() { + doReturn(true).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("screenBrightWakeLock", + PowerManager.SCREEN_BRIGHT_WAKE_LOCK); + setCachedUidProcState(wakeLock.mOwnerUid); + + setUncachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + @Test + public void testFeatureDisabledProcStateCachedToUncached_screenBrightWakeLockEnabled() { + doReturn(false).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("screenBrightWakeLock", + PowerManager.SCREEN_BRIGHT_WAKE_LOCK); + setCachedUidProcState(wakeLock.mOwnerUid); + + setUncachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + @Test + public void testFeatureEnabledProcStateCachedToUncached_screenDimWakeLockEnabled() { + doReturn(true).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("screenDimWakeLock", + PowerManager.SCREEN_DIM_WAKE_LOCK); + setCachedUidProcState(wakeLock.mOwnerUid); + + setUncachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + @Test + public void testFeatureDisabledProcStateCachedToUncached_screenDimWakeLockEnabled() { + doReturn(false).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + createService(); + startSystem(); + WakeLock wakeLock = acquireWakeLock("screenDimWakeLock", + PowerManager.SCREEN_DIM_WAKE_LOCK); + setCachedUidProcState(wakeLock.mOwnerUid); + + setUncachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + @Test + public void testFeatureDynamicallyDisabledProcStateUncachedToCached_fullWakeLockEnabled() { + doReturn(true).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + ArgumentCaptor<DeviceConfig.OnPropertiesChangedListener> listenerCaptor = + ArgumentCaptor.forClass(DeviceConfig.OnPropertiesChangedListener.class); + createService(); + startSystem(); + verify(mDeviceParameterProvider, times(1)) + .addOnPropertiesChangedListener(any(), listenerCaptor.capture()); + WakeLock wakeLock = acquireWakeLock("fullWakeLock", PowerManager.FULL_WAKE_LOCK); + setUncachedUidProcState(wakeLock.mOwnerUid); + // dynamically disable the feature + doReturn(false).when(mDeviceParameterProvider) + .isDisableScreenWakeLocksWhileCachedFeatureEnabled(); + listenerCaptor.getValue().onPropertiesChanged( + new DeviceConfig.Properties("ignored_namespace", null)); + + setUncachedUidProcState(wakeLock.mOwnerUid); + assertThat(wakeLock.mDisabled).isFalse(); + } + + private void setCachedUidProcState(int uid) { + mService.updateUidProcStateInternal(uid, PROCESS_STATE_TOP_SLEEPING); + } + + private void setUncachedUidProcState(int uid) { + mService.updateUidProcStateInternal(uid, PROCESS_STATE_RECEIVER); + } } diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java index f235d153c658..233a2076a867 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java @@ -52,7 +52,8 @@ public class DimmerTests extends WindowTestsBase { private static class TestWindowContainer extends WindowContainer<TestWindowContainer> { final SurfaceControl mControl = mock(SurfaceControl.class); - final SurfaceControl.Transaction mTransaction = spy(StubTransaction.class); + final SurfaceControl.Transaction mPendingTransaction = spy(StubTransaction.class); + final SurfaceControl.Transaction mSyncTransaction = spy(StubTransaction.class); TestWindowContainer(WindowManagerService wm) { super(wm); @@ -65,12 +66,12 @@ public class DimmerTests extends WindowTestsBase { @Override public SurfaceControl.Transaction getSyncTransaction() { - return mTransaction; + return mSyncTransaction; } @Override public SurfaceControl.Transaction getPendingTransaction() { - return mTransaction; + return mPendingTransaction; } } @@ -144,7 +145,7 @@ public class DimmerTests extends WindowTestsBase { mHost.addChild(child, 0); final float alpha = 0.8f; - mDimmer.dimAbove(mTransaction, child, alpha); + mDimmer.dimAbove(child, alpha); int width = 100; int height = 300; @@ -161,13 +162,13 @@ public class DimmerTests extends WindowTestsBase { mHost.addChild(child, 0); final float alpha = 0.8f; - mDimmer.dimAbove(mTransaction, child, alpha); + mDimmer.dimAbove(child, alpha); SurfaceControl dimLayer = getDimLayer(); assertNotNull("Dimmer should have created a surface", dimLayer); - verify(mTransaction).setAlpha(dimLayer, alpha); - verify(mTransaction).setRelativeLayer(dimLayer, child.mControl, 1); + verify(mHost.getPendingTransaction()).setAlpha(dimLayer, alpha); + verify(mHost.getPendingTransaction()).setRelativeLayer(dimLayer, child.mControl, 1); } @Test @@ -176,13 +177,13 @@ public class DimmerTests extends WindowTestsBase { mHost.addChild(child, 0); final float alpha = 0.8f; - mDimmer.dimBelow(mTransaction, child, alpha, 0); + mDimmer.dimBelow(child, alpha, 0); SurfaceControl dimLayer = getDimLayer(); assertNotNull("Dimmer should have created a surface", dimLayer); - verify(mTransaction).setAlpha(dimLayer, alpha); - verify(mTransaction).setRelativeLayer(dimLayer, child.mControl, -1); + verify(mHost.getPendingTransaction()).setAlpha(dimLayer, alpha); + verify(mHost.getPendingTransaction()).setRelativeLayer(dimLayer, child.mControl, -1); } @Test @@ -191,7 +192,7 @@ public class DimmerTests extends WindowTestsBase { mHost.addChild(child, 0); final float alpha = 0.8f; - mDimmer.dimAbove(mTransaction, child, alpha); + mDimmer.dimAbove(child, alpha); SurfaceControl dimLayer = getDimLayer(); mDimmer.resetDimStates(); @@ -208,10 +209,10 @@ public class DimmerTests extends WindowTestsBase { mHost.addChild(child, 0); final float alpha = 0.8f; - mDimmer.dimAbove(mTransaction, child, alpha); + mDimmer.dimAbove(child, alpha); SurfaceControl dimLayer = getDimLayer(); mDimmer.resetDimStates(); - mDimmer.dimAbove(mTransaction, child, alpha); + mDimmer.dimAbove(child, alpha); mDimmer.updateDims(mTransaction); verify(mTransaction).show(dimLayer); @@ -224,7 +225,7 @@ public class DimmerTests extends WindowTestsBase { mHost.addChild(child, 0); final float alpha = 0.8f; - mDimmer.dimAbove(mTransaction, child, alpha); + mDimmer.dimAbove(child, alpha); final Rect bounds = mDimmer.mDimState.mDimBounds; SurfaceControl dimLayer = getDimLayer(); @@ -245,7 +246,7 @@ public class DimmerTests extends WindowTestsBase { TestWindowContainer child = new TestWindowContainer(mWm); mHost.addChild(child, 0); - mDimmer.dimAbove(mTransaction, child, 1); + mDimmer.dimAbove(child, 1); SurfaceControl dimLayer = getDimLayer(); mDimmer.updateDims(mTransaction); verify(mTransaction, times(1)).show(dimLayer); @@ -266,13 +267,13 @@ public class DimmerTests extends WindowTestsBase { mHost.addChild(child, 0); final int blurRadius = 50; - mDimmer.dimBelow(mTransaction, child, 0, blurRadius); + mDimmer.dimBelow(child, 0, blurRadius); SurfaceControl dimLayer = getDimLayer(); assertNotNull("Dimmer should have created a surface", dimLayer); - verify(mTransaction).setBackgroundBlurRadius(dimLayer, blurRadius); - verify(mTransaction).setRelativeLayer(dimLayer, child.mControl, -1); + verify(mHost.getPendingTransaction()).setBackgroundBlurRadius(dimLayer, blurRadius); + verify(mHost.getPendingTransaction()).setRelativeLayer(dimLayer, child.mControl, -1); } private SurfaceControl getDimLayer() { |