blob: 26ac1dc48c4a8763d681b3fe866e95bace491b39 [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;
Brad Ebingeraf1e9832020-10-14 10:49:28 -070025import android.telephony.ims.DelegateRequest;
James.cf Lincad981c2019-12-10 20:37:56 +080026import android.telephony.ims.ImsException;
James.cf Lindc2d5422019-12-31 14:40:25 +080027import android.telephony.ims.RegistrationManager;
James.cf Linaf3183c2019-10-24 00:59:00 +080028import android.telephony.ims.aidl.IImsCapabilityCallback;
29import android.telephony.ims.aidl.IImsRcsController;
James.cf Lindc2d5422019-12-31 14:40:25 +080030import android.telephony.ims.aidl.IImsRegistrationCallback;
James.cf Linaf3183c2019-10-24 00:59:00 +080031import android.telephony.ims.aidl.IRcsUceControllerCallback;
James.cf Lincdad3862020-02-25 15:55:03 +080032import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
Brad Ebingeraf1e9832020-10-14 10:49:28 -070033import android.telephony.ims.aidl.ISipDelegate;
34import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
35import android.telephony.ims.aidl.ISipDelegateMessageCallback;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070036import android.telephony.ims.feature.ImsFeature;
James.cf Linaf3183c2019-10-24 00:59:00 +080037import android.telephony.ims.feature.RcsFeature;
James.cf Lincad981c2019-12-10 20:37:56 +080038import android.telephony.ims.stub.ImsRegistrationImplBase;
James.cf Linaf3183c2019-10-24 00:59:00 +080039import android.util.Log;
40
James.cf Lindc2d5422019-12-31 14:40:25 +080041import com.android.ims.ImsManager;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070042import com.android.ims.internal.IImsServiceFeatureCallback;
James.cf Lindc2d5422019-12-31 14:40:25 +080043import com.android.internal.telephony.IIntegerConsumer;
James.cf Lincad981c2019-12-10 20:37:56 +080044import com.android.internal.telephony.Phone;
Brad Ebinger8b79edc2020-02-27 19:13:24 -080045import com.android.internal.telephony.TelephonyPermissions;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070046import com.android.internal.telephony.ims.ImsResolver;
James.cf Lincad981c2019-12-10 20:37:56 +080047import com.android.internal.telephony.imsphone.ImsPhone;
Brad Ebingera68a4972020-01-30 17:31:23 -080048import com.android.services.telephony.rcs.RcsFeatureController;
Brad Ebingerb989c7c2020-09-23 17:03:48 -070049import com.android.services.telephony.rcs.SipTransportController;
James.cf Linc9f35a42020-01-15 02:35:22 +080050import com.android.services.telephony.rcs.TelephonyRcsService;
Brad Ebingera68a4972020-01-30 17:31:23 -080051import com.android.services.telephony.rcs.UserCapabilityExchangeImpl;
James.cf Lincad981c2019-12-10 20:37:56 +080052
James.cf Linaf3183c2019-10-24 00:59:00 +080053import java.util.List;
54
55/**
56 * Implementation of the IImsRcsController interface.
57 */
58public class ImsRcsController extends IImsRcsController.Stub {
59 private static final String TAG = "ImsRcsController";
60
61 /** The singleton instance. */
62 private static ImsRcsController sInstance;
63
64 private PhoneGlobals mApp;
James.cf Linc9f35a42020-01-15 02:35:22 +080065 private TelephonyRcsService mRcsService;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070066 private ImsResolver mImsResolver;
James.cf Linaf3183c2019-10-24 00:59:00 +080067
68 /**
69 * Initialize the singleton ImsRcsController instance.
70 * This is only done once, at startup, from PhoneApp.onCreate().
71 */
72 static ImsRcsController init(PhoneGlobals app) {
73 synchronized (ImsRcsController.class) {
74 if (sInstance == null) {
75 sInstance = new ImsRcsController(app);
76 } else {
77 Log.wtf(TAG, "init() called multiple times! sInstance = " + sInstance);
78 }
79 return sInstance;
80 }
81 }
82
83 /** Private constructor; @see init() */
84 private ImsRcsController(PhoneGlobals app) {
85 Log.i(TAG, "ImsRcsController");
86 mApp = app;
Peter Wangc035ce42020-01-08 21:00:22 -080087 TelephonyFrameworkInitializer
88 .getTelephonyServiceManager().getTelephonyImsServiceRegisterer().register(this);
Brad Ebingere3ae65a2020-09-11 12:45:11 -070089 mImsResolver = mApp.getImsResolver();
James.cf Linaf3183c2019-10-24 00:59:00 +080090 }
91
James.cf Lincad981c2019-12-10 20:37:56 +080092 /**
Brad Ebingera68a4972020-01-30 17:31:23 -080093 * Register a {@link RegistrationManager.RegistrationCallback} to receive IMS network
94 * registration state.
James.cf Lindc2d5422019-12-31 14:40:25 +080095 */
96 @Override
Brad Ebingera68a4972020-01-30 17:31:23 -080097 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
James.cf Lindc2d5422019-12-31 14:40:25 +080098 enforceReadPrivilegedPermission("registerImsRegistrationCallback");
99 final long token = Binder.clearCallingIdentity();
100 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800101 getRcsFeatureController(subId).registerImsRegistrationCallback(subId, callback);
102 } catch (ImsException e) {
James.cf Lindc2d5422019-12-31 14:40:25 +0800103 Log.e(TAG, "registerImsRegistrationCallback: sudId=" + subId + ", " + e.getMessage());
104 throw new ServiceSpecificException(e.getCode());
105 } finally {
106 Binder.restoreCallingIdentity(token);
107 }
108 }
109
110 /**
Brad Ebingera68a4972020-01-30 17:31:23 -0800111 * Removes an existing {@link RegistrationManager.RegistrationCallback}.
James.cf Lindc2d5422019-12-31 14:40:25 +0800112 */
113 @Override
114 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
115 enforceReadPrivilegedPermission("unregisterImsRegistrationCallback");
116 final long token = Binder.clearCallingIdentity();
117 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800118 getRcsFeatureController(subId).unregisterImsRegistrationCallback(subId, callback);
James.cf Lindc2d5422019-12-31 14:40:25 +0800119 } catch (ServiceSpecificException e) {
120 Log.e(TAG, "unregisterImsRegistrationCallback: error=" + e.errorCode);
121 } finally {
122 Binder.restoreCallingIdentity(token);
123 }
124 }
125
126 /**
127 * Get the IMS service registration state for the RcsFeature associated with this sub id.
128 */
129 @Override
130 public void getImsRcsRegistrationState(int subId, IIntegerConsumer consumer) {
131 enforceReadPrivilegedPermission("getImsRcsRegistrationState");
132 final long token = Binder.clearCallingIdentity();
133 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800134 getRcsFeatureController(subId).getRegistrationState(regState -> {
James.cf Lindc2d5422019-12-31 14:40:25 +0800135 try {
136 consumer.accept((regState == null)
137 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
138 } catch (RemoteException e) {
139 Log.w(TAG, "getImsRcsRegistrationState: callback is not available.");
140 }
141 });
142 } finally {
143 Binder.restoreCallingIdentity(token);
144 }
145 }
146
147 /**
148 * Gets the Transport Type associated with the current IMS RCS registration.
149 */
150 @Override
151 public void getImsRcsRegistrationTransportType(int subId, IIntegerConsumer consumer) {
152 enforceReadPrivilegedPermission("getImsRcsRegistrationTransportType");
153 final long token = Binder.clearCallingIdentity();
154 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800155 getRcsFeatureController(subId).getRegistrationTech(regTech -> {
James.cf Lindc2d5422019-12-31 14:40:25 +0800156 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
157 int regTechConverted = (regTech == null)
158 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
159 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
160 regTechConverted);
161 try {
162 consumer.accept(regTechConverted);
163 } catch (RemoteException e) {
164 Log.w(TAG, "getImsRcsRegistrationTransportType: callback is not available.");
165 }
166 });
167 } finally {
168 Binder.restoreCallingIdentity(token);
169 }
170 }
171
172 /**
James.cf Lincad981c2019-12-10 20:37:56 +0800173 * Register a capability callback which will provide RCS availability updates for the
174 * subscription specified.
175 *
176 * @param subId the subscription ID
177 * @param callback The ImsCapabilityCallback to be registered.
178 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800179 @Override
Brad Ebingera68a4972020-01-30 17:31:23 -0800180 public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800181 enforceReadPrivilegedPermission("registerRcsAvailabilityCallback");
James.cf Lincad981c2019-12-10 20:37:56 +0800182 final long token = Binder.clearCallingIdentity();
183 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800184 getRcsFeatureController(subId).registerRcsAvailabilityCallback(subId, callback);
185 } catch (ImsException e) {
James.cf Lincad981c2019-12-10 20:37:56 +0800186 Log.e(TAG, "registerRcsAvailabilityCallback: sudId=" + subId + ", " + e.getMessage());
187 throw new ServiceSpecificException(e.getCode());
188 } finally {
189 Binder.restoreCallingIdentity(token);
190 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800191 }
192
James.cf Lincad981c2019-12-10 20:37:56 +0800193 /**
194 * Remove the registered capability callback.
195 *
196 * @param subId the subscription ID
197 * @param callback The ImsCapabilityCallback to be removed.
198 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800199 @Override
James.cf Lincad981c2019-12-10 20:37:56 +0800200 public void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800201 enforceReadPrivilegedPermission("unregisterRcsAvailabilityCallback");
James.cf Lincad981c2019-12-10 20:37:56 +0800202 final long token = Binder.clearCallingIdentity();
203 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800204 getRcsFeatureController(subId).unregisterRcsAvailabilityCallback(subId, callback);
James.cf Lincad981c2019-12-10 20:37:56 +0800205 } finally {
206 Binder.restoreCallingIdentity(token);
207 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800208 }
209
James.cf Lincdad3862020-02-25 15:55:03 +0800210 @Override
211 public void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
212 enforceReadPrivilegedPermission("registerUcePublishStateCallback");
213 final long token = Binder.clearCallingIdentity();
214 try {
215 UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
216 UserCapabilityExchangeImpl.class);
217 if (uce == null) {
218 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
219 "This subscription does not support UCE.");
220 }
221 uce.registerPublishStateCallback(c);
222 } finally {
223 Binder.restoreCallingIdentity(token);
224 }
225 }
226
227 @Override
228 public void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
229 enforceReadPrivilegedPermission("unregisterUcePublishStateCallback");
230 final long token = Binder.clearCallingIdentity();
231 try {
232 UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
233 UserCapabilityExchangeImpl.class);
234 if (uce == null) {
235 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
236 "This subscription does not support UCE.");
237 }
238 uce.unregisterUcePublishStateCallback(c);
239 } finally {
240 Binder.restoreCallingIdentity(token);
241 }
242 }
243
James.cf Lincad981c2019-12-10 20:37:56 +0800244 /**
245 * Query for the capability of an IMS RCS service
246 *
247 * @param subId the subscription ID
248 * @param capability the RCS capability to query.
249 * @param radioTech the radio tech that this capability failed for
250 * @return true if the RCS capability is capable for this subscription, false otherwise.
251 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800252 @Override
253 public boolean isCapable(int subId,
James.cf Lincad981c2019-12-10 20:37:56 +0800254 @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
255 @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800256 enforceReadPrivilegedPermission("isCapable");
James.cf Lincad981c2019-12-10 20:37:56 +0800257 final long token = Binder.clearCallingIdentity();
258 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800259 return getRcsFeatureController(subId).isCapable(capability, radioTech);
260 } catch (ImsException e) {
James.cf Lincad981c2019-12-10 20:37:56 +0800261 Log.e(TAG, "isCapable: sudId=" + subId
262 + ", capability=" + capability + ", " + e.getMessage());
263 return false;
264 } finally {
265 Binder.restoreCallingIdentity(token);
266 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800267 }
268
James.cf Lincad981c2019-12-10 20:37:56 +0800269 /**
270 * Query the availability of an IMS RCS capability.
271 *
272 * @param subId the subscription ID
273 * @param capability the RCS capability to query.
274 * @return true if the RCS capability is currently available for the associated subscription,
275 * false otherwise.
276 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800277 @Override
278 public boolean isAvailable(int subId,
279 @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
280 enforceReadPrivilegedPermission("isAvailable");
James.cf Lincad981c2019-12-10 20:37:56 +0800281 final long token = Binder.clearCallingIdentity();
282 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800283 return getRcsFeatureController(subId).isAvailable(capability);
284 } catch (ImsException e) {
James.cf Lincad981c2019-12-10 20:37:56 +0800285 Log.e(TAG, "isAvailable: sudId=" + subId
286 + ", capability=" + capability + ", " + e.getMessage());
287 return false;
288 } finally {
289 Binder.restoreCallingIdentity(token);
290 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800291 }
292
293 @Override
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800294 public void requestCapabilities(int subId, String callingPackage, String callingFeatureId,
295 List<Uri> contactNumbers, IRcsUceControllerCallback c) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800296 enforceReadPrivilegedPermission("requestCapabilities");
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800297 if (!isUceSettingEnabled(subId, callingPackage, callingFeatureId)) {
298 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
299 "The user has not enabled UCE for this subscription.");
300 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800301 final long token = Binder.clearCallingIdentity();
302 try {
303 UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
304 UserCapabilityExchangeImpl.class);
305 if (uce == null) {
306 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
307 "This subscription does not support UCE.");
308 }
309 uce.requestCapabilities(contactNumbers, c);
310 } finally {
311 Binder.restoreCallingIdentity(token);
Brad Ebinger1aa94992020-01-22 14:17:23 -0800312 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800313 }
314
315 @Override
316 public int getUcePublishState(int subId) {
317 enforceReadPrivilegedPermission("getUcePublishState");
Brad Ebingera68a4972020-01-30 17:31:23 -0800318 final long token = Binder.clearCallingIdentity();
319 try {
320 UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
321 UserCapabilityExchangeImpl.class);
322 if (uce == null) {
323 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
324 "This subscription does not support UCE.");
325 }
326 return uce.getUcePublishState();
327 } finally {
328 Binder.restoreCallingIdentity(token);
Brad Ebinger1aa94992020-01-22 14:17:23 -0800329 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800330 }
331
332 @Override
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800333 public boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId) {
334 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
335 mApp, subId, callingPackage, callingFeatureId, "isUceSettingEnabled")) {
336 Log.w(TAG, "isUceSettingEnabled: READ_PHONE_STATE app op disabled when accessing "
337 + "isUceSettingEnabled");
338 return false;
339 }
340 final long token = Binder.clearCallingIdentity();
341 try {
342 return SubscriptionManager.getBooleanSubscriptionProperty(subId,
343 SubscriptionManager.IMS_RCS_UCE_ENABLED, false /*defaultValue*/, mApp);
344 } finally {
345 Binder.restoreCallingIdentity(token);
346 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800347 }
348
349 @Override
350 public void setUceSettingEnabled(int subId, boolean isEnabled) {
351 enforceModifyPermission();
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800352 final long token = Binder.clearCallingIdentity();
353 try {
354 SubscriptionManager.setSubscriptionProperty(subId,
355 SubscriptionManager.IMS_RCS_UCE_ENABLED, (isEnabled ? "1" : "0"));
356 } finally {
357 Binder.restoreCallingIdentity(token);
358 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800359 }
360
Brad Ebingerb989c7c2020-09-23 17:03:48 -0700361 @Override
362 public boolean isSipDelegateSupported(int subId) {
363 enforceReadPrivilegedPermission("isSipDelegateSupported");
364 final long token = Binder.clearCallingIdentity();
365 try {
366 SipTransportController transport = getRcsFeatureController(subId).getFeature(
367 SipTransportController.class);
368 if (transport == null) {
369 return false;
370 }
371 return transport.isSupported(subId);
372 } catch (ImsException e) {
373 throw new ServiceSpecificException(e.getCode(), e.getMessage());
374 } catch (ServiceSpecificException e) {
375 if (e.errorCode == ImsException.CODE_ERROR_UNSUPPORTED_OPERATION) {
376 return false;
377 }
378 throw e;
379 } finally {
380 Binder.restoreCallingIdentity(token);
381 }
382 }
383
Brad Ebingeraf1e9832020-10-14 10:49:28 -0700384 @Override
385 public void createSipDelegate(int subId, DelegateRequest request,
386 ISipDelegateConnectionStateCallback delegateState,
387 ISipDelegateMessageCallback delegateMessage) {
388 enforceModifyPermission();
389
390 final long identity = Binder.clearCallingIdentity();
391 SipTransportController transport = getRcsFeatureController(subId).getFeature(
392 SipTransportController.class);
393 if (transport == null) {
394 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
395 "This subscription does not support the creation of SIP delegates");
396 }
397 try {
398 transport.createSipDelegate(subId, request, delegateState, delegateMessage);
399 } catch (ImsException e) {
400 throw new ServiceSpecificException(e.getCode(), e.getMessage());
401 } finally {
402 Binder.restoreCallingIdentity(identity);
403 }
404 }
405
406 @Override
407 public void destroySipDelegate(int subId, ISipDelegate connection, int reason) {
408 enforceModifyPermission();
409
410 final long identity = Binder.clearCallingIdentity();
411 try {
412 // Do nothing yet, we do not support this API yet.
413 } finally {
414 Binder.restoreCallingIdentity(identity);
415 }
416 }
417
James.cf Linaf3183c2019-10-24 00:59:00 +0800418 /**
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700419 * Registers for updates to the RcsFeature connection through the IImsServiceFeatureCallback
420 * callback.
421 */
422 @Override
Brad Ebinger6366ce92020-10-01 13:51:05 -0700423 public void registerRcsFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700424 enforceModifyPermission();
425
426 final long identity = Binder.clearCallingIdentity();
427 try {
428 if (mImsResolver == null) {
429 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
430 "Device does not support IMS");
431 }
Brad Ebinger6366ce92020-10-01 13:51:05 -0700432 mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_RCS, callback);
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700433 } finally {
434 Binder.restoreCallingIdentity(identity);
435 }
436 }
Brad Ebinger6366ce92020-10-01 13:51:05 -0700437
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700438 /**
439 * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
440 */
441 @Override
442 public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
443 enforceModifyPermission();
444
445 final long identity = Binder.clearCallingIdentity();
446 try {
447 if (mImsResolver == null) return;
448 mImsResolver.unregisterImsFeatureCallback(callback);
449 } finally {
450 Binder.restoreCallingIdentity(identity);
451 }
452 }
453
454 /**
James.cf Linaf3183c2019-10-24 00:59:00 +0800455 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
456 *
457 * @throws SecurityException if the caller does not have the required permission
458 */
459 private void enforceReadPrivilegedPermission(String message) {
460 mApp.enforceCallingOrSelfPermission(
461 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);
462 }
463
464 /**
465 * Make sure the caller has the MODIFY_PHONE_STATE permission.
466 *
467 * @throws SecurityException if the caller does not have the required permission
468 */
469 private void enforceModifyPermission() {
470 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
471 }
James.cf Lincad981c2019-12-10 20:37:56 +0800472
473 /**
James.cf Lindc2d5422019-12-31 14:40:25 +0800474 * Retrieve ImsPhone instance.
James.cf Lincad981c2019-12-10 20:37:56 +0800475 *
476 * @param subId the subscription ID
James.cf Lindc2d5422019-12-31 14:40:25 +0800477 * @return The ImsPhone instance
478 * @throws ServiceSpecificException if getting ImsPhone instance failed.
James.cf Lincad981c2019-12-10 20:37:56 +0800479 */
James.cf Lindc2d5422019-12-31 14:40:25 +0800480 private ImsPhone getImsPhone(int subId) {
481 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
482 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
483 "IMS is not available on device.");
484 }
James.cf Lincad981c2019-12-10 20:37:56 +0800485 Phone phone = PhoneGlobals.getPhone(subId);
486 if (phone == null) {
487 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
488 "Invalid subscription Id: " + subId);
489 }
490 ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
491 if (imsPhone == null) {
James.cf Lindc2d5422019-12-31 14:40:25 +0800492 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
493 "Cannot find ImsPhone instance: " + subId);
494 }
495 return imsPhone;
496 }
497
498 /**
499 * Retrieve RcsFeatureManager instance.
500 *
501 * @param subId the subscription ID
502 * @return The RcsFeatureManager instance
503 * @throws ServiceSpecificException if getting RcsFeatureManager instance failed.
504 */
Brad Ebingera68a4972020-01-30 17:31:23 -0800505 private RcsFeatureController getRcsFeatureController(int subId) {
James.cf Lindc2d5422019-12-31 14:40:25 +0800506 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
James.cf Lincad981c2019-12-10 20:37:56 +0800507 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
James.cf Lindc2d5422019-12-31 14:40:25 +0800508 "IMS is not available on device.");
509 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800510 if (mRcsService == null) {
511 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
512 "IMS is not available on device.");
513 }
James.cf Lindc2d5422019-12-31 14:40:25 +0800514 Phone phone = PhoneGlobals.getPhone(subId);
515 if (phone == null) {
516 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
517 "Invalid subscription Id: " + subId);
518 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800519 int slotId = phone.getPhoneId();
520 RcsFeatureController c = mRcsService.getFeatureController(slotId);
521 if (c == null) {
Brad Ebinger036dc9e2020-02-06 15:49:06 -0800522 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
523 "The requested operation is not supported for subId " + subId);
James.cf Lincad981c2019-12-10 20:37:56 +0800524 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800525 return c;
James.cf Lincad981c2019-12-10 20:37:56 +0800526 }
James.cf Linc9f35a42020-01-15 02:35:22 +0800527
528 void setRcsService(TelephonyRcsService rcsService) {
529 mRcsService = rcsService;
530 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800531}