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 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 
     93     public PollingAction(Context context, PollingTask task) {
     94         mContext = context;
     95         mPollingTask = task;
     96         logger.info("PollingAction(), task=" + mPollingTask);
     97     }
     98 
     99     @Override
    100     protected void onPreExecute() {
    101         super.onPreExecute();
    102         mPollingTask.onPreExecute();
    103     }
    104 
    105     @Override
    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 
    198     private String getCompleteUri(String phone) {
    199         phone = "tel:" + phone;
    200         return phone;
    201     }
    202 
    203     @Override
    204     protected void onPostExecute(Integer result) {
    205         super.onPostExecute(result);
    206         logger.print("onPostExecute(), result = " + result);
    207     }
    208 }
    209 
    210