Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
Adds @hide ImsService APIs
Browse files Browse the repository at this point in the history
Adds @hide ImsService API implementations to be used for the new
dynamic ImsResolver.

1) ImsService - The main class that all vendor ImsServices will implement.
ImsServices that implement this method must return their implementations
of MMTelFeature when onCreateMMTelFeature is called. The base ImsService
class also relays all method calls through itself as a proxy. So, when
Telephony calls a method, the ImsService figures out which MMTelFeature
should be called (by slot) and then calls that feature's method
implementation.

2) MMTelFeature/RcsFeature - Implements the I*Feature interfaces, which
are used on both sides of the interface. The vendor implemented ImsService
must implement all methods provided in the I*Feature interface in their
implementation of *Feature that they return to the ImsService.

3) ImsServiceProxy[Compat] - The Proxy interface in telephony that will be
called in ImsManager. When a method in this class is called, it will call
the respective AIDL function: Telephony -> IImsServiceController AIDL ->
vendor ImsService -> vendor ImsFeature implementation.
ImsServiceProxyCompat is there to provide backwards compatibility with
older ImsServices that do not use the new ImsService implementations.
It implements all of the methods that are defined in the new I*Feature
interfaces and translates them to the old ImsService AIDL calls.

Test: Adds Unit Tests (see frameworks/opt/telephony)
Merged-In: Id3466c178384158c788ab1d708ab108bb95866fc
Change-Id: Id3466c178384158c788ab1d708ab108bb95866fc
  • Loading branch information
Brad Ebinger committed Feb 16, 2017
1 parent eb82e3d commit 1639c21
Show file tree
Hide file tree
Showing 13 changed files with 1,471 additions and 4 deletions.
1 change: 1 addition & 0 deletions Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ LOCAL_SRC_FILES += \
telephony/java/com/android/ims/internal/IImsEcbm.aidl \
telephony/java/com/android/ims/internal/IImsEcbmListener.aidl \
telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl \
telephony/java/com/android/ims/internal/IImsFeatureStatusCallback.aidl \
telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl \
telephony/java/com/android/ims/internal/IImsService.aidl \
telephony/java/com/android/ims/internal/IImsServiceController.aidl \
Expand Down
430 changes: 430 additions & 0 deletions telephony/java/android/telephony/ims/ImsService.java

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion telephony/java/android/telephony/ims/ImsServiceBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import android.os.IBinder;

/**
* Base ImsService Implementation, which is used by the ImsResolver to bind.
* Base ImsService Implementation, which is used by the ImsResolver to bind. ImsServices that do not
* need to provide an ImsService implementation but still wish to be managed by the ImsResolver
* lifecycle may implement this class directly.
* @hide
*/
@SystemApi
Expand Down
316 changes: 316 additions & 0 deletions telephony/java/android/telephony/ims/ImsServiceProxy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
/*
* 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;

import android.app.PendingIntent;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.ims.feature.IRcsFeature;
import android.telephony.ims.feature.ImsFeature;
import android.util.Log;

import com.android.ims.ImsCallProfile;
import com.android.ims.internal.IImsCallSession;
import com.android.ims.internal.IImsCallSessionListener;
import com.android.ims.internal.IImsConfig;
import com.android.ims.internal.IImsEcbm;
import com.android.ims.internal.IImsMultiEndpoint;
import com.android.ims.internal.IImsRegistrationListener;
import com.android.ims.internal.IImsServiceController;
import com.android.ims.internal.IImsServiceFeatureListener;
import com.android.ims.internal.IImsUt;

/**
* A container of the IImsServiceController binder, which implements all of the ImsFeatures that
* the platform currently supports: MMTel and RCS.
* @hide
*/

public class ImsServiceProxy extends ImsServiceProxyCompat implements IRcsFeature {

protected String LOG_TAG = "ImsServiceProxy";
private final int mSupportedFeature;

// Start by assuming the proxy is available for usage.
private boolean mIsAvailable = true;
// ImsFeature Status from the ImsService. Cached.
private Integer mFeatureStatusCached = null;
private ImsServiceProxy.INotifyStatusChanged mStatusCallback;
private final Object mLock = new Object();

public interface INotifyStatusChanged {
void notifyStatusChanged();
}

private final IImsServiceFeatureListener mListenerBinder =
new IImsServiceFeatureListener.Stub() {

@Override
public void imsFeatureCreated(int slotId, int feature) throws RemoteException {
// The feature has been re-enabled. This may happen when the service crashes.
synchronized (mLock) {
if (!mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) {
Log.i(LOG_TAG, "Feature enabled on slotId: " + slotId + " for feature: " +
feature);
mIsAvailable = true;
}
}
}

@Override
public void imsFeatureRemoved(int slotId, int feature) throws RemoteException {
synchronized (mLock) {
if (mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) {
Log.i(LOG_TAG, "Feature disabled on slotId: " + slotId + " for feature: " +
feature);
mIsAvailable = false;
}
}
}

@Override
public void imsStatusChanged(int slotId, int feature, int status) throws RemoteException {
synchronized (mLock) {
Log.i(LOG_TAG, "imsStatusChanged: slot: " + slotId + " feature: " + feature +
" status: " + status);
if (mSlotId == slotId && feature == mSupportedFeature) {
mFeatureStatusCached = status;
}
}
if (mStatusCallback != null) {
mStatusCallback.notifyStatusChanged();
}
}
};

public ImsServiceProxy(int slotId, IBinder binder, int featureType) {
super(slotId, binder);
mSupportedFeature = featureType;
}

public ImsServiceProxy(int slotId, int featureType) {
super(slotId, null /*IBinder*/);
mSupportedFeature = featureType;
}

public IImsServiceFeatureListener getListener() {
return mListenerBinder;
}

public void setBinder(IBinder binder) {
mBinder = binder;
}

@Override
public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).startSession(mSlotId, mSupportedFeature,
incomingCallIntent, listener);
}
}

@Override
public void endSession(int sessionId) throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
getServiceInterface(mBinder).endSession(mSlotId, mSupportedFeature, sessionId);
}
}

@Override
public boolean isConnected(int sessionId, int callServiceType, int callType)
throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).isConnected(mSlotId, mSupportedFeature, sessionId,
callServiceType, callType);
}
}

@Override
public boolean isOpened(int sessionId) throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).isOpened(mSlotId, mSupportedFeature, sessionId);
}
}

@Override
public void addRegistrationListener(int sessionId, IImsRegistrationListener listener)
throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
getServiceInterface(mBinder).addRegistrationListener(mSlotId, mSupportedFeature,
sessionId, listener);
}
}

@Override
public void removeRegistrationListener(int sessionId, IImsRegistrationListener listener)
throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
getServiceInterface(mBinder).removeRegistrationListener(mSlotId, mSupportedFeature,
sessionId, listener);
}
}

@Override
public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType)
throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).createCallProfile(mSlotId, mSupportedFeature,
sessionId, callServiceType, callType);
}
}

@Override
public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
IImsCallSessionListener listener) throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).createCallSession(mSlotId, mSupportedFeature,
sessionId, profile, listener);
}
}

@Override
public IImsCallSession getPendingCallSession(int sessionId, String callId)
throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).getPendingCallSession(mSlotId, mSupportedFeature,
sessionId, callId);
}
}

@Override
public IImsUt getUtInterface(int sessionId) throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).getUtInterface(mSlotId, mSupportedFeature,
sessionId);
}
}

@Override
public IImsConfig getConfigInterface(int sessionId) throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).getConfigInterface(mSlotId, mSupportedFeature,
sessionId);
}
}

@Override
public void turnOnIms(int sessionId) throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
getServiceInterface(mBinder).turnOnIms(mSlotId, mSupportedFeature, sessionId);
}
}

@Override
public void turnOffIms(int sessionId) throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
getServiceInterface(mBinder).turnOffIms(mSlotId, mSupportedFeature, sessionId);
}
}

@Override
public IImsEcbm getEcbmInterface(int sessionId) throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).getEcbmInterface(mSlotId, mSupportedFeature,
sessionId);
}
}

@Override
public void setUiTTYMode(int sessionId, int uiTtyMode, Message onComplete)
throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
getServiceInterface(mBinder).setUiTTYMode(mSlotId, mSupportedFeature, sessionId,
uiTtyMode, onComplete);
}
}

@Override
public IImsMultiEndpoint getMultiEndpointInterface(int sessionId) throws RemoteException {
synchronized (mLock) {
checkBinderConnection();
return getServiceInterface(mBinder).getMultiEndpointInterface(mSlotId,
mSupportedFeature, sessionId);
}
}

@Override
public int getFeatureStatus() {
synchronized (mLock) {
if (mFeatureStatusCached != null) {
return mFeatureStatusCached;
}
}
// Don't synchronize on Binder call.
Integer status = retrieveFeatureStatus();
synchronized (mLock) {
if (status == null) {
return ImsFeature.STATE_NOT_AVAILABLE;
}
// Cache only non-null value for feature status.
mFeatureStatusCached = status;
}
return status;
}

/**
* Internal method used to retrieve the feature status from the corresponding ImsService.
*/
private Integer retrieveFeatureStatus() {
if (mBinder != null) {
try {
return getServiceInterface(mBinder).getFeatureStatus(mSlotId, mSupportedFeature);
} catch (RemoteException e) {
// Status check failed, don't update cache
}
}
return null;
}

/**
* @param c Callback that will fire when the feature status has changed.
*/
public void setStatusCallback(INotifyStatusChanged c) {
mStatusCallback = c;
}

@Override
public boolean isBinderAlive() {
return mIsAvailable && getFeatureStatus() == ImsFeature.STATE_READY && mBinder != null &&
mBinder.isBinderAlive();
}

private IImsServiceController getServiceInterface(IBinder b) {
return IImsServiceController.Stub.asInterface(b);
}
}

0 comments on commit 1639c21

Please sign in to comment.