Integrate MMTel APIs into the framework am: 936a7d1641 am: fd04a75710
am: 6c96d2cb30 -s ours
Change-Id: I1a0c5536419890813722e95ae19adb76a345646e
diff --git a/src/java/com/android/ims/ImsCall.java b/src/java/com/android/ims/ImsCall.java
index 6200a07..e32103e 100644
--- a/src/java/com/android/ims/ImsCall.java
+++ b/src/java/com/android/ims/ImsCall.java
@@ -36,10 +36,15 @@
import java.util.concurrent.atomic.AtomicInteger;
import android.telephony.ServiceState;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsConferenceState;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsStreamMediaProfile;
+import android.telephony.ims.ImsSuppServiceNotification;
import android.util.Log;
import com.android.ims.internal.ICall;
-import com.android.ims.internal.ImsCallSession;
+import android.telephony.ims.ImsCallSession;
import com.android.ims.internal.ImsStreamMediaSession;
import com.android.internal.annotations.VisibleForTesting;
@@ -1623,6 +1628,7 @@
// Make a copy of the current ImsCallProfile and modify it to enable RTT
Parcel p = Parcel.obtain();
mCallProfile.writeToParcel(p, 0);
+ p.setDataPosition(0);
ImsCallProfile requestedProfile = new ImsCallProfile(p);
requestedProfile.mMediaProfile.setRttMode(ImsStreamMediaProfile.RTT_MODE_FULL);
@@ -3072,6 +3078,7 @@
public void callSessionRttModifyRequestReceived(ImsCallSession session,
ImsCallProfile callProfile) {
ImsCall.Listener listener;
+ logi("callSessionRttModifyRequestReceived");
synchronized(ImsCall.this) {
listener = mListener;
@@ -3096,6 +3103,7 @@
public void callSessionRttModifyResponseReceived(int status) {
ImsCall.Listener listener;
+ logi("callSessionRttModifyResponseReceived");
synchronized(ImsCall.this) {
listener = mListener;
}
diff --git a/src/java/com/android/ims/ImsConnectionStateListener.java b/src/java/com/android/ims/ImsConnectionStateListener.java
index 049b846..d5fb633 100644
--- a/src/java/com/android/ims/ImsConnectionStateListener.java
+++ b/src/java/com/android/ims/ImsConnectionStateListener.java
@@ -17,6 +17,7 @@
package com.android.ims;
import android.net.Uri;
+import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
diff --git a/src/java/com/android/ims/ImsEcbm.java b/src/java/com/android/ims/ImsEcbm.java
index 53549bf..99d99f1 100644
--- a/src/java/com/android/ims/ImsEcbm.java
+++ b/src/java/com/android/ims/ImsEcbm.java
@@ -29,18 +29,12 @@
package com.android.ims;
-import java.util.HashMap;
-import java.util.Map;
-
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Message;
import android.os.RemoteException;
import android.telephony.Rlog;
+import android.telephony.ims.ImsReasonInfo;
import com.android.ims.internal.IImsEcbm;
import com.android.ims.internal.IImsEcbmListener;
-import com.android.ims.ImsEcbmStateListener;
/**
* Provides APIs for the supplementary service settings using IMS (Ut interface).
diff --git a/src/java/com/android/ims/ImsExternalCallStateListener.java b/src/java/com/android/ims/ImsExternalCallStateListener.java
index 3f4f163..aae4c9b 100644
--- a/src/java/com/android/ims/ImsExternalCallStateListener.java
+++ b/src/java/com/android/ims/ImsExternalCallStateListener.java
@@ -16,6 +16,8 @@
package com.android.ims;
+import android.telephony.ims.ImsExternalCallState;
+
import java.util.List;
/**
diff --git a/src/java/com/android/ims/ImsManager.java b/src/java/com/android/ims/ImsManager.java
index 9cfff78..0a0eb24 100644
--- a/src/java/com/android/ims/ImsManager.java
+++ b/src/java/com/android/ims/ImsManager.java
@@ -19,11 +19,8 @@
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.Context;
-import android.os.AsyncTask;
-import android.os.Handler;
import android.os.Bundle;
import android.os.IBinder;
-import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.PersistableBundle;
@@ -31,33 +28,32 @@
import android.os.SystemProperties;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
-import android.telephony.ims.internal.feature.ImsFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsSmsListener;
import android.telephony.ims.feature.CapabilityChangeRequest;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
-import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.util.Log;
import com.android.ims.internal.IImsCallSession;
import com.android.ims.internal.IImsEcbm;
import com.android.ims.internal.IImsMultiEndpoint;
import com.android.ims.internal.IImsUt;
-import com.android.ims.internal.ImsCallSession;
+import android.telephony.ims.ImsCallSession;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.ExponentialBackoff;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.CopyOnWriteArraySet;
/**
@@ -165,6 +161,11 @@
*/
public static final String EXTRA_IS_UNKNOWN_CALL = "android:isUnknown";
+ private static final int SYSTEM_PROPERTY_NOT_SET = -1;
+
+ // -1 indicates a subscriptionProperty value that is never set.
+ private static final int SUB_PROPERTY_NOT_INITIALIZED = -1;
+
private static final String TAG = "ImsManager";
private static final boolean DBG = true;
@@ -193,14 +194,6 @@
private Set<MmTelFeatureConnection.IFeatureUpdate> mStatusCallbacks =
new CopyOnWriteArraySet<>();
- // SystemProperties used as cache
- private static final String VOLTE_PROVISIONED_PROP = "net.lte.ims.volte.provisioned";
- private static final String WFC_PROVISIONED_PROP = "net.lte.ims.wfc.provisioned";
- private static final String VT_PROVISIONED_PROP = "net.lte.ims.vt.provisioned";
- // Flag indicating data enabled or not. This flag should be in sync with
- // DcTracker.isDataEnabled(). The flag will be set later during boot up.
- private static final String DATA_ENABLED_PROP = "net.lte.ims.data.enabled";
-
public static final String TRUE = "true";
public static final String FALSE = "false";
@@ -209,19 +202,6 @@
private ConcurrentLinkedDeque<ImsReasonInfo> mRecentDisconnectReasons =
new ConcurrentLinkedDeque<>();
- // Exponential backoff for provisioning cache update. May be null for instances of ImsManager
- // that are not on a thread supporting a looper.
- private ExponentialBackoff mProvisionBackoff;
- // Initial Provisioning check delay in ms
- private static final long BACKOFF_INITIAL_DELAY_MS = 500;
- // Max Provisioning check delay in ms (5 Minutes)
- private static final long BACKOFF_MAX_DELAY_MS = 300000;
- // Multiplier for exponential delay
- private static final int BACKOFF_MULTIPLIER = 2;
- // -1 indicates a subscriptionProperty value that is never set.
- private static final int SUB_PROPERTY_NOT_INITIALIZED = -1;
-
-
/**
* Gets a manager instance.
*
@@ -265,9 +245,12 @@
/**
* Returns the user configuration of Enhanced 4G LTE Mode setting for slot. If the option is
- * not editable ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false),
- * this method will return default value specified by
+ * not editable ({@link CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL} is false), or
+ * the setting is not initialized, this method will return default value specified by
* {@link CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL}.
+ *
+ * Note that even if the setting was set, it may no longer be editable. If this is the case we
+ * return the default value.
*/
public boolean isEnhanced4gLteModeSettingEnabledByUser() {
int setting = SubscriptionManager.getIntegerSubscriptionProperty(
@@ -387,8 +370,13 @@
* basis.
*/
public boolean isVolteEnabledByPlatform() {
- if (SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
- PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT) == 1) {
+ // We first read the per slot value. If doesn't exist, we read the general value. If still
+ // doesn't exist, we use the hardcoded default value.
+ if (SystemProperties.getInt(
+ PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE + Integer.toString(mPhoneId),
+ SYSTEM_PROPERTY_NOT_SET) == 1 ||
+ SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
+ SYSTEM_PROPERTY_NOT_SET) == 1) {
return true;
}
@@ -521,8 +509,12 @@
* which must be done correctly).
*/
public boolean isVtEnabledByPlatform() {
- if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE,
- PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT) == 1) {
+ // We first read the per slot value. If doesn't exist, we read the general value. If still
+ // doesn't exist, we use the hardcoded default value.
+ if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE +
+ Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
+ SystemProperties.getInt(
+ PROPERTY_DBG_VT_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
return true;
}
@@ -557,7 +549,8 @@
SUB_PROPERTY_NOT_INITIALIZED, mContext);
// If it's never set, by default we return true.
- return (setting == SUB_PROPERTY_NOT_INITIALIZED || setting == 1);
+ return (setting == SUB_PROPERTY_NOT_INITIALIZED
+ || setting == ImsConfig.FeatureValueConstants.ON);
}
/**
@@ -624,10 +617,15 @@
* The platform property may override the carrier config.
*/
private boolean isTurnOffImsAllowedByPlatform() {
- if (SystemProperties.getInt(PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE,
- PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE_DEFAULT) == 1) {
+ // We first read the per slot value. If doesn't exist, we read the general value. If still
+ // doesn't exist, we use the hardcoded default value.
+ if (SystemProperties.getInt(PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE +
+ Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
+ SystemProperties.getInt(
+ PROPERTY_DBG_ALLOW_IMS_OFF_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
return true;
}
+
return getBooleanCarrierConfig(
CarrierConfigManager.KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL);
}
@@ -662,7 +660,7 @@
return getBooleanCarrierConfig(
CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL);
} else {
- return setting == 1;
+ return setting == ImsConfig.FeatureValueConstants.ON;
}
}
@@ -942,7 +940,7 @@
return getBooleanCarrierConfig(
CarrierConfigManager.KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL);
} else {
- return (setting == 1);
+ return setting == ImsConfig.FeatureValueConstants.ON;
}
}
@@ -1008,8 +1006,12 @@
* configuration settings which must be done correctly).
*/
public boolean isWfcEnabledByPlatform() {
- if (SystemProperties.getInt(PROPERTY_DBG_WFC_AVAIL_OVERRIDE,
- PROPERTY_DBG_WFC_AVAIL_OVERRIDE_DEFAULT) == 1) {
+ // We first read the per slot value. If doesn't exist, we read the general value. If still
+ // doesn't exist, we use the hardcoded default value.
+ if (SystemProperties.getInt(PROPERTY_DBG_WFC_AVAIL_OVERRIDE +
+ Integer.toString(mPhoneId), SYSTEM_PROPERTY_NOT_SET) == 1 ||
+ SystemProperties.getInt(
+ PROPERTY_DBG_WFC_AVAIL_OVERRIDE, SYSTEM_PROPERTY_NOT_SET) == 1) {
return true;
}
@@ -1044,116 +1046,28 @@
}
/**
- * This function should be called when ImsConfig.ACTION_IMS_CONFIG_CHANGED is received.
- *
- * We cannot register receiver in ImsManager because this would lead to resource leak.
- * ImsManager can be created in different processes and it is not notified when that process
- * is about to be terminated.
- *
- * @hide
- * */
- public static void onProvisionedValueChanged(Context context, int item, String value) {
- if (DBG) Rlog.d(TAG, "onProvisionedValueChanged: item=" + item + " val=" + value);
- ImsManager mgr = ImsManager.getInstance(context,
- SubscriptionManager.getDefaultVoicePhoneId());
-
- switch (item) {
- case ImsConfig.ConfigConstants.VLT_SETTING_ENABLED:
- mgr.setVolteProvisionedProperty(value.equals("1"));
- if (DBG) Rlog.d(TAG,"isVoLteProvisioned = " + mgr.isVolteProvisioned());
- break;
-
- case ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED:
- mgr.setWfcProvisionedProperty(value.equals("1"));
- if (DBG) Rlog.d(TAG,"isWfcProvisioned = " + mgr.isWfcProvisioned());
- break;
-
- case ImsConfig.ConfigConstants.LVC_SETTING_ENABLED:
- mgr.setVtProvisionedProperty(value.equals("1"));
- if (DBG) Rlog.d(TAG,"isVtProvisioned = " + mgr.isVtProvisioned());
- break;
-
+ * Will return with config value or throw an ImsException if we receive an error from
+ * ImsConfig for that value.
+ */
+ private boolean getProvisionedBool(ImsConfig config, int item) throws ImsException {
+ int value = config.getProvisionedValue(item);
+ if (value == ImsConfig.OperationStatusConstants.UNKNOWN) {
+ throw new ImsException("getProvisionedBool failed with error for item: " + item,
+ ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
}
- }
-
- private class AsyncUpdateProvisionedValues extends AsyncTask<Void, Void, Boolean> {
- @Override
- protected Boolean doInBackground(Void... params) {
- // disable on any error
- setVolteProvisionedProperty(false);
- setWfcProvisionedProperty(false);
- setVtProvisionedProperty(false);
-
- try {
- ImsConfig config = getConfigInterface();
- if (config != null) {
- setVolteProvisionedProperty(getProvisionedBool(config,
- ImsConfig.ConfigConstants.VLT_SETTING_ENABLED));
- if (DBG) Rlog.d(TAG, "isVoLteProvisioned = " + isVolteProvisioned());
-
- setWfcProvisionedProperty(getProvisionedBool(config,
- ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED));
- if (DBG) Rlog.d(TAG, "isWfcProvisioned = " + isWfcProvisioned());
-
- setVtProvisionedProperty(getProvisionedBool(config,
- ImsConfig.ConfigConstants.LVC_SETTING_ENABLED));
- if (DBG) Rlog.d(TAG, "isVtProvisioned = " + isVtProvisioned());
-
- }
- } catch (ImsException ie) {
- Rlog.e(TAG, "AsyncUpdateProvisionedValues error: ", ie);
- return false;
- }
-
- return true;
- }
-
- @Override
- protected void onPostExecute(Boolean completed) {
- if (mProvisionBackoff == null) {
- return;
- }
- if (!completed) {
- mProvisionBackoff.notifyFailed();
- } else {
- mProvisionBackoff.stop();
- }
- }
-
- /**
- * Will return with config value or throw an ImsException if we receive an error from
- * ImsConfig for that value.
- */
- private boolean getProvisionedBool(ImsConfig config, int item) throws ImsException {
- int value = config.getProvisionedValue(item);
- if (value == ImsConfig.FeatureValueConstants.ERROR) {
- throw new ImsException("getProvisionedBool failed with error for item: " + item,
- ImsReasonInfo.CODE_LOCAL_INTERNAL_ERROR);
- }
- return config.getProvisionedValue(item) == ImsConfig.FeatureValueConstants.ON;
- }
- }
-
- // used internally only, use #updateProvisionedValues instead.
- private void handleUpdateProvisionedValues() {
- if (getBooleanCarrierConfig(
- CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL)) {
-
- new AsyncUpdateProvisionedValues().execute();
- }
+ return config.getProvisionedValue(item) == ImsConfig.FeatureValueConstants.ON;
}
/**
- * Asynchronously get VoLTE, WFC, VT provisioning statuses. If ImsConfig is not available, we
- * will retry with exponential backoff.
+ * Will return with config value or return false if we receive an error from
+ * ImsConfig for that value.
*/
- private void updateProvisionedValues() {
- // Start trying to receive provisioning status after BACKOFF_INITIAL_DELAY_MS.
- if (mProvisionBackoff != null) {
- mProvisionBackoff.start();
- } else {
- // bypass and launch async thread once without backoff.
- handleUpdateProvisionedValues();
+ private boolean getProvisionedBoolNoException(int item) {
+ try {
+ ImsConfig config = getConfigInterface();
+ return getProvisionedBool(config, item);
+ } catch (ImsException ex) {
+ return false;
}
}
@@ -1178,8 +1092,6 @@
/**
* Sync carrier config and user settings with ImsConfig.
*
- * @param context for the manager object
- * @param phoneId phone id
* @param force update
*/
public void updateImsServiceConfig(boolean force) {
@@ -1194,8 +1106,6 @@
if (!mConfigUpdated || force) {
try {
- updateProvisionedValues();
-
// TODO: Extend ImsConfig API and set all feature values in single function call.
// Note: currently the order of updates is set to produce different order of
@@ -1318,11 +1228,6 @@
com.android.internal.R.bool.config_dynamic_bind_ims);
mConfigManager = (CarrierConfigManager) context.getSystemService(
Context.CARRIER_CONFIG_SERVICE);
- if (Looper.getMainLooper() != null) {
- mProvisionBackoff = new ExponentialBackoff(BACKOFF_INITIAL_DELAY_MS,
- BACKOFF_MAX_DELAY_MS, BACKOFF_MULTIPLIER,
- new Handler(Looper.getMainLooper()), this::handleUpdateProvisionedValues);
- }
createImsService();
}
@@ -1734,6 +1639,28 @@
}
}
+ public void setRttEnabled(boolean enabled) {
+ try {
+ setAdvanced4GMode(enabled || isEnhanced4gLteModeSettingEnabledByUser());
+ final int value = enabled ? ImsConfig.FeatureValueConstants.ON :
+ ImsConfig.FeatureValueConstants.OFF;
+ Thread thread = new Thread(() -> {
+ try {
+ Log.i(ImsManager.class.getSimpleName(), "Setting RTT enabled to " + enabled);
+ getConfigInterface().setProvisionedValue(
+ ImsConfig.ConfigConstants.RTT_SETTING_ENABLED, value);
+ } catch (ImsException e) {
+ Log.e(ImsManager.class.getSimpleName(), "Unable to set RTT enabled to "
+ + enabled + ": " + e);
+ }
+ });
+ thread.start();
+ } catch (ImsException e) {
+ Log.e(ImsManager.class.getSimpleName(), "Unable to set RTT enabled to " + enabled
+ + ": " + e);
+ }
+ }
+
/**
* Set the TTY mode. This is the actual tty mode (varies depending on peripheral status)
*/
@@ -2101,21 +2028,13 @@
public void onSmsReady() throws ImsException{
try {
- mImsServiceProxy.onSmsReady();
+ mMmTelFeatureConnection.onSmsReady();
} catch (RemoteException e) {
throw new ImsException("onSmsReady()", e,
ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
}
}
- public void addRegistrationCallback(ImsRegistrationImplBase.Callback callback) {
- // TODO: implement (coming in ag/3472519)
- }
-
- public void addCapabilitiesCallback(ImsFeature.CapabilityCallback callback) {
- // TODO: implement (coming in ag/3472519)
- }
-
/**
* Gets the Multi-Endpoint interface to subscribe to multi-enpoint notifications..
*
@@ -2168,7 +2087,9 @@
public void factoryReset() {
// Set VoLTE to default
SubscriptionManager.setSubscriptionProperty(getSubId(),
- SubscriptionManager.ENHANCED_4G_MODE_ENABLED, booleanToPropertyString(true));
+ SubscriptionManager.ENHANCED_4G_MODE_ENABLED,
+ booleanToPropertyString(getBooleanCarrierConfig(
+ CarrierConfigManager.KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL)));
// Set VoWiFi to default
SubscriptionManager.setSubscriptionProperty(getSubId(),
@@ -2197,40 +2118,22 @@
}
private boolean isDataEnabled() {
- return SystemProperties.getBoolean(DATA_ENABLED_PROP, true);
- }
-
- /**
- * Set data enabled/disabled flag.
- * @param enabled True if data is enabled, otherwise disabled.
- */
- public void setDataEnabled(boolean enabled) {
- log("setDataEnabled: " + enabled);
- SystemProperties.set(DATA_ENABLED_PROP, enabled ? TRUE : FALSE);
+ return new TelephonyManager(mContext, getSubId()).isMobileDataEnabled();
}
private boolean isVolteProvisioned() {
- return SystemProperties.getBoolean(VOLTE_PROVISIONED_PROP, true);
- }
-
- private void setVolteProvisionedProperty(boolean provisioned) {
- SystemProperties.set(VOLTE_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
+ return getProvisionedBoolNoException(
+ ImsConfig.ConfigConstants.VLT_SETTING_ENABLED);
}
private boolean isWfcProvisioned() {
- return SystemProperties.getBoolean(WFC_PROVISIONED_PROP, true);
- }
-
- private void setWfcProvisionedProperty(boolean provisioned) {
- SystemProperties.set(WFC_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
+ return getProvisionedBoolNoException(
+ ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED);
}
private boolean isVtProvisioned() {
- return SystemProperties.getBoolean(VT_PROVISIONED_PROP, true);
- }
-
- private void setVtProvisionedProperty(boolean provisioned) {
- SystemProperties.set(VT_PROVISIONED_PROP, provisioned ? TRUE : FALSE);
+ return getProvisionedBoolNoException(
+ ImsConfig.ConfigConstants.LVC_SETTING_ENABLED);
}
private static String booleanToPropertyString(boolean bool) {
diff --git a/src/java/com/android/ims/ImsMultiEndpoint.java b/src/java/com/android/ims/ImsMultiEndpoint.java
index 9692696..1315dbd 100644
--- a/src/java/com/android/ims/ImsMultiEndpoint.java
+++ b/src/java/com/android/ims/ImsMultiEndpoint.java
@@ -21,6 +21,8 @@
import android.os.RemoteException;
import android.telephony.Rlog;
+import android.telephony.ims.ImsExternalCallState;
+import android.telephony.ims.ImsReasonInfo;
import java.util.List;
diff --git a/src/java/com/android/ims/ImsServiceBase.java b/src/java/com/android/ims/ImsServiceBase.java
index 66122df..0a15c9d 100644
--- a/src/java/com/android/ims/ImsServiceBase.java
+++ b/src/java/com/android/ims/ImsServiceBase.java
@@ -18,7 +18,7 @@
import android.app.PendingIntent;
-import com.android.ims.ImsCallProfile;
+import android.telephony.ims.ImsCallProfile;
import com.android.ims.internal.IImsCallSession;
import com.android.ims.internal.IImsCallSessionListener;
import com.android.ims.internal.IImsConfig;
diff --git a/src/java/com/android/ims/ImsServiceProxy.java b/src/java/com/android/ims/ImsServiceProxy.java
deleted file mode 100644
index a874436..0000000
--- a/src/java/com/android/ims/ImsServiceProxy.java
+++ /dev/null
@@ -1,423 +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.ims;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.Rlog;
-import android.telephony.TelephonyManager;
-import android.telephony.ims.aidl.IImsCallSessionListener;
-import android.telephony.ims.feature.ImsFeature;
-import android.telephony.SmsMessage;
-import android.telephony.ims.internal.stub.SmsImplBase;
-import android.util.Log;
-
-import com.android.ims.internal.IImsCallSession;
-import com.android.ims.internal.IImsConfig;
-import com.android.ims.internal.IImsEcbm;
-import com.android.ims.internal.IImsMMTelFeature;
-import com.android.ims.internal.IImsMultiEndpoint;
-import com.android.ims.internal.IImsRegistration;
-import com.android.ims.internal.IImsRegistrationListener;
-import com.android.ims.internal.IImsServiceFeatureCallback;
-import com.android.ims.internal.IImsSmsListener;
-import com.android.ims.internal.IImsUt;
-
-/**
- * A container of the IImsServiceController binder, which implements all of the ImsFeatures that
- * the platform currently supports: MMTel and RCS.
- * @hide
- */
-
-public class ImsServiceProxy {
-
- protected static final String TAG = "ImsServiceProxy";
- protected final int mSlotId;
- protected IBinder mBinder;
- private final int mSupportedFeature;
- private Context mContext;
-
- // Start by assuming the proxy is available for usage.
- private boolean mIsAvailable = true;
- // ImsFeature Status from the ImsService. Cached.
- private Integer mFeatureStatusCached = null;
- private IFeatureUpdate mStatusCallback;
- private final Object mLock = new Object();
-
- public static ImsServiceProxy create(Context context , int slotId) {
- ImsServiceProxy serviceProxy = new ImsServiceProxy(context, slotId, ImsFeature.MMTEL);
-
- TelephonyManager tm = getTelephonyManager(context);
- if (tm == null) {
- Rlog.w(TAG, "getServiceProxy: TelephonyManager is null!");
- // Binder can be unset in this case because it will be torn down/recreated as part of
- // a retry mechanism until the serviceProxy binder is set successfully.
- return serviceProxy;
- }
-
- IImsMMTelFeature binder = tm.getImsMMTelFeatureAndListen(slotId,
- serviceProxy.getListener());
- if (binder != null) {
- serviceProxy.setBinder(binder.asBinder());
- // Trigger the cache to be updated for feature status.
- serviceProxy.getFeatureStatus();
- } else {
- Rlog.w(TAG, "getServiceProxy: binder is null! Phone Id: " + slotId);
- }
- return serviceProxy;
- }
-
- public static TelephonyManager getTelephonyManager(Context context) {
- return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- }
-
- public interface IFeatureUpdate {
- /**
- * Called when the ImsFeature has changed its state. Use
- * {@link ImsFeature#getFeatureState()} to get the new state.
- */
- void notifyStateChanged();
-
- /**
- * Called when the ImsFeature has become unavailable due to the binder switching or app
- * crashing. A new ImsServiceProxy should be requested for that feature.
- */
- void notifyUnavailable();
- }
-
- private final IImsServiceFeatureCallback mListenerBinder =
- new IImsServiceFeatureCallback.Stub() {
-
- @Override
- public void imsFeatureCreated(int slotId, int feature) throws RemoteException {
- // The feature has been re-enabled. This may happen when the service crashes.
- synchronized (mLock) {
- if (!mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) {
- Log.i(TAG, "Feature enabled on slotId: " + slotId + " for feature: " +
- feature);
- mIsAvailable = true;
- }
- }
- }
-
- @Override
- public void imsFeatureRemoved(int slotId, int feature) throws RemoteException {
- synchronized (mLock) {
- if (mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) {
- Log.i(TAG, "Feature disabled on slotId: " + slotId + " for feature: " +
- feature);
- mIsAvailable = false;
- if (mStatusCallback != null) {
- mStatusCallback.notifyUnavailable();
- }
- }
- }
- }
-
- @Override
- public void imsStatusChanged(int slotId, int feature, int status) throws RemoteException {
- synchronized (mLock) {
- Log.i(TAG, "imsStatusChanged: slot: " + slotId + " feature: " + feature +
- " status: " + status);
- if (mSlotId == slotId && feature == mSupportedFeature) {
- mFeatureStatusCached = status;
- if (mStatusCallback != null) {
- mStatusCallback.notifyStateChanged();
- }
- }
- }
- }
- };
-
- public ImsServiceProxy(Context context, int slotId, IBinder binder, int featureType) {
- mSlotId = slotId;
- mBinder = binder;
- mSupportedFeature = featureType;
- mContext = context;
- }
-
- public ImsServiceProxy(Context context, int slotId, int featureType) {
- this(context, slotId, null, featureType);
- }
-
- public @Nullable IImsRegistration getRegistration() {
- TelephonyManager tm = getTelephonyManager(mContext);
- return tm != null ? tm.getImsRegistration(mSlotId, ImsFeature.MMTEL) : null;
- }
-
- public IImsServiceFeatureCallback getListener() {
- return mListenerBinder;
- }
-
- public void setBinder(IBinder binder) {
- mBinder = binder;
- }
-
- public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
- throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).startSession(incomingCallIntent, listener);
- }
- }
-
- public void endSession(int sessionId) throws RemoteException {
- synchronized (mLock) {
- // Only check to make sure the binder connection still exists. This method should
- // still be able to be called when the state is STATE_NOT_AVAILABLE.
- checkBinderConnection();
- getServiceInterface(mBinder).endSession(sessionId);
- }
- }
-
- public boolean isConnected(int callServiceType, int callType)
- throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).isConnected(callServiceType, callType);
- }
- }
-
- public boolean isOpened() throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).isOpened();
- }
- }
-
- public void addRegistrationListener(IImsRegistrationListener listener)
- throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).addRegistrationListener(listener);
- }
- }
-
- public void removeRegistrationListener(IImsRegistrationListener listener)
- throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).removeRegistrationListener(listener);
- }
- }
-
- public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType)
- throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).createCallProfile(sessionId, callServiceType,
- callType);
- }
- }
-
- public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile)
- throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).createCallSession(sessionId, profile);
- }
- }
-
- public IImsCallSession getPendingCallSession(int sessionId, String callId)
- throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).getPendingCallSession(sessionId, callId);
- }
- }
-
- public IImsUt getUtInterface() throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).getUtInterface();
- }
- }
-
- public IImsConfig getConfigInterface() throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).getConfigInterface();
- }
- }
-
- public void turnOnIms() throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).turnOnIms();
- }
- }
-
- public void turnOffIms() throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).turnOffIms();
- }
- }
-
- public IImsEcbm getEcbmInterface() throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).getEcbmInterface();
- }
- }
-
- public void setUiTTYMode(int uiTtyMode, Message onComplete)
- throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).setUiTTYMode(uiTtyMode, onComplete);
- }
- }
-
- public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).getMultiEndpointInterface();
- }
- }
-
- /**
- * @return an integer describing the current Feature Status, defined in
- * {@link ImsFeature.ImsState}.
- */
- public int getFeatureStatus() {
- synchronized (mLock) {
- if (isBinderAlive() && mFeatureStatusCached != null) {
- Log.i(TAG, "getFeatureStatus - returning cached: " + mFeatureStatusCached);
- return mFeatureStatusCached;
- }
- }
- // Don't synchronize on Binder call.
- Integer status = retrieveFeatureStatus();
- synchronized (mLock) {
- if (status == null) {
- return ImsFeature.STATE_NOT_AVAILABLE;
- }
- // Cache only non-null value for feature status.
- mFeatureStatusCached = status;
- }
- Log.i(TAG, "getFeatureStatus - returning " + status);
- return status;
- }
-
- /**
- * Internal method used to retrieve the feature status from the corresponding ImsService.
- */
- private Integer retrieveFeatureStatus() {
- if (mBinder != null) {
- try {
- return getServiceInterface(mBinder).getFeatureStatus();
- } catch (RemoteException e) {
- // Status check failed, don't update cache
- }
- }
- return null;
- }
-
- /**
- * @param c Callback that will fire when the feature status has changed.
- */
- public void setStatusCallback(IFeatureUpdate c) {
- mStatusCallback = c;
- }
-
- public void sendSms(int token, int messageRef, String format, String smsc, boolean isRetry,
- byte[] pdu) throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).sendSms(token, messageRef, format, smsc, isRetry,
- pdu);
- }
- }
-
- public void acknowledgeSms(int token, int messageRef,
- @SmsImplBase.SendStatusResult int result) throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).acknowledgeSms(token, messageRef, result);
- }
- }
-
- public void acknowledgeSmsReport(int token, int messageRef,
- @SmsImplBase.StatusReportResult int result) throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).acknowledgeSmsReport(token, messageRef, result);
- }
- }
-
- public String getSmsFormat() throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- return getServiceInterface(mBinder).getSmsFormat();
- }
- }
-
- public void onSmsReady() throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).onSmsReady();
- }
- }
-
- public void setSmsListener(IImsSmsListener listener) throws RemoteException {
- synchronized (mLock) {
- checkServiceIsReady();
- getServiceInterface(mBinder).setSmsListener(listener);
- }
- }
-
- /**
- * @return Returns true if the ImsService is ready to take commands, false otherwise. If this
- * method returns false, it doesn't mean that the Binder connection is not available (use
- * {@link #isBinderReady()} to check that), but that the ImsService is not accepting commands
- * at this time.
- *
- * For example, for DSDS devices, only one slot can be {@link ImsFeature#STATE_READY} to take
- * commands at a time, so the other slot must stay at {@link ImsFeature#STATE_NOT_AVAILABLE}.
- */
- public boolean isBinderReady() {
- return isBinderAlive() && getFeatureStatus() == ImsFeature.STATE_READY;
- }
-
- /**
- * @return false if the binder connection is no longer alive.
- */
- public boolean isBinderAlive() {
- return mIsAvailable && mBinder != null && mBinder.isBinderAlive();
- }
-
- protected void checkServiceIsReady() throws RemoteException {
- if (!isBinderReady()) {
- throw new RemoteException("ImsServiceProxy is not ready to accept commands.");
- }
- }
-
- private IImsMMTelFeature getServiceInterface(IBinder b) {
- return IImsMMTelFeature.Stub.asInterface(b);
- }
-
- protected void checkBinderConnection() throws RemoteException {
- if (!isBinderAlive()) {
- throw new RemoteException("ImsServiceProxy is not available for that feature.");
- }
- }
-}
diff --git a/src/java/com/android/ims/ImsUt.java b/src/java/com/android/ims/ImsUt.java
index eaeb551..b3d4c8a 100644
--- a/src/java/com/android/ims/ImsUt.java
+++ b/src/java/com/android/ims/ImsUt.java
@@ -27,6 +27,10 @@
import android.os.Registrant;
import android.os.RemoteException;
import android.telephony.Rlog;
+import android.telephony.ims.ImsCallForwardInfo;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsSsData;
+import android.telephony.ims.ImsSsInfo;
import com.android.ims.internal.IImsUt;
import com.android.ims.internal.IImsUtListener;
diff --git a/src/java/com/android/ims/MmTelFeatureConnection.java b/src/java/com/android/ims/MmTelFeatureConnection.java
index 00dec65..571670d 100644
--- a/src/java/com/android/ims/MmTelFeatureConnection.java
+++ b/src/java/com/android/ims/MmTelFeatureConnection.java
@@ -24,6 +24,8 @@
import android.os.RemoteException;
import android.telephony.Rlog;
import android.telephony.TelephonyManager;
+import android.telephony.ims.ImsCallProfile;
+import android.telephony.ims.ImsReasonInfo;
import android.telephony.ims.aidl.IImsConfig;
import android.telephony.ims.aidl.IImsMmTelFeature;
import android.telephony.ims.aidl.IImsRegistration;
@@ -524,6 +526,13 @@
}
}
+ public void onSmsReady() throws RemoteException {
+ synchronized (mLock) {
+ checkServiceIsReady();
+ getServiceInterface(mBinder).onSmsReady();
+ }
+ }
+
public void setSmsListener(IImsSmsListener listener) throws RemoteException {
synchronized (mLock) {
checkServiceIsReady();
diff --git a/src/java/com/android/ims/internal/VideoPauseTracker.java b/src/java/com/android/ims/internal/VideoPauseTracker.java
index baa3163..9243008 100644
--- a/src/java/com/android/ims/internal/VideoPauseTracker.java
+++ b/src/java/com/android/ims/internal/VideoPauseTracker.java
@@ -18,11 +18,11 @@
import android.telecom.Log;
import android.telecom.VideoProfile;
+import android.telephony.ims.ImsVideoCallProvider;
import android.util.ArraySet;
import java.util.Collection;
import java.util.Set;
-import java.util.StringJoiner;
import java.util.stream.Collectors;
/**
@@ -71,7 +71,7 @@
*
* @param source The source of the pause request.
* @return {@code true} if a pause should be issued to the
- * {@link com.android.ims.internal.ImsVideoCallProvider}, {@code false} otherwise.
+ * {@link ImsVideoCallProvider}, {@code false} otherwise.
*/
public boolean shouldPauseVideoFor(int source) {
synchronized (mPauseRequestsLock) {
@@ -102,7 +102,7 @@
*
* @param source The source of the resume request.
* @return {@code true} if a resume should be issued to the
- * {@link com.android.ims.internal.ImsVideoCallProvider}, {@code false} otherwise.
+ * {@link ImsVideoCallProvider}, {@code false} otherwise.
*/
public boolean shouldResumeVideoFor(int source) {
synchronized (mPauseRequestsLock) {
diff --git a/tests/src/com/android/ims/ImsConfigTest.java b/tests/src/com/android/ims/ImsConfigTest.java
index 18d53b1..4cf7a92 100644
--- a/tests/src/com/android/ims/ImsConfigTest.java
+++ b/tests/src/com/android/ims/ImsConfigTest.java
@@ -17,8 +17,7 @@
package com.android.ims;
import android.support.test.runner.AndroidJUnit4;
-
-import com.android.ims.internal.IImsConfig;
+import android.telephony.ims.aidl.IImsConfig;
import org.junit.After;
import org.junit.Before;
@@ -59,6 +58,6 @@
mTestImsConfig.getProvisionedValue(testItem);
- verify(mMockImsConfigInterface).getProvisionedValue(eq(testItem));
+ verify(mMockImsConfigInterface).getConfigInt(eq(testItem));
}
}