import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.content.pm.PackageManager;
import android.text.TextUtils;
import java.lang.annotation.Retention;
/**
* This device or carrier configuration does not support IMS for this subscription.
* <p>
- * This is a permanent configuration error and there should be no retry.
+ * This is a permanent configuration error and there should be no retry. Usually this is
+ * because {@link PackageManager#FEATURE_TELEPHONY_IMS} is not available
+ * or the device has no ImsService implementation to service this request.
*/
public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Binder;
import android.os.RemoteException;
private int mSubId;
/**
- * Create an instance of ImsManager for the subscription id specified.
+ * Create an instance of {@link ImsMmTelManager} for the subscription id specified.
*
* @param subId The ID of the subscription that this ImsMmTelManager will use.
* @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
if (executor == null) {
throw new IllegalArgumentException("Must include a non-null Executor.");
}
+ if (!isImsAvailableOnDevice()) {
+ throw new ImsException("IMS not available on device.",
+ ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
+ }
c.setExecutor(executor);
try {
getITelephony().registerImsRegistrationCallback(mSubId, c.getBinder());
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- } catch (IllegalStateException e) {
+ } catch (RemoteException | IllegalStateException e) {
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
if (executor == null) {
throw new IllegalArgumentException("Must include a non-null Executor.");
}
+ if (!isImsAvailableOnDevice()) {
+ throw new ImsException("IMS not available on device.",
+ ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
+ }
c.setExecutor(executor);
try {
getITelephony().registerMmTelCapabilityCallback(mSubId, c.getBinder());
}
}
+ private static boolean isImsAvailableOnDevice() {
+ IPackageManager pm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+ if (pm == null) {
+ // For some reason package manger is not available.. This will fail internally anyways,
+ // so do not throw error and allow.
+ return true;
+ }
+ try {
+ return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
+ } catch (RemoteException e) {
+ // For some reason package manger is not available.. This will fail internally anyways,
+ // so do not throw error and allow.
+ }
+ return true;
+ }
+
private static ITelephony getITelephony() {
ITelephony binder = ITelephony.Stub.asInterface(
ServiceManager.getService(Context.TELEPHONY_SERVICE));
* Call was disconnected because a handover is not feasible due to network conditions.
*/
public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149;
+ /**
+ * This device does not support IMS.
+ * @hide
+ */
+ public static final int CODE_LOCAL_IMS_NOT_SUPPORTED_ON_DEVICE = 150;
/*
* TIMEOUT (IMS -> Telephony)
import android.annotation.SystemApi;
import android.annotation.WorkerThread;
import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void registerProvisioningChangedCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull Callback callback) throws ImsException {
+ if (!isImsAvailableOnDevice()) {
+ throw new ImsException("IMS not available on device.",
+ ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
+ }
callback.setExecutor(executor);
try {
getITelephony().registerImsProvisioningChangedCallback(mSubId, callback.getBinder());
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
- } catch (IllegalStateException e) {
+ } catch (RemoteException | IllegalStateException e) {
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
}
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void unregisterProvisioningChangedCallback(@NonNull Callback callback) {
try {
- getITelephony().unregisterImsProvisioningChangedCallback(mSubId,
- callback.getBinder());
+ getITelephony().unregisterImsProvisioningChangedCallback(mSubId, callback.getBinder());
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
}
+ private static boolean isImsAvailableOnDevice() {
+ IPackageManager pm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+ if (pm == null) {
+ // For some reason package manger is not available.. This will fail internally anyways,
+ // so do not throw error and allow.
+ return true;
+ }
+ try {
+ return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
+ } catch (RemoteException e) {
+ // For some reason package manger is not available.. This will fail internally anyways,
+ // so do not throw error and allow.
+ }
+ return true;
+ }
+
private static ITelephony getITelephony() {
ITelephony binder = ITelephony.Stub.asInterface(
ServiceManager.getService(Context.TELEPHONY_SERVICE));