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

Commit f30e1aa0 authored by Darrell Shi's avatar Darrell Shi
Browse files

Add runtime user process assersions

This change adds assertions in various classes to ensure they are
instantiated only for the expected user.

Test: verified no crashing at runtime which proves the marked classes
      are not instantiated on the headless system user
Bug: 357621815
Flag: com.android.systemui.secondary_user_widget_host

Change-Id: Ieed792011da6c7e35a2cd30242c647d006c110d9
parent 59b6c3b3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.testing.TestableLooper.RunWithLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.shared.model.fakeGlanceableHubMultiUserHelper
import com.android.systemui.communal.widgets.CommunalAppWidgetHost
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -61,6 +62,7 @@ class CommunalAppWidgetHostTest : SysuiTestCase() {
                backgroundScope = kosmos.applicationCoroutineScope,
                hostId = 116,
                logBuffer = logcatLogBuffer("CommunalAppWidgetHostTest"),
                glanceableHubMultiUserHelper = kosmos.fakeGlanceableHubMultiUserHelper,
            )
    }

+13 −50
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.shared.model.fakeGlanceableHubMultiUserHelper
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -84,7 +85,7 @@ class CommunalWidgetHostTest : SysuiTestCase() {
                    any<Int>(),
                    any<UserHandle>(),
                    any<ComponentName>(),
                    any<Bundle>()
                    any<Bundle>(),
                )
            )
            .thenReturn(true)
@@ -96,6 +97,7 @@ class CommunalWidgetHostTest : SysuiTestCase() {
                appWidgetHost,
                selectedUserInteractor,
                logcatLogBuffer("CommunalWidgetHostTest"),
                glanceableHubMultiUserHelper = kosmos.fakeGlanceableHubMultiUserHelper,
            )
    }

@@ -162,7 +164,7 @@ class CommunalWidgetHostTest : SysuiTestCase() {
                        any<Int>(),
                        any<UserHandle>(),
                        any<ComponentName>(),
                        any<Bundle>()
                        any<Bundle>(),
                    )
                )
                .thenReturn(false)
@@ -283,12 +285,7 @@ class CommunalWidgetHostTest : SysuiTestCase() {
            // all providers are emitted at once
            assertThat(providerInfoValues).hasSize(2)
            assertThat(providerInfoValues[1])
                .containsExactlyEntriesIn(
                    mapOf(
                        Pair(1, providerInfo1),
                        Pair(2, providerInfo2),
                    )
                )
                .containsExactlyEntriesIn(mapOf(Pair(1, providerInfo1), Pair(2, providerInfo2)))
        }

    @Test
@@ -304,12 +301,7 @@ class CommunalWidgetHostTest : SysuiTestCase() {
            // Assert that the provider info map is populated
            val providerInfo by collectLastValue(underTest.appWidgetProviders)
            assertThat(providerInfo)
                .containsExactlyEntriesIn(
                    mapOf(
                        Pair(1, providerInfo1),
                        Pair(2, providerInfo2),
                    )
                )
                .containsExactlyEntriesIn(mapOf(Pair(1, providerInfo1), Pair(2, providerInfo2)))

            // Host stop listening
            observer.onHostStopListening()
@@ -332,12 +324,7 @@ class CommunalWidgetHostTest : SysuiTestCase() {

            // Assert that the provider info map is populated
            assertThat(providerInfo)
                .containsExactlyEntriesIn(
                    mapOf(
                        Pair(1, providerInfo1),
                        Pair(2, providerInfo2),
                    )
                )
                .containsExactlyEntriesIn(mapOf(Pair(1, providerInfo1), Pair(2, providerInfo2)))

            // Provider info for widget 1 updated
            val listener =
@@ -349,12 +336,7 @@ class CommunalWidgetHostTest : SysuiTestCase() {

            // Assert that the update is reflected in the flow
            assertThat(providerInfo)
                .containsExactlyEntriesIn(
                    mapOf(
                        Pair(1, providerInfo3),
                        Pair(2, providerInfo2),
                    )
                )
                .containsExactlyEntriesIn(mapOf(Pair(1, providerInfo3), Pair(2, providerInfo2)))
        }

    @Test
@@ -371,12 +353,7 @@ class CommunalWidgetHostTest : SysuiTestCase() {

            // Assert that the provider info map is populated
            assertThat(providerInfo)
                .containsExactlyEntriesIn(
                    mapOf(
                        Pair(1, providerInfo1),
                        Pair(2, providerInfo2),
                    )
                )
                .containsExactlyEntriesIn(mapOf(Pair(1, providerInfo1), Pair(2, providerInfo2)))

            // Bind a new widget
            whenever(appWidgetHost.allocateAppWidgetId()).thenReturn(3)
@@ -388,11 +365,7 @@ class CommunalWidgetHostTest : SysuiTestCase() {
            // Assert that the new provider is reflected in the flow
            assertThat(providerInfo)
                .containsExactlyEntriesIn(
                    mapOf(
                        Pair(1, providerInfo1),
                        Pair(2, providerInfo2),
                        Pair(3, providerInfo3),
                    )
                    mapOf(Pair(1, providerInfo1), Pair(2, providerInfo2), Pair(3, providerInfo3))
                )
        }

@@ -410,31 +383,21 @@ class CommunalWidgetHostTest : SysuiTestCase() {

            // Assert that the provider info map is populated
            assertThat(providerInfo)
                .containsExactlyEntriesIn(
                    mapOf(
                        Pair(1, providerInfo1),
                        Pair(2, providerInfo2),
                    )
                )
                .containsExactlyEntriesIn(mapOf(Pair(1, providerInfo1), Pair(2, providerInfo2)))

            // Remove widget 1
            observer.onDeleteAppWidgetId(1)
            runCurrent()

            // Assert that provider info for widget 1 is removed
            assertThat(providerInfo)
                .containsExactlyEntriesIn(
                    mapOf(
                        Pair(2, providerInfo2),
                    )
                )
            assertThat(providerInfo).containsExactlyEntriesIn(mapOf(Pair(2, providerInfo2)))
        }

    private fun selectUser() {
        kosmos.fakeUserRepository.selectedUser.value =
            SelectedUserModel(
                userInfo = UserInfo(0, "Current user", 0),
                selectionStatus = SelectionStatus.SELECTION_COMPLETE
                selectionStatus = SelectionStatus.SELECTION_COMPLETE,
            )
    }

+8 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import androidx.activity.ComponentActivity
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.shared.model.fakeGlanceableHubMultiUserHelper
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
@@ -55,7 +56,12 @@ class WidgetConfigurationControllerTest : SysuiTestCase() {
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        underTest =
            WidgetConfigurationController(ownerActivity, appWidgetHost, kosmos.testDispatcher)
            WidgetConfigurationController(
                ownerActivity,
                { appWidgetHost },
                kosmos.testDispatcher,
                kosmos.fakeGlanceableHubMultiUserHelper,
            )
    }

    @Test
@@ -68,7 +74,7 @@ class WidgetConfigurationControllerTest : SysuiTestCase() {
                            eq(123),
                            anyInt(),
                            eq(WidgetConfigurationController.REQUEST_CODE),
                            any()
                            any(),
                        )
                    )
                    .thenThrow(ActivityNotFoundException())
+7 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.communal.data.db

import android.content.Context
import android.os.Process
import android.util.Log
import androidx.annotation.VisibleForTesting
import androidx.room.Database
@@ -24,6 +25,7 @@ import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.android.systemui.communal.shared.model.GlanceableHubMultiUserHelperImpl
import com.android.systemui.res.R

@Database(entities = [CommunalWidgetItem::class, CommunalItemRank::class], version = 4)
@@ -44,6 +46,11 @@ abstract class CommunalDatabase : RoomDatabase() {
         *   new instance is created.
         */
        fun getInstance(context: Context, callback: Callback? = null): CommunalDatabase {
            with(GlanceableHubMultiUserHelperImpl(Process.myUserHandle())) {
                // Assert that the database is never accessed from a headless system user.
                assertNotInHeadlessSystemUser()
            }

            if (instance == null) {
                instance =
                    Room.databaseBuilder(
+0 −3
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import com.android.systemui.communal.shared.model.CommunalContentSize.THIRD
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
import com.android.systemui.communal.shared.model.EditModeState
import com.android.systemui.communal.widgets.CommunalAppWidgetHost
import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
import com.android.systemui.communal.widgets.WidgetConfigurator
import com.android.systemui.dagger.SysUISingleton
@@ -108,7 +107,6 @@ constructor(
    keyguardInteractor: KeyguardInteractor,
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
    communalSettingsInteractor: CommunalSettingsInteractor,
    private val appWidgetHost: CommunalAppWidgetHost,
    private val editWidgetsActivityStarter: EditWidgetsActivityStarter,
    private val userTracker: UserTracker,
    private val activityStarter: ActivityStarter,
@@ -451,7 +449,6 @@ constructor(
                            appWidgetId = widget.appWidgetId,
                            rank = widget.rank,
                            providerInfo = widget.providerInfo,
                            appWidgetHost = appWidgetHost,
                            inQuietMode = isQuietModeEnabled(widget.providerInfo.profile),
                            size = CommunalContentSize.toSize(widget.spanY),
                        )
Loading