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

Commit b2cae00a authored by Ben Fennema's avatar Ben Fennema Committed by Automerger Merge Worker
Browse files

Merge "Revert "Check keyguard policy before launching note shortcut at lock...

Merge "Revert "Check keyguard policy before launching note shortcut at lock screen"" into udc-dev am: ab677c71

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21545818



Change-Id: I9f2b8b5befec67b14606128f5a3d9e26203e9e1e
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents c84c414a ab677c71
Loading
Loading
Loading
Loading
+0 −32
Original line number Original line Diff line number Diff line
/*
 * 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.devicepolicy

import android.app.admin.DevicePolicyManager
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL
import android.content.ComponentName

/** Returns true if the admin of [userId] disallows keyguard shortcuts. */
fun DevicePolicyManager.areKeyguardShortcutsDisabled(
    admin: ComponentName? = null,
    userId: Int
): Boolean {
    val flags = getKeyguardDisabledFeatures(admin, userId)
    return flags and KEYGUARD_DISABLE_SHORTCUTS_ALL == KEYGUARD_DISABLE_SHORTCUTS_ALL ||
        flags and KEYGUARD_DISABLE_FEATURES_ALL == KEYGUARD_DISABLE_FEATURES_ALL
}
+10 −5
Original line number Original line Diff line number Diff line
@@ -26,7 +26,6 @@ import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.animation.Expandable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
@@ -411,9 +410,15 @@ constructor(
        )
        )
    }
    }


    private suspend fun isFeatureDisabledByDevicePolicy(): Boolean =
    private suspend fun isFeatureDisabledByDevicePolicy(): Boolean {
        val flags =
            withContext(backgroundDispatcher) {
            withContext(backgroundDispatcher) {
            devicePolicyManager.areKeyguardShortcutsDisabled(userId = userTracker.userId)
                devicePolicyManager.getKeyguardDisabledFeatures(null, userTracker.userId)
            }
        val flagsToCheck =
            DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL or
                DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL
        return flagsToCheck and flags != 0
    }
    }


    companion object {
    companion object {
+2 −26
Original line number Original line Diff line number Diff line
@@ -17,21 +17,17 @@
package com.android.systemui.notetask
package com.android.systemui.notetask


import android.app.KeyguardManager
import android.app.KeyguardManager
import android.app.admin.DevicePolicyManager
import android.content.ActivityNotFoundException
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.ComponentName
import android.content.Context
import android.content.Context
import android.content.Intent
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.PackageManager
import android.os.Build
import android.os.UserManager
import android.os.UserManager
import android.util.Log
import android.util.Log
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.internal.logging.UiEventLogger
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.kotlin.getOrNull
import com.android.systemui.util.kotlin.getOrNull
import com.android.wm.shell.bubbles.Bubbles
import com.android.wm.shell.bubbles.Bubbles
import java.util.Optional
import java.util.Optional
@@ -53,10 +49,8 @@ constructor(
    private val optionalBubbles: Optional<Bubbles>,
    private val optionalBubbles: Optional<Bubbles>,
    private val optionalKeyguardManager: Optional<KeyguardManager>,
    private val optionalKeyguardManager: Optional<KeyguardManager>,
    private val optionalUserManager: Optional<UserManager>,
    private val optionalUserManager: Optional<UserManager>,
    private val devicePolicyManager: DevicePolicyManager,
    @NoteTaskEnabledKey private val isEnabled: Boolean,
    @NoteTaskEnabledKey private val isEnabled: Boolean,
    private val uiEventLogger: UiEventLogger,
    private val uiEventLogger: UiEventLogger,
    private val userTracker: UserTracker,
) {
) {


    /**
    /**
@@ -86,18 +80,6 @@ constructor(
        // TODO(b/249954038): We should handle direct boot (isUserUnlocked). For now, we do nothing.
        // TODO(b/249954038): We should handle direct boot (isUserUnlocked). For now, we do nothing.
        if (!userManager.isUserUnlocked) return
        if (!userManager.isUserUnlocked) return


        val isKeyguardLocked = keyguardManager.isKeyguardLocked
        // KeyguardQuickAffordanceInteractor blocks the quick affordance from showing in the
        // keyguard if it is not allowed by the admin policy. Here we block any other way to show
        // note task when the screen is locked.
        if (
            isKeyguardLocked &&
                devicePolicyManager.areKeyguardShortcutsDisabled(userId = userTracker.userId)
        ) {
            logDebug { "Enterprise policy disallows launching note app when the screen is locked." }
            return
        }

        val noteTaskInfo = resolver.resolveInfo() ?: return
        val noteTaskInfo = resolver.resolveInfo() ?: return


        uiEvent?.let { uiEventLogger.log(it, noteTaskInfo.uid, noteTaskInfo.packageName) }
        uiEvent?.let { uiEventLogger.log(it, noteTaskInfo.uid, noteTaskInfo.packageName) }
@@ -105,7 +87,7 @@ constructor(
        // TODO(b/266686199): We should handle when app not available. For now, we log.
        // TODO(b/266686199): We should handle when app not available. For now, we log.
        val intent = noteTaskInfo.toCreateNoteIntent()
        val intent = noteTaskInfo.toCreateNoteIntent()
        try {
        try {
            if (isInMultiWindowMode || isKeyguardLocked) {
            if (isInMultiWindowMode || keyguardManager.isKeyguardLocked) {
                context.startActivity(intent)
                context.startActivity(intent)
            } else {
            } else {
                bubbles.showOrHideAppBubble(intent)
                bubbles.showOrHideAppBubble(intent)
@@ -162,7 +144,7 @@ constructor(
    }
    }


    companion object {
    companion object {
        val TAG = NoteTaskController::class.simpleName.orEmpty()
        private val TAG = NoteTaskController::class.simpleName.orEmpty()


        private fun NoteTaskInfoResolver.NoteTaskInfo.toCreateNoteIntent(): Intent {
        private fun NoteTaskInfoResolver.NoteTaskInfo.toCreateNoteIntent(): Intent {
            return Intent(ACTION_CREATE_NOTE)
            return Intent(ACTION_CREATE_NOTE)
@@ -183,9 +165,3 @@ constructor(
        const val INTENT_EXTRA_USE_STYLUS_MODE = "android.intent.extra.USE_STYLUS_MODE"
        const val INTENT_EXTRA_USE_STYLUS_MODE = "android.intent.extra.USE_STYLUS_MODE"
    }
    }
}
}

private inline fun logDebug(message: () -> String) {
    if (Build.IS_DEBUGGABLE) {
        Log.d(NoteTaskController.TAG, message())
    }
}
+0 −93
Original line number Original line Diff line number Diff line
/*
 * 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.devicepolicy

import android.app.admin.DevicePolicyManager
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FACE
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA
import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL
import androidx.test.filters.SmallTest
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.MockitoAnnotations

@SmallTest
@RunWith(JUnit4::class)
class DevicePolicyManagerExtTest {

    @Mock lateinit var devicePolicyManager: DevicePolicyManager
    @Mock private lateinit var userTracker: UserTracker

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)

        whenever(userTracker.userId).thenReturn(CURRENT_USER_ID)
    }

    // region areKeyguardShortcutsDisabled
    @Test
    fun areKeyguardShortcutsDisabled_noDisabledKeyguardFeature_shouldReturnFalse() {
        whenever(devicePolicyManager.getKeyguardDisabledFeatures(eq(null), anyInt()))
            .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE)

        assertThat(devicePolicyManager.areKeyguardShortcutsDisabled(userId = CURRENT_USER_ID))
            .isFalse()
    }

    @Test
    fun areKeyguardShortcutsDisabled_otherDisabledKeyguardFeatures_shouldReturnFalse() {
        whenever(devicePolicyManager.getKeyguardDisabledFeatures(eq(null), anyInt()))
            .thenReturn(KEYGUARD_DISABLE_SECURE_CAMERA or KEYGUARD_DISABLE_FACE)

        assertThat(devicePolicyManager.areKeyguardShortcutsDisabled(userId = CURRENT_USER_ID))
            .isFalse()
    }

    @Test
    fun areKeyguardShortcutsDisabled_disabledShortcutsKeyguardFeature_shouldReturnTrue() {
        whenever(devicePolicyManager.getKeyguardDisabledFeatures(eq(null), anyInt()))
            .thenReturn(KEYGUARD_DISABLE_SHORTCUTS_ALL)

        assertThat(devicePolicyManager.areKeyguardShortcutsDisabled(userId = CURRENT_USER_ID))
            .isTrue()
    }

    @Test
    fun areKeyguardShortcutsDisabled_disabledAllKeyguardFeatures_shouldReturnTrue() {
        whenever(devicePolicyManager.getKeyguardDisabledFeatures(eq(null), anyInt()))
            .thenReturn(KEYGUARD_DISABLE_FEATURES_ALL)

        assertThat(devicePolicyManager.areKeyguardShortcutsDisabled(userId = CURRENT_USER_ID))
            .isTrue()
    }
    // endregion

    private companion object {
        const val CURRENT_USER_ID = 123
    }
}
+0 −94
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@
package com.android.systemui.notetask
package com.android.systemui.notetask


import android.app.KeyguardManager
import android.app.KeyguardManager
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.ComponentName
import android.content.Context
import android.content.Context
import android.content.Intent
import android.content.Intent
@@ -30,7 +29,6 @@ import com.android.systemui.notetask.NoteTaskController.Companion.INTENT_EXTRA_U
import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent
import com.android.systemui.notetask.NoteTaskController.ShowNoteTaskUiEvent
import com.android.systemui.notetask.NoteTaskInfoResolver.NoteTaskInfo
import com.android.systemui.notetask.NoteTaskInfoResolver.NoteTaskInfo
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.eq
@@ -41,7 +39,6 @@ import java.util.Optional
import org.junit.Before
import org.junit.Before
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.Mockito.verifyZeroInteractions
@@ -67,8 +64,6 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
    @Mock lateinit var optionalUserManager: Optional<UserManager>
    @Mock lateinit var optionalUserManager: Optional<UserManager>
    @Mock lateinit var userManager: UserManager
    @Mock lateinit var userManager: UserManager
    @Mock lateinit var uiEventLogger: UiEventLogger
    @Mock lateinit var uiEventLogger: UiEventLogger
    @Mock private lateinit var userTracker: UserTracker
    @Mock private lateinit var devicePolicyManager: DevicePolicyManager


    @Before
    @Before
    fun setUp() {
    fun setUp() {
@@ -80,13 +75,6 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
        whenever(optionalKeyguardManager.orElse(null)).thenReturn(keyguardManager)
        whenever(optionalKeyguardManager.orElse(null)).thenReturn(keyguardManager)
        whenever(optionalUserManager.orElse(null)).thenReturn(userManager)
        whenever(optionalUserManager.orElse(null)).thenReturn(userManager)
        whenever(userManager.isUserUnlocked).thenReturn(true)
        whenever(userManager.isUserUnlocked).thenReturn(true)
        whenever(
                devicePolicyManager.getKeyguardDisabledFeatures(
                    /* admin= */ eq(null),
                    /* userHandle= */ anyInt()
                )
            )
            .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE)
    }
    }


    private fun createNoteTaskController(isEnabled: Boolean = true): NoteTaskController {
    private fun createNoteTaskController(isEnabled: Boolean = true): NoteTaskController {
@@ -96,10 +84,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
            optionalBubbles = optionalBubbles,
            optionalBubbles = optionalBubbles,
            optionalKeyguardManager = optionalKeyguardManager,
            optionalKeyguardManager = optionalKeyguardManager,
            optionalUserManager = optionalUserManager,
            optionalUserManager = optionalUserManager,
            devicePolicyManager = devicePolicyManager,
            isEnabled = isEnabled,
            isEnabled = isEnabled,
            uiEventLogger = uiEventLogger,
            uiEventLogger = uiEventLogger,
            userTracker = userTracker,
        )
        )
    }
    }


@@ -305,86 +291,6 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
    }
    }
    // endregion
    // endregion


    // region keyguard policy
    @Test
    fun showNoteTask_keyguardLocked_keyguardDisableShortcutsAll_shouldDoNothing() {
        whenever(keyguardManager.isKeyguardLocked).thenReturn(true)
        whenever(
                devicePolicyManager.getKeyguardDisabledFeatures(
                    /* admin= */ eq(null),
                    /* userHandle= */ anyInt()
                )
            )
            .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)

        createNoteTaskController().showNoteTask(isInMultiWindowMode = false, uiEvent = null)

        verifyZeroInteractions(context, bubbles, uiEventLogger)
    }

    @Test
    fun showNoteTask_keyguardLocked_keyguardDisableFeaturesAll_shouldDoNothing() {
        whenever(keyguardManager.isKeyguardLocked).thenReturn(true)
        whenever(
                devicePolicyManager.getKeyguardDisabledFeatures(
                    /* admin= */ eq(null),
                    /* userHandle= */ anyInt()
                )
            )
            .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)

        createNoteTaskController().showNoteTask(isInMultiWindowMode = false, uiEvent = null)

        verifyZeroInteractions(context, bubbles, uiEventLogger)
    }

    @Test
    fun showNoteTask_keyguardUnlocked_keyguardDisableShortcutsAll_shouldStartBubble() {
        whenever(keyguardManager.isKeyguardLocked).thenReturn(false)
        whenever(
                devicePolicyManager.getKeyguardDisabledFeatures(
                    /* admin= */ eq(null),
                    /* userHandle= */ anyInt()
                )
            )
            .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)

        createNoteTaskController().showNoteTask(isInMultiWindowMode = false, uiEvent = null)

        val intentCaptor = argumentCaptor<Intent>()
        verify(bubbles).showOrHideAppBubble(capture(intentCaptor))
        intentCaptor.value.let { intent ->
            assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE)
            assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
            assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK)
            assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue()
        }
    }

    @Test
    fun showNoteTask_keyguardUnlocked_keyguardDisableFeaturesAll_shouldStartBubble() {
        whenever(keyguardManager.isKeyguardLocked).thenReturn(false)
        whenever(
                devicePolicyManager.getKeyguardDisabledFeatures(
                    /* admin= */ eq(null),
                    /* userHandle= */ anyInt()
                )
            )
            .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)

        createNoteTaskController().showNoteTask(isInMultiWindowMode = false, uiEvent = null)

        val intentCaptor = argumentCaptor<Intent>()
        verify(bubbles).showOrHideAppBubble(capture(intentCaptor))
        intentCaptor.value.let { intent ->
            assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE)
            assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
            assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK)
            assertThat(intent.getBooleanExtra(INTENT_EXTRA_USE_STYLUS_MODE, false)).isTrue()
        }
    }
    // endregion

    private companion object {
    private companion object {
        const val NOTES_PACKAGE_NAME = "com.android.note.app"
        const val NOTES_PACKAGE_NAME = "com.android.note.app"
        const val NOTES_UID = 123456
        const val NOTES_UID = 123456