1 /* 2 * Copyright (C) 2018 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 17 package com.android.internal.telephony.ims; 18 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.os.IBinder; 22 import android.os.IInterface; 23 import android.os.RemoteException; 24 import android.telephony.ims.aidl.IImsConfig; 25 import android.telephony.ims.aidl.IImsMmTelFeature; 26 import android.telephony.ims.aidl.IImsRcsFeature; 27 import android.telephony.ims.aidl.IImsRegistration; 28 import android.telephony.ims.aidl.ISipTransport; 29 import android.telephony.ims.compat.ImsService; 30 import android.telephony.ims.compat.feature.ImsFeature; 31 import android.telephony.ims.compat.feature.MMTelFeature; 32 import android.util.Log; 33 import android.util.SparseArray; 34 35 import com.android.ims.ImsFeatureBinderRepository; 36 import com.android.ims.internal.IImsFeatureStatusCallback; 37 import com.android.ims.internal.IImsMMTelFeature; 38 import com.android.ims.internal.IImsServiceController; 39 40 /** 41 * Manages the Binding lifecycle of one ImsService as well as the relevant ImsFeatures that the 42 * ImsService will support. 43 * 44 * Compatibility interface for interacting with older implementations of ImsService. The older 45 * ImsService implementation is contained within the android.telephony.ims.compat.* namespace. 46 * Newer implementations of ImsService should use the current APIs contained in 47 * android.telephony.ims.*. 48 */ 49 public class ImsServiceControllerCompat extends ImsServiceController { 50 51 private static final String TAG = "ImsSCCompat"; 52 53 private IImsServiceController mServiceController; 54 55 private final SparseArray<MmTelFeatureCompatAdapter> mMmTelCompatAdapters = new SparseArray<>(); 56 private final SparseArray<ImsConfigCompatAdapter> mConfigCompatAdapters = new SparseArray<>(); 57 private final SparseArray<ImsRegistrationCompatAdapter> mRegCompatAdapters = 58 new SparseArray<>(); 59 ImsServiceControllerCompat(Context context, ComponentName componentName, ImsServiceController.ImsServiceControllerCallbacks callbacks, ImsFeatureBinderRepository repo)60 public ImsServiceControllerCompat(Context context, ComponentName componentName, 61 ImsServiceController.ImsServiceControllerCallbacks callbacks, 62 ImsFeatureBinderRepository repo) { 63 super(context, componentName, callbacks, repo); 64 } 65 66 @Override getServiceInterface()67 protected final String getServiceInterface() { 68 // Return compatibility version of String. 69 return ImsService.SERVICE_INTERFACE; 70 } 71 72 /** 73 * Converts the new command to {@link MMTelFeature#turnOnIms()}. 74 */ 75 @Override enableIms(int slotId)76 public final void enableIms(int slotId) { 77 MmTelFeatureCompatAdapter adapter = mMmTelCompatAdapters.get(slotId); 78 if (adapter == null) { 79 Log.w(TAG, "enableIms: adapter null for slot :" + slotId); 80 return; 81 } 82 try { 83 adapter.enableIms(); 84 } catch (RemoteException e) { 85 Log.w(TAG, "Couldn't enable IMS: " + e.getMessage()); 86 } 87 } 88 89 /** 90 * Converts the new command to {@link MMTelFeature#turnOffIms()}. 91 */ 92 @Override disableIms(int slotId)93 public final void disableIms(int slotId) { 94 MmTelFeatureCompatAdapter adapter = mMmTelCompatAdapters.get(slotId); 95 if (adapter == null) { 96 Log.w(TAG, "enableIms: adapter null for slot :" + slotId); 97 return; 98 } 99 try { 100 adapter.disableIms(); 101 } catch (RemoteException e) { 102 Log.w(TAG, "Couldn't enable IMS: " + e.getMessage()); 103 } 104 } 105 106 /** 107 * @return the IImsRegistration that corresponds to the slot id specified. 108 */ 109 @Override getRegistration(int slotId)110 public final IImsRegistration getRegistration(int slotId) { 111 ImsRegistrationCompatAdapter adapter = mRegCompatAdapters.get(slotId); 112 if (adapter == null) { 113 Log.w(TAG, "getRegistration: Registration does not exist for slot " + slotId); 114 return null; 115 } 116 return adapter.getBinder(); 117 } 118 119 /** 120 * @return the IImsConfig that corresponds to the slot id specified. 121 */ 122 @Override getConfig(int slotId)123 public final IImsConfig getConfig(int slotId) { 124 ImsConfigCompatAdapter adapter = mConfigCompatAdapters.get(slotId); 125 if (adapter == null) { 126 Log.w(TAG, "getConfig: Config does not exist for slot " + slotId); 127 return null; 128 } 129 return adapter.getIImsConfig(); 130 } 131 132 /** 133 * Return the SIP transport interface, which is not supported on the compat version of 134 * ImsService, so return null. 135 */ 136 @Override getSipTransport(int slotId)137 public ISipTransport getSipTransport(int slotId) { 138 return null; 139 } 140 141 @Override getStaticServiceCapabilities()142 protected long getStaticServiceCapabilities() { 143 // Older implementations do not support optional static capabilities 144 return 0L; 145 } 146 147 @Override notifyImsServiceReady()148 protected final void notifyImsServiceReady() { 149 Log.d(TAG, "notifyImsServiceReady"); 150 // don't do anything for compat impl. 151 } 152 153 @Override createImsFeature(int slotId, int featureType)154 protected final IInterface createImsFeature(int slotId, int featureType) 155 throws RemoteException { 156 switch (featureType) { 157 case ImsFeature.MMTEL: { 158 return createMMTelCompat(slotId); 159 } 160 case ImsFeature.RCS: { 161 162 return createRcsFeature(slotId); 163 } 164 default: 165 return null; 166 } 167 } 168 169 @Override registerImsFeatureStatusCallback(int slotId, int featureType, IImsFeatureStatusCallback c)170 protected void registerImsFeatureStatusCallback(int slotId, int featureType, 171 IImsFeatureStatusCallback c) throws RemoteException { 172 mServiceController.addFeatureStatusCallback(slotId, featureType, c); 173 } 174 175 @Override unregisterImsFeatureStatusCallback(int slotId, int featureType, IImsFeatureStatusCallback c)176 protected void unregisterImsFeatureStatusCallback(int slotId, int featureType, 177 IImsFeatureStatusCallback c) { 178 try { 179 mServiceController.removeFeatureStatusCallback(slotId, featureType, c); 180 } catch (RemoteException e) { 181 Log.w(TAG, "compat - unregisterImsFeatureStatusCallback - couldn't remove " + c); 182 } 183 } 184 185 @Override removeImsFeature(int slotId, int featureType)186 protected final void removeImsFeature(int slotId, int featureType) 187 throws RemoteException { 188 if (featureType == ImsFeature.MMTEL) { 189 mMmTelCompatAdapters.remove(slotId); 190 mRegCompatAdapters.remove(slotId); 191 mConfigCompatAdapters.remove(slotId); 192 } 193 if (mServiceController != null) { 194 mServiceController.removeImsFeature(slotId, featureType); 195 } 196 } 197 198 @Override setServiceController(IBinder serviceController)199 protected void setServiceController(IBinder serviceController) { 200 mServiceController = IImsServiceController.Stub.asInterface(serviceController); 201 } 202 203 @Override isServiceControllerAvailable()204 protected boolean isServiceControllerAvailable() { 205 return mServiceController != null; 206 } 207 getInterface(int slotId)208 private MmTelInterfaceAdapter getInterface(int slotId) 209 throws RemoteException { 210 IImsMMTelFeature feature = mServiceController.createMMTelFeature(slotId); 211 if (feature == null) { 212 Log.w(TAG, "createMMTelCompat: createMMTelFeature returned null."); 213 return null; 214 } 215 return new MmTelInterfaceAdapter(slotId, feature.asBinder()); 216 } 217 createMMTelCompat(int slotId)218 private IImsMmTelFeature createMMTelCompat(int slotId) 219 throws RemoteException { 220 MmTelInterfaceAdapter interfaceAdapter = getInterface(slotId); 221 MmTelFeatureCompatAdapter mmTelAdapter = new MmTelFeatureCompatAdapter(mContext, slotId, 222 interfaceAdapter); 223 mMmTelCompatAdapters.put(slotId, mmTelAdapter); 224 ImsRegistrationCompatAdapter regAdapter = new ImsRegistrationCompatAdapter(); 225 mmTelAdapter.addRegistrationAdapter(regAdapter); 226 mRegCompatAdapters.put(slotId, regAdapter); 227 mConfigCompatAdapters.put(slotId, new ImsConfigCompatAdapter( 228 mmTelAdapter.getOldConfigInterface())); 229 return mmTelAdapter.getBinder(); 230 } 231 createRcsFeature(int slotId)232 private IImsRcsFeature createRcsFeature(int slotId) { 233 // Return non-null if there is a custom RCS implementation that needs a compatability layer. 234 return null; 235 } 236 } 237