[CS] Define DisplayMetricsRepo and use it for QsFrameTranslateImpl.
CentralSurfacesImpl updated the display metrics on configuration change (see #updateDisplaySize), so the new repo does the same. Removing QsFrameTranslateImpl's usage of CentralSurfaces is necessary to make NotificationPanelViewController a singleton. Bug: 277762009 Bug: 277764509 Test: atest DisplayMetricsRepositoryTest Test: `adb shell dumpsys activity service com.android.systemui/.SystemUIService DisplayMetricsRepo` -> dumps the display metric changes. Notably, the widthPixels and heightPixels change when the device is rotated. Change-Id: Ibef256bab38db5a7226d29a8b68546f093b78dd8
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.display.data.repository
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.util.DisplayMetrics
|
||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.log.LogBuffer
|
||||
import com.android.systemui.log.LogLevel
|
||||
import com.android.systemui.log.dagger.DisplayMetricsRepoLog
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
/** Repository tracking display-related metrics like display height and width. */
|
||||
@SysUISingleton
|
||||
class DisplayMetricsRepository
|
||||
@Inject
|
||||
constructor(
|
||||
@Application scope: CoroutineScope,
|
||||
configurationController: ConfigurationController,
|
||||
displayMetricsHolder: DisplayMetrics,
|
||||
context: Context,
|
||||
@DisplayMetricsRepoLog logBuffer: LogBuffer,
|
||||
) {
|
||||
|
||||
private val displayMetrics: StateFlow<DisplayMetrics> =
|
||||
conflatedCallbackFlow {
|
||||
val callback =
|
||||
object : ConfigurationController.ConfigurationListener {
|
||||
override fun onConfigChanged(newConfig: Configuration?) {
|
||||
context.display.getMetrics(displayMetricsHolder)
|
||||
trySend(displayMetricsHolder)
|
||||
}
|
||||
}
|
||||
configurationController.addCallback(callback)
|
||||
awaitClose { configurationController.removeCallback(callback) }
|
||||
}
|
||||
.onEach {
|
||||
logBuffer.log(
|
||||
"DisplayMetrics",
|
||||
LogLevel.INFO,
|
||||
{ str1 = it.toString() },
|
||||
{ "New metrics: $str1" },
|
||||
)
|
||||
}
|
||||
.stateIn(scope, SharingStarted.Eagerly, displayMetricsHolder)
|
||||
|
||||
/** Returns the current display height in pixels. */
|
||||
val heightPixels: Int
|
||||
get() = displayMetrics.value.heightPixels
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.log.dagger
|
||||
|
||||
import javax.inject.Qualifier
|
||||
|
||||
/** A [com.android.systemui.log.LogBuffer] for display metrics related logging. */
|
||||
@Qualifier
|
||||
@MustBeDocumented
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class DisplayMetricsRepoLog
|
||||
@@ -488,4 +488,12 @@ public class LogModule {
|
||||
public static LogBuffer provideDreamLogBuffer(LogBufferFactory factory) {
|
||||
return factory.create("DreamLog", 250);
|
||||
}
|
||||
|
||||
/** Provides a {@link LogBuffer} for display metrics related logs. */
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@DisplayMetricsRepoLog
|
||||
public static LogBuffer provideDisplayMetricsRepoLogBuffer(LogBufferFactory factory) {
|
||||
return factory.create("DisplayMetricsRepo", 50);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,19 +18,19 @@ package com.android.systemui.statusbar;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.display.data.repository.DisplayMetricsRepository;
|
||||
import com.android.systemui.plugins.qs.QS;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
|
||||
import com.android.systemui.statusbar.phone.CentralSurfaces;
|
||||
|
||||
/**
|
||||
* Calculates and moves the QS frame vertically.
|
||||
*/
|
||||
public abstract class QsFrameTranslateController {
|
||||
|
||||
protected CentralSurfaces mCentralSurfaces;
|
||||
protected DisplayMetricsRepository mDisplayMetricsRepository;
|
||||
|
||||
public QsFrameTranslateController(CentralSurfaces centralSurfaces) {
|
||||
mCentralSurfaces = centralSurfaces;
|
||||
public QsFrameTranslateController(DisplayMetricsRepository displayMetricsRepository) {
|
||||
mDisplayMetricsRepository = displayMetricsRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,9 +19,9 @@ package com.android.systemui.statusbar;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.display.data.repository.DisplayMetricsRepository;
|
||||
import com.android.systemui.plugins.qs.QS;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
|
||||
import com.android.systemui.statusbar.phone.CentralSurfaces;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@@ -34,8 +34,8 @@ import javax.inject.Inject;
|
||||
public class QsFrameTranslateImpl extends QsFrameTranslateController {
|
||||
|
||||
@Inject
|
||||
public QsFrameTranslateImpl(CentralSurfaces centralSurfaces) {
|
||||
super(centralSurfaces);
|
||||
public QsFrameTranslateImpl(DisplayMetricsRepository displayMetricsRepository) {
|
||||
super(displayMetricsRepository);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.keyguard.AuthKeyguardMessageArea;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||
import com.android.systemui.display.data.repository.DisplayMetricsRepository;
|
||||
import com.android.systemui.navigationbar.NavigationBarView;
|
||||
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
|
||||
import com.android.systemui.qs.QSPanelController;
|
||||
@@ -250,8 +251,12 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
|
||||
@Override
|
||||
void dump(PrintWriter pwOriginal, String[] args);
|
||||
|
||||
/** @deprecated Use {@link DisplayMetricsRepository} instead. */
|
||||
@Deprecated
|
||||
float getDisplayWidth();
|
||||
|
||||
/** @deprecated Use {@link DisplayMetricsRepository} instead. */
|
||||
@Deprecated
|
||||
float getDisplayHeight();
|
||||
|
||||
void readyForKeyguardDone();
|
||||
@@ -394,6 +399,9 @@ public interface CentralSurfaces extends Dumpable, LifecycleOwner {
|
||||
void setLaunchEmergencyActionOnFinishedWaking(boolean launch);
|
||||
|
||||
QSPanelController getQSPanelController();
|
||||
|
||||
/** @deprecated Use {@link DisplayMetricsRepository} instead. */
|
||||
@Deprecated
|
||||
float getDisplayDensity();
|
||||
|
||||
void extendDozePulse();
|
||||
|
||||
@@ -2114,16 +2114,19 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public float getDisplayDensity() {
|
||||
return mDisplayMetrics.density;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public float getDisplayWidth() {
|
||||
return mDisplayMetrics.widthPixels;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public float getDisplayHeight() {
|
||||
return mDisplayMetrics.heightPixels;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.display.data.repository
|
||||
|
||||
import android.content.Context
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.Display
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.log.LogBuffer
|
||||
import com.android.systemui.statusbar.policy.FakeConfigurationController
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@SmallTest
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class DisplayMetricsRepositoryTest : SysuiTestCase() {
|
||||
private lateinit var underTest: DisplayMetricsRepository
|
||||
|
||||
private val testScope = TestScope(StandardTestDispatcher())
|
||||
private val configurationController = FakeConfigurationController()
|
||||
|
||||
private val displayMetrics =
|
||||
DisplayMetrics().apply { this.heightPixels = INITIAL_HEIGHT_PIXELS }
|
||||
private val mockContext: Context = mock()
|
||||
private val mockDisplay: Display = mock()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
underTest =
|
||||
DisplayMetricsRepository(
|
||||
testScope.backgroundScope,
|
||||
configurationController,
|
||||
displayMetrics,
|
||||
mockContext,
|
||||
LogBuffer("TestBuffer", maxSize = 10, logcatEchoTracker = mock())
|
||||
)
|
||||
whenever(mockContext.display).thenReturn(mockDisplay)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun heightPixels_getsInitialValue() {
|
||||
assertThat(underTest.heightPixels).isEqualTo(INITIAL_HEIGHT_PIXELS)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun heightPixels_configChanged_heightUpdated() =
|
||||
testScope.runTest {
|
||||
runCurrent()
|
||||
|
||||
updateDisplayMetrics(456)
|
||||
configurationController.notifyConfigurationChanged()
|
||||
runCurrent()
|
||||
|
||||
assertThat(underTest.heightPixels).isEqualTo(456)
|
||||
|
||||
updateDisplayMetrics(23)
|
||||
configurationController.notifyConfigurationChanged()
|
||||
runCurrent()
|
||||
|
||||
assertThat(underTest.heightPixels).isEqualTo(23)
|
||||
}
|
||||
|
||||
private fun updateDisplayMetrics(newHeight: Int) {
|
||||
whenever(mockDisplay.getMetrics(displayMetrics)).thenAnswer {
|
||||
it.getArgument<DisplayMetrics>(0).heightPixels = newHeight
|
||||
Unit
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val INITIAL_HEIGHT_PIXELS = 345
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user