Implement VisualVoicemailService cascading.
This CL determines which VisualVoicemailService should be active.
The order is:
1. Current default dialer
The dialer might disable itself when a carrier VVM package is
installed.
2. The carrier packages
Designated with CarrierConfig using KEY_CARRIER_VVM_PACKAGE_NAME_STRING.
This value is used before solely to disable the system client.
KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY should be added to allow
multiple clients.
3. The system package.
A device specific package override-able with
R.string.system_visual_voicemail_client
4. The system dialer.
Bug: 34132028
Bug: 32414216
Change-Id: Ifa6d0bbb3033a14757ab99226f28aca245848c0f
Merged-in: Ifa6d0bbb3033a14757ab99226f28aca245848c0f
Fixes: 34132028
Test: manual test using the dialer and the system package.
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 130e9a8..81de9d7 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -94,10 +94,10 @@
import com.android.internal.util.HexDump;
import com.android.phone.settings.VisualVoicemailSettingsUtil;
import com.android.phone.settings.VoicemailNotificationSettingsUtil;
+import com.android.phone.vvm.RemoteVvmTaskManager;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
@@ -2069,7 +2069,7 @@
public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
String number, int port, String text, PendingIntent sentIntent) {
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
- enforceDefaultDialer(callingPackage);
+ enforceVisualVoicemailPackage(callingPackage, subId);
enforceSendSmsPermission();
// Make the calls as the phone process.
final long identity = Binder.clearCallingIdentity();
@@ -3432,14 +3432,16 @@
}
/**
- * Make sure called from the default dialer
+ * Make sure called from the package in charge of visual voicemail.
*
- * @throws SecurityException if the caller is not the default dialer
+ * @throws SecurityException if the caller is not the visual voicemail package.
*/
- private void enforceDefaultDialer(String callingPackage) {
- TelecomManager telecomManager = mPhone.getContext().getSystemService(TelecomManager.class);
- if (!callingPackage.equals(telecomManager.getDefaultDialerPackage())) {
- throw new SecurityException("Caller not default dialer.");
+ private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
+ String vvmPackage = RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId)
+ .getPackageName();
+ if (!callingPackage.equals(vvmPackage)) {
+ throw new SecurityException("Caller not current active visual voicemail package[" +
+ vvmPackage + "]");
}
}
diff --git a/src/com/android/phone/VisualVoicemailSmsFilterConfig.java b/src/com/android/phone/VisualVoicemailSmsFilterConfig.java
index 2ffb477..db79e2b 100644
--- a/src/com/android/phone/VisualVoicemailSmsFilterConfig.java
+++ b/src/com/android/phone/VisualVoicemailSmsFilterConfig.java
@@ -64,7 +64,7 @@
public static VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(
Context context, int subId) {
- ComponentName componentName = RemoteVvmTaskManager.getRemotePackage(context);
+ ComponentName componentName = RemoteVvmTaskManager.getRemotePackage(context, subId);
String packageName;
if (componentName == null) {
packageName = DEFAULT_PACKAGE;
diff --git a/src/com/android/phone/vvm/RemoteVvmTaskManager.java b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
index ce6fce6..9236bd2 100644
--- a/src/com/android/phone/vvm/RemoteVvmTaskManager.java
+++ b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
@@ -29,16 +29,23 @@
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
import android.telephony.VisualVoicemailService;
import android.telephony.VisualVoicemailSms;
+import android.text.TextUtils;
import com.android.phone.Assert;
+import com.android.phone.R;
import com.android.phone.vvm.omtp.VvmLog;
+import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
+import java.util.ArrayList;
import java.util.LinkedList;
+import java.util.List;
import java.util.Queue;
/**
@@ -93,18 +100,39 @@
context.startService(intent);
}
- public static boolean hasRemoteService(Context context) {
- return getRemotePackage(context) != null;
+ public static boolean hasRemoteService(Context context, int subId) {
+ return getRemotePackage(context, subId) != null;
}
- public static ComponentName getRemotePackage(Context context) {
+ public static ComponentName getRemotePackage(Context context, int subId) {
+ Intent bindIntent = newBindIntent(context);
- ResolveInfo info = context.getPackageManager()
- .resolveService(newBindIntent(context), PackageManager.MATCH_ALL);
- if (info == null) {
- return null;
+ TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+ List<String> packages = new ArrayList<>();
+ packages.add(telecomManager.getDefaultDialerPackage());
+ PersistableBundle carrierConfig = context
+ .getSystemService(CarrierConfigManager.class).getConfigForSubId(subId);
+ packages.add(
+ carrierConfig.getString(CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING));
+ for (String packageName : carrierConfig
+ .getStringArray(CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY)) {
+ packages.add(packageName);
}
- return info.getComponentInfo().getComponentName();
+ packages.add(context.getResources().getString(R.string.system_visual_voicemail_client));
+ packages.add(telecomManager.getSystemDialerPackage());
+ for (String packageName : packages) {
+ if (TextUtils.isEmpty(packageName)) {
+ continue;
+ }
+ bindIntent.setPackage(packageName);
+ ResolveInfo info = context.getPackageManager()
+ .resolveService(bindIntent, PackageManager.MATCH_ALL);
+ if (info != null) {
+ return info.getComponentInfo().getComponentName();
+ }
+
+ }
+ return null;
}
@Override
@@ -130,15 +158,27 @@
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
Assert.isMainThread();
mTaskReferenceCount++;
+
+ PhoneAccountHandle phoneAccountHandle = intent.getExtras()
+ .getParcelable(VisualVoicemailService.DATA_PHONE_ACCOUNT_HANDLE);
+ int subId = PhoneAccountHandleConverter.toSubId(phoneAccountHandle);
+ ComponentName remotePackage = getRemotePackage(this, subId);
+ if (remotePackage == null) {
+ VvmLog.i(TAG, "No service to handle " + intent.getAction() + ", ignoring");
+ checkReference();
+ return START_NOT_STICKY;
+ }
+
switch (intent.getAction()) {
case ACTION_START_CELL_SERVICE_CONNECTED:
- send(VisualVoicemailService.MSG_ON_CELL_SERVICE_CONNECTED, intent.getExtras());
+ send(remotePackage, VisualVoicemailService.MSG_ON_CELL_SERVICE_CONNECTED,
+ intent.getExtras());
break;
case ACTION_START_SMS_RECEIVED:
- send(VisualVoicemailService.MSG_ON_SMS_RECEIVED, intent.getExtras());
+ send(remotePackage, VisualVoicemailService.MSG_ON_SMS_RECEIVED, intent.getExtras());
break;
case ACTION_START_SIM_REMOVED:
- send(VisualVoicemailService.MSG_ON_SIM_REMOVED, intent.getExtras());
+ send(remotePackage, VisualVoicemailService.MSG_ON_SIM_REMOVED, intent.getExtras());
break;
default:
Assert.fail("Unexpected action +" + intent.getAction());
@@ -217,7 +257,7 @@
}
}
- private void send(int what, Bundle extras) {
+ private void send(ComponentName remotePackage,int what, Bundle extras) {
Assert.isMainThread();
Message message = Message.obtain();
message.what = what;
@@ -229,12 +269,16 @@
if (!mConnection.isConnected()) {
Intent intent = newBindIntent(this);
- intent.setComponent(getRemotePackage(this));
+ intent.setComponent(remotePackage);
+ VvmLog.i(TAG, "Binding to " + intent.getComponent());
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
}
private void checkReference() {
+ if (mConnection == null) {
+ return;
+ }
if (mTaskReferenceCount == 0) {
unbindService(mConnection);
mConnection = null;
@@ -244,8 +288,6 @@
private static Intent newBindIntent(Context context) {
Intent intent = new Intent();
intent.setAction(VisualVoicemailService.SERVICE_INTERFACE);
- TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
- intent.setPackage(telecomManager.getDefaultDialerPackage());
return intent;
}
}
diff --git a/src/com/android/phone/vvm/VvmSmsReceiver.java b/src/com/android/phone/vvm/VvmSmsReceiver.java
index 91e7933..feaa46b 100644
--- a/src/com/android/phone/vvm/VvmSmsReceiver.java
+++ b/src/com/android/phone/vvm/VvmSmsReceiver.java
@@ -20,10 +20,12 @@
import android.content.Context;
import android.content.Intent;
import android.provider.VoicemailContract;
+import android.telephony.SubscriptionManager;
import android.telephony.VisualVoicemailSms;
import com.android.phone.vvm.omtp.VvmLog;
import com.android.phone.vvm.omtp.sms.OmtpMessageReceiver;
+import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
/**
* Receives the SMS filtered by {@link com.android.internal.telephony.VisualVoicemailSmsFilter} and
@@ -45,7 +47,13 @@
return;
}
- if (RemoteVvmTaskManager.hasRemoteService(context)) {
+ int subId = PhoneAccountHandleConverter.toSubId(sms.getPhoneAccountHandle());
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+ VvmLog.e(TAG, "Received message for invalid subId");
+ return;
+ }
+
+ if (RemoteVvmTaskManager.hasRemoteService(context, subId)) {
VvmLog.i(TAG, "Sending SMS received event to remote service");
RemoteVvmTaskManager.startSmsReceived(context, sms);
return;
diff --git a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
index 0f93f01..fb8f02d 100644
--- a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
+++ b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
@@ -28,6 +28,7 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
@@ -56,7 +57,15 @@
return;
}
- if (RemoteVvmTaskManager.hasRemoteService(context)) {
+ int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+ if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+ VvmLog.i(TAG, "Received SIM change for invalid subscription id.");
+ return;
+ }
+
+ if (RemoteVvmTaskManager.hasRemoteService(context, subId)) {
return;
}
@@ -69,13 +78,7 @@
}
break;
case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
- int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- if (!SubscriptionManager.isValidSubscriptionId(subId)) {
- VvmLog.i(TAG, "Received SIM change for invalid subscription id.");
- return;
- }
TelephonyManager telephonyManager = context
.getSystemService(TelephonyManager.class);
diff --git a/src/com/android/phone/vvm/omtp/VvmBootCompletedReceiver.java b/src/com/android/phone/vvm/omtp/VvmBootCompletedReceiver.java
index 21cce31..f725f96 100644
--- a/src/com/android/phone/vvm/omtp/VvmBootCompletedReceiver.java
+++ b/src/com/android/phone/vvm/omtp/VvmBootCompletedReceiver.java
@@ -22,6 +22,7 @@
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.SubscriptionManager;
+
import com.android.phone.vvm.RemoteVvmTaskManager;
import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
@@ -46,10 +47,6 @@
return;
}
- if (RemoteVvmTaskManager.hasRemoteService(context)) {
- return;
- }
-
VvmLog.v(TAG, "processing subId list");
for (PhoneAccountHandle handle : TelecomManager.from(context)
.getCallCapablePhoneAccounts()) {
@@ -60,6 +57,10 @@
VvmLog.e(TAG, "phone account " + handle + " has invalid subId " + subId);
continue;
}
+ if (RemoteVvmTaskManager.hasRemoteService(context, subId)) {
+ return;
+ }
+
VvmLog.v(TAG, "processing subId " + subId);
SimChangeReceiver.processSubId(context, subId);
}
diff --git a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
index 31c173d..75ffc71 100644
--- a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
+++ b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
@@ -20,6 +20,7 @@
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
+
import com.android.phone.PhoneUtils;
import com.android.phone.VoicemailStatus;
import com.android.phone.vvm.RemoteVvmTaskManager;
@@ -55,7 +56,7 @@
return;
}
- if (RemoteVvmTaskManager.hasRemoteService(mContext)) {
+ if (RemoteVvmTaskManager.hasRemoteService(mContext, subId)) {
return;
}