/*
* Copyright (C) 2017 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.stub;
import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.net.Uri;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.util.Log;
import android.telephony.ims.ImsReasonInfo;
import com.android.internal.annotations.VisibleForTesting;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Controls IMS registration for this ImsService and notifies the framework when the IMS
registration for this ImsService has changed status.
@hide
/**
* Controls IMS registration for this ImsService and notifies the framework when the IMS
* registration for this ImsService has changed status.
* @hide
*/
@SystemApi
public class ImsRegistrationImplBase {
private static final String LOG_TAG = "ImsRegistrationImplBase";
@hide
/**
* @hide
*/
// Defines the underlying radio technology type that we have registered for IMS over.
@IntDef(flag = true,
value = {
REGISTRATION_TECH_NONE,
REGISTRATION_TECH_LTE,
REGISTRATION_TECH_IWLAN
})
@Retention(RetentionPolicy.SOURCE)
public @interface ImsRegistrationTech {}
No registration technology specified, used when we are not registered.
/**
* No registration technology specified, used when we are not registered.
*/
public static final int REGISTRATION_TECH_NONE = -1;
IMS is registered to IMS via LTE.
/**
* IMS is registered to IMS via LTE.
*/
public static final int REGISTRATION_TECH_LTE = 0;
IMS is registered to IMS via IWLAN.
/**
* IMS is registered to IMS via IWLAN.
*/
public static final int REGISTRATION_TECH_IWLAN = 1;
// Registration states, used to notify new ImsRegistrationImplBase#Callbacks of the current
// state.
// The unknown state is set as the initialization state. This is so that we do not call back
// with NOT_REGISTERED in the case where the ImsService has not updated the registration state
// yet.
private static final int REGISTRATION_STATE_UNKNOWN = -1;
private static final int REGISTRATION_STATE_NOT_REGISTERED = 0;
private static final int REGISTRATION_STATE_REGISTERING = 1;
private static final int REGISTRATION_STATE_REGISTERED = 2;
Callback class for receiving Registration callback events.
@hide
/**
* Callback class for receiving Registration callback events.
* @hide
*/
public static class Callback {
Notifies the framework when the IMS Provider is connected to the IMS network.
Params: - imsRadioTech – the radio access technology. Valid values are defined in
ImsRegistrationTech
.
/**
* Notifies the framework when the IMS Provider is connected to the IMS network.
*
* @param imsRadioTech the radio access technology. Valid values are defined in
* {@link ImsRegistrationTech}.
*/
public void onRegistered(@ImsRegistrationTech int imsRadioTech) {
}
Notifies the framework when the IMS Provider is trying to connect the IMS network.
Params: - imsRadioTech – the radio access technology. Valid values are defined in
ImsRegistrationTech
.
/**
* Notifies the framework when the IMS Provider is trying to connect the IMS network.
*
* @param imsRadioTech the radio access technology. Valid values are defined in
* {@link ImsRegistrationTech}.
*/
public void onRegistering(@ImsRegistrationTech int imsRadioTech) {
}
Notifies the framework when the IMS Provider is disconnected from the IMS network.
Params: - info – the
ImsReasonInfo
associated with why registration was disconnected.
/**
* Notifies the framework when the IMS Provider is disconnected from the IMS network.
*
* @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
*/
public void onDeregistered(ImsReasonInfo info) {
}
A failure has occurred when trying to handover registration to another technology type, defined in ImsRegistrationTech
Params: - imsRadioTech – The
ImsRegistrationTech
type that has failed - info – A
ImsReasonInfo
that identifies the reason for failure.
/**
* A failure has occurred when trying to handover registration to another technology type,
* defined in {@link ImsRegistrationTech}
*
* @param imsRadioTech The {@link ImsRegistrationTech} type that has failed
* @param info A {@link ImsReasonInfo} that identifies the reason for failure.
*/
public void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech,
ImsReasonInfo info) {
}
Returns a list of subscriber Uri
s associated with this IMS subscription when it changes. Params: - uris – new array of subscriber
Uri
s that are associated with this IMS subscription.
/**
* Returns a list of subscriber {@link Uri}s associated with this IMS subscription when
* it changes.
* @param uris new array of subscriber {@link Uri}s that are associated with this IMS
* subscription.
*/
public void onSubscriberAssociatedUriChanged(Uri[] uris) {
}
}
private final IImsRegistration mBinder = new IImsRegistration.Stub() {
@Override
public @ImsRegistrationTech int getRegistrationTechnology() throws RemoteException {
return getConnectionType();
}
@Override
public void addRegistrationCallback(IImsRegistrationCallback c) throws RemoteException {
ImsRegistrationImplBase.this.addRegistrationCallback(c);
}
@Override
public void removeRegistrationCallback(IImsRegistrationCallback c) throws RemoteException {
ImsRegistrationImplBase.this.removeRegistrationCallback(c);
}
};
private final RemoteCallbackList<IImsRegistrationCallback> mCallbacks
= new RemoteCallbackList<>();
private final Object mLock = new Object();
// Locked on mLock
private @ImsRegistrationTech
int mConnectionType = REGISTRATION_TECH_NONE;
// Locked on mLock
private int mRegistrationState = REGISTRATION_STATE_UNKNOWN;
// Locked on mLock, create unspecified disconnect cause.
private ImsReasonInfo mLastDisconnectCause = new ImsReasonInfo();
@hide
/**
* @hide
*/
public final IImsRegistration getBinder() {
return mBinder;
}
private void addRegistrationCallback(IImsRegistrationCallback c) throws RemoteException {
mCallbacks.register(c);
updateNewCallbackWithState(c);
}
private void removeRegistrationCallback(IImsRegistrationCallback c) {
mCallbacks.unregister(c);
}
Notify the framework that the device is connected to the IMS network.
Params: - imsRadioTech – the radio access technology. Valid values are defined as
REGISTRATION_TECH_LTE
and REGISTRATION_TECH_IWLAN
.
/**
* Notify the framework that the device is connected to the IMS network.
*
* @param imsRadioTech the radio access technology. Valid values are defined as
* {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}.
*/
public final void onRegistered(@ImsRegistrationTech int imsRadioTech) {
updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERED);
mCallbacks.broadcast((c) -> {
try {
c.onRegistered(imsRadioTech);
} catch (RemoteException e) {
Log.w(LOG_TAG, e + " " + "onRegistrationConnected() - Skipping " +
"callback.");
}
});
}
Notify the framework that the device is trying to connect the IMS network.
Params: - imsRadioTech – the radio access technology. Valid values are defined as
REGISTRATION_TECH_LTE
and REGISTRATION_TECH_IWLAN
.
/**
* Notify the framework that the device is trying to connect the IMS network.
*
* @param imsRadioTech the radio access technology. Valid values are defined as
* {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}.
*/
public final void onRegistering(@ImsRegistrationTech int imsRadioTech) {
updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERING);
mCallbacks.broadcast((c) -> {
try {
c.onRegistering(imsRadioTech);
} catch (RemoteException e) {
Log.w(LOG_TAG, e + " " + "onRegistrationProcessing() - Skipping " +
"callback.");
}
});
}
Notify the framework that the device is disconnected from the IMS network.
Note: Prior to calling onDeregistered(ImsReasonInfo)
, you should ensure that any changes to ImsFeature
capability availability is sent to the framework. For example, MmTelCapabilities.CAPABILITY_TYPE_VIDEO
and MmTelCapabilities.CAPABILITY_TYPE_VOICE
may be set to unavailable to ensure the framework knows these services are no longer available due to de-registration. If you do not report capability changes impacted by de-registration, the framework will not know which features are no longer available as a result.
Params: - info – the
ImsReasonInfo
associated with why registration was disconnected.
/**
* Notify the framework that the device is disconnected from the IMS network.
* <p>
* Note: Prior to calling {@link #onDeregistered(ImsReasonInfo)}, you should ensure that any
* changes to {@link android.telephony.ims.feature.ImsFeature} capability availability is sent
* to the framework. For example,
* {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}
* and
* {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}
* may be set to unavailable to ensure the framework knows these services are no longer
* available due to de-registration. If you do not report capability changes impacted by
* de-registration, the framework will not know which features are no longer available as a
* result.
*
* @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
*/
public final void onDeregistered(ImsReasonInfo info) {
updateToDisconnectedState(info);
mCallbacks.broadcast((c) -> {
try {
c.onDeregistered(info);
} catch (RemoteException e) {
Log.w(LOG_TAG, e + " " + "onRegistrationDisconnected() - Skipping " +
"callback.");
}
});
}
Notify the framework that the handover from the current radio technology to the technology defined in imsRadioTech
has failed. Params: - imsRadioTech – The technology that has failed to be changed. Valid values are
REGISTRATION_TECH_LTE
and REGISTRATION_TECH_IWLAN
. - info – The
ImsReasonInfo
for the failure to change technology.
/**
* Notify the framework that the handover from the current radio technology to the technology
* defined in {@code imsRadioTech} has failed.
* @param imsRadioTech The technology that has failed to be changed. Valid values are
* {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}.
* @param info The {@link ImsReasonInfo} for the failure to change technology.
*/
public final void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech,
ImsReasonInfo info) {
mCallbacks.broadcast((c) -> {
try {
c.onTechnologyChangeFailed(imsRadioTech, info);
} catch (RemoteException e) {
Log.w(LOG_TAG, e + " " + "onRegistrationChangeFailed() - Skipping " +
"callback.");
}
});
}
The this device's subscriber associated Uri
s have changed, which are used to filter out this device's Uri
s during conference calling. Params: - uris –
/**
* The this device's subscriber associated {@link Uri}s have changed, which are used to filter
* out this device's {@link Uri}s during conference calling.
* @param uris
*/
public final void onSubscriberAssociatedUriChanged(Uri[] uris) {
mCallbacks.broadcast((c) -> {
try {
c.onSubscriberAssociatedUriChanged(uris);
} catch (RemoteException e) {
Log.w(LOG_TAG, e + " " + "onSubscriberAssociatedUriChanged() - Skipping " +
"callback.");
}
});
}
private void updateToState(@ImsRegistrationTech int connType, int newState) {
synchronized (mLock) {
mConnectionType = connType;
mRegistrationState = newState;
mLastDisconnectCause = null;
}
}
private void updateToDisconnectedState(ImsReasonInfo info) {
synchronized (mLock) {
updateToState(REGISTRATION_TECH_NONE, REGISTRATION_STATE_NOT_REGISTERED);
if (info != null) {
mLastDisconnectCause = info;
} else {
Log.w(LOG_TAG, "updateToDisconnectedState: no ImsReasonInfo provided.");
mLastDisconnectCause = new ImsReasonInfo();
}
}
}
Returns: the current registration connection type. Valid values are REGISTRATION_TECH_LTE
and REGISTRATION_TECH_IWLAN
@hide
/**
* @return the current registration connection type. Valid values are
* {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}
* @hide
*/
@VisibleForTesting
public final @ImsRegistrationTech int getConnectionType() {
synchronized (mLock) {
return mConnectionType;
}
}
Params: - c – the newly registered callback that will be updated with the current registration
state.
/**
* @param c the newly registered callback that will be updated with the current registration
* state.
*/
private void updateNewCallbackWithState(IImsRegistrationCallback c) throws RemoteException {
int state;
ImsReasonInfo disconnectInfo;
synchronized (mLock) {
state = mRegistrationState;
disconnectInfo = mLastDisconnectCause;
}
switch (state) {
case REGISTRATION_STATE_NOT_REGISTERED: {
c.onDeregistered(disconnectInfo);
break;
}
case REGISTRATION_STATE_REGISTERING: {
c.onRegistering(getConnectionType());
break;
}
case REGISTRATION_STATE_REGISTERED: {
c.onRegistered(getConnectionType());
break;
}
case REGISTRATION_STATE_UNKNOWN: {
// Do not callback if the state has not been updated yet by the ImsService.
break;
}
}
}
}