Home | History | Annotate | Download | only in presence
      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.presence;
     30 
     31 import java.lang.String;
     32 import android.content.ContentResolver;
     33 import android.content.ContentValues;
     34 import android.content.Context;
     35 import android.os.RemoteException;
     36 import android.content.Intent;
     37 import com.android.internal.telephony.TelephonyIntents;
     38 import android.content.ComponentName;
     39 
     40 import com.android.ims.internal.uce.common.StatusCode;
     41 import com.android.ims.internal.uce.common.StatusCode;
     42 import com.android.ims.internal.uce.presence.PresCmdStatus;
     43 import com.android.ims.internal.uce.presence.PresResInfo;
     44 import com.android.ims.internal.uce.presence.PresSipResponse;
     45 
     46 import com.android.ims.RcsManager.ResultCode;
     47 import com.android.ims.RcsPresence.PublishState;
     48 import com.android.ims.RcsPresenceInfo;
     49 
     50 import com.android.ims.internal.Logger;
     51 import com.android.service.ims.Task;
     52 import com.android.service.ims.RcsUtils;
     53 import com.android.service.ims.TaskManager;
     54 
     55 public abstract class PresenceBase{
     56     /*
     57      * The logger
     58      */
     59     static private Logger logger = Logger.getLogger("PresenceBase");
     60 
     61     protected Context mContext = null;
     62 
     63     public PresenceBase() {
     64     }
     65 
     66     protected void handleCallback(Task task, int resultCode, boolean forCmdStatus){
     67         if(task == null){
     68             logger.debug("task == null");
     69             return;
     70         }
     71 
     72         if(task.mListener != null){
     73             try{
     74                 if(resultCode >= ResultCode.SUCCESS){
     75                     if(!forCmdStatus){
     76                         task.mListener.onSuccess(task.mTaskId);
     77                     }
     78                 }else{
     79                     task.mListener.onError(task.mTaskId, resultCode);
     80                 }
     81             }catch(RemoteException e){
     82                 logger.debug("Failed to send the status to client.");
     83             }
     84         }
     85 
     86         // remove task when error
     87         // remove task when SIP response success.
     88         // For list capability polling we will waiting for the terminated notify or timeout.
     89         if(resultCode != ResultCode.SUCCESS){
     90             if(task instanceof PresencePublishTask){
     91                 PresencePublishTask publishTask = (PresencePublishTask) task;
     92                 logger.debug("handleCallback for publishTask=" + publishTask);
     93                 if(resultCode == PublishState.PUBLISH_STATE_VOLTE_PROVISION_ERROR) {
     94                     // retry 3 times for "403 Not Authorized for Presence".
     95                     if(publishTask.getRetryCount() >= 3) {
     96                         //remove capability after try 3 times by PresencePolling
     97                         logger.debug("handleCallback remove task=" + task);
     98                         TaskManager.getDefault().removeTask(task.mTaskId);
     99                     } else {
    100                         // Continue retry
    101                         publishTask.setRetryCount(publishTask.getRetryCount() + 1);
    102                     }
    103                 } else {
    104                     logger.debug("handleCallback remove task=" + task);
    105                     TaskManager.getDefault().removeTask(task.mTaskId);
    106                 }
    107             } else {
    108                 logger.debug("handleCallback remove task=" + task);
    109                 TaskManager.getDefault().removeTask(task.mTaskId);
    110             }
    111         }else{
    112             if(forCmdStatus || !forCmdStatus && (task instanceof PresenceCapabilityTask)){
    113                 logger.debug("handleCallback remove task later");
    114 
    115                 //waiting for Notify from network
    116                 if(!forCmdStatus){
    117                     ((PresenceCapabilityTask)task).setWaitingForNotify(true);
    118                 }
    119             }else{
    120                 if(!forCmdStatus && (task instanceof PresenceAvailabilityTask) &&
    121                         (resultCode == ResultCode.SUCCESS)){
    122                     // Availiablity, cache for 60s, remove it later.
    123                     logger.debug("handleCallback PresenceAvailabilityTask cache for 60s task="
    124                             + task);
    125                     return;
    126                 }
    127 
    128                 logger.debug("handleCallback remove task=" + task);
    129                 TaskManager.getDefault().removeTask(task.mTaskId);
    130             }
    131         }
    132     }
    133 
    134     public void handleCmdStatus(PresCmdStatus pCmdStatus){
    135         if(pCmdStatus == null){
    136             logger.error("handleCallbackForCmdStatus pCmdStatus=null");
    137             return;
    138         }
    139 
    140         Task task = TaskManager.getDefault().getTask(pCmdStatus.getUserData());
    141         int resultCode = RcsUtils.statusCodeToResultCode(pCmdStatus.getStatus().getStatusCode());
    142         if(task != null){
    143             task.mSipRequestId = pCmdStatus.getRequestId();
    144             task.mCmdStatus = resultCode;
    145             TaskManager.getDefault().putTask(task.mTaskId, task);
    146         }
    147 
    148         handleCallback(task, resultCode, true);
    149     }
    150 
    151     protected void notifyDm() {
    152         logger.debug("notifyDm");
    153         Intent intent = new Intent(
    154                 TelephonyIntents.ACTION_FORBIDDEN_NO_SERVICE_AUTHORIZATION);
    155         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
    156 
    157         mContext.sendBroadcast(intent);
    158     }
    159 
    160     protected boolean isInConfigList(int errorNo, String phrase, int configId) {
    161         String inErrorString = ("" + errorNo).trim();
    162 
    163         String[] errorArray = mContext.getResources().getStringArray(configId);
    164         logger.debug("errorArray length=" + errorArray.length + " errorArray=" + errorArray);
    165         for (String errorStr : errorArray) {
    166             if (errorStr != null && errorStr.startsWith(inErrorString)) {
    167                 String errorPhrase = errorStr.substring(inErrorString.length());
    168                 if(errorPhrase == null || errorPhrase.isEmpty()) {
    169                     return true;
    170                 }
    171 
    172                 if(phrase == null || phrase.isEmpty()) {
    173                     return false;
    174                 }
    175 
    176                 return phrase.toLowerCase().contains(errorPhrase.toLowerCase());
    177             }
    178         }
    179         return false;
    180     }
    181 
    182     abstract public void handleSipResponse(PresSipResponse pSipResponse);
    183 }
    184 
    185