diff options
author | Brad Ebinger <breadley@google.com> | 2020-09-11 12:36:50 -0700 |
---|---|---|
committer | Brad Ebinger <breadley@google.com> | 2020-10-05 11:03:59 -0700 |
commit | 1e9cc7b2e5d961107aa31c680263ed51e3232f5c (patch) | |
tree | fce7db8cd57c4800069150bf542b9493556b4ea9 | |
parent | b2356e4d98541bbad31aa6af72350a1a0b80b6da (diff) |
Clean up IMS based interfaces to use a push model instead of poll
[RESUBMISSION AFTER REVERT aosp/1443078]
Instead of requiring that listeners poll for an ImsFeature binder
when they go down, modify interfaces to notify listeners when a
new instance of a Binder is available.
Test: atest CtsTelephonyTestCases FrameworksTelephonyTests ImsCommonTests
Test: manual E2E tests of IMS functionality (call, SMS, settings...)
Merged-In: I0bb48f82ecf7a1283be8fd441a787dff587d6d61
Change-Id: I0bb48f82ecf7a1283be8fd441a787dff587d6d61
8 files changed, 272 insertions, 95 deletions
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 4b5399e74abf..189c940cbf8f 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -85,8 +85,6 @@ import android.telephony.emergency.EmergencyNumber; import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories; import android.telephony.ims.ImsMmTelManager; import android.telephony.ims.aidl.IImsConfig; -import android.telephony.ims.aidl.IImsMmTelFeature; -import android.telephony.ims.aidl.IImsRcsFeature; import android.telephony.ims.aidl.IImsRegistration; import android.telephony.ims.feature.MmTelFeature; import android.telephony.ims.stub.ImsRegistrationImplBase; @@ -94,7 +92,6 @@ import android.text.TextUtils; import android.util.Log; import android.util.Pair; -import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.CellNetworkScanResult; @@ -7326,80 +7323,6 @@ public class TelephonyManager { } /** - * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id and MMTel - * feature or {@link null} if the service is not available. If an MMTelFeature is available, the - * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates. - * @param slotIndex The SIM slot that we are requesting the {@link IImsMmTelFeature} for. - * @param callback Listener that will send updates to ImsManager when there are updates to - * ImsServiceController. - * @return {@link IImsMmTelFeature} interface for the feature specified or {@code null} if - * it is unavailable. - * @hide - */ - public @Nullable IImsMmTelFeature getImsMmTelFeatureAndListen(int slotIndex, - IImsServiceFeatureCallback callback) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getMmTelFeatureAndListen(slotIndex, callback); - } - } catch (RemoteException e) { - Rlog.e(TAG, "getImsMmTelFeatureAndListen, RemoteException: " - + e.getMessage()); - } - return null; - } - - /** - * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id and RCS - * feature for emergency calling or {@link null} if the service is not available. If an - * RcsFeature is available, the {@link IImsServiceFeatureCallback} callback is registered as a - * listener for feature updates. - * @param slotIndex The SIM slot that we are requesting the {@link IImsRcsFeature} for. - * @param callback Listener that will send updates to ImsManager when there are updates to - * ImsServiceController. - * @return {@link IImsRcsFeature} interface for the feature specified or {@code null} if - * it is unavailable. - * @hide - */ - public @Nullable IImsRcsFeature getImsRcsFeatureAndListen(int slotIndex, - IImsServiceFeatureCallback callback) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - return telephony.getRcsFeatureAndListen(slotIndex, callback); - } - } catch (RemoteException e) { - Rlog.e(TAG, "getImsRcsFeatureAndListen, RemoteException: " - + e.getMessage()); - } - return null; - } - - /** - * Unregister a IImsServiceFeatureCallback previously associated with an ImsFeature through - * {@link #getImsMmTelFeatureAndListen(int, IImsServiceFeatureCallback)} or - * {@link #getImsRcsFeatureAndListen(int, IImsServiceFeatureCallback)}. - * @param slotIndex The SIM slot associated with the callback. - * @param featureType The {@link android.telephony.ims.feature.ImsFeature.FeatureType} - * associated with the callback. - * @param callback The callback to be unregistered. - * @hide - */ - public void unregisterImsFeatureCallback(int slotIndex, int featureType, - IImsServiceFeatureCallback callback) { - try { - ITelephony telephony = getITelephony(); - if (telephony != null) { - telephony.unregisterImsFeatureCallback(slotIndex, featureType, callback); - } - } catch (RemoteException e) { - Rlog.e(TAG, "unregisterImsFeatureCallback, RemoteException: " - + e.getMessage()); - } - } - - /** * @return the {@IImsRegistration} interface that corresponds with the slot index and feature. * @param slotIndex The SIM slot corresponding to the ImsService ImsRegistration is active for. * @param feature An integer indicating the feature that we wish to get the ImsRegistration for. diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java index f6c14e67306b..ee2fce7e7dd5 100644 --- a/telephony/java/android/telephony/ims/ImsMmTelManager.java +++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java @@ -59,6 +59,7 @@ import java.util.function.Consumer; * manager. */ public class ImsMmTelManager implements RegistrationManager { + private static final String TAG = "ImsMmTelManager"; /** * @hide @@ -809,7 +810,7 @@ public class ImsMmTelManager implements RegistrationManager { } try { - getITelephony().isMmTelCapabilitySupported(mSubId, new IIntegerConsumer.Stub() { + iTelephony.isMmTelCapabilitySupported(mSubId, new IIntegerConsumer.Stub() { @Override public void accept(int result) { executor.execute(() -> callback.accept(result == 1)); diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java index da7311c08307..8a05bdfc8401 100644 --- a/telephony/java/android/telephony/ims/ImsService.java +++ b/telephony/java/android/telephony/ims/ImsService.java @@ -16,6 +16,7 @@ package android.telephony.ims; +import android.annotation.LongDef; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.Service; @@ -41,6 +42,11 @@ import android.util.SparseArray; import com.android.ims.internal.IImsFeatureStatusCallback; import com.android.internal.annotations.VisibleForTesting; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.HashMap; +import java.util.Map; + /** * Main ImsService implementation, which binds via the Telephony ImsResolver. Services that extend * ImsService must register the service in their AndroidManifest to be detected by the framework. @@ -98,6 +104,32 @@ public class ImsService extends Service { private static final String LOG_TAG = "ImsService"; /** + * This ImsService supports the capability to place emergency calls over MMTEL. + * @hide This is encoded into the {@link ImsFeature#FEATURE_EMERGENCY_MMTEL}, but we will be + * adding other capabilities in a central location, so track this capability here as well. + */ + public static final long CAPABILITY_EMERGENCY_OVER_MMTEL = 1 << 0; + + /** + * @hide + */ + @LongDef(flag = true, + prefix = "CAPABILITY_", + value = { + CAPABILITY_EMERGENCY_OVER_MMTEL + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ImsServiceCapability {} + + /** + * Used for logging purposes, see {@link #getCapabilitiesString(long)} + * @hide + */ + private static final Map<Long, String> CAPABILITIES_LOG_MAP = new HashMap<Long, String>() {{ + put(CAPABILITY_EMERGENCY_OVER_MMTEL, "EMERGENCY_OVER_MMTEL"); + }}; + + /** * The intent that must be defined as an intent-filter in the AndroidManifest of the ImsService. * @hide */ @@ -409,4 +441,30 @@ public class ImsService extends Service { public ImsRegistrationImplBase getRegistration(int slotId) { return new ImsRegistrationImplBase(); } + + /** + * @return A string representation of the ImsService capabilties for logging. + * @hide + */ + public static String getCapabilitiesString(@ImsServiceCapability long caps) { + StringBuffer result = new StringBuffer(); + result.append("capabilities={ "); + // filter incrementally fills 0s from left to right. This is used to keep filtering out + // more bits in the long until the remaining leftmost bits are all zero. + long filter = 0xFFFFFFFFFFFFFFFFL; + // position of iterator to potentially print capability. + long i = 0; + while ((caps & filter) != 0 && i <= 63) { + long bitToCheck = (1L << i); + if ((caps & bitToCheck) != 0) { + result.append(CAPABILITIES_LOG_MAP.getOrDefault(bitToCheck, bitToCheck + "?")); + result.append(" "); + } + // shift left by one and fill in another 1 on the leftmost bit. + filter <<= 1; + i++; + } + result.append("}"); + return result.toString(); + } }
\ No newline at end of file diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl index 9e461420e126..d012703b7510 100644 --- a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl +++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl @@ -22,6 +22,7 @@ import android.telephony.ims.aidl.IRcsUceControllerCallback; import android.telephony.ims.aidl.IRcsUcePublishStateCallback; import android.telephony.ims.aidl.IImsRegistrationCallback; +import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.telephony.IIntegerConsumer; /** @@ -50,4 +51,9 @@ interface IImsRcsController { void setUceSettingEnabled(int subId, boolean isEnabled); void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c); void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c); + + // Internal commands that should not be made public + void registerRcsFeatureCallback(int slotId, in IImsServiceFeatureCallback callback, + boolean oneShot); + void unregisterImsFeatureCallback(in IImsServiceFeatureCallback callback); } diff --git a/telephony/java/com/android/ims/ImsFeatureContainer.aidl b/telephony/java/com/android/ims/ImsFeatureContainer.aidl new file mode 100644 index 000000000000..9706f20c59ca --- /dev/null +++ b/telephony/java/com/android/ims/ImsFeatureContainer.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 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; + +parcelable ImsFeatureContainer;
\ No newline at end of file diff --git a/telephony/java/com/android/ims/ImsFeatureContainer.java b/telephony/java/com/android/ims/ImsFeatureContainer.java new file mode 100644 index 000000000000..b259679ea1bf --- /dev/null +++ b/telephony/java/com/android/ims/ImsFeatureContainer.java @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2020 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.NonNull; +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.ims.ImsService; +import android.telephony.ims.aidl.IImsConfig; +import android.telephony.ims.aidl.IImsRegistration; +import android.telephony.ims.feature.ImsFeature; + +import java.util.Objects; + +/** + * Contains an IBinder linking to the appropriate ImsFeature as well as the associated + * interfaces. + * @hide + */ +public final class ImsFeatureContainer implements Parcelable { + /** + * ImsFeature that is being tracked. + */ + public final IBinder imsFeature; + + /** + * IImsConfig interface that should be associated with the ImsFeature. + */ + public final android.telephony.ims.aidl.IImsConfig imsConfig; + + /** + * IImsRegistration interface that should be associated with this ImsFeature. + */ + public final IImsRegistration imsRegistration; + + /** + * State of the feature that is being tracked. + */ + private @ImsFeature.ImsState int mState = ImsFeature.STATE_UNAVAILABLE; + + /** + * Capabilities of this ImsService. + */ + private @ImsService.ImsServiceCapability long mCapabilities; + /** + * Contains the ImsFeature IBinder as well as the ImsService interfaces associated with + * that feature. + * @param iFace IBinder connection to the ImsFeature. + * @param iConfig IImsConfig interface associated with the ImsFeature. + * @param iReg IImsRegistration interface associated with the ImsFeature + * @param initialCaps The initial capabilities that the ImsService supports. + */ + public ImsFeatureContainer(@NonNull IBinder iFace, @NonNull IImsConfig iConfig, + @NonNull IImsRegistration iReg, long initialCaps) { + imsFeature = iFace; + imsConfig = iConfig; + imsRegistration = iReg; + mCapabilities = initialCaps; + } + + /** + * Create an ImsFeatureContainer from a Parcel. + */ + private ImsFeatureContainer(Parcel in) { + imsFeature = in.readStrongBinder(); + imsConfig = IImsConfig.Stub.asInterface(in.readStrongBinder()); + imsRegistration = IImsRegistration.Stub.asInterface(in.readStrongBinder()); + mState = in.readInt(); + mCapabilities = in.readLong(); + } + + /** + * @return the capabilties that are associated with the ImsService that this ImsFeature + * belongs to. + */ + public @ImsService.ImsServiceCapability long getCapabilities() { + return mCapabilities; + } + + /** + * Update the capabilities that are associated with the ImsService that this ImsFeature + * belongs to. + */ + public void setCapabilities(@ImsService.ImsServiceCapability long caps) { + mCapabilities = caps; + } + + /** + * @return The state of the ImsFeature. + */ + public @ImsFeature.ImsState int getState() { + return mState; + } + + /** + * Set the state that is associated with the ImsService that this ImsFeature + * belongs to. + */ + public void setState(@ImsFeature.ImsState int state) { + mState = state; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ImsFeatureContainer that = (ImsFeatureContainer) o; + return imsFeature.equals(that.imsFeature) && + imsConfig.equals(that.imsConfig) && + imsRegistration.equals(that.imsRegistration) && + mState == that.getState() && + mCapabilities == that.getCapabilities(); + } + + @Override + public int hashCode() { + return Objects.hash(imsFeature, imsConfig, imsRegistration, mState, mCapabilities); + } + + @Override + public String toString() { + return "FeatureContainer{" + + "imsFeature=" + imsFeature + + ", imsConfig=" + imsConfig + + ", imsRegistration=" + imsRegistration + + ", state=" + ImsFeature.STATE_LOG_MAP.get(mState) + + ", capabilities = " + ImsService.getCapabilitiesString(mCapabilities) + + '}'; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeStrongBinder(imsFeature); + dest.writeStrongInterface(imsConfig); + dest.writeStrongInterface(imsRegistration); + dest.writeInt(mState); + dest.writeLong(mCapabilities); + } + + + public static final Creator<ImsFeatureContainer> CREATOR = new Creator<ImsFeatureContainer>() { + @Override + public ImsFeatureContainer createFromParcel(Parcel source) { + return new ImsFeatureContainer(source); + } + + @Override + public ImsFeatureContainer[] newArray(int size) { + return new ImsFeatureContainer[size]; + } + }; +} diff --git a/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl index 9a9cf5325310..f5f67bd36ec3 100644 --- a/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl +++ b/telephony/java/com/android/ims/internal/IImsServiceFeatureCallback.aidl @@ -16,13 +16,18 @@ package com.android.ims.internal; +import com.android.ims.ImsFeatureContainer; /** - * Interface from ImsResolver to ImsServiceProxy in ImsManager. - * Callback to ImsManager when a feature changes in the ImsServiceController. + * Interface from ImsResolver to FeatureConnections. + * Callback to FeatureConnections when a feature's status changes. * {@hide} */ oneway interface IImsServiceFeatureCallback { - void imsFeatureCreated(int slotId, int feature); - void imsFeatureRemoved(int slotId, int feature); - void imsStatusChanged(int slotId, int feature, int status); + void imsFeatureCreated(in ImsFeatureContainer feature); + // Reason defined in FeatureConnector.UnavailableReason + void imsFeatureRemoved(int reason); + // Status defined in ImsFeature.ImsState. + void imsStatusChanged(int status); + //Capabilities defined in ImsService.ImsServiceCapability + void updateCapabilities(long capabilities); }
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index ae1b5c1b50bd..815ec68b2c4d 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -828,22 +828,15 @@ interface ITelephony { * as well as registering the MmTelFeature for callbacks using the IImsServiceFeatureCallback * interface. */ - IImsMmTelFeature getMmTelFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback); - - /** - * Get IImsRcsFeature binder from ImsResolver that corresponds to the subId and RCS feature - * as well as registering the RcsFeature for callbacks using the IImsServiceFeatureCallback - * interface. - */ - IImsRcsFeature getRcsFeatureAndListen(int slotId, in IImsServiceFeatureCallback callback); + void registerMmTelFeatureCallback(int slotId, in IImsServiceFeatureCallback callback, + boolean oneShot); /** * Unregister a callback that was previously registered through - * {@link #getMmTelFeatureAndListen} or {@link #getRcsFeatureAndListen}. This should always be - * called when the callback is no longer being used. + * {@link #registerMmTelFeatureCallback}. This should always be called when the callback is no + * longer being used. */ - void unregisterImsFeatureCallback(int slotId, int featureType, - in IImsServiceFeatureCallback callback); + void unregisterImsFeatureCallback(in IImsServiceFeatureCallback callback); /** * Returns the IImsRegistration associated with the slot and feature specified. |