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