blob: b7116717455ebc70ba92ccb4ad3700abe9765f6c [file] [log] [blame]
Wink Savilleef36ef62014-06-11 08:39:38 -07001/*
2 * Copyright (c) 2013 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.ims;
18
19import android.app.PendingIntent;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.os.IBinder;
24import android.os.IBinder.DeathRecipient;
25import android.os.Message;
26import android.os.Process;
27import android.os.RemoteException;
28import android.os.ServiceManager;
29import android.telephony.Rlog;
30
31import com.android.ims.internal.IImsCallSession;
32import com.android.ims.internal.IImsRegistrationListener;
33import com.android.ims.internal.IImsService;
34import com.android.ims.internal.IImsUt;
35import com.android.ims.internal.ImsCallSession;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -050036import com.android.ims.internal.IImsConfig;
37
Wink Savilleef36ef62014-06-11 08:39:38 -070038
Etan Cohend7727462014-07-12 14:54:10 -070039import java.util.HashMap;
40
Wink Savilleef36ef62014-06-11 08:39:38 -070041/**
42 * Provides APIs for IMS services, such as initiating IMS calls, and provides access to
43 * the operator's IMS network. This class is the starting point for any IMS actions.
44 * You can acquire an instance of it with {@link #getInstance getInstance()}.</p>
45 * <p>The APIs in this class allows you to:</p>
46 *
47 * @hide
48 */
49public class ImsManager {
50 /**
51 * For accessing the IMS related service.
52 * Internal use only.
53 * @hide
54 */
Etan Cohend7727462014-07-12 14:54:10 -070055 private static final String IMS_SERVICE = "ims";
Wink Savilleef36ef62014-06-11 08:39:38 -070056
57 /**
58 * The result code to be sent back with the incoming call {@link PendingIntent}.
59 * @see #open(PendingIntent, ImsConnectionStateListener)
60 */
61 public static final int INCOMING_CALL_RESULT_CODE = 101;
62
63 /**
64 * Key to retrieve the call ID from an incoming call intent.
65 * @see #open(PendingIntent, ImsConnectionStateListener)
66 */
67 public static final String EXTRA_CALL_ID = "android:imsCallID";
68
69 /**
70 * Action to broadcast when ImsService is up.
71 * Internal use only.
72 * @hide
73 */
74 public static final String ACTION_IMS_SERVICE_UP =
75 "com.android.ims.IMS_SERVICE_UP";
76
77 /**
78 * Action to broadcast when ImsService is down.
79 * Internal use only.
80 * @hide
81 */
82 public static final String ACTION_IMS_SERVICE_DOWN =
83 "com.android.ims.IMS_SERVICE_DOWN";
84
85 /**
Etan Cohend7727462014-07-12 14:54:10 -070086 * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
87 * A long value; the subId corresponding to the IMS service coming up or down.
88 * Internal use only.
89 * @hide
90 */
91 public static final String EXTRA_SUBID = "android:subid";
92
93 /**
Wink Savilleef36ef62014-06-11 08:39:38 -070094 * Action for the incoming call intent for the Phone app.
95 * Internal use only.
96 * @hide
97 */
98 public static final String ACTION_IMS_INCOMING_CALL =
99 "com.android.ims.IMS_INCOMING_CALL";
100
101 /**
102 * Part of the ACTION_IMS_INCOMING_CALL intents.
103 * An integer value; service identifier obtained from {@link ImsManager#open}.
104 * Internal use only.
105 * @hide
106 */
107 public static final String EXTRA_SERVICE_ID = "android:imsServiceId";
108
109 /**
110 * Part of the ACTION_IMS_INCOMING_CALL intents.
111 * An boolean value; Flag to indicate that the incoming call is a normal call or call for USSD.
112 * The value "true" indicates that the incoming call is for USSD.
113 * Internal use only.
114 * @hide
115 */
116 public static final String EXTRA_USSD = "android:ussd";
117
118
119
120 private static final String TAG = "ImsManager";
121 private static final boolean DBG = true;
122
Etan Cohend7727462014-07-12 14:54:10 -0700123 private static HashMap<Long, ImsManager> sImsManagerInstances =
124 new HashMap<Long, ImsManager>();
125
Wink Savilleef36ef62014-06-11 08:39:38 -0700126 private Context mContext;
Etan Cohend7727462014-07-12 14:54:10 -0700127 private long mSubId;
Wink Savilleef36ef62014-06-11 08:39:38 -0700128 private IImsService mImsService = null;
129 private ImsServiceDeathRecipient mDeathRecipient = new ImsServiceDeathRecipient();
130 // Ut interface for the supplementary service configuration
131 private ImsUt mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500132 // Interface to get/set ims config items
133 private ImsConfig mConfig = null;
Wink Savilleef36ef62014-06-11 08:39:38 -0700134
135 /**
136 * Gets a manager instance.
137 *
138 * @param context application context for creating the manager object
Etan Cohend7727462014-07-12 14:54:10 -0700139 * @param subId the subscription ID for the IMS Service
140 * @return the manager instance corresponding to the subId
Wink Savilleef36ef62014-06-11 08:39:38 -0700141 */
Etan Cohend7727462014-07-12 14:54:10 -0700142 public static ImsManager getInstance(Context context, long subId) {
143 synchronized (sImsManagerInstances) {
144 if (sImsManagerInstances.containsKey(subId))
145 return sImsManagerInstances.get(subId);
Wink Savilleef36ef62014-06-11 08:39:38 -0700146
Etan Cohend7727462014-07-12 14:54:10 -0700147 ImsManager mgr = new ImsManager(context, subId);
148 sImsManagerInstances.put(subId, mgr);
149
150 return mgr;
151 }
Wink Savilleef36ef62014-06-11 08:39:38 -0700152 }
153
Etan Cohend7727462014-07-12 14:54:10 -0700154 private ImsManager(Context context, long subId) {
Wink Savilleef36ef62014-06-11 08:39:38 -0700155 mContext = context;
Etan Cohend7727462014-07-12 14:54:10 -0700156 mSubId = subId;
Wink Savilleef36ef62014-06-11 08:39:38 -0700157 createImsService(true);
158 }
159
160 /**
161 * Opens the IMS service for making calls and/or receiving generic IMS calls.
162 * The caller may make subsquent calls through {@link #makeCall}.
163 * The IMS service will register the device to the operator's network with the credentials
164 * (from ISIM) periodically in order to receive calls from the operator's network.
165 * When the IMS service receives a new call, it will send out an intent with
166 * the provided action string.
167 * The intent contains a call ID extra {@link getCallId} and it can be used to take a call.
168 *
169 * @param serviceClass a service class specified in {@link ImsServiceClass}
170 * For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
171 * @param incomingCallPendingIntent When an incoming call is received,
172 * the IMS service will call {@link PendingIntent#send(Context, int, Intent)} to
173 * send back the intent to the caller with {@link #INCOMING_CALL_RESULT_CODE}
174 * as the result code and the intent to fill in the call ID; It cannot be null
175 * @param listener To listen to IMS registration events; It cannot be null
176 * @return identifier (greater than 0) for the specified service
177 * @throws NullPointerException if {@code incomingCallPendingIntent}
178 * or {@code listener} is null
179 * @throws ImsException if calling the IMS service results in an error
180 * @see #getCallId
181 * @see #getServiceId
182 */
183 public int open(int serviceClass, PendingIntent incomingCallPendingIntent,
184 ImsConnectionStateListener listener) throws ImsException {
185 checkAndThrowExceptionIfServiceUnavailable();
186
187 if (incomingCallPendingIntent == null) {
188 throw new NullPointerException("incomingCallPendingIntent can't be null");
189 }
190
191 if (listener == null) {
192 throw new NullPointerException("listener can't be null");
193 }
194
195 int result = 0;
196
197 try {
198 result = mImsService.open(serviceClass, incomingCallPendingIntent,
199 createRegistrationListenerProxy(serviceClass, listener));
200 } catch (RemoteException e) {
201 throw new ImsException("open()", e,
202 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
203 }
204
205 if (result <= 0) {
206 // If the return value is a minus value,
207 // it means that an error occurred in the service.
208 // So, it needs to convert to the reason code specified in ImsReasonInfo.
209 throw new ImsException("open()", (result * (-1)));
210 }
211
212 return result;
213 }
214
215 /**
216 * Closes the specified service ({@link ImsServiceClass}) not to make/receive calls.
217 * All the resources that were allocated to the service are also released.
218 *
219 * @param serviceId a service id to be closed which is obtained from {@link ImsManager#open}
220 * @throws ImsException if calling the IMS service results in an error
221 */
222 public void close(int serviceId) throws ImsException {
223 checkAndThrowExceptionIfServiceUnavailable();
224
225 try {
226 mImsService.close(serviceId);
227 } catch (RemoteException e) {
228 throw new ImsException("close()", e,
229 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
230 } finally {
231 mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500232 mConfig = null;
Wink Savilleef36ef62014-06-11 08:39:38 -0700233 }
234 }
235
236 /**
237 * Gets the configuration interface to provision / withdraw the supplementary service settings.
238 *
239 * @param serviceId a service id which is obtained from {@link ImsManager#open}
240 * @return the Ut interface instance
241 * @throws ImsException if getting the Ut interface results in an error
242 */
243 public ImsUtInterface getSupplementaryServiceConfiguration(int serviceId)
244 throws ImsException {
245 // FIXME: manage the multiple Ut interfaces based on the service id
246 if (mUt == null) {
247 checkAndThrowExceptionIfServiceUnavailable();
248
249 try {
250 IImsUt iUt = mImsService.getUtInterface(serviceId);
251
252 if (iUt == null) {
253 throw new ImsException("getSupplementaryServiceConfiguration()",
254 ImsReasonInfo.CODE_UT_NOT_SUPPORTED);
255 }
256
257 mUt = new ImsUt(iUt);
258 } catch (RemoteException e) {
259 throw new ImsException("getSupplementaryServiceConfiguration()", e,
260 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
261 }
262 }
263
264 return mUt;
265 }
266
267 /**
268 * Checks if the IMS service has successfully registered to the IMS network
269 * with the specified service & call type.
270 *
271 * @param serviceId a service id which is obtained from {@link ImsManager#open}
272 * @param serviceType a service type that is specified in {@link ImsCallProfile}
273 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
274 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
275 * @param callType a call type that is specified in {@link ImsCallProfile}
276 * {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO}
277 * {@link ImsCallProfile#CALL_TYPE_VOICE}
278 * {@link ImsCallProfile#CALL_TYPE_VT}
279 * {@link ImsCallProfile#CALL_TYPE_VS}
280 * @return true if the specified service id is connected to the IMS network;
281 * false otherwise
282 * @throws ImsException if calling the IMS service results in an error
283 */
284 public boolean isConnected(int serviceId, int serviceType, int callType)
285 throws ImsException {
286 checkAndThrowExceptionIfServiceUnavailable();
287
288 try {
289 return mImsService.isConnected(serviceId, serviceType, callType);
290 } catch (RemoteException e) {
291 throw new ImsException("isServiceConnected()", e,
292 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
293 }
294 }
295
296 /**
297 * Checks if the specified IMS service is opend.
298 *
299 * @param serviceId a service id which is obtained from {@link ImsManager#open}
300 * @return true if the specified service id is opened; false otherwise
301 * @throws ImsException if calling the IMS service results in an error
302 */
303 public boolean isOpened(int serviceId) throws ImsException {
304 checkAndThrowExceptionIfServiceUnavailable();
305
306 try {
307 return mImsService.isOpened(serviceId);
308 } catch (RemoteException e) {
309 throw new ImsException("isOpened()", e,
310 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
311 }
312 }
313
314 /**
315 * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.
316 *
317 * @param serviceId a service id which is obtained from {@link ImsManager#open}
318 * @param serviceType a service type that is specified in {@link ImsCallProfile}
319 * {@link ImsCallProfile#SERVICE_TYPE_NONE}
320 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL}
321 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
322 * @param callType a call type that is specified in {@link ImsCallProfile}
323 * {@link ImsCallProfile#CALL_TYPE_VOICE}
324 * {@link ImsCallProfile#CALL_TYPE_VT}
325 * {@link ImsCallProfile#CALL_TYPE_VT_TX}
326 * {@link ImsCallProfile#CALL_TYPE_VT_RX}
327 * {@link ImsCallProfile#CALL_TYPE_VT_NODIR}
328 * {@link ImsCallProfile#CALL_TYPE_VS}
329 * {@link ImsCallProfile#CALL_TYPE_VS_TX}
330 * {@link ImsCallProfile#CALL_TYPE_VS_RX}
331 * @return a {@link ImsCallProfile} object
332 * @throws ImsException if calling the IMS service results in an error
333 */
334 public ImsCallProfile createCallProfile(int serviceId,
335 int serviceType, int callType) throws ImsException {
336 checkAndThrowExceptionIfServiceUnavailable();
337
338 try {
339 return mImsService.createCallProfile(serviceId, serviceType, callType);
340 } catch (RemoteException e) {
341 throw new ImsException("createCallProfile()", e,
342 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
343 }
344 }
345
346 /**
347 * Creates a {@link ImsCall} to make a call.
348 *
349 * @param serviceId a service id which is obtained from {@link ImsManager#open}
350 * @param profile a call profile to make the call
351 * (it contains service type, call type, media information, etc.)
352 * @param participants participants to invite the conference call
353 * @param listener listen to the call events from {@link ImsCall}
354 * @return a {@link ImsCall} object
355 * @throws ImsException if calling the IMS service results in an error
356 */
357 public ImsCall makeCall(int serviceId, ImsCallProfile profile, String[] callees,
358 ImsCall.Listener listener) throws ImsException {
359 if (DBG) {
360 log("makeCall :: serviceId=" + serviceId
361 + ", profile=" + profile + ", callees=" + callees);
362 }
363
364 checkAndThrowExceptionIfServiceUnavailable();
365
366 ImsCall call = new ImsCall(mContext, profile);
367
368 call.setListener(listener);
369 ImsCallSession session = createCallSession(serviceId, profile);
370
371 if ((callees != null) && (callees.length == 1)) {
372 call.start(session, callees[0]);
373 } else {
374 call.start(session, callees);
375 }
376
377 return call;
378 }
379
380 /**
381 * Creates a {@link ImsCall} to take an incoming call.
382 *
383 * @param serviceId a service id which is obtained from {@link ImsManager#open}
384 * @param incomingCallIntent the incoming call broadcast intent
385 * @param listener to listen to the call events from {@link ImsCall}
386 * @return a {@link ImsCall} object
387 * @throws ImsException if calling the IMS service results in an error
388 */
389 public ImsCall takeCall(int serviceId, Intent incomingCallIntent,
390 ImsCall.Listener listener) throws ImsException {
391 if (DBG) {
392 log("takeCall :: serviceId=" + serviceId
393 + ", incomingCall=" + incomingCallIntent);
394 }
395
396 checkAndThrowExceptionIfServiceUnavailable();
397
398 if (incomingCallIntent == null) {
399 throw new ImsException("Can't retrieve session with null intent",
400 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
401 }
402
403 int incomingServiceId = getServiceId(incomingCallIntent);
404
405 if (serviceId != incomingServiceId) {
406 throw new ImsException("Service id is mismatched in the incoming call intent",
407 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
408 }
409
410 String callId = getCallId(incomingCallIntent);
411
412 if (callId == null) {
413 throw new ImsException("Call ID missing in the incoming call intent",
414 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
415 }
416
417 try {
418 IImsCallSession session = mImsService.getPendingCallSession(serviceId, callId);
419
420 if (session == null) {
421 throw new ImsException("No pending session for the call",
422 ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL);
423 }
424
425 ImsCall call = new ImsCall(mContext, session.getCallProfile());
426
427 call.attachSession(new ImsCallSession(session));
428 call.setListener(listener);
429
430 return call;
431 } catch (Throwable t) {
432 throw new ImsException("takeCall()", t, ImsReasonInfo.CODE_UNSPECIFIED);
433 }
434 }
435
436 /**
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500437 * Gets the config interface to get/set service/capability parameters.
438 *
439 * @return the ImsConfig instance.
440 * @throws ImsException if getting the setting interface results in an error.
441 */
442 public ImsConfig getConfigInterface() throws ImsException {
443
444 if (mConfig == null) {
445 checkAndThrowExceptionIfServiceUnavailable();
446
447 try {
448 IImsConfig config = mImsService.getConfigInterface();
449 if (config == null) {
450 throw new ImsException("getConfigInterface()",
451 ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
452 }
453 mConfig = new ImsConfig(config);
454 } catch (RemoteException e) {
455 throw new ImsException("getConfigInterface()", e,
456 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
457 }
458 }
459 if (DBG) log("getConfigInterface(), mConfig= " + mConfig);
460 return mConfig;
461 }
462
463 /**
Wink Savilleef36ef62014-06-11 08:39:38 -0700464 * Gets the call ID from the specified incoming call broadcast intent.
465 *
466 * @param incomingCallIntent the incoming call broadcast intent
467 * @return the call ID or null if the intent does not contain it
468 */
469 private static String getCallId(Intent incomingCallIntent) {
470 if (incomingCallIntent == null) {
471 return null;
472 }
473
474 return incomingCallIntent.getStringExtra(EXTRA_CALL_ID);
475 }
476
477 /**
478 * Gets the service type from the specified incoming call broadcast intent.
479 *
480 * @param incomingCallIntent the incoming call broadcast intent
481 * @return the service identifier or -1 if the intent does not contain it
482 */
483 private static int getServiceId(Intent incomingCallIntent) {
484 if (incomingCallIntent == null) {
485 return (-1);
486 }
487
488 return incomingCallIntent.getIntExtra(EXTRA_SERVICE_ID, -1);
489 }
490
491 /**
492 * Binds the IMS service only if the service is not created.
493 */
494 private void checkAndThrowExceptionIfServiceUnavailable()
495 throws ImsException {
496 if (mImsService == null) {
497 createImsService(true);
498
499 if (mImsService == null) {
500 throw new ImsException("Service is unavailable",
501 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
502 }
503 }
504 }
505
Etan Cohend7727462014-07-12 14:54:10 -0700506 private static String getImsServiceName(long subId) {
507 // TODO: MSIM implementation needs to decide on service name as a function of subId
508 // or value derived from subId (slot ID?)
509 return IMS_SERVICE;
510 }
511
Wink Savilleef36ef62014-06-11 08:39:38 -0700512 /**
513 * Binds the IMS service to make/receive the call.
514 */
515 private void createImsService(boolean checkService) {
516 if (checkService) {
Etan Cohend7727462014-07-12 14:54:10 -0700517 IBinder binder = ServiceManager.checkService(getImsServiceName(mSubId));
Wink Savilleef36ef62014-06-11 08:39:38 -0700518
519 if (binder == null) {
520 return;
521 }
522 }
523
Etan Cohend7727462014-07-12 14:54:10 -0700524 IBinder b = ServiceManager.getService(getImsServiceName(mSubId));
Wink Savilleef36ef62014-06-11 08:39:38 -0700525
526 if (b != null) {
527 try {
528 b.linkToDeath(mDeathRecipient, 0);
529 } catch (RemoteException e) {
530 }
531 }
532
533 mImsService = IImsService.Stub.asInterface(b);
534 }
535
536 /**
537 * Creates a {@link ImsCallSession} with the specified call profile.
538 * Use other methods, if applicable, instead of interacting with
539 * {@link ImsCallSession} directly.
540 *
541 * @param serviceId a service id which is obtained from {@link ImsManager#open}
542 * @param profile a call profile to make the call
543 */
544 private ImsCallSession createCallSession(int serviceId,
545 ImsCallProfile profile) throws ImsException {
546 try {
547 return new ImsCallSession(mImsService.createCallSession(serviceId, profile, null));
548 } catch (RemoteException e) {
549 return null;
550 }
551 }
552
553 private ImsRegistrationListenerProxy createRegistrationListenerProxy(int serviceClass,
554 ImsConnectionStateListener listener) {
555 ImsRegistrationListenerProxy proxy =
556 new ImsRegistrationListenerProxy(serviceClass, listener);
557 return proxy;
558 }
559
560 private void log(String s) {
561 Rlog.d(TAG, s);
562 }
563
564 private void loge(String s) {
565 Rlog.e(TAG, s);
566 }
567
568 private void loge(String s, Throwable t) {
569 Rlog.e(TAG, s, t);
570 }
571
572 /**
573 * Death recipient class for monitoring IMS service.
574 */
575 private class ImsServiceDeathRecipient implements IBinder.DeathRecipient {
576 @Override
577 public void binderDied() {
578 mImsService = null;
579 mUt = null;
Libin.Tang@motorola.com076c55d2014-06-23 19:46:36 -0500580 mConfig = null;
Wink Savilleef36ef62014-06-11 08:39:38 -0700581
582 if (mContext != null) {
Etan Cohend7727462014-07-12 14:54:10 -0700583 Intent intent = new Intent(ACTION_IMS_SERVICE_DOWN);
584 intent.putExtra(EXTRA_SUBID, mSubId);
585 mContext.sendBroadcast(new Intent(intent));
Wink Savilleef36ef62014-06-11 08:39:38 -0700586 }
587 }
588 }
589
590 /**
591 * Adapter class for {@link IImsRegistrationListener}.
592 */
593 private class ImsRegistrationListenerProxy extends IImsRegistrationListener.Stub {
594 private int mServiceClass;
595 private ImsConnectionStateListener mListener;
596
597 public ImsRegistrationListenerProxy(int serviceClass,
598 ImsConnectionStateListener listener) {
599 mServiceClass = serviceClass;
600 mListener = listener;
601 }
602
603 public boolean isSameProxy(int serviceClass) {
604 return (mServiceClass == serviceClass);
605 }
606
607 @Override
608 public void registrationConnected() {
609 if (DBG) {
610 log("registrationConnected ::");
611 }
612
613 if (mListener != null) {
614 mListener.onImsConnected();
615 }
616 }
617
618 @Override
619 public void registrationDisconnected() {
620 if (DBG) {
621 log("registrationDisconnected ::");
622 }
623
624 if (mListener != null) {
625 mListener.onImsDisconnected();
626 }
627 }
628
629 @Override
630 public void registrationResumed() {
631 if (DBG) {
632 log("registrationResumed ::");
633 }
634
635 if (mListener != null) {
636 mListener.onImsResumed();
637 }
638 }
639
640 @Override
641 public void registrationSuspended() {
642 if (DBG) {
643 log("registrationSuspended ::");
644 }
645
646 if (mListener != null) {
647 mListener.onImsSuspended();
648 }
649 }
650
651 @Override
652 public void registrationServiceCapabilityChanged(int serviceClass, int event) {
653 log("registrationServiceCapabilityChanged :: serviceClass=" +
654 serviceClass + ", event=" + event);
655
656 if (mListener != null) {
657 mListener.onImsConnected();
658 }
659 }
660 }
661}