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