222 lines
7.5 KiB
Java
222 lines
7.5 KiB
Java
/*
|
|
* 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.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.os.Binder;
|
|
import android.os.RemoteException;
|
|
import android.telephony.ims.DelegateMessageCallback;
|
|
import android.telephony.ims.DelegateRegistrationState;
|
|
import android.telephony.ims.DelegateStateCallback;
|
|
import android.telephony.ims.FeatureTagState;
|
|
import android.telephony.ims.SipDelegateConfiguration;
|
|
import android.telephony.ims.SipDelegateImsConfiguration;
|
|
import android.telephony.ims.SipDelegateManager;
|
|
import android.telephony.ims.SipMessage;
|
|
import android.telephony.ims.stub.SipDelegate;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.Set;
|
|
import java.util.concurrent.Executor;
|
|
|
|
/**
|
|
* Implementation of callbacks by wrapping the internal AIDL from telephony. Also implements
|
|
* ISipDelegate internally when {@link DelegateStateCallback#onCreated(SipDelegate, Set)} is called
|
|
* in order to trampoline events back to telephony.
|
|
* @hide
|
|
*/
|
|
public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMessageCallback {
|
|
private static final String LOG_TAG = "SipDelegateAW";
|
|
|
|
private final ISipDelegate.Stub mDelegateBinder = new ISipDelegate.Stub() {
|
|
@Override
|
|
public void sendMessage(SipMessage sipMessage, long configVersion) {
|
|
SipDelegate d = mDelegate;
|
|
if (d == null) {
|
|
return;
|
|
}
|
|
final long token = Binder.clearCallingIdentity();
|
|
try {
|
|
mExecutor.execute(() -> d.sendMessage(sipMessage, configVersion));
|
|
} finally {
|
|
Binder.restoreCallingIdentity(token);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void notifyMessageReceived(String viaTransactionId) {
|
|
SipDelegate d = mDelegate;
|
|
if (d == null) {
|
|
return;
|
|
}
|
|
final long token = Binder.clearCallingIdentity();
|
|
try {
|
|
mExecutor.execute(() -> d.notifyMessageReceived(viaTransactionId));
|
|
} finally {
|
|
Binder.restoreCallingIdentity(token);
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public void notifyMessageReceiveError(String viaTransactionId, int reason) {
|
|
SipDelegate d = mDelegate;
|
|
if (d == null) {
|
|
return;
|
|
}
|
|
final long token = Binder.clearCallingIdentity();
|
|
try {
|
|
mExecutor.execute(() -> d.notifyMessageReceiveError(viaTransactionId, reason));
|
|
} finally {
|
|
Binder.restoreCallingIdentity(token);
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public void cleanupSession(String callId) {
|
|
SipDelegate d = mDelegate;
|
|
if (d == null) {
|
|
return;
|
|
}
|
|
final long token = Binder.clearCallingIdentity();
|
|
try {
|
|
mExecutor.execute(() -> d.cleanupSession(callId));
|
|
} finally {
|
|
Binder.restoreCallingIdentity(token);
|
|
}
|
|
}
|
|
};
|
|
|
|
private final ISipDelegateMessageCallback mMessageBinder;
|
|
private final ISipDelegateStateCallback mStateBinder;
|
|
private final Executor mExecutor;
|
|
|
|
private volatile SipDelegate mDelegate;
|
|
|
|
public SipDelegateAidlWrapper(Executor executor, ISipDelegateStateCallback stateBinder,
|
|
ISipDelegateMessageCallback messageBinder) {
|
|
mExecutor = executor;
|
|
mStateBinder = stateBinder;
|
|
mMessageBinder = messageBinder;
|
|
}
|
|
|
|
@Override
|
|
public void onMessageReceived(SipMessage message) {
|
|
try {
|
|
mMessageBinder.onMessageReceived(message);
|
|
} catch (RemoteException e) {
|
|
// BinderDied will be called on SipTransport instance to trigger destruction. Notify
|
|
// failure message failure locally for now.
|
|
SipDelegate d = mDelegate;
|
|
if (d != null) {
|
|
notifyLocalMessageFailedToBeReceived(message,
|
|
SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onMessageSent(String viaTransactionId) {
|
|
try {
|
|
mMessageBinder.onMessageSent(viaTransactionId);
|
|
} catch (RemoteException e) {
|
|
// BinderDied will trigger destroySipDelegate, so just ignore this locally.
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onMessageSendFailure(String viaTransactionId, int reason) {
|
|
try {
|
|
mMessageBinder.onMessageSendFailure(viaTransactionId, reason);
|
|
} catch (RemoteException e) {
|
|
// BinderDied will trigger destroySipDelegate, so just ignore this locally.
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onCreated(@NonNull SipDelegate delegate,
|
|
@Nullable Set<FeatureTagState> deniedTags) {
|
|
mDelegate = delegate;
|
|
deniedTags = (deniedTags == null) ? Collections.emptySet() : deniedTags;
|
|
try {
|
|
mStateBinder.onCreated(mDelegateBinder, new ArrayList<>(deniedTags));
|
|
} catch (RemoteException e) {
|
|
// BinderDied will trigger destroySipDelegate, so just ignore this locally.
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onFeatureTagRegistrationChanged(DelegateRegistrationState registrationState) {
|
|
try {
|
|
mStateBinder.onFeatureTagRegistrationChanged(registrationState);
|
|
} catch (RemoteException e) {
|
|
// BinderDied will trigger destroySipDelegate, so just ignore this locally.
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onImsConfigurationChanged(@NonNull SipDelegateImsConfiguration config) {
|
|
try {
|
|
mStateBinder.onImsConfigurationChanged(config);
|
|
} catch (RemoteException e) {
|
|
// BinderDied will trigger destroySipDelegate, so just ignore this locally.
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onConfigurationChanged(@NonNull SipDelegateConfiguration config) {
|
|
try {
|
|
mStateBinder.onConfigurationChanged(config);
|
|
} catch (RemoteException e) {
|
|
// BinderDied will trigger destroySipDelegate, so just ignore this locally.
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onDestroyed(int reasonCode) {
|
|
mDelegate = null;
|
|
try {
|
|
mStateBinder.onDestroyed(reasonCode);
|
|
} catch (RemoteException e) {
|
|
// Do not worry about this if the remote side is already dead.
|
|
}
|
|
}
|
|
|
|
public SipDelegate getDelegate() {
|
|
return mDelegate;
|
|
}
|
|
|
|
public ISipDelegate getDelegateBinder() {
|
|
return mDelegateBinder;
|
|
}
|
|
|
|
public ISipDelegateStateCallback getStateCallbackBinder() {
|
|
return mStateBinder;
|
|
}
|
|
|
|
private void notifyLocalMessageFailedToBeReceived(SipMessage m, int reason) {
|
|
String transactionId = m.getViaBranchParameter();
|
|
SipDelegate d = mDelegate;
|
|
if (d != null) {
|
|
mExecutor.execute(() -> d.notifyMessageReceiveError(transactionId, reason));
|
|
}
|
|
}
|
|
}
|