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_BASE_URI
= "baseURI";
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_BASE_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
, "onBind -> baseURI=" + requestBaseURI
);
72 Log
.d(TAG
, "onBind -> requestDeviceCode=" + requestDeviceCode
);
73 Log
.d(TAG
, "onBind -> requestInterval=" + requestInterval
);
75 Log
.e(TAG
, "onBind -> params could not be null");
78 return Service
.START_NOT_STICKY
;
82 public void onCreate() {
87 public void onDestroy() {
92 private void startService() {
93 final UrlEncodedFormEntity params
= prepareComm();
94 timer
.scheduleAtFixedRate(
99 }, 0, requestInterval
* 1000);
100 Log
.d(TAG
, "startService -> Timer started");
103 private void shutdownService() {
104 if (timer
!= null
) timer
.cancel();
105 Log
.d(TAG
, "shutdownService -> Timer stopped");
109 private UrlEncodedFormEntity
prepareComm() {
111 UrlEncodedFormEntity params
= null
;
112 connectorOAuth2
= new ConnectorOAuth2();
114 if (requestBaseURI
== null
|| requestBaseURI
.trim().equals("")) {
115 Log
.e(TAG
, "run -> request URI could not be null");
119 if (requestInterval
== -1) {
120 Log
.e(TAG
, "run -> request Interval must have valid positive value");
124 if (requestDeviceCode
== null
|| requestDeviceCode
.trim().equals("")) {
125 Log
.e(TAG
, "run -> request DeviceCode could not be null");
130 connectorOAuth2
.setConnectorOAuth2Url(requestBaseURI
+ OAuth2Context
.OAUTH2_DEVICE_GETTOKEN_URL
);
132 List
<NameValuePair
> nameValuePairs
= new ArrayList
<NameValuePair
>(2);
133 nameValuePairs
.add(new BasicNameValuePair("client_id", OAuth2Context
.OAUTH2_DEVICE_CLIENT_ID
));
134 nameValuePairs
.add(new BasicNameValuePair("client_secret", OAuth2Context
.OAUTH2_DEVICE_CLIENT_SECRET
));
135 nameValuePairs
.add(new BasicNameValuePair("code",requestDeviceCode
));
136 nameValuePairs
.add(new BasicNameValuePair("grant_type",OAuth2Context
.OAUTH_DEVICE_GETTOKEN_GRANT_TYPE
));
138 params
= new UrlEncodedFormEntity(nameValuePairs
);
140 catch (Exception ex1
){
141 Log
.w(TAG
, ex1
.toString());
148 protected void requestToken(UrlEncodedFormEntity params
){
149 JSONObject tokenJson
= null
;
151 HashMap
<String
, String
> resultTokenMap
;
153 String tokenResponse
= connectorOAuth2
.connPost(params
);
156 tokenJson
= new JSONObject(tokenResponse
);
157 } catch (JSONException e
) {
158 Log
.e(TAG
, "Exception converting to Json " + e
.toString());
162 // We try to get error string.
163 if (tokenJson
.has(TOKEN_RECEIVED_ERROR
)) {
164 error
= tokenJson
.getString(TOKEN_RECEIVED_ERROR
);
165 Log
.d(TAG
, "requestToken -> Obtained error "+ error
);
167 //We have got the token. Parse the answer.
168 resultTokenMap
= parseResult(tokenJson
);
169 postResult(resultTokenMap
);
171 } catch (JSONException e
) {
172 Log
.e(TAG
, "Exception converting to Json " + e
.toString());
176 private HashMap
<String
, String
> parseResult (JSONObject tokenJson
) {
177 HashMap
<String
, String
> resultTokenMap
=new HashMap
<String
, String
>();
180 resultTokenMap
.put(TOKEN_ACCESS_TOKEN
, tokenJson
.getString(TOKEN_ACCESS_TOKEN
));
181 resultTokenMap
.put(TOKEN_TOKEN_TYPE
, tokenJson
.getString(TOKEN_TOKEN_TYPE
));
182 resultTokenMap
.put(TOKEN_EXPIRES_IN
, tokenJson
.getString(TOKEN_EXPIRES_IN
));
183 resultTokenMap
.put(TOKEN_REFRESH_TOKEN
, tokenJson
.getString(TOKEN_REFRESH_TOKEN
));
184 } catch (JSONException e
) {
185 Log
.e(TAG
, "parseResult: Exception converting to Json " + e
.toString());
187 return resultTokenMap
;
191 * Returns obtained values with a broadcast.
193 * @param tokenResponse : obtained values.
195 private void postResult(HashMap
<String
, String
> tokenResponse
) {
196 Intent intent
= new Intent(TOKEN_RECEIVED_MESSAGE
);
197 intent
.putExtra(TOKEN_RECEIVED_DATA
,tokenResponse
);
198 sendBroadcast(intent
);