Create Device configuration for per feature binding in ImsResolver
Bug: 111305845
Test: atest FrameworksTelephonyTests; atest CtsTelephonyTestCases
Merged-In: I162011d7cf05e6e690fd8f65259f2463111517ba
Change-Id: I162011d7cf05e6e690fd8f65259f2463111517ba
diff --git a/res/values/config.xml b/res/values/config.xml
index 8bc1919..8c36b1a 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -235,6 +235,12 @@
<!-- Flag indicating whether the device supports RTT (real-time text) -->
<bool name="config_support_rtt">false</bool>
+ <!-- String indicating the package name of the device ImsService implementation for MMTEL. -->
+ <string name="config_ims_mmtel_package"></string>
+
+ <!-- String indicating the package name of the device ImsService implementation for RCS. -->
+ <string name="config_ims_rcs_package"></string>
+
<!-- The package name for the platform number verification supplier app. -->
<string name="platform_number_verification_package" translatable="false"></string>
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 5d4d9b3..1371674 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -26,6 +26,7 @@
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.res.XmlResourceParser;
import android.media.AudioManager;
import android.net.ConnectivityManager;
@@ -66,6 +67,7 @@
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.dataconnection.DataConnectionReasons;
import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
+import com.android.internal.telephony.ims.ImsResolver;
import com.android.internal.util.IndentingPrintWriter;
import com.android.phone.settings.SettingsConstants;
import com.android.phone.vvm.CarrierVvmPackageInstalledReceiver;
@@ -146,6 +148,7 @@
CallNotifier notifier;
CallerInfoCache callerInfoCache;
NotificationMgr notificationMgr;
+ ImsResolver mImsResolver;
public PhoneInterfaceManager phoneMgr;
public ImsRcsController imsRcsController;
CarrierConfigLoader configLoader;
@@ -317,6 +320,19 @@
// Initialize the telephony framework
PhoneFactory.makeDefaultPhones(this);
+ // Only bring up ImsResolver if the device supports having an IMS stack.
+ if (getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TELEPHONY_IMS)) {
+ // Get the package name of the default IMS implementation.
+ String defaultImsMmtelPackage = getResources().getString(
+ R.string.config_ims_mmtel_package);
+ String defaultImsRcsPackage = getResources().getString(
+ R.string.config_ims_rcs_package);
+ mImsResolver = new ImsResolver(this, defaultImsMmtelPackage,
+ defaultImsRcsPackage, PhoneFactory.getPhones().length);
+ mImsResolver.initialize();
+ }
+
// Start TelephonyDebugService After the default phone is created.
Intent intent = new Intent(this, TelephonyDebugService.class);
startService(intent);
@@ -438,6 +454,10 @@
return PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
}
+ public ImsResolver getImsResolver() {
+ return mImsResolver;
+ }
+
/* package */ CallManager getCallManager() {
return mCM;
}
@@ -877,6 +897,14 @@
pw.increaseIndent();
mDataRoamingNotifLog.dump(fd, pw, args);
pw.decreaseIndent();
+ pw.println("ImsResolver:");
+ pw.increaseIndent();
+ try {
+ if (mImsResolver != null) mImsResolver.dump(fd, pw, args);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ pw.decreaseIndent();
pw.decreaseIndent();
pw.println("------- End PhoneGlobals -------");
}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 296525d..183a50c 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -281,6 +281,7 @@
private PhoneGlobals mApp;
private CallManager mCM;
+ private ImsResolver mImsResolver;
private UserManager mUserManager;
private AppOpsManager mAppOps;
private MainThreadHandler mMainThreadHandler;
@@ -1393,6 +1394,7 @@
private PhoneInterfaceManager(PhoneGlobals app) {
mApp = app;
mCM = PhoneGlobals.getInstance().mCM;
+ mImsResolver = PhoneGlobals.getInstance().getImsResolver();
mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
mMainThreadHandler = new MainThreadHandler();
@@ -4462,12 +4464,11 @@
final long identity = Binder.clearCallingIdentity();
try {
- ImsResolver resolver = PhoneFactory.getImsResolver();
- if (resolver == null) {
+ if (mImsResolver == null) {
// may happen if the device does not support IMS.
return;
}
- resolver.enableIms(slotId);
+ mImsResolver.enableIms(slotId);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4482,12 +4483,11 @@
final long identity = Binder.clearCallingIdentity();
try {
- ImsResolver resolver = PhoneFactory.getImsResolver();
- if (resolver == null) {
+ if (mImsResolver == null) {
// may happen if the device does not support IMS.
return;
}
- resolver.disableIms(slotId);
+ mImsResolver.disableIms(slotId);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4504,12 +4504,11 @@
final long identity = Binder.clearCallingIdentity();
try {
- ImsResolver resolver = PhoneFactory.getImsResolver();
- if (resolver == null) {
+ if (mImsResolver == null) {
// may happen if the device does not support IMS.
return null;
}
- return resolver.getMmTelFeatureAndListen(slotId, callback);
+ return mImsResolver.getMmTelFeatureAndListen(slotId, callback);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4526,12 +4525,11 @@
final long identity = Binder.clearCallingIdentity();
try {
- ImsResolver resolver = PhoneFactory.getImsResolver();
- if (resolver == null) {
+ if (mImsResolver == null) {
// may happen if the device does not support IMS.
return null;
}
- return resolver.getRcsFeatureAndListen(slotId, callback);
+ return mImsResolver.getRcsFeatureAndListen(slotId, callback);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4546,12 +4544,11 @@
final long identity = Binder.clearCallingIdentity();
try {
- ImsResolver resolver = PhoneFactory.getImsResolver();
- if (resolver == null) {
+ if (mImsResolver == null) {
// may happen if the device does not support IMS.
return null;
}
- return resolver.getImsRegistration(slotId, feature);
+ return mImsResolver.getImsRegistration(slotId, feature);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4566,12 +4563,11 @@
final long identity = Binder.clearCallingIdentity();
try {
- ImsResolver resolver = PhoneFactory.getImsResolver();
- if (resolver == null) {
+ if (mImsResolver == null) {
// may happen if the device does not support IMS.
return null;
}
- return resolver.getImsConfig(slotId, feature);
+ return mImsResolver.getImsConfig(slotId, feature);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4580,58 +4576,65 @@
/**
* Sets the ImsService Package Name that Telephony will bind to.
*
- * @param slotId the slot ID that the ImsService should bind for.
- * @param isCarrierImsService true if the ImsService is the carrier override, false if the
+ * @param slotIndex the slot ID that the ImsService should bind for.
+ * @param isCarrierService true if the ImsService is the carrier override, false if the
* ImsService is the device default ImsService.
- * @param packageName The package name of the application that contains the ImsService to bind
- * to.
+ * @param featureTypes An integer array of feature types associated with a packageName.
+ * @param packageName The name of the package that the current configuration will be replaced
+ * with.
* @return true if setting the ImsService to bind to succeeded, false if it did not.
- * @hide
*/
- public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
- int[] subIds = SubscriptionManager.getSubId(slotId);
+ public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
+ int[] featureTypes, String packageName) {
+ int[] subIds = SubscriptionManager.getSubId(slotIndex);
+ TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
(subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
- "setImsService");
+ "setBoundImsServiceOverride");
final long identity = Binder.clearCallingIdentity();
try {
- ImsResolver resolver = PhoneFactory.getImsResolver();
- if (resolver == null) {
+ if (mImsResolver == null) {
// may happen if the device does not support IMS.
return false;
}
- return resolver.overrideImsServiceConfiguration(slotId, isCarrierImsService,
- packageName);
+ Map<Integer, String> featureConfig = new HashMap<>();
+ for (int featureType : featureTypes) {
+ featureConfig.put(featureType, packageName);
+ }
+ return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
+ featureConfig);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
/**
- * Return the ImsService configuration.
+ * Return the package name of the currently bound ImsService.
*
* @param slotId The slot that the ImsService is associated with.
* @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
* the device default.
+ * @param featureType The feature associated with the queried configuration.
* @return the package name of the ImsService configuration.
*/
- public String getImsService(int slotId, boolean isCarrierImsService) {
+ public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
+ @ImsFeature.FeatureType int featureType) {
int[] subIds = SubscriptionManager.getSubId(slotId);
- TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
- (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
- "getImsService");
+ TelephonyPermissions
+ .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
+ mApp, (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
+ "getBoundImsServicePackage");
final long identity = Binder.clearCallingIdentity();
try {
- ImsResolver resolver = PhoneFactory.getImsResolver();
- if (resolver == null) {
+ if (mImsResolver == null) {
// may happen if the device does not support IMS.
return "";
}
// TODO: change API to query RCS separately.
- return resolver.getImsServiceConfiguration(slotId, isCarrierImsService,
- ImsFeature.FEATURE_MMTEL);
+ return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
+ featureType);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 0806fd1..53b3356 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -26,6 +26,7 @@
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.feature.ImsFeature;
import android.util.Log;
import com.android.internal.telephony.ITelephony;
@@ -35,6 +36,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.TreeSet;
@@ -180,13 +182,15 @@
private void onHelpIms() {
PrintWriter pw = getOutPrintWriter();
pw.println("IMS Commands:");
- pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d) PACKAGE_NAME");
+ pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
pw.println(" ImsService. Options are:");
pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
pw.println(" is specified, it will choose the default voice SIM slot.");
pw.println(" -c: Override the ImsService defined in the carrier configuration.");
pw.println(" -d: Override the ImsService defined in the device overlay.");
+ pw.println(" -f: Set the feature that this override if for, if no option is");
+ pw.println(" specified, the new package name will be used for all features.");
pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
pw.println(" Gets the package name of the currently defined ImsService.");
pw.println(" Options are:");
@@ -194,6 +198,8 @@
pw.println(" is specified, it will choose the default voice SIM slot.");
pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
pw.println(" -c: The ImsService defined as the device default ImsService.");
+ pw.println(" -f: The feature type that the query will be requested for. If none is");
+ pw.println(" specified, the returned package name will correspond to MMTEL.");
pw.println(" ims enable [-s SLOT_ID]");
pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
pw.println(" if none is specified.");
@@ -444,6 +450,7 @@
PrintWriter errPw = getErrPrintWriter();
int slotId = getDefaultSlot();
Boolean isCarrierService = null;
+ List<Integer> featuresList = new ArrayList<>();
String opt;
while ((opt = getNextOption()) != null) {
@@ -465,6 +472,26 @@
isCarrierService = false;
break;
}
+ case "-f": {
+ String featureString = getNextArgRequired();
+ String[] features = featureString.split(",");
+ for (int i = 0; i < features.length; i++) {
+ try {
+ Integer result = Integer.parseInt(features[i]);
+ if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
+ || result >= ImsFeature.FEATURE_MAX) {
+ errPw.println("ims set-ims-service -f " + result
+ + " is an invalid feature.");
+ return -1;
+ }
+ featuresList.add(result);
+ } catch (NumberFormatException e) {
+ errPw.println("ims set-ims-service -f tried to parse " + features[i]
+ + " as an integer.");
+ return -1;
+ }
+ }
+ }
}
}
// Mandatory param, either -c or -d
@@ -479,16 +506,24 @@
if (packageName == null) {
packageName = "";
}
- boolean result = mInterface.setImsService(slotId, isCarrierService, packageName);
+ int[] featureArray = new int[featuresList.size()];
+ for (int i = 0; i < featuresList.size(); i++) {
+ featureArray[i] = featuresList.get(i);
+ }
+ boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
+ featureArray, packageName);
if (VDBG) {
Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
- + (isCarrierService ? "-c " : "-d ") + packageName + ", result=" + result);
+ + (isCarrierService ? "-c " : "-d ")
+ + "-f " + featuresList + " "
+ + packageName + ", result=" + result);
}
getOutPrintWriter().println(result);
} catch (RemoteException e) {
Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
- + (isCarrierService ? "-c " : "-d ") + packageName + ", error"
- + e.getMessage());
+ + (isCarrierService ? "-c " : "-d ")
+ + "-f " + featuresList + " "
+ + packageName + ", error" + e.getMessage());
errPw.println("Exception: " + e.getMessage());
return -1;
}
@@ -500,6 +535,7 @@
PrintWriter errPw = getErrPrintWriter();
int slotId = getDefaultSlot();
Boolean isCarrierService = null;
+ Integer featureType = ImsFeature.FEATURE_MMTEL;
String opt;
while ((opt = getNextOption()) != null) {
@@ -521,23 +557,38 @@
isCarrierService = false;
break;
}
+ case "-f": {
+ try {
+ featureType = Integer.parseInt(getNextArg());
+ } catch (NumberFormatException e) {
+ errPw.println("ims get-ims-service -f requires valid integer as feature.");
+ return -1;
+ }
+ if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
+ || featureType >= ImsFeature.FEATURE_MAX) {
+ errPw.println("ims get-ims-service -f invalid feature.");
+ return -1;
+ }
+ }
}
}
// Mandatory param, either -c or -d
if (isCarrierService == null) {
- errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
+ errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
return -1;
}
String result;
try {
- result = mInterface.getImsService(slotId, isCarrierService);
+ result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
} catch (RemoteException e) {
return -1;
}
if (VDBG) {
Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
- + (isCarrierService ? "-c " : "-d ") + ", returned: " + result);
+ + (isCarrierService ? "-c " : "-d ")
+ + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
+ + result);
}
getOutPrintWriter().println(result);
return 0;