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

Commit 3cc5bf6c authored by Aaron Liu's avatar Aaron Liu
Browse files

Home Controls: Add Device Controls settings

Add a KEY for the settings and apply the associated business logic.

Fixes: 216102581
Test: Manual
Change-Id: Ic66cd0a865044c602bf7f5364abd726e445c9386
parent 455a973d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -9949,6 +9949,14 @@ public final class Settings {
         */
        public static final String LOCKSCREEN_SHOW_CONTROLS = "lockscreen_show_controls";
        /**
         * Whether trivial home controls can be used without authentication
         *
         * @hide
         */
        public static final String LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS =
                "lockscreen_allow_trivial_controls";
        /**
         * Whether wallet should be accessible from the lockscreen
         *
+1 −0
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ public class SecureSettings {
        Settings.Secure.NOTIFICATION_BUBBLES,
        Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
        Settings.Secure.LOCKSCREEN_SHOW_CONTROLS,
        Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS,
        Settings.Secure.LOCKSCREEN_SHOW_WALLET,
        Settings.Secure.LOCK_SCREEN_SHOW_QR_CODE_SCANNER,
        Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
+1 −0
Original line number Diff line number Diff line
@@ -152,6 +152,7 @@ public class SecureSettingsValidators {
        VALIDATORS.put(Secure.CONTROLS_ENABLED, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.POWER_MENU_LOCKED_SHOW_CONTENT, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.LOCKSCREEN_SHOW_CONTROLS, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.LOCKSCREEN_SHOW_WALLET, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_QR_CODE_SCANNER, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, BOOLEAN_VALIDATOR);
+37 −6
Original line number Diff line number Diff line
@@ -23,7 +23,11 @@ import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.os.VibrationEffect
import android.provider.Settings
import android.service.controls.Control
import android.service.controls.actions.BooleanAction
import android.service.controls.actions.CommandAction
@@ -38,6 +42,7 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.settings.SecureSettings
import com.android.wm.shell.TaskViewFactory
import java.util.Optional
import javax.inject.Inject
@@ -51,19 +56,41 @@ class ControlActionCoordinatorImpl @Inject constructor(
    private val keyguardStateController: KeyguardStateController,
    private val taskViewFactory: Optional<TaskViewFactory>,
    private val controlsMetricsLogger: ControlsMetricsLogger,
    private val vibrator: VibratorHelper
    private val vibrator: VibratorHelper,
    private val secureSettings: SecureSettings,
    @Main mainHandler: Handler
) : ControlActionCoordinator {
    private var dialog: Dialog? = null
    private var pendingAction: Action? = null
    private var actionsInProgress = mutableSetOf<String>()
    private val isLocked: Boolean
        get() = !keyguardStateController.isUnlocked()
    private var mAllowTrivialControls: Boolean = secureSettings.getInt(
            Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
    override lateinit var activityContext: Context

    companion object {
        private const val RESPONSE_TIMEOUT_IN_MILLIS = 3000L
    }

    init {
        val lockScreenShowControlsUri =
            secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS)
        val controlsContentObserver = object : ContentObserver(mainHandler) {
            override fun onChange(selfChange: Boolean, uri: Uri?) {
                super.onChange(selfChange, uri)
                if (uri == lockScreenShowControlsUri) {
                    mAllowTrivialControls = secureSettings.getInt(
                            Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
                }
            }
        }
        secureSettings.registerContentObserver(
            lockScreenShowControlsUri,
            false /* notifyForDescendants */, controlsContentObserver
        )
    }

    override fun closeDialogs() {
        dialog?.dismiss()
        dialog = null
@@ -80,7 +107,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
                },
                true /* blockable */
            ),
            isAuthRequired(cvh)
            isAuthRequired(cvh, mAllowTrivialControls)
        )
    }

@@ -100,7 +127,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
                },
                blockable
            ),
            isAuthRequired(cvh)
            isAuthRequired(cvh, mAllowTrivialControls)
        )
    }

@@ -120,7 +147,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
                { cvh.action(FloatAction(templateId, newValue)) },
                false /* blockable */
            ),
            isAuthRequired(cvh)
            isAuthRequired(cvh, mAllowTrivialControls)
        )
    }

@@ -139,7 +166,7 @@ class ControlActionCoordinatorImpl @Inject constructor(
                },
                false /* blockable */
            ),
            isAuthRequired(cvh)
            isAuthRequired(cvh, mAllowTrivialControls)
        )
    }

@@ -156,7 +183,11 @@ class ControlActionCoordinatorImpl @Inject constructor(
        actionsInProgress.remove(controlId)
    }

    private fun isAuthRequired(cvh: ControlViewHolder) = cvh.cws.control?.isAuthRequired() ?: true
    @VisibleForTesting()
    fun isAuthRequired(cvh: ControlViewHolder, allowTrivialControls: Boolean): Boolean {
        val isAuthRequired = cvh.cws.control?.isAuthRequired ?: true
        return isAuthRequired || !allowTrivialControls
    }

    private fun shouldRunAction(controlId: String) =
        if (actionsInProgress.add(controlId)) {
+43 −12
Original line number Diff line number Diff line
@@ -16,15 +16,22 @@

package com.android.systemui.controls.ui

import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.provider.Settings
import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.ControlsMetricsLogger
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.settings.SecureSettings
import com.android.wm.shell.TaskViewFactory
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -44,7 +51,6 @@ import java.util.Optional
@SmallTest
@RunWith(AndroidTestingRunner::class)
class ControlActionCoordinatorImplTest : SysuiTestCase() {

    @Mock
    private lateinit var vibratorHelper: VibratorHelper
    @Mock
@@ -61,6 +67,10 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
    private lateinit var cvh: ControlViewHolder
    @Mock
    private lateinit var metricsLogger: ControlsMetricsLogger
    @Mock
    private lateinit var secureSettings: SecureSettings
    @Mock
    private lateinit var mainHandler: Handler

    companion object {
        fun <T> any(): T = Mockito.any<T>()
@@ -75,6 +85,10 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
    fun setUp() {
        MockitoAnnotations.initMocks(this)

        `when`(secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))
                .thenReturn(Settings.Secure
                        .getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))

        coordinator = spy(ControlActionCoordinatorImpl(
                mContext,
                bgExecutor,
@@ -83,8 +97,12 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
                keyguardStateController,
                taskViewFactory,
                metricsLogger,
            vibratorHelper
        ))
                vibratorHelper,
                secureSettings,
                mainHandler))

        verify(secureSettings).registerContentObserver(any(Uri::class.java),
                anyBoolean(), any(ContentObserver::class.java))

        `when`(cvh.cws.ci.controlId).thenReturn(ID)
        `when`(cvh.cws.control?.isAuthRequired()).thenReturn(true)
@@ -126,10 +144,23 @@ class ControlActionCoordinatorImplTest : SysuiTestCase() {
    fun testToggleRunsWhenLockedAndAuthNotRequired() {
        `when`(keyguardStateController.isShowing()).thenReturn(true)
        `when`(keyguardStateController.isUnlocked()).thenReturn(false)
        `when`(cvh.cws.control?.isAuthRequired()).thenReturn(false)
        doReturn(false).`when`(coordinator).isAuthRequired(
                any(), anyBoolean())

        coordinator.toggle(cvh, "", true)

        verify(coordinator).bouncerOrRun(action, false /* authRequired */)
        verify(action).invoke()
    }

    @Test
    fun testIsAuthRequired() {
        `when`(cvh.cws.control?.isAuthRequired).thenReturn(true)
        assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()

        `when`(cvh.cws.control?.isAuthRequired).thenReturn(false)
        assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()

        assertThat(coordinator.isAuthRequired(cvh, true)).isFalse()
    }
}