Merge changes Ic71e99ed,Ic7dec5ee,If801b452,Iecb99c65,I8db7e08b, ...
* changes:
Support GID1 for VVM configs
Add VVM Config for Bouygues FR
Fix new special codes
Handle concurrently deleted rows in all updateSmartDialDatabase cursors
Deleted some unused classes
Replace ContactPhotoManager with GlidePhotoManager in new call log.
Fix glide makefile
diff --git a/Android.mk b/Android.mk
index 9014a05..c69a090 100644
--- a/Android.mk
+++ b/Android.mk
@@ -109,6 +109,8 @@
dialer-mime4j-dom-target \
dialer-error-prone-target \
dialer-guava-target \
+ dialer-glide-target \
+ dialer-glide-annotation-target \
jsr305 \
libbackup \
libphonenumber \
@@ -130,11 +132,12 @@
LOCAL_ANNOTATION_PROCESSORS := \
dialer-auto-value \
+ dialer-javapoet \
dialer-dagger2 \
dialer-dagger2-compiler \
dialer-dagger2-producers \
- dialer-glide-compiler \
dialer-glide-annotation \
+ dialer-glide-compiler \
dialer-guava \
dialer-javax-annotation-api \
dialer-javax-inject \
@@ -197,7 +200,8 @@
dialer-grpc-stub:../../../prebuilts/tools/common/m2/repository/io/grpc/grpc-stub/1.0.3/grpc-stub-1.0.3.jar \
dialer-guava:../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/23.0/guava-23.0.jar \
dialer-javax-annotation-api:../../../prebuilts/tools/common/m2/repository/javax/annotation/javax.annotation-api/1.2/javax.annotation-api-1.2.jar \
- dialer-javax-inject:../../../prebuilts/tools/common/m2/repository/javax/inject/javax.inject/1/javax.inject-1.jar
+ dialer-javax-inject:../../../prebuilts/tools/common/m2/repository/javax/inject/javax.inject/1/javax.inject-1.jar \
+ dialer-javapoet:../../../prebuilts/tools/common/m2/repository/com/squareup/javapoet/1.8.0/javapoet-1.8.0.jar \
include $(BUILD_HOST_PREBUILT)
@@ -266,6 +270,16 @@
include $(CLEAR_VARS)
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_MODULE := dialer-glide-annotation-target
+LOCAL_SDK_VERSION := current
+LOCAL_SRC_FILES := ../../../prebuilts/maven_repo/bumptech/com/github/bumptech/glide/annotation/SNAPSHOT/annotation-SNAPSHOT.jar
+LOCAL_UNINSTALLABLE_MODULE := true
+
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE := dialer-javax-annotation-api-target
LOCAL_SDK_VERSION := current
LOCAL_SRC_FILES := ../../../prebuilts/tools/common/m2/repository/javax/annotation/javax.annotation-api/1.2/javax.annotation-api-1.2.jar
diff --git a/java/com/android/dialer/database/DialerDatabaseHelper.java b/java/com/android/dialer/database/DialerDatabaseHelper.java
index 8431a90..efff11e 100644
--- a/java/com/android/dialer/database/DialerDatabaseHelper.java
+++ b/java/com/android/dialer/database/DialerDatabaseHelper.java
@@ -375,7 +375,9 @@
do {
if (deletedContactCursor.isNull(DeleteContactQuery.DELETED_CONTACT_ID)) {
- LogUtil.i("DialerDatabaseHelper.removeDeletedContacts", "null contact id, skipping row");
+ LogUtil.i(
+ "DialerDatabaseHelper.removeDeletedContacts",
+ "contact_id column null. Row was deleted during iteration, skipping");
continue;
}
@@ -455,6 +457,13 @@
try {
updatedContactCursor.moveToPosition(-1);
while (updatedContactCursor.moveToNext()) {
+ if (updatedContactCursor.isNull(UpdatedContactQuery.UPDATED_CONTACT_ID)) {
+ LogUtil.i(
+ "DialerDatabaseHelper.removeUpdatedContacts",
+ "contact_id column null. Row was deleted during iteration, skipping");
+ continue;
+ }
+
final Long contactId = updatedContactCursor.getLong(UpdatedContactQuery.UPDATED_CONTACT_ID);
db.delete(Tables.SMARTDIAL_TABLE, SmartDialDbColumns.CONTACT_ID + "=" + contactId, null);
@@ -529,6 +538,13 @@
while (updatedContactCursor.moveToNext()) {
insert.clearBindings();
+ if (updatedContactCursor.isNull(PhoneQuery.PHONE_ID)) {
+ LogUtil.i(
+ "DialerDatabaseHelper.insertUpdatedContactsAndNumberPrefix",
+ "_id column null. Row was deleted during iteration, skipping");
+ continue;
+ }
+
// Handle string columns which can possibly be null first. In the case of certain
// null columns (due to malformed rows possibly inserted by third-party apps
// or sync adapters), skip the phone number row.
@@ -607,6 +623,13 @@
final SQLiteStatement insert = db.compileStatement(sqlInsert);
while (nameCursor.moveToNext()) {
+ if (nameCursor.isNull(columnIndexContactId)) {
+ LogUtil.i(
+ "DialerDatabaseHelper.insertNamePrefixes",
+ "contact_id column null. Row was deleted during iteration, skipping");
+ continue;
+ }
+
/** Computes a list of prefixes of a given contact name. */
final ArrayList<String> namePrefixes =
SmartDialPrefix.generateNamePrefixes(context, nameCursor.getString(columnIndexName));
diff --git a/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java b/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
index ca548ff..2b7209e 100644
--- a/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
+++ b/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
@@ -85,9 +85,9 @@
{
add("*#07#");
add("*#87#");
- add("#43#");
+ add("*#43#");
add("*#2727#");
- add("#88#");
+ add("*#88#");
}
};
diff --git a/java/com/android/dialer/main/impl/MainPagerAdapter.java b/java/com/android/dialer/main/impl/MainPagerAdapter.java
deleted file mode 100644
index d294640..0000000
--- a/java/com/android/dialer/main/impl/MainPagerAdapter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.main.impl;
-
-import android.content.Context;
-import android.support.annotation.IntDef;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentPagerAdapter;
-import com.android.dialer.calllog.ui.NewCallLogFragment;
-import com.android.dialer.common.Assert;
-import com.android.dialer.voicemail.listui.NewVoicemailFragment;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/** Adapter for {@link MainActivity} ViewPager. */
-final class MainPagerAdapter extends FragmentPagerAdapter {
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({
- TabIndex.SPEED_DIAL,
- TabIndex.HISTORY,
- TabIndex.VOICEMAIL,
- })
- private @interface TabIndex {
- int SPEED_DIAL = 0;
- int HISTORY = 1;
- int VOICEMAIL = 2;
- }
-
- private final Context context;
-
- MainPagerAdapter(Context context, FragmentManager fragmentManager) {
- super(fragmentManager);
- this.context = context;
- }
-
- @Override
- public int getCount() {
- // TODO(calderwoodra): add logic to hide/show voicemail tab
- return 3;
- }
-
- @Override
- public Fragment getItem(@TabIndex int position) {
- // TODO(calderwoodra): implement tabs
- switch (position) {
- case TabIndex.VOICEMAIL:
- return new NewVoicemailFragment();
- case TabIndex.HISTORY:
- return new NewCallLogFragment();
- default:
- return new StubFragment();
- }
- }
-
- @Override
- public CharSequence getPageTitle(int position) {
- switch (position) {
- case TabIndex.SPEED_DIAL:
- return context.getString(R.string.tab_title_speed_dial);
- case TabIndex.HISTORY:
- return context.getString(R.string.tab_title_call_history);
- case TabIndex.VOICEMAIL:
- return context.getString(R.string.tab_title_voicemail);
- default:
- throw Assert.createIllegalStateFailException("Tab position with no title: " + position);
- }
- }
-}
diff --git a/java/com/android/dialer/main/impl/StubFragment.java b/java/com/android/dialer/main/impl/StubFragment.java
deleted file mode 100644
index 8e0accf..0000000
--- a/java/com/android/dialer/main/impl/StubFragment.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.main.impl;
-
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-/** Stub Fragment for Dialer. */
-public class StubFragment extends Fragment {
-
- @Nullable
- @Override
- public View onCreateView(
- LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- return inflater.inflate(R.layout.stub_fragment, container, false);
- }
-}
diff --git a/java/com/android/voicemail/impl/CarrierIdentifier.java b/java/com/android/voicemail/impl/CarrierIdentifier.java
new file mode 100644
index 0000000..82b6a24
--- /dev/null
+++ b/java/com/android/voicemail/impl/CarrierIdentifier.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 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.voicemail.impl;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build.VERSION_CODES;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.TelephonyManager;
+import com.google.auto.value.AutoValue;
+
+/** Identifies a carrier. */
+@AutoValue
+@TargetApi(VERSION_CODES.O)
+@SuppressWarnings("missingpermission")
+public abstract class CarrierIdentifier {
+
+ public abstract String mccMnc();
+
+ /**
+ * Group ID Level 1. Used to identify MVNO(Mobile Virtual Network Operators) who subleases other
+ * carrier's network and share their mccMnc. MVNO should have a GID1 different from the host.
+ */
+ public abstract String gid1();
+
+ /** Builder for the matcher */
+ @AutoValue.Builder
+ public abstract static class Builder {
+
+ public abstract Builder setMccMnc(String mccMnc);
+
+ public abstract Builder setGid1(String gid1);
+
+ public abstract CarrierIdentifier build();
+ }
+
+ public static Builder builder() {
+ return new AutoValue_CarrierIdentifier.Builder().setGid1("");
+ }
+
+ public static CarrierIdentifier forHandle(
+ Context context, PhoneAccountHandle phoneAccountHandle) {
+ TelephonyManager telephonyManager =
+ context
+ .getSystemService(TelephonyManager.class)
+ .createForPhoneAccountHandle(phoneAccountHandle);
+ if (telephonyManager == null) {
+ throw new IllegalArgumentException("Invalid PhoneAccountHandle");
+ }
+ String gid1 = telephonyManager.getGroupIdLevel1();
+ if (gid1 == null) {
+ gid1 = "";
+ }
+
+ return builder().setMccMnc(telephonyManager.getSimOperator()).setGid1(gid1).build();
+ }
+}
diff --git a/java/com/android/voicemail/impl/CarrierIdentifierMatcher.java b/java/com/android/voicemail/impl/CarrierIdentifierMatcher.java
new file mode 100644
index 0000000..d7c28fe
--- /dev/null
+++ b/java/com/android/voicemail/impl/CarrierIdentifierMatcher.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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.voicemail.impl;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+
+/**
+ * Matches a {@link CarrierIdentifier}. Full equality check on CarrierIdentifiers is often unfit
+ * because non-MVNO carriers usually just specify the {@link CarrierIdentifier#mccMnc()} while their
+ * {@link CarrierIdentifier#gid1()} could be anything. This matcher ignore fields that are not
+ * specified in the matcher.
+ */
+@AutoValue
+public abstract class CarrierIdentifierMatcher {
+
+ public abstract String mccMnc();
+
+ public abstract Optional<String> gid1();
+
+ public static Builder builder() {
+ return new AutoValue_CarrierIdentifierMatcher.Builder();
+ }
+
+ /** Builder for the matcher */
+ @AutoValue.Builder
+ public abstract static class Builder {
+ public abstract Builder setMccMnc(String mccMnc);
+
+ public abstract Builder setGid1(String gid1);
+
+ public abstract CarrierIdentifierMatcher build();
+ }
+
+ public boolean matches(CarrierIdentifier carrierIdentifier) {
+ if (!mccMnc().equals(carrierIdentifier.mccMnc())) {
+ return false;
+ }
+ if (gid1().isPresent()) {
+ if (!gid1().get().equals(carrierIdentifier.gid1())) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/java/com/android/voicemail/impl/DialerVvmConfigManager.java b/java/com/android/voicemail/impl/DialerVvmConfigManager.java
new file mode 100644
index 0000000..7fa960e
--- /dev/null
+++ b/java/com/android/voicemail/impl/DialerVvmConfigManager.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2016 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.voicemail.impl;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.PersistableBundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.util.ArrayMap;
+import com.android.dialer.configprovider.ConfigProviderBindings;
+import com.android.voicemail.impl.utils.XmlUtils;
+import com.google.common.collect.ComparisonChain;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+/** Load and caches dialer vvm config from res/xml/vvm_config.xml */
+public class DialerVvmConfigManager {
+ private static class ConfigEntry implements Comparable<ConfigEntry> {
+
+ final CarrierIdentifierMatcher matcher;
+ final PersistableBundle config;
+
+ ConfigEntry(CarrierIdentifierMatcher matcher, PersistableBundle config) {
+ this.matcher = matcher;
+ this.config = config;
+ }
+
+ /**
+ * A more specific matcher should return a negative value to have higher priority over generic
+ * matchers.
+ */
+ @Override
+ public int compareTo(@NonNull ConfigEntry other) {
+ ComparisonChain comparisonChain = ComparisonChain.start();
+ if (!(matcher.gid1().isPresent() && other.matcher.gid1().isPresent())) {
+ if (matcher.gid1().isPresent()) {
+ return -1;
+ } else if (other.matcher.gid1().isPresent()) {
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ comparisonChain = comparisonChain.compare(matcher.gid1().get(), other.matcher.gid1().get());
+ }
+
+ return comparisonChain.compare(matcher.mccMnc(), other.matcher.mccMnc()).result();
+ }
+ }
+
+ private static final String TAG_PERSISTABLEMAP = "pbundle_as_map";
+
+ /**
+ * A string array of MCCMNC the config applies to. Addtional filters should be appended as the URI
+ * query parameter format.
+ *
+ * <p>For example{@code <string-array name="mccmnc"> <item value="12345?gid1=foo"/> <item
+ * value="67890"/> </string-array> }
+ *
+ * @see #KEY_GID1
+ */
+ @VisibleForTesting static final String KEY_MCCMNC = "mccmnc";
+
+ /**
+ * Additional query parameter in {@link #KEY_MCCMNC} to filter by the Group ID level 1.
+ *
+ * @see CarrierIdentifierMatcher#gid1()
+ */
+ private static final String KEY_GID1 = "gid1";
+
+ private static final String KEY_FEATURE_FLAG_NAME = "feature_flag_name";
+
+ private static Map<String, SortedSet<ConfigEntry>> cachedConfigs;
+
+ private final Map<String, SortedSet<ConfigEntry>> configs;
+
+ public DialerVvmConfigManager(Context context) {
+ if (cachedConfigs == null) {
+ cachedConfigs = loadConfigs(context, context.getResources().getXml(R.xml.vvm_config));
+ }
+ configs = cachedConfigs;
+ }
+
+ @VisibleForTesting
+ DialerVvmConfigManager(Context context, XmlPullParser parser) {
+ configs = loadConfigs(context, parser);
+ }
+
+ @Nullable
+ public PersistableBundle getConfig(CarrierIdentifier carrierIdentifier) {
+ if (!configs.containsKey(carrierIdentifier.mccMnc())) {
+ return null;
+ }
+ for (ConfigEntry configEntry : configs.get(carrierIdentifier.mccMnc())) {
+ if (configEntry.matcher.matches(carrierIdentifier)) {
+ return configEntry.config;
+ }
+ }
+ return null;
+ }
+
+ private static Map<String, SortedSet<ConfigEntry>> loadConfigs(
+ Context context, XmlPullParser parser) {
+ Map<String, SortedSet<ConfigEntry>> configs = new ArrayMap<>();
+ try {
+ ArrayList list = readBundleList(parser);
+ for (Object object : list) {
+ if (!(object instanceof PersistableBundle)) {
+ throw new IllegalArgumentException("PersistableBundle expected, got " + object);
+ }
+ PersistableBundle bundle = (PersistableBundle) object;
+
+ if (bundle.containsKey(KEY_FEATURE_FLAG_NAME)
+ && !ConfigProviderBindings.get(context)
+ .getBoolean(bundle.getString(KEY_FEATURE_FLAG_NAME), false)) {
+ continue;
+ }
+
+ String[] identifiers = bundle.getStringArray(KEY_MCCMNC);
+ if (identifiers == null) {
+ throw new IllegalArgumentException("MCCMNC is null");
+ }
+ for (String identifier : identifiers) {
+ Uri uri = Uri.parse(identifier);
+ String mccMnc = uri.getPath();
+ SortedSet<ConfigEntry> set;
+ if (configs.containsKey(mccMnc)) {
+ set = configs.get(mccMnc);
+ } else {
+ // Need a SortedSet so matchers will be sorted by priority.
+ set = new TreeSet<>();
+ configs.put(mccMnc, set);
+ }
+ CarrierIdentifierMatcher.Builder matcherBuilder = CarrierIdentifierMatcher.builder();
+ matcherBuilder.setMccMnc(mccMnc);
+ if (uri.getQueryParameterNames().contains(KEY_GID1)) {
+ matcherBuilder.setGid1(uri.getQueryParameter(KEY_GID1));
+ }
+ set.add(new ConfigEntry(matcherBuilder.build(), bundle));
+ }
+ }
+ } catch (IOException | XmlPullParserException e) {
+ throw new RuntimeException(e);
+ }
+ return configs;
+ }
+
+ @Nullable
+ public static ArrayList readBundleList(XmlPullParser in)
+ throws IOException, XmlPullParserException {
+ final int outerDepth = in.getDepth();
+ int event;
+ while (((event = in.next()) != XmlPullParser.END_DOCUMENT)
+ && (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
+ if (event == XmlPullParser.START_TAG) {
+ final String startTag = in.getName();
+ final String[] tagName = new String[1];
+ in.next();
+ return XmlUtils.readThisListXml(in, startTag, tagName, new MyReadMapCallback(), false);
+ }
+ }
+ return null;
+ }
+
+ public static PersistableBundle restoreFromXml(XmlPullParser in)
+ throws IOException, XmlPullParserException {
+ final int outerDepth = in.getDepth();
+ final String startTag = in.getName();
+ final String[] tagName = new String[1];
+ int event;
+ while (((event = in.next()) != XmlPullParser.END_DOCUMENT)
+ && (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
+ if (event == XmlPullParser.START_TAG) {
+ ArrayMap<String, ?> map =
+ XmlUtils.readThisArrayMapXml(in, startTag, tagName, new MyReadMapCallback());
+ PersistableBundle result = new PersistableBundle();
+ for (Entry<String, ?> entry : map.entrySet()) {
+ Object value = entry.getValue();
+ if (value instanceof Integer) {
+ result.putInt(entry.getKey(), (int) value);
+ } else if (value instanceof Boolean) {
+ result.putBoolean(entry.getKey(), (boolean) value);
+ } else if (value instanceof String) {
+ result.putString(entry.getKey(), (String) value);
+ } else if (value instanceof String[]) {
+ result.putStringArray(entry.getKey(), (String[]) value);
+ } else if (value instanceof PersistableBundle) {
+ result.putPersistableBundle(entry.getKey(), (PersistableBundle) value);
+ }
+ }
+ return result;
+ }
+ }
+ return PersistableBundle.EMPTY;
+ }
+
+ static class MyReadMapCallback implements XmlUtils.ReadMapCallback {
+
+ @Override
+ public Object readThisUnknownObjectXml(XmlPullParser in, String tag)
+ throws XmlPullParserException, IOException {
+ if (TAG_PERSISTABLEMAP.equals(tag)) {
+ return restoreFromXml(in);
+ }
+ throw new XmlPullParserException("Unknown tag=" + tag);
+ }
+ }
+}
diff --git a/java/com/android/voicemail/impl/OmtpVvmCarrierConfigHelper.java b/java/com/android/voicemail/impl/OmtpVvmCarrierConfigHelper.java
index ef62d2a..f8a9e4b 100644
--- a/java/com/android/voicemail/impl/OmtpVvmCarrierConfigHelper.java
+++ b/java/com/android/voicemail/impl/OmtpVvmCarrierConfigHelper.java
@@ -55,6 +55,7 @@
* <p>TODO(twyen): refactor this to an interface.
*/
@TargetApi(VERSION_CODES.O)
+@SuppressWarnings("missingpermission")
public class OmtpVvmCarrierConfigHelper {
private static final String TAG = "OmtpVvmCarrierCfgHlpr";
@@ -131,7 +132,8 @@
carrierConfig = getCarrierConfig(telephonyManager);
telephonyConfig =
- new TelephonyVvmConfigManager(context).getConfig(telephonyManager.getSimOperator());
+ new DialerVvmConfigManager(context)
+ .getConfig(CarrierIdentifier.forHandle(context, phoneAccountHandle));
}
vvmType = getVvmType();
@@ -199,12 +201,6 @@
}
@Nullable
- public Set<String> getCarrierVvmPackageNames() {
- Assert.checkArgument(isValid());
- return getCarrierVvmPackageNamesWithoutValidation();
- }
-
- @Nullable
private Set<String> getCarrierVvmPackageNamesWithoutValidation() {
Set<String> names = getCarrierVvmPackageNames(overrideConfig);
if (names != null) {
@@ -217,6 +213,12 @@
return getCarrierVvmPackageNames(telephonyConfig);
}
+ @Nullable
+ public Set<String> getCarrierVvmPackageNames() {
+ Assert.checkArgument(isValid());
+ return getCarrierVvmPackageNamesWithoutValidation();
+ }
+
private static Set<String> getCarrierVvmPackageNames(@Nullable PersistableBundle bundle) {
if (bundle == null) {
return null;
diff --git a/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java b/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java
deleted file mode 100644
index ecf4e6f..0000000
--- a/java/com/android/voicemail/impl/TelephonyVvmConfigManager.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2016 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.voicemail.impl;
-
-import android.content.Context;
-import android.os.PersistableBundle;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.util.ArrayMap;
-import com.android.dialer.configprovider.ConfigProviderBindings;
-import com.android.voicemail.impl.utils.XmlUtils;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-/** Load and caches telephony vvm config from res/xml/vvm_config.xml */
-public class TelephonyVvmConfigManager {
-
- private static final String TAG = "TelephonyVvmCfgMgr";
-
- private static final boolean USE_DEBUG_CONFIG = false;
-
- private static final String TAG_PERSISTABLEMAP = "pbundle_as_map";
-
- @VisibleForTesting static final String KEY_MCCMNC = "mccmnc";
-
- private static final String KEY_FEATURE_FLAG_NAME = "feature_flag_name";
-
- private static Map<String, PersistableBundle> cachedConfigs;
-
- private final Map<String, PersistableBundle> configs;
-
- public TelephonyVvmConfigManager(Context context) {
- if (cachedConfigs == null) {
- cachedConfigs = loadConfigs(context, context.getResources().getXml(R.xml.vvm_config));
- }
- configs = cachedConfigs;
- }
-
- @VisibleForTesting
- TelephonyVvmConfigManager(Context context, XmlPullParser parser) {
- configs = loadConfigs(context, parser);
- }
-
- @Nullable
- public PersistableBundle getConfig(String mccMnc) {
- if (USE_DEBUG_CONFIG) {
- return configs.get("TEST");
- }
- return configs.get(mccMnc);
- }
-
- private static Map<String, PersistableBundle> loadConfigs(Context context, XmlPullParser parser) {
- Map<String, PersistableBundle> configs = new ArrayMap<>();
- try {
- ArrayList list = readBundleList(parser);
- for (Object object : list) {
- if (!(object instanceof PersistableBundle)) {
- throw new IllegalArgumentException("PersistableBundle expected, got " + object);
- }
- PersistableBundle bundle = (PersistableBundle) object;
-
- if (bundle.containsKey(KEY_FEATURE_FLAG_NAME)
- && !ConfigProviderBindings.get(context)
- .getBoolean(bundle.getString(KEY_FEATURE_FLAG_NAME), false)) {
- continue;
- }
-
- String[] mccMncs = bundle.getStringArray(KEY_MCCMNC);
- if (mccMncs == null) {
- throw new IllegalArgumentException("MCCMNC is null");
- }
- for (String mccMnc : mccMncs) {
- configs.put(mccMnc, bundle);
- }
- }
- } catch (IOException | XmlPullParserException e) {
- throw new RuntimeException(e);
- }
- return configs;
- }
-
- @Nullable
- public static ArrayList readBundleList(XmlPullParser in)
- throws IOException, XmlPullParserException {
- final int outerDepth = in.getDepth();
- int event;
- while (((event = in.next()) != XmlPullParser.END_DOCUMENT)
- && (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
- if (event == XmlPullParser.START_TAG) {
- final String startTag = in.getName();
- final String[] tagName = new String[1];
- in.next();
- return XmlUtils.readThisListXml(in, startTag, tagName, new MyReadMapCallback(), false);
- }
- }
- return null;
- }
-
- public static PersistableBundle restoreFromXml(XmlPullParser in)
- throws IOException, XmlPullParserException {
- final int outerDepth = in.getDepth();
- final String startTag = in.getName();
- final String[] tagName = new String[1];
- int event;
- while (((event = in.next()) != XmlPullParser.END_DOCUMENT)
- && (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
- if (event == XmlPullParser.START_TAG) {
- ArrayMap<String, ?> map =
- XmlUtils.readThisArrayMapXml(in, startTag, tagName, new MyReadMapCallback());
- PersistableBundle result = new PersistableBundle();
- for (Entry<String, ?> entry : map.entrySet()) {
- Object value = entry.getValue();
- if (value instanceof Integer) {
- result.putInt(entry.getKey(), (int) value);
- } else if (value instanceof Boolean) {
- result.putBoolean(entry.getKey(), (boolean) value);
- } else if (value instanceof String) {
- result.putString(entry.getKey(), (String) value);
- } else if (value instanceof String[]) {
- result.putStringArray(entry.getKey(), (String[]) value);
- } else if (value instanceof PersistableBundle) {
- result.putPersistableBundle(entry.getKey(), (PersistableBundle) value);
- }
- }
- return result;
- }
- }
- return PersistableBundle.EMPTY;
- }
-
- static class MyReadMapCallback implements XmlUtils.ReadMapCallback {
-
- @Override
- public Object readThisUnknownObjectXml(XmlPullParser in, String tag)
- throws XmlPullParserException, IOException {
- if (TAG_PERSISTABLEMAP.equals(tag)) {
- return restoreFromXml(in);
- }
- throw new XmlPullParserException("Unknown tag=" + tag);
- }
- }
-}
diff --git a/java/com/android/voicemail/impl/res/xml/vvm_config.xml b/java/com/android/voicemail/impl/res/xml/vvm_config.xml
index 499bae2..ed7761a 100644
--- a/java/com/android/voicemail/impl/res/xml/vvm_config.xml
+++ b/java/com/android/voicemail/impl/res/xml/vvm_config.xml
@@ -23,6 +23,21 @@
</pbundle_as_map>
<pbundle_as_map>
+ <!-- Bouygues France -->
+ <string-array name="mccmnc">
+ <item value="20820"/>
+ <item value="20821"/>
+ <item value="20888"/>
+ </string-array>
+ <string name="feature_flag_name">vvm_carrier_flag_20820</string>
+ <int
+ name="vvm_port_number_int"
+ value="5499"/>
+ <string name="vvm_destination_number_string">22344</string>
+ <string name="vvm_type_string">vvm_type_omtp</string>
+ </pbundle_as_map>
+
+ <pbundle_as_map>
<!-- Orange Belgium -->
<string-array name="mccmnc">
<item value="20610"/>