Add switch preference for Audio Description.

Preview: https://screenshot.googleplex.com/AXMFpGPPGPPBzXG

Bug: 214634651i
Test: Local flash and test
Test: atest SettingsRoboTests:AudioDescriptionPreferenceControllerTest

Change-Id: Ice2e2bc8ec4e77aba0cd486f854254009b91e541
This commit is contained in:
Kaiqiang Wang
2022-01-17 14:32:46 +01:00
parent bf576a628c
commit 6a23595bb9
6 changed files with 267 additions and 0 deletions

View File

@@ -2877,6 +2877,22 @@
column="13"/> column="13"/>
</issue> </issue>
<issue
id="HardCodedColor"
severity="Error"
message="Avoid using hardcoded color"
category="Correctness"
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.&#xA;This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:color=&quot;@color/accessibility_feature_background&quot;/>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="res/drawable/ic_audio_description.xml"
line="22"
column="13"/>
</issue>
<issue <issue
id="HardCodedColor" id="HardCodedColor"
severity="Error" severity="Error"

View File

@@ -0,0 +1,35 @@
<!--
Copyright 2022 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.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<com.android.settingslib.widget.AdaptiveIconShapeDrawable
android:width="@dimen/accessibility_icon_size"
android:height="@dimen/accessibility_icon_size"
android:color="@color/accessibility_feature_background"/>
</item>
<item android:gravity="center">
<vector
android:width="@dimen/accessibility_icon_foreground_size"
android:height="@dimen/accessibility_icon_foreground_size"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M10,18v-4L8,14v-2q0,-1.65 1.175,-2.825Q10.35,8 12,8q1.65,0 2.825,1.175Q16,10.35 16,12v2h-2v4h2.8q0.5,0 0.85,-0.35t0.35,-0.85L18,12q0,-2.5 -1.75,-4.25T12,6Q9.5,6 7.75,7.75T6,12v4.8q0,0.5 0.35,0.85t0.85,0.35zM5,21q-0.825,0 -1.413,-0.587Q3,19.825 3,19L3,5q0,-0.825 0.587,-1.413Q4.175,3 5,3h14q0.825,0 1.413,0.587Q21,4.175 21,5v14q0,0.825 -0.587,1.413Q19.825,21 19,21zM5,19h14L19,5L5,5v14zM5,19L5,5v14z"/>
</vector>
</item>
</layer-list>

View File

@@ -5554,6 +5554,13 @@
</plurals> </plurals>
<!-- Title for the accessibility audio adjustment page. [CHAR LIMIT=50] --> <!-- Title for the accessibility audio adjustment page. [CHAR LIMIT=50] -->
<string name="accessibility_audio_adjustment_title">Audio adjustment</string> <string name="accessibility_audio_adjustment_title">Audio adjustment</string>
<!-- Title for control audio description preference. [CHAR LIMIT=50] -->
<string name="accessibility_toggle_audio_description_preference_title">Audio Description</string>
<!-- Summary for accessibility preference for audio description when need
audio description in adopted apps. [CHAR_LIMIT=NONE] -->
<string name="accessibility_audio_description_summary">Select audio sound track with audio description by default</string>
<!-- List of synonyms used in the settings search bar to find the "Audio Description. [CHAR LIMIT=NONE] -->
<string name="keywords_audio_description">audio description, audio, description, low vision,</string>
<!-- Preference's shortcut when enabled. [CHAR LIMIT=NONE] --> <!-- Preference's shortcut when enabled. [CHAR LIMIT=NONE] -->
<string name="accessibility_summary_shortcut_enabled">Shortcut on</string> <string name="accessibility_summary_shortcut_enabled">Shortcut on</string>

View File

@@ -81,6 +81,16 @@
settings:keywords="@string/keywords_magnification" settings:keywords="@string/keywords_magnification"
settings:controller="com.android.settings.accessibility.MagnificationPreferenceController"/> settings:controller="com.android.settings.accessibility.MagnificationPreferenceController"/>
<SwitchPreference
android:key="toggle_audio_description"
android:persistent="false"
android:icon="@drawable/ic_audio_description"
android:summary="@string/accessibility_audio_description_summary"
android:title="@string/accessibility_toggle_audio_description_preference_title"
settings:keywords="@string/keywords_audio_description"
settings:searchable="true"
settings:controller="com.android.settings.accessibility.AudioDescriptionPreferenceController"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import static android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import android.content.Context;
import android.os.UserHandle;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
/**
* A toggle preference controller for audio description
*/
public class AudioDescriptionPreferenceController extends TogglePreferenceController {
static final String PREF_KEY = "toggle_audio_description";
public AudioDescriptionPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public boolean isChecked() {
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT,
OFF /* default */,
UserHandle.USER_CURRENT) == ON;
}
@Override
public boolean setChecked(boolean isChecked) {
return Settings.Secure.putIntForUser(mContext.getContentResolver(),
ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT,
isChecked ? ON : OFF,
UserHandle.USER_CURRENT);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE;
}
@Override
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (C) 2022 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.settings.accessibility;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.core.BasePreferenceController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@RunWith(RobolectricTestRunner.class)
public class AudioDescriptionPreferenceControllerTest {
private static final String KEY_AUDIO_DESCRIPTION =
Settings.Secure.ENABLED_ACCESSIBILITY_AUDIO_DESCRIPTION_BY_DEFAULT;
private static final int UNKNOWN = -1;
private final Context mContext = ApplicationProvider.getApplicationContext();
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
private final AudioDescriptionPreferenceController mController =
new AudioDescriptionPreferenceController(mContext,
AudioDescriptionPreferenceController.PREF_KEY);
@Before
public void setUp() {
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
mSwitchPreference.setKey(AudioDescriptionPreferenceController.PREF_KEY);
screen.addPreference(mSwitchPreference);
mController.displayPreference(screen);
}
@Test
public void getAvailabilityStatus_byDefault_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.AVAILABLE);
}
@Test
public void isChecked_disableAudioDescription_onResumeShouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, OFF);
mController.updateState(mSwitchPreference);
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.isChecked()).isFalse();
}
@Test
public void isChecked_enableAudioDescription_onResumeShouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, ON);
mController.updateState(mSwitchPreference);
assertThat(mController.isChecked()).isTrue();
assertThat(mSwitchPreference.isChecked()).isTrue();
}
@Test
public void performClick_enableAudioDescription_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, OFF);
mController.updateState(mSwitchPreference);
mSwitchPreference.performClick();
verify(mSwitchPreference).setChecked(true);
assertThat(mController.isChecked()).isTrue();
assertThat(mSwitchPreference.isChecked()).isTrue();
}
@Test
public void performClick_disableAudioDescription_shouldReturnFalse() {
Settings.Secure.putInt(mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, ON);
mController.updateState(mSwitchPreference);
mSwitchPreference.performClick();
verify(mSwitchPreference).setChecked(false);
assertThat(mController.isChecked()).isFalse();
assertThat(mSwitchPreference.isChecked()).isFalse();
}
@Test
public void setChecked_setFalse_shouldDisableAudioDescription() {
mController.setChecked(false);
assertThat(Settings.Secure.getInt(
mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, UNKNOWN)).isEqualTo(OFF);
}
@Test
public void setChecked_setTrue_shouldEnableAudioDescription() {
mController.setChecked(true);
assertThat(Settings.Secure.getInt(
mContext.getContentResolver(), KEY_AUDIO_DESCRIPTION, UNKNOWN)).isEqualTo(ON);
}
}