Merge "Modify RCS UCE APIs to use AIDL Interfaces."
This commit is contained in:
@@ -508,6 +508,7 @@ java_defaults {
|
||||
"telephony/java/android/telephony/ims/aidl/IImsServiceControllerListener.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IRcsMessage.aidl",
|
||||
"telephony/java/android/telephony/ims/aidl/IRcsFeatureListener.aidl",
|
||||
"telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
|
||||
"telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl",
|
||||
"telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl",
|
||||
|
||||
@@ -39,11 +39,11 @@ public final class ImsException extends Exception {
|
||||
*/
|
||||
public static final int CODE_ERROR_UNSPECIFIED = 0;
|
||||
/**
|
||||
* The operation has failed because there is no {@link ImsService} available to service it. This
|
||||
* may be due to an {@link ImsService} crash or other illegal state.
|
||||
* The operation has failed because there is no remote process available to service it. This
|
||||
* may be due to a process crash or other illegal state.
|
||||
* <p>
|
||||
* This is a temporary error and the operation may be retried until the connection to the
|
||||
* {@link ImsService} is restored.
|
||||
* remote process is restored.
|
||||
*/
|
||||
public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1;
|
||||
|
||||
|
||||
@@ -16,10 +16,38 @@
|
||||
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.telephony.ims.RcsContactUceCapability;
|
||||
import android.telephony.ims.aidl.IImsCapabilityCallback;
|
||||
import android.telephony.ims.aidl.IRcsFeatureListener;
|
||||
import android.telephony.ims.feature.CapabilityChangeRequest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* See RcsFeature for more information.
|
||||
* {@hide}
|
||||
*/
|
||||
interface IImsRcsFeature {
|
||||
//Empty Default Implementation
|
||||
// Not oneway because we need to verify this completes before doing anything else.
|
||||
void setListener(IRcsFeatureListener listener);
|
||||
int queryCapabilityStatus();
|
||||
// Inherited from ImsFeature
|
||||
int getFeatureState();
|
||||
oneway void addCapabilityCallback(IImsCapabilityCallback c);
|
||||
oneway void removeCapabilityCallback(IImsCapabilityCallback c);
|
||||
oneway void changeCapabilitiesConfiguration(in CapabilityChangeRequest r,
|
||||
IImsCapabilityCallback c);
|
||||
oneway void queryCapabilityConfiguration(int capability, int radioTech,
|
||||
IImsCapabilityCallback c);
|
||||
// RcsPresenceExchangeImplBase specific api
|
||||
oneway void requestCapabilities(in List<Uri> uris, int operationToken);
|
||||
oneway void updateCapabilities(in RcsContactUceCapability capabilities, int operationToken);
|
||||
// RcsSipOptionsImplBase specific api
|
||||
oneway void sendCapabilityRequest(in Uri contactUri,
|
||||
in RcsContactUceCapability capabilities, int operationToken);
|
||||
oneway void respondToCapabilityRequest(in String contactUri,
|
||||
in RcsContactUceCapability ownCapabilities, int operationToken);
|
||||
oneway void respondToCapabilityRequestWithError(in Uri contactUri, int code, in String reason,
|
||||
int operationToken);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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 android.telephony.ims.aidl;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.telephony.ims.RcsContactUceCapability;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Listener interface for updates from the RcsFeature back to the framework.
|
||||
* {@hide}
|
||||
*/
|
||||
interface IRcsFeatureListener {
|
||||
//RcsCapabilityExchange specific
|
||||
oneway void onCommandUpdate(int commandCode, int operationToken);
|
||||
// RcsPresenceExchangeImplBase Specific
|
||||
oneway void onNetworkResponse(int code, in String reason, int operationToken);
|
||||
oneway void onCapabilityRequestResponsePresence(in List<RcsContactUceCapability> infos,
|
||||
int operationToken);
|
||||
oneway void onNotifyUpdateCapabilities();
|
||||
oneway void onUnpublish();
|
||||
// RcsSipOptionsImplBase specific
|
||||
oneway void onCapabilityRequestResponseOptions(int code, in String reason,
|
||||
in RcsContactUceCapability info, int operationToken);
|
||||
oneway void onRemoteCapabilityRequest(in Uri contactUri, in RcsContactUceCapability remoteInfo,
|
||||
int operationToken);
|
||||
}
|
||||
@@ -33,12 +33,8 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Base class for all IMS features that are supported by the framework. Use a concrete subclass
|
||||
@@ -51,35 +47,6 @@ public abstract class ImsFeature {
|
||||
|
||||
private static final String LOG_TAG = "ImsFeature";
|
||||
|
||||
/**
|
||||
* Action to broadcast when ImsService is up.
|
||||
* Internal use only.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_IMS_SERVICE_UP =
|
||||
"com.android.ims.IMS_SERVICE_UP";
|
||||
|
||||
/**
|
||||
* Action to broadcast when ImsService is down.
|
||||
* Internal use only.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_IMS_SERVICE_DOWN =
|
||||
"com.android.ims.IMS_SERVICE_DOWN";
|
||||
|
||||
/**
|
||||
* Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
|
||||
* A long value; the phone ID corresponding to the IMS service coming up or down.
|
||||
* Only defined here separately for compatibility purposes with the old ImsService.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_PHONE_ID = "android:phone_id";
|
||||
|
||||
/**
|
||||
* Invalid feature value
|
||||
* @hide
|
||||
@@ -335,8 +302,8 @@ public abstract class ImsFeature {
|
||||
/** @hide */
|
||||
protected final Object mLock = new Object();
|
||||
|
||||
private final Set<IImsFeatureStatusCallback> mStatusCallbacks =
|
||||
Collections.newSetFromMap(new WeakHashMap<>());
|
||||
private final RemoteCallbackList<IImsFeatureStatusCallback> mStatusCallbacks =
|
||||
new RemoteCallbackList<>();
|
||||
private @ImsState int mState = STATE_UNAVAILABLE;
|
||||
private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
private final RemoteCallbackList<IImsCapabilityCallback> mCapabilityCallbacks =
|
||||
@@ -397,9 +364,7 @@ public abstract class ImsFeature {
|
||||
// If we have just connected, send queued status.
|
||||
c.notifyImsFeatureStatus(getFeatureState());
|
||||
// Add the callback if the callback completes successfully without a RemoteException.
|
||||
synchronized (mLock) {
|
||||
mStatusCallbacks.add(c);
|
||||
}
|
||||
mStatusCallbacks.register(c);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
|
||||
}
|
||||
@@ -411,29 +376,21 @@ public abstract class ImsFeature {
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public void removeImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) {
|
||||
synchronized (mLock) {
|
||||
mStatusCallbacks.remove(c);
|
||||
}
|
||||
mStatusCallbacks.unregister(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method called by ImsFeature when setFeatureState has changed.
|
||||
*/
|
||||
private void notifyFeatureState(@ImsState int state) {
|
||||
synchronized (mLock) {
|
||||
for (Iterator<IImsFeatureStatusCallback> iter = mStatusCallbacks.iterator();
|
||||
iter.hasNext(); ) {
|
||||
IImsFeatureStatusCallback callback = iter.next();
|
||||
try {
|
||||
Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
|
||||
callback.notifyImsFeatureStatus(state);
|
||||
} catch (RemoteException e) {
|
||||
// remove if the callback is no longer alive.
|
||||
iter.remove();
|
||||
Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
|
||||
}
|
||||
mStatusCallbacks.broadcast((c) -> {
|
||||
try {
|
||||
c.notifyImsFeatureStatus(state);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, e + " notifyFeatureState() - Skipping "
|
||||
+ "callback.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -452,10 +409,23 @@ public abstract class ImsFeature {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public final void removeCapabilityCallback(IImsCapabilityCallback c) {
|
||||
final void removeCapabilityCallback(IImsCapabilityCallback c) {
|
||||
mCapabilityCallbacks.unregister(c);
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
final void queryCapabilityConfigurationInternal(int capability, int radioTech,
|
||||
IImsCapabilityCallback c) {
|
||||
boolean enabled = queryCapabilityConfiguration(capability, radioTech);
|
||||
try {
|
||||
if (c != null) {
|
||||
c.onQueryCapabilityConfiguration(capability, radioTech, enabled);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(LOG_TAG, "queryCapabilityConfigurationInternal called on dead binder!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cached capabilities status for this feature.
|
||||
* @hide
|
||||
@@ -484,30 +454,35 @@ public abstract class ImsFeature {
|
||||
/**
|
||||
* Called by the ImsFeature when the capabilities status has changed.
|
||||
*
|
||||
* @param c A {@link Capabilities} containing the new Capabilities status.
|
||||
* @param caps the new {@link Capabilities} status of the {@link ImsFeature}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
protected final void notifyCapabilitiesStatusChanged(Capabilities c) {
|
||||
protected final void notifyCapabilitiesStatusChanged(Capabilities caps) {
|
||||
synchronized (mLock) {
|
||||
mCapabilityStatus = c.copy();
|
||||
mCapabilityStatus = caps.copy();
|
||||
}
|
||||
int count = mCapabilityCallbacks.beginBroadcast();
|
||||
try {
|
||||
for (int i = 0; i < count; i++) {
|
||||
try {
|
||||
mCapabilityCallbacks.getBroadcastItem(i).onCapabilitiesStatusChanged(
|
||||
c.mCapabilities);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, e + " " + "notifyCapabilitiesStatusChanged() - Skipping " +
|
||||
"callback.");
|
||||
}
|
||||
mCapabilityCallbacks.broadcast((callback) -> {
|
||||
try {
|
||||
callback.onCapabilitiesStatusChanged(caps.mCapabilities);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, e + " notifyCapabilitiesStatusChanged() - Skipping "
|
||||
+ "callback.");
|
||||
}
|
||||
} finally {
|
||||
mCapabilityCallbacks.finishBroadcast();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the ImsFeature with the ability to return the framework Capability Configuration
|
||||
* for a provided Capability. If the framework calls {@link #changeEnabledCapabilities} and
|
||||
* includes a capability A to enable or disable, this method should return the correct enabled
|
||||
* status for capability A.
|
||||
* @param capability The capability that we are querying the configuration for.
|
||||
* @return true if the capability is enabled, false otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public abstract boolean queryCapabilityConfiguration(int capability, int radioTech);
|
||||
|
||||
/**
|
||||
* Features should override this method to receive Capability preference change requests from
|
||||
* the framework using the provided {@link CapabilityChangeRequest}. If any of the capabilities
|
||||
|
||||
@@ -37,7 +37,6 @@ import android.telephony.ims.stub.ImsMultiEndpointImplBase;
|
||||
import android.telephony.ims.stub.ImsRegistrationImplBase;
|
||||
import android.telephony.ims.stub.ImsSmsImplBase;
|
||||
import android.telephony.ims.stub.ImsUtImplBase;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.ims.internal.IImsCallSession;
|
||||
import com.android.ims.internal.IImsEcbm;
|
||||
@@ -154,17 +153,13 @@ public class MmTelFeature extends ImsFeature {
|
||||
@Override
|
||||
public void changeCapabilitiesConfiguration(CapabilityChangeRequest request,
|
||||
IImsCapabilityCallback c) {
|
||||
synchronized (mLock) {
|
||||
MmTelFeature.this.requestChangeEnabledCapabilities(request, c);
|
||||
}
|
||||
MmTelFeature.this.requestChangeEnabledCapabilities(request, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryCapabilityConfiguration(int capability, int radioTech,
|
||||
IImsCapabilityCallback c) {
|
||||
synchronized (mLock) {
|
||||
queryCapabilityConfigurationInternal(capability, radioTech, c);
|
||||
}
|
||||
queryCapabilityConfigurationInternal(capability, radioTech, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -381,18 +376,6 @@ public class MmTelFeature extends ImsFeature {
|
||||
}
|
||||
}
|
||||
|
||||
private void queryCapabilityConfigurationInternal(int capability, int radioTech,
|
||||
IImsCapabilityCallback c) {
|
||||
boolean enabled = queryCapabilityConfiguration(capability, radioTech);
|
||||
try {
|
||||
if (c != null) {
|
||||
c.onQueryCapabilityConfiguration(capability, radioTech, enabled);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(LOG_TAG, "queryCapabilityConfigurationInternal called on dead binder!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The current capability status that this MmTelFeature has defined is available. This
|
||||
* configuration will be used by the platform to figure out which capabilities are CURRENTLY
|
||||
@@ -512,6 +495,7 @@ public class MmTelFeature extends ImsFeature {
|
||||
* @param capability The capability that we are querying the configuration for.
|
||||
* @return true if the capability is enabled, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean queryCapabilityConfiguration(@MmTelCapabilities.MmTelCapability int capability,
|
||||
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
|
||||
// Base implementation - Override to provide functionality
|
||||
|
||||
@@ -16,14 +16,32 @@
|
||||
|
||||
package android.telephony.ims.feature;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.ims.RcsContactUceCapability;
|
||||
import android.telephony.ims.aidl.IImsCapabilityCallback;
|
||||
import android.telephony.ims.aidl.IImsRcsFeature;
|
||||
import android.telephony.ims.aidl.IRcsFeatureListener;
|
||||
import android.telephony.ims.stub.ImsRegistrationImplBase;
|
||||
import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
|
||||
import android.telephony.ims.stub.RcsSipOptionsImplBase;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.FunctionalUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend
|
||||
@@ -33,10 +51,132 @@ import java.lang.annotation.RetentionPolicy;
|
||||
@SystemApi
|
||||
public class RcsFeature extends ImsFeature {
|
||||
|
||||
/**{@inheritDoc}*/
|
||||
private final IImsRcsFeature mImsRcsBinder = new IImsRcsFeature.Stub() {
|
||||
// Empty Default Implementation.
|
||||
};
|
||||
private static final String LOG_TAG = "RcsFeature";
|
||||
|
||||
private static final class RcsFeatureBinder extends IImsRcsFeature.Stub {
|
||||
// Reference the outer class in order to have better test coverage metrics instead of
|
||||
// creating a inner class referencing the outer class directly.
|
||||
private final RcsFeature mReference;
|
||||
private final Executor mExecutor;
|
||||
|
||||
RcsFeatureBinder(RcsFeature classRef, @CallbackExecutor Executor executor) {
|
||||
mReference = classRef;
|
||||
mExecutor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListener(IRcsFeatureListener listener) {
|
||||
mReference.setListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int queryCapabilityStatus() throws RemoteException {
|
||||
return executeMethodAsyncForResult(
|
||||
() -> mReference.queryCapabilityStatus().mCapabilities,
|
||||
"queryCapabilityStatus");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCapabilityCallback(IImsCapabilityCallback c) throws RemoteException {
|
||||
executeMethodAsync(() -> mReference.addCapabilityCallback(c), "addCapabilityCallback");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCapabilityCallback(IImsCapabilityCallback c) throws RemoteException {
|
||||
executeMethodAsync(() -> mReference.removeCapabilityCallback(c),
|
||||
"removeCapabilityCallback");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeCapabilitiesConfiguration(CapabilityChangeRequest r,
|
||||
IImsCapabilityCallback c) throws RemoteException {
|
||||
executeMethodAsync(() -> mReference.requestChangeEnabledCapabilities(r, c),
|
||||
"changeCapabilitiesConfiguration");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queryCapabilityConfiguration(int capability, int radioTech,
|
||||
IImsCapabilityCallback c) throws RemoteException {
|
||||
executeMethodAsync(() -> mReference.queryCapabilityConfigurationInternal(capability,
|
||||
radioTech, c), "queryCapabilityConfiguration");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFeatureState() throws RemoteException {
|
||||
return executeMethodAsyncForResult(mReference::getFeatureState, "getFeatureState");
|
||||
}
|
||||
|
||||
// RcsPresenceExchangeImplBase specific APIS
|
||||
@Override
|
||||
public void requestCapabilities(List<Uri> uris, int operationToken) throws RemoteException {
|
||||
executeMethodAsync(() -> mReference.getPresenceExchangeInternal()
|
||||
.requestCapabilities(uris, operationToken), "requestCapabilities");
|
||||
}
|
||||
@Override
|
||||
public void updateCapabilities(RcsContactUceCapability capabilities, int operationToken)
|
||||
throws RemoteException {
|
||||
executeMethodAsync(() -> mReference.getPresenceExchangeInternal()
|
||||
.updateCapabilities(capabilities, operationToken),
|
||||
"updateCapabilities");
|
||||
|
||||
}
|
||||
// RcsSipOptionsImplBase specific APIS
|
||||
@Override
|
||||
public void sendCapabilityRequest(Uri contactUri, RcsContactUceCapability capabilities,
|
||||
int operationToken) throws RemoteException {
|
||||
executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
|
||||
.sendCapabilityRequest(contactUri, capabilities, operationToken),
|
||||
"sendCapabilityRequest");
|
||||
|
||||
}
|
||||
@Override
|
||||
public void respondToCapabilityRequest(String contactUri,
|
||||
RcsContactUceCapability ownCapabilities, int operationToken)
|
||||
throws RemoteException {
|
||||
executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
|
||||
.respondToCapabilityRequest(contactUri, ownCapabilities,
|
||||
operationToken), "respondToCapabilityRequest");
|
||||
|
||||
}
|
||||
@Override
|
||||
public void respondToCapabilityRequestWithError(Uri contactUri, int code, String reason,
|
||||
int operationToken) throws RemoteException {
|
||||
executeMethodAsync(() -> mReference.getOptionsExchangeInternal()
|
||||
.respondToCapabilityRequestWithError(contactUri, code, reason,
|
||||
operationToken), "respondToCapabilityRequestWithError");
|
||||
}
|
||||
|
||||
// Call the methods with a clean calling identity on the executor and wait indefinitely for
|
||||
// the future to return.
|
||||
private void executeMethodAsync(FunctionalUtils.ThrowingRunnable r, String errorLogName)
|
||||
throws RemoteException {
|
||||
// call with a clean calling identity on the executor and wait indefinitely for the
|
||||
// future to return.
|
||||
try {
|
||||
CompletableFuture.runAsync(
|
||||
() -> Binder.withCleanCallingIdentity(r), mExecutor).join();
|
||||
} catch (CancellationException | CompletionException e) {
|
||||
Log.w(LOG_TAG, "RcsFeatureBinder - " + errorLogName + " exception: "
|
||||
+ e.getMessage());
|
||||
throw new RemoteException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T executeMethodAsyncForResult(FunctionalUtils.ThrowingSupplier<T> r,
|
||||
String errorLogName) throws RemoteException {
|
||||
// call with a clean calling identity on the executor and wait indefinitely for the
|
||||
// future to return.
|
||||
CompletableFuture<T> future = CompletableFuture.supplyAsync(
|
||||
() -> Binder.withCleanCallingIdentity(r), mExecutor);
|
||||
try {
|
||||
return future.get();
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
Log.w(LOG_TAG, "RcsFeatureBinder - " + errorLogName + " exception: "
|
||||
+ e.getMessage());
|
||||
throw new RemoteException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains the capabilities defined and supported by a {@link RcsFeature} in the
|
||||
@@ -81,27 +221,66 @@ public class RcsFeature extends ImsFeature {
|
||||
|
||||
/**@hide*/
|
||||
public RcsImsCapabilities(@RcsImsCapabilityFlag int capabilities) {
|
||||
super(capabilities);
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
private RcsImsCapabilities(Capabilities c) {
|
||||
super(c.getMask());
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
@Override
|
||||
public void addCapabilities(@RcsImsCapabilityFlag int capabilities) {
|
||||
|
||||
super.addCapabilities(capabilities);
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
@Override
|
||||
public void removeCapabilities(@RcsImsCapabilityFlag int capabilities) {
|
||||
|
||||
super.removeCapabilities(capabilities);
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
@Override
|
||||
public boolean isCapable(@RcsImsCapabilityFlag int capabilities) {
|
||||
return false;
|
||||
return super.isCapable(capabilities);
|
||||
}
|
||||
}
|
||||
|
||||
private final RcsFeatureBinder mImsRcsBinder;
|
||||
private IRcsFeatureListener mListenerBinder;
|
||||
private RcsPresenceExchangeImplBase mPresExchange;
|
||||
private RcsSipOptionsImplBase mSipOptions;
|
||||
|
||||
/**
|
||||
* Create a new RcsFeature.
|
||||
* <p>
|
||||
* Method stubs called from the framework will be called asynchronously. To specify the
|
||||
* {@link Executor} that the methods stubs will be called, use
|
||||
* {@link RcsFeature#RcsFeature(Executor)} instead.
|
||||
*/
|
||||
public RcsFeature() {
|
||||
super();
|
||||
// Run on the Binder threads that call them.
|
||||
mImsRcsBinder = new RcsFeatureBinder(this, Runnable::run);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new RcsFeature using the Executor specified for methods being called by the
|
||||
* framework.
|
||||
* @param executor The executor for the framework to use when making calls to this service.
|
||||
* @hide
|
||||
*/
|
||||
public RcsFeature(@NonNull Executor executor) {
|
||||
super();
|
||||
if (executor == null) {
|
||||
throw new IllegalArgumentException("executor can not be null.");
|
||||
}
|
||||
// Run on the Binder thread by default.
|
||||
mImsRcsBinder = new RcsFeatureBinder(this, executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the current {@link RcsImsCapabilities} status set by the RcsFeature. If a capability is
|
||||
* set, the {@link RcsFeature} has brought up the capability and is ready for framework
|
||||
@@ -111,7 +290,7 @@ public class RcsFeature extends ImsFeature {
|
||||
*/
|
||||
@Override
|
||||
public final RcsImsCapabilities queryCapabilityStatus() {
|
||||
throw new UnsupportedOperationException();
|
||||
return new RcsImsCapabilities(super.queryCapabilityStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,8 +299,11 @@ public class RcsFeature extends ImsFeature {
|
||||
* Call {@link #queryCapabilityStatus()} to return the current capability status.
|
||||
* @hide
|
||||
*/
|
||||
public final void notifyCapabilitiesStatusChanged(RcsImsCapabilities c) {
|
||||
throw new UnsupportedOperationException();
|
||||
public final void notifyCapabilitiesStatusChanged(@NonNull RcsImsCapabilities c) {
|
||||
if (c == null) {
|
||||
throw new IllegalArgumentException("RcsImsCapabilities must be non-null!");
|
||||
}
|
||||
super.notifyCapabilitiesStatusChanged(c);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,8 +315,10 @@ public class RcsFeature extends ImsFeature {
|
||||
* @hide
|
||||
*/
|
||||
public boolean queryCapabilityConfiguration(
|
||||
@RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
|
||||
throw new UnsupportedOperationException();
|
||||
@RcsImsCapabilities.RcsImsCapabilityFlag int capability,
|
||||
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
|
||||
// Base Implementation - Override to provide functionality
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Called from the framework when the {@link RcsImsCapabilities} that have been configured for
|
||||
@@ -155,7 +339,7 @@ public class RcsFeature extends ImsFeature {
|
||||
@Override
|
||||
public void changeEnabledCapabilities(CapabilityChangeRequest request,
|
||||
CapabilityCallbackProxy c) {
|
||||
throw new UnsupportedOperationException();
|
||||
// Base Implementation - Override to provide functionality
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,13 +376,6 @@ public class RcsFeature extends ImsFeature {
|
||||
return new RcsPresenceExchangeImplBase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link RcsFeature} instance.
|
||||
*/
|
||||
public RcsFeature() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**{@inheritDoc}*/
|
||||
@Override
|
||||
public void onFeatureRemoved() {
|
||||
@@ -218,4 +395,40 @@ public class RcsFeature extends ImsFeature {
|
||||
public final IImsRcsFeature getBinder() {
|
||||
return mImsRcsBinder;
|
||||
}
|
||||
|
||||
/**@hide*/
|
||||
public IRcsFeatureListener getListener() {
|
||||
synchronized (mLock) {
|
||||
return mListenerBinder;
|
||||
}
|
||||
}
|
||||
|
||||
private void setListener(IRcsFeatureListener listener) {
|
||||
synchronized (mLock) {
|
||||
mListenerBinder = listener;
|
||||
if (mListenerBinder != null) {
|
||||
onFeatureReady();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RcsPresenceExchangeImplBase getPresenceExchangeInternal() {
|
||||
synchronized (mLock) {
|
||||
if (mPresExchange == null) {
|
||||
mPresExchange = getPresenceExchangeImpl();
|
||||
mPresExchange.initialize(this);
|
||||
}
|
||||
return mPresExchange;
|
||||
}
|
||||
}
|
||||
|
||||
private RcsSipOptionsImplBase getOptionsExchangeInternal() {
|
||||
synchronized (mLock) {
|
||||
if (mSipOptions == null) {
|
||||
mSipOptions = getOptionsExchangeImpl();
|
||||
mSipOptions.initialize(this);
|
||||
}
|
||||
return mSipOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
package android.telephony.ims.stub;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.ims.ImsException;
|
||||
import android.telephony.ims.aidl.IRcsFeatureListener;
|
||||
import android.telephony.ims.feature.ImsFeature;
|
||||
import android.telephony.ims.feature.RcsFeature;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -72,6 +77,24 @@ public class RcsCapabilityExchange {
|
||||
})
|
||||
public @interface CommandCode {}
|
||||
|
||||
|
||||
private RcsFeature mFeature;
|
||||
|
||||
/** @hide */
|
||||
public final void initialize(RcsFeature feature) {
|
||||
mFeature = feature;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
protected final IRcsFeatureListener getListener() throws ImsException {
|
||||
IRcsFeatureListener listener = mFeature.getListener();
|
||||
if (listener == null) {
|
||||
throw new ImsException("Connection to Framework has not been established, wait for "
|
||||
+ "onFeatureReady().", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
return mFeature.getListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the framework with an update as to whether or not a command completed successfully
|
||||
* locally. This includes capabilities requests and updates from the network. If it does not
|
||||
@@ -82,8 +105,18 @@ public class RcsCapabilityExchange {
|
||||
* @param code The result of the pending command. If {@link #COMMAND_CODE_SUCCESS}, further
|
||||
* updates will be sent for this command using the associated operationToken.
|
||||
* @param operationToken the token associated with the pending command.
|
||||
* @throws ImsException If this {@link RcsCapabilityExchange} instance is not currently
|
||||
* connected to the framework. This can happen if the {@link RcsFeature} is not
|
||||
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
|
||||
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
|
||||
* Telephony stack has crashed.
|
||||
*/
|
||||
public final void onCommandUpdate(@CommandCode int code, int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
public final void onCommandUpdate(@CommandCode int code, int operationToken)
|
||||
throws ImsException {
|
||||
try {
|
||||
getListener().onCommandUpdate(code, operationToken);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,11 @@ package android.telephony.ims.stub;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.ims.ImsException;
|
||||
import android.telephony.ims.RcsContactUceCapability;
|
||||
import android.telephony.ims.feature.ImsFeature;
|
||||
import android.telephony.ims.feature.RcsFeature;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -113,54 +117,95 @@ public class RcsPresenceExchangeImplBase extends RcsCapabilityExchange {
|
||||
* Provide the framework with a subsequent network response update to
|
||||
* {@link #updateCapabilities(RcsContactUceCapability, int)} and
|
||||
* {@link #requestCapabilities(List, int)} operations.
|
||||
*
|
||||
* @param code The SIP response code sent from the network for the operation token specified.
|
||||
* @param reason The optional reason response from the network. If the network provided no
|
||||
* reason with the code, the string should be empty.
|
||||
* @param operationToken The token associated with the operation this service is providing a
|
||||
* response for.
|
||||
* @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
|
||||
* connected to the framework. This can happen if the {@link RcsFeature} is not
|
||||
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
|
||||
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
|
||||
* Telephony stack has crashed.
|
||||
*/
|
||||
public final void onNetworkResponse(@PresenceResponseCode int code, @NonNull String reason,
|
||||
int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
int operationToken) throws ImsException {
|
||||
try {
|
||||
getListener().onNetworkResponse(code, reason, operationToken);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the framework with the requested contacts’ capabilities requested by the framework
|
||||
* using {@link #requestCapabilities(List, int)} .
|
||||
* using {@link #requestCapabilities(List, int)}.
|
||||
*
|
||||
* @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
|
||||
* connected to the framework. This can happen if the {@link RcsFeature} is not
|
||||
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
|
||||
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
|
||||
* Telephony stack has crashed.
|
||||
*/
|
||||
public final void onCapabilityRequestResponse(@NonNull List<RcsContactUceCapability> infos,
|
||||
int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
int operationToken) throws ImsException {
|
||||
try {
|
||||
getListener().onCapabilityRequestResponsePresence(infos, operationToken);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the framework to provide a capability update using
|
||||
* {@link #updateCapabilities(RcsContactUceCapability, int)}. This is typically used when trying
|
||||
* to generate an initial PUBLISH for a new subscription to the network.
|
||||
* {@link #updateCapabilities(RcsContactUceCapability, int)}.
|
||||
* <p>
|
||||
* The device will cache all presence publications after boot until this method is called once.
|
||||
* This is typically used when trying to generate an initial PUBLISH for a new subscription to
|
||||
* the network. The device will cache all presence publications after boot until this method is
|
||||
* called once.
|
||||
* @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
|
||||
* connected to the framework. This can happen if the {@link RcsFeature} is not
|
||||
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
|
||||
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
|
||||
* Telephony stack has crashed.
|
||||
*/
|
||||
public final void onNotifyUpdateCapabilites() {
|
||||
throw new UnsupportedOperationException();
|
||||
public final void onNotifyUpdateCapabilites() throws ImsException {
|
||||
try {
|
||||
getListener().onNotifyUpdateCapabilities();
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the framework that the device’s capabilities have been unpublished from the network.
|
||||
*
|
||||
* @throws ImsException If this {@link RcsPresenceExchangeImplBase} instance is not currently
|
||||
* connected to the framework. This can happen if the {@link RcsFeature} is not
|
||||
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
|
||||
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
|
||||
* Telephony stack has crashed.
|
||||
*/
|
||||
public final void onUnpublish() {
|
||||
throw new UnsupportedOperationException();
|
||||
public final void onUnpublish() throws ImsException {
|
||||
try {
|
||||
getListener().onUnpublish();
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The user capabilities of one or multiple contacts have been requested.
|
||||
* The user capabilities of one or multiple contacts have been requested by the framework.
|
||||
* <p>
|
||||
* This must be followed up with one call to {@link #onCommandUpdate(int, int)} with an update
|
||||
* as to whether or not the command completed as well as subsequent network
|
||||
* updates using {@link #onNetworkResponse(int, String, int)}. When the operation is completed,
|
||||
* {@link #onCapabilityRequestResponse(List, int)} should be called with
|
||||
* the presence information for the contacts specified.
|
||||
* @param uris A {@link List} of the URIs that the framework is requesting the UCE capabilities
|
||||
* for.
|
||||
* The implementer must follow up this call with an {@link #onCommandUpdate(int, int)} call to
|
||||
* indicate whether or not this operation succeeded. If this operation succeeds, network
|
||||
* response updates should be sent to the framework using
|
||||
* {@link #onNetworkResponse(int, String, int)}. When the operation is completed,
|
||||
* {@link #onCapabilityRequestResponse(List, int)} should be called with the presence
|
||||
* information for the contacts specified.
|
||||
* @param uris A {@link List} of the {@link Uri}s that the framework is requesting the UCE
|
||||
* capabilities for.
|
||||
* @param operationToken The token associated with this operation. Updates to this request using
|
||||
* {@link #onCommandUpdate(int, int)}, {@link #onNetworkResponse(int, String, int)}, and
|
||||
* {@link #onCapabilityRequestResponse(List, int)} must use the same operation token
|
||||
@@ -169,14 +214,20 @@ public class RcsPresenceExchangeImplBase extends RcsCapabilityExchange {
|
||||
public void requestCapabilities(@NonNull List<Uri> uris, int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "requestCapabilities called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
try {
|
||||
getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
|
||||
} catch (RemoteException | ImsException e) {
|
||||
// Do not do anything, this is a stub implementation.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The capabilities of this device have been updated and should be published
|
||||
* to the network. The framework will expect one {@link #onCommandUpdate(int, int)} call to
|
||||
* indicate whether or not this operation failed first as well as network response
|
||||
* updates to this update using {@link #onNetworkResponse(int, String, int)}.
|
||||
* The capabilities of this device have been updated and should be published to the network.
|
||||
* <p>
|
||||
* The implementer must follow up this call with an {@link #onCommandUpdate(int, int)} call to
|
||||
* indicate whether or not this operation succeeded. If this operation succeeds, network
|
||||
* response updates should be sent to the framework using
|
||||
* {@link #onNetworkResponse(int, String, int)}.
|
||||
* @param capabilities The capabilities for this device.
|
||||
* @param operationToken The token associated with this operation. Any subsequent
|
||||
* {@link #onCommandUpdate(int, int)} or {@link #onNetworkResponse(int, String, int)}
|
||||
@@ -186,6 +237,10 @@ public class RcsPresenceExchangeImplBase extends RcsCapabilityExchange {
|
||||
int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "updateCapabilities called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
try {
|
||||
getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
|
||||
} catch (RemoteException | ImsException e) {
|
||||
// Do not do anything, this is a stub implementation.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,11 @@ import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.ims.ImsException;
|
||||
import android.telephony.ims.RcsContactUceCapability;
|
||||
import android.telephony.ims.feature.ImsFeature;
|
||||
import android.telephony.ims.feature.RcsFeature;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -87,10 +91,19 @@ public class RcsSipOptionsImplBase extends RcsCapabilityExchange {
|
||||
* @param info the contact's UCE capabilities associated with the capability request.
|
||||
* @param operationToken The token associated with the original capability request, set by
|
||||
* {@link #sendCapabilityRequest(Uri, RcsContactUceCapability, int)}.
|
||||
* @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not currently
|
||||
* connected to the framework. This can happen if the {@link RcsFeature} is not
|
||||
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
|
||||
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
|
||||
* Telephony stack has crashed.
|
||||
*/
|
||||
public final void onCapabilityRequestResponse(@SipResponseCode int code, @NonNull String reason,
|
||||
@Nullable RcsContactUceCapability info, int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
@Nullable RcsContactUceCapability info, int operationToken) throws ImsException {
|
||||
try {
|
||||
getListener().onCapabilityRequestResponseOptions(code, reason, info, operationToken);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,10 +117,19 @@ public class RcsSipOptionsImplBase extends RcsCapabilityExchange {
|
||||
* @param operationToken An unique operation token that you have generated that will be returned
|
||||
* by the framework in
|
||||
* {@link #respondToCapabilityRequest(String, RcsContactUceCapability, int)}.
|
||||
* @throws ImsException If this {@link RcsSipOptionsImplBase} instance is not currently
|
||||
* connected to the framework. This can happen if the {@link RcsFeature} is not
|
||||
* {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received the
|
||||
* {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare cases when the
|
||||
* Telephony stack has crashed.
|
||||
*/
|
||||
public final void onRemoteCapabilityRequest(@NonNull Uri contactUri,
|
||||
@NonNull RcsContactUceCapability remoteInfo, int operationToken) {
|
||||
throw new UnsupportedOperationException();
|
||||
@NonNull RcsContactUceCapability remoteInfo, int operationToken) throws ImsException {
|
||||
try {
|
||||
getListener().onRemoteCapabilityRequest(contactUri, remoteInfo, operationToken);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,7 +149,11 @@ public class RcsSipOptionsImplBase extends RcsCapabilityExchange {
|
||||
@NonNull RcsContactUceCapability capabilities, int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "sendCapabilityRequest called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
try {
|
||||
getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
|
||||
} catch (RemoteException | ImsException e) {
|
||||
// Do not do anything, this is a stub implementation.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,7 +171,11 @@ public class RcsSipOptionsImplBase extends RcsCapabilityExchange {
|
||||
@NonNull RcsContactUceCapability ownCapabilities, int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "respondToCapabilityRequest called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
try {
|
||||
getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
|
||||
} catch (RemoteException | ImsException e) {
|
||||
// Do not do anything, this is a stub implementation.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,6 +194,10 @@ public class RcsSipOptionsImplBase extends RcsCapabilityExchange {
|
||||
@SipResponseCode int code, @NonNull String reason, int operationToken) {
|
||||
// Stub - to be implemented by service
|
||||
Log.w(LOG_TAG, "respondToCapabiltyRequestWithError called with no implementation.");
|
||||
onCommandUpdate(COMMAND_CODE_GENERIC_FAILURE, operationToken);
|
||||
try {
|
||||
getListener().onCommandUpdate(COMMAND_CODE_NOT_SUPPORTED, operationToken);
|
||||
} catch (RemoteException | ImsException e) {
|
||||
// Do not do anything, this is a stub implementation.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user