blob: 701a7593743a92fd65d346282a10484d8508d4b5 [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 Lin051dd252021-01-21 03:30:54 +080019import android.app.ActivityManager;
Brad Ebinger63b6f5a2020-10-27 11:43:35 -070020import android.content.pm.PackageManager;
James.cf Linaf3183c2019-10-24 00:59:00 +080021import android.net.Uri;
James.cf Lincad981c2019-12-10 20:37:56 +080022import android.os.Binder;
23import android.os.RemoteException;
James.cf Lincad981c2019-12-10 20:37:56 +080024import android.os.ServiceSpecificException;
Brad Ebinger63b6f5a2020-10-27 11:43:35 -070025import android.os.UserHandle;
Brad Ebingerb7a866a2020-01-22 17:51:55 -080026import android.telephony.SubscriptionManager;
Peter Wangc035ce42020-01-08 21:00:22 -080027import android.telephony.TelephonyFrameworkInitializer;
Brad Ebingeraf1e9832020-10-14 10:49:28 -070028import android.telephony.ims.DelegateRequest;
James.cf Lincad981c2019-12-10 20:37:56 +080029import android.telephony.ims.ImsException;
James.cf Lin99a360d2020-11-04 10:48:37 +080030import android.telephony.ims.RcsUceAdapter.PublishState;
James.cf Lindc2d5422019-12-31 14:40:25 +080031import android.telephony.ims.RegistrationManager;
James.cf Linaf3183c2019-10-24 00:59:00 +080032import android.telephony.ims.aidl.IImsCapabilityCallback;
33import android.telephony.ims.aidl.IImsRcsController;
James.cf Lindc2d5422019-12-31 14:40:25 +080034import android.telephony.ims.aidl.IImsRegistrationCallback;
James.cf Linaf3183c2019-10-24 00:59:00 +080035import android.telephony.ims.aidl.IRcsUceControllerCallback;
James.cf Lincdad3862020-02-25 15:55:03 +080036import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
Brad Ebingeraf1e9832020-10-14 10:49:28 -070037import android.telephony.ims.aidl.ISipDelegate;
38import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
39import android.telephony.ims.aidl.ISipDelegateMessageCallback;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070040import android.telephony.ims.feature.ImsFeature;
James.cf Linaf3183c2019-10-24 00:59:00 +080041import android.telephony.ims.feature.RcsFeature;
James.cf Lincad981c2019-12-10 20:37:56 +080042import android.telephony.ims.stub.ImsRegistrationImplBase;
James.cf Linaf3183c2019-10-24 00:59:00 +080043import android.util.Log;
44
James.cf Lindc2d5422019-12-31 14:40:25 +080045import com.android.ims.ImsManager;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070046import com.android.ims.internal.IImsServiceFeatureCallback;
James.cf Lindc2d5422019-12-31 14:40:25 +080047import com.android.internal.telephony.IIntegerConsumer;
James.cf Lincad981c2019-12-10 20:37:56 +080048import com.android.internal.telephony.Phone;
Brad Ebinger8b79edc2020-02-27 19:13:24 -080049import com.android.internal.telephony.TelephonyPermissions;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070050import com.android.internal.telephony.ims.ImsResolver;
James.cf Lincad981c2019-12-10 20:37:56 +080051import com.android.internal.telephony.imsphone.ImsPhone;
Brad Ebingera68a4972020-01-30 17:31:23 -080052import com.android.services.telephony.rcs.RcsFeatureController;
Brad Ebingerb989c7c2020-09-23 17:03:48 -070053import com.android.services.telephony.rcs.SipTransportController;
James.cf Linc9f35a42020-01-15 02:35:22 +080054import com.android.services.telephony.rcs.TelephonyRcsService;
James.cf Lin99a360d2020-11-04 10:48:37 +080055import com.android.services.telephony.rcs.UceControllerManager;
James.cf Lincad981c2019-12-10 20:37:56 +080056
James.cf Linaf3183c2019-10-24 00:59:00 +080057import java.util.List;
58
59/**
60 * Implementation of the IImsRcsController interface.
61 */
62public class ImsRcsController extends IImsRcsController.Stub {
63 private static final String TAG = "ImsRcsController";
64
65 /** The singleton instance. */
66 private static ImsRcsController sInstance;
67
68 private PhoneGlobals mApp;
James.cf Linc9f35a42020-01-15 02:35:22 +080069 private TelephonyRcsService mRcsService;
Brad Ebingere3ae65a2020-09-11 12:45:11 -070070 private ImsResolver mImsResolver;
Brad Ebinger49a72b42021-01-29 00:55:24 +000071 // set by shell cmd phone src set-device-enabled true/false
72 private Boolean mSingleRegistrationOverride;
James.cf Linaf3183c2019-10-24 00:59:00 +080073
74 /**
75 * Initialize the singleton ImsRcsController instance.
76 * This is only done once, at startup, from PhoneApp.onCreate().
77 */
78 static ImsRcsController init(PhoneGlobals app) {
79 synchronized (ImsRcsController.class) {
80 if (sInstance == null) {
81 sInstance = new ImsRcsController(app);
82 } else {
83 Log.wtf(TAG, "init() called multiple times! sInstance = " + sInstance);
84 }
85 return sInstance;
86 }
87 }
88
89 /** Private constructor; @see init() */
90 private ImsRcsController(PhoneGlobals app) {
91 Log.i(TAG, "ImsRcsController");
92 mApp = app;
Peter Wangc035ce42020-01-08 21:00:22 -080093 TelephonyFrameworkInitializer
94 .getTelephonyServiceManager().getTelephonyImsServiceRegisterer().register(this);
Brad Ebingere3ae65a2020-09-11 12:45:11 -070095 mImsResolver = mApp.getImsResolver();
James.cf Linaf3183c2019-10-24 00:59:00 +080096 }
97
James.cf Lincad981c2019-12-10 20:37:56 +080098 /**
Brad Ebingera68a4972020-01-30 17:31:23 -080099 * Register a {@link RegistrationManager.RegistrationCallback} to receive IMS network
100 * registration state.
James.cf Lindc2d5422019-12-31 14:40:25 +0800101 */
102 @Override
Brad Ebingera68a4972020-01-30 17:31:23 -0800103 public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
James.cf Linf020d162021-01-31 22:15:52 +0800104 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
105 mApp, subId, "registerImsRegistrationCallback");
James.cf Lindc2d5422019-12-31 14:40:25 +0800106 final long token = Binder.clearCallingIdentity();
107 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800108 getRcsFeatureController(subId).registerImsRegistrationCallback(subId, callback);
109 } catch (ImsException e) {
James.cf Lindc2d5422019-12-31 14:40:25 +0800110 Log.e(TAG, "registerImsRegistrationCallback: sudId=" + subId + ", " + e.getMessage());
111 throw new ServiceSpecificException(e.getCode());
112 } finally {
113 Binder.restoreCallingIdentity(token);
114 }
115 }
116
117 /**
Brad Ebingera68a4972020-01-30 17:31:23 -0800118 * Removes an existing {@link RegistrationManager.RegistrationCallback}.
James.cf Lindc2d5422019-12-31 14:40:25 +0800119 */
120 @Override
121 public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
James.cf Linf020d162021-01-31 22:15:52 +0800122 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
123 mApp, subId, "unregisterImsRegistrationCallback");
James.cf Lindc2d5422019-12-31 14:40:25 +0800124 final long token = Binder.clearCallingIdentity();
125 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800126 getRcsFeatureController(subId).unregisterImsRegistrationCallback(subId, callback);
James.cf Lindc2d5422019-12-31 14:40:25 +0800127 } catch (ServiceSpecificException e) {
128 Log.e(TAG, "unregisterImsRegistrationCallback: error=" + e.errorCode);
129 } finally {
130 Binder.restoreCallingIdentity(token);
131 }
132 }
133
134 /**
135 * Get the IMS service registration state for the RcsFeature associated with this sub id.
136 */
137 @Override
138 public void getImsRcsRegistrationState(int subId, IIntegerConsumer consumer) {
James.cf Linf020d162021-01-31 22:15:52 +0800139 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
140 mApp, subId, "getImsRcsRegistrationState");
James.cf Lindc2d5422019-12-31 14:40:25 +0800141 final long token = Binder.clearCallingIdentity();
142 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800143 getRcsFeatureController(subId).getRegistrationState(regState -> {
James.cf Lindc2d5422019-12-31 14:40:25 +0800144 try {
145 consumer.accept((regState == null)
146 ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
147 } catch (RemoteException e) {
148 Log.w(TAG, "getImsRcsRegistrationState: callback is not available.");
149 }
150 });
151 } finally {
152 Binder.restoreCallingIdentity(token);
153 }
154 }
155
156 /**
157 * Gets the Transport Type associated with the current IMS RCS registration.
158 */
159 @Override
160 public void getImsRcsRegistrationTransportType(int subId, IIntegerConsumer consumer) {
James.cf Linf020d162021-01-31 22:15:52 +0800161 TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
162 mApp, subId, "getImsRcsRegistrationTransportType");
James.cf Lindc2d5422019-12-31 14:40:25 +0800163 final long token = Binder.clearCallingIdentity();
164 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800165 getRcsFeatureController(subId).getRegistrationTech(regTech -> {
James.cf Lindc2d5422019-12-31 14:40:25 +0800166 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
167 int regTechConverted = (regTech == null)
168 ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
169 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
170 regTechConverted);
171 try {
172 consumer.accept(regTechConverted);
173 } catch (RemoteException e) {
174 Log.w(TAG, "getImsRcsRegistrationTransportType: callback is not available.");
175 }
176 });
177 } finally {
178 Binder.restoreCallingIdentity(token);
179 }
180 }
181
182 /**
James.cf Lincad981c2019-12-10 20:37:56 +0800183 * Register a capability callback which will provide RCS availability updates for the
184 * subscription specified.
185 *
186 * @param subId the subscription ID
187 * @param callback The ImsCapabilityCallback to be registered.
188 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800189 @Override
Brad Ebingera68a4972020-01-30 17:31:23 -0800190 public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800191 enforceReadPrivilegedPermission("registerRcsAvailabilityCallback");
James.cf Lincad981c2019-12-10 20:37:56 +0800192 final long token = Binder.clearCallingIdentity();
193 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800194 getRcsFeatureController(subId).registerRcsAvailabilityCallback(subId, callback);
195 } catch (ImsException e) {
James.cf Lincad981c2019-12-10 20:37:56 +0800196 Log.e(TAG, "registerRcsAvailabilityCallback: sudId=" + subId + ", " + e.getMessage());
197 throw new ServiceSpecificException(e.getCode());
198 } finally {
199 Binder.restoreCallingIdentity(token);
200 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800201 }
202
James.cf Lincad981c2019-12-10 20:37:56 +0800203 /**
204 * Remove the registered capability callback.
205 *
206 * @param subId the subscription ID
207 * @param callback The ImsCapabilityCallback to be removed.
208 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800209 @Override
James.cf Lincad981c2019-12-10 20:37:56 +0800210 public void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800211 enforceReadPrivilegedPermission("unregisterRcsAvailabilityCallback");
James.cf Lincad981c2019-12-10 20:37:56 +0800212 final long token = Binder.clearCallingIdentity();
213 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800214 getRcsFeatureController(subId).unregisterRcsAvailabilityCallback(subId, callback);
James.cf Lincad981c2019-12-10 20:37:56 +0800215 } finally {
216 Binder.restoreCallingIdentity(token);
217 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800218 }
219
James.cf Lincad981c2019-12-10 20:37:56 +0800220 /**
221 * Query for the capability of an IMS RCS service
222 *
223 * @param subId the subscription ID
224 * @param capability the RCS capability to query.
James.cf Linf020d162021-01-31 22:15:52 +0800225 * @param radioTech the radio technology type that we are querying.
James.cf Lincad981c2019-12-10 20:37:56 +0800226 * @return true if the RCS capability is capable for this subscription, false otherwise.
227 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800228 @Override
229 public boolean isCapable(int subId,
James.cf Lincad981c2019-12-10 20:37:56 +0800230 @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
231 @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800232 enforceReadPrivilegedPermission("isCapable");
James.cf Lincad981c2019-12-10 20:37:56 +0800233 final long token = Binder.clearCallingIdentity();
234 try {
Brad Ebingera68a4972020-01-30 17:31:23 -0800235 return getRcsFeatureController(subId).isCapable(capability, radioTech);
236 } catch (ImsException e) {
James.cf Lincad981c2019-12-10 20:37:56 +0800237 Log.e(TAG, "isCapable: sudId=" + subId
238 + ", capability=" + capability + ", " + e.getMessage());
239 return false;
240 } finally {
241 Binder.restoreCallingIdentity(token);
242 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800243 }
244
James.cf Lincad981c2019-12-10 20:37:56 +0800245 /**
246 * Query the availability of an IMS RCS capability.
247 *
248 * @param subId the subscription ID
249 * @param capability the RCS capability to query.
250 * @return true if the RCS capability is currently available for the associated subscription,
James.cf Linf020d162021-01-31 22:15:52 +0800251 * @param radioTech the radio technology type that we are querying.
James.cf Lincad981c2019-12-10 20:37:56 +0800252 * false otherwise.
253 */
James.cf Linaf3183c2019-10-24 00:59:00 +0800254 @Override
255 public boolean isAvailable(int subId,
James.cf Linf020d162021-01-31 22:15:52 +0800256 @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
257 @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
James.cf Linaf3183c2019-10-24 00:59:00 +0800258 enforceReadPrivilegedPermission("isAvailable");
James.cf Lincad981c2019-12-10 20:37:56 +0800259 final long token = Binder.clearCallingIdentity();
260 try {
James.cf Linf020d162021-01-31 22:15:52 +0800261 return getRcsFeatureController(subId).isAvailable(capability, radioTech);
Brad Ebingera68a4972020-01-30 17:31:23 -0800262 } catch (ImsException e) {
James.cf Lincad981c2019-12-10 20:37:56 +0800263 Log.e(TAG, "isAvailable: sudId=" + subId
264 + ", capability=" + capability + ", " + e.getMessage());
265 return false;
266 } finally {
267 Binder.restoreCallingIdentity(token);
268 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800269 }
270
271 @Override
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800272 public void requestCapabilities(int subId, String callingPackage, String callingFeatureId,
273 List<Uri> contactNumbers, IRcsUceControllerCallback c) {
James.cf Lin051dd252021-01-21 03:30:54 +0800274 enforceAccessUserCapabilityExchangePermission("requestCapabilities");
275 enforceReadContactsPermission("requestCapabilities");
276 if (!isCallingProcessInForeground(Binder.getCallingUid())) {
277 throw new SecurityException("The caller is not in the foreground.");
278 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800279 final long token = Binder.clearCallingIdentity();
280 try {
James.cf Lin99a360d2020-11-04 10:48:37 +0800281 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
282 UceControllerManager.class);
283 if (uceCtrlManager == null) {
Brad Ebingera68a4972020-01-30 17:31:23 -0800284 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
285 "This subscription does not support UCE.");
286 }
James.cf Lin99a360d2020-11-04 10:48:37 +0800287 uceCtrlManager.requestCapabilities(contactNumbers, c);
288 } catch (ImsException e) {
289 throw new ServiceSpecificException(e.getCode(), e.getMessage());
Brad Ebingera68a4972020-01-30 17:31:23 -0800290 } finally {
291 Binder.restoreCallingIdentity(token);
Brad Ebinger1aa94992020-01-22 14:17:23 -0800292 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800293 }
294
295 @Override
James.cf Linbcdf8b32021-01-14 16:44:13 +0800296 public void requestAvailability(int subId, String callingPackage,
James.cf Lin64e91212020-10-30 01:09:52 +0800297 String callingFeatureId, Uri contactNumber, IRcsUceControllerCallback c) {
James.cf Lin051dd252021-01-21 03:30:54 +0800298 enforceAccessUserCapabilityExchangePermission("requestAvailability");
299 enforceReadContactsPermission("requestAvailability");
300 if (!isCallingProcessInForeground(Binder.getCallingUid())) {
301 throw new SecurityException("The caller is not in the foreground.");
302 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800303 final long token = Binder.clearCallingIdentity();
304 try {
James.cf Lin99a360d2020-11-04 10:48:37 +0800305 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
306 UceControllerManager.class);
307 if (uceCtrlManager == null) {
Brad Ebingera68a4972020-01-30 17:31:23 -0800308 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
309 "This subscription does not support UCE.");
310 }
James.cf Lin99a360d2020-11-04 10:48:37 +0800311 uceCtrlManager.requestNetworkAvailability(contactNumber, c);
312 } catch (ImsException e) {
313 throw new ServiceSpecificException(e.getCode(), e.getMessage());
314 } finally {
315 Binder.restoreCallingIdentity(token);
316 }
317 }
318
319 @Override
320 public @PublishState int getUcePublishState(int subId) {
321 enforceReadPrivilegedPermission("getUcePublishState");
322 final long token = Binder.clearCallingIdentity();
323 try {
324 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
325 UceControllerManager.class);
326 if (uceCtrlManager == null) {
327 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
328 "This subscription does not support UCE.");
329 }
330 return uceCtrlManager.getUcePublishState();
331 } catch (ImsException e) {
332 throw new ServiceSpecificException(e.getCode(), e.getMessage());
333 } finally {
334 Binder.restoreCallingIdentity(token);
335 }
336 }
337
338 @Override
339 public void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
340 enforceReadPrivilegedPermission("registerUcePublishStateCallback");
341 final long token = Binder.clearCallingIdentity();
342 try {
343 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
344 UceControllerManager.class);
345 if (uceCtrlManager == null) {
346 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
347 "This subscription does not support UCE.");
348 }
349 uceCtrlManager.registerPublishStateCallback(c);
350 } catch (ImsException e) {
351 throw new ServiceSpecificException(e.getCode(), e.getMessage());
352 } finally {
353 Binder.restoreCallingIdentity(token);
354 }
355 }
356
357 @Override
358 public void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
359 enforceReadPrivilegedPermission("unregisterUcePublishStateCallback");
360 final long token = Binder.clearCallingIdentity();
361 try {
362 UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
363 UceControllerManager.class);
364 if (uceCtrlManager == null) {
365 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
366 "This subscription does not support UCE.");
367 }
368 uceCtrlManager.unregisterPublishStateCallback(c);
Brad Ebingera68a4972020-01-30 17:31:23 -0800369 } finally {
370 Binder.restoreCallingIdentity(token);
Brad Ebinger1aa94992020-01-22 14:17:23 -0800371 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800372 }
373
374 @Override
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800375 public boolean isUceSettingEnabled(int subId, String callingPackage, String callingFeatureId) {
376 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
377 mApp, subId, callingPackage, callingFeatureId, "isUceSettingEnabled")) {
378 Log.w(TAG, "isUceSettingEnabled: READ_PHONE_STATE app op disabled when accessing "
379 + "isUceSettingEnabled");
380 return false;
381 }
382 final long token = Binder.clearCallingIdentity();
383 try {
384 return SubscriptionManager.getBooleanSubscriptionProperty(subId,
385 SubscriptionManager.IMS_RCS_UCE_ENABLED, false /*defaultValue*/, mApp);
386 } finally {
387 Binder.restoreCallingIdentity(token);
388 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800389 }
390
391 @Override
392 public void setUceSettingEnabled(int subId, boolean isEnabled) {
393 enforceModifyPermission();
Brad Ebinger8b79edc2020-02-27 19:13:24 -0800394 final long token = Binder.clearCallingIdentity();
395 try {
396 SubscriptionManager.setSubscriptionProperty(subId,
397 SubscriptionManager.IMS_RCS_UCE_ENABLED, (isEnabled ? "1" : "0"));
398 } finally {
399 Binder.restoreCallingIdentity(token);
400 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800401 }
402
Brad Ebingerb989c7c2020-09-23 17:03:48 -0700403 @Override
404 public boolean isSipDelegateSupported(int subId) {
405 enforceReadPrivilegedPermission("isSipDelegateSupported");
Brad Ebinger49a72b42021-01-29 00:55:24 +0000406 if (!isImsSingleRegistrationSupportedOnDevice()) {
407 return false;
408 }
Brad Ebingerb989c7c2020-09-23 17:03:48 -0700409 final long token = Binder.clearCallingIdentity();
410 try {
411 SipTransportController transport = getRcsFeatureController(subId).getFeature(
412 SipTransportController.class);
413 if (transport == null) {
414 return false;
415 }
416 return transport.isSupported(subId);
417 } catch (ImsException e) {
418 throw new ServiceSpecificException(e.getCode(), e.getMessage());
419 } catch (ServiceSpecificException e) {
420 if (e.errorCode == ImsException.CODE_ERROR_UNSUPPORTED_OPERATION) {
421 return false;
422 }
423 throw e;
424 } finally {
425 Binder.restoreCallingIdentity(token);
426 }
427 }
428
Brad Ebingeraf1e9832020-10-14 10:49:28 -0700429 @Override
Brad Ebinger63b6f5a2020-10-27 11:43:35 -0700430 public void createSipDelegate(int subId, DelegateRequest request, String packageName,
Brad Ebingeraf1e9832020-10-14 10:49:28 -0700431 ISipDelegateConnectionStateCallback delegateState,
432 ISipDelegateMessageCallback delegateMessage) {
433 enforceModifyPermission();
Brad Ebinger49a72b42021-01-29 00:55:24 +0000434 if (!isImsSingleRegistrationSupportedOnDevice()) {
435 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
436 "SipDelegate creation is only supported for devices supporting IMS single "
437 + "registration");
438 }
Brad Ebinger63b6f5a2020-10-27 11:43:35 -0700439 if (!UserHandle.getUserHandleForUid(Binder.getCallingUid()).isSystem()) {
440 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
441 "SipDelegate creation is only available to primary user.");
442 }
443 try {
444 int remoteUid = mApp.getPackageManager().getPackageUid(packageName, 0 /*flags*/);
445 if (Binder.getCallingUid() != remoteUid) {
446 throw new SecurityException("passed in packageName does not match the caller");
447 }
448 } catch (PackageManager.NameNotFoundException e) {
449 throw new SecurityException("Passed in PackageName can not be found on device");
450 }
Brad Ebingeraf1e9832020-10-14 10:49:28 -0700451
452 final long identity = Binder.clearCallingIdentity();
453 SipTransportController transport = getRcsFeatureController(subId).getFeature(
454 SipTransportController.class);
455 if (transport == null) {
456 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
457 "This subscription does not support the creation of SIP delegates");
458 }
459 try {
Brad Ebinger63b6f5a2020-10-27 11:43:35 -0700460 transport.createSipDelegate(subId, request, packageName, delegateState,
461 delegateMessage);
Brad Ebingeraf1e9832020-10-14 10:49:28 -0700462 } catch (ImsException e) {
463 throw new ServiceSpecificException(e.getCode(), e.getMessage());
464 } finally {
465 Binder.restoreCallingIdentity(identity);
466 }
467 }
468
469 @Override
470 public void destroySipDelegate(int subId, ISipDelegate connection, int reason) {
471 enforceModifyPermission();
472
473 final long identity = Binder.clearCallingIdentity();
474 try {
Brad Ebinger63b6f5a2020-10-27 11:43:35 -0700475 SipTransportController transport = getRcsFeatureController(subId).getFeature(
476 SipTransportController.class);
477 if (transport == null) {
478 return;
479 }
480 transport.destroySipDelegate(subId, connection, reason);
Brad Ebingeraf1e9832020-10-14 10:49:28 -0700481 } finally {
482 Binder.restoreCallingIdentity(identity);
483 }
484 }
485
Brad Ebinger36221382020-12-09 00:33:39 +0000486 @Override
487 public void triggerNetworkRegistration(int subId, ISipDelegate connection, int sipCode,
488 String sipReason) {
489 enforceModifyPermission();
490
491 final long identity = Binder.clearCallingIdentity();
492 try {
493 SipTransportController transport = getRcsFeatureController(subId).getFeature(
494 SipTransportController.class);
495 if (transport == null) {
496 return;
497 }
498 transport.triggerFullNetworkRegistration(subId, connection, sipCode, sipReason);
499 } finally {
500 Binder.restoreCallingIdentity(identity);
501 }
502 }
503
James.cf Linaf3183c2019-10-24 00:59:00 +0800504 /**
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700505 * Registers for updates to the RcsFeature connection through the IImsServiceFeatureCallback
506 * callback.
507 */
508 @Override
Brad Ebinger6366ce92020-10-01 13:51:05 -0700509 public void registerRcsFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700510 enforceModifyPermission();
511
512 final long identity = Binder.clearCallingIdentity();
513 try {
514 if (mImsResolver == null) {
515 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
516 "Device does not support IMS");
517 }
Brad Ebinger6366ce92020-10-01 13:51:05 -0700518 mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_RCS, callback);
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700519 } finally {
520 Binder.restoreCallingIdentity(identity);
521 }
522 }
Brad Ebinger6366ce92020-10-01 13:51:05 -0700523
Brad Ebingere3ae65a2020-09-11 12:45:11 -0700524 /**
525 * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
526 */
527 @Override
528 public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
529 enforceModifyPermission();
530
531 final long identity = Binder.clearCallingIdentity();
532 try {
533 if (mImsResolver == null) return;
534 mImsResolver.unregisterImsFeatureCallback(callback);
535 } finally {
536 Binder.restoreCallingIdentity(identity);
537 }
538 }
539
540 /**
James.cf Linaf3183c2019-10-24 00:59:00 +0800541 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
542 *
543 * @throws SecurityException if the caller does not have the required permission
544 */
545 private void enforceReadPrivilegedPermission(String message) {
546 mApp.enforceCallingOrSelfPermission(
547 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message);
548 }
549
550 /**
551 * Make sure the caller has the MODIFY_PHONE_STATE permission.
552 *
553 * @throws SecurityException if the caller does not have the required permission
554 */
555 private void enforceModifyPermission() {
556 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
557 }
James.cf Lincad981c2019-12-10 20:37:56 +0800558
559 /**
James.cf Lin051dd252021-01-21 03:30:54 +0800560 * Make sure the caller has the ACCESS_RCS_USER_CAPABILITY_EXCHANGE permission.
561 *
562 * @throws SecurityException if the caller does not have the required permission.
563 */
564 private void enforceAccessUserCapabilityExchangePermission(String message) {
565 mApp.enforceCallingOrSelfPermission(
566 android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, message);
567 }
568
569 /**
570 * Make sure the caller has the READ_CONTACTS permission.
571 *
572 * @throws SecurityException if the caller does not have the required permission.
573 */
574 private void enforceReadContactsPermission(String message) {
575 mApp.enforceCallingOrSelfPermission(
576 android.Manifest.permission.READ_CONTACTS, message);
577 }
578
579 /**
580 * Check if the calling process is in the foreground.
581 *
582 * @return true if the caller is in the foreground.
583 */
584 private boolean isCallingProcessInForeground(int uid) {
585 ActivityManager am = mApp.getSystemService(ActivityManager.class);
586 boolean isCallingProcessForeground = am != null
587 && am.getUidImportance(uid)
588 == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
589 return isCallingProcessForeground;
590 }
591
592 /**
James.cf Lindc2d5422019-12-31 14:40:25 +0800593 * Retrieve ImsPhone instance.
James.cf Lincad981c2019-12-10 20:37:56 +0800594 *
595 * @param subId the subscription ID
James.cf Lindc2d5422019-12-31 14:40:25 +0800596 * @return The ImsPhone instance
597 * @throws ServiceSpecificException if getting ImsPhone instance failed.
James.cf Lincad981c2019-12-10 20:37:56 +0800598 */
James.cf Lindc2d5422019-12-31 14:40:25 +0800599 private ImsPhone getImsPhone(int subId) {
600 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
601 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
602 "IMS is not available on device.");
603 }
James.cf Lincad981c2019-12-10 20:37:56 +0800604 Phone phone = PhoneGlobals.getPhone(subId);
605 if (phone == null) {
606 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
607 "Invalid subscription Id: " + subId);
608 }
609 ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
610 if (imsPhone == null) {
James.cf Lindc2d5422019-12-31 14:40:25 +0800611 throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
612 "Cannot find ImsPhone instance: " + subId);
613 }
614 return imsPhone;
615 }
616
617 /**
618 * Retrieve RcsFeatureManager instance.
619 *
620 * @param subId the subscription ID
621 * @return The RcsFeatureManager instance
622 * @throws ServiceSpecificException if getting RcsFeatureManager instance failed.
623 */
Brad Ebingera68a4972020-01-30 17:31:23 -0800624 private RcsFeatureController getRcsFeatureController(int subId) {
James.cf Lindc2d5422019-12-31 14:40:25 +0800625 if (!ImsManager.isImsSupportedOnDevice(mApp)) {
James.cf Lincad981c2019-12-10 20:37:56 +0800626 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
James.cf Lindc2d5422019-12-31 14:40:25 +0800627 "IMS is not available on device.");
628 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800629 if (mRcsService == null) {
630 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
631 "IMS is not available on device.");
632 }
James.cf Lindc2d5422019-12-31 14:40:25 +0800633 Phone phone = PhoneGlobals.getPhone(subId);
634 if (phone == null) {
635 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
636 "Invalid subscription Id: " + subId);
637 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800638 int slotId = phone.getPhoneId();
639 RcsFeatureController c = mRcsService.getFeatureController(slotId);
640 if (c == null) {
Brad Ebinger036dc9e2020-02-06 15:49:06 -0800641 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
642 "The requested operation is not supported for subId " + subId);
James.cf Lincad981c2019-12-10 20:37:56 +0800643 }
Brad Ebingera68a4972020-01-30 17:31:23 -0800644 return c;
James.cf Lincad981c2019-12-10 20:37:56 +0800645 }
James.cf Linc9f35a42020-01-15 02:35:22 +0800646
Brad Ebinger49a72b42021-01-29 00:55:24 +0000647 private boolean isImsSingleRegistrationSupportedOnDevice() {
648 return mSingleRegistrationOverride != null ? mSingleRegistrationOverride
649 : mApp.getPackageManager().hasSystemFeature(
650 PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION);
651 }
652
James.cf Linc9f35a42020-01-15 02:35:22 +0800653 void setRcsService(TelephonyRcsService rcsService) {
654 mRcsService = rcsService;
655 }
Brad Ebinger49a72b42021-01-29 00:55:24 +0000656
657 /**
658 * Override device RCS single registration support check for CTS testing or remove override
659 * if the Boolean is set to null.
660 */
661 void setDeviceSingleRegistrationSupportOverride(Boolean deviceOverrideValue) {
662 mSingleRegistrationOverride = deviceOverrideValue;
663 }
James.cf Linaf3183c2019-10-24 00:59:00 +0800664}