1 package com
.owncloud
.android
.authenticator
.oauth2
.services
;
3 import java
.util
.ArrayList
;
4 import java
.util
.HashMap
;
6 import java
.util
.Timer
;
7 import java
.util
.TimerTask
;
9 import org
.apache
.http
.NameValuePair
;
10 import org
.apache
.http
.client
.entity
.UrlEncodedFormEntity
;
11 import org
.apache
.http
.message
.BasicNameValuePair
;
12 import org
.json
.JSONException
;
13 import org
.json
.JSONObject
;
15 import android
.app
.Service
;
16 import android
.content
.Intent
;
17 import android
.os
.Bundle
;
18 import android
.os
.IBinder
;
19 import android
.util
.Log
;
21 import com
.owncloud
.android
.authenticator
.oauth2
.OAuth2Context
;
22 import com
.owncloud
.android
.authenticator
.oauth2
.connection
.ConnectorOAuth2
;
25 * Service class that implements the second communication with the oAuth2 server:
26 * pooling for the token in an interval. It send a broadcast with the results when are positive;
27 * otherwise, it continues asking to the server.
29 * @author Solid Gear S.L.
32 public class OAuth2GetTokenService
extends Service
{
34 public static final String TOKEN_RECEIVED_MESSAGE
= "TOKEN_RECEIVED";
35 public static final String TOKEN_RECEIVED_DATA
= "TOKEN_DATA";
36 public static final String TOKEN_URI
= "TOKEN_URI";
37 public static final String TOKEN_DEVICE_CODE
= "device_code";
38 public static final String TOKEN_INTERVAL
= "interval";
39 public static final String TOKEN_RECEIVED_ERROR
= "error";
40 public static final String TOKEN_RECEIVED_ERROR_AUTH_TOKEN
= "authorization_pending";
41 public static final String TOKEN_RECEIVED_ERROR_SLOW_DOWN
= "slow_down";
42 public static final String TOKEN_ACCESS_TOKEN
= "access_token";
43 public static final String TOKEN_TOKEN_TYPE
= "token_type";
44 public static final String TOKEN_EXPIRES_IN
= "expires_in";
45 public static final String TOKEN_REFRESH_TOKEN
= "refresh_token";
47 private String requestDeviceCode
;
48 private int requestInterval
= -1;
49 private String requestBaseURI
;
50 private ConnectorOAuth2 connectorOAuth2
;
51 private static final String TAG
= "OAuth2GetTokenService";
52 private Timer timer
= new Timer();
55 public IBinder
onBind(Intent arg0
) {
60 public int onStartCommand(Intent intent
, int flags
, int startId
) {
61 Bundle param
= intent
.getExtras();
64 String mUrl
= param
.getString(TOKEN_URI
);
65 if (!mUrl
.startsWith("http://") || !mUrl
.startsWith("https://")) {
66 requestBaseURI
= "https://" + mUrl
;
68 requestDeviceCode
= param
.getString(TOKEN_DEVICE_CODE
);
69 requestInterval
= param
.getInt(TOKEN_INTERVAL
);
71 Log
.d(TAG
, "onStartCommand -> requestDeviceCode=" + requestDeviceCode
);
72 Log
.d(TAG
, "onStartCommand -> requestInterval=" + requestInterval
);
74 Log
.e(TAG
, "onStartCommand -> params could not be null");
77 return Service
.START_NOT_STICKY
;
81 public void onCreate() {
86 public void onDestroy() {
91 private void startService() {
92 final UrlEncodedFormEntity params
= prepareComm();
93 timer
.scheduleAtFixedRate(
98 }, 0, requestInterval
* 1000);
99 Log
.d(TAG
, "startService -> Timer started");
102 private void shutdownService() {
103 if (timer
!= null
) timer
.cancel();
104 Log
.d(TAG
, "shutdownService -> Timer stopped");
108 private UrlEncodedFormEntity
prepareComm() {
110 UrlEncodedFormEntity params
= null
;
111 connectorOAuth2
= new ConnectorOAuth2();
113 if (requestBaseURI
== null
|| requestBaseURI
.trim().equals("")) {
114 Log
.e(TAG
, "run -> request URI could not be null");
118 if (requestInterval
== -1) {
119 Log
.e(TAG
, "run -> request Interval must have valid positive value");
123 if (requestDeviceCode
== null
|| requestDeviceCode
.trim().equals("")) {
124 Log
.e(TAG
, "run -> request DeviceCode could not be null");
129 connectorOAuth2
.setConnectorOAuth2Url(requestBaseURI
+ OAuth2Context
.OAUTH2_G_DEVICE_GETTOKEN_URL
);
131 List
<NameValuePair
> nameValuePairs
= new ArrayList
<NameValuePair
>(2);
132 nameValuePairs
.add(new BasicNameValuePair("client_id", OAuth2Context
.OAUTH2_G_DEVICE_CLIENT_ID
));
133 nameValuePairs
.add(new BasicNameValuePair("client_secret", OAuth2Context
.OAUTH2_G_DEVICE_CLIENT_SECRET
));
134 nameValuePairs
.add(new BasicNameValuePair("code",requestDeviceCode
));
135 nameValuePairs
.add(new BasicNameValuePair("grant_type",OAuth2Context
.OAUTH_G_DEVICE_GETTOKEN_GRANT_TYPE
));
137 params
= new UrlEncodedFormEntity(nameValuePairs
);
139 catch (Exception ex1
){
140 Log
.w(TAG
, ex1
.toString());
147 protected void requestToken(UrlEncodedFormEntity params
){
148 JSONObject tokenJson
= null
;
150 HashMap
<String
, String
> resultTokenMap
;
152 String tokenResponse
= connectorOAuth2
.connPost(params
);
155 tokenJson
= new JSONObject(tokenResponse
);
156 } catch (JSONException e
) {
157 Log
.e(TAG
, "Exception converting to Json " + e
.toString());
161 // We try to get error string.
162 if (tokenJson
.has(TOKEN_RECEIVED_ERROR
)) {
163 error
= tokenJson
.getString(TOKEN_RECEIVED_ERROR
);
164 Log
.d(TAG
, "requestToken -> Obtained error "+ error
);
166 //We have got the token. Parse the answer.
167 resultTokenMap
= parseResult(tokenJson
);
168 postResult(resultTokenMap
);
170 } catch (JSONException e
) {
171 Log
.e(TAG
, "Exception converting to Json " + e
.toString());
175 private HashMap
<String
, String
> parseResult (JSONObject tokenJson
) {
176 HashMap
<String
, String
> resultTokenMap
=new HashMap
<String
, String
>();
179 resultTokenMap
.put(TOKEN_ACCESS_TOKEN
, tokenJson
.getString(TOKEN_ACCESS_TOKEN
));
180 resultTokenMap
.put(TOKEN_TOKEN_TYPE
, tokenJson
.getString(TOKEN_TOKEN_TYPE
));
181 resultTokenMap
.put(TOKEN_EXPIRES_IN
, tokenJson
.getString(TOKEN_EXPIRES_IN
));
182 resultTokenMap
.put(TOKEN_REFRESH_TOKEN
, tokenJson
.getString(TOKEN_REFRESH_TOKEN
));
183 } catch (JSONException e
) {
184 Log
.e(TAG
, "parseResult: Exception converting to Json " + e
.toString());
186 return resultTokenMap
;
190 * Returns obtained values with a broadcast.
192 * @param tokenResponse : obtained values.
194 private void postResult(HashMap
<String
, String
> tokenResponse
) {
195 Intent intent
= new Intent(TOKEN_RECEIVED_MESSAGE
);
196 intent
.putExtra(TOKEN_RECEIVED_DATA
,tokenResponse
);
197 sendBroadcast(intent
);