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

This commit is contained in:
Ben Fennema
2023-02-23 02:05:48 +00:00
committed by Android (Google) Code Review
5 changed files with 12 additions and 250 deletions

View File

@@ -1,32 +0,0 @@
/*
* 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
}

View File

@@ -26,7 +26,6 @@ import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.animation.Expandable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
@@ -411,10 +410,16 @@ constructor(
)
}
private suspend fun isFeatureDisabledByDevicePolicy(): Boolean =
withContext(backgroundDispatcher) {
devicePolicyManager.areKeyguardShortcutsDisabled(userId = userTracker.userId)
}
private suspend fun isFeatureDisabledByDevicePolicy(): Boolean {
val flags =
withContext(backgroundDispatcher) {
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 {
private const val TAG = "KeyguardQuickAffordanceInteractor"

View File

@@ -17,21 +17,17 @@
package com.android.systemui.notetask
import android.app.KeyguardManager
import android.app.admin.DevicePolicyManager
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.UserManager
import android.util.Log
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.kotlin.getOrNull
import com.android.wm.shell.bubbles.Bubbles
import java.util.Optional
@@ -53,10 +49,8 @@ constructor(
private val optionalBubbles: Optional<Bubbles>,
private val optionalKeyguardManager: Optional<KeyguardManager>,
private val optionalUserManager: Optional<UserManager>,
private val devicePolicyManager: DevicePolicyManager,
@NoteTaskEnabledKey private val isEnabled: Boolean,
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.
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
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.
val intent = noteTaskInfo.toCreateNoteIntent()
try {
if (isInMultiWindowMode || isKeyguardLocked) {
if (isInMultiWindowMode || keyguardManager.isKeyguardLocked) {
context.startActivity(intent)
} else {
bubbles.showOrHideAppBubble(intent)
@@ -162,7 +144,7 @@ constructor(
}
companion object {
val TAG = NoteTaskController::class.simpleName.orEmpty()
private val TAG = NoteTaskController::class.simpleName.orEmpty()
private fun NoteTaskInfoResolver.NoteTaskInfo.toCreateNoteIntent(): Intent {
return Intent(ACTION_CREATE_NOTE)
@@ -183,9 +165,3 @@ constructor(
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())
}
}

View File

@@ -1,93 +0,0 @@
/*
* 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
}
}

View File

@@ -16,7 +16,6 @@
package com.android.systemui.notetask
import android.app.KeyguardManager
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
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.NoteTaskInfoResolver.NoteTaskInfo
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.capture
import com.android.systemui.util.mockito.eq
@@ -41,7 +39,6 @@ import java.util.Optional
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
@@ -67,8 +64,6 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Mock lateinit var optionalUserManager: Optional<UserManager>
@Mock lateinit var userManager: UserManager
@Mock lateinit var uiEventLogger: UiEventLogger
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var devicePolicyManager: DevicePolicyManager
@Before
fun setUp() {
@@ -80,13 +75,6 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(optionalKeyguardManager.orElse(null)).thenReturn(keyguardManager)
whenever(optionalUserManager.orElse(null)).thenReturn(userManager)
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 {
@@ -96,10 +84,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
optionalBubbles = optionalBubbles,
optionalKeyguardManager = optionalKeyguardManager,
optionalUserManager = optionalUserManager,
devicePolicyManager = devicePolicyManager,
isEnabled = isEnabled,
uiEventLogger = uiEventLogger,
userTracker = userTracker,
)
}
@@ -305,86 +291,6 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
}
// 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 {
const val NOTES_PACKAGE_NAME = "com.android.note.app"
const val NOTES_UID = 123456