1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/*
2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project
3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License");
5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License.
6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at
7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *      http://www.apache.org/licenses/LICENSE-2.0
9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd *
10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software
11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS,
12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and
14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License.
15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */
16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.util;
17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context;
19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.res.Resources;
20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v4.view.accessibility.AccessibilityEventCompat;
21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.support.v4.view.accessibility.AccessibilityRecordCompat;
22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.text.TextUtils;
23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.View;
24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.accessibility.AccessibilityEvent;
25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.view.accessibility.AccessibilityManager;
26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.Factory;
28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.R;
29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport javax.annotation.Nullable;
31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class AccessibilityUtil {
33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static String sContentDescriptionDivider;
34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static boolean isTouchExplorationEnabled(final Context context) {
36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final AccessibilityManager accessibilityManager = (AccessibilityManager)
37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                context.getSystemService(Context.ACCESSIBILITY_SERVICE);
38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return accessibilityManager.isTouchExplorationEnabled();
39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static StringBuilder appendContentDescription(final Context context,
42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final StringBuilder contentDescription, final String val) {
43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (sContentDescriptionDivider == null) {
44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            sContentDescriptionDivider =
45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    context.getResources().getString(R.string.enumeration_comma);
46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (contentDescription.length() != 0) {
48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            contentDescription.append(sContentDescriptionDivider);
49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        contentDescription.append(val);
51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return contentDescription;
52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static void announceForAccessibilityCompat(
55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final View view, @Nullable final AccessibilityManager accessibilityManager,
56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final int textResourceId) {
57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final String text = Factory.get().getApplicationContext().getResources().getString(
58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                textResourceId);
59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        announceForAccessibilityCompat(view, accessibilityManager, text);
60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static void announceForAccessibilityCompat(
63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final View view, @Nullable AccessibilityManager accessibilityManager,
64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final CharSequence text) {
65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final Context context = view.getContext().getApplicationContext();
66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (accessibilityManager == null) {
67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            accessibilityManager = (AccessibilityManager) context.getSystemService(
68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                    Context.ACCESSIBILITY_SERVICE);
69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (!accessibilityManager.isEnabled()) {
72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return;
73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Jelly Bean added support for speaking text verbatim
76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final int eventType = OsUtil.isAtLeastJB() ? AccessibilityEvent.TYPE_ANNOUNCEMENT
77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                : AccessibilityEvent.TYPE_VIEW_FOCUSED;
78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Construct an accessibility event with the minimum recommended
80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // attributes. An event without a class name or package may be dropped.
81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        event.getText().add(text);
83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        event.setEnabled(view.isEnabled());
84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        event.setClassName(view.getClass().getName());
85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        event.setPackageName(context.getPackageName());
86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // JellyBean MR1 requires a source view to set the window ID.
88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        record.setSource(view);
90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // Sends the event directly through the accessibility manager. If we only supported SDK 14+
92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // we could have done:
93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        // getParent().requestSendAccessibilityEvent(this, event);
94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        accessibilityManager.sendAccessibilityEvent(event);
95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    /**
98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * Check to see if the current layout is Right-to-Left. This check is only supported for
99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * API 17+.
100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * For earlier versions, this method will just return false.
101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     * @return boolean Boolean indicating whether the currently locale is RTL.
102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd     */
103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static boolean isLayoutRtl(final View view) {
104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (OsUtil.isAtLeastJB_MR1()) {
105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return View.LAYOUT_DIRECTION_RTL == view.getLayoutDirection();
106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        } else {
107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return false;
108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static String getVocalizedPhoneNumber(final Resources res, final String phoneNumber) {
112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        if (TextUtils.isEmpty(phoneNumber)) {
113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            return "";
114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        final StringBuilder vocalizedPhoneNumber = new StringBuilder();
116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        for (final char c : phoneNumber.toCharArray()) {
117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            getVocalizedNumber(res, c, vocalizedPhoneNumber);
118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        return vocalizedPhoneNumber.toString();
120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd
122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    public static void getVocalizedNumber(final Resources res, final char c,
123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            final StringBuilder builder) {
124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        switch (c) {
125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '0':
126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_zero));
127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '1':
130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_one));
131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '2':
134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_two));
135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '3':
138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_three));
139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '4':
142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_four));
143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '5':
146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_five));
147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '6':
150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_six));
151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '7':
154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_seven));
155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '8':
158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_eight));
159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            case '9':
162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(res.getString(R.string.content_description_for_number_nine));
163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(" ");
164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd            default:
166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                builder.append(c);
167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd                return;
168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd        }
169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd    }
170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd}
171