最近,客户提出一个需求,要加设备中加入VVM相关。
VVM配置:
客户提供了一个VVM配置信息,如下:.
Orange France (208/01)
Type : vvm_type_omtp
Dest Number : 21101
Dest port : 20481
vvm package : com.orange.vvm
prefetch : true
cellular data : true
ssl port : 0
legacy mode : false
disabled capabilities : STARTTLS
client prefix: //VVM
配置的信息,主要包含于Package/apps/CarrierConfig中,具体配置为:
packages/apps/CarrierConfig/assets/carrier_config_20801.xml
<!--Visual voicemail config-->
<!--VVM Type-->
<string name="vvm_type_string">vvm_type_omtp</string>
<!--VVM Dest Number-->
<string name="vvm_destination_number_string">21101</string>
<!--VVM Dest port-->
<int name="vvm_port_number_int" value="20481"/>
<!--VVM package-->
<string-array name="carrier_vvm_package_name_string_array" num="1">
<item value="com.orange.vvm"/>
</string-array>
<!--VVM prefetch-->
<boolean name="vvm_prefetch_bool" value="true"/>
<!--VVM cellular data-->
<boolean name="vvm_cellular_data_required_bool" value="true"/>
<!--VVM ssl port-->
<int name="vvm_ssl_port_number_int" value="0"/>
<!--VVM legacy mode-->
<boolean name="vvm_legacy_mode_enabled_bool" value="false"/>
<!--VVM disabled capabilities-->
<string-array name="vvm_disabled_capabilities_string_array" num="1">
<item value="STARTTLS"/>
</string-array>
<!--VVM client prefix-->
<string name="vvm_client_prefix_string">//VVM</string>
配置完成后,插入对应Orange SIM卡后,运行正常。
经由客户测试后,反馈一个bug,安装运营商的VVM应用后,原生VVM自动禁用,但是卸载VVM后,原生代码没有自动开启。
查看对应的代码,发现目前只对应用的安装进行了监听,并未对应用卸载进行监听,具体如下:
packages/services/Telephony/src/com/android/phone/vvm/CarrierVvmPackageInstalledReceiver.java
public void register(Context context) {
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addDataScheme("package");
context.registerReceiver(this, intentFilter);
}
对应的处理类中,也只对安装进行了处理,具体如下:
packages/apps/Dialer/java/com/android/voicemail/impl/VvmPackageInstallHandler.java
public static void handlePackageInstalled(Context context, String packageName) {...}
因此我们只需加入对应的处理即可,修改代码如下:
packages/services/Telephony/src/com/android/phone/vvm/CarrierVvmPackageInstalledReceiver.java
+ private static final String ACTION_CARRIER_VVM_PACKAGE_UNINSTALLED =
+ "com.android.internal.telephony.CARRIER_VVM_PACKAGE_UNINSTALLED";
+
public void register(Context context) {
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addDataScheme("package");
context.registerReceiver(this, intentFilter);
+ IntentFilter uninstallFilter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
+ uninstallFilter.addDataScheme("package");
+ context.registerReceiver(this, uninstallFilter);
}
@Override
public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+ if (intent.getData() == null) {
+ return;
}
+ String packageName = intent.getData().getSchemeSpecificPart();
+ if (packageName == null) {
+ return;
}
+ TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+ String systemDialer = telecomManager.getSystemDialerPackage();
+ TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
+ for (PhoneAccountHandle phoneAccountHandle : telecomManager.getCallCapablePhoneAccounts()) {
+ TelephonyManager pinnedTelephonyManager = telephonyManager
+ .createForPhoneAccountHandle(phoneAccountHandle);
+
+ if (pinnedTelephonyManager == null) {
+ VvmLog.e(TAG, "cannot create TelephonyManager from " + phoneAccountHandle);
+ continue;
+ }
+
+ if (!getCarrierVvmPackages(telephonyManager).contains(packageName)) {
+ continue;
+ }
+
+ VvmLog.i(TAG, "Carrier VVM app " + packageName + " installed");
+
+ String vvmPackage = pinnedTelephonyManager.getVisualVoicemailPackageName();
+ if (!TextUtils.equals(vvmPackage, systemDialer)) {
+ // Non system dialer do not need to prioritize carrier vvm app.
+ VvmLog.i(TAG, "non system dialer " + vvmPackage + " ignored");
+ continue;
+ }
+
+ VvmLog.i(TAG, "sending broadcast to " + vvmPackage);
+ Intent broadcast = new Intent(ACTION_CARRIER_VVM_PACKAGE_INSTALLED);
+ broadcast.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
+ broadcast.setPackage(vvmPackage);
+ context.sendBroadcast(broadcast);
+ }
+ } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+ if (intent.getData() == null) {
+ return;
+ }
+ String packageName = intent.getData().getSchemeSpecificPart();
+ if (packageName == null) {
+ return;
}
+ TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+ String systemDialer = telecomManager.getSystemDialerPackage();
+ TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
+ for (PhoneAccountHandle phoneAccountHandle : telecomManager.getCallCapablePhoneAccounts()) {
+ TelephonyManager pinnedTelephonyManager = telephonyManager
+ .createForPhoneAccountHandle(phoneAccountHandle);
+
+ if (pinnedTelephonyManager == null) {
+ VvmLog.e(TAG, "cannot create TelephonyManager from " + phoneAccountHandle);
+ continue;
+ }
+
+ if (!getCarrierVvmPackages(telephonyManager).contains(packageName)) {
+ continue;
+ }
+
+ VvmLog.i(TAG, "Carrier VVM app " + packageName + " uninstalled");
+
+ String vvmPackage = pinnedTelephonyManager.getVisualVoicemailPackageName();
+ if (!TextUtils.equals(vvmPackage, systemDialer)) {
+ // Non system dialer do not need to prioritize carrier vvm app.
+ VvmLog.i(TAG, "non system dialer " + vvmPackage + " ignored");
+ continue;
+ }
+
+ VvmLog.i(TAG, "sending broadcast to " + vvmPackage);
+ Intent broadcast = new Intent(ACTION_CARRIER_VVM_PACKAGE_UNINSTALLED);
+ broadcast.putExtra("carrier_vvm_uninstall", packageName);
+ broadcast.setPackage(vvmPackage);
+ context.sendBroadcast(broadcast);
+ }
+ }
packages/apps/Dialer/java/com/android/voicemail/impl/AndroidManifest.xml
<!-- system dialer only broadcast -->
<action
android:name="com.android.internal.telephony.CARRIER_VVM_PACKAGE_INSTALLED" />
+ <action
+ android:name="com.android.internal.telephony.CARRIER_VVM_PACKAGE_UNINSTALLED" />
packages/apps/Dialer/java/com/android/voicemail/impl/CarrierVvmPackageInstalledReceiver.java
+ private static final String ACTION_CARRIER_VVM_PACKAGE_INSTALLED =
+ "com.android.internal.telephony.CARRIER_VVM_PACKAGE_INSTALLED";
+
+ private static final String ACTION_CARRIER_VVM_PACKAGE_UNINSTALLED =
+ "com.android.internal.telephony.CARRIER_VVM_PACKAGE_UNINSTALLED";
+
@Override
public void onReceive(Context context, Intent intent) {
- String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
- VvmLog.i("CarrierVvmPackageInstalledReceiver.onReceive", "package installed: " + packageName);
- VvmPackageInstallHandler.handlePackageInstalled(context, packageName);
+ String action = intent.getAction();
+ if (ACTION_CARRIER_VVM_PACKAGE_INSTALLED.equals(action)) {
+ String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+ VvmLog.i("CarrierVvmPackageInstalledReceiver.onReceive", "package installed: " + packageName);
+ VvmPackageInstallHandler.handlePackageInstalled(context, packageName);
+ } else if (ACTION_CARRIER_VVM_PACKAGE_UNINSTALLED.equals(action)) {
+ String uninstall = intent.getStringExtra("carrier_vvm_uninstall");
+ VvmLog.i("CarrierVvmPackageInstalledReceiver.onReceive", "package uninstalled: " + uninstall);
+ VvmPackageInstallHandler.handlePackageUninstalled(context, uninstall);
+ }
}
packages/apps/Dialer/java/com/android/voicemail/impl/VvmPackageInstallHandler.java
if (VisualVoicemailSettingsUtil.isEnabledUserSet(context, phoneAccount)) {
+ /*if (VisualVoicemailSettingsUtil.isEnabledUserSet(context, phoneAccount)) {
// Skip the check if this voicemail source's setting is overridden by the user.
VvmLog.i(
"VvmPackageInstallHandler.handlePackageInstalled",
"VVM enabled by user, not disabling");
continue;
- }
+ }*/
// Force deactivate the client. The user can re-enable it in the settings.
// There is no need to update the settings for deactivation. At this point, if the
@@ -77,4 +79,30 @@ public final class VvmPackageInstallHandler {
VisualVoicemailSettingsUtil.setEnabled(context, phoneAccount, false);
}
}
+
+ public static void handlePackageUninstalled(Context context, String packageName) {
+ // This get called every time an app is installed and will be noisy. Don't log until the app
+ // is identified as a carrier VVM app.
+ for (PhoneAccountHandle phoneAccount :
+ context.getSystemService(TelecomManager.class).getCallCapablePhoneAccounts()) {
+ OmtpVvmCarrierConfigHelper carrierConfigHelper =
+ new OmtpVvmCarrierConfigHelper(context, phoneAccount);
+ if (!carrierConfigHelper.isValid()) {
+ continue;
+ }
+ if (carrierConfigHelper.getCarrierVvmPackageNames() == null) {
+ continue;
+ }
+ if (!carrierConfigHelper.getCarrierVvmPackageNames().contains(packageName)) {
+ continue;
+ }
+
+ VvmLog.i("VvmPackageInstallHandler.handlePackageUninstalled", "Carrier app uninstalled");
+
+ // Force activate the client. The user can disable it in the settings.
+ VisualVoicemailSettingsUtil.setEnabled(context, phoneAccount, true);
+ }
+ }
修改后,自测通过。