All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.android.telephony.ims.aidl.SipDelegateAidlWrapper Maven / Gradle / Ivy

/*
 * 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 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));
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy