ImsManager.java revision e229678c0502930303de5dfdb939c0214a67d151
1/* 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.os.IBinder; 23import android.os.IBinder.DeathRecipient; 24import android.os.Message; 25import android.os.Process; 26import android.os.RemoteException; 27import android.os.ServiceManager; 28import android.telephony.Rlog; 29import android.telephony.TelephonyManager; 30 31import com.android.ims.internal.IImsCallSession; 32import com.android.ims.internal.IImsEcbm; 33import com.android.ims.internal.IImsEcbmListener; 34import com.android.ims.internal.IImsRegistrationListener; 35import com.android.ims.internal.IImsService; 36import com.android.ims.internal.IImsUt; 37import com.android.ims.internal.ImsCallSession; 38import com.android.ims.internal.IImsConfig; 39 40import java.util.HashMap; 41 42/** 43 * Provides APIs for IMS services, such as initiating IMS calls, and provides access to 44 * the operator's IMS network. This class is the starting point for any IMS actions. 45 * You can acquire an instance of it with {@link #getInstance getInstance()}.</p> 46 * <p>The APIs in this class allows you to:</p> 47 * 48 * @hide 49 */ 50public class ImsManager { 51 /* 52 * Shared preference constants storing the "Enhanced 4G LTE Mode" configuration 53 */ 54 public static final String IMS_SHARED_PREFERENCES = "IMS_PREFERENCES"; 55 public static final String KEY_IMS_ON = "IMS"; 56 public static final boolean IMS_DEFAULT_SETTING = true; 57 58 /** 59 * For accessing the IMS related service. 60 * Internal use only. 61 * @hide 62 */ 63 private static final String IMS_SERVICE = "ims"; 64 65 /** 66 * The result code to be sent back with the incoming call {@link PendingIntent}. 67 * @see #open(PendingIntent, ImsConnectionStateListener) 68 */ 69 public static final int INCOMING_CALL_RESULT_CODE = 101; 70 71 /** 72 * Key to retrieve the call ID from an incoming call intent. 73 * @see #open(PendingIntent, ImsConnectionStateListener) 74 */ 75 public static final String EXTRA_CALL_ID = "android:imsCallID"; 76 77 /** 78 * Action to broadcast when ImsService is up. 79 * Internal use only. 80 * @hide 81 */ 82 public static final String ACTION_IMS_SERVICE_UP = 83 "com.android.ims.IMS_SERVICE_UP"; 84 85 /** 86 * Action to broadcast when ImsService is down. 87 * Internal use only. 88 * @hide 89 */ 90 public static final String ACTION_IMS_SERVICE_DOWN = 91 "com.android.ims.IMS_SERVICE_DOWN"; 92 93 /** 94 * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents. 95 * A long value; the subId corresponding to the IMS service coming up or down. 96 * Internal use only. 97 * @hide 98 */ 99 public static final String EXTRA_SUBID = "android:subid"; 100 101 /** 102 * Action for the incoming call intent for the Phone app. 103 * Internal use only. 104 * @hide 105 */ 106 public static final String ACTION_IMS_INCOMING_CALL = 107 "com.android.ims.IMS_INCOMING_CALL"; 108 109 /** 110 * Part of the ACTION_IMS_INCOMING_CALL intents. 111 * An integer value; service identifier obtained from {@link ImsManager#open}. 112 * Internal use only. 113 * @hide 114 */ 115 public static final String EXTRA_SERVICE_ID = "android:imsServiceId"; 116 117 /** 118 * Part of the ACTION_IMS_INCOMING_CALL intents. 119 * An boolean value; Flag to indicate that the incoming call is a normal call or call for USSD. 120 * The value "true" indicates that the incoming call is for USSD. 121 * Internal use only. 122 * @hide 123 */ 124 public static final String EXTRA_USSD = "android:ussd"; 125 126 private static final String TAG = "ImsManager"; 127 private static final boolean DBG = true; 128 129 private static HashMap<Long, ImsManager> sImsManagerInstances = 130 new HashMap<Long, ImsManager>(); 131 132 private Context mContext; 133 private long mSubId; 134 private IImsService mImsService = null; 135 private ImsServiceDeathRecipient mDeathRecipient = new ImsServiceDeathRecipient(); 136 // Ut interface for the supplementary service configuration 137 private ImsUt mUt = null; 138 // Interface to get/set ims config items 139 private ImsConfig mConfig = null; 140 141 // ECBM interface 142 private ImsEcbm mEcbm = null; 143 144 /** 145 * Gets a manager instance. 146 * 147 * @param context application context for creating the manager object 148 * @param subId the subscription ID for the IMS Service 149 * @return the manager instance corresponding to the subId 150 */ 151 public static ImsManager getInstance(Context context, long subId) { 152 synchronized (sImsManagerInstances) { 153 if (sImsManagerInstances.containsKey(subId)) 154 return sImsManagerInstances.get(subId); 155 156 ImsManager mgr = new ImsManager(context, subId); 157 sImsManagerInstances.put(subId, mgr); 158 159 return mgr; 160 } 161 } 162 163 /** 164 * Returns the user configuration of Enhanced 4G LTE Mode setting 165 */ 166 public static boolean isEnhanced4gLteModeSettingEnabledByUser(Context context) { 167 return context.getSharedPreferences(IMS_SHARED_PREFERENCES, 168 Context.MODE_WORLD_READABLE).getBoolean(KEY_IMS_ON, 169 IMS_DEFAULT_SETTING); 170 } 171 172 /** 173 * Returns a platform configuration which may override the user setting. 174 */ 175 public static boolean isEnhanced4gLteModeSettingEnabledByPlatform(Context context) { 176 return context.getResources().getBoolean( 177 com.android.internal.R.bool.config_mobile_allow_volte_vt); 178 } 179 180 private ImsManager(Context context, long subId) { 181 mContext = context; 182 mSubId = subId; 183 createImsService(true); 184 } 185 186 /** 187 * Opens the IMS service for making calls and/or receiving generic IMS calls. 188 * The caller may make subsquent calls through {@link #makeCall}. 189 * The IMS service will register the device to the operator's network with the credentials 190 * (from ISIM) periodically in order to receive calls from the operator's network. 191 * When the IMS service receives a new call, it will send out an intent with 192 * the provided action string. 193 * The intent contains a call ID extra {@link getCallId} and it can be used to take a call. 194 * 195 * @param serviceClass a service class specified in {@link ImsServiceClass} 196 * For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}. 197 * @param incomingCallPendingIntent When an incoming call is received, 198 * the IMS service will call {@link PendingIntent#send(Context, int, Intent)} to 199 * send back the intent to the caller with {@link #INCOMING_CALL_RESULT_CODE} 200 * as the result code and the intent to fill in the call ID; It cannot be null 201 * @param listener To listen to IMS registration events; It cannot be null 202 * @return identifier (greater than 0) for the specified service 203 * @throws NullPointerException if {@code incomingCallPendingIntent} 204 * or {@code listener} is null 205 * @throws ImsException if calling the IMS service results in an error 206 * @see #getCallId 207 * @see #getServiceId 208 */ 209 public int open(int serviceClass, PendingIntent incomingCallPendingIntent, 210 ImsConnectionStateListener listener) throws ImsException { 211 checkAndThrowExceptionIfServiceUnavailable(); 212 213 if (incomingCallPendingIntent == null) { 214 throw new NullPointerException("incomingCallPendingIntent can't be null"); 215 } 216 217 if (listener == null) { 218 throw new NullPointerException("listener can't be null"); 219 } 220 221 int result = 0; 222 223 try { 224 result = mImsService.open(serviceClass, incomingCallPendingIntent, 225 createRegistrationListenerProxy(serviceClass, listener)); 226 } catch (RemoteException e) { 227 throw new ImsException("open()", e, 228 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 229 } 230 231 if (result <= 0) { 232 // If the return value is a minus value, 233 // it means that an error occurred in the service. 234 // So, it needs to convert to the reason code specified in ImsReasonInfo. 235 throw new ImsException("open()", (result * (-1))); 236 } 237 238 return result; 239 } 240 241 /** 242 * Closes the specified service ({@link ImsServiceClass}) not to make/receive calls. 243 * All the resources that were allocated to the service are also released. 244 * 245 * @param serviceId a service id to be closed which is obtained from {@link ImsManager#open} 246 * @throws ImsException if calling the IMS service results in an error 247 */ 248 public void close(int serviceId) throws ImsException { 249 checkAndThrowExceptionIfServiceUnavailable(); 250 251 try { 252 mImsService.close(serviceId); 253 } catch (RemoteException e) { 254 throw new ImsException("close()", e, 255 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 256 } finally { 257 mUt = null; 258 mConfig = null; 259 mEcbm = null; 260 } 261 } 262 263 /** 264 * Gets the configuration interface to provision / withdraw the supplementary service settings. 265 * 266 * @param serviceId a service id which is obtained from {@link ImsManager#open} 267 * @return the Ut interface instance 268 * @throws ImsException if getting the Ut interface results in an error 269 */ 270 public ImsUtInterface getSupplementaryServiceConfiguration(int serviceId) 271 throws ImsException { 272 // FIXME: manage the multiple Ut interfaces based on the service id 273 if (mUt == null) { 274 checkAndThrowExceptionIfServiceUnavailable(); 275 276 try { 277 IImsUt iUt = mImsService.getUtInterface(serviceId); 278 279 if (iUt == null) { 280 throw new ImsException("getSupplementaryServiceConfiguration()", 281 ImsReasonInfo.CODE_UT_NOT_SUPPORTED); 282 } 283 284 mUt = new ImsUt(iUt); 285 } catch (RemoteException e) { 286 throw new ImsException("getSupplementaryServiceConfiguration()", e, 287 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 288 } 289 } 290 291 return mUt; 292 } 293 294 /** 295 * Checks if the IMS service has successfully registered to the IMS network 296 * with the specified service & call type. 297 * 298 * @param serviceId a service id which is obtained from {@link ImsManager#open} 299 * @param serviceType a service type that is specified in {@link ImsCallProfile} 300 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL} 301 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY} 302 * @param callType a call type that is specified in {@link ImsCallProfile} 303 * {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO} 304 * {@link ImsCallProfile#CALL_TYPE_VOICE} 305 * {@link ImsCallProfile#CALL_TYPE_VT} 306 * {@link ImsCallProfile#CALL_TYPE_VS} 307 * @return true if the specified service id is connected to the IMS network; 308 * false otherwise 309 * @throws ImsException if calling the IMS service results in an error 310 */ 311 public boolean isConnected(int serviceId, int serviceType, int callType) 312 throws ImsException { 313 checkAndThrowExceptionIfServiceUnavailable(); 314 315 try { 316 return mImsService.isConnected(serviceId, serviceType, callType); 317 } catch (RemoteException e) { 318 throw new ImsException("isServiceConnected()", e, 319 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 320 } 321 } 322 323 /** 324 * Checks if the specified IMS service is opend. 325 * 326 * @param serviceId a service id which is obtained from {@link ImsManager#open} 327 * @return true if the specified service id is opened; false otherwise 328 * @throws ImsException if calling the IMS service results in an error 329 */ 330 public boolean isOpened(int serviceId) throws ImsException { 331 checkAndThrowExceptionIfServiceUnavailable(); 332 333 try { 334 return mImsService.isOpened(serviceId); 335 } catch (RemoteException e) { 336 throw new ImsException("isOpened()", e, 337 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 338 } 339 } 340 341 /** 342 * Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state. 343 * 344 * @param serviceId a service id which is obtained from {@link ImsManager#open} 345 * @param serviceType a service type that is specified in {@link ImsCallProfile} 346 * {@link ImsCallProfile#SERVICE_TYPE_NONE} 347 * {@link ImsCallProfile#SERVICE_TYPE_NORMAL} 348 * {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY} 349 * @param callType a call type that is specified in {@link ImsCallProfile} 350 * {@link ImsCallProfile#CALL_TYPE_VOICE} 351 * {@link ImsCallProfile#CALL_TYPE_VT} 352 * {@link ImsCallProfile#CALL_TYPE_VT_TX} 353 * {@link ImsCallProfile#CALL_TYPE_VT_RX} 354 * {@link ImsCallProfile#CALL_TYPE_VT_NODIR} 355 * {@link ImsCallProfile#CALL_TYPE_VS} 356 * {@link ImsCallProfile#CALL_TYPE_VS_TX} 357 * {@link ImsCallProfile#CALL_TYPE_VS_RX} 358 * @return a {@link ImsCallProfile} object 359 * @throws ImsException if calling the IMS service results in an error 360 */ 361 public ImsCallProfile createCallProfile(int serviceId, 362 int serviceType, int callType) throws ImsException { 363 checkAndThrowExceptionIfServiceUnavailable(); 364 365 try { 366 return mImsService.createCallProfile(serviceId, serviceType, callType); 367 } catch (RemoteException e) { 368 throw new ImsException("createCallProfile()", e, 369 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 370 } 371 } 372 373 /** 374 * Creates a {@link ImsCall} to make a call. 375 * 376 * @param serviceId a service id which is obtained from {@link ImsManager#open} 377 * @param profile a call profile to make the call 378 * (it contains service type, call type, media information, etc.) 379 * @param participants participants to invite the conference call 380 * @param listener listen to the call events from {@link ImsCall} 381 * @return a {@link ImsCall} object 382 * @throws ImsException if calling the IMS service results in an error 383 */ 384 public ImsCall makeCall(int serviceId, ImsCallProfile profile, String[] callees, 385 ImsCall.Listener listener) throws ImsException { 386 if (DBG) { 387 log("makeCall :: serviceId=" + serviceId 388 + ", profile=" + profile + ", callees=" + callees); 389 } 390 391 checkAndThrowExceptionIfServiceUnavailable(); 392 393 ImsCall call = new ImsCall(mContext, profile); 394 395 call.setListener(listener); 396 ImsCallSession session = createCallSession(serviceId, profile); 397 398 if ((callees != null) && (callees.length == 1)) { 399 call.start(session, callees[0]); 400 } else { 401 call.start(session, callees); 402 } 403 404 return call; 405 } 406 407 /** 408 * Creates a {@link ImsCall} to take an incoming call. 409 * 410 * @param serviceId a service id which is obtained from {@link ImsManager#open} 411 * @param incomingCallIntent the incoming call broadcast intent 412 * @param listener to listen to the call events from {@link ImsCall} 413 * @return a {@link ImsCall} object 414 * @throws ImsException if calling the IMS service results in an error 415 */ 416 public ImsCall takeCall(int serviceId, Intent incomingCallIntent, 417 ImsCall.Listener listener) throws ImsException { 418 if (DBG) { 419 log("takeCall :: serviceId=" + serviceId 420 + ", incomingCall=" + incomingCallIntent); 421 } 422 423 checkAndThrowExceptionIfServiceUnavailable(); 424 425 if (incomingCallIntent == null) { 426 throw new ImsException("Can't retrieve session with null intent", 427 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT); 428 } 429 430 int incomingServiceId = getServiceId(incomingCallIntent); 431 432 if (serviceId != incomingServiceId) { 433 throw new ImsException("Service id is mismatched in the incoming call intent", 434 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT); 435 } 436 437 String callId = getCallId(incomingCallIntent); 438 439 if (callId == null) { 440 throw new ImsException("Call ID missing in the incoming call intent", 441 ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT); 442 } 443 444 try { 445 IImsCallSession session = mImsService.getPendingCallSession(serviceId, callId); 446 447 if (session == null) { 448 throw new ImsException("No pending session for the call", 449 ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL); 450 } 451 452 ImsCall call = new ImsCall(mContext, session.getCallProfile()); 453 454 call.attachSession(new ImsCallSession(session)); 455 call.setListener(listener); 456 457 return call; 458 } catch (Throwable t) { 459 throw new ImsException("takeCall()", t, ImsReasonInfo.CODE_UNSPECIFIED); 460 } 461 } 462 463 /** 464 * Gets the config interface to get/set service/capability parameters. 465 * 466 * @return the ImsConfig instance. 467 * @throws ImsException if getting the setting interface results in an error. 468 */ 469 public ImsConfig getConfigInterface() throws ImsException { 470 471 if (mConfig == null) { 472 checkAndThrowExceptionIfServiceUnavailable(); 473 474 try { 475 IImsConfig config = mImsService.getConfigInterface(); 476 if (config == null) { 477 throw new ImsException("getConfigInterface()", 478 ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE); 479 } 480 mConfig = new ImsConfig(config); 481 } catch (RemoteException e) { 482 throw new ImsException("getConfigInterface()", e, 483 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 484 } 485 } 486 if (DBG) log("getConfigInterface(), mConfig= " + mConfig); 487 return mConfig; 488 } 489 490 /** 491 * Gets the call ID from the specified incoming call broadcast intent. 492 * 493 * @param incomingCallIntent the incoming call broadcast intent 494 * @return the call ID or null if the intent does not contain it 495 */ 496 private static String getCallId(Intent incomingCallIntent) { 497 if (incomingCallIntent == null) { 498 return null; 499 } 500 501 return incomingCallIntent.getStringExtra(EXTRA_CALL_ID); 502 } 503 504 /** 505 * Gets the service type from the specified incoming call broadcast intent. 506 * 507 * @param incomingCallIntent the incoming call broadcast intent 508 * @return the service identifier or -1 if the intent does not contain it 509 */ 510 private static int getServiceId(Intent incomingCallIntent) { 511 if (incomingCallIntent == null) { 512 return (-1); 513 } 514 515 return incomingCallIntent.getIntExtra(EXTRA_SERVICE_ID, -1); 516 } 517 518 /** 519 * Binds the IMS service only if the service is not created. 520 */ 521 private void checkAndThrowExceptionIfServiceUnavailable() 522 throws ImsException { 523 if (mImsService == null) { 524 createImsService(true); 525 526 if (mImsService == null) { 527 throw new ImsException("Service is unavailable", 528 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 529 } 530 } 531 } 532 533 private static String getImsServiceName(long subId) { 534 // TODO: MSIM implementation needs to decide on service name as a function of subId 535 // or value derived from subId (slot ID?) 536 return IMS_SERVICE; 537 } 538 539 /** 540 * Binds the IMS service to make/receive the call. 541 */ 542 private void createImsService(boolean checkService) { 543 if (checkService) { 544 IBinder binder = ServiceManager.checkService(getImsServiceName(mSubId)); 545 546 if (binder == null) { 547 return; 548 } 549 } 550 551 IBinder b = ServiceManager.getService(getImsServiceName(mSubId)); 552 553 if (b != null) { 554 try { 555 b.linkToDeath(mDeathRecipient, 0); 556 } catch (RemoteException e) { 557 } 558 } 559 560 mImsService = IImsService.Stub.asInterface(b); 561 } 562 563 /** 564 * Creates a {@link ImsCallSession} with the specified call profile. 565 * Use other methods, if applicable, instead of interacting with 566 * {@link ImsCallSession} directly. 567 * 568 * @param serviceId a service id which is obtained from {@link ImsManager#open} 569 * @param profile a call profile to make the call 570 */ 571 private ImsCallSession createCallSession(int serviceId, 572 ImsCallProfile profile) throws ImsException { 573 try { 574 return new ImsCallSession(mImsService.createCallSession(serviceId, profile, null)); 575 } catch (RemoteException e) { 576 return null; 577 } 578 } 579 580 private ImsRegistrationListenerProxy createRegistrationListenerProxy(int serviceClass, 581 ImsConnectionStateListener listener) { 582 ImsRegistrationListenerProxy proxy = 583 new ImsRegistrationListenerProxy(serviceClass, listener); 584 return proxy; 585 } 586 587 private void log(String s) { 588 Rlog.d(TAG, s); 589 } 590 591 private void loge(String s) { 592 Rlog.e(TAG, s); 593 } 594 595 private void loge(String s, Throwable t) { 596 Rlog.e(TAG, s, t); 597 } 598 599 /** 600 * Used for turning on IMS.if its off already 601 */ 602 public void turnOnIms() throws ImsException { 603 checkAndThrowExceptionIfServiceUnavailable(); 604 605 try { 606 mImsService.turnOnIms(); 607 } catch (RemoteException e) { 608 throw new ImsException("turnOnIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 609 } 610 } 611 612 public void setAdvanced4GMode(boolean turnOn) throws ImsException { 613 checkAndThrowExceptionIfServiceUnavailable(); 614 615 ImsConfig config = getConfigInterface(); 616 if (config != null) { 617 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE, 618 TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, null); 619 config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE, 620 TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, null); 621 } 622 623 if (turnOn) { 624 turnOnIms(); 625 } else if (mContext.getResources().getBoolean( 626 com.android.internal.R.bool.imsServiceAllowTurnOff)) { 627 log("setAdvanced4GMode() : imsServiceAllowTurnOff -> turnOffIms"); 628 turnOffIms(); 629 } 630 } 631 632 /** 633 * Used for turning off IMS completely in order to make the device CSFB'ed. 634 * Once turned off, all calls will be over CS. 635 */ 636 public void turnOffIms() throws ImsException { 637 checkAndThrowExceptionIfServiceUnavailable(); 638 639 try { 640 mImsService.turnOffIms(); 641 } catch (RemoteException e) { 642 throw new ImsException("turnOffIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 643 } 644 } 645 646 /** 647 * Death recipient class for monitoring IMS service. 648 */ 649 private class ImsServiceDeathRecipient implements IBinder.DeathRecipient { 650 @Override 651 public void binderDied() { 652 mImsService = null; 653 mUt = null; 654 mConfig = null; 655 mEcbm = null; 656 657 if (mContext != null) { 658 Intent intent = new Intent(ACTION_IMS_SERVICE_DOWN); 659 intent.putExtra(EXTRA_SUBID, mSubId); 660 mContext.sendBroadcast(new Intent(intent)); 661 } 662 } 663 } 664 665 /** 666 * Adapter class for {@link IImsRegistrationListener}. 667 */ 668 private class ImsRegistrationListenerProxy extends IImsRegistrationListener.Stub { 669 private int mServiceClass; 670 private ImsConnectionStateListener mListener; 671 672 public ImsRegistrationListenerProxy(int serviceClass, 673 ImsConnectionStateListener listener) { 674 mServiceClass = serviceClass; 675 mListener = listener; 676 } 677 678 public boolean isSameProxy(int serviceClass) { 679 return (mServiceClass == serviceClass); 680 } 681 682 @Override 683 public void registrationConnected() { 684 if (DBG) { 685 log("registrationConnected ::"); 686 } 687 688 if (mListener != null) { 689 mListener.onImsConnected(); 690 } 691 } 692 693 @Override 694 public void registrationDisconnected() { 695 if (DBG) { 696 log("registrationDisconnected ::"); 697 } 698 699 if (mListener != null) { 700 mListener.onImsDisconnected(); 701 } 702 } 703 704 @Override 705 public void registrationResumed() { 706 if (DBG) { 707 log("registrationResumed ::"); 708 } 709 710 if (mListener != null) { 711 mListener.onImsResumed(); 712 } 713 } 714 715 @Override 716 public void registrationSuspended() { 717 if (DBG) { 718 log("registrationSuspended ::"); 719 } 720 721 if (mListener != null) { 722 mListener.onImsSuspended(); 723 } 724 } 725 726 @Override 727 public void registrationServiceCapabilityChanged(int serviceClass, int event) { 728 log("registrationServiceCapabilityChanged :: serviceClass=" + 729 serviceClass + ", event=" + event); 730 731 if (mListener != null) { 732 mListener.onImsConnected(); 733 } 734 } 735 736 @Override 737 public void registrationFeatureCapabilityChanged(int serviceClass, 738 int[] enabledFeatures, int[] disabledFeatures) { 739 log("registrationFeatureCapabilityChanged :: serviceClass=" + 740 serviceClass); 741 if (mListener != null) { 742 mListener.onFeatureCapabilityChanged(serviceClass, 743 enabledFeatures, disabledFeatures); 744 } 745 } 746 747 } 748 /** 749 * Gets the ECBM interface to request ECBM exit. 750 * 751 * @param serviceId a service id which is obtained from {@link ImsManager#open} 752 * @return the ECBM interface instance 753 * @throws ImsException if getting the ECBM interface results in an error 754 */ 755 public ImsEcbm getEcbmInterface(int serviceId) throws ImsException { 756 if (mEcbm == null) { 757 checkAndThrowExceptionIfServiceUnavailable(); 758 759 try { 760 IImsEcbm iEcbm = mImsService.getEcbmInterface(serviceId); 761 762 if (iEcbm == null) { 763 throw new ImsException("getEcbmInterface()", 764 ImsReasonInfo.CODE_ECBM_NOT_SUPPORTED); 765 } 766 mEcbm = new ImsEcbm(iEcbm); 767 } catch (RemoteException e) { 768 throw new ImsException("getEcbmInterface()", e, 769 ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN); 770 } 771 } 772 return mEcbm; 773 } 774} 775