Merge "feat(EvenDimmer): Add popup for removing accessibility shortcuts" into main
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index f9c2947..e8831ec 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -36,6 +36,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.ContentObserver;
@@ -63,6 +64,7 @@
import com.android.internal.R;
import com.android.internal.accessibility.dialog.AccessibilityTarget;
import com.android.internal.accessibility.util.ShortcutUtils;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.function.pooled.PooledLambda;
import java.lang.annotation.Retention;
@@ -122,6 +124,13 @@
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY)
.build();
+
+ /**
+ * An intent action to launch Extra Dim dialog.
+ */
+ @VisibleForTesting
+ static final String ACTION_LAUNCH_REMOVE_EXTRA_DIM_DIALOG =
+ "com.android.systemui.action.LAUNCH_REMOVE_EXTRA_DIM_DIALOG";
private static Map<ComponentName, FrameworkFeatureInfo> sFrameworkShortcutFeaturesMap;
private final Context mContext;
@@ -846,7 +855,7 @@
if (com.android.server.display.feature.flags.Flags.evenDimmer()
&& context.getResources().getBoolean(
com.android.internal.R.bool.config_evenDimmerEnabled)) {
- launchExtraDimDialog();
+ launchExtraDimDialog(context);
return true;
} else {
// Assuming that the default state will be to have the feature off
@@ -863,8 +872,12 @@
}
}
- private void launchExtraDimDialog() {
- // TODO: launch Extra dim dialog for feature migration
+ private void launchExtraDimDialog(Context context) {
+ final Intent intent = new Intent(ACTION_LAUNCH_REMOVE_EXTRA_DIM_DIALOG);
+ intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ intent.setPackage(
+ context.getString(com.android.internal.R.string.config_systemUi));
+ context.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
}
}
diff --git a/core/java/com/android/internal/accessibility/common/ShortcutConstants.java b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
index a3fcfad..44dceb9 100644
--- a/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
+++ b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
@@ -72,7 +72,8 @@
UserShortcutType.TRIPLETAP,
UserShortcutType.TWOFINGER_DOUBLETAP,
UserShortcutType.QUICK_SETTINGS,
- UserShortcutType.GESTURE
+ UserShortcutType.GESTURE,
+ UserShortcutType.ALL
})
public @interface UserShortcutType {
int DEFAULT = 0;
@@ -84,6 +85,7 @@
int QUICK_SETTINGS = 1 << 4;
int GESTURE = 1 << 5;
// LINT.ThenChange(:shortcut_type_array)
+ int ALL = SOFTWARE | HARDWARE | TRIPLETAP | TWOFINGER_DOUBLETAP | QUICK_SETTINGS | GESTURE;
}
/**
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 92abc4c..9f3c2bf 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -1062,6 +1062,14 @@
</intent-filter>
</receiver>
+ <receiver android:name=".accessibility.extradim.ExtraDimDialogReceiver"
+ android:singleUser="true"
+ android:exported="false">
+ <intent-filter android:priority="1">
+ <action android:name="com.android.systemui.action.LAUNCH_REMOVE_EXTRA_DIM_DIALOG" />
+ </intent-filter>
+ </receiver>
+
<activity android:name=".logcat.LogAccessDialogActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:excludeFromRecents="true"
diff --git a/packages/SystemUI/res/drawable/brightness_bar.xml b/packages/SystemUI/res/drawable/brightness_bar.xml
new file mode 100644
index 0000000..2afe164
--- /dev/null
+++ b/packages/SystemUI/res/drawable/brightness_bar.xml
@@ -0,0 +1,36 @@
+<!--
+ ~ 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ android:width="200dp"
+ android:height="32dp"
+ android:viewportWidth="304"
+ android:viewportHeight="48">
+<path
+ android:pathData="M2,22L302,22A2,2 0,0 1,304 24L304,24A2,2 0,0 1,302 26L2,26A2,2 0,0 1,0 24L0,24A2,2 0,0 1,2 22z"
+ android:fillColor="@color/brightness_slider_track"/>
+<path
+ android:pathData="M24,0L205.71,0A24,24 0,0 1,229.71 24L229.71,24A24,24 0,0 1,205.71 48L24,48A24,24 0,0 1,0 24L0,24A24,24 0,0 1,24 0z"
+ android:fillColor="?attr/shadeActive"/>
+<path
+ android:pathData="M0,24C0,10.75 10.75,0 24,0H63.85V48H24C10.75,48 0,37.25 0,24Z"
+ android:fillColor="?androidprv:attr/colorAccentPrimaryVariant"/>
+<path
+ android:pathData="M208.98,21.26V17.37H205.09L202.34,14.62L199.6,17.37H195.71V21.26L192.96,24L195.71,26.75V30.63H199.6L202.34,33.38L205.09,30.63H208.98V26.75L211.72,24L208.98,21.26ZM207.32,26.06V28.98H204.4L202.34,31.03L200.29,28.98H197.37V26.06L195.31,24L197.37,21.94V19.02H200.29L202.34,16.97L204.4,19.02H207.32V21.94L209.37,24L207.32,26.06ZM206.49,24C206.49,26.29 204.63,28.15 202.34,28.15V19.85C204.63,19.85 206.49,21.71 206.49,24Z"
+ android:fillColor="?attr/onShadeActive"
+ android:fillType="evenOdd"/>
+</vector>
+
diff --git a/packages/SystemUI/res/layout/accessibility_deprecate_extra_dim_dialog.xml b/packages/SystemUI/res/layout/accessibility_deprecate_extra_dim_dialog.xml
new file mode 100644
index 0000000..e839f4c
--- /dev/null
+++ b/packages/SystemUI/res/layout/accessibility_deprecate_extra_dim_dialog.xml
@@ -0,0 +1,41 @@
+<!--
+ ~ 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/illustration_frame"
+ android:orientation="vertical"
+ android:paddingHorizontal="16dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center">
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:adjustViewBounds="true"
+ android:layout_marginVertical="24dp"
+ android:scaleType="fitCenter"
+ android:importantForAccessibility="no"
+ android:theme="@style/Theme.SystemUI.QuickSettings"
+ android:src="@drawable/brightness_bar"/>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:textSize="16sp"
+ android:text="@string/accessibility_deprecate_extra_dim_dialog_description"
+ android:textAppearance="@style/TextAppearance.Dialog.Body"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ba37d58..e590f15 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3725,4 +3725,16 @@
<string name="all_apps_edu_notification_title">Use your keyboard to view all apps</string>
<!-- Education notification text for All Apps [CHAR_LIMIT=100] -->
<string name="all_apps_edu_notification_content">Press the action key at any time. Tap to learn more gestures.</string>
+
+ <!-- Title for Extra Dim dialog [CHAR LIMIT=NONE] -->
+ <string name="accessibility_deprecate_extra_dim_dialog_title">Extra dim is now part of the brightness bar</string>
+ <!-- Content description for Extra Dim dialog. This helps users understand that we could make screen much dimmer by lowering the brightness through the brightness bar in a dark environment. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_deprecate_extra_dim_dialog_description">
+ You can now make the screen extra dim by lowering the brightness level even further from the top of your screen.\n\nThis works best when you\'re in a dark environment.
+ </string>
+ <!-- Label for button removing Extra Dim shortcuts [CHAR LIMIT=NONE] -->
+ <string name="accessibility_deprecate_extra_dim_dialog_button">Remove extra dim shortcut</string>
+ <!-- Toast message for notifying users to use regular brightness bar to lower the brightness. [CHAR LIMIT=NONE] -->
+ <string name="accessibility_deprecate_extra_dim_dialog_toast">
+ Extra dim shortcut removed. To lower your brightness, use the regular brightness bar.</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegate.kt
new file mode 100644
index 0000000..fcb1206
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegate.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.accessibility.extradim
+
+import android.content.Context
+import android.content.DialogInterface
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.accessibility.AccessibilityManager
+import android.widget.Toast
+import com.android.internal.accessibility.AccessibilityShortcutController
+import com.android.internal.accessibility.common.ShortcutConstants
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.res.R
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/** Dialog for removing Extra Dim shortcuts. */
+class ExtraDimDialogDelegate
+@Inject
+constructor(
+ private val context: Context,
+ @Application private val applicationScope: CoroutineScope,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+ private val systemUIDialogFactory: SystemUIDialog.Factory,
+ private val accessibilityManager: AccessibilityManager,
+ private val userTracker: UserTracker,
+) : SystemUIDialog.Delegate {
+
+ private val onClickListener: DialogInterface.OnClickListener =
+ DialogInterface.OnClickListener { dialog, _ ->
+ applicationScope.launch {
+ dialog.dismiss()
+ onRemoveExtraDimShortcutButtonClicked()
+ Toast.makeText(
+ context,
+ context.getText(R.string.accessibility_deprecate_extra_dim_dialog_toast),
+ Toast.LENGTH_LONG
+ )
+ .show()
+ }
+ }
+
+ override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+ dialog.setTitle(R.string.accessibility_deprecate_extra_dim_dialog_title)
+ dialog.setView(
+ LayoutInflater.from(dialog.context)
+ .inflate(R.layout.accessibility_deprecate_extra_dim_dialog, null)
+ )
+ dialog.setPositiveButton(
+ R.string.accessibility_deprecate_extra_dim_dialog_button,
+ onClickListener
+ )
+ }
+
+ override fun createDialog(): SystemUIDialog {
+ val dialog = systemUIDialogFactory.create(this)
+ dialog.setCanceledOnTouchOutside(false)
+ return dialog
+ }
+
+ private suspend fun onRemoveExtraDimShortcutButtonClicked() =
+ withContext(backgroundDispatcher) {
+ accessibilityManager.enableShortcutsForTargets(
+ /* enable= */ false,
+ ShortcutConstants.UserShortcutType.ALL,
+ setOf(
+ AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME
+ .flattenToString()
+ ),
+ userTracker.userId
+ )
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt
new file mode 100644
index 0000000..e1297d3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManager.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.accessibility.extradim
+
+import androidx.annotation.VisibleForTesting
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import javax.inject.Inject
+import javax.inject.Provider
+
+/** Managing the Extra Dim Dialog behaviors. */
+@SysUISingleton
+class ExtraDimDialogManager
+@Inject
+constructor(
+ private val extraDimDialogDelegateProvider: Provider<ExtraDimDialogDelegate>,
+ private val mActivityStarter: ActivityStarter
+) {
+ private var dialog: SystemUIDialog? = null
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+ fun dismissKeyguardIfNeededAndShowDialog() {
+ mActivityStarter.executeRunnableDismissingKeyguard(
+ { showRemoveExtraDimShortcutsDialog() },
+ /* cancelAction= */ null,
+ /* dismissShade= */ false,
+ /* afterKeyguardGone= */ true,
+ /* deferred= */ false
+ )
+ }
+
+ /** Show the dialog for removing all Extra Dim shortcuts. */
+ private fun showRemoveExtraDimShortcutsDialog() {
+ dialog?.dismiss()
+ dialog = extraDimDialogDelegateProvider.get().createDialog()
+ dialog!!.show()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogReceiver.kt b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogReceiver.kt
new file mode 100644
index 0000000..405993a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/extradim/ExtraDimDialogReceiver.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.accessibility.extradim
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import com.android.server.display.feature.flags.Flags
+import javax.inject.Inject
+
+/**
+ * BroadcastReceiver for handling [ExtraDimDialogDelegate] intent.
+ *
+ * This is not exported. Need to call from framework and use SYSTEM user to send the intent.
+ */
+class ExtraDimDialogReceiver
+@Inject
+constructor(
+ private val extraDimDialogManager: ExtraDimDialogManager,
+) : BroadcastReceiver() {
+
+ override fun onReceive(context: Context, intent: Intent) {
+ if (
+ !Flags.evenDimmer() ||
+ !context
+ .getResources()
+ .getBoolean(com.android.internal.R.bool.config_evenDimmerEnabled)
+ ) {
+ return
+ }
+
+ if (ACTION == intent.action) {
+ extraDimDialogManager.dismissKeyguardIfNeededAndShowDialog()
+ }
+ }
+
+ companion object {
+ const val ACTION = "com.android.systemui.action.LAUNCH_REMOVE_EXTRA_DIM_DIALOG"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
index 7ced932..5a0eb72 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
@@ -19,6 +19,7 @@
import android.content.BroadcastReceiver;
import com.android.systemui.GuestResetOrExitSessionReceiver;
+import com.android.systemui.accessibility.extradim.ExtraDimDialogReceiver;
import com.android.systemui.accessibility.hearingaid.HearingDevicesDialogReceiver;
import com.android.systemui.media.dialog.MediaOutputDialogReceiver;
import com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver;
@@ -88,4 +89,13 @@
@ClassKey(HearingDevicesDialogReceiver.class)
public abstract BroadcastReceiver bindHearingDevicesDialogReceiver(
HearingDevicesDialogReceiver broadcastReceiver);
+
+ /**
+ *
+ */
+ @Binds
+ @IntoMap
+ @ClassKey(ExtraDimDialogReceiver.class)
+ public abstract BroadcastReceiver bindExtraDimDialogReceiver(
+ ExtraDimDialogReceiver broadcastReceiver);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt
new file mode 100644
index 0000000..b80836d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt
@@ -0,0 +1,118 @@
+/*
+ * 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.accessibility.extradim
+
+import android.content.DialogInterface
+import android.testing.TestableLooper
+import android.view.accessibility.AccessibilityManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.accessibility.AccessibilityShortcutController
+import com.android.internal.accessibility.common.ShortcutConstants
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.model.SysUiState
+import com.android.systemui.res.R
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyLong
+import org.mockito.Mock
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.verify
+
+/** Tests for [ExtraDimDialogDelegate]. */
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
[email protected](setAsMainLooper = true)
+@RunWith(AndroidJUnit4::class)
+class ExtraDimDialogDelegateTest : SysuiTestCase() {
+ @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+ private lateinit var extraDimDialogDelegate: ExtraDimDialogDelegate
+
+ private val kosmos = Kosmos().also { it.testCase = this }
+ private val testScope = kosmos.testScope
+
+ @Mock private lateinit var dialog: SystemUIDialog
+ @Mock private lateinit var accessibilityManager: AccessibilityManager
+ @Mock private lateinit var dialogFactory: SystemUIDialog.Factory
+ @Mock private lateinit var userTracker: UserTracker
+ @Mock private lateinit var sysuiState: SysUiState
+
+ @Before
+ fun setUp() {
+ whenever(sysuiState.setFlag(anyLong(), anyBoolean())).thenReturn(sysuiState)
+ whenever(dialog.context).thenReturn(context)
+
+ extraDimDialogDelegate =
+ ExtraDimDialogDelegate(
+ context,
+ testScope.backgroundScope,
+ kosmos.testDispatcher,
+ dialogFactory,
+ accessibilityManager,
+ userTracker
+ )
+ }
+
+ @Test
+ fun clickButton_removeExtraDimShortcuts() =
+ kosmos.testScope.runTest {
+ extraDimDialogDelegate.beforeCreate(dialog, /* savedInstanceState= */ null)
+
+ val clickListener = argumentCaptor<DialogInterface.OnClickListener>()
+
+ // Verify the button has the right text
+ verify(dialog)
+ .setPositiveButton(
+ eq(R.string.accessibility_deprecate_extra_dim_dialog_button),
+ clickListener.capture()
+ )
+
+ clickListener.firstValue.onClick(dialog, 0)
+ advanceUntilIdle()
+ runCurrent()
+ verify(accessibilityManager)
+ .enableShortcutsForTargets(
+ eq(false),
+ eq(ShortcutConstants.UserShortcutType.ALL),
+ eq(
+ setOf(
+ AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME
+ .flattenToString()
+ )
+ ),
+ anyInt()
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt
new file mode 100644
index 0000000..1386092
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogManagerTest.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.accessibility.extradim
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.plugins.ActivityStarter
+import javax.inject.Provider
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.verify
+
+/** Tests for [ExtraDimDialogManager]. */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ExtraDimDialogManagerTest : SysuiTestCase() {
+ @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+ private lateinit var extraDimDialogManager: ExtraDimDialogManager
+
+ @Mock private lateinit var activityStarter: ActivityStarter
+ @Mock private lateinit var dialogProvider: Provider<ExtraDimDialogDelegate>
+
+ @Before
+ fun setUp() {
+ extraDimDialogManager = ExtraDimDialogManager(dialogProvider, activityStarter)
+ }
+
+ @Test
+ fun dismissKeyguardIfNeededAndShowDialog_executeRunnableDismissingKeyguard() {
+ extraDimDialogManager.dismissKeyguardIfNeededAndShowDialog()
+ verify(activityStarter)
+ .executeRunnableDismissingKeyguard(
+ any(),
+ /* cancelAction= */ eq(null),
+ /* dismissShade= */ eq(false),
+ /* afterKeyguardGone= */ eq(true),
+ /* deferred= */ eq(false)
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogReceiverTest.kt
new file mode 100644
index 0000000..ebe7500
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogReceiverTest.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.accessibility.extradim
+
+import android.content.Intent
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.server.display.feature.flags.Flags
+import com.android.systemui.SysuiTestCase
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+/** Tests for [ExtraDimDialogReceiver]. */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ExtraDimDialogReceiverTest : SysuiTestCase() {
+ @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+ private lateinit var extraDimDialogReceiver: ExtraDimDialogReceiver
+
+ @Mock private lateinit var extraDimDialogManager: ExtraDimDialogManager
+
+ @Before
+ fun setUp() {
+ extraDimDialogReceiver = ExtraDimDialogReceiver(extraDimDialogManager)
+ mContext
+ .getOrCreateTestableResources()
+ .addOverride(com.android.internal.R.bool.config_evenDimmerEnabled, true)
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_EVEN_DIMMER)
+ fun receiveAction_flagEvenDimmerEnabled_showDialog() {
+ extraDimDialogReceiver.onReceive(mContext, Intent(ExtraDimDialogReceiver.ACTION))
+ verify(extraDimDialogManager).dismissKeyguardIfNeededAndShowDialog()
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_EVEN_DIMMER)
+ fun receiveAction_flagEvenDimmerDisabled_neverShowDialog() {
+ extraDimDialogReceiver.onReceive(mContext, Intent(ExtraDimDialogReceiver.ACTION))
+ verify(extraDimDialogManager, never()).dismissKeyguardIfNeededAndShowDialog()
+ }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 9067cda6..45fcf6b 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -4090,11 +4090,7 @@
boolean enable, @UserShortcutType int shortcutTypes,
@NonNull List<String> shortcutTargets, @UserIdInt int userId) {
enableShortcutsForTargets_enforcePermission();
- if ((shortcutTypes & GESTURE) == GESTURE
- && !android.provider.Flags.a11yStandaloneGestureEnabled()) {
- throw new IllegalArgumentException(
- "GESTURE type shortcuts are disabled by feature flag");
- }
+
for (int shortcutType : USER_SHORTCUT_TYPES) {
if ((shortcutTypes & shortcutType) == shortcutType) {
enableShortcutForTargets(enable, shortcutType, shortcutTargets, userId);
@@ -4105,6 +4101,13 @@
private void enableShortcutForTargets(
boolean enable, @UserShortcutType int shortcutType,
@NonNull List<String> shortcutTargets, @UserIdInt int userId) {
+ if (shortcutType == UserShortcutType.GESTURE
+ && !android.provider.Flags.a11yStandaloneGestureEnabled()) {
+ Slog.w(LOG_TAG,
+ "GESTURE type shortcuts are disabled by feature flag");
+ return;
+ }
+
final String shortcutTypeSettingKey = ShortcutUtils.convertToKey(shortcutType);
if (shortcutType == UserShortcutType.TRIPLETAP
|| shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP) {