• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.ims;
30 
31 import java.util.List;
32 import java.util.ArrayList;
33 import android.content.Intent;
34 import android.os.RemoteException;
35 import android.util.Log;
36 
37 import com.android.ims.internal.IRcsPresence;
38 import com.android.ims.RcsManager.ResultCode;
39 
40 /**
41  *
42  * @hide
43  */
44 public class RcsPresence {
45     static final String TAG = "RcsPresence";
46     private boolean DBG = true;
47     private IRcsPresence mIRcsPresence = null;
48 
49     /**
50      * Key to retrieve the RcsPresenceInfo list from intent ACTION_PRESENCE_CHANGED
51      * The RcsPresenceInfo list can be got by the following function call:
52      * ArrayList<RcsPresenceInfo> rcsPresenceInfoList = intent.getParcelableArrayListExtra(
53      *           RcsPresence.EXTRA_PRESENCE_INFO_LIST);
54      *
55      * @see RcsPresenceInfo
56      */
57     public static final String EXTRA_PRESENCE_INFO_LIST = "presence_info_list";
58 
59     /**
60      * Key to retrieve the subscription ID. This is for muliti-SIM implementation.
61      */
62     public static final String EXTRA_SUBID = "android:subid";
63 
64     /**
65      * The intent will be broadcasted when the presence changed.
66      * It happens on the following cases:
67      *   1. When the phone gets a NOTIFY from network.
68      *   2. When the phone gets some SUBSCRIBE error from network for some case (such as 404).
69      * It takes two extra parameters:
70      *   1. EXTRA_PRESENCE_INFO_LIST
71      *     need to get it by the following statement:
72      *     ArrayList<RcsPresenceInfo> rcsPresenceInfoList = intent.getParcelableArrayListExtra(
73      *             RcsPresence.EXTRA_PRESENCE_INFO_LIST);
74      *   2. EXTRA_SUBID
75      *
76      * @see RcsPresenceInfO
77      * @see EXTRA_PRESENCE_INFO_LIST
78      * @see EXTRA_SUBID
79      */
80     public static final String ACTION_PRESENCE_CHANGED = "com.android.ims.ACTION_PRESENCE_CHANGED";
81 
82     /**
83      * Key to retrieve "publish_state" for
84      * intent ACTION_PUBLISH_STATE_CHANGED.
85      *
86      * @See PublishState.
87      * @see ACTION_PUBLISH_STATE_CHANGED
88      */
89     public static final String EXTRA_PUBLISH_STATE = "publish_state";
90 
91     /**
92      * The intent will be broadcasted when latest publish status changed
93      * It takes two extra parameters:
94      * 1. EXTRA_PUBLISH_STATE
95      * 2. EXTRA_SUBID
96      *
97      * @see #EXTRA_PUBLISH_STATE
98      * @see #EXTRA_SUBID
99      * @see PublishState
100      */
101     public static final String ACTION_PUBLISH_STATE_CHANGED =
102             "com.android.ims.ACTION_PUBLISH_STATUS_CHANGED";
103 
104     /**
105      *  The last publish state
106      */
107     public static class PublishState {
108         /**
109          * The phone is PUBLISH_STATE_200_OK when
110          * the response of the last publish is "200 OK"
111          */
112         public static final int PUBLISH_STATE_200_OK = 0;
113 
114         /**
115          * The phone didn't publish after power on.
116          * the phone didn't get any publish response yet.
117          */
118         public static final int PUBLISH_STATE_NOT_PUBLISHED = 1;
119 
120         /**
121          * The phone is PUBLISH_STATE_VOLTE_PROVISION_ERROR when the response is one of items
122           * in config_volte_provision_error_on_publish_response for PUBLISH or
123           * in config_volte_provision_error_on_subscribe_response for SUBSCRIBE.
124          */
125         public static final int PUBLISH_STATE_VOLTE_PROVISION_ERROR = 2;
126 
127         /**
128          * The phone is PUBLISH_STATE_RCS_PROVISION_ERROR when the response is one of items
129           * in config_rcs_provision_error_on_publish_response for PUBLISH or
130           * in config_rcs_provision_error_on_subscribe_response for SUBSCRIBE.
131          */
132         public static final int PUBLISH_STATE_RCS_PROVISION_ERROR = 3;
133 
134         /**
135          * The phone is PUBLISH_STATE_REQUEST_TIMEOUT when
136          * The response of the last publish is "408 Request Timeout".
137          */
138         public static final int PUBLISH_STATE_REQUEST_TIMEOUT = 4;
139 
140         /**
141          * The phone is PUBLISH_STATE_OTHER_ERROR when
142          * the response of the last publish is other temp error. Such as
143          * 503 Service Unavailable
144          * Device shall retry with exponential back-off
145          *
146          * 423 Interval Too Short. Requested expiry interval too short and server rejects it
147          * Device shall re-attempt subscription after changing the expiration interval in
148          * the Expires header field to be equal to or greater than the expiration interval
149          * within the Min-Expires header field of the 423 response
150          *
151          * ...
152          */
153         public static final int PUBLISH_STATE_OTHER_ERROR = 5;
154     };
155 
156     /**
157      * Constructor.
158      * @param presenceService the IRcsPresence which get by RcsManager.getRcsPresenceInterface.
159      *
160      * @see RcsManager#getRcsPresenceInterface
161      */
RcsPresence(IRcsPresence presenceService)162     public RcsPresence(IRcsPresence presenceService) {
163         if (DBG) Log.d(TAG, "IRcsPresence creates");
164 
165         mIRcsPresence = presenceService;
166     }
167 
168     /**
169      * Send the request to the server to get the capability.
170      *   1. If the presence service sent the request to network successfully
171      * then it will return the request ID (>0). It will not wait for the response from
172      * network. The response from network will be returned by callback onSuccess() or onError().
173      *   2. If the presence service failed to send the request to network then it will return error
174      *  code which is defined by RcsManager.ResultCode (<0).
175      *   3. If the network returns "200 OK" for a request then the listener.onSuccess() will be
176      * called by presence service.
177      *   4. If the network resturns "404" for a single target number then it means the target
178      * number is not VoLte capable, so the listener.onSuccess() will be called and intent
179      * ACTION_PRESENCE_CHANGED will be broadcasted by presence service.
180      *   5. If the network returns other error then the listener.onError() will be called by
181      * presence service.
182      *   6. If the network returns "200 OK" then we can expect the presence service receives notify
183      * from network. If the presence service receives notify then it will broadcast the
184      * intent ACTION_PRESENCE_CHANGED. If the notify state is "terminated" then the
185      * listener.onFinish() will be called by presence service as well.
186      *   7. If the presence service doesn't get response after "Subscribe Expiration + T1" then the
187      * listener.onTimeout() will be called by presence service.
188      *
189      * @param contactsNumber the contact number list which will be requested.
190      * @param listener the IRcsPresenceListener which will return the status and response.
191      *
192      * @return the request ID if it is >0. Or it is RcsManager.ResultCode for error.
193      *
194      * @see IRcsPresenceListener
195      * @see RcsManager.ResultCode
196      */
requestCapability(List<String> contactsNumber, IRcsPresenceListener listener)197     public int requestCapability(List<String> contactsNumber,
198             IRcsPresenceListener listener) throws RcsException {
199         if (DBG) Log.d(TAG, "call requestCapability, contactsNumber=" + contactsNumber);
200         int ret = ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
201 
202         try {
203             ret = mIRcsPresence.requestCapability(contactsNumber, listener);
204         }  catch (RemoteException e) {
205             throw new RcsException("requestCapability", e,
206                     ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
207         }
208 
209         if (DBG) Log.d(TAG, "requestCapability ret =" + ret);
210         return ret;
211     }
212 
213     /**
214      * Send the request to the server to get the availability.
215      *   1. If the presence service sent the request to network successfully then it will return
216      * the request ID (>0).
217      *   2. If the presence serive failed to send the request to network then it will return error
218      * code which is defined by RcsManager.ResultCode (<0).
219      *   3. If the network returns "200 OK" for a request then the listener.onSuccess() will be
220      * called by presence service.
221      *   4. If the network resturns "404" then it means the target number is not VoLte capable,
222      * so the listener.onSuccess() will be called and intent ACTION_PRESENCE_CHANGED will be
223      * broadcasted by presence service.
224      *   5. If the network returns other error code then the listener.onError() will be called by
225      * presence service.
226      *   6. If the network returns "200 OK" then we can expect the presence service receives notify
227      * from network. If the presence service receives notify then it will broadcast the intent
228      * ACTION_PRESENCE_CHANGED. If the notify state is "terminated" then the listener.onFinish()
229      * will be called by presence service as well.
230      *   7. If the presence service doesn't get response after "Subscribe Expiration + T1" then it
231      * will call listener.onTimeout().
232      *
233      * @param contactNumber the contact which will request the availability.
234      *     Only support phone number at present.
235      * @param listener the IRcsPresenceListener to get the response.
236      *
237      * @return the request ID if it is >0. Or it is RcsManager.ResultCode for error.
238      *
239      * @see IRcsPresenceListener
240      * @see RcsManager.ResultCode
241      * @see RcsPresence.ACTION_PRESENCE_CHANGED
242      */
requestAvailability(String contactNumber, IRcsPresenceListener listener)243     public int requestAvailability(String contactNumber, IRcsPresenceListener listener)
244              throws RcsException {
245         if (DBG) Log.d(TAG, "call requestAvailability, contactNumber=" + contactNumber);
246         int ret = ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
247 
248         try {
249             ret = mIRcsPresence.requestAvailability(contactNumber, listener);
250         }  catch (RemoteException e) {
251             throw new RcsException("requestAvailability", e,
252                     ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
253         }
254 
255         if (DBG) Log.d(TAG, "requestAvailability ret =" + ret);
256         return ret;
257     }
258 
259     /**
260      * Same as requestAvailability. but requestAvailability will consider throttle to avoid too
261      * fast call. Which means it will not send the request to network in next 60s for the same
262      * request.
263      * The error code SUBSCRIBE_TOO_FREQUENTLY will be returned under the case.
264      * But for this funcation it will always send the request to network.
265      *
266      * @see IRcsPresenceListener
267      * @see RcsManager.ResultCode
268      * @see RcsPresence.ACTION_PRESENCE_CHANGED
269      * @see ResultCode.SUBSCRIBE_TOO_FREQUENTLY
270      */
requestAvailabilityNoThrottle(String contactNumber, IRcsPresenceListener listener)271     public int requestAvailabilityNoThrottle(String contactNumber, IRcsPresenceListener listener)
272              throws RcsException {
273         if (DBG) Log.d(TAG, "call requestAvailabilityNoThrottle, contactNumber=" + contactNumber);
274         int ret = ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
275 
276         try {
277             ret = mIRcsPresence.requestAvailabilityNoThrottle(contactNumber, listener);
278         }  catch (RemoteException e) {
279             throw new RcsException("requestAvailabilityNoThrottle", e,
280                     ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
281         }
282 
283         if (DBG) Log.d(TAG, "requestAvailabilityNoThrottle ret =" + ret);
284         return ret;
285     }
286 
287     /**
288      * Get the latest publish state.
289      *
290      * @see PublishState
291      */
getPublishState()292     public int getPublishState() throws RcsException {
293         int ret = PublishState.PUBLISH_STATE_NOT_PUBLISHED;
294         try {
295             ret = mIRcsPresence.getPublishState();
296         }  catch (RemoteException e) {
297             throw new RcsException("getPublishState", e,
298                     ResultCode.ERROR_SERVICE_NOT_AVAILABLE);
299         }
300 
301         if (DBG) Log.d(TAG, "getPublishState ret =" + ret);
302         return ret;
303     }
304 }
305 
306