| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chromoting; | 5 package org.chromium.chromoting.base; |
| 6 | 6 |
| 7 import android.app.Activity; | 7 import android.app.Activity; |
| 8 import android.os.AsyncTask; | 8 import android.os.AsyncTask; |
| 9 | 9 |
| 10 import com.google.android.gms.auth.GoogleAuthException; | 10 import com.google.android.gms.auth.GoogleAuthException; |
| 11 import com.google.android.gms.auth.GoogleAuthUtil; | 11 import com.google.android.gms.auth.GoogleAuthUtil; |
| 12 import com.google.android.gms.auth.UserRecoverableAuthException; | 12 import com.google.android.gms.auth.UserRecoverableAuthException; |
| 13 | 13 |
| 14 import java.io.IOException; | 14 import java.io.IOException; |
| 15 | 15 |
| 16 /** | 16 /** |
| 17 * This helper class fetches an OAuth token on a separate thread, and properly h
andles the various | 17 * This helper class fetches an OAuth token on a separate thread, and properly h
andles the various |
| 18 * error-conditions that can occur (such as, starting an Activity to prompt user
for input). | 18 * error-conditions that can occur (such as, starting an Activity to prompt user
for input). |
| 19 */ | 19 */ |
| 20 public class OAuthTokenFetcher { | 20 public class OAuthTokenFetcher { |
| 21 /** | 21 /** |
| 22 * Callback interface to receive the token, or an error notification. These
will be called | 22 * Callback interface to receive the token, or an error notification. These
will be called |
| 23 * on the application's main thread. Note that if a user-recoverable error o
ccurs, neither of | 23 * on the application's main thread. Note that if a user-recoverable error o
ccurs, neither of |
| 24 * these callback will be triggered. Instead, a new Activity will be launche
d, and the calling | 24 * these callback will be triggered. Instead, a new Activity will be launche
d, and the calling |
| 25 * Activity must override | 25 * Activity must override |
| 26 * {@link android.app.Activity#onActivityResult} and handle the result code | 26 * {@link android.app.Activity#onActivityResult} and handle the result code |
| 27 * {@link REQUEST_CODE_RECOVER_FROM_OAUTH_ERROR} to re-attempt or cancel fet
ching the token. | 27 * {@link REQUEST_CODE_RECOVER_FROM_OAUTH_ERROR} to re-attempt or cancel fet
ching the token. |
| 28 */ | 28 */ |
| 29 public interface Callback { | 29 public interface Callback { |
| 30 /** Called when a token is obtained. */ | 30 /** Called when a token is obtained. */ |
| 31 void onTokenFetched(String token); | 31 void onTokenFetched(String token); |
| 32 | 32 |
| 33 /** | 33 /** |
| 34 * Called if an unrecoverable error prevents fetching a token. | 34 * Called if an unrecoverable error prevents fetching a token. |
| 35 * @param errorResource String resource of error-message to be displayed
. | |
| 36 */ | 35 */ |
| 37 void onError(int errorResource); | 36 void onError(Error error); |
| 38 } | 37 } |
| 39 | 38 |
| 39 /** Error types that can be returned as non-recoverable errors from the toke
n-fetcher. */ |
| 40 public enum Error { NETWORK, UNEXPECTED } |
| 41 |
| 40 /** Request code used for starting the OAuth recovery activity. */ | 42 /** Request code used for starting the OAuth recovery activity. */ |
| 41 public static final int REQUEST_CODE_RECOVER_FROM_OAUTH_ERROR = 100; | 43 public static final int REQUEST_CODE_RECOVER_FROM_OAUTH_ERROR = 100; |
| 42 | 44 |
| 43 /** Scopes at which the authentication token we request will be valid. */ | |
| 44 private static final String TOKEN_SCOPE = "oauth2:https://www.googleapis.com
/auth/chromoting " | |
| 45 + "https://www.googleapis.com/auth/googletalk"; | |
| 46 | |
| 47 /** | 45 /** |
| 48 * Reference to the main activity. Used for running tasks on the main thread
, and for | 46 * Reference to the main activity. Used for running tasks on the main thread
, and for |
| 49 * starting other activities to handle user-recoverable errors. | 47 * starting other activities to handle user-recoverable errors. |
| 50 */ | 48 */ |
| 51 private Activity mActivity; | 49 private Activity mActivity; |
| 52 | 50 |
| 53 /** Account name (e-mail) for which the token will be fetched. */ | 51 /** Account name (e-mail) for which the token will be fetched. */ |
| 54 private String mAccountName; | 52 private String mAccountName; |
| 55 | 53 |
| 54 /** OAuth scope used for the token request. */ |
| 55 private String mTokenScope; |
| 56 |
| 56 private Callback mCallback; | 57 private Callback mCallback; |
| 57 | 58 |
| 58 public OAuthTokenFetcher(Activity activity, String accountName, Callback cal
lback) { | 59 public OAuthTokenFetcher(Activity activity, String accountName, String token
Scope, |
| 60 Callback callback) { |
| 59 mActivity = activity; | 61 mActivity = activity; |
| 60 mAccountName = accountName; | 62 mAccountName = accountName; |
| 63 mTokenScope = tokenScope; |
| 61 mCallback = callback; | 64 mCallback = callback; |
| 62 } | 65 } |
| 63 | 66 |
| 64 /** Begins fetching a token. Should be called on the main thread. */ | 67 /** Begins fetching a token. Should be called on the main thread. */ |
| 65 public void fetch() { | 68 public void fetch() { |
| 66 fetchImpl(null); | 69 fetchImpl(null); |
| 67 } | 70 } |
| 68 | 71 |
| 69 /** | 72 /** |
| 70 * Begins fetching a token, clearing an existing token from the cache. Shoul
d be called on the | 73 * Begins fetching a token, clearing an existing token from the cache. Shoul
d be called on the |
| 71 * main thread. | 74 * main thread. |
| 72 * @param expiredToken A previously-fetched token which has expired. | 75 * @param expiredToken A previously-fetched token which has expired. |
| 73 */ | 76 */ |
| 74 public void clearAndFetch(String expiredToken) { | 77 public void clearAndFetch(String expiredToken) { |
| 75 fetchImpl(expiredToken); | 78 fetchImpl(expiredToken); |
| 76 } | 79 } |
| 77 | 80 |
| 78 private void fetchImpl(final String expiredToken) { | 81 private void fetchImpl(final String expiredToken) { |
| 79 new AsyncTask<Void, Void, Void>() { | 82 new AsyncTask<Void, Void, Void>() { |
| 80 @Override | 83 @Override |
| 81 protected Void doInBackground(Void... params) { | 84 protected Void doInBackground(Void... params) { |
| 82 try { | 85 try { |
| 83 if (expiredToken != null) { | 86 if (expiredToken != null) { |
| 84 GoogleAuthUtil.clearToken(mActivity, expiredToken); | 87 GoogleAuthUtil.clearToken(mActivity, expiredToken); |
| 85 } | 88 } |
| 86 | 89 |
| 87 // This method is deprecated but its replacement is not yet
available. | 90 // This method is deprecated but its replacement is not yet
available. |
| 88 // TODO(lambroslambrou): Fix this by replacing |mAccountName
| with an instance | 91 // TODO(lambroslambrou): Fix this by replacing |mAccountName
| with an instance |
| 89 // of android.accounts.Account. | 92 // of android.accounts.Account. |
| 90 String token = GoogleAuthUtil.getToken(mActivity, mAccountNa
me, TOKEN_SCOPE); | 93 String token = GoogleAuthUtil.getToken(mActivity, mAccountNa
me, mTokenScope); |
| 91 handleTokenReceived(token); | 94 handleTokenReceived(token); |
| 92 } catch (IOException ioException) { | 95 } catch (IOException ioException) { |
| 93 handleError(R.string.error_network_error); | 96 handleError(Error.NETWORK); |
| 94 } catch (UserRecoverableAuthException recoverableException) { | 97 } catch (UserRecoverableAuthException recoverableException) { |
| 95 handleRecoverableException(recoverableException); | 98 handleRecoverableException(recoverableException); |
| 96 } catch (GoogleAuthException fatalException) { | 99 } catch (GoogleAuthException fatalException) { |
| 97 handleError(R.string.error_unexpected); | 100 handleError(Error.UNEXPECTED); |
| 98 } | 101 } |
| 99 return null; | 102 return null; |
| 100 } | 103 } |
| 101 }.execute(); | 104 }.execute(); |
| 102 } | 105 } |
| 103 | 106 |
| 104 private void handleTokenReceived(final String token) { | 107 private void handleTokenReceived(final String token) { |
| 105 mActivity.runOnUiThread(new Runnable() { | 108 mActivity.runOnUiThread(new Runnable() { |
| 106 @Override | 109 @Override |
| 107 public void run() { | 110 public void run() { |
| 108 mCallback.onTokenFetched(token); | 111 mCallback.onTokenFetched(token); |
| 109 } | 112 } |
| 110 }); | 113 }); |
| 111 } | 114 } |
| 112 | 115 |
| 113 private void handleError(final int error) { | 116 private void handleError(final Error error) { |
| 114 mActivity.runOnUiThread(new Runnable() { | 117 mActivity.runOnUiThread(new Runnable() { |
| 115 @Override | 118 @Override |
| 116 public void run() { | 119 public void run() { |
| 117 mCallback.onError(error); | 120 mCallback.onError(error); |
| 118 } | 121 } |
| 119 }); | 122 }); |
| 120 } | 123 } |
| 121 | 124 |
| 122 private void handleRecoverableException(final UserRecoverableAuthException e
xception) { | 125 private void handleRecoverableException(final UserRecoverableAuthException e
xception) { |
| 123 mActivity.runOnUiThread(new Runnable() { | 126 mActivity.runOnUiThread(new Runnable() { |
| 124 @Override | 127 @Override |
| 125 public void run() { | 128 public void run() { |
| 126 mActivity.startActivityForResult(exception.getIntent(), | 129 mActivity.startActivityForResult(exception.getIntent(), |
| 127 REQUEST_CODE_RECOVER_FROM_OAUTH_ERROR); | 130 REQUEST_CODE_RECOVER_FROM_OAUTH_ERROR); |
| 128 } | 131 } |
| 129 }); | 132 }); |
| 130 } | 133 } |
| 131 } | 134 } |
| OLD | NEW |