summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res-keyguard/values/strings.xml3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java67
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java91
4 files changed, 162 insertions, 1 deletions
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 2f5222744a86..1efa3a81e5ab 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -102,6 +102,9 @@
<string name="keyguard_widget_12_hours_format" translatable="false">h\uee01mm</string>
<!-- Time format strings for fall-back clock widget -->
<string name="keyguard_widget_24_hours_format" translatable="false">kk\uee01mm</string>
+ <!-- The character used in keyguard_widget_12_hours_format and keyguard_widget_24_hours_format
+ to represent a ":". -->
+ <string name="keyguard_fancy_colon" translatable="false">\uee01</string>
<!-- Accessibility description of the PIN password view. [CHAR_LIMIT=none] -->
<string name="keyguard_accessibility_pin_area">PIN area</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
new file mode 100644
index 000000000000..80509a689a64
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockAccessibilityDelegate.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 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.keyguard;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.TextView;
+
+/**
+ * Replaces fancy colons with regular colons. Only works on TextViews.
+ */
+class KeyguardClockAccessibilityDelegate extends View.AccessibilityDelegate {
+ private final String mFancyColon;
+
+ public KeyguardClockAccessibilityDelegate(Context context) {
+ mFancyColon = context.getString(R.string.keyguard_fancy_colon);
+ }
+
+ @Override
+ public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(host, event);
+ CharSequence text = event.getContentDescription();
+ if (!TextUtils.isEmpty(text)) {
+ event.setContentDescription(replaceFancyColon(text));
+ }
+ }
+
+ @Override
+ public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
+ CharSequence text = ((TextView) host).getText();
+ if (!TextUtils.isEmpty(text)) {
+ event.getText().add(replaceFancyColon(text));
+ }
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ if (!TextUtils.isEmpty(info.getText())) {
+ info.setText(replaceFancyColon(info.getText()));
+ }
+ if (!TextUtils.isEmpty(info.getContentDescription())) {
+ info.setContentDescription(replaceFancyColon(info.getContentDescription()));
+ }
+ }
+
+ private CharSequence replaceFancyColon(CharSequence text) {
+ return text.toString().replace(mFancyColon, ":");
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 162faa595ed3..d4d69ffd3b7c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -38,7 +38,6 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ChargingView;
-import java.util.Arrays;
import java.util.Locale;
public class KeyguardStatusView extends GridLayout {
@@ -121,6 +120,7 @@ public class KeyguardStatusView extends GridLayout {
mClockView = findViewById(R.id.clock_view);
mDateView.setShowCurrentUserTime(true);
mClockView.setShowCurrentUserTime(true);
+ mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
mOwnerInfo = findViewById(R.id.owner_info);
mBatteryDoze = findViewById(R.id.battery_doze);
mVisibleInDoze = new View[]{mBatteryDoze, mClockView};
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
new file mode 100644
index 000000000000..1c9f8133a15f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockAccessibilityDelegateTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 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.keyguard;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.text.TextUtils;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.TextView;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+public class KeyguardClockAccessibilityDelegateTest {
+
+ private Context mContext;
+ private TextView mView;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+ mView = new TextView(mContext);
+ mView.setText(R.string.keyguard_widget_12_hours_format);
+ mView.setContentDescription(mContext.getString(R.string.keyguard_widget_12_hours_format));
+ mView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
+ }
+
+ @Test
+ public void onInitializeAccessibilityEvent_producesNonEmptyAsciiContentDesc() throws Exception {
+ AccessibilityEvent ev = AccessibilityEvent.obtain();
+ mView.onInitializeAccessibilityEvent(ev);
+
+ assertFalse(TextUtils.isEmpty(ev.getContentDescription()));
+ assertTrue(isAscii(ev.getContentDescription()));
+ }
+
+ @Test
+ public void onPopulateAccessibilityEvent_producesNonEmptyAsciiText() throws Exception {
+ AccessibilityEvent ev = AccessibilityEvent.obtain();
+ mView.onPopulateAccessibilityEvent(ev);
+
+ assertFalse(isEmpty(ev.getText()));
+ assertTrue(isAscii(ev.getText()));
+ }
+
+ @Test
+ public void onInitializeAccessibilityNodeInfo_producesNonEmptyAsciiText() throws Exception {
+ AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+ // Usually done in View.onInitializeAccessibilityNodeInfoInternal, but only when attached.
+ info.setContentDescription(mView.getContentDescription());
+ mView.onInitializeAccessibilityNodeInfo(info);
+
+ assertFalse(TextUtils.isEmpty(info.getText()));
+ assertTrue(isAscii(info.getText()));
+
+ assertFalse(TextUtils.isEmpty(info.getContentDescription()));
+ assertTrue(isAscii(info.getContentDescription()));
+ }
+
+ private boolean isAscii(CharSequence text) {
+ return text.chars().allMatch((i) -> i < 128);
+ }
+
+ private boolean isAscii(List<CharSequence> texts) {
+ return texts.stream().allMatch(this::isAscii);
+ }
+
+ private boolean isEmpty(List<CharSequence> texts) {
+ return texts.stream().allMatch(TextUtils::isEmpty);
+ }
+} \ No newline at end of file