Add AIDL connections for SipDelegateManager am: bf9c710733 am: 20734105de
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1462844 Change-Id: Ib01d1b59e6b73ae3c93e0c7dbe6c8cab421f2957
This commit is contained in:
@@ -22,7 +22,12 @@ import android.annotation.SuppressLint;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.content.Context;
|
||||
import android.telephony.BinderCacheManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyFrameworkInitializer;
|
||||
import android.telephony.ims.aidl.IImsRcsController;
|
||||
|
||||
import com.android.internal.telephony.ITelephony;
|
||||
|
||||
/**
|
||||
* Provides access to information about Telephony IMS services on the device.
|
||||
@@ -30,8 +35,6 @@ import android.telephony.SubscriptionManager;
|
||||
@SystemService(Context.TELEPHONY_IMS_SERVICE)
|
||||
public class ImsManager {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* <p>Broadcast Action: Indicates that a previously allowed IMS operation was rejected by the
|
||||
* network due to the network returning a "forbidden" response. This may be due to a
|
||||
@@ -87,6 +90,14 @@ public class ImsManager {
|
||||
public static final String EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE =
|
||||
"android.telephony.ims.extra.WFC_REGISTRATION_FAILURE_MESSAGE";
|
||||
|
||||
// Cache Telephony Binder interfaces, one cache per process.
|
||||
private static final BinderCacheManager<ITelephony> sTelephonyCache =
|
||||
new BinderCacheManager<>(ImsManager::getITelephonyInterface);
|
||||
private static final BinderCacheManager<IImsRcsController> sRcsCache =
|
||||
new BinderCacheManager<>(ImsManager::getIImsRcsControllerInterface);
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
/**
|
||||
* Use {@link Context#getSystemService(String)} to get an instance of this class.
|
||||
* @hide
|
||||
@@ -108,7 +119,7 @@ public class ImsManager {
|
||||
throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
|
||||
}
|
||||
|
||||
return new ImsRcsManager(mContext, subscriptionId);
|
||||
return new ImsRcsManager(mContext, subscriptionId, sRcsCache);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,7 +135,7 @@ public class ImsManager {
|
||||
throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
|
||||
}
|
||||
|
||||
return new ImsMmTelManager(subscriptionId);
|
||||
return new ImsMmTelManager(subscriptionId, sTelephonyCache);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,6 +157,22 @@ public class ImsManager {
|
||||
throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
|
||||
}
|
||||
|
||||
return new SipDelegateManager(mContext, subscriptionId);
|
||||
return new SipDelegateManager(mContext, subscriptionId, sRcsCache);
|
||||
}
|
||||
|
||||
private static IImsRcsController getIImsRcsControllerInterface() {
|
||||
return IImsRcsController.Stub.asInterface(
|
||||
TelephonyFrameworkInitializer
|
||||
.getTelephonyServiceManager()
|
||||
.getTelephonyImsServiceRegisterer()
|
||||
.get());
|
||||
}
|
||||
|
||||
private static ITelephony getITelephonyInterface() {
|
||||
return ITelephony.Stub.asInterface(
|
||||
TelephonyFrameworkInitializer
|
||||
.getTelephonyServiceManager()
|
||||
.getTelephonyServiceRegisterer()
|
||||
.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 android.telephony.ims;
|
||||
|
||||
parcelable DelegateRegistrationState;
|
||||
19
telephony/java/android/telephony/ims/DelegateRequest.aidl
Normal file
19
telephony/java/android/telephony/ims/DelegateRequest.aidl
Normal file
@@ -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 android.telephony.ims;
|
||||
|
||||
parcelable DelegateRequest;
|
||||
19
telephony/java/android/telephony/ims/FeatureTagState.aidl
Normal file
19
telephony/java/android/telephony/ims/FeatureTagState.aidl
Normal file
@@ -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 android.telephony.ims;
|
||||
|
||||
parcelable FeatureTagState;
|
||||
@@ -29,6 +29,7 @@ import android.os.Binder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.telephony.AccessNetworkConstants;
|
||||
import android.telephony.BinderCacheManager;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyFrameworkInitializer;
|
||||
@@ -213,6 +214,7 @@ public class ImsMmTelManager implements RegistrationManager {
|
||||
}
|
||||
|
||||
private final int mSubId;
|
||||
private final BinderCacheManager<ITelephony> mBinderCache;
|
||||
|
||||
/**
|
||||
* Create an instance of {@link ImsMmTelManager} for the subscription id specified.
|
||||
@@ -242,7 +244,8 @@ public class ImsMmTelManager implements RegistrationManager {
|
||||
throw new IllegalArgumentException("Invalid subscription ID");
|
||||
}
|
||||
|
||||
return new ImsMmTelManager(subId);
|
||||
return new ImsMmTelManager(subId, new BinderCacheManager<>(
|
||||
ImsMmTelManager::getITelephonyInterface));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,8 +253,9 @@ public class ImsMmTelManager implements RegistrationManager {
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public ImsMmTelManager(int subId) {
|
||||
public ImsMmTelManager(int subId, BinderCacheManager<ITelephony> binderCache) {
|
||||
mSubId = subId;
|
||||
mBinderCache = binderCache;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1367,7 +1371,11 @@ public class ImsMmTelManager implements RegistrationManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static ITelephony getITelephony() {
|
||||
private ITelephony getITelephony() {
|
||||
return mBinderCache.getBinder();
|
||||
}
|
||||
|
||||
private static ITelephony getITelephonyInterface() {
|
||||
ITelephony binder = ITelephony.Stub.asInterface(
|
||||
TelephonyFrameworkInitializer
|
||||
.getTelephonyServiceManager()
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.AccessNetworkConstants;
|
||||
import android.telephony.BinderCacheManager;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.TelephonyFrameworkInitializer;
|
||||
import android.telephony.ims.aidl.IImsCapabilityCallback;
|
||||
@@ -149,14 +150,17 @@ public class ImsRcsManager {
|
||||
|
||||
private final int mSubId;
|
||||
private final Context mContext;
|
||||
private final BinderCacheManager<IImsRcsController> mBinderCache;
|
||||
|
||||
/**
|
||||
* Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this class.
|
||||
* @hide
|
||||
*/
|
||||
public ImsRcsManager(Context context, int subId) {
|
||||
public ImsRcsManager(Context context, int subId,
|
||||
BinderCacheManager<IImsRcsController> binderCache) {
|
||||
mSubId = subId;
|
||||
mContext = context;
|
||||
mBinderCache = binderCache;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 android.telephony.ims;
|
||||
|
||||
parcelable SipDelegateImsConfiguration;
|
||||
@@ -22,12 +22,12 @@ import android.annotation.NonNull;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceSpecificException;
|
||||
import android.telephony.BinderCacheManager;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.TelephonyFrameworkInitializer;
|
||||
import android.telephony.ims.aidl.IImsRcsController;
|
||||
import android.telephony.ims.aidl.SipDelegateConnectionAidlWrapper;
|
||||
import android.telephony.ims.stub.DelegateConnectionMessageCallback;
|
||||
import android.telephony.ims.stub.DelegateConnectionStateCallback;
|
||||
import android.telephony.ims.stub.SipDelegate;
|
||||
@@ -261,6 +261,7 @@ public class SipDelegateManager {
|
||||
|
||||
private final Context mContext;
|
||||
private final int mSubId;
|
||||
private final BinderCacheManager<IImsRcsController> mBinderCache;
|
||||
|
||||
/**
|
||||
* Only visible for testing. To instantiate an instance of this class, please use
|
||||
@@ -268,9 +269,11 @@ public class SipDelegateManager {
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public SipDelegateManager(Context context, int subId) {
|
||||
public SipDelegateManager(Context context, int subId,
|
||||
BinderCacheManager<IImsRcsController> binderCache) {
|
||||
mContext = context;
|
||||
mSubId = subId;
|
||||
mBinderCache = binderCache;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -290,7 +293,7 @@ public class SipDelegateManager {
|
||||
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
|
||||
public boolean isSupported() throws ImsException {
|
||||
try {
|
||||
IImsRcsController controller = getIImsRcsController();
|
||||
IImsRcsController controller = mBinderCache.getBinder();
|
||||
if (controller == null) {
|
||||
throw new ImsException("Telephony server is down",
|
||||
ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
@@ -315,7 +318,7 @@ public class SipDelegateManager {
|
||||
* a persistent binding to when the app is the default SMS application.
|
||||
* @param request The parameters that are associated with the SipDelegate creation request that
|
||||
* will be used to create the SipDelegate connection.
|
||||
* @param e The executor that will be used to call the callbacks associated with this
|
||||
* @param executor The executor that will be used to call the callbacks associated with this
|
||||
* SipDelegate.
|
||||
* @param dc The callback that will be used to notify the listener of the creation/destruction
|
||||
* of the remote SipDelegate as well as changes to the state of the remote SipDelegate
|
||||
@@ -327,18 +330,34 @@ public class SipDelegateManager {
|
||||
* associated with this SipDelegateManager. See {@link ImsException#getCode()}.
|
||||
* @hide
|
||||
*/
|
||||
public void createSipDelegate(@NonNull DelegateRequest request, @NonNull Executor e,
|
||||
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
|
||||
public void createSipDelegate(@NonNull DelegateRequest request, @NonNull Executor executor,
|
||||
@NonNull DelegateConnectionStateCallback dc,
|
||||
@NonNull DelegateConnectionMessageCallback mc) throws ImsException {
|
||||
if (request == null || e == null || dc == null || mc == null) {
|
||||
if (request == null || executor == null || dc == null || mc == null) {
|
||||
throw new IllegalArgumentException("Invalid arguments passed into createSipDelegate");
|
||||
}
|
||||
throw new ImsException("creating a SipDelegate is not supported" ,
|
||||
ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
|
||||
try {
|
||||
SipDelegateConnectionAidlWrapper wrapper =
|
||||
new SipDelegateConnectionAidlWrapper(executor, dc, mc);
|
||||
IImsRcsController controller = mBinderCache.listenOnBinder(wrapper,
|
||||
wrapper::binderDied);
|
||||
if (controller == null) {
|
||||
throw new ImsException("Telephony server is down",
|
||||
ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
controller.createSipDelegate(mSubId, request, wrapper.getStateCallbackBinder(),
|
||||
wrapper.getMessageCallbackBinder());
|
||||
} catch (ServiceSpecificException e) {
|
||||
throw new ImsException(e.getMessage(), e.errorCode);
|
||||
} catch (RemoteException e) {
|
||||
throw new ImsException(e.getMessage(),
|
||||
ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a previously created SipDelegateConnection that was created using
|
||||
* Destroy a previously created {@link SipDelegateConnection} that was created using
|
||||
* {@link #createSipDelegate}.
|
||||
* <p>
|
||||
* This will also clean up all related callbacks in the associated ImsService.
|
||||
@@ -346,20 +365,32 @@ public class SipDelegateManager {
|
||||
* @param reason The reason for why this SipDelegateConnection was destroyed.
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
|
||||
public void destroySipDelegate(@NonNull SipDelegateConnection delegateConnection,
|
||||
@SipDelegateDestroyReason int reason) {
|
||||
|
||||
if (delegateConnection == null) {
|
||||
throw new IllegalArgumentException("invalid argument passed into destroySipDelegate");
|
||||
}
|
||||
// not supported yet.
|
||||
}
|
||||
|
||||
private IImsRcsController getIImsRcsController() {
|
||||
IBinder binder = TelephonyFrameworkInitializer
|
||||
.getTelephonyServiceManager()
|
||||
.getTelephonyImsServiceRegisterer()
|
||||
.get();
|
||||
return IImsRcsController.Stub.asInterface(binder);
|
||||
if (delegateConnection instanceof SipDelegateConnectionAidlWrapper) {
|
||||
SipDelegateConnectionAidlWrapper w =
|
||||
(SipDelegateConnectionAidlWrapper) delegateConnection;
|
||||
try {
|
||||
IImsRcsController c = mBinderCache.removeRunnable(w);
|
||||
c.destroySipDelegate(mSubId, w.getSipDelegateBinder(), reason);
|
||||
} catch (RemoteException e) {
|
||||
// Connection to telephony died, but this will signal destruction of SipDelegate
|
||||
// eventually anyway, so return normally.
|
||||
try {
|
||||
w.getStateCallbackBinder().onDestroyed(
|
||||
SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
|
||||
} catch (RemoteException ignore) {
|
||||
// Local to process.
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown SipDelegateConnection implementation passed"
|
||||
+ " into this method");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
telephony/java/android/telephony/ims/SipMessage.aidl
Normal file
19
telephony/java/android/telephony/ims/SipMessage.aidl
Normal file
@@ -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 android.telephony.ims;
|
||||
|
||||
parcelable SipMessage;
|
||||
@@ -17,10 +17,15 @@
|
||||
package android.telephony.ims.aidl;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.telephony.ims.DelegateRequest;
|
||||
import android.telephony.ims.aidl.IImsCapabilityCallback;
|
||||
import android.telephony.ims.aidl.IImsRegistrationCallback;
|
||||
import android.telephony.ims.aidl.IRcsUceControllerCallback;
|
||||
import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
|
||||
import android.telephony.ims.aidl.IImsRegistrationCallback;
|
||||
import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
|
||||
import android.telephony.ims.aidl.ISipDelegate;
|
||||
import android.telephony.ims.aidl.ISipDelegateMessageCallback;
|
||||
import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
|
||||
|
||||
import com.android.ims.ImsFeatureContainer;
|
||||
import com.android.ims.internal.IImsServiceFeatureCallback;
|
||||
@@ -58,6 +63,10 @@ interface IImsRcsController {
|
||||
|
||||
// SipDelegateManager
|
||||
boolean isSipDelegateSupported(int subId);
|
||||
void createSipDelegate(int subId, in DelegateRequest request,
|
||||
ISipDelegateConnectionStateCallback delegateState,
|
||||
ISipDelegateMessageCallback delegateMessage);
|
||||
void destroySipDelegate(int subId, ISipDelegate connection, int reason);
|
||||
|
||||
// Internal commands that should not be made public
|
||||
void registerRcsFeatureCallback(int slotId, in IImsServiceFeatureCallback callback);
|
||||
|
||||
32
telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl
Normal file
32
telephony/java/android/telephony/ims/aidl/ISipDelegate.aidl
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 android.telephony.ims.aidl;
|
||||
|
||||
import android.telephony.ims.SipMessage;
|
||||
|
||||
/**
|
||||
* See {@link SipDelegate} and {@link SipDelegateConnection} for docs regarding this callback.
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface ISipDelegate {
|
||||
void sendMessage(in SipMessage sipMessage, int configVersion);
|
||||
void notifyMessageReceived(in String viaTransactionId);
|
||||
void notifyMessageReceiveError(in String viaTransactionId, int reason);
|
||||
|
||||
// only used by SipDelegate.
|
||||
void closeDialog(in String callId);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 android.telephony.ims.aidl;
|
||||
|
||||
import android.telephony.ims.DelegateRegistrationState;
|
||||
import android.telephony.ims.FeatureTagState;
|
||||
import android.telephony.ims.SipDelegateImsConfiguration;
|
||||
import android.telephony.ims.aidl.ISipDelegate;
|
||||
|
||||
/**
|
||||
* See {@link SipDelegateConnectionStateCallback} for docs regarding this callback.
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface ISipDelegateConnectionStateCallback {
|
||||
void onCreated(ISipDelegate c);
|
||||
void onFeatureTagStatusChanged(in DelegateRegistrationState registrationState,
|
||||
in List<FeatureTagState> deniedFeatureTags);
|
||||
void onImsConfigurationChanged(in SipDelegateImsConfiguration registeredSipConfig);
|
||||
void onDestroyed(int reason);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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 android.telephony.ims.aidl;
|
||||
|
||||
import android.telephony.ims.SipMessage;
|
||||
|
||||
/**
|
||||
* See {@link DelegateMessageCallback} and {@link DelegateConnectionMessageCallback} for docs
|
||||
* regarding this callback.
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface ISipDelegateMessageCallback {
|
||||
void onMessageReceived(in SipMessage message);
|
||||
void onMessageSent(in String viaTransactionId);
|
||||
void onMessageSendFailure(in String viaTransactionId, int reason);
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* 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 android.telephony.ims.aidl;
|
||||
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.telephony.ims.DelegateRegistrationState;
|
||||
import android.telephony.ims.FeatureTagState;
|
||||
import android.telephony.ims.SipDelegateConnection;
|
||||
import android.telephony.ims.SipDelegateImsConfiguration;
|
||||
import android.telephony.ims.SipDelegateManager;
|
||||
import android.telephony.ims.SipMessage;
|
||||
import android.telephony.ims.stub.DelegateConnectionMessageCallback;
|
||||
import android.telephony.ims.stub.DelegateConnectionStateCallback;
|
||||
import android.telephony.ims.stub.SipDelegate;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Wrapper class implementing {@link SipDelegateConnection} using AIDL, which is returned to the
|
||||
* local process. Also holds a reference to incoming connection message and state AIDL impl to
|
||||
* trampoline events to callbacks as well as notify the local process in the event that the remote
|
||||
* process becomes unavailable.
|
||||
* <p>
|
||||
* When the remote {@link SipDelegate} is created, this instance tracks the
|
||||
* {@link ISipDelegate} associated with it and implements the
|
||||
* {@link SipDelegateConnection} sent back to the local callback.
|
||||
* @hide
|
||||
*/
|
||||
public class SipDelegateConnectionAidlWrapper implements SipDelegateConnection,
|
||||
IBinder.DeathRecipient {
|
||||
private static final String LOG_TAG = "SipDelegateCAW";
|
||||
|
||||
private final ISipDelegateConnectionStateCallback.Stub mStateBinder =
|
||||
new ISipDelegateConnectionStateCallback.Stub() {
|
||||
@Override
|
||||
public void onCreated(ISipDelegate c) {
|
||||
associateSipDelegate(c);
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() ->
|
||||
mStateCallback.onCreated(SipDelegateConnectionAidlWrapper.this));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFeatureTagStatusChanged(DelegateRegistrationState registrationState,
|
||||
List<FeatureTagState> deniedFeatureTags) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() ->
|
||||
mStateCallback.onFeatureTagStatusChanged(registrationState,
|
||||
new ArraySet<>(deniedFeatureTags)));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImsConfigurationChanged(SipDelegateImsConfiguration registeredSipConfig) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() ->
|
||||
mStateCallback.onImsConfigurationChanged(registeredSipConfig));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyed(int reason) {
|
||||
invalidateSipDelegateBinder();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() ->
|
||||
mStateCallback.onDestroyed(reason));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final ISipDelegateMessageCallback.Stub mMessageBinder =
|
||||
new ISipDelegateMessageCallback.Stub() {
|
||||
@Override
|
||||
public void onMessageReceived(SipMessage message) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() ->
|
||||
mMessageCallback.onMessageReceived(message));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageSent(String viaTransactionId) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() ->
|
||||
mMessageCallback.onMessageSent(viaTransactionId));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageSendFailure(String viaTransactionId, int reason) {
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(() ->
|
||||
mMessageCallback.onMessageSendFailure(viaTransactionId, reason));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(token);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final Executor mExecutor;
|
||||
private final DelegateConnectionStateCallback mStateCallback;
|
||||
private final DelegateConnectionMessageCallback mMessageCallback;
|
||||
private final AtomicReference<ISipDelegate> mDelegateBinder =
|
||||
new AtomicReference<>();
|
||||
|
||||
/**
|
||||
* Wrap the local state and message callbacks, calling the implementation of these interfaces
|
||||
* when the remote process calls these methods.
|
||||
*/
|
||||
public SipDelegateConnectionAidlWrapper(Executor executor,
|
||||
DelegateConnectionStateCallback stateCallback,
|
||||
DelegateConnectionMessageCallback messageCallback) {
|
||||
mExecutor = executor;
|
||||
mStateCallback = stateCallback;
|
||||
mMessageCallback = messageCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(SipMessage sipMessage, int configVersion) {
|
||||
try {
|
||||
ISipDelegate conn = getSipDelegateBinder();
|
||||
if (conn == null) {
|
||||
notifyLocalMessageFailedToSend(sipMessage,
|
||||
SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
|
||||
return;
|
||||
}
|
||||
conn.sendMessage(sipMessage, configVersion);
|
||||
} catch (RemoteException e) {
|
||||
notifyLocalMessageFailedToSend(sipMessage,
|
||||
SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyMessageReceived(String viaTransactionId) {
|
||||
try {
|
||||
ISipDelegate conn = getSipDelegateBinder();
|
||||
if (conn == null) {
|
||||
return;
|
||||
}
|
||||
conn.notifyMessageReceived(viaTransactionId);
|
||||
} catch (RemoteException e) {
|
||||
// Nothing to do here, app will eventually get remote death callback.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyMessageReceiveError(String viaTransactionId, int reason) {
|
||||
try {
|
||||
ISipDelegate conn = getSipDelegateBinder();
|
||||
if (conn == null) {
|
||||
return;
|
||||
}
|
||||
conn.notifyMessageReceiveError(viaTransactionId, reason);
|
||||
} catch (RemoteException e) {
|
||||
// Nothing to do here, app will eventually get remote death callback.
|
||||
}
|
||||
}
|
||||
|
||||
// Also called upon IImsRcsController death (telephony process dies).
|
||||
@Override
|
||||
public void binderDied() {
|
||||
invalidateSipDelegateBinder();
|
||||
mExecutor.execute(() -> mStateCallback.onDestroyed(
|
||||
SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Implementation of state binder.
|
||||
*/
|
||||
public ISipDelegateConnectionStateCallback getStateCallbackBinder() {
|
||||
return mStateBinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Implementation of message binder.
|
||||
*/
|
||||
public ISipDelegateMessageCallback getMessageCallbackBinder() {
|
||||
return mMessageBinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ISipDelegateConnection associated with this wrapper.
|
||||
*/
|
||||
public ISipDelegate getSipDelegateBinder() {
|
||||
return mDelegateBinder.get();
|
||||
}
|
||||
|
||||
private void associateSipDelegate(ISipDelegate c) {
|
||||
if (c != null) {
|
||||
try {
|
||||
c.asBinder().linkToDeath(this, 0 /*flags*/);
|
||||
} catch (RemoteException e) {
|
||||
// already dead.
|
||||
c = null;
|
||||
}
|
||||
}
|
||||
mDelegateBinder.set(c);
|
||||
}
|
||||
|
||||
private void invalidateSipDelegateBinder() {
|
||||
ISipDelegate oldVal = mDelegateBinder.getAndUpdate((unused) -> null);
|
||||
if (oldVal != null) {
|
||||
try {
|
||||
oldVal.asBinder().unlinkToDeath(this, 0 /*flags*/);
|
||||
} catch (NoSuchElementException e) {
|
||||
Log.i(LOG_TAG, "invalidateSipDelegateBinder: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyLocalMessageFailedToSend(SipMessage m, int reason) {
|
||||
//TODO: parse transaction ID or throw IllegalArgumentException if the SipMessage
|
||||
// transaction ID can not be parsed.
|
||||
mExecutor.execute(() ->
|
||||
mMessageCallback.onMessageSendFailure(null, reason));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user