From 62d10b3fde07f34cc4693d9168528729a6731a79 Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Tue, 9 Feb 2016 20:20:56 +0100 Subject: [PATCH 01/14] Update grade, RxJava, GSON and other libraries --- library/build.gradle | 10 +-- sample/build.gradle | 19 +++--- .../actvities/LoginActivity.java | 11 +-- .../heimdalldroid/actvities/MainActivity.java | 10 +-- .../utils/rx/RxAppCompatActivity.java | 68 ------------------- 5 files changed, 28 insertions(+), 90 deletions(-) delete mode 100644 sample/src/main/java/de/rheinfabrik/heimdalldroid/utils/rx/RxAppCompatActivity.java diff --git a/library/build.gradle b/library/build.gradle index fbefb9b..c51769a 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -20,8 +20,8 @@ buildscript { group = 'com.github.rheinfabrik' android { - compileSdkVersion 22 - buildToolsVersion "22.0.1" + compileSdkVersion 23 + buildToolsVersion "23.0.2" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -36,7 +36,7 @@ android { defaultConfig { minSdkVersion 9 - targetSdkVersion 22 + targetSdkVersion 23 versionCode 103 versionName "1.0.3" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -57,10 +57,10 @@ repositories { dependencies { // Rx - compile 'io.reactivex:rxjava:1.0.12' + compile 'io.reactivex:rxjava:1.0.14' // GSON - compile 'com.google.code.gson:gson:2.3.1' + compile 'com.google.code.gson:gson:2.4' // Spock androidTestCompile 'org.codehaus.groovy:groovy:2.4.2:grooid' diff --git a/sample/build.gradle b/sample/build.gradle index a9ca568..fb9b6f4 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -12,13 +12,13 @@ buildscript { } android { - compileSdkVersion 22 - buildToolsVersion "22.0.1" + compileSdkVersion 23 + buildToolsVersion "23.0.2" defaultConfig { applicationId "de.rheinfabrik.heimdall" minSdkVersion 15 - targetSdkVersion 22 + targetSdkVersion 23 versionCode 1 versionName "1.0" } @@ -33,18 +33,21 @@ android { dependencies { // Android - compile 'com.android.support:appcompat-v7:22.2.0' - compile 'com.android.support:recyclerview-v7:21.0.0' - compile 'com.android.support:cardview-v7:21.0.3' + compile 'com.android.support:appcompat-v7:23.1.1' + compile 'com.android.support:recyclerview-v7:23.1.1' + compile 'com.android.support:cardview-v7:23.1.1' // Heimdall compile project(':library') // Rx - compile 'io.reactivex:rxandroid-framework:0.24.0' + compile 'io.reactivex:rxandroid:1.0.1' + compile 'io.reactivex:rxjava:1.0.14' + compile 'com.trello:rxlifecycle:0.3.0' + compile 'com.trello:rxlifecycle-components:0.3.0' // Serialization - compile 'com.google.code.gson:gson:2.3' + compile 'com.google.code.gson:gson:2.4' compile 'org.parceler:parceler-api:0.2.16' // Network diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/LoginActivity.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/LoginActivity.java index af15c43..c0cf6f6 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/LoginActivity.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/LoginActivity.java @@ -7,17 +7,16 @@ import android.webkit.WebView; import android.webkit.WebViewClient; +import com.trello.rxlifecycle.components.support.RxAppCompatActivity; + import butterknife.ButterKnife; import butterknife.InjectView; import de.rheinfabrik.heimdalldroid.R; import de.rheinfabrik.heimdalldroid.network.oauth2.TraktTvAuthorizationCodeGrant; import de.rheinfabrik.heimdalldroid.network.oauth2.TraktTvOauth2AccessTokenManager; import de.rheinfabrik.heimdalldroid.utils.AlertDialogFactory; -import de.rheinfabrik.heimdalldroid.utils.rx.RxAppCompatActivity; import rx.android.schedulers.AndroidSchedulers; -import static rx.android.lifecycle.LifecycleObservable.bindActivityLifecycle; - /** * Activity used to let the user login with his GitHub credentials. * You may want to move most of this code to your presenter class or view model. @@ -57,8 +56,9 @@ private void authorize() { TraktTvAuthorizationCodeGrant grant = tokenManager.newAuthorizationCodeGrant(); // Listen for the authorization url and load it once needed - bindActivityLifecycle(lifecycle(), grant.authorizationUri()) + grant.authorizationUri() .map(Uri::toString) + .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(mWebView::loadUrl); @@ -79,7 +79,8 @@ public void onPageStarted(WebView view, String url, Bitmap favicon) { }); // Start authorization and listen for success - bindActivityLifecycle(lifecycle(), tokenManager.grantNewAccessToken(grant)) + tokenManager.grantNewAccessToken(grant) + .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(x -> handleSuccess(), x -> handleError()); } diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java index 3b69bce..41a2cb5 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java @@ -8,6 +8,8 @@ import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import com.trello.rxlifecycle.components.support.RxAppCompatActivity; + import java.util.List; import butterknife.ButterKnife; @@ -19,12 +21,10 @@ import de.rheinfabrik.heimdalldroid.network.oauth2.TraktTvOauth2AccessTokenManager; import de.rheinfabrik.heimdalldroid.utils.AlertDialogFactory; import de.rheinfabrik.heimdalldroid.utils.IntentFactory; -import de.rheinfabrik.heimdalldroid.utils.rx.RxAppCompatActivity; +import retrofit.RetrofitError; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; -import static rx.android.lifecycle.LifecycleObservable.bindActivityLifecycle; - /** * Activity showing either the list of the user's repositories or the login screen. * You may want to move most of this code to your presenter class or view model. @@ -107,7 +107,8 @@ private void loadLists() { .concatMap(authorizationHeader -> TraktTvApiFactory.newApiService().getLists(authorizationHeader)); // Bind to lifecycle - bindActivityLifecycle(lifecycle(), listsObservable) + listsObservable + .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(lists -> { if (lists == null || lists.isEmpty()) { @@ -152,6 +153,7 @@ private void refresh() { mSwipeRefreshLayout.setRefreshing(true); mTokenManager.getStorage().hasAccessToken() + .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(loggedIn -> { if (loggedIn) { diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/utils/rx/RxAppCompatActivity.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/utils/rx/RxAppCompatActivity.java deleted file mode 100644 index ed136c3..0000000 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/utils/rx/RxAppCompatActivity.java +++ /dev/null @@ -1,68 +0,0 @@ -package de.rheinfabrik.heimdalldroid.utils.rx; - -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; - -import rx.Observable; -import rx.android.lifecycle.LifecycleEvent; -import rx.subjects.BehaviorSubject; - -/** - * An Activity with reactive extensions. - */ -public class RxAppCompatActivity extends AppCompatActivity { - - // Members - - private final BehaviorSubject lifecycleSubject = BehaviorSubject.create(); - - // Public Api - - public Observable lifecycle() { - return lifecycleSubject.asObservable(); - } - - // Activity lifecycle - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - lifecycleSubject.onNext(LifecycleEvent.CREATE); - } - - @Override - protected void onStart() { - super.onStart(); - - lifecycleSubject.onNext(LifecycleEvent.START); - } - - @Override - protected void onResume() { - super.onResume(); - - lifecycleSubject.onNext(LifecycleEvent.RESUME); - } - - @Override - protected void onPause() { - lifecycleSubject.onNext(LifecycleEvent.PAUSE); - - super.onPause(); - } - - @Override - protected void onStop() { - lifecycleSubject.onNext(LifecycleEvent.STOP); - - super.onStop(); - } - - @Override - protected void onDestroy() { - lifecycleSubject.onNext(LifecycleEvent.DESTROY); - - super.onDestroy(); - } -} From 00b37be65df254b91263d540b6aa49079506d0d4 Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Tue, 9 Feb 2016 20:21:05 +0100 Subject: [PATCH 02/14] Add custom error handling --- .../heimdalldroid/actvities/MainActivity.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java index 41a2cb5..25cc2d2 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java @@ -116,7 +116,7 @@ private void loadLists() { } else { handleSuccess(lists); } - }, x -> handleError()); + }, this::handleError); } // Start the LoginActivity. @@ -135,10 +135,20 @@ private void handleEmptyList() { } // Show an error dialog - private void handleError() { + private void handleError(Throwable error) { mSwipeRefreshLayout.setRefreshing(false); - AlertDialogFactory.errorAlertDialog(this).show(); + // Clear token and login if 401 + if (error instanceof RetrofitError) { + RetrofitError retrofitError = (RetrofitError) error; + if (retrofitError.getResponse().getStatus() == 401) { + mTokenManager.getStorage().removeAccessToken(); + + refresh(); + } + } else { + AlertDialogFactory.errorAlertDialog(this).show(); + } } // Update our recycler view From bbcda8b827f2c52e00d789604eaa9b97fb2d2dd4 Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Tue, 9 Feb 2016 20:21:14 +0100 Subject: [PATCH 03/14] API_KEY is CLIENT_ID --- .../de/rheinfabrik/heimdalldroid/network/TraktTvApiFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/TraktTvApiFactory.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/TraktTvApiFactory.java index 1d2b0c7..f9c47ee 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/TraktTvApiFactory.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/TraktTvApiFactory.java @@ -27,7 +27,7 @@ public static TraktTvApiService newApiService() { .setRequestInterceptor(request -> { request.addHeader("Content-type", "application/json"); request.addHeader("trakt-api-version", "2"); - request.addHeader("trakt-api-key", TraktTvAPIConfiguration.API_KEY); + request.addHeader("trakt-api-key", TraktTvAPIConfiguration.CLIENT_ID); }) .setLogLevel(RestAdapter.LogLevel.FULL) .setEndpoint(API_ENDPOINT); From 3ea91ae96cccd63102cead0012714440927c9f92 Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Tue, 9 Feb 2016 20:26:48 +0100 Subject: [PATCH 04/14] Update gradle wrapper --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 39eab07..3e3a55d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Jun 15 17:18:44 CEST 2015 +#Tue Feb 09 20:24:04 CET 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip From d7429d02ab19b377cd6c1d74723ec228bd72764e Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Tue, 9 Feb 2016 20:29:50 +0100 Subject: [PATCH 05/14] Raise version --- library/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/build.gradle b/library/build.gradle index c51769a..8d88e9a 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -37,8 +37,8 @@ android { defaultConfig { minSdkVersion 9 targetSdkVersion 23 - versionCode 103 - versionName "1.0.3" + versionCode 104 + versionName "1.0.4" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } From 7d0757deb8136240fb5b4e9f321d185ae6eab630 Mon Sep 17 00:00:00 2001 From: Adam Harazim Date: Wed, 10 Feb 2016 11:19:39 +0100 Subject: [PATCH 06/14] use android 23 and build-tools 23.0.1 --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 679dc2f..573d99f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,13 @@ language: android jdk: oraclejdk8 env: matrix: - - ANDROID_TARGET=android-22 ANDROID_ABI=armeabi-v7a + - ANDROID_TARGET=android-23 ANDROID_ABI=armeabi-v7a android: components: - - build-tools-22.0.1 - - android-22 - - sys-img-armeabi-v7a-android-22 + - build-tools-23.0.1 + - android-23 + - sys-img-armeabi-v7a-android-23 - extra-google-m2repository - extra-android-m2repository - extra-android-support From cb130f463d5e8a1de54deb69b95ddc97f9f12132 Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Mon, 15 Feb 2016 09:01:15 +0100 Subject: [PATCH 07/14] Use even newer versions --- library/build.gradle | 2 +- sample/build.gradle | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library/build.gradle b/library/build.gradle index 8d88e9a..a8a78da 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -57,7 +57,7 @@ repositories { dependencies { // Rx - compile 'io.reactivex:rxjava:1.0.14' + compile 'io.reactivex:rxjava:1.1.1' // GSON compile 'com.google.code.gson:gson:2.4' diff --git a/sample/build.gradle b/sample/build.gradle index fb9b6f4..0d4860e 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -41,10 +41,10 @@ dependencies { compile project(':library') // Rx - compile 'io.reactivex:rxandroid:1.0.1' - compile 'io.reactivex:rxjava:1.0.14' - compile 'com.trello:rxlifecycle:0.3.0' - compile 'com.trello:rxlifecycle-components:0.3.0' + compile 'io.reactivex:rxandroid:1.1.0' + compile 'io.reactivex:rxjava:1.1.0' + compile 'com.trello:rxlifecycle:0.4.0' + compile 'com.trello:rxlifecycle-components:0.4.0' // Serialization compile 'com.google.code.gson:gson:2.4' From 2679005422023856bbfc196594281329f7a3bb5f Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Mon, 15 Feb 2016 09:36:10 +0100 Subject: [PATCH 08/14] Use RxSingle --- .../OAuth2AccessTokenManagerSpecs.groovy | 10 +++++----- ...rencesOAuth2AccessTokenStorageSpecs.groovy | 6 +++--- .../heimdall/OAuth2AccessTokenManager.java | 19 +++++++++---------- .../heimdall/OAuth2AccessTokenStorage.java | 6 +++--- ...edPreferencesOAuth2AccessTokenStorage.java | 17 +++++------------ .../grants/OAuth2AuthorizationCodeGrant.java | 6 ++++-- .../heimdall/grants/OAuth2Grant.java | 4 ++-- .../actvities/LoginActivity.java | 1 + .../heimdalldroid/actvities/MainActivity.java | 3 ++- .../TraktTvOauth2AccessTokenManager.java | 4 ++-- .../TraktTvRefreshAccessTokenGrant.java | 5 +++-- 11 files changed, 39 insertions(+), 42 deletions(-) diff --git a/library/src/androidTest/groovy/de/rheinfabrik/heimdall/OAuth2AccessTokenManagerSpecs.groovy b/library/src/androidTest/groovy/de/rheinfabrik/heimdall/OAuth2AccessTokenManagerSpecs.groovy index 79febb6..e570264 100644 --- a/library/src/androidTest/groovy/de/rheinfabrik/heimdall/OAuth2AccessTokenManagerSpecs.groovy +++ b/library/src/androidTest/groovy/de/rheinfabrik/heimdall/OAuth2AccessTokenManagerSpecs.groovy @@ -5,7 +5,7 @@ import de.rheinfabrik.heimdall.grants.OAuth2Grant import de.rheinfabrik.heimdall.grants.OAuth2RefreshAccessTokenGrant import spock.lang.Title -import static rx.Observable.just +import static rx.Single.just @Title("Tests for the constructor of the OAuth2AccessTokenManager class") class OAuth2AccessTokenManagerConstructorSpecs extends AndroidSpecification { @@ -63,7 +63,7 @@ class OAuth2AccessTokenManagerGrantNewAccessTokenSpecs extends AndroidSpecificat Calendar calendar = Calendar.getInstance() when: "I ask for a new access token" - OAuth2AccessToken newToken = tokenManager.grantNewAccessToken(grant, calendar).toBlocking().first() + OAuth2AccessToken newToken = tokenManager.grantNewAccessToken(grant, calendar).toBlocking().value() then: "The access token should have the correct expiration date" newToken.expirationDate.timeInMillis == calendar.getTimeInMillis() + 3000 @@ -83,7 +83,7 @@ class OAuth2AccessTokenManagerGrantNewAccessTokenSpecs extends AndroidSpecificat OAuth2AccessTokenManager tokenManager = new OAuth2AccessTokenManager(Mock(OAuth2AccessTokenStorage)) when: "I ask for a new access token" - OAuth2AccessToken newToken = tokenManager.grantNewAccessToken(grant).toBlocking().first() + OAuth2AccessToken newToken = tokenManager.grantNewAccessToken(grant).toBlocking().value() then: "The access token should have the NO expiration date" newToken.expirationDate == null @@ -105,7 +105,7 @@ class OAuth2AccessTokenManagerGrantNewAccessTokenSpecs extends AndroidSpecificat OAuth2AccessTokenManager tokenManager = new OAuth2AccessTokenManager(storage) when: "I ask for a new access token" - tokenManager.grantNewAccessToken(grant).toBlocking().first() + tokenManager.grantNewAccessToken(grant).toBlocking().value() then: "The storage is asked to save the token" 1 * storage.storeAccessToken(accessToken) @@ -171,7 +171,7 @@ class OAuth2AccessTokenManagerGetValidAccessTokenSpecs extends AndroidSpecificat OAuth2AccessTokenManager tokenManager = new OAuth2AccessTokenManager(storage) when: "I ask for a valid access token" - OAuth2AccessToken validToken = tokenManager.getValidAccessToken(grant).toBlocking().first() + OAuth2AccessToken validToken = tokenManager.getValidAccessToken(grant).toBlocking().value() then: "The I receive the non-expired token" validToken == accessToken diff --git a/library/src/androidTest/groovy/de/rheinfabrik/heimdall/extras/SharedPreferencesOAuth2AccessTokenStorageSpecs.groovy b/library/src/androidTest/groovy/de/rheinfabrik/heimdall/extras/SharedPreferencesOAuth2AccessTokenStorageSpecs.groovy index abde747..7690f06 100644 --- a/library/src/androidTest/groovy/de/rheinfabrik/heimdall/extras/SharedPreferencesOAuth2AccessTokenStorageSpecs.groovy +++ b/library/src/androidTest/groovy/de/rheinfabrik/heimdall/extras/SharedPreferencesOAuth2AccessTokenStorageSpecs.groovy @@ -53,7 +53,7 @@ class SharedPreferencesOAuth2AccessTokenStorageGetStoredAccessTokenSpecs extends SharedPreferencesOAuth2AccessTokenStorage storage = new SharedPreferencesOAuth2AccessTokenStorage<>(preferences, OAuth2AccessToken.class) when: "I ask for the access token" - OAuth2AccessToken token = storage.getStoredAccessToken().toBlocking().first() + OAuth2AccessToken token = storage.getStoredAccessToken().toBlocking().value() then: "The token should have the correct access token" token.accessToken == "2YotnFZFEjr1zCsicMWpAA" @@ -111,7 +111,7 @@ class SharedPreferencesOAuth2AccessTokenStorageHasAccessTokenSpecs extends Andro SharedPreferencesOAuth2AccessTokenStorage storage = new SharedPreferencesOAuth2AccessTokenStorage<>(preferences, OAuth2AccessToken.class) when: "I ask if there is a token" - boolean hasToken = storage.hasAccessToken().toBlocking().first() + boolean hasToken = storage.hasAccessToken().toBlocking().value() then: "It should be true" hasToken == true @@ -128,7 +128,7 @@ class SharedPreferencesOAuth2AccessTokenStorageHasAccessTokenSpecs extends Andro SharedPreferencesOAuth2AccessTokenStorage storage = new SharedPreferencesOAuth2AccessTokenStorage<>(preferences, OAuth2AccessToken.class) when: "I ask if there is a token" - boolean hasToken = storage.hasAccessToken().toBlocking().first() + boolean hasToken = storage.hasAccessToken().toBlocking().value() then: "It should be false" hasToken == false diff --git a/library/src/main/java/de/rheinfabrik/heimdall/OAuth2AccessTokenManager.java b/library/src/main/java/de/rheinfabrik/heimdall/OAuth2AccessTokenManager.java index fc3f931..f772ace 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall/OAuth2AccessTokenManager.java +++ b/library/src/main/java/de/rheinfabrik/heimdall/OAuth2AccessTokenManager.java @@ -4,10 +4,10 @@ import de.rheinfabrik.heimdall.grants.OAuth2Grant; import de.rheinfabrik.heimdall.grants.OAuth2RefreshAccessTokenGrant; -import rx.Observable; +import rx.Single; +import rx.functions.Func1; -import static rx.Observable.error; -import static rx.Observable.just; +import static rx.Single.error; /** * The all-seeing and all-hearing guardian sentry of your application who @@ -55,7 +55,7 @@ public OAuth2AccessTokenStorage getStorage() { * @param grant A class implementing the OAuth2Grant interface. * @return - An observable emitting the granted access token. */ - public Observable grantNewAccessToken(OAuth2Grant grant) { + public Single grantNewAccessToken(OAuth2Grant grant) { return grantNewAccessToken(grant, Calendar.getInstance()); } @@ -66,14 +66,14 @@ public Observable grantNewAccessToken(OAuth2Grant gr * @param calendar A calendar instance used to calculate the expiration date of the token. * @return - An observable emitting the granted access token. */ - public Observable grantNewAccessToken(OAuth2Grant grant, Calendar calendar) { + public Single grantNewAccessToken(OAuth2Grant grant, Calendar calendar) { if (grant == null) { throw new IllegalArgumentException("Grant MUST NOT be null."); } return grant .grantNewAccessToken() - .doOnNext(accessToken -> { + .doOnSuccess(accessToken -> { if (accessToken.expiresIn != null) { Calendar expirationDate = (Calendar) calendar.clone(); expirationDate.add(Calendar.SECOND, accessToken.expiresIn); @@ -92,13 +92,13 @@ public Observable grantNewAccessToken(OAuth2Grant gr * @param refreshAccessTokenGrant The refresh grant that will be used if the access token is expired. * @return - An Observable emitting an unexpired access token. */ - public Observable getValidAccessToken(final OAuth2RefreshAccessTokenGrant refreshAccessTokenGrant) { + public Single getValidAccessToken(final OAuth2RefreshAccessTokenGrant refreshAccessTokenGrant) { if (refreshAccessTokenGrant == null) { throw new IllegalArgumentException("RefreshAccessTokenGrant MUST NOT be null."); } return mStorage.getStoredAccessToken() - .concatMap(accessToken -> { + .flatMap(accessToken -> { if (accessToken == null) { return error(new IllegalStateException("No access token found.")); } else if (accessToken.isExpired()) { @@ -106,9 +106,8 @@ public Observable getValidAccessToken(final OAuth2RefreshAccessTok return grantNewAccessToken(refreshAccessTokenGrant); } else { - return just(accessToken); + return Single.just(accessToken); } }); } - } diff --git a/library/src/main/java/de/rheinfabrik/heimdall/OAuth2AccessTokenStorage.java b/library/src/main/java/de/rheinfabrik/heimdall/OAuth2AccessTokenStorage.java index 4eedd12..3b531da 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall/OAuth2AccessTokenStorage.java +++ b/library/src/main/java/de/rheinfabrik/heimdall/OAuth2AccessTokenStorage.java @@ -1,6 +1,6 @@ package de.rheinfabrik.heimdall; -import rx.Observable; +import rx.Single; /** * Interface used to define how to store and retrieve a stored access token. @@ -16,7 +16,7 @@ public interface OAuth2AccessTokenStorage getStoredAccessToken(); + Single getStoredAccessToken(); /** * Stores the given access token. @@ -31,7 +31,7 @@ public interface OAuth2AccessTokenStorage hasAccessToken(); + Single hasAccessToken(); /** * Removes the stored access token. diff --git a/library/src/main/java/de/rheinfabrik/heimdall/extras/SharedPreferencesOAuth2AccessTokenStorage.java b/library/src/main/java/de/rheinfabrik/heimdall/extras/SharedPreferencesOAuth2AccessTokenStorage.java index 2ce972b..5bc9612 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall/extras/SharedPreferencesOAuth2AccessTokenStorage.java +++ b/library/src/main/java/de/rheinfabrik/heimdall/extras/SharedPreferencesOAuth2AccessTokenStorage.java @@ -6,7 +6,7 @@ import de.rheinfabrik.heimdall.OAuth2AccessToken; import de.rheinfabrik.heimdall.OAuth2AccessTokenStorage; -import rx.Observable; +import rx.Single; /** * A simple storage that saves the access token as plain text in the passed shared preferences. @@ -52,16 +52,9 @@ public SharedPreferencesOAuth2AccessTokenStorage(SharedPreferences sharedPrefere @SuppressWarnings("unchecked") @Override - public Observable getStoredAccessToken() { - return Observable + public Single getStoredAccessToken() { + return Single .just(mSharedPreferences.getString(ACCESS_TOKEN_PREFERENCES_KEY, null)) - .filter(accessToken -> { - if (accessToken == null) { - throw new RuntimeException("No access token found."); - } - - return true; - }) .map(json -> (TAccessToken) new Gson().fromJson(json, mTokenClass)); } @@ -74,8 +67,8 @@ public void storeAccessToken(TAccessToken accessToken) { } @Override - public Observable hasAccessToken() { - return Observable.just(mSharedPreferences.contains(ACCESS_TOKEN_PREFERENCES_KEY)); + public Single hasAccessToken() { + return Single.just(mSharedPreferences.contains(ACCESS_TOKEN_PREFERENCES_KEY)); } @Override diff --git a/library/src/main/java/de/rheinfabrik/heimdall/grants/OAuth2AuthorizationCodeGrant.java b/library/src/main/java/de/rheinfabrik/heimdall/grants/OAuth2AuthorizationCodeGrant.java index 16d58f5..b2a1d1c 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall/grants/OAuth2AuthorizationCodeGrant.java +++ b/library/src/main/java/de/rheinfabrik/heimdall/grants/OAuth2AuthorizationCodeGrant.java @@ -4,6 +4,7 @@ import de.rheinfabrik.heimdall.OAuth2AccessToken; import rx.Observable; +import rx.Single; import rx.subjects.BehaviorSubject; import rx.subjects.PublishSubject; @@ -91,7 +92,7 @@ public final Observable authorizationUri() { // OAuth2AccessToken @Override - public Observable grantNewAccessToken() { + public Single grantNewAccessToken() { mAuthorizationUriSubject.onNext(buildAuthorizationUri()); return onUriLoadedCommand @@ -99,6 +100,7 @@ public Observable grantNewAccessToken() { .filter(code -> code != null) .take(1) .retry() - .concatMap(this::exchangeTokenUsingCode); + .concatMap(this::exchangeTokenUsingCode) + .toSingle(); } } diff --git a/library/src/main/java/de/rheinfabrik/heimdall/grants/OAuth2Grant.java b/library/src/main/java/de/rheinfabrik/heimdall/grants/OAuth2Grant.java index ba0fa88..4c6f8b8 100644 --- a/library/src/main/java/de/rheinfabrik/heimdall/grants/OAuth2Grant.java +++ b/library/src/main/java/de/rheinfabrik/heimdall/grants/OAuth2Grant.java @@ -1,7 +1,7 @@ package de.rheinfabrik.heimdall.grants; import de.rheinfabrik.heimdall.OAuth2AccessToken; -import rx.Observable; +import rx.Single; /** * Interface describing an OAuth2 Grant as described in https://tools.ietf.org/html/rfc6749#page-23. @@ -17,5 +17,5 @@ public interface OAuth2Grant { * * @return - An Observable emitting the granted access token. */ - Observable grantNewAccessToken(); + Single grantNewAccessToken(); } diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/LoginActivity.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/LoginActivity.java index c0cf6f6..93971d4 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/LoginActivity.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/LoginActivity.java @@ -80,6 +80,7 @@ public void onPageStarted(WebView view, String url, Bitmap favicon) { // Start authorization and listen for success tokenManager.grantNewAccessToken(grant) + .toObservable() .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(x -> handleSuccess(), x -> handleError()); diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java index 25cc2d2..a2886ef 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/actvities/MainActivity.java @@ -104,7 +104,7 @@ private void loadLists() { .getValidAccessToken() /* Load lists */ - .concatMap(authorizationHeader -> TraktTvApiFactory.newApiService().getLists(authorizationHeader)); + .flatMapObservable(authorizationHeader -> TraktTvApiFactory.newApiService().getLists(authorizationHeader)); // Bind to lifecycle listsObservable @@ -163,6 +163,7 @@ private void refresh() { mSwipeRefreshLayout.setRefreshing(true); mTokenManager.getStorage().hasAccessToken() + .toObservable() .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(loggedIn -> { diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvOauth2AccessTokenManager.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvOauth2AccessTokenManager.java index a8a3d4f..4acf705 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvOauth2AccessTokenManager.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvOauth2AccessTokenManager.java @@ -8,7 +8,7 @@ import de.rheinfabrik.heimdall.OAuth2AccessTokenStorage; import de.rheinfabrik.heimdall.extras.SharedPreferencesOAuth2AccessTokenStorage; import de.rheinfabrik.heimdalldroid.network.TraktTvAPIConfiguration; -import rx.Observable; +import rx.Single; /** * Token manger used to handle all your access token needs with the TraktTv API (http://docs.trakt.apiary.io/#). @@ -55,7 +55,7 @@ public TraktTvAuthorizationCodeGrant newAuthorizationCodeGrant() { /** * Returns a valid authorization header string using a preconfigured TraktTvRefreshAccessTokenGrant. */ - public Observable getValidAccessToken() { + public Single getValidAccessToken() { TraktTvRefreshAccessTokenGrant grant = new TraktTvRefreshAccessTokenGrant(); grant.clientId = TraktTvAPIConfiguration.CLIENT_ID; grant.clientSecret = TraktTvAPIConfiguration.CLIENT_SECRET; diff --git a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvRefreshAccessTokenGrant.java b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvRefreshAccessTokenGrant.java index 1a7248e..61122a7 100644 --- a/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvRefreshAccessTokenGrant.java +++ b/sample/src/main/java/de/rheinfabrik/heimdalldroid/network/oauth2/TraktTvRefreshAccessTokenGrant.java @@ -5,6 +5,7 @@ import de.rheinfabrik.heimdalldroid.network.TraktTvApiFactory; import de.rheinfabrik.heimdalldroid.network.models.RefreshTokenRequestBody; import rx.Observable; +import rx.Single; /** * TraktTv refresh token grant as described in http://docs.trakt.apiary.io/#reference/authentication-oauth/token/exchange-refresh_token-for-access_token. @@ -20,8 +21,8 @@ public class TraktTvRefreshAccessTokenGrant extends OAuth2RefreshAccessTokenGran // OAuth2RefreshAccessTokenGrant @Override - public Observable grantNewAccessToken() { + public Single grantNewAccessToken() { RefreshTokenRequestBody body = new RefreshTokenRequestBody(refreshToken, clientId, clientSecret, redirectUri, GRANT_TYPE); - return TraktTvApiFactory.newApiService().refreshAccessToken(body); + return TraktTvApiFactory.newApiService().refreshAccessToken(body).toSingle(); } } From 5f53e78fa8d4fd72db1af25ee7db47f6d7906f35 Mon Sep 17 00:00:00 2001 From: Adam Harazim Date: Mon, 15 Feb 2016 10:12:29 +0100 Subject: [PATCH 09/14] change to emulator 22 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 573d99f..cd0561f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,13 +2,13 @@ language: android jdk: oraclejdk8 env: matrix: - - ANDROID_TARGET=android-23 ANDROID_ABI=armeabi-v7a + - ANDROID_TARGET=android-22 ANDROID_ABI=armeabi-v7a android: components: - build-tools-23.0.1 - android-23 - - sys-img-armeabi-v7a-android-23 + - sys-img-armeabi-v7a-android-22rge - extra-google-m2repository - extra-android-m2repository - extra-android-support From 1786f2907d265f19c33a59c256435e6b97f63703 Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Mon, 15 Feb 2016 10:19:08 +0100 Subject: [PATCH 10/14] Fix typo --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cd0561f..c299975 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ android: components: - build-tools-23.0.1 - android-23 - - sys-img-armeabi-v7a-android-22rge + - sys-img-armeabi-v7a-android-22 - extra-google-m2repository - extra-android-m2repository - extra-android-support From 3e887ebaa5b9bb13f3737fbe8726c04ad2356761 Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Mon, 15 Feb 2016 10:27:36 +0100 Subject: [PATCH 11/14] Also download android 22 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c299975..80a72a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ android: components: - build-tools-23.0.1 - android-23 + - android-22 - sys-img-armeabi-v7a-android-22 - extra-google-m2repository - extra-android-m2repository From 367ea875432fcd970625fad4636656a90c21cc79 Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Mon, 15 Feb 2016 11:44:14 +0100 Subject: [PATCH 12/14] Load 23.0.2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 80a72a3..4251d03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ env: android: components: - - build-tools-23.0.1 + - build-tools-23.0.2 - android-23 - android-22 - sys-img-armeabi-v7a-android-22 From a59164fc490f5b06f6c90068b0af43fc932921e0 Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Mon, 15 Feb 2016 12:02:20 +0100 Subject: [PATCH 13/14] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 4251d03..6fde995 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ env: android: components: + - tools - build-tools-23.0.2 - android-23 - android-22 From 54a8d727d71aab9d297452e01da0b4d54b0621fd Mon Sep 17 00:00:00 2001 From: Giulio Petek Date: Mon, 15 Feb 2016 13:49:45 +0100 Subject: [PATCH 14/14] Update .travis.yml --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6fde995..f17a99d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,10 @@ language: android + jdk: oraclejdk8 + env: + global: + - MALLOC_ARENA_MAX=2 matrix: - ANDROID_TARGET=android-22 ANDROID_ABI=armeabi-v7a @@ -14,7 +18,9 @@ android: - extra-google-m2repository - extra-android-m2repository - extra-android-support - + +sudo: required + before_script: - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI - emulator -avd test -no-skin -no-audio -no-window &