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 17 package com.android.ims; 18 19 import android.content.res.Resources; 20 import android.os.AsyncResult; 21 import android.os.Bundle; 22 import android.os.Handler; 23 import android.os.Message; 24 import android.os.Registrant; 25 import android.os.RemoteException; 26 import android.telephony.ims.ImsCallForwardInfo; 27 import android.telephony.ims.ImsReasonInfo; 28 import android.telephony.ims.ImsSsData; 29 import android.telephony.ims.ImsSsInfo; 30 import android.telephony.ims.ImsUtListener; 31 32 import com.android.ims.internal.IImsUt; 33 import com.android.ims.internal.IImsUtListener; 34 import com.android.internal.annotations.VisibleForTesting; 35 import com.android.telephony.Rlog; 36 import com.android.internal.telephony.util.TelephonyUtils; 37 38 import java.util.HashMap; 39 import java.util.Map; 40 import java.util.concurrent.Executor; 41 42 /** 43 * Provides APIs for the supplementary service settings using IMS (Ut interface). 44 * It is created from 3GPP TS 24.623 (XCAP(XML Configuration Access Protocol) 45 * over the Ut interface for manipulating supplementary services). 46 * 47 * @hide 48 */ 49 public class ImsUt implements ImsUtInterface { 50 /** 51 * Key string for an additional supplementary service configurations. 52 */ 53 /** 54 * Actions : string format of ImsUtInterface#ACTION_xxx 55 * "0" (deactivation), "1" (activation), "2" (not_used), 56 * "3" (registration), "4" (erasure), "5" (Interrogation) 57 */ 58 public static final String KEY_ACTION = "action"; 59 /** 60 * Categories : 61 * "OIP", "OIR", "TIP", "TIR", "CDIV", "CB", "CW", "CONF", 62 * "ACR", "MCID", "ECT", "CCBS", "AOC", "MWI", "FA", "CAT" 63 * 64 * Detailed parameter name will be determined according to the properties 65 * of the supplementary service configuration. 66 */ 67 public static final String KEY_CATEGORY = "category"; 68 public static final String CATEGORY_OIP = "OIP"; 69 public static final String CATEGORY_OIR = "OIR"; 70 public static final String CATEGORY_TIP = "TIP"; 71 public static final String CATEGORY_TIR = "TIR"; 72 public static final String CATEGORY_CDIV = "CDIV"; 73 public static final String CATEGORY_CB = "CB"; 74 public static final String CATEGORY_CW = "CW"; 75 public static final String CATEGORY_CONF = "CONF"; 76 77 private static final String TAG = "ImsUt"; 78 private static final boolean DBG = true; 79 80 //These service class values are same as the one in CommandsInterface.java 81 private static final int SERVICE_CLASS_NONE = 0; 82 private static final int SERVICE_CLASS_VOICE = (1 << 0); 83 84 // For synchronization of private variables 85 private Object mLockObj = new Object(); 86 private final IImsUt miUt; 87 private HashMap<Integer, Message> mPendingCmds = 88 new HashMap<Integer, Message>(); 89 private Registrant mSsIndicationRegistrant; 90 private Executor mExecutor = Runnable::run; 91 ImsUt(IImsUt iUt, Executor executor)92 public ImsUt(IImsUt iUt, Executor executor) { 93 miUt = iUt; 94 if (executor != null) { 95 mExecutor = executor; 96 } 97 98 if (miUt != null) { 99 try { 100 miUt.setListener(new IImsUtListenerProxy()); 101 } catch (RemoteException e) { 102 } 103 } 104 } 105 close()106 public void close() { 107 synchronized(mLockObj) { 108 if (miUt != null) { 109 try { 110 miUt.close(); 111 } catch (RemoteException e) { 112 } 113 } 114 115 if (!mPendingCmds.isEmpty()) { 116 Map.Entry<Integer, Message>[] entries = 117 mPendingCmds.entrySet().toArray(new Map.Entry[mPendingCmds.size()]); 118 119 for (Map.Entry<Integer, Message> entry : entries) { 120 sendFailureReport(entry.getValue(), 121 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 122 } 123 124 mPendingCmds.clear(); 125 } 126 } 127 } 128 129 /** 130 * Registers a handler for Supplementary Service Indications. The 131 * result is returned in the {@link AsyncResult#result) field 132 * of the {@link AsyncResult} object returned by {@link Message.obj}. 133 * Value of ((AsyncResult)result.obj) is of {@link ImsSsData}. 134 */ registerForSuppServiceIndication(Handler h, int what, Object obj)135 public void registerForSuppServiceIndication(Handler h, int what, Object obj) { 136 mSsIndicationRegistrant = new Registrant (h, what, obj); 137 } 138 139 /** 140 * UnRegisters a handler for Supplementary Service Indications. 141 */ unregisterForSuppServiceIndication(Handler h)142 public void unregisterForSuppServiceIndication(Handler h) { 143 mSsIndicationRegistrant.clear(); 144 } 145 146 /** 147 * Operations for the supplementary service configuration 148 */ 149 150 /** 151 * Retrieves the configuration of the call barring. 152 * 153 * @param cbType type of call barring to be queried; ImsUtInterface#CB_XXX 154 * @param result message to pass the result of this operation 155 * The return value of ((AsyncResult)result.obj) is an array of {@link ImsSsInfo}. 156 * @deprecated Use {@link #queryCallBarring(int, Message, int)} instead. 157 */ 158 @Override queryCallBarring(int cbType, Message result)159 public void queryCallBarring(int cbType, Message result) { 160 queryCallBarring(cbType, result, SERVICE_CLASS_NONE); 161 } 162 163 /** 164 * Retrieves the configuration of the call barring for specified service class. 165 * 166 * @param cbType type of call barring to be queried; ImsUtInterface#CB_XXX 167 * @param result message to pass the result of this operation 168 * The return value of ((AsyncResult)result.obj) is an array of {@link ImsSsInfo}. 169 * @param serviceClass service class for e.g. voice/video 170 */ 171 @Override queryCallBarring(int cbType, Message result, int serviceClass)172 public void queryCallBarring(int cbType, Message result, int serviceClass) { 173 if (DBG) { 174 log("queryCallBarring :: Ut=" + miUt + ", cbType=" + cbType + ", serviceClass=" 175 + serviceClass); 176 } 177 178 synchronized(mLockObj) { 179 try { 180 int id = miUt.queryCallBarringForServiceClass(cbType, serviceClass); 181 182 if (id < 0) { 183 sendFailureReport(result, 184 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 185 return; 186 } 187 188 mPendingCmds.put(Integer.valueOf(id), result); 189 } catch (RemoteException e) { 190 sendFailureReport(result, 191 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 192 } 193 } 194 } 195 196 /** 197 * Retrieves the configuration of the call forward. 198 * The return value of ((AsyncResult)result.obj) is an array of {@link ImsCallForwardInfo}. 199 */ 200 @Override queryCallForward(int condition, String number, Message result)201 public void queryCallForward(int condition, String number, Message result) { 202 if (DBG) { 203 log("queryCallForward :: Ut=" + miUt + ", condition=" + condition 204 + ", number=" + Rlog.pii(TAG, number)); 205 } 206 207 synchronized(mLockObj) { 208 try { 209 int id = miUt.queryCallForward(condition, number); 210 211 if (id < 0) { 212 sendFailureReport(result, 213 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 214 return; 215 } 216 217 mPendingCmds.put(Integer.valueOf(id), result); 218 } catch (RemoteException e) { 219 sendFailureReport(result, 220 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 221 } 222 } 223 } 224 225 /** 226 * Retrieves the configuration of the call waiting. 227 * The return value of ((AsyncResult)result.obj) is an array of {@link ImsSsInfo}. 228 */ 229 @Override queryCallWaiting(Message result)230 public void queryCallWaiting(Message result) { 231 if (DBG) { 232 log("queryCallWaiting :: Ut=" + miUt); 233 } 234 235 synchronized(mLockObj) { 236 try { 237 int id = miUt.queryCallWaiting(); 238 239 if (id < 0) { 240 sendFailureReport(result, 241 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 242 return; 243 } 244 245 mPendingCmds.put(Integer.valueOf(id), result); 246 } catch (RemoteException e) { 247 sendFailureReport(result, 248 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 249 } 250 } 251 } 252 253 /** 254 * Retrieves the default CLIR setting. 255 */ 256 @Override queryCLIR(Message result)257 public void queryCLIR(Message result) { 258 if (DBG) { 259 log("queryCLIR :: Ut=" + miUt); 260 } 261 262 synchronized(mLockObj) { 263 try { 264 int id = miUt.queryCLIR(); 265 266 if (id < 0) { 267 sendFailureReport(result, 268 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 269 return; 270 } 271 272 mPendingCmds.put(Integer.valueOf(id), result); 273 } catch (RemoteException e) { 274 sendFailureReport(result, 275 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 276 } 277 } 278 } 279 280 /** 281 * Retrieves the CLIP call setting. 282 */ queryCLIP(Message result)283 public void queryCLIP(Message result) { 284 if (DBG) { 285 log("queryCLIP :: Ut=" + miUt); 286 } 287 288 synchronized(mLockObj) { 289 try { 290 int id = miUt.queryCLIP(); 291 292 if (id < 0) { 293 sendFailureReport(result, 294 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 295 return; 296 } 297 298 mPendingCmds.put(Integer.valueOf(id), result); 299 } catch (RemoteException e) { 300 sendFailureReport(result, 301 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 302 } 303 } 304 } 305 306 /** 307 * Retrieves the COLR call setting. 308 */ queryCOLR(Message result)309 public void queryCOLR(Message result) { 310 if (DBG) { 311 log("queryCOLR :: Ut=" + miUt); 312 } 313 314 synchronized(mLockObj) { 315 try { 316 int id = miUt.queryCOLR(); 317 318 if (id < 0) { 319 sendFailureReport(result, 320 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 321 return; 322 } 323 324 mPendingCmds.put(Integer.valueOf(id), result); 325 } catch (RemoteException e) { 326 sendFailureReport(result, 327 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 328 } 329 } 330 } 331 332 /** 333 * Retrieves the COLP call setting. 334 */ queryCOLP(Message result)335 public void queryCOLP(Message result) { 336 if (DBG) { 337 log("queryCOLP :: Ut=" + miUt); 338 } 339 340 synchronized(mLockObj) { 341 try { 342 int id = miUt.queryCOLP(); 343 344 if (id < 0) { 345 sendFailureReport(result, 346 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 347 return; 348 } 349 350 mPendingCmds.put(Integer.valueOf(id), result); 351 } catch (RemoteException e) { 352 sendFailureReport(result, 353 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 354 } 355 } 356 } 357 358 /** 359 * Modifies the configuration of the call barring. 360 * @deprecated Use {@link #updateCallBarring(int, int, Message, String[], int)} instead. 361 */ 362 @Override updateCallBarring(int cbType, int action, Message result, String[] barrList)363 public void updateCallBarring(int cbType, int action, Message result, String[] barrList) { 364 updateCallBarring(cbType, action, result, barrList, SERVICE_CLASS_NONE); 365 } 366 367 /** 368 * Modifies the configuration of the call barring for specified service class. 369 * @deprecated Use {@link #updateCallBarring(int, int, Message, String[], int, String)} instead. 370 */ 371 @Override updateCallBarring(int cbType, int action, Message result, String[] barrList, int serviceClass)372 public void updateCallBarring(int cbType, int action, Message result, String[] barrList, 373 int serviceClass) { 374 updateCallBarring(cbType, action, result, barrList, serviceClass, ""); 375 } 376 377 /** 378 * Modifies the configuration of the call barring for specified service class with password. 379 */ 380 @Override updateCallBarring(int cbType, int action, Message result, String[] barrList, int serviceClass, String password)381 public void updateCallBarring(int cbType, int action, Message result, 382 String[] barrList, int serviceClass, String password) { 383 if (DBG) { 384 if (barrList != null) { 385 String bList = ""; 386 for (int i = 0; i < barrList.length; i++) { 387 bList += barrList[i] + " "; 388 } 389 log("updateCallBarring :: Ut=" + miUt + ", cbType=" + cbType 390 + ", action=" + action + ", serviceClass=" + serviceClass 391 + ", barrList=" + bList); 392 } 393 else { 394 log("updateCallBarring :: Ut=" + miUt + ", cbType=" + cbType 395 + ", action=" + action + ", serviceClass=" + serviceClass); 396 } 397 } 398 399 synchronized(mLockObj) { 400 try { 401 int id = miUt.updateCallBarringWithPassword(cbType, action, 402 barrList, serviceClass, password); 403 404 if (id < 0) { 405 sendFailureReport(result, 406 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 407 return; 408 } 409 410 mPendingCmds.put(Integer.valueOf(id), result); 411 } catch (RemoteException e) { 412 sendFailureReport(result, 413 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 414 } 415 } 416 } 417 418 /** 419 * Modifies the configuration of the call forward. 420 */ 421 @Override updateCallForward(int action, int condition, String number, int serviceClass, int timeSeconds, Message result)422 public void updateCallForward(int action, int condition, String number, 423 int serviceClass, int timeSeconds, Message result) { 424 if (DBG) { 425 log("updateCallForward :: Ut=" + miUt + ", action=" + action 426 + ", condition=" + condition + ", number=" + Rlog.pii(TAG, number) 427 + ", serviceClass=" + serviceClass + ", timeSeconds=" + timeSeconds); 428 } 429 430 synchronized(mLockObj) { 431 try { 432 int id = miUt.updateCallForward(action, condition, number, serviceClass, timeSeconds); 433 434 if (id < 0) { 435 sendFailureReport(result, 436 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 437 return; 438 } 439 440 mPendingCmds.put(Integer.valueOf(id), result); 441 } catch (RemoteException e) { 442 sendFailureReport(result, 443 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 444 } 445 } 446 } 447 448 /** 449 * Modifies the configuration of the call waiting. 450 */ 451 @Override updateCallWaiting(boolean enable, int serviceClass, Message result)452 public void updateCallWaiting(boolean enable, int serviceClass, Message result) { 453 if (DBG) { 454 log("updateCallWaiting :: Ut=" + miUt + ", enable=" + enable 455 + ",serviceClass=" + serviceClass); 456 } 457 458 synchronized(mLockObj) { 459 try { 460 int id = miUt.updateCallWaiting(enable, serviceClass); 461 462 if (id < 0) { 463 sendFailureReport(result, 464 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 465 return; 466 } 467 468 mPendingCmds.put(Integer.valueOf(id), result); 469 } catch (RemoteException e) { 470 sendFailureReport(result, 471 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 472 } 473 } 474 } 475 476 /** 477 * Updates the configuration of the CLIR supplementary service. 478 */ 479 @Override updateCLIR(int clirMode, Message result)480 public void updateCLIR(int clirMode, Message result) { 481 if (DBG) { 482 log("updateCLIR :: Ut=" + miUt + ", clirMode=" + clirMode); 483 } 484 485 synchronized(mLockObj) { 486 try { 487 int id = miUt.updateCLIR(clirMode); 488 489 if (id < 0) { 490 sendFailureReport(result, 491 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 492 return; 493 } 494 495 mPendingCmds.put(Integer.valueOf(id), result); 496 } catch (RemoteException e) { 497 sendFailureReport(result, 498 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 499 } 500 } 501 } 502 503 /** 504 * Updates the configuration of the CLIP supplementary service. 505 */ 506 @Override updateCLIP(boolean enable, Message result)507 public void updateCLIP(boolean enable, Message result) { 508 if (DBG) { 509 log("updateCLIP :: Ut=" + miUt + ", enable=" + enable); 510 } 511 512 synchronized(mLockObj) { 513 try { 514 int id = miUt.updateCLIP(enable); 515 516 if (id < 0) { 517 sendFailureReport(result, 518 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 519 return; 520 } 521 522 mPendingCmds.put(Integer.valueOf(id), result); 523 } catch (RemoteException e) { 524 sendFailureReport(result, 525 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 526 } 527 } 528 } 529 530 /** 531 * Updates the configuration of the COLR supplementary service. 532 */ 533 @Override updateCOLR(int presentation, Message result)534 public void updateCOLR(int presentation, Message result) { 535 if (DBG) { 536 log("updateCOLR :: Ut=" + miUt + ", presentation=" + presentation); 537 } 538 539 synchronized(mLockObj) { 540 try { 541 int id = miUt.updateCOLR(presentation); 542 543 if (id < 0) { 544 sendFailureReport(result, 545 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 546 return; 547 } 548 549 mPendingCmds.put(Integer.valueOf(id), result); 550 } catch (RemoteException e) { 551 sendFailureReport(result, 552 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 553 } 554 } 555 } 556 557 /** 558 * Updates the configuration of the COLP supplementary service. 559 */ 560 @Override updateCOLP(boolean enable, Message result)561 public void updateCOLP(boolean enable, Message result) { 562 if (DBG) { 563 log("updateCallWaiting :: Ut=" + miUt + ", enable=" + enable); 564 } 565 566 synchronized(mLockObj) { 567 try { 568 int id = miUt.updateCOLP(enable); 569 570 if (id < 0) { 571 sendFailureReport(result, 572 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 573 return; 574 } 575 576 mPendingCmds.put(Integer.valueOf(id), result); 577 } catch (RemoteException e) { 578 sendFailureReport(result, 579 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 580 } 581 } 582 } 583 584 /** 585 * @return returns true if the binder is alive, false otherwise. 586 */ isBinderAlive()587 public boolean isBinderAlive() { 588 return miUt.asBinder().isBinderAlive(); 589 } 590 transact(Bundle ssInfo, Message result)591 public void transact(Bundle ssInfo, Message result) { 592 if (DBG) { 593 log("transact :: Ut=" + miUt + ", ssInfo=" + ssInfo); 594 } 595 596 synchronized(mLockObj) { 597 try { 598 int id = miUt.transact(ssInfo); 599 600 if (id < 0) { 601 sendFailureReport(result, 602 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 603 return; 604 } 605 606 mPendingCmds.put(Integer.valueOf(id), result); 607 } catch (RemoteException e) { 608 sendFailureReport(result, 609 new ImsReasonInfo(ImsReasonInfo.CODE_UT_SERVICE_UNAVAILABLE, 0)); 610 } 611 } 612 } 613 sendFailureReport(Message result, ImsReasonInfo error)614 private void sendFailureReport(Message result, ImsReasonInfo error) { 615 if (result == null || error == null) { 616 return; 617 } 618 619 String errorString; 620 // If ImsReasonInfo object does not have a String error code, use a 621 // default error string. 622 if (error.mExtraMessage == null) { 623 errorString = Resources.getSystem().getString( 624 com.android.internal.R.string.mmiError); 625 } 626 else { 627 errorString = new String(error.mExtraMessage); 628 } 629 AsyncResult.forMessage(result, null, new ImsException(errorString, error.mCode)); 630 result.sendToTarget(); 631 } 632 sendSuccessReport(Message result)633 private void sendSuccessReport(Message result) { 634 if (result == null) { 635 return; 636 } 637 638 AsyncResult.forMessage(result, null, null); 639 result.sendToTarget(); 640 } 641 sendSuccessReport(Message result, Object ssInfo)642 private void sendSuccessReport(Message result, Object ssInfo) { 643 if (result == null) { 644 return; 645 } 646 647 AsyncResult.forMessage(result, ssInfo, null); 648 result.sendToTarget(); 649 } 650 log(String s)651 private void log(String s) { 652 Rlog.d(TAG, s); 653 } 654 loge(String s)655 private void loge(String s) { 656 Rlog.e(TAG, s); 657 } 658 loge(String s, Throwable t)659 private void loge(String s, Throwable t) { 660 Rlog.e(TAG, s, t); 661 } 662 663 /** 664 * A listener type for the result of the supplementary service configuration. 665 */ 666 @VisibleForTesting 667 public class IImsUtListenerProxy extends IImsUtListener.Stub { 668 /** 669 * Notifies the result of the supplementary service configuration udpate. 670 */ 671 @Override utConfigurationUpdated(IImsUt ut, int id)672 public void utConfigurationUpdated(IImsUt ut, int id) { 673 TelephonyUtils.runWithCleanCallingIdentity(()-> { 674 Integer key = Integer.valueOf(id); 675 676 synchronized(mLockObj) { 677 sendSuccessReport(mPendingCmds.get(key)); 678 mPendingCmds.remove(key); 679 } 680 }, mExecutor); 681 } 682 683 @Override utConfigurationUpdateFailed(IImsUt ut, int id, ImsReasonInfo error)684 public void utConfigurationUpdateFailed(IImsUt ut, int id, ImsReasonInfo error) { 685 TelephonyUtils.runWithCleanCallingIdentity(()-> { 686 Integer key = Integer.valueOf(id); 687 688 synchronized(mLockObj) { 689 sendFailureReport(mPendingCmds.get(key), error); 690 mPendingCmds.remove(key); 691 } 692 }, mExecutor); 693 } 694 695 /** 696 * Notifies the result of the supplementary service configuration query. 697 */ 698 // API Deprecated, internally use new API to process query result. 699 @Override utConfigurationQueried(IImsUt ut, int id, Bundle ssInfo)700 public void utConfigurationQueried(IImsUt ut, int id, Bundle ssInfo) { 701 int[] clirResponse = ssInfo.getIntArray(ImsUtListener.BUNDLE_KEY_CLIR); 702 if (clirResponse != null && clirResponse.length == 2) { 703 // Deprecated functionality does not use status, set as NOT_REGISTERED. 704 ImsSsInfo info = new ImsSsInfo.Builder(ImsSsInfo.NOT_REGISTERED) 705 .setClirOutgoingState(clirResponse[0]) 706 .setClirInterrogationStatus(clirResponse[1]).build(); 707 lineIdentificationSupplementaryServiceResponse(id, info); 708 return; 709 } 710 ImsSsInfo info = ssInfo.getParcelable(ImsUtListener.BUNDLE_KEY_SSINFO); 711 if (info != null) { 712 lineIdentificationSupplementaryServiceResponse(id, info); 713 return; 714 } 715 Rlog.w(TAG, "Invalid utConfigurationQueried response received for Bundle " + ssInfo); 716 } 717 718 /** 719 * Notifies the result of a line identification supplementary service query. 720 */ 721 @Override lineIdentificationSupplementaryServiceResponse(int id, ImsSsInfo config)722 public void lineIdentificationSupplementaryServiceResponse(int id, ImsSsInfo config) { 723 TelephonyUtils.runWithCleanCallingIdentity(()-> { 724 synchronized(mLockObj) { 725 sendSuccessReport(mPendingCmds.get(id), config); 726 mPendingCmds.remove(id); 727 } 728 }, mExecutor); 729 } 730 731 @Override utConfigurationQueryFailed(IImsUt ut, int id, ImsReasonInfo error)732 public void utConfigurationQueryFailed(IImsUt ut, int id, ImsReasonInfo error) { 733 TelephonyUtils.runWithCleanCallingIdentity(()-> { 734 Integer key = Integer.valueOf(id); 735 736 synchronized(mLockObj) { 737 sendFailureReport(mPendingCmds.get(key), error); 738 mPendingCmds.remove(key); 739 } 740 }, mExecutor); 741 } 742 743 /** 744 * Notifies the status of the call barring supplementary service. 745 */ 746 @Override utConfigurationCallBarringQueried(IImsUt ut, int id, ImsSsInfo[] cbInfo)747 public void utConfigurationCallBarringQueried(IImsUt ut, 748 int id, ImsSsInfo[] cbInfo) { 749 TelephonyUtils.runWithCleanCallingIdentity(()-> { 750 Integer key = Integer.valueOf(id); 751 752 synchronized(mLockObj) { 753 sendSuccessReport(mPendingCmds.get(key), cbInfo); 754 mPendingCmds.remove(key); 755 } 756 }, mExecutor); 757 } 758 759 /** 760 * Notifies the status of the call forwarding supplementary service. 761 */ 762 @Override utConfigurationCallForwardQueried(IImsUt ut, int id, ImsCallForwardInfo[] cfInfo)763 public void utConfigurationCallForwardQueried(IImsUt ut, 764 int id, ImsCallForwardInfo[] cfInfo) { 765 TelephonyUtils.runWithCleanCallingIdentity(()-> { 766 Integer key = Integer.valueOf(id); 767 768 synchronized(mLockObj) { 769 sendSuccessReport(mPendingCmds.get(key), cfInfo); 770 mPendingCmds.remove(key); 771 } 772 }, mExecutor); 773 } 774 775 /** 776 * Notifies the status of the call waiting supplementary service. 777 */ 778 @Override utConfigurationCallWaitingQueried(IImsUt ut, int id, ImsSsInfo[] cwInfo)779 public void utConfigurationCallWaitingQueried(IImsUt ut, 780 int id, ImsSsInfo[] cwInfo) { 781 TelephonyUtils.runWithCleanCallingIdentity(()-> { 782 Integer key = Integer.valueOf(id); 783 784 synchronized(mLockObj) { 785 sendSuccessReport(mPendingCmds.get(key), cwInfo); 786 mPendingCmds.remove(key); 787 } 788 }, mExecutor); 789 } 790 791 /** 792 * Notifies client when Supplementary Service indication is received 793 */ 794 @Override onSupplementaryServiceIndication(ImsSsData ssData)795 public void onSupplementaryServiceIndication(ImsSsData ssData) { 796 TelephonyUtils.runWithCleanCallingIdentity(()-> { 797 if (mSsIndicationRegistrant != null) { 798 mSsIndicationRegistrant.notifyResult(ssData); 799 } 800 }, mExecutor); 801 } 802 } 803 } 804