ImsServiceProxy.java revision 1639c21be6e7cd7699db4080fcf2ccc5cb2006e6
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package android.telephony.ims; 18 19import android.app.PendingIntent; 20import android.os.IBinder; 21import android.os.Message; 22import android.os.RemoteException; 23import android.telephony.ims.feature.IRcsFeature; 24import android.telephony.ims.feature.ImsFeature; 25import android.util.Log; 26 27import com.android.ims.ImsCallProfile; 28import com.android.ims.internal.IImsCallSession; 29import com.android.ims.internal.IImsCallSessionListener; 30import com.android.ims.internal.IImsConfig; 31import com.android.ims.internal.IImsEcbm; 32import com.android.ims.internal.IImsMultiEndpoint; 33import com.android.ims.internal.IImsRegistrationListener; 34import com.android.ims.internal.IImsServiceController; 35import com.android.ims.internal.IImsServiceFeatureListener; 36import com.android.ims.internal.IImsUt; 37 38/** 39 * A container of the IImsServiceController binder, which implements all of the ImsFeatures that 40 * the platform currently supports: MMTel and RCS. 41 * @hide 42 */ 43 44public class ImsServiceProxy extends ImsServiceProxyCompat implements IRcsFeature { 45 46 protected String LOG_TAG = "ImsServiceProxy"; 47 private final int mSupportedFeature; 48 49 // Start by assuming the proxy is available for usage. 50 private boolean mIsAvailable = true; 51 // ImsFeature Status from the ImsService. Cached. 52 private Integer mFeatureStatusCached = null; 53 private ImsServiceProxy.INotifyStatusChanged mStatusCallback; 54 private final Object mLock = new Object(); 55 56 public interface INotifyStatusChanged { 57 void notifyStatusChanged(); 58 } 59 60 private final IImsServiceFeatureListener mListenerBinder = 61 new IImsServiceFeatureListener.Stub() { 62 63 @Override 64 public void imsFeatureCreated(int slotId, int feature) throws RemoteException { 65 // The feature has been re-enabled. This may happen when the service crashes. 66 synchronized (mLock) { 67 if (!mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) { 68 Log.i(LOG_TAG, "Feature enabled on slotId: " + slotId + " for feature: " + 69 feature); 70 mIsAvailable = true; 71 } 72 } 73 } 74 75 @Override 76 public void imsFeatureRemoved(int slotId, int feature) throws RemoteException { 77 synchronized (mLock) { 78 if (mIsAvailable && mSlotId == slotId && feature == mSupportedFeature) { 79 Log.i(LOG_TAG, "Feature disabled on slotId: " + slotId + " for feature: " + 80 feature); 81 mIsAvailable = false; 82 } 83 } 84 } 85 86 @Override 87 public void imsStatusChanged(int slotId, int feature, int status) throws RemoteException { 88 synchronized (mLock) { 89 Log.i(LOG_TAG, "imsStatusChanged: slot: " + slotId + " feature: " + feature + 90 " status: " + status); 91 if (mSlotId == slotId && feature == mSupportedFeature) { 92 mFeatureStatusCached = status; 93 } 94 } 95 if (mStatusCallback != null) { 96 mStatusCallback.notifyStatusChanged(); 97 } 98 } 99 }; 100 101 public ImsServiceProxy(int slotId, IBinder binder, int featureType) { 102 super(slotId, binder); 103 mSupportedFeature = featureType; 104 } 105 106 public ImsServiceProxy(int slotId, int featureType) { 107 super(slotId, null /*IBinder*/); 108 mSupportedFeature = featureType; 109 } 110 111 public IImsServiceFeatureListener getListener() { 112 return mListenerBinder; 113 } 114 115 public void setBinder(IBinder binder) { 116 mBinder = binder; 117 } 118 119 @Override 120 public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener) 121 throws RemoteException { 122 synchronized (mLock) { 123 checkBinderConnection(); 124 return getServiceInterface(mBinder).startSession(mSlotId, mSupportedFeature, 125 incomingCallIntent, listener); 126 } 127 } 128 129 @Override 130 public void endSession(int sessionId) throws RemoteException { 131 synchronized (mLock) { 132 checkBinderConnection(); 133 getServiceInterface(mBinder).endSession(mSlotId, mSupportedFeature, sessionId); 134 } 135 } 136 137 @Override 138 public boolean isConnected(int sessionId, int callServiceType, int callType) 139 throws RemoteException { 140 synchronized (mLock) { 141 checkBinderConnection(); 142 return getServiceInterface(mBinder).isConnected(mSlotId, mSupportedFeature, sessionId, 143 callServiceType, callType); 144 } 145 } 146 147 @Override 148 public boolean isOpened(int sessionId) throws RemoteException { 149 synchronized (mLock) { 150 checkBinderConnection(); 151 return getServiceInterface(mBinder).isOpened(mSlotId, mSupportedFeature, sessionId); 152 } 153 } 154 155 @Override 156 public void addRegistrationListener(int sessionId, IImsRegistrationListener listener) 157 throws RemoteException { 158 synchronized (mLock) { 159 checkBinderConnection(); 160 getServiceInterface(mBinder).addRegistrationListener(mSlotId, mSupportedFeature, 161 sessionId, listener); 162 } 163 } 164 165 @Override 166 public void removeRegistrationListener(int sessionId, IImsRegistrationListener listener) 167 throws RemoteException { 168 synchronized (mLock) { 169 checkBinderConnection(); 170 getServiceInterface(mBinder).removeRegistrationListener(mSlotId, mSupportedFeature, 171 sessionId, listener); 172 } 173 } 174 175 @Override 176 public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType) 177 throws RemoteException { 178 synchronized (mLock) { 179 checkBinderConnection(); 180 return getServiceInterface(mBinder).createCallProfile(mSlotId, mSupportedFeature, 181 sessionId, callServiceType, callType); 182 } 183 } 184 185 @Override 186 public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile, 187 IImsCallSessionListener listener) throws RemoteException { 188 synchronized (mLock) { 189 checkBinderConnection(); 190 return getServiceInterface(mBinder).createCallSession(mSlotId, mSupportedFeature, 191 sessionId, profile, listener); 192 } 193 } 194 195 @Override 196 public IImsCallSession getPendingCallSession(int sessionId, String callId) 197 throws RemoteException { 198 synchronized (mLock) { 199 checkBinderConnection(); 200 return getServiceInterface(mBinder).getPendingCallSession(mSlotId, mSupportedFeature, 201 sessionId, callId); 202 } 203 } 204 205 @Override 206 public IImsUt getUtInterface(int sessionId) throws RemoteException { 207 synchronized (mLock) { 208 checkBinderConnection(); 209 return getServiceInterface(mBinder).getUtInterface(mSlotId, mSupportedFeature, 210 sessionId); 211 } 212 } 213 214 @Override 215 public IImsConfig getConfigInterface(int sessionId) throws RemoteException { 216 synchronized (mLock) { 217 checkBinderConnection(); 218 return getServiceInterface(mBinder).getConfigInterface(mSlotId, mSupportedFeature, 219 sessionId); 220 } 221 } 222 223 @Override 224 public void turnOnIms(int sessionId) throws RemoteException { 225 synchronized (mLock) { 226 checkBinderConnection(); 227 getServiceInterface(mBinder).turnOnIms(mSlotId, mSupportedFeature, sessionId); 228 } 229 } 230 231 @Override 232 public void turnOffIms(int sessionId) throws RemoteException { 233 synchronized (mLock) { 234 checkBinderConnection(); 235 getServiceInterface(mBinder).turnOffIms(mSlotId, mSupportedFeature, sessionId); 236 } 237 } 238 239 @Override 240 public IImsEcbm getEcbmInterface(int sessionId) throws RemoteException { 241 synchronized (mLock) { 242 checkBinderConnection(); 243 return getServiceInterface(mBinder).getEcbmInterface(mSlotId, mSupportedFeature, 244 sessionId); 245 } 246 } 247 248 @Override 249 public void setUiTTYMode(int sessionId, int uiTtyMode, Message onComplete) 250 throws RemoteException { 251 synchronized (mLock) { 252 checkBinderConnection(); 253 getServiceInterface(mBinder).setUiTTYMode(mSlotId, mSupportedFeature, sessionId, 254 uiTtyMode, onComplete); 255 } 256 } 257 258 @Override 259 public IImsMultiEndpoint getMultiEndpointInterface(int sessionId) throws RemoteException { 260 synchronized (mLock) { 261 checkBinderConnection(); 262 return getServiceInterface(mBinder).getMultiEndpointInterface(mSlotId, 263 mSupportedFeature, sessionId); 264 } 265 } 266 267 @Override 268 public int getFeatureStatus() { 269 synchronized (mLock) { 270 if (mFeatureStatusCached != null) { 271 return mFeatureStatusCached; 272 } 273 } 274 // Don't synchronize on Binder call. 275 Integer status = retrieveFeatureStatus(); 276 synchronized (mLock) { 277 if (status == null) { 278 return ImsFeature.STATE_NOT_AVAILABLE; 279 } 280 // Cache only non-null value for feature status. 281 mFeatureStatusCached = status; 282 } 283 return status; 284 } 285 286 /** 287 * Internal method used to retrieve the feature status from the corresponding ImsService. 288 */ 289 private Integer retrieveFeatureStatus() { 290 if (mBinder != null) { 291 try { 292 return getServiceInterface(mBinder).getFeatureStatus(mSlotId, mSupportedFeature); 293 } catch (RemoteException e) { 294 // Status check failed, don't update cache 295 } 296 } 297 return null; 298 } 299 300 /** 301 * @param c Callback that will fire when the feature status has changed. 302 */ 303 public void setStatusCallback(INotifyStatusChanged c) { 304 mStatusCallback = c; 305 } 306 307 @Override 308 public boolean isBinderAlive() { 309 return mIsAvailable && getFeatureStatus() == ImsFeature.STATE_READY && mBinder != null && 310 mBinder.isBinderAlive(); 311 } 312 313 private IImsServiceController getServiceInterface(IBinder b) { 314 return IImsServiceController.Stub.asInterface(b); 315 } 316} 317