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