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 android.content.Context; 32 import android.os.AsyncTask; 33 import android.os.Looper; 34 35 import com.android.ims.IRcsPresenceListener; 36 import com.android.ims.RcsManager; 37 import com.android.ims.RcsPresence; 38 import com.android.ims.RcsException; 39 import com.android.ims.RcsManager.ResultCode; 40 import com.android.ims.internal.Logger; 41 42 import java.util.ArrayList; 43 import java.util.List; 44 45 public class PollingAction extends AsyncTask<Void, Integer, Integer> { 46 private Logger logger = Logger.getLogger(this.getClass().getName()); 47 48 private Context mContext; 49 private PollingTask mPollingTask; 50 private int mResult; 51 private int mRequestId = -1; 52 53 private final Object mPollingSyncObj = new Object(); 54 private boolean mIsPolling = false; 55 private boolean mFullUpdated = false; 56 57 private IRcsPresenceListener mClientListener = new IRcsPresenceListener.Stub() { 58 public void onSuccess(int reqId) { 59 logger.print("onSuccess() is called. reqId=" + reqId); 60 } 61 62 public void onError(int reqId, int code) { 63 logger.print("onError() is called, reqId=" + reqId + " error code: " + code); 64 synchronized(mPollingSyncObj) { 65 mResult = code; 66 mIsPolling = false; 67 mPollingSyncObj.notifyAll(); 68 } 69 } 70 71 public void onFinish(int reqId) { 72 logger.print("onFinish() is called, reqId=" + reqId); 73 if (reqId == mRequestId) { 74 synchronized(mPollingSyncObj) { 75 mFullUpdated = true; 76 mIsPolling = false; 77 mPollingSyncObj.notifyAll(); 78 } 79 } 80 } 81 82 public void onTimeout(int reqId) { 83 logger.print("onTimeout() is called, reqId=" + reqId); 84 if (reqId == mRequestId) { 85 synchronized(mPollingSyncObj) { 86 mIsPolling = false; 87 mPollingSyncObj.notifyAll(); 88 } 89 } 90 } 91 }; 92 PollingAction(Context context, PollingTask task)93 public PollingAction(Context context, PollingTask task) { 94 mContext = context; 95 mPollingTask = task; 96 logger.info("PollingAction(), task=" + mPollingTask); 97 } 98 99 @Override onPreExecute()100 protected void onPreExecute() { 101 super.onPreExecute(); 102 mPollingTask.onPreExecute(); 103 } 104 105 @Override doInBackground(Void... params)106 protected Integer doInBackground(Void... params) { 107 logger.debug("doInBackground(), Thread = " + Thread.currentThread().getName()); 108 109 if (Looper.myLooper() == null) { 110 Looper.prepare(); 111 } 112 113 int requestExpiration = PresenceSetting.getCapabilityPollListSubscriptionExpiration(); 114 logger.print("getCapabilityPollListSubscriptionExpiration: " + requestExpiration); 115 if (requestExpiration == -1) { 116 requestExpiration = 30; 117 } 118 requestExpiration += 30; 119 120 mResult = ResultCode.SUBSCRIBE_NOT_FOUND; 121 ArrayList<String> uriList = new ArrayList<String>(); 122 uriList.clear(); 123 124 List<Contacts.Item> contacts = mPollingTask.mContacts; 125 for (int i = 0; i < contacts.size(); i++) { 126 Contacts.Item item = contacts.get(i); 127 uriList.add(getCompleteUri(item.number())); 128 } 129 int size = uriList.size(); 130 if (size <= 0) { 131 logger.debug("No contacts in polling task, no action."); 132 } else { 133 mResult = ResultCode.ERROR_SERVICE_NOT_AVAILABLE; 134 synchronized(mPollingSyncObj) { 135 RcsManager rcsManager = RcsManager.getInstance(mContext, 0); 136 if (rcsManager == null) { 137 logger.debug("rcsManager == null"); 138 } else { 139 try { 140 RcsPresence rcsPresence = rcsManager.getRcsPresenceInterface(); 141 if (rcsPresence == null) { 142 logger.debug("rcsPresence == null"); 143 } else { 144 logger.print("call requestCapability: " + size); 145 // If ret > 0 then it is the request Id, or it is result code. 146 int ret = rcsPresence.requestCapability(uriList, mClientListener); 147 if (ret > 0) { 148 mRequestId = ret; 149 mResult = ResultCode.SUCCESS; 150 } else { 151 mRequestId = -1; 152 mResult = ret; 153 } 154 } 155 } catch (RcsException ex) { 156 logger.print("RcsException", ex); 157 } 158 } 159 160 if (mResult == ResultCode.SUCCESS) { 161 logger.print("Capability discovery success, RequestId = " + mRequestId); 162 mIsPolling = true; 163 } else { 164 logger.info("Capability discovery failure result = " + mResult); 165 mIsPolling = false; 166 } 167 168 final long endTime = System.currentTimeMillis() + requestExpiration * 1000; 169 while(true) { 170 if (!mIsPolling) { 171 break; 172 } 173 174 long delay = endTime - System.currentTimeMillis(); 175 if (delay <= 0) { 176 break; 177 } 178 179 try { 180 mPollingSyncObj.wait(delay); 181 } catch (InterruptedException ex) { 182 } 183 } 184 } 185 } 186 187 logger.print("The action final result = " + mResult); 188 mPollingTask.onPostExecute(mResult); 189 if (ResultCode.SUBSCRIBE_TEMPORARY_ERROR == mResult) { 190 mPollingTask.retry(); 191 } else { 192 mPollingTask.finish(mFullUpdated); 193 } 194 195 return mResult; 196 } 197 getCompleteUri(String phone)198 private String getCompleteUri(String phone) { 199 phone = "tel:" + phone; 200 return phone; 201 } 202 203 @Override onPostExecute(Integer result)204 protected void onPostExecute(Integer result) { 205 super.onPostExecute(result); 206 logger.print("onPostExecute(), result = " + result); 207 } 208 } 209 210