Add captioning preferences screen

BUG: 9926077
Change-Id: Iea141d5d6fd0e4f134c36c51d89830b3c31abd09
This commit is contained in:
Alan Viverette
2013-08-06 13:53:58 -07:00
parent 279a8dfc40
commit cc0e782871
28 changed files with 1939 additions and 12 deletions

View File

@@ -973,6 +973,21 @@
android:resource="@id/accessibility_settings" /> android:resource="@id/accessibility_settings" />
</activity> </activity>
<activity android:name="Settings$CaptioningSettingsActivity"
android:label="@string/accessibility_captioning_title"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings$AccessibilitySettingsActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.CAPTIONING_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.accessibility.ToggleCaptioningPreferenceFragment" />
<meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
android:resource="@id/accessibility_settings" />
</activity>
<activity android:name="Settings$TextToSpeechSettingsActivity" <activity android:name="Settings$TextToSpeechSettingsActivity"
android:label="@string/tts_settings" android:label="@string/tts_settings"
android:taskAffinity="com.android.settings" android:taskAffinity="com.android.settings"

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 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.
-->
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/transparency"
android:tileMode="repeat"
android:dither="true" />

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="@dimen/captioning_preview_height" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@null"
android:scaleType="centerCrop"
android:src="@drawable/caption_background" />
<com.android.settings.accessibility.CaptioningTextView
android:id="@+id/preview_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|start"
android:layout_margin="16dp"
android:text="@string/captioning_preview_text" />
</FrameLayout>
<fragment
android:id="@+id/properties_fragment"
android:name="com.android.settings.accessibility.CaptionPropertiesFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 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:layout_width="96dp"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/color_swatch"
android:layout_width="96dp"
android:layout_height="96dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
</LinearLayout>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<GridView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="400dp"
android:columnWidth="112dp"
android:numColumns="auto_fit"
android:stretchMode="spacingWidthUniform"
android:verticalSpacing="16dp"
android:paddingTop="16dp" />
</LinearLayout>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 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.
-->
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/color_preview"
android:layout_width="?android:attr/listPreferredItemHeight"
android:layout_height="?android:attr/listPreferredItemHeight"
android:contentDescription="@null" />

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 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:layout_width="96dp"
android:layout_height="wrap_content"
android:orientation="vertical" >
<FrameLayout
android:layout_width="96dp"
android:layout_height="96dp"
android:background="@drawable/transparency_tileable" >
<com.android.settings.accessibility.CaptioningTextView
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/captioning_preview_characters" />
</FrameLayout>
<TextView
android:id="@+id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
</LinearLayout>

View File

@@ -22,4 +22,6 @@
<dimen name="keyguard_appwidget_picker_margin_left">2dip</dimen> <dimen name="keyguard_appwidget_picker_margin_left">2dip</dimen>
<dimen name="keyguard_appwidget_picker_margin_right">2dip</dimen> <dimen name="keyguard_appwidget_picker_margin_right">2dip</dimen>
<integer name="keyguard_appwidget_picker_cols">2</integer> <integer name="keyguard_appwidget_picker_cols">2</integer>
<dimen name="captioning_preview_height">100dp</dimen>
</resources> </resources>

View File

@@ -706,6 +706,144 @@
<item>1500</item> <item>1500</item>
</string-array> </string-array>
<!-- Titles for captioning typeface preference. [CHAR LIMIT=35] -->
<string-array name="captioning_typeface_selector_titles">
<item>Default</item>
<item>Sans-serif</item>
<item>Sans-serif condensed</item>
<item>Serif</item>
<item>Monospace</item>
</string-array>
<!-- Values for captioning typeface preference. -->
<string-array name="captioning_typeface_selector_values" translatable="false" >
<item></item>
<item>sans-serif</item>
<item>sans-serif-condensed</item>
<item>serif</item>
<item>monospace</item>
</string-array>
<!-- Titles for captioning font size preference. [CHAR LIMIT=35] -->
<string-array name="captioning_font_size_selector_titles">
<item>Very small</item>
<item>Small</item>
<item>Normal</item>
<item>Large</item>
<item>Very large</item>
</string-array>
<!-- Values for captioning font size preference. -->
<string-array name="captioning_font_size_selector_values" translatable="false" >
<item>6.0</item>
<item>12.0</item>
<item>24.0</item>
<item>32.0</item>
<item>48.0</item>
</string-array>
<!-- Titles for captioning character edge type preference. [CHAR LIMIT=35] -->
<string-array name="captioning_edge_type_selector_titles">
<item>None</item>
<item>Outline</item>
<item>Drop shadow</item>
</string-array>
<!-- Values for captioning character edge type preference. -->
<integer-array name="captioning_edge_type_selector_values" translatable="false" >
<item>0</item>
<item>1</item>
<item>2</item>
</integer-array>
<!-- Titles for captioning color preference. -->
<string-array name="captioning_color_selector_titles" translatable="false" >
<item>@string/color_white</item>
<item>@string/color_gray</item>
<item>@string/color_black</item>
<item>@string/color_red</item>
<item>@string/color_yellow</item>
<item>@string/color_green</item>
<item>@string/color_cyan</item>
<item>@string/color_blue</item>
<item>@string/color_magenta</item>
</string-array>
<!-- Values for captioning color preference. -->
<integer-array name="captioning_color_selector_values" translatable="false" >
<item>0xFFFFFFFF</item>
<item>0xFF808080</item>
<item>0xFF000000</item>
<item>0xFFFF0000</item>
<item>0xFFFFFF00</item>
<item>0xFF00FF00</item>
<item>0xFF00FFFF</item>
<item>0xFF0000FF</item>
<item>0xFFFF00FF</item>
</integer-array>
<!-- Titles for captioning background color preference. -->
<string-array name="captioning_background_color_selector_titles" translatable="false" >
<item>@string/color_none</item>
<item>@string/color_white</item>
<item>@string/color_gray</item>
<item>@string/color_black</item>
<item>@string/color_red</item>
<item>@string/color_yellow</item>
<item>@string/color_green</item>
<item>@string/color_cyan</item>
<item>@string/color_blue</item>
<item>@string/color_magenta</item>
</string-array>
<!-- Values for captioning background color preference. -->
<integer-array name="captioning_background_color_selector_values" translatable="false" >
<item>0x00000000</item>
<item>0xFFFFFFFF</item>
<item>0xFF808080</item>
<item>0xFF000000</item>
<item>0xFFFF0000</item>
<item>0xFFFFFF00</item>
<item>0xFF00FF00</item>
<item>0xFF00FFFF</item>
<item>0xFF0000FF</item>
<item>0xFFFF00FF</item>
</integer-array>
<!-- Titles for captioning opacity preference. [CHAR LIMIT=35] -->
<string-array name="captioning_opacity_selector_titles" >
<item>25%</item>
<item>50%</item>
<item>75%</item>
<item>100%</item>
</string-array>
<!-- Values for captioning opacity preference. -->
<integer-array name="captioning_opacity_selector_values" translatable="false" >
<item>0x40FFFFFF</item>
<item>0x80FFFFFF</item>
<item>0xC0FFFFFF</item>
<item>0xFFFFFFFF</item>
</integer-array>
<!-- Titles for captioning text style preset preference. [CHAR LIMIT=35] -->
<string-array name="captioning_preset_selector_titles" >
<item>Black on white</item>
<item>White on black</item>
<item>Yellow on black</item>
<item>Yellow on blue</item>
<item>Custom</item>
</string-array>
<!-- Values for captioning text style preset preference. -->
<integer-array name="captioning_preset_selector_values" translatable="false" >
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>-1</item>
</integer-array>
<!-- Titles for runtime selection preference. [CHAR LIMIT=35] --> <!-- Titles for runtime selection preference. [CHAR LIMIT=35] -->
<string-array name="select_runtime_titles"> <string-array name="select_runtime_titles">
<item>Dalvik</item> <item>Dalvik</item>
@@ -984,4 +1122,5 @@
<!-- Always allow app to send to premium SMS short code. --> <!-- Always allow app to send to premium SMS short code. -->
<item>Always allow</item> <item>Always allow</item>
</string-array> </string-array>
</resources> </resources>

View File

@@ -69,4 +69,6 @@
<!-- Minimum width for the popup for updating a user's photo. --> <!-- Minimum width for the popup for updating a user's photo. -->
<dimen name="update_user_photo_popup_min_width">300dip</dimen> <dimen name="update_user_photo_popup_min_width">300dip</dimen>
<dimen name="captioning_preview_height">200dp</dimen>
</resources> </resources>

View File

@@ -3206,6 +3206,8 @@
<string name="accessibility_services_title">Services</string> <string name="accessibility_services_title">Services</string>
<!-- Title for the accessibility preference category of system related preferences. [CHAR LIMIT=25] --> <!-- Title for the accessibility preference category of system related preferences. [CHAR LIMIT=25] -->
<string name="accessibility_system_title">System</string> <string name="accessibility_system_title">System</string>
<!-- Title for the accessibility preference screen to enable video captioning. [CHAR LIMIT=35] -->
<string name="accessibility_captioning_title">Captions</string>
<!-- Title for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=35] --> <!-- Title for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=35] -->
<string name="accessibility_screen_magnification_title">Magnification gestures</string> <string name="accessibility_screen_magnification_title">Magnification gestures</string>
<!-- Summary for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=none] --> <!-- Summary for the accessibility preference screen to enable screen magnification. [CHAR LIMIT=none] -->
@@ -3243,6 +3245,59 @@
<!-- Summary for the disabled state of an accessibility feature. [CHAR LIMIT=10] --> <!-- Summary for the disabled state of an accessibility feature. [CHAR LIMIT=10] -->
<string name="accessibility_feature_state_off">Off</string> <string name="accessibility_feature_state_off">Off</string>
<!-- Title for the preference category containing the video caption preview. [CHAR LIMIT=35] -->
<string name="captioning_preview_title">Preview</string>
<!-- Title for the preference catgeory containing standard video caption options. [CHAR LIMIT=35] -->
<string name="captioning_standard_options_title">Standard options</string>
<!-- Title for the preference to change video caption locale. [CHAR LIMIT=35] -->
<string name="captioning_locale">Language</string>
<!-- Title for the preference to change video caption text size. [CHAR LIMIT=35] -->
<string name="captioning_text_size">Text size</string>
<!-- Title for the preference category containing video caption property presets. [CHAR LIMIT=35] -->
<string name="captioning_preset">Caption style</string>
<!-- Title for the preference catgeory containing custom video caption properties. [CHAR LIMIT=35] -->
<string name="captioning_custom_options_title">Custom options</string>
<!-- Title for the preference to change video caption background color. [CHAR LIMIT=35] -->
<string name="captioning_background_color">Background color</string>
<!-- Title for the preference to change video caption background opacity. [CHAR LIMIT=35] -->
<string name="captioning_background_opacity">Background opacity</string>
<!-- Title for the preference to change video caption text color. [CHAR LIMIT=35] -->
<string name="captioning_foreground_color">Text color</string>
<!-- Title for the preference to change video caption edge color. [CHAR LIMIT=35] -->
<string name="captioning_edge_color">Edge color</string>
<!-- Title for the preference to change video caption edge type. [CHAR LIMIT=35] -->
<string name="captioning_edge_type">Edge type</string>
<!-- Title for the preference to change video caption font family (ex. monospace, sans-serif). [CHAR LIMIT=35] -->
<string name="captioning_typeface">Font family</string>
<!-- Sample text for previewing video caption preferences. [CHAR LIMIT=NONE] -->
<string name="captioning_preview_text">Captions will look like this</string>
<!-- Sample characters for previewing video caption preferences. [CHAR LIMIT=2] -->
<string name="captioning_preview_characters">Aa</string>
<!-- Label for the default device locale. [CHAR LIMIT=35] -->
<string name="locale_default">Default</string>
<!-- Label for no color. [CHAR LIMIT=35] -->
<string name="color_none">None</string>
<!-- Label for the color white. [CHAR LIMIT=35] -->
<string name="color_white">White</string>
<!-- Label for the color gray. [CHAR LIMIT=35] -->
<string name="color_gray">Gray</string>
<!-- Label for the color black. [CHAR LIMIT=35] -->
<string name="color_black">Black</string>
<!-- Label for the color red. [CHAR LIMIT=35] -->
<string name="color_red">Red</string>
<!-- Label for the color green. [CHAR LIMIT=35] -->
<string name="color_green">Green</string>
<!-- Label for the color blue. [CHAR LIMIT=35] -->
<string name="color_blue">Blue</string>
<!-- Label for the color cyan. [CHAR LIMIT=35] -->
<string name="color_cyan">Cyan</string>
<!-- Label for the color yellow. [CHAR LIMIT=35] -->
<string name="color_yellow">Yellow</string>
<!-- Label for the color magenta. [CHAR LIMIT=35] -->
<string name="color_magenta">Magenta</string>
<!-- Title for a warning about security implications of enabling an accessibility <!-- Title for a warning about security implications of enabling an accessibility
service. [CHAR LIMIT=NONE] --> service. [CHAR LIMIT=NONE] -->
<string name="enable_service_title">Use <string name="enable_service_title">Use

View File

@@ -27,6 +27,11 @@
android:key="system_category" android:key="system_category"
android:title="@string/accessibility_system_title"> android:title="@string/accessibility_system_title">
<PreferenceScreen
android:fragment="com.android.settings.accessibility.ToggleCaptioningPreferenceFragment"
android:key="captioning_preference_screen"
android:title="@string/accessibility_captioning_title" />
<PreferenceScreen <PreferenceScreen
android:fragment="com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment" android:fragment="com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment"
android:key="screen_magnification_preference_screen" android:key="screen_magnification_preference_screen"

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2013 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:fragment="com.android.settings.accessibility.ToggleCaptioningPreferenceFragment"
android:key="captioning_preference_screen"
android:title="@string/accessibility_captioning_title" >
<PreferenceCategory
android:key="standard"
android:title="@string/captioning_standard_options_title" >
<com.android.settings.accessibility.LocalePreference
android:key="captioning_locale"
android:persistent="false"
android:summary="%s"
android:title="@string/captioning_locale" />
<ListPreference
android:entries="@array/captioning_font_size_selector_titles"
android:entryValues="@array/captioning_font_size_selector_values"
android:key="captioning_font_size"
android:persistent="false"
android:summary="%s"
android:title="@string/captioning_text_size" />
<com.android.settings.accessibility.PresetPreference
android:key="captioning_preset"
android:persistent="false"
android:title="@string/captioning_preset" />
</PreferenceCategory>
<PreferenceCategory
android:key="custom"
android:title="@string/captioning_custom_options_title" >
<ListPreference
android:dependency="captioning_preset"
android:entries="@array/captioning_typeface_selector_titles"
android:entryValues="@array/captioning_typeface_selector_values"
android:key="captioning_typeface"
android:persistent="false"
android:summary="%s"
android:title="@string/captioning_typeface" />
<com.android.settings.accessibility.ColorPreference
android:dependency="captioning_preset"
android:key="captioning_foreground_color"
android:persistent="false"
android:title="@string/captioning_foreground_color" />
<com.android.settings.accessibility.EdgeTypePreference
android:dependency="captioning_preset"
android:key="captioning_edge_type"
android:persistent="false"
android:title="@string/captioning_edge_type" />
<com.android.settings.accessibility.ColorPreference
android:dependency="captioning_edge_type"
android:key="captioning_edge_color"
android:persistent="false"
android:title="@string/captioning_edge_color" />
<com.android.settings.accessibility.ColorPreference
android:dependency="captioning_preset"
android:key="captioning_background_color"
android:persistent="false"
android:title="@string/captioning_background_color" />
<com.android.settings.accessibility.ColorPreference
android:dependency="captioning_background_color"
android:key="captioning_background_opacity"
android:persistent="false"
android:title="@string/captioning_background_opacity" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -95,6 +95,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
"select_long_press_timeout_preference"; "select_long_press_timeout_preference";
private static final String ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN = private static final String ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN =
"enable_global_gesture_preference_screen"; "enable_global_gesture_preference_screen";
private static final String CAPTIONING_PREFERENCE_SCREEN =
"captioning_preference_screen";
private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN = private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN =
"screen_magnification_preference_screen"; "screen_magnification_preference_screen";
@@ -189,6 +191,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
private CheckBoxPreference mToggleSpeakPasswordPreference; private CheckBoxPreference mToggleSpeakPasswordPreference;
private ListPreference mSelectLongPressTimeoutPreference; private ListPreference mSelectLongPressTimeoutPreference;
private Preference mNoServicesMessagePreference; private Preference mNoServicesMessagePreference;
private PreferenceScreen mCaptioningPreferenceScreen;
private PreferenceScreen mDisplayMagnificationPreferenceScreen; private PreferenceScreen mDisplayMagnificationPreferenceScreen;
private PreferenceScreen mGlobalGesturePreferenceScreen; private PreferenceScreen mGlobalGesturePreferenceScreen;
@@ -360,6 +363,10 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
} }
} }
// Captioning.
mCaptioningPreferenceScreen = (PreferenceScreen) findPreference(
CAPTIONING_PREFERENCE_SCREEN);
// Display magnification. // Display magnification.
mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference( mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference(
DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN); DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN);
@@ -507,6 +514,15 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
mSelectLongPressTimeoutPreference.setValue(value); mSelectLongPressTimeoutPreference.setValue(value);
mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value)); mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value));
// Captioning.
final boolean captioningEnabled = Settings.Secure.getInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, 0) == 1;
if (captioningEnabled) {
mCaptioningPreferenceScreen.setSummary(R.string.accessibility_feature_state_on);
} else {
mCaptioningPreferenceScreen.setSummary(R.string.accessibility_feature_state_off);
}
// Screen magnification. // Screen magnification.
final boolean magnificationEnabled = Settings.Secure.getInt(getContentResolver(), final boolean magnificationEnabled = Settings.Secure.getInt(getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1; Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1;

View File

@@ -1,37 +1,77 @@
/*
* Copyright (C) 2013 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; package com.android.settings.accessibility;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.provider.Settings; import android.provider.Settings;
import android.provider.Settings.Secure;
import android.text.TextUtils.SimpleStringSplitter; import android.text.TextUtils.SimpleStringSplitter;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale;
import java.util.Set; import java.util.Set;
/** /**
* TODO: Insert description here. (generated by alanv) * Utility methods used within accessibility settings.
*/
class AccessibilityUtils {
/**
* @return the set of enabled accessibility services
*/ */
public class AccessibilityUtils {
static Set<ComponentName> getEnabledServicesFromSettings(Context context) { static Set<ComponentName> getEnabledServicesFromSettings(Context context) {
String enabledServicesSetting = Settings.Secure.getString(context.getContentResolver(), final String enabledServicesSetting = Settings.Secure.getString(
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (enabledServicesSetting == null) { if (enabledServicesSetting == null) {
enabledServicesSetting = ""; return Collections.emptySet();
} }
Set<ComponentName> enabledServices = new HashSet<ComponentName>();
SimpleStringSplitter colonSplitter = AccessibilitySettings.sStringColonSplitter; final Set<ComponentName> enabledServices = new HashSet<ComponentName>();
final SimpleStringSplitter colonSplitter = AccessibilitySettings.sStringColonSplitter;
colonSplitter.setString(enabledServicesSetting); colonSplitter.setString(enabledServicesSetting);
while (colonSplitter.hasNext()) { while (colonSplitter.hasNext()) {
String componentNameString = colonSplitter.next(); final String componentNameString = colonSplitter.next();
ComponentName enabledService = ComponentName.unflattenFromString( final ComponentName enabledService = ComponentName.unflattenFromString(
componentNameString); componentNameString);
if (enabledService != null) { if (enabledService != null) {
enabledServices.add(enabledService); enabledServices.add(enabledService);
} }
} }
return enabledServices; return enabledServices;
} }
/**
* @return a localized version of the text resource specified by resId
*/
static CharSequence getTextForLocale(Context context, Locale locale, int resId) {
final Resources res = context.getResources();
final Configuration config = res.getConfiguration();
final Locale prevLocale = config.locale;
try {
config.locale = locale;
res.updateConfiguration(config, null);
return res.getText(resId);
} finally {
config.locale = prevLocale;
res.updateConfiguration(config, null);
}
}
} }

View File

@@ -0,0 +1,208 @@
/*
* Copyright (C) 2013 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 android.content.ContentResolver;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.provider.Settings;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener;
/**
* Settings fragment containing captioning properties.
*/
public class CaptionPropertiesFragment extends SettingsPreferenceFragment
implements OnPreferenceChangeListener, OnValueChangedListener {
private ToggleCaptioningPreferenceFragment mParent;
// Standard options.
private LocalePreference mLocale;
private ListPreference mFontSize;
private PresetPreference mPreset;
// Custom options.
private ListPreference mTypeface;
private ColorPreference mForegroundColor;
private EdgeTypePreference mEdgeType;
private ColorPreference mEdgeColor;
private ColorPreference mBackgroundColor;
private ColorPreference mBackgroundOpacity;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.captioning_settings);
initializeAllPreferences();
updateAllPreferences();
installUpdateListeners();
}
/**
* Sets the parent fragment, which is used to update the live preview.
*
* @param parent the parent fragment
*/
public void setParent(ToggleCaptioningPreferenceFragment parent) {
mParent = parent;
}
private void initializeAllPreferences() {
final Resources res = getResources();
final int[] presetValues = res.getIntArray(R.array.captioning_preset_selector_values);
final String[] presetTitles = res.getStringArray(R.array.captioning_preset_selector_titles);
mPreset = (PresetPreference) findPreference("captioning_preset");
mPreset.setValues(presetValues);
mPreset.setTitles(presetTitles);
final int[] colorValues = res.getIntArray(R.array.captioning_color_selector_values);
final String[] colorTitles = res.getStringArray(R.array.captioning_color_selector_titles);
mForegroundColor = (ColorPreference) findPreference("captioning_foreground_color");
mForegroundColor.setTitles(colorTitles);
mForegroundColor.setValues(colorValues);
mEdgeColor = (ColorPreference) findPreference("captioning_edge_color");
mEdgeColor.setTitles(colorTitles);
mEdgeColor.setValues(colorValues);
final int[] bgColorValues = res.getIntArray(
R.array.captioning_background_color_selector_values);
final String[] bgColorTitles = res.getStringArray(
R.array.captioning_background_color_selector_titles);
mBackgroundColor = (ColorPreference) findPreference("captioning_background_color");
mBackgroundColor.setTitles(bgColorTitles);
mBackgroundColor.setValues(bgColorValues);
final int[] opacityValues = res.getIntArray(R.array.captioning_opacity_selector_values);
final String[] opacityTitles = res.getStringArray(
R.array.captioning_opacity_selector_titles);
mBackgroundOpacity = (ColorPreference) findPreference("captioning_background_opacity");
mBackgroundOpacity.setTitles(opacityTitles);
mBackgroundOpacity.setValues(opacityValues);
mEdgeType = (EdgeTypePreference) findPreference("captioning_edge_type");
mTypeface = (ListPreference) findPreference("captioning_typeface");
mFontSize = (ListPreference) findPreference("captioning_font_size");
mLocale = (LocalePreference) findPreference("captioning_locale");
}
private void installUpdateListeners() {
mPreset.setOnValueChangedListener(this);
mForegroundColor.setOnValueChangedListener(this);
mEdgeColor.setOnValueChangedListener(this);
mBackgroundColor.setOnValueChangedListener(this);
mBackgroundOpacity.setOnValueChangedListener(this);
mEdgeType.setOnValueChangedListener(this);
mTypeface.setOnPreferenceChangeListener(this);
mFontSize.setOnPreferenceChangeListener(this);
mLocale.setOnPreferenceChangeListener(this);
}
private void updateAllPreferences() {
final ContentResolver cr = getContentResolver();
final int preset = CaptionStyle.getRawPreset(cr);
mPreset.setValue(preset);
final float fontSize = CaptioningManager.getFontSize(cr);
mFontSize.setValue(Float.toString(fontSize));
final CaptionStyle attrs = CaptionStyle.getCustomStyle(cr);
mForegroundColor.setValue(attrs.foregroundColor);
mEdgeType.setValue(attrs.edgeType);
mEdgeColor.setValue(attrs.edgeColor);
final int backgroundColor = attrs.backgroundColor;
final int bgColor;
final int bgAlpha;
if (Color.alpha(backgroundColor) == 0) {
bgColor = Color.TRANSPARENT;
bgAlpha = (backgroundColor & 0xFF) << 24;
} else {
bgColor = backgroundColor | 0xFF000000;
bgAlpha = backgroundColor & 0xFF000000;
}
mBackgroundColor.setValue(bgColor);
mBackgroundOpacity.setValue(bgAlpha | 0xFFFFFF);
final String rawTypeface = attrs.mRawTypeface;
mTypeface.setValue(rawTypeface == null ? "" : rawTypeface);
final String rawLocale = CaptioningManager.getRawLocale(cr);
mLocale.setValue(rawLocale == null ? "" : rawLocale);
}
private void refreshPreviewText() {
if (mParent != null) {
mParent.refreshPreviewText();
}
}
@Override
public void onValueChanged(ListDialogPreference preference, int value) {
final ContentResolver cr = getActivity().getContentResolver();
if (mForegroundColor == preference) {
Settings.Secure.putInt(
cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, value);
} else if (mBackgroundColor == preference || mBackgroundOpacity == preference) {
final int bgColor = mBackgroundColor.getValue();
final int bgAlpha = mBackgroundOpacity.getValue();
final int argb;
if (Color.alpha(bgColor) == 0) {
argb = Color.alpha(bgAlpha);
} else {
argb = bgColor & 0x00FFFFFF | bgAlpha & 0xFF000000;
}
Settings.Secure.putInt(
cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, argb);
} else if (mEdgeColor == preference) {
Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, value);
} else if (mPreset == preference) {
Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, value);
} else if (mEdgeType == preference) {
Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, value);
}
refreshPreviewText();
}
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
final ContentResolver cr = getActivity().getContentResolver();
if (mTypeface == preference) {
Settings.Secure.putString(
cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, (String) value);
} else if (mFontSize == preference) {
Settings.Secure.putFloat(
cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SIZE,
Float.parseFloat((String) value));
} else if (mLocale == preference) {
Settings.Secure.putString(
cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE, (String) value);
}
refreshPreviewText();
return true;
}
}

View File

@@ -0,0 +1,309 @@
/*
* Copyright (C) 2013 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 android.content.ContentResolver;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.os.Parcel;
import android.support.v4.view.ViewCompat;
import android.text.Editable;
import android.text.ParcelableSpan;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.UpdateAppearance;
import android.util.AttributeSet;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import android.widget.TextView;
public class CaptioningTextView extends TextView {
private MutableBackgroundColorSpan mBackgroundSpan;
private ColorStateList mOutlineColorState;
private float mOutlineWidth;
private int mOutlineColor;
private int mEdgeType = CaptionStyle.EDGE_TYPE_NONE;
private int mEdgeColor = Color.TRANSPARENT;
private float mEdgeWidth = 0;
private boolean mHasBackground = false;
public CaptioningTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CaptioningTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CaptioningTextView(Context context) {
super(context);
}
public void applyStyleAndFontSize(int styleId) {
final Context context = mContext;
final ContentResolver cr = context.getContentResolver();
final CaptionStyle style;
if (styleId == CaptionStyle.PRESET_CUSTOM) {
style = CaptionStyle.getCustomStyle(cr);
} else {
style = CaptionStyle.PRESETS[styleId];
}
setTextColor(style.foregroundColor);
setBackgroundColor(style.backgroundColor);
setTypeface(style.getTypeface());
// Clears all outlines.
applyEdge(style.edgeType, style.edgeColor, 4.0f);
final float fontSize = CaptioningManager.getFontSize(cr);
if (fontSize != 0) {
setTextSize(fontSize);
}
}
/**
* Applies an edge preset using a combination of {@link #setOutlineLayer}
* and {@link #setShadowLayer}. Any subsequent calls to either of these
* methods will invalidate the applied preset.
*
* @param type Type of edge to apply, one of:
* <ul>
* <li>{@link CaptionStyle#EDGE_TYPE_NONE}
* <li>{@link CaptionStyle#EDGE_TYPE_OUTLINE}
* <li>{@link CaptionStyle#EDGE_TYPE_DROP_SHADOW}
* </ul>
* @param color Edge color as a packed 32-bit ARGB color.
* @param width Width of the edge in pixels.
*/
public void applyEdge(int type, int color, float width) {
if (mEdgeType != type || mEdgeColor != color || mEdgeWidth != width) {
final int textColor = getTextColors().getDefaultColor();
switch (type) {
case CaptionStyle.EDGE_TYPE_DROP_SHADOW:
setOutlineLayer(0, 0);
super.setShadowLayer(width, width, width, color);
break;
case CaptionStyle.EDGE_TYPE_OUTLINE:
setOutlineLayer(width, color);
super.setShadowLayer(0, 0, 0, 0);
break;
default:
super.setShadowLayer(0, 0, 0, 0);
setOutlineLayer(0, 0);
}
mEdgeType = type;
mEdgeColor = color;
mEdgeWidth = width;
}
}
@Override
public void setShadowLayer(float radius, float dx, float dy, int color) {
mEdgeType = CaptionStyle.EDGE_TYPE_NONE;
super.setShadowLayer(radius, dx, dy, color);
}
/**
* Gives the text an outline of the specified pixel width and color.
*/
public void setOutlineLayer(float width, int color) {
width *= 2.0f;
mEdgeType = CaptionStyle.EDGE_TYPE_NONE;
if (mOutlineColor != color || mOutlineWidth != width) {
mOutlineColorState = ColorStateList.valueOf(color);
mOutlineColor = color;
mOutlineWidth = width;
invalidate();
// TODO: Remove after display list bug is fixed.
if (width > 0 && Color.alpha(color) != 0) {
setLayerType(ViewCompat.LAYER_TYPE_SOFTWARE, null);
} else {
setLayerType(ViewCompat.LAYER_TYPE_HARDWARE, null);
}
}
}
/**
* @return the color of the outline layer
* @see #setOutlineLayer(float, int)
*/
public int getOutlineColor() {
return mOutlineColor;
}
/**
* @return the width of the outline layer
* @see #setOutlineLayer(float, int)
*/
public float getOutlineWidth() {
return mOutlineWidth;
}
@Override
public Editable getEditableText() {
final CharSequence text = getText();
if (text instanceof Editable) {
return (Editable) text;
}
setText(text, BufferType.EDITABLE);
return (Editable) getText();
}
@Override
public void setBackgroundColor(int color) {
if (Color.alpha(color) == 0) {
if (mHasBackground) {
mHasBackground = false;
getEditableText().removeSpan(mBackgroundSpan);
}
} else {
if (mBackgroundSpan == null) {
mBackgroundSpan = new MutableBackgroundColorSpan(color);
} else {
mBackgroundSpan.setColor(color);
}
if (mHasBackground) {
invalidate();
} else {
mHasBackground = true;
getEditableText().setSpan(mBackgroundSpan, 0, length(), 0);
}
}
}
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
if (mBackgroundSpan != null) {
getEditableText().setSpan(mBackgroundSpan, 0, lengthAfter, 0);
}
}
@Override
protected void onDraw(Canvas c) {
if (mOutlineWidth > 0 && Color.alpha(mOutlineColor) > 0) {
final TextPaint textPaint = getPaint();
final Paint.Style previousStyle = textPaint.getStyle();
final ColorStateList previousColors = getTextColors();
textPaint.setStyle(Style.STROKE);
textPaint.setStrokeWidth(mOutlineWidth);
textPaint.setStrokeCap(Cap.ROUND);
textPaint.setStrokeJoin(Join.ROUND);
setTextColor(mOutlineColorState);
// Remove the shadow.
final float shadowRadius = getShadowRadius();
final float shadowDx = getShadowDx();
final float shadowDy = getShadowDy();
final int shadowColor = getShadowColor();
if (shadowRadius > 0) {
setShadowLayer(0, 0, 0, 0);
}
// Draw outline and background only.
super.onDraw(c);
// Restore the shadow.
if (shadowRadius > 0) {
setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
}
// Restore original settings.
textPaint.setStyle(previousStyle);
setTextColor(previousColors);
// Remove the background.
final int color;
if (mBackgroundSpan != null) {
color = mBackgroundSpan.getBackgroundColor();
mBackgroundSpan.setColor(Color.TRANSPARENT);
} else {
color = 0;
}
// Draw foreground only.
super.onDraw(c);
// Restore the background.
if (mBackgroundSpan != null) {
mBackgroundSpan.setColor(color);
}
} else {
super.onDraw(c);
}
}
public static class MutableBackgroundColorSpan extends CharacterStyle
implements UpdateAppearance, ParcelableSpan {
private int mColor;
public MutableBackgroundColorSpan(int color) {
mColor = color;
}
public MutableBackgroundColorSpan(Parcel src) {
mColor = src.readInt();
}
public void setColor(int color) {
mColor = color;
}
@Override
public int getSpanTypeId() {
return TextUtils.BACKGROUND_COLOR_SPAN;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mColor);
}
public int getBackgroundColor() {
return mColor;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.bgColor = mColor;
}
}
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright (C) 2013 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 android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.settings.R;
/**
* Grid preference that allows the user to pick a color from a predefined set of
* colors. Optionally shows a preview in the preference item.
*/
public class ColorPreference extends ListDialogPreference {
private ColorDrawable mPreviewColor;
private boolean mPreviewEnabled;
public ColorPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.grid_picker_dialog);
setListItemLayoutResource(R.layout.color_picker_item);
}
/**
* @param enabled whether to show a preview in the preference item
*/
public void setPreviewEnabled(boolean enabled) {
if (mPreviewEnabled != enabled) {
mPreviewEnabled = enabled;
if (enabled) {
setWidgetLayoutResource(R.layout.preference_color);
} else {
setWidgetLayoutResource(0);
}
}
}
@Override
public boolean shouldDisableDependents() {
return getValue() == Color.TRANSPARENT || super.shouldDisableDependents();
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
if (mPreviewEnabled) {
final ImageView previewImage = (ImageView) view.findViewById(R.id.color_preview);
final int argb = getValue();
if (Color.alpha(argb) < 255) {
previewImage.setBackgroundResource(R.drawable.transparency_tileable);
} else {
previewImage.setBackground(null);
}
if (mPreviewColor == null) {
mPreviewColor = new ColorDrawable(argb);
previewImage.setImageDrawable(mPreviewColor);
} else {
mPreviewColor.setColor(argb);
}
final CharSequence summary = getSummary();
if (!TextUtils.isEmpty(summary)) {
previewImage.setContentDescription(summary);
} else {
previewImage.setContentDescription(null);
}
previewImage.setAlpha(isEnabled() ? 1f : 0.2f);
}
}
@Override
protected void onBindListItem(View view, int index) {
final int argb = getValueAt(index);
final int alpha = Color.alpha(argb);
final ImageView swatch = (ImageView) view.findViewById(R.id.color_swatch);
if (alpha < 255) {
swatch.setBackgroundResource(R.drawable.transparency_tileable);
} else {
swatch.setBackground(null);
}
final Drawable foreground = swatch.getDrawable();
if (foreground instanceof ColorDrawable) {
((ColorDrawable) foreground).setColor(argb);
} else {
swatch.setImageDrawable(new ColorDrawable(argb));
}
final CharSequence title = getTitleAt(index);
if (title != null) {
final TextView summary = (TextView) view.findViewById(R.id.summary);
summary.setText(title);
}
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2013 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 android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import android.widget.TextView;
import com.android.settings.R;
/**
* Grid preference that allows the user to pick a captioning edge type.
*/
public class EdgeTypePreference extends ListDialogPreference {
public EdgeTypePreference(Context context, AttributeSet attrs) {
super(context, attrs);
final Resources res = context.getResources();
setValues(res.getIntArray(R.array.captioning_edge_type_selector_values));
setTitles(res.getStringArray(R.array.captioning_edge_type_selector_titles));
setDialogLayoutResource(R.layout.grid_picker_dialog);
setListItemLayoutResource(R.layout.preset_picker_item);
}
@Override
public boolean shouldDisableDependents() {
return getValue() == CaptionStyle.EDGE_TYPE_NONE || super.shouldDisableDependents();
}
@Override
protected void onBindListItem(View view, int index) {
final float fontSize = CaptioningManager.getFontSize(getContext().getContentResolver());
final CaptioningTextView preview = (CaptioningTextView) view.findViewById(R.id.preview);
preview.setTextColor(Color.WHITE);
preview.setBackgroundColor(Color.TRANSPARENT);
preview.setTextSize(fontSize);
final int value = getValueAt(index);
preview.applyEdge(value, Color.BLACK, 4.0f);
final CharSequence title = getTitleAt(index);
if (title != null) {
final TextView summary = (TextView) view.findViewById(R.id.summary);
summary.setText(title);
}
}
}

View File

@@ -0,0 +1,322 @@
/*
* Copyright (C) 2013 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 android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
/**
* Abstract dialog preference that displays a set of values and optional titles.
*/
public abstract class ListDialogPreference extends DialogPreference {
private CharSequence[] mEntryTitles;
private int[] mEntryValues;
private OnValueChangedListener mOnValueChangedListener;
/** The layout resource to use for grid items. */
private int mListItemLayout;
/** The current value of this preference. */
private int mValue;
/** The index within the value set of the current value. */
private int mValueIndex;
/** Whether the value had been set using {@link #setValue}. */
private boolean mValueSet;
public ListDialogPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* Sets a listened to invoke when the value of this preference changes.
*
* @param listener the listener to invoke
*/
public void setOnValueChangedListener(OnValueChangedListener listener) {
mOnValueChangedListener = listener;
}
/**
* Sets the layout to use for grid items.
*
* @param layoutResId the layout to use for displaying grid items
*/
public void setListItemLayoutResource(int layoutResId) {
mListItemLayout = layoutResId;
}
/**
* Sets the list of item values. Values must be distinct.
*
* @param values the list of item values
*/
public void setValues(int[] values) {
mEntryValues = values;
}
/**
* Sets the list of item titles. May be null if no titles are specified, or
* may be shorter than the list of values to leave some titles unspecified.
*
* @param titles the list of item titles
*/
public void setTitles(CharSequence[] titles) {
mEntryTitles = titles;
}
/**
* Populates a list item view with data for the specified index.
*
* @param view the view to populate
* @param index the index for which to populate the view
* @see #setListItemLayoutResource(int)
* @see #getValueAt(int)
* @see #getTitleAt(int)
*/
protected abstract void onBindListItem(View view, int index);
/**
* @return the title at the specified index, or null if none specified
*/
protected CharSequence getTitleAt(int index) {
if (mEntryTitles == null || mEntryTitles.length <= index) {
return null;
}
return mEntryTitles[index];
}
/**
* @return the value at the specified index
*/
protected int getValueAt(int index) {
return mEntryValues[index];
}
@Override
public CharSequence getSummary() {
if (mValueIndex >= 0) {
return getTitleAt(mValueIndex);
}
return null;
}
@Override
protected void onPrepareDialogBuilder(Builder builder) {
super.onPrepareDialogBuilder(builder);
final Context context = getContext();
final int dialogLayout = getDialogLayoutResource();
final View picker = LayoutInflater.from(context).inflate(dialogLayout, null);
final ListPreferenceAdapter adapter = new ListPreferenceAdapter();
final AbsListView list = (AbsListView) picker.findViewById(android.R.id.list);
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
if (callChangeListener((int) id)) {
setValue((int) id);
}
final Dialog dialog = getDialog();
if (dialog != null) {
dialog.dismiss();
}
}
});
// Set initial selection.
final int selectedPosition = getIndexForValue(mValue);
if (selectedPosition != AbsListView.INVALID_POSITION) {
list.setSelection(selectedPosition);
}
builder.setView(picker);
builder.setPositiveButton(null, null);
}
/**
* @return the index of the specified value within the list of entry values,
* or {@link AbsListView#INVALID_POSITION} if not found
*/
protected int getIndexForValue(int value) {
final int[] values = mEntryValues;
final int count = values.length;
for (int i = 0; i < count; i++) {
if (values[i] == value) {
return i;
}
}
return AbsListView.INVALID_POSITION;
}
/**
* Sets the current value. If the value exists within the set of entry
* values, updates the selection index.
*
* @param value the value to set
*/
public void setValue(int value) {
final boolean changed = mValue != value;
if (changed || !mValueSet) {
mValue = value;
mValueIndex = getIndexForValue(value);
mValueSet = true;
persistInt(value);
if (changed) {
notifyDependencyChange(shouldDisableDependents());
notifyChanged();
}
if (mOnValueChangedListener != null) {
mOnValueChangedListener.onValueChanged(this, value);
}
}
}
/**
* @return the current value
*/
public int getValue() {
return mValue;
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getInt(index, 0);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setValue(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue);
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
// No need to save instance state since it's persistent
return superState;
}
final SavedState myState = new SavedState(superState);
myState.value = getValue();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
setValue(myState.value);
}
private class ListPreferenceAdapter extends BaseAdapter {
private LayoutInflater mInflater;
@Override
public int getCount() {
return mEntryValues.length;
}
@Override
public Integer getItem(int position) {
return mEntryValues[position];
}
@Override
public long getItemId(int position) {
return mEntryValues[position];
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
if (mInflater == null) {
mInflater = LayoutInflater.from(parent.getContext());
}
convertView = mInflater.inflate(mListItemLayout, parent, false);
}
onBindListItem(convertView, position);
return convertView;
}
}
private static class SavedState extends BaseSavedState {
public int value;
public SavedState(Parcel source) {
super(source);
value = source.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(value);
}
public SavedState(Parcelable superState) {
super(superState);
}
@SuppressWarnings({ "hiding", "unused" })
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
public interface OnValueChangedListener {
public void onValueChanged(ListDialogPreference preference, int value);
}
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright (C) 2013 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 android.content.Context;
import android.content.res.Resources;
import android.preference.ListPreference;
import android.util.AttributeSet;
import com.android.settings.R;
import java.text.Collator;
import java.util.Arrays;
import java.util.Locale;
/**
* List preference that allows the user to pick a locale from the list of
* supported device locales.
*/
public class LocalePreference extends ListPreference {
public LocalePreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public LocalePreference(Context context) {
super(context);
init(context);
}
public void init(Context context) {
final String[] systemLocales = Resources.getSystem().getAssets().getLocales();
Arrays.sort(systemLocales);
final Resources resources = context.getResources();
final String[] specialLocaleCodes = resources.getStringArray(
com.android.internal.R.array.special_locale_codes);
final String[] specialLocaleNames = resources.getStringArray(
com.android.internal.R.array.special_locale_names);
int finalSize = 0;
final int origSize = systemLocales.length;
final LocaleInfo[] localeInfos = new LocaleInfo[origSize];
for (int i = 0; i < origSize; i++) {
final String localeStr = systemLocales[i];
final int len = localeStr.length();
if (len != 5) {
continue;
}
final String language = localeStr.substring(0, 2);
final String country = localeStr.substring(3, 5);
final Locale l = new Locale(language, country);
if (finalSize == 0) {
localeInfos[finalSize++] = new LocaleInfo(l.getDisplayLanguage(l), l);
} else {
// check previous entry:
// same lang and a country -> upgrade to full name and
// insert ours with full name
// diff lang -> insert ours with lang-only name
final LocaleInfo previous = localeInfos[finalSize - 1];
if (previous.locale.getLanguage().equals(language)
&& !previous.locale.getLanguage().equals("zz")) {
previous.label = getDisplayName(
localeInfos[finalSize - 1].locale, specialLocaleCodes,
specialLocaleNames);
localeInfos[finalSize++] = new LocaleInfo(getDisplayName(l,
specialLocaleCodes, specialLocaleNames), l);
} else {
final String displayName;
if (localeStr.equals("zz_ZZ")) {
displayName = "[Developer] Accented English";
} else if (localeStr.equals("zz_ZY")) {
displayName = "[Developer] Fake Bi-Directional";
} else {
displayName = l.getDisplayLanguage(l);
}
localeInfos[finalSize++] = new LocaleInfo(displayName, l);
}
}
}
final CharSequence[] entries = new CharSequence[finalSize + 1];
final CharSequence[] entryValues = new CharSequence[finalSize + 1];
Arrays.sort(localeInfos, 0, finalSize);
entries[0] = resources.getString(R.string.locale_default);
entryValues[0] = "";
for (int i = 0; i < finalSize; i++) {
final LocaleInfo info = localeInfos[i];
entries[i + 1] = info.toString();
entryValues[i + 1] = info.locale.toString();
}
setEntries(entries);
setEntryValues(entryValues);
}
private static String getDisplayName(
Locale l, String[] specialLocaleCodes, String[] specialLocaleNames) {
String code = l.toString();
for (int i = 0; i < specialLocaleCodes.length; i++) {
if (specialLocaleCodes[i].equals(code)) {
return specialLocaleNames[i];
}
}
return l.getDisplayName(l);
}
private static class LocaleInfo implements Comparable<LocaleInfo> {
private static final Collator sCollator = Collator.getInstance();
public String label;
public Locale locale;
public LocaleInfo(String label, Locale locale) {
this.label = label;
this.locale = locale;
}
@Override
public String toString() {
return label;
}
@Override
public int compareTo(LocaleInfo another) {
return sCollator.compare(this.label, another.label);
}
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2013 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 android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import android.widget.TextView;
import com.android.settings.R;
public class PresetPreference extends ListDialogPreference {
public PresetPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.grid_picker_dialog);
setListItemLayoutResource(R.layout.preset_picker_item);
}
@Override
public boolean shouldDisableDependents() {
return getValue() != CaptionStyle.PRESET_CUSTOM
|| super.shouldDisableDependents();
}
@Override
protected void onBindListItem(View view, int index) {
final CaptioningTextView previewText = (CaptioningTextView) view.findViewById(
R.id.preview);
final int value = getValueAt(index);
ToggleCaptioningPreferenceFragment.applyCaptionProperties(previewText, value);
final CharSequence title = getTitleAt(index);
if (title != null) {
final TextView summary = (TextView) view.findViewById(R.id.summary);
summary.setText(title);
}
}
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (C) 2013 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 android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Bundle;
import android.preference.PreferenceFrameLayout;
import android.provider.Settings;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.CaptioningManager;
import android.view.accessibility.CaptioningManager.CaptionStyle;
import com.android.settings.R;
import com.android.settings.accessibility.ToggleSwitch.OnBeforeCheckedChangeListener;
import java.util.Locale;
public class ToggleCaptioningPreferenceFragment extends Fragment {
private CaptionPropertiesFragment mPropsFragment;
private CaptioningTextView mPreviewText;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.captioning_preview, container, false);
// We have to do this now because PreferenceFrameLayout looks at it
// only when the view is added.
if (container instanceof PreferenceFrameLayout) {
((PreferenceFrameLayout.LayoutParams) rootView.getLayoutParams()).removeBorders = true;
}
return rootView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mPropsFragment = ((CaptionPropertiesFragment) getFragmentManager()
.findFragmentById(R.id.properties_fragment));
mPropsFragment.setParent(this);
mPreviewText = (CaptioningTextView) view.findViewById(R.id.preview_text);
installActionBarToggleSwitch();
refreshPreviewText();
}
public void refreshPreviewText() {
final CaptioningTextView preview = mPreviewText;
if (preview != null) {
final Activity activity = getActivity();
final ContentResolver cr = activity.getContentResolver();
final int styleId = CaptionStyle.getRawPreset(cr);
applyCaptionProperties(preview, styleId);
final Locale locale = CaptioningManager.getLocale(cr);
if (locale != null) {
final CharSequence localizedText = AccessibilityUtils.getTextForLocale(
activity, locale, R.string.captioning_preview_text);
preview.setText(localizedText);
}
}
}
public static void applyCaptionProperties(CaptioningTextView previewText, int styleId) {
previewText.applyStyleAndFontSize(styleId);
final Context context = previewText.getContext();
final ContentResolver cr = context.getContentResolver();
final Locale locale = CaptioningManager.getLocale(cr);
if (locale != null) {
final CharSequence localizedText = AccessibilityUtils.getTextForLocale(
context, locale, R.string.captioning_preview_characters);
previewText.setText(localizedText);
}
}
private void installActionBarToggleSwitch() {
final Activity activity = getActivity();
final ToggleSwitch toggleSwitch = new ToggleSwitch(activity);
final int padding = getResources().getDimensionPixelSize(
R.dimen.action_bar_switch_padding);
toggleSwitch.setPaddingRelative(0, 0, padding, 0);
final ActionBar actionBar = activity.getActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM);
final ActionBar.LayoutParams params = new ActionBar.LayoutParams(
ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT,
Gravity.CENTER_VERTICAL | Gravity.END);
actionBar.setCustomView(toggleSwitch, params);
final boolean enabled = CaptioningManager.isEnabled(getActivity().getContentResolver());
mPropsFragment.getPreferenceScreen().setEnabled(enabled);
mPreviewText.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
toggleSwitch.setCheckedInternal(enabled);
toggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() {
@Override
public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
toggleSwitch.setCheckedInternal(checked);
Settings.Secure.putInt(getActivity().getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, checked ? 1 : 0);
mPropsFragment.getPreferenceScreen().setEnabled(checked);
mPreviewText.setVisibility(checked ? View.VISIBLE : View.INVISIBLE);
return false;
}
});
}
}