diff options
Diffstat (limited to 'java/com/android/dialer/oem')
11 files changed, 705 insertions, 0 deletions
diff --git a/java/com/android/dialer/oem/AndroidManifest.xml b/java/com/android/dialer/oem/AndroidManifest.xml new file mode 100644 index 000000000..9e0373ab4 --- /dev/null +++ b/java/com/android/dialer/oem/AndroidManifest.xml @@ -0,0 +1,21 @@ +<!-- 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.dialer.oem"> + <!-- This is used for querying Cequint caller id. --> + <uses-permission android:name="com.cequint.ecid.CALLER_ID_LOOKUP"/> + +</manifest>
\ No newline at end of file diff --git a/java/com/android/dialer/oem/CequintCallerIdManager.java b/java/com/android/dialer/oem/CequintCallerIdManager.java new file mode 100644 index 000000000..095ee4e66 --- /dev/null +++ b/java/com/android/dialer/oem/CequintCallerIdManager.java @@ -0,0 +1,317 @@ +/* + * 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.dialer.oem; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.pm.PackageManager; +import android.database.ContentObserver; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build.VERSION_CODES; +import android.support.annotation.AnyThread; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.WorkerThread; +import android.telephony.PhoneNumberUtils; +import android.text.TextUtils; +import com.android.dialer.common.Assert; +import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.common.LogUtil; +import com.android.dialer.util.PermissionsUtil; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Cequint Caller ID manager to provide caller information. + * + * <p>This is only enabled on Motorola devices for Sprint. + * + * <p>If it's enabled, this class will be called by call log and incall to get caller info from + * Cequint Caller ID. It also caches any information fetched in static map, which lives through + * whole application lifecycle. + */ +@TargetApi(VERSION_CODES.M) +public class CequintCallerIdManager { + + private static final String CONFIG_CALLER_ID_ENABLED = "config_caller_id_enabled"; + + private static final String PROVIDER_NAME = "com.cequint.ecid"; + + private static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/lookup"); + + private static final int CALLER_ID_LOOKUP_USER_PROVIDED_CID = 0x0001; + private static final int CALLER_ID_LOOKUP_SYSTEM_PROVIDED_CID = 0x0002; + private static final int CALLER_ID_LOOKUP_INCOMING_CALL = 0x0020; + + private static final Uri CONTENT_URI_FOR_INCALL = + Uri.parse("content://" + PROVIDER_NAME + "/incalllookup"); + + private static final String[] EMPTY_PROJECTION = new String[] {}; + + // Column names in Cequint provider. + private static final String CITY_NAME = "cid_pCityName"; + private static final String STATE_NAME = "cid_pStateName"; + private static final String STATE_ABBR = "cid_pStateAbbr"; + private static final String COUNTRY_NAME = "cid_pCountryName"; + private static final String COMPANY = "cid_pCompany"; + private static final String NAME = "cid_pName"; + private static final String FIRST_NAME = "cid_pFirstName"; + private static final String LAST_NAME = "cid_pLastName"; + private static final String IMAGE = "cid_pLogo"; + private static final String DISPLAY_NAME = "cid_pDisplayName"; + + // TODO: Revisit it and maybe remove it if it's not necessary. + private static final ConcurrentHashMap<String, CequintCallerIdContact> callLogCache = + new ConcurrentHashMap<>(); + private static final ConcurrentHashMap<String, CequintCallerIdContact> incallIncomingCallCache = + new ConcurrentHashMap<>(); + private static final ConcurrentHashMap<String, CequintCallerIdContact> incallOutgoingCallCache = + new ConcurrentHashMap<>(); + private static boolean hasRegisteredContentObserver; + private static boolean hasAlreadyCheckedCequintCallerIdPackage; + private static boolean isCequintCallerIdEnabled; + + /** Cequint caller id contact information. */ + public static class CequintCallerIdContact { + public final String name; + public final String geoDescription; + public final String imageUrl; + + private CequintCallerIdContact(String name, String geoDescription, String imageUrl) { + this.name = name; + this.geoDescription = geoDescription; + this.imageUrl = imageUrl; + } + } + + /** Check whether Cequint Caller Id provider package is available and enabled. */ + @AnyThread + public static synchronized boolean isCequintCallerIdEnabled(@NonNull Context context) { + if (!ConfigProviderBindings.get(context).getBoolean(CONFIG_CALLER_ID_ENABLED, true)) { + return false; + } + if (!hasAlreadyCheckedCequintCallerIdPackage) { + hasAlreadyCheckedCequintCallerIdPackage = true; + isCequintCallerIdEnabled = false; + + try { + context.getPackageManager().getPackageInfo(PROVIDER_NAME, 0); + isCequintCallerIdEnabled = true; + } catch (PackageManager.NameNotFoundException e) { + isCequintCallerIdEnabled = false; + } + } + return isCequintCallerIdEnabled; + } + + @WorkerThread + @Nullable + public static CequintCallerIdContact getCequintCallerIdContact(Context context, String number) { + Assert.isWorkerThread(); + LogUtil.d( + "CequintCallerIdManager.getCequintCallerIdContact", + "number: %s", + LogUtil.sanitizePhoneNumber(number)); + if (callLogCache.containsKey(number)) { + return callLogCache.get(number); + } + CequintCallerIdContact cequintCallerIdContact = + lookup( + context, + CONTENT_URI, + PhoneNumberUtils.stripSeparators(number), + new String[] {"system"}); + if (cequintCallerIdContact != null) { + callLogCache.put(number, cequintCallerIdContact); + } + return cequintCallerIdContact; + } + + @WorkerThread + @Nullable + public static CequintCallerIdContact getCequintCallerIdContactForInCall( + Context context, String number, String cnapName, boolean isIncoming) { + Assert.isWorkerThread(); + LogUtil.d( + "CequintCallerIdManager.getCequintCallerIdContactForInCall", + "number: %s, cnapName: %s, isIncoming: %b", + LogUtil.sanitizePhoneNumber(number), + LogUtil.sanitizePii(cnapName), + isIncoming); + registerContentObserver(context); + if (isIncoming && incallIncomingCallCache.containsKey(number)) { + return incallIncomingCallCache.get(number); + } else if (!isIncoming && incallOutgoingCallCache.containsKey(number)) { + return incallOutgoingCallCache.get(number); + } + int flag = 0; + if (isIncoming) { + flag |= CALLER_ID_LOOKUP_INCOMING_CALL; + flag |= CALLER_ID_LOOKUP_SYSTEM_PROVIDED_CID; + } else { + flag |= CALLER_ID_LOOKUP_USER_PROVIDED_CID; + } + String[] flags = {cnapName, String.valueOf(flag)}; + CequintCallerIdContact cequintCallerIdContact = + lookup(context, CONTENT_URI_FOR_INCALL, number, flags); + if (cequintCallerIdContact != null) { + if (isIncoming) { + incallIncomingCallCache.put(number, cequintCallerIdContact); + } else { + incallOutgoingCallCache.put(number, cequintCallerIdContact); + } + } + return cequintCallerIdContact; + } + + @WorkerThread + @Nullable + private static CequintCallerIdContact lookup( + Context context, Uri uri, @NonNull String number, String[] flags) { + Assert.isWorkerThread(); + Assert.isNotNull(number); + + // Cequint is using custom arguments for content provider. See more details in b/35766080. + try (Cursor cursor = + context.getContentResolver().query(uri, EMPTY_PROJECTION, number, flags, null)) { + if (cursor != null && cursor.moveToFirst()) { + String city = getString(cursor, cursor.getColumnIndex(CITY_NAME)); + String state = getString(cursor, cursor.getColumnIndex(STATE_NAME)); + String stateAbbr = getString(cursor, cursor.getColumnIndex(STATE_ABBR)); + String country = getString(cursor, cursor.getColumnIndex(COUNTRY_NAME)); + String company = getString(cursor, cursor.getColumnIndex(COMPANY)); + String name = getString(cursor, cursor.getColumnIndex(NAME)); + String firstName = getString(cursor, cursor.getColumnIndex(FIRST_NAME)); + String lastName = getString(cursor, cursor.getColumnIndex(LAST_NAME)); + String imageUrl = getString(cursor, cursor.getColumnIndex(IMAGE)); + String displayName = getString(cursor, cursor.getColumnIndex(DISPLAY_NAME)); + + String contactName = + TextUtils.isEmpty(displayName) + ? generateDisplayName(firstName, lastName, company, name) + : displayName; + String geoDescription = getGeoDescription(city, state, stateAbbr, country); + LogUtil.d( + "CequintCallerIdManager.lookup", + "number: %s, contact name: %s, geo: %s, photo url: %s", + LogUtil.sanitizePhoneNumber(number), + LogUtil.sanitizePii(contactName), + LogUtil.sanitizePii(geoDescription), + imageUrl); + return new CequintCallerIdContact(contactName, geoDescription, imageUrl); + } else { + LogUtil.d("CequintCallerIdManager.lookup", "No CequintCallerIdContact found"); + return null; + } + } catch (Exception e) { + LogUtil.e("CequintCallerIdManager.lookup", "exception on query", e); + return null; + } + } + + private static String getString(Cursor cursor, int columnIndex) { + if (!cursor.isNull(columnIndex)) { + String string = cursor.getString(columnIndex); + if (!TextUtils.isEmpty(string)) { + return string; + } + } + return null; + } + + /** + * Returns generated name from other names, e.g. first name, last name etc. Returns null if there + * is no other names. + */ + @Nullable + private static String generateDisplayName( + String firstName, String lastName, String company, String name) { + boolean hasFirstName = !TextUtils.isEmpty(firstName); + boolean hasLastName = !TextUtils.isEmpty(lastName); + boolean hasCompanyName = !TextUtils.isEmpty(company); + boolean hasName = !TextUtils.isEmpty(name); + + StringBuilder stringBuilder = new StringBuilder(); + + if (hasFirstName || hasLastName) { + if (hasFirstName) { + stringBuilder.append(firstName); + if (hasLastName) { + stringBuilder.append(" "); + } + } + if (hasLastName) { + stringBuilder.append(lastName); + } + } else if (hasCompanyName) { + stringBuilder.append(company); + } else if (hasName) { + stringBuilder.append(name); + } else { + return null; + } + + if (stringBuilder.length() > 0) { + return stringBuilder.toString(); + } + return null; + } + + /** Returns geo location information. e.g. Mountain View, CA. */ + private static String getGeoDescription( + String city, String state, String stateAbbr, String country) { + String geoDescription = null; + + if (TextUtils.isEmpty(city) && !TextUtils.isEmpty(state)) { + geoDescription = state; + } else if (!TextUtils.isEmpty(city) && !TextUtils.isEmpty(stateAbbr)) { + geoDescription = city + ", " + stateAbbr; + } else if (!TextUtils.isEmpty(country)) { + geoDescription = country; + } + return geoDescription; + } + + private static synchronized void registerContentObserver(Context context) { + if (!PermissionsUtil.hasCequintPermissions(context)) { + LogUtil.i("CequintCallerIdManager.registerContentObserver", "no cequint permissions"); + return; + } + + if (hasRegisteredContentObserver) { + return; + } + ContentObserver contentObserver = + new ContentObserver(null) { + @Override + public void onChange(boolean selfChange) { + invalidateCache(); + } + }; + + context + .getContentResolver() + .registerContentObserver(CONTENT_URI_FOR_INCALL, true, contentObserver); + hasRegisteredContentObserver = true; + } + + private static void invalidateCache() { + incallIncomingCallCache.clear(); + incallOutgoingCallCache.clear(); + } + + private CequintCallerIdManager() {} +} diff --git a/java/com/android/dialer/oem/MotorolaHiddenMenuKeySequence.java b/java/com/android/dialer/oem/MotorolaHiddenMenuKeySequence.java new file mode 100644 index 000000000..9cf145b7a --- /dev/null +++ b/java/com/android/dialer/oem/MotorolaHiddenMenuKeySequence.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * This file is derived in part from code issued under the following license. + * + * 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.dialer.oem; + +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import com.android.dialer.common.LogUtil; +import java.util.regex.Pattern; + +/** + * Util class to handle special char sequence and launch corresponding intent based the sequence. + */ +public class MotorolaHiddenMenuKeySequence { + private static final String EXTRA_HIDDEN_MENU_CODE = "HiddenMenuCode"; + private static MotorolaHiddenMenuKeySequence instance = null; + + private static String[] hiddenKeySequenceArray = null; + private static String[] hiddenKeySequenceIntentArray = null; + private static String[] hiddenKeyPatternArray = null; + private static String[] hiddenKeyPatternIntentArray = null; + private static boolean featureHiddenMenuEnabled = false; + + /** + * Handle input char sequence. + * + * @param context context + * @param input input sequence + * @return true if the input matches any pattern + */ + static boolean handleCharSequence(Context context, String input) { + getInstance(context); + if (!featureHiddenMenuEnabled) { + return false; + } + return handleKeySequence(context, input) || handleKeyPattern(context, input); + } + + /** + * Public interface to return the Singleton instance + * + * @param context the Context + * @return the MotorolaHiddenMenuKeySequence singleton instance + */ + private static synchronized MotorolaHiddenMenuKeySequence getInstance(Context context) { + if (null == instance) { + instance = new MotorolaHiddenMenuKeySequence(context); + } + return instance; + } + + private MotorolaHiddenMenuKeySequence(Context context) { + featureHiddenMenuEnabled = + MotorolaUtils.isSpnMatched(context) + && context.getResources().getBoolean(R.bool.motorola_feature_hidden_menu); + // In case we do have a SPN from resource we need to match from service; otherwise we are + // free to go + if (featureHiddenMenuEnabled) { + + hiddenKeySequenceArray = + context.getResources().getStringArray(R.array.motorola_hidden_menu_key_sequence); + hiddenKeySequenceIntentArray = + context.getResources().getStringArray(R.array.motorola_hidden_menu_key_sequence_intents); + hiddenKeyPatternArray = + context.getResources().getStringArray(R.array.motorola_hidden_menu_key_pattern); + hiddenKeyPatternIntentArray = + context.getResources().getStringArray(R.array.motorola_hidden_menu_key_pattern_intents); + + if (hiddenKeySequenceArray.length != hiddenKeySequenceIntentArray.length + || hiddenKeyPatternArray.length != hiddenKeyPatternIntentArray.length + || (hiddenKeySequenceArray.length == 0 && hiddenKeyPatternArray.length == 0)) { + LogUtil.e( + "MotorolaHiddenMenuKeySequence", + "the key sequence array is not matching, turn off feature." + + "key sequence: %d != %d, key pattern %d != %d", + hiddenKeySequenceArray.length, + hiddenKeySequenceIntentArray.length, + hiddenKeyPatternArray.length, + hiddenKeyPatternIntentArray.length); + featureHiddenMenuEnabled = false; + } + } + } + + private static boolean handleKeyPattern(Context context, String input) { + int len = input.length(); + if (len <= 3 || hiddenKeyPatternArray == null || hiddenKeyPatternIntentArray == null) { + return false; + } + + for (int i = 0; i < hiddenKeyPatternArray.length; i++) { + if ((Pattern.compile(hiddenKeyPatternArray[i])).matcher(input).matches()) { + return sendIntent(context, input, hiddenKeyPatternIntentArray[i]); + } + } + return false; + } + + private static boolean handleKeySequence(Context context, String input) { + int len = input.length(); + if (len <= 3 || hiddenKeySequenceArray == null || hiddenKeySequenceIntentArray == null) { + return false; + } + + for (int i = 0; i < hiddenKeySequenceArray.length; i++) { + if (hiddenKeySequenceArray[i].equals(input)) { + return sendIntent(context, input, hiddenKeySequenceIntentArray[i]); + } + } + return false; + } + + private static boolean sendIntent( + final Context context, final String input, final String action) { + LogUtil.d("MotorolaHiddenMenuKeySequence.sendIntent", "input: %s", input); + try { + Intent intent = new Intent(action); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(EXTRA_HIDDEN_MENU_CODE, input); + + ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0); + + if (resolveInfo != null + && resolveInfo.activityInfo != null + && resolveInfo.activityInfo.enabled) { + context.startActivity(intent); + return true; + } else { + LogUtil.w("MotorolaHiddenMenuKeySequence.sendIntent", "not able to resolve the intent"); + } + } catch (ActivityNotFoundException e) { + LogUtil.e( + "MotorolaHiddenMenuKeySequence.sendIntent", "handleHiddenMenu Key Pattern Exception", e); + } + return false; + } +} diff --git a/java/com/android/dialer/oem/MotorolaUtils.java b/java/com/android/dialer/oem/MotorolaUtils.java new file mode 100644 index 000000000..db2b8909a --- /dev/null +++ b/java/com/android/dialer/oem/MotorolaUtils.java @@ -0,0 +1,118 @@ +/* + * 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.dialer.oem; + +import android.content.Context; +import android.content.res.Resources; +import android.telephony.TelephonyManager; +import com.android.dialer.common.ConfigProviderBindings; +import com.android.dialer.common.PackageUtils; + +/** Util class for Motorola OEM devices. */ +public class MotorolaUtils { + + private static final String CONFIG_HD_CODEC_BLINKING_ICON_WHEN_CONNECTING_CALL_ENABLED = + "hd_codec_blinking_icon_when_connecting_enabled"; + private static final String CONFIG_HD_CODEC_SHOW_ICON_IN_NOTIFICATION_ENABLED = + "hd_codec_show_icon_in_notification_enabled"; + private static final String CONFIG_HD_CODEC_SHOW_ICON_IN_CALL_LOG_ENABLED = + "hd_codec_show_icon_in_call_log_enabled"; + private static final String CONFIG_WIFI_CALL_SHOW_ICON_IN_CALL_LOG_ENABLED = + "wifi_call_show_icon_in_call_log_enabled"; + + // This is used to check if a Motorola device supports HD voice call feature, which comes from + // system feature setting. + private static final String HD_CALL_FEATRURE = "com.motorola.software.sprint.hd_call"; + // This is used to check if a Motorola device supports WiFi call feature, by checking if a certain + // package is enabled. + private static final String WIFI_CALL_PACKAGE_NAME = "com.motorola.sprintwfc"; + + // Feature flag indicates it's a HD call, currently this is only used by Motorola system build. + // TODO(b/35359461): Use reference to android.provider.CallLog once it's in new SDK. + private static final int FEATURES_HD_CALL = 0x4; + // Feature flag indicates it's a WiFi call, currently this is only used by Motorola system build. + private static final int FEATURES_WIFI = 0x8; + + private static boolean hasCheckedSprintWifiCall; + private static boolean supportSprintWifiCall; + + /** + * Returns true if SPN is specified and matched the current sim operator name. This is necessary + * since mcc310-mnc000 is not sufficient to identify Sprint network. + */ + static boolean isSpnMatched(Context context) { + try { + String spnResource = context.getResources().getString(R.string.motorola_enabled_spn); + return spnResource.equalsIgnoreCase( + context.getSystemService(TelephonyManager.class).getSimOperatorName()); + } catch (Resources.NotFoundException exception) { + // If SPN is not specified we consider as not necessary to enable/disable the feature. + return true; + } + } + + public static boolean shouldBlinkHdIconWhenConnectingCall(Context context) { + return ConfigProviderBindings.get(context) + .getBoolean(CONFIG_HD_CODEC_BLINKING_ICON_WHEN_CONNECTING_CALL_ENABLED, true) + && isSupportingSprintHdCodec(context); + } + + public static boolean shouldShowHdIconInNotification(Context context) { + return ConfigProviderBindings.get(context) + .getBoolean(CONFIG_HD_CODEC_SHOW_ICON_IN_NOTIFICATION_ENABLED, true) + && isSupportingSprintHdCodec(context); + } + + public static boolean shouldShowHdIconInCallLog(Context context, int features) { + return ConfigProviderBindings.get(context) + .getBoolean(CONFIG_HD_CODEC_SHOW_ICON_IN_CALL_LOG_ENABLED, true) + && (features & FEATURES_HD_CALL) == FEATURES_HD_CALL + && isSupportingSprintHdCodec(context); + } + + public static boolean shouldShowWifiIconInCallLog(Context context, int features) { + return ConfigProviderBindings.get(context) + .getBoolean(CONFIG_WIFI_CALL_SHOW_ICON_IN_CALL_LOG_ENABLED, true) + && (features & FEATURES_WIFI) == FEATURES_WIFI + && isSupportingSprintWifiCall(context); + } + + /** + * Handle special char sequence entered in dialpad. This may launch special intent based on input. + * + * @param context context + * @param input input string + * @return true if the input is consumed and the intent is launched + */ + public static boolean handleSpecialCharSequence(Context context, String input) { + // TODO(b/35395377): Add check for Motorola devices. + return MotorolaHiddenMenuKeySequence.handleCharSequence(context, input); + } + + private static boolean isSupportingSprintHdCodec(Context context) { + return isSpnMatched(context) + && context.getResources().getBoolean(R.bool.motorola_sprint_hd_codec) + && context.getPackageManager().hasSystemFeature(HD_CALL_FEATRURE); + } + + private static boolean isSupportingSprintWifiCall(Context context) { + if (!hasCheckedSprintWifiCall) { + supportSprintWifiCall = PackageUtils.isPackageEnabled(WIFI_CALL_PACKAGE_NAME, context); + hasCheckedSprintWifiCall = true; + } + return supportSprintWifiCall; + } +} diff --git a/java/com/android/dialer/oem/res/values-mcc310-mnc000/motorola_config.xml b/java/com/android/dialer/oem/res/values-mcc310-mnc000/motorola_config.xml new file mode 100644 index 000000000..7f63bee75 --- /dev/null +++ b/java/com/android/dialer/oem/res/values-mcc310-mnc000/motorola_config.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <bool name="motorola_sprint_hd_codec">true</bool> + <bool name="motorola_feature_hidden_menu">true</bool> + <string name="motorola_enabled_spn">Sprint</string> +</resources>
\ No newline at end of file diff --git a/java/com/android/dialer/oem/res/values-mcc310-mnc120/motorola_config.xml b/java/com/android/dialer/oem/res/values-mcc310-mnc120/motorola_config.xml new file mode 100644 index 000000000..39b72cdd1 --- /dev/null +++ b/java/com/android/dialer/oem/res/values-mcc310-mnc120/motorola_config.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <bool name="motorola_sprint_hd_codec">true</bool> + <bool name="motorola_feature_hidden_menu">true</bool> +</resources>
\ No newline at end of file diff --git a/java/com/android/dialer/oem/res/values-mcc311-mnc490/motorola_config.xml b/java/com/android/dialer/oem/res/values-mcc311-mnc490/motorola_config.xml new file mode 100644 index 000000000..39b72cdd1 --- /dev/null +++ b/java/com/android/dialer/oem/res/values-mcc311-mnc490/motorola_config.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <bool name="motorola_sprint_hd_codec">true</bool> + <bool name="motorola_feature_hidden_menu">true</bool> +</resources>
\ No newline at end of file diff --git a/java/com/android/dialer/oem/res/values-mcc311-mnc870/motorola_config.xml b/java/com/android/dialer/oem/res/values-mcc311-mnc870/motorola_config.xml new file mode 100644 index 000000000..39b72cdd1 --- /dev/null +++ b/java/com/android/dialer/oem/res/values-mcc311-mnc870/motorola_config.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <bool name="motorola_sprint_hd_codec">true</bool> + <bool name="motorola_feature_hidden_menu">true</bool> +</resources>
\ No newline at end of file diff --git a/java/com/android/dialer/oem/res/values-mcc312-mnc530/motorola_config.xml b/java/com/android/dialer/oem/res/values-mcc312-mnc530/motorola_config.xml new file mode 100644 index 000000000..39b72cdd1 --- /dev/null +++ b/java/com/android/dialer/oem/res/values-mcc312-mnc530/motorola_config.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <bool name="motorola_sprint_hd_codec">true</bool> + <bool name="motorola_feature_hidden_menu">true</bool> +</resources>
\ No newline at end of file diff --git a/java/com/android/dialer/oem/res/values-mcc316-mnc010/motorola_config.xml b/java/com/android/dialer/oem/res/values-mcc316-mnc010/motorola_config.xml new file mode 100644 index 000000000..39b72cdd1 --- /dev/null +++ b/java/com/android/dialer/oem/res/values-mcc316-mnc010/motorola_config.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <bool name="motorola_sprint_hd_codec">true</bool> + <bool name="motorola_feature_hidden_menu">true</bool> +</resources>
\ No newline at end of file diff --git a/java/com/android/dialer/oem/res/values/motorola_config.xml b/java/com/android/dialer/oem/res/values/motorola_config.xml new file mode 100644 index 000000000..f875d573d --- /dev/null +++ b/java/com/android/dialer/oem/res/values/motorola_config.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <!-- Flag to control if HD codec is supported by Sprint. --> + <bool name="motorola_sprint_hd_codec">false</bool> + + <!-- Hidden menu configuration for Motorola. --> + <!-- Flag to control if the Hidden Menu sequence will be supported by Sprint. --> + <bool name="motorola_feature_hidden_menu">false</bool> + + <!-- This defines the specific key seuquence that will be catched in the SpecialCharSequenceMgr + such as, ##OMADM# --> + <string-array name="motorola_hidden_menu_key_sequence"> + <item>##66236#</item> <!--##OMADM#--> + <item>##2539#</item> <!--##AKEY#--> + <item>##786#</item> <!--##RTN#--> + <item>##72786#</item> <!--##SCRTN#--> + <item>##3282#</item> <!--##DATA#--> + <item>##33284#</item> <!--##DEBUG#--> + <item>##3424#</item> <!--##DIAG#--> + <item>##564#</item> <!--##LOG#--> + <item>##4567257#</item> <!--##GLMSCLR#--> + <item>##873283#</item> <!--##UPDATE#--> + <item>##6343#</item> <!--##MEID#--> + <item>##27263#</item> <!--##BRAND#--> + <item>##258#</item> <!--##BLV#--> + <item>##8422#</item> <!--##UICC#--> + <item>##4382#</item> <!--CMAS/WEA--> + </string-array> + + <string name="motorola_hidden_menu_intent">com.motorola.intent.action.LAUNCH_HIDDEN_MENU</string> + + <!-- This defines the intents that will be send out when the key quence is matched, this must be + in the same order with he KeySequence array. --> + <string-array name="motorola_hidden_menu_key_sequence_intents"> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>com.motorola.android.intent.action.omadm.sprint.hfa</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + <item>@string/motorola_hidden_menu_intent</item> + </string-array> + + <!-- This defines the specific key patterns that will be catched in the SpecialCharSequenceMgr + such as, ##[0-9]{3,7}# --> + <string-array name="motorola_hidden_menu_key_pattern"> + <!--##MSL#, here MSL is 6 digits SPC code, ##OTKSL#, OTKSL is also digits code --> + <item>##[0-9]{6}#</item> + </string-array> + + <!-- This defines the intents that will be send out when the key quence is matched, this must be + in the same order with he KeyPattern array. --> + <string-array name="motorola_hidden_menu_key_pattern_intents"> + <item>@string/motorola_hidden_menu_intent</item> + </string-array> +</resources>
\ No newline at end of file |