blob: 4294f7ea7ed9dea9f3efe8ab866278f4ad811acd [file] [log] [blame]
James.cf Linaf3183c2019-10-24 00:59:00 +08001/*
2 * Copyright (C) 2019 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 com.android.phone;
18
James.cf Linaf3183c2019-10-24 00:59:00 +080019import android.net.Uri;
James.cf Lincad981c2019-12-10 20:37:56 +080020import android.os.Binder;
21import android.os.RemoteException;
James.cf Lincad981c2019-12-10 20:37:56 +080022import android.os.ServiceSpecificException;
Brad Ebingerb7a866a2020-01-22 17:51:55 -080023import android.telephony.SubscriptionManager;
Peter Wangc035ce42020-01-08 21:00:22 -080024import android.telephony.TelephonyFrameworkInitializer;
James.cf Lincad981c2019-12-10 20:37:56 +080025import android.telephony.ims.ImsException;
James.cf Lindc2d5422019-12-31 14:40:25 +080026import android.telephony.ims.RegistrationManager;
James.cf Linaf3183c2019-10-24 00:59:00 +080027import android.telephony.ims.aidl.IImsCapabilityCallback;
28import android.telephony.ims.aidl.IImsRcsController;
James.cf Lindc2d5422019-12-31 14:40:25 +080029import android.telephony.ims.aidl.IImsRegistrationCallback;
James.cf Linaf3183c2019-10-24 00:59:00 +080030import android.telephony.ims.aidl.IRcsUceControllerCallback;
James.cf Lincdad3862020-02-25 15:55:03 +080031import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070032import android.telephony.ims.feature.ImsFeature;
James.cf Linaf3183c2019-10-24 00:59:00 +080033import android.telephony.ims.feature.RcsFeature;
James.cf Lincad981c2019-12-10 20:37:56 +080034import android.telephony.ims.stub.ImsRegistrationImplBase;
James.cf Linaf3183c2019-10-24 00:59:00 +080035import android.util.Log;
36
James.cf Lindc2d5422019-12-31 14:40:25 +080037import com.android.ims.ImsManager;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070038import com.android.ims.internal.IImsServiceFeatureCallback;
James.cf Lindc2d5422019-12-31 14:40:25 +080039import com.android.internal.telephony.IIntegerConsumer;
James.cf Lincad981c2019-12-10 20:37:56 +080040import com.android.internal.telephony.Phone;
Brad Ebinger8b79edc2020-02-27 19:13:24 -080041import com.android.internal.telephony.TelephonyPermissions;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070042import com.android.internal.telephony.ims.ImsResolver;
James.cf Lincad981c2019-12-10 20:37:56 +080043import com.android.internal.telephony.imsphone.ImsPhone;
Brad Ebingera68a4972020-01-30 17:31:23 -080044import com.android.services.telephony.rcs.RcsFeatureController;
James.cf Linc9f35a42020-01-15 02:35:22 +080045import com.android.services.telephony.rcs.TelephonyRcsService;
Brad Ebingera68a4972020-01-30 17:31:23 -080046import com.android.services.telephony.rcs.UserCapabilityExchangeImpl;
James.cf Lincad981c2019-12-10 20:37:56 +080047
James.cf Linaf3183c2019-10-24 00:59:00 +080048import java.util.List;
49
50/**
51 * Implementation of the IImsRcsController interface.
52 */
53public class ImsRcsController extends IImsRcsController.Stub {
54 private static final String TAG = "ImsRcsController";
55
56 /** The singleton instance. */
57 private static ImsRcsController sInstance;
58
59 private PhoneGlobals mApp;
James.cf Linc9f35a42020-01-15 02:35:22 +080060 private TelephonyRcsService mRcsService;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070061 private ImsResolver mImsResolver;
James.cf Linaf3183c2019-10-24 00:59:00 +080062
63 /**
64 * Initialize the singleton ImsRcsController instance.
65 * This is only done once, at startup, from PhoneApp.onCreate().
66 */
67 static ImsRcsController init(PhoneGlobals app) {
68 synchronized (ImsRcsController.class) {
69 if (sInstance == null) {
70 sInstance = new ImsRcsController(app);
71 } else {
72 Log.wtf(TAG, "init() called multiple times! sInstance = " + sInstance);
73 }
74 return sInstance;
75 }
76 }
77
78 /** Private constructor; @see init() */
79 private ImsRcsController(PhoneGlobals app) {
80 Log.i(TAG, "ImsRcsController");
81 mApp = app;
Peter Wangc035ce42020-01-08 21:00:22 -080082 TelephonyFrameworkInitializer
83 .getTelephonyServiceManager().getTelephonyImsServiceRegisterer().register(this);
Brad Ebingere3ae65a2020-09-11 12:45:11 -070084 mImsResolver = mApp.getImsResolver();
James.cf Linaf3183c2019-10-24 00:59:00 +080085 }
86
James.cf Lincad981c2019-12-10 20:37:56 +080087 /**
Brad Ebingera68a4972020-01-30 17:31:23 -080088 * Register a {@link RegistrationManager.RegistrationCallback} to receive IMS network
89 * registration state.
James.cf Lindc2d5422019-12-31 14:40:25 +080090 */
91 @Override
Brad Ebingera68a4972020-01-30 17:31:23 -080092 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
James.cf Lindc2d5422019-12-31 14:40:25 +080093 enforceReadPrivilegedPermission("registerImsRegistrationCallback");
94 final long token = Binder.clearCallingIdentity();
95 try {
Brad Ebingera68a4972020-01-30 17:31:23 -080096 getRcsFeatureController(subId).registerImsRegistrationCallback(subId, callback);
97 } catch (ImsException e) {
James.cf Lindc2d5422019-12-31 14:40:25 +080098 Log.e(TAG, "registerImsRegistrationCallback: sudId=" + subId + ", " + e.getMessage());
99 throw new ServiceSpecificException(e.getCode());
100 } finally {
101 Binder.restoreCallingIdentity(token);
102 }
103 }
104
105 /**
Brad Ebingera68a4972020-01-30 17:31:23 -0800106 * Removes an existing {@link RegistrationManager.RegistrationCallback}.
James.cf Lindc2d5422019-12-31 14:40:25 +0800107 */
108 @Override
109 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
110 enforceReadPrivilegedPermission("unregisterImsRegistrationCallback");
111 final long token = Binder.clearCallingIdentity();
112 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800113 getRcsFeatureController(subId).unregisterImsRegistrationCallback(subId, callback);
James.cf Lindc2d5422019-12-31 14:40:25 +0800114 } catch (ServiceSpecificException e) {
115 Log.e(TAG, "unregisterImsRegistrationCallback: error=" + e.errorCode);
116 } finally {
117 Binder.restoreCallingIdentity(token);
118 }
119 }
120
121 /**
122 * Get the IMS service registration state for the RcsFeature associated with this sub id.
123 */
124 @Override
125 public void getImsRcsRegistrationState(int subId, IIntegerConsumer consumer) {
126 enforceReadPrivilegedPermission("getImsRcsRegistrationState");
127 final long token = Binder.clearCallingIdentity();
128 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800129 getRcsFeatureController(subId).getRegistrationState(regState -> {
James.cf Lindc2d5422019-12-31 14:40:25 +0800130 try {
131 consumer.accept((regState == null)
132 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
133 } catch (RemoteException e) {
134 Log.w(TAG, "getImsRcsRegistrationState: callback is not available.");
135 }
136 });
137 } finally {
138 Binder.restoreCallingIdentity(token);
139 }
140 }
141
142 /**
143 * Gets the Transport Type associated with the current IMS RCS registration.
144 */
145 @Override
146 public void getImsRcsRegistrationTransportType(int subId, IIntegerConsumer consumer) {
147 enforceReadPrivilegedPermission("getImsRcsRegistrationTransportType");
148 final long token = Binder.clearCallingIdentity();
149 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800150 getRcsFeatureController(subId).getRegistrationTech(regTech -> {
James.cf Lindc2d5422019-12-31 14:40:25 +0800151 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
152 int regTechConverted = (regTech == null)
153 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
154 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
155 regTechConverted);
156 try {
157 consumer.accept(regTechConverted);
158 } catch (RemoteException e) {
159 Log.w(TAG, "getImsRcsRegistrationTransportType: callback is not available.");
160 }
161 });
162 } finally {
163 Binder.restoreCallingIdentity(token);
164 }
165 }
166
167 /**
James.cf Lincad981c2019-12-10 20:37:56 +0800168 * Register a capability callback which will provide RCS availability updates for the
169 * subscription specified.
170 *
171 * @param subId the subscription ID
172 * @param callback The ImsCapabilityCallback to be registered.
173 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800174 @Override
Brad Ebingera68a4972020-01-30 17:31:23 -0800175 public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800176 enforceReadPrivilegedPermission("registerRcsAvailabilityCallback");
James.cf Lincad981c2019-12-10 20:37:56 +0800177 final long token = Binder.clearCallingIdentity();
178 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800179 getRcsFeatureController(subId).registerRcsAvailabilityCallback(subId, callback);
180 } catch (ImsException e) {
James.cf Lincad981c2019-12-10 20:37:56 +0800181 Log.e(TAG, "registerRcsAvailabilityCallback: sudId=" + subId + ", " + e.getMessage());
182 throw new ServiceSpecificException(e.getCode());
183 } finally {
184 Binder.restoreCallingIdentity(token);
185 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800186 }
187
James.cf Lincad981c2019-12-10 20:37:56 +0800188 /**
189 * Remove the registered capability callback.
190 *
191 * @param subId the subscription ID
192 * @param callback The ImsCapabilityCallback to be removed.
193 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800194 @Override
James.cf Lincad981c2019-12-10 20:37:56 +0800195 public void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800196 enforceReadPrivilegedPermission("unregisterRcsAvailabilityCallback");
James.cf Lincad981c2019-12-10 20:37:56 +0800197 final long token = Binder.clearCallingIdentity();
198 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800199 getRcsFeatureController(subId).unregisterRcsAvailabilityCallback(subId, callback);
James.cf Lincad981c2019-12-10 20:37:56 +0800200 } finally {
201 Binder.restoreCallingIdentity(token);
202 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800203 }
204
James.cf Lincdad3862020-02-25 15:55:03 +0800205 @Override
206 public void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
207 enforceReadPrivilegedPermission("registerUcePublishStateCallback");
208 final long token = Binder.clearCallingIdentity();
209 try {
210 UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
211 UserCapabilityExchangeImpl.class);
212 if (uce == null) {
213 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
214 "This subscription does not support UCE.");
215 }
216 uce.registerPublishStateCallback(c);
217 } finally {
218 Binder.restoreCallingIdentity(token);
219 }
220 }
221
222 @Override
223 public void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
224 enforceReadPrivilegedPermission("unregisterUcePublishStateCallback");
225 final long token = Binder.clearCallingIdentity();
226 try {
227 UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
228 UserCapabilityExchangeImpl.class);
229 if (uce == null) {
230 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
231 "This subscription does not support UCE.");
232 }
233 uce.unregisterUcePublishStateCallback(c);
234 } finally {
235 Binder.restoreCallingIdentity(token);
236 }
237 }
238
James.cf Lincad981c2019-12-10 20:37:56 +0800239 /**
240 * Query for the capability of an IMS RCS service
241 *
242 * @param subId the subscription ID
243 * @param capability the RCS capability to query.
244 * @param radioTech the radio tech that this capability failed for
245 * @return true if the RCS capability is capable for this subscription, false otherwise.
246 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800247 @Override
248 public boolean isCapable(int subId,
James.cf Lincad981c2019-12-10 20:37:56 +0800249 @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
250 @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800251 enforceReadPrivilegedPermission("isCapable");
James.cf Lincad981c2019-12-10 20:37:56 +0800252 final long token = Binder.clearCallingIdentity();
253 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800254 return getRcsFeatureController(subId).isCapable(capability, radioTech);
255 } catch (ImsException e) {
James.cf Lincad981c2019-12-10 20:37:56 +0800256 Log.e(TAG, "isCapable: sudId=" + subId
257 + ", capability=" + capability + ", " + e.getMessage());
258 return false;
259 } finally {
260 Binder.restoreCallingIdentity(token);
261 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800262 }
263
James.cf Lincad981c2019-12-10 20:37:56 +0800264 /**
265 * Query the availability of an IMS RCS capability.
266 *
267 * @param subId the subscription ID
268 * @param capability the RCS capability to query.
269 * @return true if the RCS capability is currently available for the associated subscription,
270 * false otherwise.
271 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800272 @Override
273 public boolean isAvailable(int subId,
274 @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
275 enforceReadPrivilegedPermission("isAvailable");
James.cf Lincad981c2019-12-10 20:37:56 +0800276 final long token = Binder.clearCallingIdentity();
277 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800278 return getRcsFeatureController(subId).isAvailable(capability);
279 } catch (ImsException e) {
James.cf Lincad981c2019-12-10 20:37:56 +0800280 Log.e(TAG, "isAvailable: sudId=" + subId
281 + ", capability=" + capability + ", " + e.getMessage());
282 return false;
283 } finally {
284 Binder.restoreCallingIdentity(token);
285 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800286 }
287
288 @Override
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800289 public void requestCapabilities(int subId, String callingPackage, String callingFeatureId,
290 List<Uri> contactNumbers, IRcsUceControllerCallback c) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800291 enforceReadPrivilegedPermission("requestCapabilities");
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800292 if (!isUceSettingEnabled(subId, callingPackage, callingFeatureId)) {
293 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
294 "The user has not enabled UCE for this subscription.");
295 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800296 final long token = Binder.clearCallingIdentity();
297 try {
298 UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
299 UserCapabilityExchangeImpl.class);
300 if (uce == null) {
301 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
302 "This subscription does not support UCE.");
303 }
304 uce.requestCapabilities(contactNumbers, c);
305 } finally {
306 Binder.restoreCallingIdentity(token);
Brad Ebinger1aa94992020-01-22 14:17:23 -0800307 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800308 }
309
310 @Override
James.cf Lin64e91212020-10-30 01:09:52 +0800311 public void requestNetworkAvailability(int subId, String callingPackage,
312 String callingFeatureId, Uri contactNumber, IRcsUceControllerCallback c) {
313 enforceReadPrivilegedPermission("requestNetworkAvailability");
314 if (!isUceSettingEnabled(subId, callingPackage, callingFeatureId)) {
315 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
316 "The user has not enabled UCE for this subscription.");
317 }
318 // TODO: Implement this method
319 }
320
321 @Override
James.cf Linaf3183c2019-10-24 00:59:00 +0800322 public int getUcePublishState(int subId) {
323 enforceReadPrivilegedPermission("getUcePublishState");
Brad Ebingera68a4972020-01-30 17:31:23 -0800324 final long token = Binder.clearCallingIdentity();
325 try {
326 UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
327 UserCapabilityExchangeImpl.class);
328 if (uce == null) {
329 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
330 "This subscription does not support UCE.");
331 }
332 return uce.getUcePublishState();
333 } finally {
334 Binder.restoreCallingIdentity(token);
Brad Ebinger1aa94992020-01-22 14:17:23 -0800335 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800336 }
337
338 @Override
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800339 public boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId) {
340 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
341 mApp, subId, callingPackage, callingFeatureId, "isUceSettingEnabled")) {
342 Log.w(TAG, "isUceSettingEnabled: READ_PHONE_STATE app op disabled when accessing "
343 + "isUceSettingEnabled");
344 return false;
345 }
346 final long token = Binder.clearCallingIdentity();
347 try {
348 return SubscriptionManager.getBooleanSubscriptionProperty(subId,
349 SubscriptionManager.IMS_RCS_UCE_ENABLED, false /*defaultValue*/, mApp);
350 } finally {
351 Binder.restoreCallingIdentity(token);
352 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800353 }
354
355 @Override
356 public void setUceSettingEnabled(int subId, boolean isEnabled) {
357 enforceModifyPermission();
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800358 final long token = Binder.clearCallingIdentity();
359 try {
360 SubscriptionManager.setSubscriptionProperty(subId,
361 SubscriptionManager.IMS_RCS_UCE_ENABLED, (isEnabled ? "1" : "0"));
362 } finally {
363 Binder.restoreCallingIdentity(token);
364 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800365 }
366
367 /**
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700368 * Registers for updates to the RcsFeature connection through the IImsServiceFeatureCallback
369 * callback.
370 */
371 @Override
Brad Ebinger6366ce92020-10-01 13:51:05 -0700372 public void registerRcsFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700373 enforceModifyPermission();
374
375 final long identity = Binder.clearCallingIdentity();
376 try {
377 if (mImsResolver == null) {
378 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
379 "Device does not support IMS");
380 }
Brad Ebinger6366ce92020-10-01 13:51:05 -0700381 mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_RCS, callback);
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700382 } finally {
383 Binder.restoreCallingIdentity(identity);
384 }
385 }
Brad Ebinger6366ce92020-10-01 13:51:05 -0700386
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700387 /**
388 * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
389 */
390 @Override
391 public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
392 enforceModifyPermission();
393
394 final long identity = Binder.clearCallingIdentity();
395 try {
396 if (mImsResolver == null) return;
397 mImsResolver.unregisterImsFeatureCallback(callback);
398 } finally {
399 Binder.restoreCallingIdentity(identity);
400 }
401 }
402
403 /**
James.cf Linaf3183c2019-10-24 00:59:00 +0800404 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
405 *
406 * @throws SecurityException if the caller does not have the required permission
407 */
408 private void enforceReadPrivilegedPermission(String message) {
409 mApp.enforceCallingOrSelfPermission(
410 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);
411 }
412
413 /**
414 * Make sure the caller has the MODIFY_PHONE_STATE permission.
415 *
416 * @throws SecurityException if the caller does not have the required permission
417 */
418 private void enforceModifyPermission() {
419 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
420 }
James.cf Lincad981c2019-12-10 20:37:56 +0800421
422 /**
James.cf Lindc2d5422019-12-31 14:40:25 +0800423 * Retrieve ImsPhone instance.
James.cf Lincad981c2019-12-10 20:37:56 +0800424 *
425 * @param subId the subscription ID
James.cf Lindc2d5422019-12-31 14:40:25 +0800426 * @return The ImsPhone instance
427 * @throws ServiceSpecificException if getting ImsPhone instance failed.
James.cf Lincad981c2019-12-10 20:37:56 +0800428 */
James.cf Lindc2d5422019-12-31 14:40:25 +0800429 private ImsPhone getImsPhone(int subId) {
430 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
431 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
432 "IMS is not available on device.");
433 }
James.cf Lincad981c2019-12-10 20:37:56 +0800434 Phone phone = PhoneGlobals.getPhone(subId);
435 if (phone == null) {
436 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
437 "Invalid subscription Id: " + subId);
438 }
439 ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
440 if (imsPhone == null) {
James.cf Lindc2d5422019-12-31 14:40:25 +0800441 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
442 "Cannot find ImsPhone instance: " + subId);
443 }
444 return imsPhone;
445 }
446
447 /**
448 * Retrieve RcsFeatureManager instance.
449 *
450 * @param subId the subscription ID
451 * @return The RcsFeatureManager instance
452 * @throws ServiceSpecificException if getting RcsFeatureManager instance failed.
453 */
Brad Ebingera68a4972020-01-30 17:31:23 -0800454 private RcsFeatureController getRcsFeatureController(int subId) {
James.cf Lindc2d5422019-12-31 14:40:25 +0800455 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
James.cf Lincad981c2019-12-10 20:37:56 +0800456 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
James.cf Lindc2d5422019-12-31 14:40:25 +0800457 "IMS is not available on device.");
458 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800459 if (mRcsService == null) {
460 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
461 "IMS is not available on device.");
462 }
James.cf Lindc2d5422019-12-31 14:40:25 +0800463 Phone phone = PhoneGlobals.getPhone(subId);
464 if (phone == null) {
465 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
466 "Invalid subscription Id: " + subId);
467 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800468 int slotId = phone.getPhoneId();
469 RcsFeatureController c = mRcsService.getFeatureController(slotId);
470 if (c == null) {
Brad Ebinger036dc9e2020-02-06 15:49:06 -0800471 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
472 "The requested operation is not supported for subId " + subId);
James.cf Lincad981c2019-12-10 20:37:56 +0800473 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800474 return c;
James.cf Lincad981c2019-12-10 20:37:56 +0800475 }
James.cf Linc9f35a42020-01-15 02:35:22 +0800476
477 void setRcsService(TelephonyRcsService rcsService) {
478 mRcsService = rcsService;
479 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800480}