Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a49f5df authored by Chris Göllner's avatar Chris Göllner Committed by Android (Google) Code Review
Browse files

Merge changes from topic "pdcd" into main

* changes:
  Create Collection extension function `containsExactly`
  Extract privacy dot corner logic into a shared enum
  Provide ScreenDecorations Executor via Dagger
  DisplayWindowProperties: add layout inflater
parents 049a148a 261bbcfa
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.display.data.repository
import android.content.testableContext
import android.platform.test.annotations.EnableFlags
import android.view.Display
import android.view.layoutInflater
import android.view.mockWindowManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -49,14 +50,18 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {

    private val applicationContext = kosmos.testableContext
    private val applicationWindowManager = kosmos.mockWindowManager
    private val applicationLayoutInflater = kosmos.layoutInflater

    private val repo =
    // Lazy so that @EnableFlags has time to run before this repo is instantiated
    private val repo by lazy {
        DisplayWindowPropertiesRepositoryImpl(
            kosmos.applicationCoroutineScope,
            applicationContext,
            applicationWindowManager,
            kosmos.layoutInflater,
            fakeDisplayRepository,
        )
    }

    @Before
    fun start() {
@@ -81,6 +86,7 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {
                        windowType = WINDOW_TYPE_FOO,
                        context = applicationContext,
                        windowManager = applicationWindowManager,
                        layoutInflater = applicationLayoutInflater,
                    )
                )
        }
@@ -101,6 +107,14 @@ class DisplayWindowPropertiesRepositoryImplTest : SysuiTestCase() {
            assertThat(displayContext.windowManager).isNotSameInstanceAs(applicationWindowManager)
        }

    @Test
    fun get_nonDefaultDisplayId_returnsNewLayoutInflater() =
        testScope.runTest {
            val displayContext = repo.get(NON_DEFAULT_DISPLAY_ID, WINDOW_TYPE_FOO)

            assertThat(displayContext.layoutInflater).isNotSameInstanceAs(applicationLayoutInflater)
        }

    @Test
    fun get_multipleCallsForDefaultDisplay_returnsSameInstance() =
        testScope.runTest {
+21 −17
Original line number Diff line number Diff line
@@ -29,6 +29,10 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.res.R
import com.android.systemui.statusbar.FakeStatusBarStateController
import com.android.systemui.statusbar.events.PrivacyDotCorner.BottomLeft
import com.android.systemui.statusbar.events.PrivacyDotCorner.BottomRight
import com.android.systemui.statusbar.events.PrivacyDotCorner.TopLeft
import com.android.systemui.statusbar.events.PrivacyDotCorner.TopRight
import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider
import com.android.systemui.statusbar.policy.FakeConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor
@@ -78,8 +82,8 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
            contentInsetsProvider,
            animationScheduler = mock<SystemStatusAnimationScheduler>(),
            shadeInteractor = null,
            uiExecutor = executor,
        )
            .also { it.setUiExecutor(executor) }

    @Test
    fun topMargin_topLeftView_basedOnSeascapeArea() {
@@ -215,7 +219,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {

        val controller = createAndInitializeController()

        assertThat(controller.currentViewState.cornerIndex).isEqualTo(TOP_RIGHT)
        assertThat(controller.currentViewState.corner).isEqualTo(TopRight)
        assertThat(controller.currentViewState.designatedCorner).isEqualTo(topRightView)
    }

@@ -225,7 +229,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {

        val controller = createAndInitializeController()

        assertThat(controller.currentViewState.cornerIndex).isEqualTo(BOTTOM_RIGHT)
        assertThat(controller.currentViewState.corner).isEqualTo(BottomRight)
        assertThat(controller.currentViewState.designatedCorner).isEqualTo(bottomRightView)
    }

@@ -235,7 +239,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {

        val controller = createAndInitializeController()

        assertThat(controller.currentViewState.cornerIndex).isEqualTo(TOP_LEFT)
        assertThat(controller.currentViewState.corner).isEqualTo(TopLeft)
        assertThat(controller.currentViewState.designatedCorner).isEqualTo(topLeftView)
    }

@@ -245,7 +249,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {

        val controller = createAndInitializeController()

        assertThat(controller.currentViewState.cornerIndex).isEqualTo(BOTTOM_LEFT)
        assertThat(controller.currentViewState.corner).isEqualTo(BottomLeft)
        assertThat(controller.currentViewState.designatedCorner).isEqualTo(bottomLeftView)
    }

@@ -256,7 +260,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
        enableRtl()
        val controller = createAndInitializeController()

        assertThat(controller.currentViewState.cornerIndex).isEqualTo(TOP_LEFT)
        assertThat(controller.currentViewState.corner).isEqualTo(TopLeft)
        assertThat(controller.currentViewState.designatedCorner).isEqualTo(topLeftView)
    }

@@ -267,7 +271,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
        enableRtl()
        val controller = createAndInitializeController()

        assertThat(controller.currentViewState.cornerIndex).isEqualTo(TOP_RIGHT)
        assertThat(controller.currentViewState.corner).isEqualTo(TopRight)
        assertThat(controller.currentViewState.designatedCorner).isEqualTo(topRightView)
    }

@@ -278,7 +282,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
        enableRtl()
        val controller = createAndInitializeController()

        assertThat(controller.currentViewState.cornerIndex).isEqualTo(BOTTOM_LEFT)
        assertThat(controller.currentViewState.corner).isEqualTo(BottomLeft)
        assertThat(controller.currentViewState.designatedCorner).isEqualTo(bottomLeftView)
    }

@@ -289,7 +293,7 @@ class PrivacyDotViewControllerTest : SysuiTestCase() {
        enableRtl()
        val controller = createAndInitializeController()

        assertThat(controller.currentViewState.cornerIndex).isEqualTo(BOTTOM_RIGHT)
        assertThat(controller.currentViewState.corner).isEqualTo(BottomRight)
        assertThat(controller.currentViewState.designatedCorner).isEqualTo(bottomRightView)
    }

+64 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.util

import androidx.test.ext.junit.runners.AndroidJUnit4
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(AndroidJUnit4::class)
class ConvenienceExtensionsKtTest : SysuiTestCase() {

    @Test
    fun containsExactly_notDuplicatedElements_allSame_returnsTrue() {
        val list = listOf(1, 2, 3)

        assertThat(list.containsExactly(2, 1, 3)).isTrue()
    }

    @Test
    fun containsExactly_duplicatedElements_allSame_returnsTrue() {
        val list = listOf(1, 1, 2, 3, 3)

        assertThat(list.containsExactly(1, 1, 2, 3, 3)).isTrue()
    }

    @Test
    fun containsExactly_duplicatedElements_sameButNotDuplicated_returnsFalse() {
        val list = listOf(1, 1, 2, 3, 3)

        assertThat(list.containsExactly(1, 2, 3)).isFalse()
    }

    @Test
    fun containsExactly_duplicatedElements_sameButNotSameAmount_returnsFalse() {
        val list = listOf(1, 1, 2, 3, 3)

        assertThat(list.containsExactly(1, 2, 2, 3, 3)).isFalse()
    }

    @Test
    fun eachCountMap_returnsExpectedCount() {
        val list = listOf(1, 3, 1, 3, 3, 3, 2)

        assertThat(list.eachCountMap()).isEqualTo(mapOf(1 to 2, 2 to 1, 3 to 4))
    }
}
+7 −10
Original line number Diff line number Diff line
@@ -92,7 +92,6 @@ import com.android.systemui.statusbar.commandline.CommandRegistry;
import com.android.systemui.statusbar.events.PrivacyDotViewController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.ThreadFactory;
import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.util.settings.SecureSettings;

@@ -147,7 +146,6 @@ public class ScreenDecorations implements
    private CameraAvailabilityListener mCameraListener;
    private final UserTracker mUserTracker;
    private final PrivacyDotViewController mDotViewController;
    private final ThreadFactory mThreadFactory;
    private final DecorProviderFactory mDotFactory;
    private final FaceScanningProviderFactory mFaceScanningFactory;
    private final CameraProtectionLoader mCameraProtectionLoader;
@@ -172,7 +170,6 @@ public class ScreenDecorations implements
    private ViewCaptureAwareWindowManager mWindowManager;
    private int mRotation;
    private UserSettingObserver mColorInversionSetting;
    @Nullable
    private DelayableExecutor mExecutor;
    private Handler mHandler;
    boolean mPendingConfigChange;
@@ -327,27 +324,28 @@ public class ScreenDecorations implements
    }

    @Inject
    public ScreenDecorations(Context context,
    public ScreenDecorations(
            Context context,
            SecureSettings secureSettings,
            CommandRegistry commandRegistry,
            UserTracker userTracker,
            DisplayTracker displayTracker,
            PrivacyDotViewController dotViewController,
            ThreadFactory threadFactory,
            PrivacyDotDecorProviderFactory dotFactory,
            FaceScanningProviderFactory faceScanningFactory,
            ScreenDecorationsLogger logger,
            FacePropertyRepository facePropertyRepository,
            JavaAdapter javaAdapter,
            CameraProtectionLoader cameraProtectionLoader,
            ViewCaptureAwareWindowManager viewCaptureAwareWindowManager) {
            ViewCaptureAwareWindowManager viewCaptureAwareWindowManager,
            @ScreenDecorationsThread Handler handler,
            @ScreenDecorationsThread DelayableExecutor executor) {
        mContext = context;
        mSecureSettings = secureSettings;
        mCommandRegistry = commandRegistry;
        mUserTracker = userTracker;
        mDisplayTracker = displayTracker;
        mDotViewController = dotViewController;
        mThreadFactory = threadFactory;
        mDotFactory = dotFactory;
        mFaceScanningFactory = faceScanningFactory;
        mCameraProtectionLoader = cameraProtectionLoader;
@@ -356,6 +354,8 @@ public class ScreenDecorations implements
        mFacePropertyRepository = facePropertyRepository;
        mJavaAdapter = javaAdapter;
        mWindowManager = viewCaptureAwareWindowManager;
        mHandler = handler;
        mExecutor = executor;
    }

    private final ScreenDecorCommand.Callback mScreenDecorCommandCallback = (cmd, pw) -> {
@@ -403,10 +403,7 @@ public class ScreenDecorations implements
            Log.i(TAG, "ScreenDecorations is disabled");
            return;
        }
        mHandler = mThreadFactory.buildHandlerOnNewThread("ScreenDecorations");
        mExecutor = mThreadFactory.buildDelayableExecutorOnHandler(mHandler);
        mExecutor.execute(this::startOnScreenDecorationsThread);
        mDotViewController.setUiExecutor(mExecutor);
        mCommandRegistry.registerCommand(ScreenDecorCommand.SCREEN_DECOR_CMD_NAME,
                () -> new ScreenDecorCommand(mScreenDecorCommandCallback));
    }
+30 −0
Original line number Diff line number Diff line
@@ -17,16 +17,23 @@
package com.android.systemui

import android.content.Context
import android.os.Handler
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.decor.FaceScanningProviderFactory
import com.android.systemui.decor.FaceScanningProviderFactoryImpl
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.concurrency.ThreadFactory
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import dagger.multibindings.IntoSet
import java.util.concurrent.Executor
import javax.inject.Qualifier

@Qualifier annotation class ScreenDecorationsThread

@Module
interface ScreenDecorationsModule {
@@ -41,6 +48,12 @@ interface ScreenDecorationsModule {
    @IntoSet
    fun bindScreenDecorationsConfigListener(impl: ScreenDecorations): ConfigurationListener

    @Binds
    @ScreenDecorationsThread
    fun screenDecorationsExecutor(
        @ScreenDecorationsThread delayableExecutor: DelayableExecutor
    ): Executor

    companion object {
        @Provides
        @SysUISingleton
@@ -50,5 +63,22 @@ interface ScreenDecorationsModule {
        ): FaceScanningProviderFactory {
            return creator.create(context)
        }

        @Provides
        @SysUISingleton
        @ScreenDecorationsThread
        fun screenDecorationsHandler(threadFactory: ThreadFactory): Handler {
            return threadFactory.buildHandlerOnNewThread("ScreenDecorations")
        }

        @Provides
        @SysUISingleton
        @ScreenDecorationsThread
        fun screenDecorationsDelayableExecutor(
            @ScreenDecorationsThread handler: Handler,
            threadFactory: ThreadFactory,
        ): DelayableExecutor {
            return threadFactory.buildDelayableExecutorOnHandler(handler)
        }
    }
}
Loading