diff options
14 files changed, 578 insertions, 9 deletions
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java index f9c294758bf0..e8831ec2743e 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.ComponentName; 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 android.widget.Toast; 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 @@ public class AccessibilityShortcutController { .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 @@ public class AccessibilityShortcutController { 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 @@ public class AccessibilityShortcutController { } } - 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 a3fcfad7afc8..44dceb9b7edb 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 @@ public final class ShortcutConstants { UserShortcutType.TRIPLETAP, UserShortcutType.TWOFINGER_DOUBLETAP, UserShortcutType.QUICK_SETTINGS, - UserShortcutType.GESTURE + UserShortcutType.GESTURE, + UserShortcutType.ALL }) public @interface UserShortcutType { int DEFAULT = 0; @@ -84,6 +85,7 @@ public final class ShortcutConstants { 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 666d939257dc..ea6717cf78d4 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 000000000000..2afe164ab5c5 --- /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 000000000000..e839f4c8ffd0 --- /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 acc12d7fdaf0..c105ae3309a9 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -3704,4 +3704,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 000000000000..fcb12068207e --- /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 000000000000..e1297d32504b --- /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 000000000000..405993a4479f --- /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 7ced9322ed38..5a0eb7260ab1 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 @@ package com.android.systemui.dagger; 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 @@ public abstract class DefaultBroadcastReceiverBinder { @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 000000000000..b80836d80e12 --- /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 +@TestableLooper.RunWithLooper(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 000000000000..1386092ef93e --- /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 000000000000..ebe7500300c8 --- /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 30c743e508b6..6b954b9e5054 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -4087,11 +4087,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub 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); @@ -4102,6 +4098,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub 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) { |