1 /*
2  * Copyright (c) 2015, Motorola Mobility LLC
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *     - Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     - Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     - Neither the name of Motorola Mobility nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26  * DAMAGE.
27  */
28 
29 package com.android.service.ims;
30 
31 import android.content.Context;
32 import android.content.Intent;
33 import android.os.Handler;
34 import android.os.Looper;
35 import android.os.Message;
36 import android.os.Parcel;
37 import android.os.RemoteException;
38 import android.telephony.ims.RcsContactUceCapability;
39 import android.text.TextUtils;
40 import android.util.Log;
41 
42 import com.android.ims.RcsManager;
43 import com.android.ims.RcsPresenceInfo;
44 import com.android.ims.internal.Logger;
45 import com.android.ims.internal.uce.common.StatusCode;
46 import com.android.ims.internal.uce.presence.IPresenceListener;
47 import com.android.ims.internal.uce.presence.PresCmdId;
48 import com.android.ims.internal.uce.presence.PresCmdStatus;
49 import com.android.ims.internal.uce.presence.PresPublishTriggerType;
50 import com.android.ims.internal.uce.presence.PresResInfo;
51 import com.android.ims.internal.uce.presence.PresRlmiInfo;
52 import com.android.ims.internal.uce.presence.PresSipResponse;
53 import com.android.ims.internal.uce.presence.PresSubscriptionState;
54 import com.android.ims.internal.uce.presence.PresTupleInfo;
55 import com.android.service.ims.presence.PresencePublication;
56 import com.android.service.ims.presence.PresenceSubscriber;
57 
58 import java.util.ArrayList;
59 
60 public class StackListener extends Handler{
61     /*
62      * The logger
63      */
64     private Logger logger = Logger.getLogger(this.getClass().getName());
65 
66     Context mContext;
67     private PresencePublication mPresencePublication = null;
68     private PresenceSubscriber mPresenceSubscriber = null;
69 
70     // RCS stack notify the AP to publish the presence.
71     private static final short PRESENCE_IMS_UNSOL_PUBLISH_TRIGGER = 1;
72     // PUBLISH CMD status changed
73     private static final short PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS = 2;
74     // Received the SIP response for publish
75     private static final short PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE = 3;
76     // Received the presence for single contact
77     private static final short PRESENCE_IMS_UNSOL_NOTIFY_UPDATE = 4;
78     // Received the presence for contacts.
79     private static final short PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE = 5;
80     // Received the CMD status for capability/availability request
81     private static final short PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_CMDSTATUS = 6;
82     // Received the SIP response for capability/availability request
83     private static final short PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_SIPRESPONSE = 7;
84 
85     private final Object mSyncObj = new Object();
86 
StackListener(Context context, Looper looper)87     public StackListener(Context context, Looper looper) {
88         super(looper);
89         mContext = context;
90     }
91 
setPresencePublication(PresencePublication presencePublication)92     public void setPresencePublication(PresencePublication presencePublication) {
93         mPresencePublication = presencePublication;
94     }
95 
setPresenceSubscriber(PresenceSubscriber presenceSubscriber)96     public void setPresenceSubscriber(PresenceSubscriber presenceSubscriber){
97         mPresenceSubscriber = presenceSubscriber;
98     }
99 
100     @Override
handleMessage(Message msg)101     public void handleMessage(Message msg) {
102         super.handleMessage(msg);
103 
104         logger.debug( "Thread=" + Thread.currentThread().getName() + " received "
105                 + msg);
106         if(msg == null){
107             logger.error("msg=null");
108             return;
109         }
110 
111         switch (msg.what) {
112             // RCS stack notify the AP to publish the presence.
113             case PRESENCE_IMS_UNSOL_PUBLISH_TRIGGER:
114             {
115                 PresPublishTriggerType val = (PresPublishTriggerType) msg.obj;
116                 if(mPresencePublication == null || val == null){
117                     logger.error("mPresencePublication=" + mPresencePublication + " val=" + val);
118                     return;
119                 }
120 
121                 mPresencePublication.onStackPublishRequested(
122                         convertToStackPublishTriggerType(val.getPublishTrigeerType()));
123                 break;
124             }
125 
126             // RCS stack tell AP that the CMD status changed.
127             case PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS:
128             {
129                 PresCmdStatus pCmdStatus = (PresCmdStatus) msg.obj;
130                 if(mPresencePublication == null || pCmdStatus == null) {
131                     logger.error("mPresencePublication=" + mPresencePublication +
132                             " pCmdStatus=" + pCmdStatus);
133                     return;
134                 }
135 
136                 int commandResult = RcsUtils.statusCodeToResultCode(
137                         pCmdStatus.getStatus().getStatusCode());
138                 mPresencePublication.onCommandStatusUpdated(pCmdStatus.getUserData(),
139                         pCmdStatus.getRequestId(), commandResult);
140             }
141                 break;
142 
143             // RCS stack tells AP that the CMD status changed.
144             case PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_CMDSTATUS:
145             {
146                 PresCmdStatus pCmdStatus = (PresCmdStatus) msg.obj;
147                 if(mPresenceSubscriber == null || pCmdStatus == null){
148                     logger.error("mPresenceSubcriber=" + mPresenceSubscriber +
149                             " pCmdStatus=" + pCmdStatus);
150                     return;
151                 }
152                 int commandResult = RcsUtils.statusCodeToResultCode(
153                         pCmdStatus.getStatus().getStatusCode());
154                 mPresenceSubscriber.onCommandStatusUpdated(pCmdStatus.getUserData(),
155                         pCmdStatus.getRequestId(), commandResult);
156                 break;
157             }
158 
159             // RCS stack tells AP that the SIP response has been received.
160             case PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE:
161             {
162                 PresSipResponse pSipResponse =  (PresSipResponse) msg.obj;
163                 if(mPresencePublication == null || pSipResponse == null) {
164                     logger.error("mPresencePublication=" + mPresencePublication +
165                             "pSipResponse=" +pSipResponse);
166                     return;
167                 }
168 
169                 mPresencePublication.onSipResponse(pSipResponse.getRequestId(),
170                         pSipResponse.getSipResponseCode(), pSipResponse.getReasonPhrase());
171                 break;
172             }
173 
174             // RCS stack tells AP that the SIP response has been received.
175             case PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_SIPRESPONSE:
176             {
177                 PresSipResponse pSipResponse =  (PresSipResponse) msg.obj;
178                 if(mPresenceSubscriber == null || pSipResponse == null){
179                     logger.error("mPresenceSubscriber=" + mPresenceSubscriber +
180                             " pSipResponse=" + pSipResponse);
181                     return;
182                 }
183 
184                 mPresenceSubscriber.onSipResponse(pSipResponse.getRequestId(),
185                         pSipResponse.getSipResponseCode(), pSipResponse.getReasonPhrase());
186                 break;
187             }
188 
189             // RCS stack tells AP that the presence data has been received.
190             case PRESENCE_IMS_UNSOL_NOTIFY_UPDATE:
191             {
192                 NotifyData notifyData = (NotifyData) msg.obj;
193                 if(mPresenceSubscriber == null || notifyData == null){
194                     logger.error("mPresenceSubscriber=" + mPresenceSubscriber +
195                             " notifyData=" + notifyData);
196                     return;
197                 }
198                 RcsPresenceInfo rcsPresenceInfo = PresenceInfoParser.getPresenceInfoFromTuple(
199                         notifyData.getUri(), notifyData.getTupleInfo());
200                 if(rcsPresenceInfo == null || TextUtils.isEmpty(
201                         rcsPresenceInfo.getContactNumber())){
202                     logger.error("rcsPresenceInfo is null or " +
203                             "TextUtils.isEmpty(rcsPresenceInfo.getContactNumber()");
204                     return;
205                 }
206                 mPresenceSubscriber.updatePresence(
207                         PresenceInfoParser.getUceCapability(rcsPresenceInfo));
208                 break;
209             }
210 
211             case PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE:
212             {
213                 NotifyListData notifyListData = (NotifyListData) msg.obj;
214                 logger.debug("Received PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE");
215                 if(mPresenceSubscriber==null || notifyListData == null){
216                     logger.error("mPresenceSubscriber=" + mPresenceSubscriber +
217                             " notifyListData=" + notifyListData);
218                     return;
219                 }
220 
221                 RcsPresenceInfo[] rcsPresenceInfos = PresenceInfoParser.
222                         getPresenceInfosFromPresenceRes(notifyListData.getRlmiInfo(),
223                                 notifyListData.getResInfo());
224                 if(rcsPresenceInfos == null){
225                     logger.error("updatePresences: rcsPresenceInfos == null");
226                     return;
227                 }
228 
229                 PresRlmiInfo info = notifyListData.getRlmiInfo();
230                 boolean isTerminated = false;
231                 if (info.getPresSubscriptionState() != null) {
232                     if (info.getPresSubscriptionState().getPresSubscriptionStateValue() ==
233                             PresSubscriptionState.UCE_PRES_SUBSCRIPTION_STATE_TERMINATED) {
234                         isTerminated = true;
235                     }
236                 }
237 
238                 ArrayList<RcsContactUceCapability> capabilities = new ArrayList<>();
239 
240                 for (int i=0; i < rcsPresenceInfos.length; i++) {
241                     if(rcsPresenceInfos[i] != null && TextUtils.isEmpty(
242                             rcsPresenceInfos[i].getContactNumber())){
243                         continue;
244                     }
245                     RcsContactUceCapability capability = PresenceInfoParser.getUceCapability(
246                             rcsPresenceInfos[i]);
247                     if(capability != null && (capability.getContactUri() != null)){
248                         logger.debug("capability=" + capability);
249                         capabilities.add(capability);
250                     }
251                 }
252 
253                 mPresenceSubscriber.updatePresences(info.getRequestId(), capabilities, isTerminated,
254                         info.getSubscriptionTerminatedReason());
255                 break;
256             }
257 
258             default:
259                 logger.debug("Unknown mesg " + msg.what + " recieved.");
260         }
261     }
262 
263     public class NotifyData{
264         private String mUri;
265         private PresTupleInfo[] mTupleInfo;
266 
NotifyData()267         NotifyData(){
268             mUri = null;
269             mTupleInfo = null;
270         }
271 
NotifyData(String uri, PresTupleInfo[] pTupleInfo)272         NotifyData(String uri, PresTupleInfo[] pTupleInfo){
273             mUri = uri;
274             mTupleInfo = pTupleInfo;
275         }
276 
getUri()277         public String getUri(){
278             return mUri;
279         }
280 
getTupleInfo()281         public PresTupleInfo[] getTupleInfo(){
282             return mTupleInfo;
283         }
284     }
285 
286     public class NotifyListData{
287         private PresRlmiInfo mRlmiInfo;
288         private PresResInfo[] mResInfo;
289 
NotifyListData()290         NotifyListData(){
291             mRlmiInfo = null;
292             mResInfo = null;
293         }
294 
NotifyListData(PresRlmiInfo pRlmiInfo, PresResInfo[] pResInfo)295         NotifyListData(PresRlmiInfo pRlmiInfo, PresResInfo[] pResInfo){
296             mRlmiInfo = pRlmiInfo;
297             mResInfo = pResInfo;
298         }
299 
getRlmiInfo()300         public PresRlmiInfo getRlmiInfo(){
301             return mRlmiInfo;
302         }
303 
getResInfo()304         public PresResInfo[] getResInfo(){
305             return mResInfo;
306         }
307     }
308 
309     public IPresenceListener mPresenceListener = new IPresenceListener.Stub() {
310         public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
311                throws RemoteException{
312             try{
313                 return super.onTransact(code, data, reply, flags);
314             } catch (RemoteException e) {
315                 Log.w("ListenerHandler", "Unexpected remote exception", e);
316                 e.printStackTrace();
317                 throw e;
318            }
319         }
320 
321         public void getVersionCb(String pVersion) {
322             logger.debug("pVersion=" + pVersion);
323         }
324 
325         public void sipResponseReceived(PresSipResponse pSipResponse) throws RemoteException {
326             synchronized(mSyncObj){
327                 if(pSipResponse == null){
328                     logger.error("ISipResponseReceived pSipResponse=null");
329                     return;
330                 }
331 
332                 logger.debug("pSipResponse.getCmdId() "+
333                         pSipResponse.getCmdId().getCmdId());
334                 logger.debug("getReasonPhrase() "+pSipResponse.getReasonPhrase());
335                 logger.debug("getsRequestID() "+pSipResponse.getRequestId());
336                 logger.debug("getsSipResponseCode() "+pSipResponse.getSipResponseCode());
337 
338                 switch (pSipResponse.getCmdId().getCmdId()) {
339                     case PresCmdId.UCE_PRES_CMD_PUBLISHMYCAP:
340                     {
341                         Message updateMesgSipPub = StackListener.this.obtainMessage(
342                                 PRESENCE_IMS_UNSOL_PUBLISH_SIPRESPONSE,
343                                 pSipResponse);
344                         StackListener.this.sendMessage(updateMesgSipPub);
345                         break;
346                     }
347 
348                     case PresCmdId.UCE_PRES_CMD_GETCONTACTCAP:
349                     case PresCmdId.UCE_PRES_CMD_GETCONTACTLISTCAP:
350                     {
351                         Message updateMesgSipPub = StackListener.this.obtainMessage(
352                                 PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_SIPRESPONSE,
353                                 pSipResponse);
354                         StackListener.this.sendMessage(updateMesgSipPub);
355 
356                         break;
357                     }
358 
359                     case PresCmdId.UCE_PRES_CMD_SETNEWFEATURETAG:
360                     {
361                         logger.debug("UCE_PRES_CMD_SETNEWFEATURETAG, doesn't care it");
362                         break;
363                     }
364 
365                     default:
366                         logger.debug("CMD ID for unknown value=" +
367                                 pSipResponse.getCmdId().getCmdId());
368                 }
369             }
370         }
371 
372         public void serviceUnAvailable(StatusCode statusCode) throws RemoteException {
373             synchronized(mSyncObj){
374                 if(statusCode == null){
375                     logger.error("statusCode=null");
376                 }else{
377                     logger.debug("IServiceUnAvailable statusCode " +
378                         statusCode.getStatusCode());
379                 }
380                 logger.debug("QPresListener_ServiceUnAvailable");
381 
382                 RcsStackAdaptor rcsStackAdaptor = RcsStackAdaptor.getInstance(null);
383                 if (rcsStackAdaptor != null) {
384                     rcsStackAdaptor.setImsEnableState(false);
385                 }
386 
387                 Intent intent = new Intent(RcsManager.ACTION_RCS_SERVICE_UNAVAILABLE);
388                 mContext.sendBroadcast(intent,
389                         "com.android.ims.rcs.permission.STATUS_CHANGED");
390             }
391         }
392 
393         public void serviceAvailable(StatusCode statusCode) throws RemoteException {
394             synchronized(mSyncObj){
395                 if(statusCode == null){
396                     logger.error("statusCode=null");
397                 }else{
398                     logger.debug("IServiceAvailable statusCode " +
399                         statusCode.getStatusCode());
400                 }
401 
402                 logger.debug("QPresListener_ServiceAvailable");
403 
404                 RcsStackAdaptor rcsStackAdaptor = RcsStackAdaptor.getInstance(null);
405                 if (rcsStackAdaptor != null) {
406                     rcsStackAdaptor.setImsEnableState(true);
407                 }
408 
409                 // Handle the cached trigger which got from stack
410                 if(mPresencePublication != null) {
411                     logger.debug("publish for cached trigger");
412                     mPresencePublication.onStackAvailable();
413                 }
414 
415                 Intent intent = new Intent(RcsManager.ACTION_RCS_SERVICE_AVAILABLE);
416                 mContext.sendBroadcast(intent,
417                         "com.android.ims.rcs.permission.STATUS_CHANGED");
418             }
419         }
420 
421         public void publishTriggering(PresPublishTriggerType publishTrigger)
422                 throws RemoteException {
423             if(publishTrigger == null){
424                 logger.error("publishTrigger=null");
425             }else{
426                 logger.debug("getPublishTrigeerType() "+
427                          publishTrigger.getPublishTrigeerType());
428             }
429             logger.debug("ListenerHandler : PublishTriggering");
430 
431             Message publishTrigerMsg = StackListener.this.obtainMessage(
432                     PRESENCE_IMS_UNSOL_PUBLISH_TRIGGER, publishTrigger);
433             StackListener.this.sendMessage(publishTrigerMsg);
434         }
435 
436         public void listCapInfoReceived(PresRlmiInfo pRlmiInfo, PresResInfo[] pResInfo)
437                 throws RemoteException {
438             if(pRlmiInfo == null || pResInfo == null){
439                 logger.error("pRlmiInfo=" + pRlmiInfo + " pResInfo=" + pResInfo);
440             }else{
441                 logger.debug("pRlmiInfo.getListName "+pRlmiInfo.getListName());
442                 logger.debug("pRlmiInfo.isFullState "+pRlmiInfo.isFullState());
443                 logger.debug("pRlmiInfo.getUri "+pRlmiInfo.getUri());
444                 logger.debug("pRlmiInfo.getVersion "+pRlmiInfo.getVersion());
445                 logger.debug("pRlmiInfo.getSubscriptionTerminatedReason " +
446                         pRlmiInfo.getSubscriptionTerminatedReason());
447                 logger.debug("pRlmiInfo.getPresSubscriptionState " +
448                         pRlmiInfo.getPresSubscriptionState());
449                 logger.debug("pRlmiInfo.getRequestID=" + pRlmiInfo.getRequestId());
450                 for(int i=0; i < pResInfo.length; i++ ){
451                     if(pResInfo[i] == null){
452                         logger.debug("ignoring, pResInfo[" + i + "]=null");
453                         continue;
454                     }
455 
456                     logger.debug(".getDisplayName() "+pResInfo[i].getDisplayName());
457                     logger.debug("getResUri() "+pResInfo[i].getResUri());
458                     if(pResInfo[i].getInstanceInfo() != null){
459                         logger.debug("getInstanceInfo().getPresentityUri() "+
460                                  pResInfo[i].getInstanceInfo().getPresentityUri());
461                         logger.debug("getInstanceInfo().getResId() "+
462                                  pResInfo[i].getInstanceInfo().getResId());
463                         logger.debug("getInstanceInfo().getsReason() "+
464                                  pResInfo[i].getInstanceInfo().getReason());
465                         logger.debug("getInstanceInfo().getResInstanceState() "+
466                                  pResInfo[i].getInstanceInfo().getResInstanceState());
467                         if(pResInfo[i].getInstanceInfo().getTupleInfo() == null){
468                            logger.debug("pResInfo[" + i +"].getInstanceInfo().getTupleInfo()=null");
469                             continue;
470                         }
471 
472                         logger.debug("getTupleInfo().length "+
473                                  pResInfo[i].getInstanceInfo().getTupleInfo().length);
474                         if(pResInfo[i].getInstanceInfo().getTupleInfo() != null){
475                             for(int j = 0; j < pResInfo[i].getInstanceInfo().getTupleInfo().length;
476                                 j++)
477                             {
478                                 if(pResInfo[i].getInstanceInfo().getTupleInfo() == null){
479                                     logger.debug("ignoring, pResInfo[" + i +
480                                             "].getInstanceInfo().getTupleInfo()[" +j + "]");
481                                     continue;
482                                 }
483 
484                                 logger.debug("getFeatureTag "+
485                                         pResInfo[i].getInstanceInfo().getTupleInfo()[j].
486                                         getFeatureTag());
487                                 logger.debug("getsContactUri "+
488                                         pResInfo[i].getInstanceInfo().getTupleInfo()[j].
489                                         getContactUri());
490                                 logger.debug("getsTimestamp "+
491                                         pResInfo[i].getInstanceInfo().getTupleInfo()[j].
492                                         getTimestamp());
493                             }
494                         }
495                     }
496                 }
497             }
498 
499             Message notifyListReceivedMsg = StackListener.this.obtainMessage(
500                     PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE,
501                     new NotifyListData(pRlmiInfo, pResInfo));
502             logger.debug("Send PRESENCE_IMS_UNSOL_NOTIFY_LIST_UPDATE");
503 
504             StackListener.this.sendMessage(notifyListReceivedMsg);
505         }
506 
507         public void capInfoReceived(String presentityURI, PresTupleInfo[] pTupleInfo)
508                 throws RemoteException {
509             logger.debug("ListenerHandler : CapInfoReceived");
510             if(presentityURI == null || presentityURI == null){
511                 logger.error("presentityURI=null or presentityURI=null");
512                 return;
513             }
514 
515             logger.debug("ListenerHandler : CapInfoReceived : presentityURI "+ presentityURI);
516 
517             Message notifyReceivedMsg = StackListener.this.obtainMessage(
518                     PRESENCE_IMS_UNSOL_NOTIFY_UPDATE,
519                     new NotifyData(presentityURI, pTupleInfo));
520             StackListener.this.sendMessage(notifyReceivedMsg);
521         }
522 
523         public void cmdStatus(PresCmdStatus pCmdStatus) throws RemoteException {
524             synchronized(mSyncObj){
525                 if(pCmdStatus == null || pCmdStatus.getCmdId() == null){
526                      logger.debug( "ICMDStatus error, pCmdStatus="+ pCmdStatus);
527                     return;
528                  }
529 
530                 logger.debug("ListenerHandler : CMDStatus");
531                 logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getRequestID() "+
532                         pCmdStatus.getRequestId());
533                 logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getUserData() "+
534                         pCmdStatus.getUserData());
535                 logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getCmdId() "+
536                         pCmdStatus.getCmdId().getCmdId());
537                 if(pCmdStatus.getStatus() != null){
538                     logger.debug("ListenerHandler : CMDStatus : pCmdStatus.getStatus() "+
539                            pCmdStatus.getStatus().getStatusCode());
540                 }
541 
542                 switch (pCmdStatus.getCmdId().getCmdId()) {
543                 case PresCmdId.UCE_PRES_CMD_PUBLISHMYCAP:
544                     Message publishCmdMsg = StackListener.this.obtainMessage(
545                             PRESENCE_IMS_UNSOL_PUBLISH_CMDSTATUS,
546                             pCmdStatus);
547                     StackListener.this.sendMessage(publishCmdMsg);
548                     break;
549 
550                 case PresCmdId.UCE_PRES_CMD_GETCONTACTCAP:
551                 case PresCmdId.UCE_PRES_CMD_GETCONTACTLISTCAP:
552                     Message notifyUpdateCmdMsg = StackListener.this.obtainMessage(
553                             PRESENCE_IMS_UNSOL_NOTIFY_UPDATE_CMDSTATUS,
554                             pCmdStatus);
555                     StackListener.this.sendMessage(notifyUpdateCmdMsg);
556                     break;
557 
558                 case PresCmdId.UCE_PRES_CMD_SETNEWFEATURETAG:
559                     logger.debug("UCE_PRES_CMD_SETNEWFEATURETAG: app does not care it");
560                     break;
561 
562                 default:
563                     logger.debug("CMD ID for unknown value=" +
564                             pCmdStatus.getCmdId().getCmdId());
565                 }
566             }
567         }
568 
569         public void unpublishMessageSent() {
570             logger.debug("unpublishMessageSent()");
571         }
572     };
573 
574     @PresencePublication.StackPublishTriggerType
convertToStackPublishTriggerType(int presPublishTriggerType)575     private static int convertToStackPublishTriggerType(int presPublishTriggerType) {
576         switch (presPublishTriggerType) {
577             case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_ETAG_EXPIRED:
578                 return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_ETAG_EXPIRED;
579             case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED:
580                 return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_DISABLED;
581             case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED:
582                 return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_LTE_VOPS_ENABLED;
583             case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_EHRPD:
584                 return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_EHRPD;
585             case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS:
586                 return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_HSPAPLUS;
587             case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_3G:
588                 return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_3G;
589             case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_2G:
590                 return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_2G;
591             case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_WLAN:
592                 return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_WLAN;
593             case PresPublishTriggerType.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN:
594                 return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_MOVE_TO_IWLAN;
595         }
596         return PresencePublication.UCE_PRES_PUBLISH_TRIGGER_UNKNOWN;
597     }
598 }
599 
600