From c5eb5a93adb7ad9f43d15926d1f5fc2441ec0169 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 11:05:04 +0200 Subject: [PATCH 01/21] Update all modules dependencies --- bolts-tasks/build.gradle | 2 +- build.gradle | 8 ++++++-- facebook/build.gradle | 6 +++--- fcm/build.gradle | 2 +- parse/build.gradle | 10 +++++----- rxjava/build.gradle | 2 +- twitter/build.gradle | 4 ++-- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/bolts-tasks/build.gradle b/bolts-tasks/build.gradle index d07c3f3fa..d9adae913 100644 --- a/bolts-tasks/build.gradle +++ b/bolts-tasks/build.gradle @@ -8,7 +8,7 @@ apply plugin: 'maven-publish' dependencies { compileOnly 'com.google.android:android:4.1.1.4' - testImplementation 'junit:junit:4.13.2' + testImplementation "junit:junit:$rootProject.ext.junitVersion" } javadoc.options.addStringOption('Xdoclint:none', '-quiet') diff --git a/build.gradle b/build.gradle index 53e066139..23bfac03f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = "1.5.31" + ext.kotlin_version = "1.6.0" ext.jacocoVersion = '0.8.7' repositories { google() @@ -65,6 +65,10 @@ allprojects { ext { compileSdkVersion = 30 - minSdkVersion = 16 + minSdkVersion = 19 targetSdkVersion = 30 + + mockitoCoreVersion = "3.12.4" + junitVersion = "4.13.2" + robolectricVersion = "4.7" } diff --git a/facebook/build.gradle b/facebook/build.gradle index fe481cd45..c74724e77 100644 --- a/facebook/build.gradle +++ b/facebook/build.gradle @@ -38,9 +38,9 @@ dependencies { api "com.facebook.android:facebook-login:8.2.0" implementation project(":parse") - testImplementation "junit:junit:4.13.2" - testImplementation "org.mockito:mockito-core:3.9.0" - testImplementation "org.robolectric:robolectric:4.6" + testImplementation "junit:junit:$rootProject.ext.junitVersion" + testImplementation "org.mockito:mockito-core:$rootProject.ext.mockitoCoreVersion" + testImplementation "org.robolectric:robolectric:$rootProject.ext.robolectricVersion" } afterEvaluate { diff --git a/fcm/build.gradle b/fcm/build.gradle index 25209a897..41c23d2a4 100644 --- a/fcm/build.gradle +++ b/fcm/build.gradle @@ -36,7 +36,7 @@ android { } dependencies { - api "com.google.firebase:firebase-messaging:22.0.0" + api "com.google.firebase:firebase-messaging:23.0.0" implementation project(":parse") } diff --git a/parse/build.gradle b/parse/build.gradle index 9921801c4..e9c1d66d8 100644 --- a/parse/build.gradle +++ b/parse/build.gradle @@ -47,15 +47,15 @@ ext { } dependencies { - api "androidx.annotation:annotation:1.2.0" - api "androidx.core:core:1.6.0" + api "androidx.annotation:annotation:1.3.0" + api "androidx.core:core:1.7.0" api "com.squareup.okhttp3:okhttp:$okhttpVersion" api project(':bolts-tasks') - testImplementation 'junit:junit:4.13.2' - testImplementation "org.robolectric:robolectric:4.6" testImplementation "org.skyscreamer:jsonassert:1.5.0" - testImplementation "org.mockito:mockito-core:3.9.0" + testImplementation "junit:junit:$rootProject.ext.junitVersion" + testImplementation "org.mockito:mockito-core:$rootProject.ext.mockitoCoreVersion" + testImplementation "org.robolectric:robolectric:$rootProject.ext.robolectricVersion" testImplementation "com.squareup.okhttp3:mockwebserver:$okhttpVersion" } diff --git a/rxjava/build.gradle b/rxjava/build.gradle index 047030f65..6d7c9995f 100644 --- a/rxjava/build.gradle +++ b/rxjava/build.gradle @@ -42,7 +42,7 @@ android { dependencies { api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - api "io.reactivex.rxjava3:rxjava:3.0.4" + api "io.reactivex.rxjava3:rxjava:3.1.0" implementation project(":parse") } diff --git a/twitter/build.gradle b/twitter/build.gradle index b8dd37321..135397656 100644 --- a/twitter/build.gradle +++ b/twitter/build.gradle @@ -40,8 +40,8 @@ dependencies { api "se.akerfeldt:okhttp-signpost:1.1.0" implementation project(":parse") - testImplementation "junit:junit:4.13.2" - testImplementation "org.mockito:mockito-core:3.9.0" + testImplementation "junit:junit:$rootProject.ext.junitVersion" + testImplementation "org.mockito:mockito-core:$rootProject.ext.mockitoCoreVersion" } afterEvaluate { From 2a2f51dd29630db9b300bcdc76aa0ceeccaf9acc Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 11:21:45 +0200 Subject: [PATCH 02/21] Update Facebook SDK --- facebook/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/facebook/build.gradle b/facebook/build.gradle index c74724e77..19786fea9 100644 --- a/facebook/build.gradle +++ b/facebook/build.gradle @@ -35,7 +35,7 @@ android { } dependencies { - api "com.facebook.android:facebook-login:8.2.0" + api "com.facebook.android:facebook-login:12.1.0" implementation project(":parse") testImplementation "junit:junit:$rootProject.ext.junitVersion" From 81c93f819e026044daeaaca8144a3bb97065126a Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 11:22:04 +0200 Subject: [PATCH 03/21] Facebook code improvements --- .../main/java/com/parse/facebook/FacebookController.java | 8 +++++--- .../main/java/com/parse/facebook/ParseFacebookUtils.java | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/facebook/src/main/java/com/parse/facebook/FacebookController.java b/facebook/src/main/java/com/parse/facebook/FacebookController.java index efd4387c0..54b09a128 100644 --- a/facebook/src/main/java/com/parse/facebook/FacebookController.java +++ b/facebook/src/main/java/com/parse/facebook/FacebookController.java @@ -22,6 +22,8 @@ import com.facebook.login.LoginManager; import com.facebook.login.LoginResult; import com.parse.boltsinternal.Task; +import com.parse.boltsinternal.TaskCompletionSource; + import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -92,7 +94,7 @@ public Task> authenticateAsync( "Unable to authenticate when another authentication is in process")); } - final Task>.TaskCompletionSource tcs = Task.create(); + final TaskCompletionSource> tcs = new TaskCompletionSource<>(); LoginManager manager = facebookSdkDelegate.getLoginManager(); callbackManager = facebookSdkDelegate.createCallbackManager(); @@ -119,13 +121,13 @@ public void onError(FacebookException e) { if (LoginAuthorizationType.PUBLISH.equals(authorizationType)) { if (fragment != null) { - manager.logInWithPublishPermissions(fragment, permissions); + manager.logInWithPublishPermissions(fragment, callbackManager, permissions); } else { manager.logInWithPublishPermissions(activity, permissions); } } else { if (fragment != null) { - manager.logInWithReadPermissions(fragment, permissions); + manager.logInWithReadPermissions(fragment, callbackManager, permissions); } else { manager.logInWithReadPermissions(activity, permissions); } diff --git a/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java b/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java index d51970964..923494c24 100644 --- a/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java +++ b/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java @@ -20,6 +20,8 @@ import com.parse.SaveCallback; import com.parse.boltsinternal.Continuation; import com.parse.boltsinternal.Task; +import com.parse.boltsinternal.TaskCompletionSource; + import java.util.Collection; import java.util.Collections; import java.util.Map; @@ -565,7 +567,7 @@ private static Task callbackOnMainThreadInternalAsync( if (callback == null) { return task; } - final Task.TaskCompletionSource tcs = Task.create(); + final TaskCompletionSource tcs = new TaskCompletionSource(); task.continueWith( (Continuation) task1 -> { From 4a4b5f57555c9a3a8c01145337f5cfbdff5b2359 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 11:32:32 +0200 Subject: [PATCH 04/21] Refactor twitter module --- .../main/java/com/parse/facebook/FacebookController.java | 1 - .../main/java/com/parse/facebook/ParseFacebookUtils.java | 1 - .../src/main/java/com/parse/twitter/ParseTwitterUtils.java | 3 ++- twitter/src/main/java/com/parse/twitter/Twitter.java | 1 + .../src/main/java/com/parse/twitter/TwitterController.java | 7 ++++--- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/facebook/src/main/java/com/parse/facebook/FacebookController.java b/facebook/src/main/java/com/parse/facebook/FacebookController.java index 54b09a128..409fdbf64 100644 --- a/facebook/src/main/java/com/parse/facebook/FacebookController.java +++ b/facebook/src/main/java/com/parse/facebook/FacebookController.java @@ -23,7 +23,6 @@ import com.facebook.login.LoginResult; import com.parse.boltsinternal.Task; import com.parse.boltsinternal.TaskCompletionSource; - import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; diff --git a/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java b/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java index 923494c24..74fb5cb18 100644 --- a/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java +++ b/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java @@ -21,7 +21,6 @@ import com.parse.boltsinternal.Continuation; import com.parse.boltsinternal.Task; import com.parse.boltsinternal.TaskCompletionSource; - import java.util.Collection; import java.util.Collections; import java.util.Map; diff --git a/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java b/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java index 4b4d91786..2815f2951 100644 --- a/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java +++ b/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java @@ -17,6 +17,7 @@ import com.parse.boltsinternal.AggregateException; import com.parse.boltsinternal.Continuation; import com.parse.boltsinternal.Task; +import com.parse.boltsinternal.TaskCompletionSource; import java.util.Map; import java.util.concurrent.CancellationException; @@ -391,7 +392,7 @@ private static Task callbackOnMainThreadInternalAsync( if (callback == null) { return task; } - final Task.TaskCompletionSource tcs = Task.create(); + final TaskCompletionSource tcs = new TaskCompletionSource(); task.continueWith( (Continuation) task1 -> { diff --git a/twitter/src/main/java/com/parse/twitter/Twitter.java b/twitter/src/main/java/com/parse/twitter/Twitter.java index 15db35b45..483dc0af5 100644 --- a/twitter/src/main/java/com/parse/twitter/Twitter.java +++ b/twitter/src/main/java/com/parse/twitter/Twitter.java @@ -107,6 +107,7 @@ public void authorize(final Context context, final AsyncCallback callback) { final OkHttpOAuthConsumer consumer = new OkHttpOAuthConsumer(getConsumerKey(), getConsumerSecret()); + // https://stackoverflow.com/a/64969640/1274974 AsyncTask task = new AsyncTask() { private Throwable error; diff --git a/twitter/src/main/java/com/parse/twitter/TwitterController.java b/twitter/src/main/java/com/parse/twitter/TwitterController.java index 9df087667..bf8ad0704 100644 --- a/twitter/src/main/java/com/parse/twitter/TwitterController.java +++ b/twitter/src/main/java/com/parse/twitter/TwitterController.java @@ -11,6 +11,7 @@ import android.content.Context; import com.parse.ParseException; import com.parse.boltsinternal.Task; +import com.parse.boltsinternal.TaskCompletionSource; import java.util.HashMap; import java.util.Map; @@ -25,7 +26,7 @@ class TwitterController { private static final String AUTH_TOKEN_SECRET_KEY = "auth_token_secret"; private final Twitter twitter; - private Task>.TaskCompletionSource currentTcs; + private TaskCompletionSource> currentTcs; TwitterController() { this(new Twitter("", "", "")); @@ -44,7 +45,7 @@ public Twitter getTwitter() { } public Task> authenticateAsync(Context context) { - final Task>.TaskCompletionSource tcs = Task.create(); + final TaskCompletionSource> tcs = new TaskCompletionSource<>(); if (currentTcs != null) { handleCancel(currentTcs); } @@ -100,7 +101,7 @@ public void onSuccess(Object result) { return tcs.getTask(); } - private void handleCancel(Task>.TaskCompletionSource callback) { + private void handleCancel(TaskCompletionSource> callback) { // Ensure that the operation being cancelled is actually the current // operation (so that if one had already been cancelled but still // invokes this method, it doesn't cancel the "real" current operation). From 77643731908d7f417cf9390e05311f986a5a1b1b Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 13:40:53 +0200 Subject: [PATCH 05/21] Bump target sdk version to 31 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 23bfac03f..f863c897d 100644 --- a/build.gradle +++ b/build.gradle @@ -63,10 +63,10 @@ allprojects { } ext { - compileSdkVersion = 30 + compileSdkVersion = 31 minSdkVersion = 19 - targetSdkVersion = 30 + targetSdkVersion = 31 mockitoCoreVersion = "3.12.4" junitVersion = "4.13.2" From 9628f3fb56a27cccf15b72d3c41caaefd7be92f8 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 15:26:29 +0200 Subject: [PATCH 06/21] Update to latest AGP 7.0.3 --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index f863c897d..c6eec9c4f 100644 --- a/build.gradle +++ b/build.gradle @@ -6,9 +6,9 @@ buildscript { mavenCentral() } dependencies { - classpath "com.android.tools.build:gradle:4.2.2" classpath "org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.3" classpath "com.github.dcendents:android-maven-gradle-plugin:2.1" + classpath "com.android.tools.build:gradle:7.0.3" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jacoco:org.jacoco.core:$jacocoVersion" classpath "com.dicedmelon.gradle:jacoco-android:0.1.5" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 68ca99ac4..00aeb6981 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Tue Nov 16 15:15:09 EET 2021 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip +zipStoreBase=GRADLE_USER_HOME From 5e0d0a1358685c01168943644c93452387138645 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 15:26:49 +0200 Subject: [PATCH 07/21] Gradle scripts cleanup --- bolts-tasks/build.gradle | 31 +++++++++++++++++-------------- parse/build.gradle | 12 ++++-------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/bolts-tasks/build.gradle b/bolts-tasks/build.gradle index d9adae913..d97b749c4 100644 --- a/bolts-tasks/build.gradle +++ b/bolts-tasks/build.gradle @@ -11,6 +11,11 @@ dependencies { testImplementation "junit:junit:$rootProject.ext.junitVersion" } +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + javadoc.options.addStringOption('Xdoclint:none', '-quiet') task sourcesJar(type: Jar) { @@ -28,6 +33,18 @@ artifacts { archives javadocJar } +//region Publishing + +afterEvaluate { + publishing { + publications { + boltsPublication(MavenPublication) { + from components.java + } + } + } +} + //endregion //region Code Coverage @@ -45,17 +62,3 @@ jacocoTestReport { //endregion -java { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 -} - -afterEvaluate { - publishing { - publications { - boltsPublication(MavenPublication) { - from components.java - } - } - } -} diff --git a/parse/build.gradle b/parse/build.gradle index e9c1d66d8..3781eb989 100644 --- a/parse/build.gradle +++ b/parse/build.gradle @@ -59,6 +59,8 @@ dependencies { testImplementation "com.squareup.okhttp3:mockwebserver:$okhttpVersion" } +//region Publishing + afterEvaluate { publishing { publications { @@ -69,6 +71,8 @@ afterEvaluate { } } +//endregion + //region Code Coverage apply plugin: "com.dicedmelon.gradle.jacoco-android" @@ -92,11 +96,3 @@ jacocoAndroidUnitTestReport { } //endregion - -//region Coveralls - -apply plugin: "com.github.kt3k.coveralls" - -coveralls.jacocoReportPath = "${buildDir}/jacoco/jacoco.xml" - -//endregion From 9314010fbe9dc2a3d35eb98c4ae7c047dbe421f8 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 15:27:07 +0200 Subject: [PATCH 08/21] Remove unused plugins --- build.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.gradle b/build.gradle index c6eec9c4f..ce294f522 100644 --- a/build.gradle +++ b/build.gradle @@ -6,8 +6,6 @@ buildscript { mavenCentral() } dependencies { - classpath "org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.3" - classpath "com.github.dcendents:android-maven-gradle-plugin:2.1" classpath "com.android.tools.build:gradle:7.0.3" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jacoco:org.jacoco.core:$jacocoVersion" From 84024cf161948c3cc9998c207eaadd1ac3b19df5 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 15:27:19 +0200 Subject: [PATCH 09/21] Update spotless plugin --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ce294f522..3c57c5249 100644 --- a/build.gradle +++ b/build.gradle @@ -11,13 +11,13 @@ buildscript { classpath "org.jacoco:org.jacoco.core:$jacocoVersion" classpath "com.dicedmelon.gradle:jacoco-android:0.1.5" classpath "io.freefair.gradle:android-gradle-plugins:4.2.0-m1" - classpath "com.diffplug.spotless:spotless-plugin-gradle:5.16.0" + classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.0" } } plugins { id "com.github.ben-manes.versions" version "0.28.0" - id "com.diffplug.spotless" version "5.16.0" + id "com.diffplug.spotless" version "6.0.0" } allprojects { From bea9511ba4ac4dd5c167290a2c90730035caedcd Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 15:27:41 +0200 Subject: [PATCH 10/21] Update coroutines to 1.5.2 --- coroutines/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coroutines/build.gradle b/coroutines/build.gradle index ff9395446..79e9b12b1 100644 --- a/coroutines/build.gradle +++ b/coroutines/build.gradle @@ -40,7 +40,7 @@ android { } ext { - coroutinesVersion = "1.5.0" + coroutinesVersion = "1.5.2" } dependencies { From 0afe7b73ef32d4b5398583515d6d4d777d1a7671 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 15:27:51 +0200 Subject: [PATCH 11/21] Upgrade OkHttp to latest version --- build.gradle | 2 +- parse/build.gradle | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 3c57c5249..7e265c050 100644 --- a/build.gradle +++ b/build.gradle @@ -63,7 +63,7 @@ allprojects { ext { compileSdkVersion = 31 - minSdkVersion = 19 + minSdkVersion = 21 targetSdkVersion = 31 mockitoCoreVersion = "3.12.4" diff --git a/parse/build.gradle b/parse/build.gradle index 3781eb989..7a2c58b3e 100644 --- a/parse/build.gradle +++ b/parse/build.gradle @@ -42,8 +42,7 @@ android { } ext { - // Note: Don't update past 3.12.x, as it sets the minSdk to Android 5.0 - okhttpVersion = "3.12.10" + okhttpVersion = "4.9.1" } dependencies { From 90127a3a95a13b2e5f943b83faf56b8c51031b6d Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 15:35:58 +0200 Subject: [PATCH 12/21] Revert to latest stable spottles 5.17.1 --- bolts-tasks/build.gradle | 1 - build.gradle | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/bolts-tasks/build.gradle b/bolts-tasks/build.gradle index d97b749c4..79f4aefa0 100644 --- a/bolts-tasks/build.gradle +++ b/bolts-tasks/build.gradle @@ -61,4 +61,3 @@ jacocoTestReport { } //endregion - diff --git a/build.gradle b/build.gradle index 7e265c050..9c03a99e7 100644 --- a/build.gradle +++ b/build.gradle @@ -11,13 +11,13 @@ buildscript { classpath "org.jacoco:org.jacoco.core:$jacocoVersion" classpath "com.dicedmelon.gradle:jacoco-android:0.1.5" classpath "io.freefair.gradle:android-gradle-plugins:4.2.0-m1" - classpath "com.diffplug.spotless:spotless-plugin-gradle:6.0.0" + classpath "com.diffplug.spotless:spotless-plugin-gradle:5.17.1" } } plugins { id "com.github.ben-manes.versions" version "0.28.0" - id "com.diffplug.spotless" version "6.0.0" + id "com.diffplug.spotless" version "5.17.1" } allprojects { From 5012d64ca3d5916d6de7e44bfea1a16663984e85 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 16:40:16 +0200 Subject: [PATCH 13/21] Fix Facebook tests --- .gitignore | 1 + facebook/build.gradle | 1 + .../test/java/com/parse/facebook/FacebookControllerTest.java | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3858c294a..8a0096f1a 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ jacoco.exec # Node node_modules/ npm-debug.log +*.hprof diff --git a/facebook/build.gradle b/facebook/build.gradle index 19786fea9..0fb8594da 100644 --- a/facebook/build.gradle +++ b/facebook/build.gradle @@ -40,6 +40,7 @@ dependencies { testImplementation "junit:junit:$rootProject.ext.junitVersion" testImplementation "org.mockito:mockito-core:$rootProject.ext.mockitoCoreVersion" + testImplementation "org.mockito:mockito-inline:$rootProject.ext.mockitoCoreVersion" testImplementation "org.robolectric:robolectric:$rootProject.ext.robolectricVersion" } diff --git a/facebook/src/test/java/com/parse/facebook/FacebookControllerTest.java b/facebook/src/test/java/com/parse/facebook/FacebookControllerTest.java index 98e772cb0..c261f4c70 100644 --- a/facebook/src/test/java/com/parse/facebook/FacebookControllerTest.java +++ b/facebook/src/test/java/com/parse/facebook/FacebookControllerTest.java @@ -314,14 +314,14 @@ public void doAuthenticateAsyncWith( verify(loginManager).logInWithPublishPermissions(activity, permissions); } if (fragment != null) { - verify(loginManager).logInWithPublishPermissions(fragment, permissions); + verify(loginManager).logInWithPublishPermissions(fragment, callbackManager, permissions); } } else { if (activity != null) { verify(loginManager).logInWithReadPermissions(activity, permissions); } if (fragment != null) { - verify(loginManager).logInWithReadPermissions(fragment, permissions); + verify(loginManager).logInWithReadPermissions(fragment, callbackManager, permissions); } } From 854dd3ee1886820cec91f9e682637c12f2db6b43 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 16:43:10 +0200 Subject: [PATCH 14/21] Pleases spotless --- .../java/com/parse/facebook/FacebookControllerTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/facebook/src/test/java/com/parse/facebook/FacebookControllerTest.java b/facebook/src/test/java/com/parse/facebook/FacebookControllerTest.java index c261f4c70..df7f9d14a 100644 --- a/facebook/src/test/java/com/parse/facebook/FacebookControllerTest.java +++ b/facebook/src/test/java/com/parse/facebook/FacebookControllerTest.java @@ -314,14 +314,16 @@ public void doAuthenticateAsyncWith( verify(loginManager).logInWithPublishPermissions(activity, permissions); } if (fragment != null) { - verify(loginManager).logInWithPublishPermissions(fragment, callbackManager, permissions); + verify(loginManager) + .logInWithPublishPermissions(fragment, callbackManager, permissions); } } else { if (activity != null) { verify(loginManager).logInWithReadPermissions(activity, permissions); } if (fragment != null) { - verify(loginManager).logInWithReadPermissions(fragment, callbackManager, permissions); + verify(loginManager) + .logInWithReadPermissions(fragment, callbackManager, permissions); } } From 89946b4010adbe124b3d51f0fa0f5441071d3488 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Tue, 16 Nov 2021 18:30:30 +0200 Subject: [PATCH 15/21] Refactor code Remove deprecated code calls Refactor code and remove not needed Android SDK checks --- .../boltsinternal/AggregateException.java | 25 -- .../java/com/parse/boltsinternal/Task.java | 13 - .../com/parse/boltsinternal/TaskTest.java | 48 ---- .../java/com/parse/google/ParseGoogleUtils.kt | 3 +- .../src/main/java/com/parse/OfflineStore.java | 5 +- parse/src/main/java/com/parse/Parse.java | 9 - .../java/com/parse/ParseCommandCache.java | 10 +- .../src/main/java/com/parse/ParseConfig.java | 2 + .../main/java/com/parse/ParseCorePlugins.java | 8 +- .../java/com/parse/ParseEventuallyQueue.java | 4 +- .../main/java/com/parse/ParseFileUtils.java | 2 +- .../src/main/java/com/parse/ParseObject.java | 1 + .../com/parse/ParseObjectCurrentCoder.java | 10 +- .../src/main/java/com/parse/ParsePlugins.java | 13 +- .../src/main/java/com/parse/ParsePolygon.java | 2 + .../com/parse/ParsePushBroadcastReceiver.java | 18 +- parse/src/main/java/com/parse/ParseQuery.java | 3 +- .../java/com/parse/ParseSQLiteCursor.java | 264 ------------------ .../java/com/parse/ParseSQLiteDatabase.java | 8 +- .../main/java/com/parse/ParseTaskUtils.java | 2 +- parse/src/main/java/com/parse/PushRouter.java | 30 +- .../test/java/com/parse/ParseTestUtils.java | 2 +- .../com/parse/twitter/ParseTwitterUtils.java | 23 -- 23 files changed, 32 insertions(+), 473 deletions(-) delete mode 100644 parse/src/main/java/com/parse/ParseSQLiteCursor.java diff --git a/bolts-tasks/src/main/java/com/parse/boltsinternal/AggregateException.java b/bolts-tasks/src/main/java/com/parse/boltsinternal/AggregateException.java index 80d39338f..4d8ca5cd2 100644 --- a/bolts-tasks/src/main/java/com/parse/boltsinternal/AggregateException.java +++ b/bolts-tasks/src/main/java/com/parse/boltsinternal/AggregateException.java @@ -8,7 +8,6 @@ import java.io.PrintStream; import java.io.PrintWriter; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -101,28 +100,4 @@ public void printStackTrace(PrintWriter err) { err.append("\n"); } } - - /** @deprecated Please use {@link #getInnerThrowables()} instead. */ - @Deprecated - public List getErrors() { - List errors = new ArrayList<>(); - if (innerThrowables == null) { - return errors; - } - - for (Throwable cause : innerThrowables) { - if (cause instanceof Exception) { - errors.add((Exception) cause); - } else { - errors.add(new Exception(cause)); - } - } - return errors; - } - - /** @deprecated Please use {@link #getInnerThrowables()} instead. */ - @Deprecated - public Throwable[] getCauses() { - return innerThrowables.toArray(new Throwable[0]); - } } diff --git a/bolts-tasks/src/main/java/com/parse/boltsinternal/Task.java b/bolts-tasks/src/main/java/com/parse/boltsinternal/Task.java index ccb14d779..8e73588b2 100644 --- a/bolts-tasks/src/main/java/com/parse/boltsinternal/Task.java +++ b/bolts-tasks/src/main/java/com/parse/boltsinternal/Task.java @@ -81,12 +81,6 @@ public static void setUnobservedExceptionHandler(UnobservedExceptionHandler eh) unobservedExceptionHandler = eh; } - /** @deprecated Please use {@link com.parse.boltsinternal.TaskCompletionSource ()} instead. */ - public static Task.TaskCompletionSource create() { - Task task = new Task<>(); - return task.new TaskCompletionSource(); - } - /** Creates a completed task with the given value. */ @SuppressWarnings("unchecked") public static Task forResult(TResult value) { @@ -988,11 +982,4 @@ public interface UnobservedExceptionHandler { */ void unobservedException(Task t, UnobservedTaskException e); } - - /** @deprecated Please use {@link com.parse.boltsinternal.TaskCompletionSource} instead. */ - public class TaskCompletionSource - extends com.parse.boltsinternal.TaskCompletionSource { - - /* package */ TaskCompletionSource() {} - } } diff --git a/bolts-tasks/src/test/java/com/parse/boltsinternal/TaskTest.java b/bolts-tasks/src/test/java/com/parse/boltsinternal/TaskTest.java index e77846130..adf179d1b 100644 --- a/bolts-tasks/src/test/java/com/parse/boltsinternal/TaskTest.java +++ b/bolts-tasks/src/test/java/com/parse/boltsinternal/TaskTest.java @@ -8,7 +8,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -1133,51 +1132,4 @@ public void testSetCancelledOnCompletedTask() { } // endregion - - // region deprecated - - @SuppressWarnings("deprecation") - @Test - public void testDeprecatedTaskCompletionSource() { - Task.TaskCompletionSource tcsA = Task.create(); - tcsA.setResult(null); - assertTrue(tcsA.getTask().isCompleted()); - - TaskCompletionSource tcsB = Task.create(); - tcsB.setResult(null); - assertTrue(tcsA.getTask().isCompleted()); - } - - @SuppressWarnings("deprecation") - @Test - public void testDeprecatedAggregateExceptionMethods() { - final Exception error0 = new Exception("This is an exception (0)."); - final Exception error1 = new Exception("This is an exception (1)."); - final Error error2 = new Error("This is an error."); - - List exceptions = new ArrayList<>(); - exceptions.add(error0); - exceptions.add(error1); - - // Test old functionality - AggregateException aggregate = new AggregateException(exceptions); - assertEquals("There were multiple errors.", aggregate.getMessage()); - assertEquals(2, aggregate.getErrors().size()); - assertEquals(error0, aggregate.getErrors().get(0)); - assertEquals(error1, aggregate.getErrors().get(1)); - assertEquals(2, aggregate.getCauses().length); - assertEquals(error0, aggregate.getCauses()[0]); - assertEquals(error1, aggregate.getCauses()[1]); - - // Test deprecated getErrors method returns sane results with non-Exceptions - aggregate = new AggregateException("message", new Throwable[] {error0, error1, error2}); - assertEquals("message", aggregate.getMessage()); - assertEquals(3, aggregate.getErrors().size()); - assertEquals(error0, aggregate.getErrors().get(0)); - assertEquals(error1, aggregate.getErrors().get(1)); - assertNotSame(error2, aggregate.getErrors().get(2)); - assertEquals(error2, aggregate.getErrors().get(2).getCause()); - } - - // endregion } diff --git a/google/src/main/java/com/parse/google/ParseGoogleUtils.kt b/google/src/main/java/com/parse/google/ParseGoogleUtils.kt index a03079d47..6ed42f765 100644 --- a/google/src/main/java/com/parse/google/ParseGoogleUtils.kt +++ b/google/src/main/java/com/parse/google/ParseGoogleUtils.kt @@ -13,6 +13,7 @@ import com.parse.ParseUser import com.parse.SaveCallback import com.parse.boltsinternal.Continuation import com.parse.boltsinternal.Task +import com.parse.boltsinternal.TaskCompletionSource /** * Provides a set of utilities for using Parse with Google. @@ -221,7 +222,7 @@ object ParseGoogleUtils { if (callback == null) { return task } - val tcs: Task.TaskCompletionSource = Task.create() + val tcs: TaskCompletionSource = TaskCompletionSource() task.continueWith( Continuation { task -> if (task.isCancelled && !reportCancellation) { diff --git a/parse/src/main/java/com/parse/OfflineStore.java b/parse/src/main/java/com/parse/OfflineStore.java index e12a44a53..accd4b78f 100644 --- a/parse/src/main/java/com/parse/OfflineStore.java +++ b/parse/src/main/java/com/parse/OfflineStore.java @@ -20,6 +20,7 @@ import com.parse.boltsinternal.Task; import com.parse.boltsinternal.TaskCompletionSource; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -834,9 +835,7 @@ private Task deleteObjects(final List uuids, final ParseSQLiteData } String[] placeholders = new String[uuids.size()]; - for (int i = 0; i < placeholders.length; i++) { - placeholders[i] = "?"; - } + Arrays.fill(placeholders, "?"); String where = OfflineSQLiteOpenHelper.KEY_UUID + " IN (" diff --git a/parse/src/main/java/com/parse/Parse.java b/parse/src/main/java/com/parse/Parse.java index d1c9a712c..468b0381a 100644 --- a/parse/src/main/java/com/parse/Parse.java +++ b/parse/src/main/java/com/parse/Parse.java @@ -309,15 +309,6 @@ private static boolean allParsePushIntentReceiversInternal() { return true; } - /** - * @deprecated Please use {@link #getParseCacheDir(String)} or {@link #getParseFilesDir(String)} - * instead. - */ - @Deprecated - static File getParseDir() { - return ParsePlugins.get().getParseDir(); - } - static File getParseCacheDir() { return ParsePlugins.get().getCacheDir(); } diff --git a/parse/src/main/java/com/parse/ParseCommandCache.java b/parse/src/main/java/com/parse/ParseCommandCache.java index 5d09a1823..39afa01c0 100644 --- a/parse/src/main/java/com/parse/ParseCommandCache.java +++ b/parse/src/main/java/com/parse/ParseCommandCache.java @@ -127,7 +127,7 @@ public ParseCommandCache(Context context, ParseHttpClient client) { private static File getCacheDir() { // Construct the path to the cache directory. - File cacheDir = new File(Parse.getParseDir(), "CommandCache"); + File cacheDir = new File(Parse.getParseCacheDir(), "CommandCache"); cacheDir.mkdirs(); return cacheDir; @@ -522,13 +522,11 @@ private void maybeRunAllCommandsNow(int retriesRemaining) { String localId = command.getLocalId(); Exception error = task.getError(); if (error != null) { - if (error instanceof ParseException - && ((ParseException) error) + if (!(error instanceof ParseException) + || ((ParseException) error) .getCode() - == ParseException + != ParseException .CONNECTION_FAILED) { - // do nothing - } else { if (tcs != null) { tcs.setError(error); } diff --git a/parse/src/main/java/com/parse/ParseConfig.java b/parse/src/main/java/com/parse/ParseConfig.java index 4ebfa3789..1af180194 100644 --- a/parse/src/main/java/com/parse/ParseConfig.java +++ b/parse/src/main/java/com/parse/ParseConfig.java @@ -8,6 +8,7 @@ */ package com.parse; +import androidx.annotation.NonNull; import com.parse.boltsinternal.Task; import java.util.Collections; import java.util.Date; @@ -502,6 +503,7 @@ public String getString(String key, String defaultValue) { return (value instanceof String) ? (String) value : defaultValue; } + @NonNull @Override public String toString() { return "ParseConfig[" + params.toString() + "]"; diff --git a/parse/src/main/java/com/parse/ParseCorePlugins.java b/parse/src/main/java/com/parse/ParseCorePlugins.java index e8c7deed7..01d5ed54b 100644 --- a/parse/src/main/java/com/parse/ParseCorePlugins.java +++ b/parse/src/main/java/com/parse/ParseCorePlugins.java @@ -128,7 +128,7 @@ public void registerSessionController(ParseSessionController controller) { public ParseCurrentUserController getCurrentUserController() { if (currentUserController.get() == null) { - File file = new File(Parse.getParseDir(), FILENAME_CURRENT_USER); + File file = new File(Parse.getParseFilesDir(), FILENAME_CURRENT_USER); FileObjectStore fileStore = new FileObjectStore<>(ParseUser.class, file, ParseUserCurrentCoder.get()); ParseObjectStore store = @@ -227,7 +227,7 @@ public void registerCloudCodeController(ParseCloudCodeController controller) { public ParseConfigController getConfigController() { if (configController.get() == null) { // TODO(mengyan): Do not rely on Parse global - File file = new File(ParsePlugins.get().getParseDir(), FILENAME_CURRENT_CONFIG); + File file = new File(ParsePlugins.get().getFilesDir(), FILENAME_CURRENT_CONFIG); ParseCurrentConfigController currentConfigController = new ParseCurrentConfigController(file); configController.compareAndSet( @@ -277,7 +277,7 @@ public void registerPushChannelsController(ParsePushChannelsController controlle public ParseCurrentInstallationController getCurrentInstallationController() { if (currentInstallationController.get() == null) { - File file = new File(ParsePlugins.get().getParseDir(), FILENAME_CURRENT_INSTALLATION); + File file = new File(ParsePlugins.get().getFilesDir(), FILENAME_CURRENT_INSTALLATION); FileObjectStore fileStore = new FileObjectStore<>( ParseInstallation.class, file, ParseObjectCurrentCoder.get()); @@ -338,7 +338,7 @@ public void registerDefaultACLController(ParseDefaultACLController controller) { public LocalIdManager getLocalIdManager() { if (localIdManager.get() == null) { - LocalIdManager manager = new LocalIdManager(Parse.getParseDir()); + LocalIdManager manager = new LocalIdManager(Parse.getParseFilesDir()); localIdManager.compareAndSet(null, manager); } return localIdManager.get(); diff --git a/parse/src/main/java/com/parse/ParseEventuallyQueue.java b/parse/src/main/java/com/parse/ParseEventuallyQueue.java index 0882db4dd..63192e8a4 100644 --- a/parse/src/main/java/com/parse/ParseEventuallyQueue.java +++ b/parse/src/main/java/com/parse/ParseEventuallyQueue.java @@ -86,9 +86,7 @@ protected ParseRESTCommand commandFromJSON(JSONObject json) throws JSONException ParseRESTCommand command = null; if (ParseRESTCommand.isValidCommandJSONObject(json)) { command = ParseRESTCommand.fromJSONObject(json); - } else if (ParseRESTCommand.isValidOldFormatCommandJSONObject(json)) { - // do nothing - } else { + } else if (!ParseRESTCommand.isValidOldFormatCommandJSONObject(json)) { throw new JSONException("Failed to load command from JSON."); } return command; diff --git a/parse/src/main/java/com/parse/ParseFileUtils.java b/parse/src/main/java/com/parse/ParseFileUtils.java index c1f85686b..070baa111 100644 --- a/parse/src/main/java/com/parse/ParseFileUtils.java +++ b/parse/src/main/java/com/parse/ParseFileUtils.java @@ -314,7 +314,7 @@ private static void doCopyFile( long count; while (pos < size) { final long remain = size - pos; - count = remain > FILE_COPY_BUFFER_SIZE ? FILE_COPY_BUFFER_SIZE : remain; + count = Math.min(remain, FILE_COPY_BUFFER_SIZE); final long bytesCopied = output.transferFrom(input, pos, count); if (bytesCopied == 0) { // IO-385 - can happen if file is truncated after caching the size diff --git a/parse/src/main/java/com/parse/ParseObject.java b/parse/src/main/java/com/parse/ParseObject.java index b06b8269e..c930a4bca 100644 --- a/parse/src/main/java/com/parse/ParseObject.java +++ b/parse/src/main/java/com/parse/ParseObject.java @@ -3977,6 +3977,7 @@ protected void writeToParcel(Parcel dest, ParseParcelEncoder encoder) { dest.writeStringList(new ArrayList<>(availableKeys)); } + @NonNull @Override public String toString() { return String.format( diff --git a/parse/src/main/java/com/parse/ParseObjectCurrentCoder.java b/parse/src/main/java/com/parse/ParseObjectCurrentCoder.java index 3f5de3eb4..1659426a7 100644 --- a/parse/src/main/java/com/parse/ParseObjectCurrentCoder.java +++ b/parse/src/main/java/com/parse/ParseObjectCurrentCoder.java @@ -130,17 +130,11 @@ public > T decode( } if (json.has(KEY_OLD_CREATED_AT)) { String createdAtString = json.getString(KEY_OLD_CREATED_AT); - if (createdAtString != null) { - builder.createdAt( - ParseImpreciseDateFormat.getInstance().parse(createdAtString)); - } + builder.createdAt(ParseImpreciseDateFormat.getInstance().parse(createdAtString)); } if (json.has(KEY_OLD_UPDATED_AT)) { String updatedAtString = json.getString(KEY_OLD_UPDATED_AT); - if (updatedAtString != null) { - builder.updatedAt( - ParseImpreciseDateFormat.getInstance().parse(updatedAtString)); - } + builder.updatedAt(ParseImpreciseDateFormat.getInstance().parse(updatedAtString)); } if (json.has(KEY_OLD_POINTERS)) { JSONObject newPointers = json.getJSONObject(KEY_OLD_POINTERS); diff --git a/parse/src/main/java/com/parse/ParsePlugins.java b/parse/src/main/java/com/parse/ParsePlugins.java index 35e69ea29..df8c1ebe6 100644 --- a/parse/src/main/java/com/parse/ParsePlugins.java +++ b/parse/src/main/java/com/parse/ParsePlugins.java @@ -168,24 +168,13 @@ String userAgent() { InstallationId installationId() { synchronized (lock) { if (installationId == null) { - //noinspection deprecation installationId = - new InstallationId(new File(getParseDir(), INSTALLATION_ID_LOCATION)); + new InstallationId(new File(getFilesDir(), INSTALLATION_ID_LOCATION)); } return installationId; } } - @Deprecated - File getParseDir() { - synchronized (lock) { - if (parseDir == null) { - parseDir = applicationContext.getDir("Parse", Context.MODE_PRIVATE); - } - return createFileDir(parseDir); - } - } - File getCacheDir() { synchronized (lock) { if (cacheDir == null) { diff --git a/parse/src/main/java/com/parse/ParsePolygon.java b/parse/src/main/java/com/parse/ParsePolygon.java index 4c96faa2a..915e43729 100644 --- a/parse/src/main/java/com/parse/ParsePolygon.java +++ b/parse/src/main/java/com/parse/ParsePolygon.java @@ -10,6 +10,7 @@ import android.os.Parcel; import android.os.Parcelable; +import androidx.annotation.NonNull; import java.util.List; import java.util.Locale; import org.json.JSONArray; @@ -197,6 +198,7 @@ public boolean equals(Object obj) { return isEqual; } + @NonNull @Override public String toString() { return String.format(Locale.US, "ParsePolygon: %s", coordinates); diff --git a/parse/src/main/java/com/parse/ParsePushBroadcastReceiver.java b/parse/src/main/java/com/parse/ParsePushBroadcastReceiver.java index ff9eeba91..489fa01ef 100644 --- a/parse/src/main/java/com/parse/ParsePushBroadcastReceiver.java +++ b/parse/src/main/java/com/parse/ParsePushBroadcastReceiver.java @@ -221,19 +221,7 @@ protected void onPushOpen(Context context, Intent intent) { } activityIntent.putExtras(intent.getExtras()); - /* - In order to remove dependency on android-support-library-v4 - The reason why we differentiate between versions instead of just using context.startActivity - for all devices is because in API 11 the recommended conventions for app navigation using - the back key changed. - */ - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - TaskStackBuilderHelper.startActivities(context, cls, activityIntent); - } else { - activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - activityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - context.startActivity(activityIntent); - } + TaskStackBuilderHelper.startActivities(context, cls, activityIntent); } /** @@ -464,9 +452,7 @@ protected NotificationCompat.Builder getNotification(Context context, Intent int // from system defaults .setDefaults(Notification.DEFAULT_ALL); - if (alert != null - && alert.length() - > ParsePushBroadcastReceiver.SMALL_NOTIFICATION_MAX_CHARACTER_LIMIT) { + if (alert.length() > ParsePushBroadcastReceiver.SMALL_NOTIFICATION_MAX_CHARACTER_LIMIT) { notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(alert)); } return notificationBuilder; diff --git a/parse/src/main/java/com/parse/ParseQuery.java b/parse/src/main/java/com/parse/ParseQuery.java index 8da58d89b..8c0288454 100644 --- a/parse/src/main/java/com/parse/ParseQuery.java +++ b/parse/src/main/java/com/parse/ParseQuery.java @@ -1392,7 +1392,6 @@ private interface CacheThenNetworkCallable { * values can either be actual values to compare with for equality, or instances of {@link * KeyConstraints}. */ - @SuppressWarnings("serial") /* package */ static class QueryConstraints extends HashMap { public QueryConstraints() { @@ -1409,7 +1408,6 @@ public QueryConstraints(Map map) { * special operators, such as $greaterThan or $nin. The values are the actual values to compare * against. */ - @SuppressWarnings("serial") /* package */ static class KeyConstraints extends HashMap {} /** Constraint for a $relatedTo query. */ @@ -1588,6 +1586,7 @@ public boolean ignoreACLs() { return params; } + @NonNull @Override public String toString() { return String.format( diff --git a/parse/src/main/java/com/parse/ParseSQLiteCursor.java b/parse/src/main/java/com/parse/ParseSQLiteCursor.java deleted file mode 100644 index ce6a15d77..000000000 --- a/parse/src/main/java/com/parse/ParseSQLiteCursor.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2015-present, Parse, LLC. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -package com.parse; - -import android.annotation.TargetApi; -import android.content.ContentResolver; -import android.database.CharArrayBuffer; -import android.database.ContentObserver; -import android.database.Cursor; -import android.database.DataSetObserver; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import com.parse.boltsinternal.Task; -import java.util.concurrent.Callable; -import java.util.concurrent.Executor; - -/** - * Wrapper class to invoke {@link Cursor#close()} on a specific thread on Android versions below - * android-14 as they require {@link Cursor#close()} to be called on the same thread the cursor was - * created in - * - *

https://github.com/android/platform_frameworks_base/commit/6f37f83a4802a0d411395f3abc5f24a2cfec025d - */ -class ParseSQLiteCursor implements Cursor { - - private final Cursor cursor; - private final Executor executor; - - private ParseSQLiteCursor(Cursor cursor, Executor executor) { - this.cursor = cursor; - this.executor = executor; - } - - public static Cursor create(Cursor cursor, Executor executor) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - return cursor; - } - return new ParseSQLiteCursor(cursor, executor); - } - - @Override - public int getCount() { - return cursor.getCount(); - } - - @Override - public int getPosition() { - return cursor.getPosition(); - } - - @Override - public boolean move(int offset) { - return cursor.move(offset); - } - - @Override - public boolean moveToPosition(int position) { - return cursor.moveToPosition(position); - } - - @Override - public boolean moveToFirst() { - return cursor.moveToFirst(); - } - - @Override - public boolean moveToLast() { - return cursor.moveToLast(); - } - - @Override - public boolean moveToNext() { - return cursor.moveToNext(); - } - - @Override - public boolean moveToPrevious() { - return cursor.moveToPrevious(); - } - - @Override - public boolean isFirst() { - return cursor.isFirst(); - } - - @Override - public boolean isLast() { - return cursor.isLast(); - } - - @Override - public boolean isBeforeFirst() { - return cursor.isBeforeFirst(); - } - - @Override - public boolean isAfterLast() { - return cursor.isAfterLast(); - } - - @Override - public int getColumnIndex(String columnName) { - return cursor.getColumnIndex(columnName); - } - - @Override - public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException { - return cursor.getColumnIndexOrThrow(columnName); - } - - @Override - public String getColumnName(int columnIndex) { - return cursor.getColumnName(columnIndex); - } - - @Override - public String[] getColumnNames() { - return cursor.getColumnNames(); - } - - @Override - public int getColumnCount() { - return cursor.getColumnCount(); - } - - @Override - public byte[] getBlob(int columnIndex) { - return cursor.getBlob(columnIndex); - } - - @Override - public String getString(int columnIndex) { - return cursor.getString(columnIndex); - } - - @Override - public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) { - cursor.copyStringToBuffer(columnIndex, buffer); - } - - @Override - public short getShort(int columnIndex) { - return cursor.getShort(columnIndex); - } - - @Override - public int getInt(int columnIndex) { - return cursor.getInt(columnIndex); - } - - @Override - public long getLong(int columnIndex) { - return cursor.getLong(columnIndex); - } - - @Override - public float getFloat(int columnIndex) { - return cursor.getFloat(columnIndex); - } - - @Override - public double getDouble(int columnIndex) { - return cursor.getDouble(columnIndex); - } - - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - @Override - public int getType(int columnIndex) { - return cursor.getType(columnIndex); - } - - @Override - public boolean isNull(int columnIndex) { - return cursor.isNull(columnIndex); - } - - @Override - @Deprecated - public void deactivate() { - cursor.deactivate(); - } - - @Override - @Deprecated - public boolean requery() { - return cursor.requery(); - } - - @Override - public void close() { - // Basically close _eventually_. - Task.call( - (Callable) - () -> { - cursor.close(); - return null; - }, - executor); - } - - @Override - public boolean isClosed() { - return cursor.isClosed(); - } - - @Override - public void registerContentObserver(ContentObserver observer) { - cursor.registerContentObserver(observer); - } - - @Override - public void unregisterContentObserver(ContentObserver observer) { - cursor.unregisterContentObserver(observer); - } - - @Override - public void registerDataSetObserver(DataSetObserver observer) { - cursor.registerDataSetObserver(observer); - } - - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - cursor.unregisterDataSetObserver(observer); - } - - @Override - public void setNotificationUri(ContentResolver cr, Uri uri) { - cursor.setNotificationUri(cr, uri); - } - - @TargetApi(Build.VERSION_CODES.KITKAT) - @Override - public Uri getNotificationUri() { - return cursor.getNotificationUri(); - } - - @Override - public boolean getWantsAllOnMoveCalls() { - return cursor.getWantsAllOnMoveCalls(); - } - - @Override - public Bundle getExtras() { - return cursor.getExtras(); - } - - @TargetApi(Build.VERSION_CODES.M) - @Override - public void setExtras(Bundle bundle) { - cursor.setExtras(bundle); - } - - @Override - public Bundle respond(Bundle extras) { - return cursor.respond(extras); - } -} diff --git a/parse/src/main/java/com/parse/ParseSQLiteDatabase.java b/parse/src/main/java/com/parse/ParseSQLiteDatabase.java index 6dd7ff969..dc1f667ac 100644 --- a/parse/src/main/java/com/parse/ParseSQLiteDatabase.java +++ b/parse/src/main/java/com/parse/ParseSQLiteDatabase.java @@ -217,9 +217,7 @@ public Task queryAsync( dbExecutor) .onSuccess( task12 -> { - Cursor cursor = - ParseSQLiteCursor.create( - task12.getResult(), dbExecutor); + Cursor cursor = task12.getResult(); /* Ensure the cursor window is filled on the dbExecutor thread. We need to do this because * the cursor cannot be filled from a different thread than it was created on. */ @@ -335,9 +333,7 @@ public Task rawQueryAsync(final String sql, final String[] args) { current.onSuccess(task13 -> db.rawQuery(sql, args), dbExecutor) .onSuccess( task12 -> { - Cursor cursor = - ParseSQLiteCursor.create( - task12.getResult(), dbExecutor); + Cursor cursor = task12.getResult(); // Ensure the cursor window is filled on the dbExecutor // thread. We need to do this because // the cursor cannot be filled from a different thread than diff --git a/parse/src/main/java/com/parse/ParseTaskUtils.java b/parse/src/main/java/com/parse/ParseTaskUtils.java index 6cd25d444..a76326743 100644 --- a/parse/src/main/java/com/parse/ParseTaskUtils.java +++ b/parse/src/main/java/com/parse/ParseTaskUtils.java @@ -98,7 +98,7 @@ static Task callbackOnMainThreadAsync( if (callback == null) { return task; } - final TaskCompletionSource tcs = new TaskCompletionSource(); + final TaskCompletionSource tcs = new TaskCompletionSource<>(); task.continueWith( (Continuation) task1 -> { diff --git a/parse/src/main/java/com/parse/PushRouter.java b/parse/src/main/java/com/parse/PushRouter.java index 56acac628..305f76096 100644 --- a/parse/src/main/java/com/parse/PushRouter.java +++ b/parse/src/main/java/com/parse/PushRouter.java @@ -29,7 +29,6 @@ */ public class PushRouter { private static final String TAG = "com.parse.ParsePushRouter"; - private static final String LEGACY_STATE_LOCATION = "pushState"; private static final String STATE_LOCATION = "push"; private static final int MAX_HISTORY_LENGTH = 10; @@ -45,8 +44,7 @@ private PushRouter(File diskState, PushHistory history) { public static synchronized PushRouter getInstance() { if (instance == null) { File diskState = new File(ParsePlugins.get().getFilesDir(), STATE_LOCATION); - File oldDiskState = new File(ParsePlugins.get().getParseDir(), LEGACY_STATE_LOCATION); - instance = pushRouterFromState(diskState, oldDiskState, MAX_HISTORY_LENGTH); + instance = pushRouterFromState(diskState, MAX_HISTORY_LENGTH); } return instance; @@ -59,33 +57,11 @@ static synchronized void resetInstance() { } /* package for tests */ - static PushRouter pushRouterFromState(File diskState, File oldDiskState, int maxHistoryLength) { + static PushRouter pushRouterFromState(File diskState, int maxHistoryLength) { JSONObject state = readJSONFileQuietly(diskState); JSONObject historyJSON = (state != null) ? state.optJSONObject("history") : null; PushHistory history = new PushHistory(maxHistoryLength, historyJSON); - - // If the deserialized push history object doesn't have a last timestamp, we might have to - // migrate the last timestamp from the legacy pushState file instead. - boolean didMigrate = false; - if (history.getLastReceivedTimestamp() == null) { - JSONObject oldState = readJSONFileQuietly(oldDiskState); - if (oldState != null) { - String lastTime = oldState.optString("lastTime", null); - if (lastTime != null) { - history.setLastReceivedTimestamp(lastTime); - } - didMigrate = true; - } - } - - PushRouter router = new PushRouter(diskState, history); - - if (didMigrate) { - router.saveStateToDisk(); - ParseFileUtils.deleteQuietly(oldDiskState); - } - - return router; + return new PushRouter(diskState, history); } private static JSONObject readJSONFileQuietly(File file) { diff --git a/parse/src/test/java/com/parse/ParseTestUtils.java b/parse/src/test/java/com/parse/ParseTestUtils.java index ce5b15bf2..b5c08192c 100644 --- a/parse/src/test/java/com/parse/ParseTestUtils.java +++ b/parse/src/test/java/com/parse/ParseTestUtils.java @@ -69,7 +69,7 @@ static ParsePlugins mockParsePlugins(Parse.Configuration configuration) { File parseDir = createFileDir(applicationContext.getDir("Parse", Context.MODE_PRIVATE)); when(parsePlugins.installationId()) .thenReturn(new InstallationId(new File(parseDir, "installationId"))); - when(parsePlugins.getParseDir()).thenReturn(parseDir); + when(parsePlugins.getFilesDir()).thenReturn(parseDir); when(parsePlugins.getCacheDir()) .thenReturn(createFileDir(new File(applicationContext.getCacheDir(), "com.parse"))); when(parsePlugins.getFilesDir()) diff --git a/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java b/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java index 2815f2951..42894ed09 100644 --- a/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java +++ b/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java @@ -129,15 +129,6 @@ public static Task linkInBackground(Context context, final ParseUser user) .onSuccessTask(task -> user.linkWithInBackground(AUTH_TYPE, task.getResult())); } - /** - * @deprecated Please use {@link ParseTwitterUtils#linkInBackground(Context, ParseUser)} - * instead. - */ - @Deprecated - public static void link(ParseUser user, Context context) { - link(user, context, null); - } - /** * Links a ParseUser to a Twitter account, allowing you to use Twitter for authentication, and * providing access to Twitter data for the user. A dialog will be shown to the user for Twitter @@ -178,20 +169,6 @@ public static Task linkInBackground( return user.linkWithInBackground(AUTH_TYPE, authData); } - /** - * @deprecated Please use {@link ParseTwitterUtils#linkInBackground(ParseUser, String, String, - * String, String)} instead. - */ - @Deprecated - public static void link( - ParseUser user, - String twitterId, - String screenName, - String authToken, - String authTokenSecret) { - link(user, twitterId, screenName, authToken, authTokenSecret, null); - } - /** * Links a ParseUser to a Twitter account, allowing you to use Twitter for authentication, and * providing access to Twitter data for the user. This method allows you to handle getting the From 83f0332f52abd43f7a5a0b420b91941517c61e13 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Wed, 17 Nov 2021 18:56:43 +0200 Subject: [PATCH 16/21] Tests code refactoring --- .../parse/facebook/FacebookController.java | 3 +- .../parse/facebook/ParseFacebookUtils.java | 2 +- .../facebook/ParseFacebookUtilsTest.java | 14 +- .../java/com/parse/ParseAnalyticsTest.java | 18 +- .../test/java/com/parse/ParseUserTest.java | 178 +++++++----------- .../com/parse/twitter/ParseTwitterUtils.java | 2 +- .../parse/twitter/ParseTwitterUtilsTest.java | 25 +-- .../parse/twitter/TwitterControllerTest.java | 2 +- 8 files changed, 99 insertions(+), 145 deletions(-) diff --git a/facebook/src/main/java/com/parse/facebook/FacebookController.java b/facebook/src/main/java/com/parse/facebook/FacebookController.java index 409fdbf64..f353ca4d0 100644 --- a/facebook/src/main/java/com/parse/facebook/FacebookController.java +++ b/facebook/src/main/java/com/parse/facebook/FacebookController.java @@ -12,6 +12,7 @@ import android.content.Context; import android.content.Intent; import android.text.TextUtils; +import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import com.facebook.AccessToken; import com.facebook.AccessTokenSource; @@ -113,7 +114,7 @@ public void onCancel() { } @Override - public void onError(FacebookException e) { + public void onError(@NonNull FacebookException e) { tcs.trySetError(e); } }); diff --git a/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java b/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java index 74fb5cb18..98e944f76 100644 --- a/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java +++ b/facebook/src/main/java/com/parse/facebook/ParseFacebookUtils.java @@ -566,7 +566,7 @@ private static Task callbackOnMainThreadInternalAsync( if (callback == null) { return task; } - final TaskCompletionSource tcs = new TaskCompletionSource(); + final TaskCompletionSource tcs = new TaskCompletionSource(); task.continueWith( (Continuation) task1 -> { diff --git a/facebook/src/test/java/com/parse/facebook/ParseFacebookUtilsTest.java b/facebook/src/test/java/com/parse/facebook/ParseFacebookUtilsTest.java index 95bbd3c7e..9d89b66cd 100644 --- a/facebook/src/test/java/com/parse/facebook/ParseFacebookUtilsTest.java +++ b/facebook/src/test/java/com/parse/facebook/ParseFacebookUtilsTest.java @@ -16,7 +16,6 @@ import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyMapOf; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doThrow; @@ -56,7 +55,7 @@ public class ParseFacebookUtilsTest { @Before public void setUp() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); ParseFacebookUtils.controller = controller; ParseFacebookUtils.userDelegate = userDelegate; } @@ -117,9 +116,7 @@ public void testRestoreAuthenticationFailure() throws java.text.ParseException { .registerAuthenticationCallback(eq("facebook"), callbackCaptor.capture()); AuthenticationCallback callback = callbackCaptor.getValue(); Map authData = new HashMap<>(); - doThrow(new RuntimeException()) - .when(controller) - .setAuthData(anyMapOf(String.class, String.class)); + doThrow(new RuntimeException()).when(controller).setAuthData(anyMap()); assertFalse(callback.onRestore(authData)); verify(controller).setAuthData(authData); @@ -160,7 +157,7 @@ public void testLogInWithAccessToken() { ParseFacebookUtils.isInitialized = true; ParseUser user = mock(ParseUser.class); - when(userDelegate.logInWithInBackground(anyString(), anyMapOf(String.class, String.class))) + when(userDelegate.logInWithInBackground(anyString(), anyMap())) .thenReturn(Task.forResult(user)); AccessToken token = TestUtils.newAccessToken(); Task task = ParseFacebookUtils.logInInBackground(token); @@ -225,7 +222,7 @@ private void doLogInWith( ParseFacebookUtils.isInitialized = true; ParseUser user = mock(ParseUser.class); - when(userDelegate.logInWithInBackground(anyString(), anyMapOf(String.class, String.class))) + when(userDelegate.logInWithInBackground(anyString(), anyMap())) .thenReturn(Task.forResult(user)); Task task; if (FacebookController.LoginAuthorizationType.PUBLISH.equals(type)) { @@ -266,8 +263,7 @@ public void testLinkWithAccessToken() { ParseFacebookUtils.isInitialized = true; ParseUser user = mock(ParseUser.class); - when(user.linkWithInBackground(anyString(), anyMapOf(String.class, String.class))) - .thenReturn(Task.forResult(null)); + when(user.linkWithInBackground(anyString(), anyMap())).thenReturn(Task.forResult(null)); AccessToken token = TestUtils.newAccessToken(); Task task = ParseFacebookUtils.linkInBackground(user, token); verify(controller).getAuthData(token); diff --git a/parse/src/test/java/com/parse/ParseAnalyticsTest.java b/parse/src/test/java/com/parse/ParseAnalyticsTest.java index 97697cede..94fa856f9 100644 --- a/parse/src/test/java/com/parse/ParseAnalyticsTest.java +++ b/parse/src/test/java/com/parse/ParseAnalyticsTest.java @@ -12,7 +12,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyMapOf; +import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isNull; @@ -53,11 +53,10 @@ public void setUp() { // Mock ParseAnalyticsController controller = mock(ParseAnalyticsController.class); - when(controller.trackEventInBackground( - anyString(), anyMapOf(String.class, String.class), anyString())) - .thenReturn(Task.forResult(null)); + when(controller.trackEventInBackground(anyString(), anyMap(), anyString())) + .thenReturn(Task.forResult(null)); when(controller.trackAppOpenedInBackground(anyString(), anyString())) - .thenReturn(Task.forResult(null)); + .thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerAnalyticsController(controller); } @@ -94,8 +93,7 @@ public void testTrackEventInBackgroundNormalName() throws Exception { ParseTaskUtils.wait(ParseAnalytics.trackEventInBackground("test")); verify(controller, times(1)) - .trackEventInBackground( - eq("test"), Matchers.>eq(null), isNull(String.class)); + .trackEventInBackground(eq("test"), Matchers.eq(null), isNull(String.class)); } @Test @@ -104,8 +102,7 @@ public void testTrackEventInBackgroundNullParameters() throws Exception { ParseAnalytics.trackEventInBackground("test", (Map) null)); verify(controller, times(1)) - .trackEventInBackground( - eq("test"), Matchers.>eq(null), isNull(String.class)); + .trackEventInBackground(eq("test"), Matchers.eq(null), isNull(String.class)); } @Test @@ -169,8 +166,7 @@ public void testTrackEventInBackgroundNormalCallback() throws Exception { // Make sure the callback is called assertTrue(doneAgain.tryAcquire(1, 10, TimeUnit.SECONDS)); verify(controller, times(1)) - .trackEventInBackground( - eq("test"), Matchers.>eq(null), isNull(String.class)); + .trackEventInBackground(eq("test"), Matchers.eq(null), isNull(String.class)); } // endregion diff --git a/parse/src/test/java/com/parse/ParseUserTest.java b/parse/src/test/java/com/parse/ParseUserTest.java index fcb1f69a0..8920e5832 100644 --- a/parse/src/test/java/com/parse/ParseUserTest.java +++ b/parse/src/test/java/com/parse/ParseUserTest.java @@ -14,12 +14,12 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyMapOf; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -51,7 +51,6 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.mockito.Matchers; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; @@ -155,8 +154,7 @@ public void testParcelableState() { public void testSignUpAsyncWithNoUserName() throws Exception { // Register a mock currentUserController to make getCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getAsync(anyBoolean())) - .thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(anyBoolean())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); ParseUser user = new ParseUser(); @@ -164,15 +162,14 @@ public void testSignUpAsyncWithNoUserName() throws Exception { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Username cannot be missing or blank"); - ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); + ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); } @Test public void testSignUpAsyncWithNoPassword() throws Exception { // Register a mock currentUserController to make getCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getAsync(anyBoolean())) - .thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(anyBoolean())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); ParseUser user = new ParseUser(); @@ -181,15 +178,14 @@ public void testSignUpAsyncWithNoPassword() throws Exception { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Password cannot be missing or blank"); - ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); + ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); } @Test public void testSignUpAsyncWithObjectIdSetAndAuthDataNotSet() throws Exception { // Register a mock currentUserController to make getCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getAsync(anyBoolean())) - .thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(anyBoolean())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); ParseUser.State userState = new ParseUser.State.Builder().objectId("test").build(); @@ -200,7 +196,7 @@ public void testSignUpAsyncWithObjectIdSetAndAuthDataNotSet() throws Exception { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Cannot sign up a user that has already signed up."); - ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); + ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); } @Test @@ -222,22 +218,19 @@ public void testSignUpAsyncWithObjectIdSetAndAuthDataSet() throws Exception { user.setPassword("password"); // TODO (mengyan): Avoid using partial mock after we have ParseObjectInstanceController ParseUser partialMockUser = spy(user); - doReturn(Task.forResult(null)) - .when(partialMockUser) - .saveAsync(anyString(), Matchers.>any()); + doReturn(Task.forResult(null)).when(partialMockUser).saveAsync(anyString(), any()); - ParseTaskUtils.wait(partialMockUser.signUpAsync(Task.forResult(null))); + ParseTaskUtils.wait(partialMockUser.signUpAsync(Task.forResult(null))); // Verify user is saved - verify(partialMockUser, times(1)).saveAsync(eq("sessionToken"), Matchers.>any()); + verify(partialMockUser, times(1)).saveAsync(eq("sessionToken"), any()); } @Test public void testSignUpAsyncWithAnotherSignUpAlreadyRunning() throws Exception { // Register a mock currentUserController to make getCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getAsync(anyBoolean())) - .thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(anyBoolean())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); ParseUser user = new ParseUser(); @@ -248,7 +241,7 @@ public void testSignUpAsyncWithAnotherSignUpAlreadyRunning() throws Exception { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Cannot sign up a user that is already signing up."); - ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); + ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); } @Test @@ -268,7 +261,7 @@ public void testSignUpAsyncWithSignUpSameAnonymousUser() throws Exception { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Attempt to merge currentUser with itself."); - ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); + ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); } @Test @@ -281,8 +274,7 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUser() throws Exception { when(currentUser.isLinked(ParseAnonymousUtils.AUTH_TYPE)).thenReturn(true); when(currentUser.getSessionToken()).thenReturn("oldSessionToken"); when(currentUser.getAuthData()).thenReturn(new HashMap<>()); - when(currentUser.saveAsync(anyString(), eq(false), Matchers.>any())) - .thenReturn(Task.forResult(null)); + when(currentUser.saveAsync(anyString(), eq(false), any())).thenReturn(Task.forResult(null)); ParseUser.State state = new ParseUser.State.Builder().put("oldKey", "oldValue").build(); when(currentUser.getState()).thenReturn(state); ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); @@ -296,7 +288,7 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUser() throws Exception { anonymousAuthData.put("key", "token"); user.putAuthData(ParseAnonymousUtils.AUTH_TYPE, anonymousAuthData); - Task signUpTask = user.signUpAsync(Task.forResult(null)); + Task signUpTask = user.signUpAsync(Task.forResult(null)); signUpTask.waitForCompletion(); // Make sure currentUser copy changes from user @@ -305,8 +297,7 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUser() throws Exception { verify(currentUser, times(1)).setUsername("userName"); verify(currentUser, times(1)).setPassword("password"); // Make sure we save currentUser - verify(currentUser, times(1)) - .saveAsync(eq("oldSessionToken"), eq(false), Matchers.>any()); + verify(currentUser, times(1)).saveAsync(eq("oldSessionToken"), eq(false), any()); // Make sure we merge currentUser with user after save assertEquals("oldValue", user.get("oldKey")); // Make sure set currentUser @@ -328,7 +319,7 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUserSaveFailure() throws Exce ParseException saveException = new ParseException(ParseException.OTHER_CAUSE, ""); doReturn(Task.forError(saveException)) .when(partialMockCurrentUser) - .saveAsync(anyString(), eq(false), Matchers.>any()); + .saveAsync(anyString(), eq(false), any()); ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.getAsync(anyBoolean())) .thenReturn(Task.forResult(partialMockCurrentUser)); @@ -341,7 +332,7 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUserSaveFailure() throws Exce anonymousAuthData.put("key", "token"); user.putAuthData(ParseAnonymousUtils.AUTH_TYPE, anonymousAuthData); - Task signUpTask = user.signUpAsync(Task.forResult(null)); + Task signUpTask = user.signUpAsync(Task.forResult(null)); signUpTask.waitForCompletion(); // Make sure we update currentUser username and password @@ -350,8 +341,7 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUserSaveFailure() throws Exce // Make sure we sync user with currentUser verify(partialMockCurrentUser, times(1)).copyChangesFrom(eq(user)); // Make sure we save currentUser - verify(partialMockCurrentUser, times(1)) - .saveAsync(eq("oldSessionToken"), eq(false), Matchers.>any()); + verify(partialMockCurrentUser, times(1)).saveAsync(eq("oldSessionToken"), eq(false), any()); // Make sure we restore old username and password after save fails verify(partialMockCurrentUser, times(1)).setUsername("oldUserName"); verify(partialMockCurrentUser, times(1)).setPassword("oldPassword"); @@ -367,8 +357,7 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUserSaveFailure() throws Exce public void testSignUpAsyncWithNoCurrentUserAndSignUpSuccess() throws Exception { // Register a mock currentUserController to make getCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getAsync(anyBoolean())) - .thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(anyBoolean())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Register a mock userController to make logIn work ParseUserController userController = mock(ParseUserController.class); @@ -388,7 +377,7 @@ public void testSignUpAsyncWithNoCurrentUserAndSignUpSuccess() throws Exception user.setUsername("userName"); user.setPassword("password"); - ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); + ParseTaskUtils.wait(user.signUpAsync(Task.forResult(null))); // Make sure we sign up the user verify(userController, times(1)) @@ -412,8 +401,7 @@ public void testSignUpAsyncWithNoCurrentUserAndSignUpSuccess() throws Exception public void testSignUpAsyncWithNoCurrentUserAndSignUpFailure() { // Register a mock currentUserController to make getCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getAsync(anyBoolean())) - .thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(anyBoolean())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Register a mock userController to make logIn work ParseUserController userController = mock(ParseUserController.class); @@ -422,7 +410,7 @@ public void testSignUpAsyncWithNoCurrentUserAndSignUpFailure() { any(ParseUser.State.class), any(ParseOperationSet.class), nullable(String.class))) - .thenReturn(Task.forError(signUpException)); + .thenReturn(Task.forError(signUpException)); ParseCorePlugins.getInstance().registerUserController(userController); ParseUser user = new ParseUser(); @@ -430,7 +418,7 @@ public void testSignUpAsyncWithNoCurrentUserAndSignUpFailure() { user.setUsername("userName"); user.setPassword("password"); - Task signUpTask = user.signUpAsync(Task.forResult(null)); + Task signUpTask = user.signUpAsync(Task.forResult(null)); // Make sure we sign up the user verify(userController, times(1)) @@ -450,9 +438,8 @@ public void testSignUpAsyncWithNoCurrentUserAndSignUpFailure() { @Test public void testLoginWithAsyncWithoutExistingLazyUser() throws ParseException { ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getAsync(false)).thenReturn(Task.forResult(null)); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(false)).thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseUser.State userState = mock(ParseUser.State.class); when(userState.className()).thenReturn("_User"); @@ -460,7 +447,7 @@ public void testLoginWithAsyncWithoutExistingLazyUser() throws ParseException { when(userState.isComplete()).thenReturn(true); ParseUserController userController = mock(ParseUserController.class); - when(userController.logInAsync(anyString(), anyMapOf(String.class, String.class))) + when(userController.logInAsync(anyString(), anyMap())) .thenReturn(Task.forResult(userState)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); @@ -490,7 +477,7 @@ public void testLoginWithAsyncWithLinkedLazyUser() throws Exception { when(partialMockCurrentUser.getSessionToken()).thenReturn("oldSessionToken"); doReturn(Task.forResult(null)) .when(partialMockCurrentUser) - .resolveLazinessAsync(Matchers.>any()); + .resolveLazinessAsync(any()); ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.getAsync(false)) .thenReturn(Task.forResult(partialMockCurrentUser)); @@ -507,7 +494,7 @@ public void testLoginWithAsyncWithLinkedLazyUser() throws Exception { // Make sure we update authData assertEquals(authData, userAfterLogin.getAuthData().get("facebook")); // Make sure we resolveLaziness - verify(partialMockCurrentUser, times(1)).resolveLazinessAsync(Matchers.>any()); + verify(partialMockCurrentUser, times(1)).resolveLazinessAsync(any()); } @Test @@ -521,7 +508,7 @@ public void testLoginWithAsyncWithLinkedLazyUseAndResolveLazinessFailure() throw when(partialMockCurrentUser.getSessionToken()).thenReturn("oldSessionToken"); doReturn(Task.forError(new Exception())) .when(partialMockCurrentUser) - .resolveLazinessAsync(Matchers.>any()); + .resolveLazinessAsync(any()); ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.getAsync(false)) .thenReturn(Task.forResult(partialMockCurrentUser)); @@ -535,7 +522,7 @@ public void testLoginWithAsyncWithLinkedLazyUseAndResolveLazinessFailure() throw loginTask.waitForCompletion(); // Make sure we try to resolveLaziness - verify(partialMockCurrentUser, times(1)).resolveLazinessAsync(Matchers.>any()); + verify(partialMockCurrentUser, times(1)).resolveLazinessAsync(any()); // Make sure we do not save new authData assertNull(partialMockCurrentUser.getAuthData().get("facebook")); // Make sure we restore anonymity after resolve laziness failure @@ -558,7 +545,7 @@ public void testLoginWithAsyncWithLinkedNotLazyUser() throws Exception { ParseUser partialMockCurrentUser = spy(currentUser); // ParseUser.mutex doReturn(Task.forResult(null)) .when(partialMockCurrentUser) - .linkWithInBackground(anyString(), Matchers.>any()); + .linkWithInBackground(anyString(), anyMap()); ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.getAsync()).thenReturn(Task.forResult(partialMockCurrentUser)); when(currentUserController.getAsync(anyBoolean())) @@ -586,7 +573,7 @@ public void testLoginWithAsyncWithLinkedNotLazyUserLinkFailure() throws Exceptio .put("newKey", "newValue") .sessionToken("newSessionToken") .build(); - when(userController.logInAsync(anyString(), Matchers.>any())) + when(userController.logInAsync(anyString(), anyMap())) .thenReturn(Task.forResult(newUserState)); ParseCorePlugins.getInstance().registerUserController(userController); // Register a mock currentUserController to make getCurrentUser work @@ -599,12 +586,11 @@ public void testLoginWithAsyncWithLinkedNotLazyUserLinkFailure() throws Exceptio new ParseException(ParseException.ACCOUNT_ALREADY_LINKED, "Account already linked"); doReturn(Task.forError(linkException)) .when(partialMockCurrentUser) - .linkWithInBackground(anyString(), Matchers.>any()); + .linkWithInBackground(anyString(), anyMap()); ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); when(currentUserController.getAsync(false)) .thenReturn(Task.forResult(partialMockCurrentUser)); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); String authType = "facebook"; @@ -637,14 +623,13 @@ public void testLoginWithAsyncWithNoCurrentUser() throws Exception { .put("newKey", "newValue") .sessionToken("newSessionToken") .build(); - when(userController.logInAsync(anyString(), Matchers.>any())) + when(userController.logInAsync(anyString(), anyMap())) .thenReturn(Task.forResult(newUserState)); ParseCorePlugins.getInstance().registerUserController(userController); // Register a mock currentUserController to make getCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getAsync(false)).thenReturn(Task.forResult(null)); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(false)).thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); String authType = "facebook"; @@ -667,14 +652,12 @@ public void testLoginWithAsyncWithNoCurrentUser() throws Exception { public void testlinkWithInBackgroundWithSaveAsyncSuccess() throws Exception { // Register a mock currentUserController to make setCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getCurrentSessionTokenAsync()) - .thenReturn(Task.forResult(null)); - when(currentUserController.getAsync(anyBoolean())) - .thenReturn(Task.forResult(null)); + when(currentUserController.getCurrentSessionTokenAsync()).thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(anyBoolean())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Register mock callbacks AuthenticationCallback callbacks = mock(AuthenticationCallback.class); - when(callbacks.onRestore(Matchers.>any())).thenReturn(true); + when(callbacks.onRestore(anyMap())).thenReturn(true); ParseUser.registerAuthenticationCallback("facebook", callbacks); ParseUser user = new ParseUser(); @@ -686,7 +669,7 @@ public void testlinkWithInBackgroundWithSaveAsyncSuccess() throws Exception { ParseUser partialMockUser = spy(user); doReturn(Task.forResult(null)) .when(partialMockUser) - .saveAsync(anyString(), eq(false), Matchers.>any()); + .saveAsync(anyString(), eq(false), any()); doReturn("sessionTokenAgain").when(partialMockUser).getSessionToken(); Map authData = new HashMap<>(); authData.put("token", "test"); @@ -698,8 +681,7 @@ public void testlinkWithInBackgroundWithSaveAsyncSuccess() throws Exception { // Make sure new authData is added assertSame(authData, partialMockUser.getAuthData().get("facebook")); // Make sure we save the user - verify(partialMockUser, times(1)) - .saveAsync(eq("sessionTokenAgain"), eq(false), Matchers.>any()); + verify(partialMockUser, times(1)).saveAsync(eq("sessionTokenAgain"), eq(false), any()); // Make sure synchronizeAuthData() is called verify(callbacks, times(1)).onRestore(authData); } @@ -726,7 +708,7 @@ public void testlinkWithInBackgroundWithSaveAsyncFailure() throws Exception { Exception saveException = new Exception(); doReturn(Task.forError(saveException)) .when(partialMockUser) - .saveAsync(anyString(), eq(false), Matchers.>any()); + .saveAsync(anyString(), eq(false), any()); doReturn("sessionTokenAgain").when(partialMockUser).getSessionToken(); String authType = "facebook"; Map authData = new HashMap<>(); @@ -736,8 +718,7 @@ public void testlinkWithInBackgroundWithSaveAsyncFailure() throws Exception { linkTask.waitForCompletion(); // Make sure we save the user - verify(partialMockUser, times(1)) - .saveAsync(eq("sessionTokenAgain"), eq(false), Matchers.>any()); + verify(partialMockUser, times(1)).saveAsync(eq("sessionTokenAgain"), eq(false), any()); // Make sure old authData is restored assertSame( anonymousAuthData, @@ -766,11 +747,10 @@ public void testResolveLazinessAsyncWithAuthDataAndNotNewUser() throws Exception ParseCorePlugins.getInstance().registerUserController(userController); // Register a mock currentUserController to make getCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); - ParseTaskUtils.wait(user.resolveLazinessAsync(Task.forResult(null))); + ParseTaskUtils.wait(user.resolveLazinessAsync(Task.forResult(null))); ArgumentCaptor userAfterResolveLazinessCaptor = ArgumentCaptor.forClass(ParseUser.class); @@ -810,7 +790,7 @@ public void testResolveLazinessAsyncWithAuthDataAndNewUser() throws Exception { ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); - ParseTaskUtils.wait(user.resolveLazinessAsync(Task.forResult(null))); + ParseTaskUtils.wait(user.resolveLazinessAsync(Task.forResult(null))); // Make sure we logIn the lazy user verify(userController, times(1)) @@ -848,13 +828,12 @@ public void testResolveLazinessAsyncWithAuthDataAndNotNewUserAndLDSEnabled() thr ParseCorePlugins.getInstance().registerUserController(userController); // Register a mock currentUserController to make getCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Enable LDS Parse.enableLocalDatastore(null); - ParseTaskUtils.wait(user.resolveLazinessAsync(Task.forResult(null))); + ParseTaskUtils.wait(user.resolveLazinessAsync(Task.forResult(null))); ArgumentCaptor userAfterResolveLazinessCaptor = ArgumentCaptor.forClass(ParseUser.class); @@ -941,8 +920,7 @@ public void testValidateSaveWithLDSNotEnabledAndCurrentUserNotMatch() { public void testSaveAsyncWithLazyAndCurrentUser() throws Exception { // Register a mock currentUserController to make setCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Set facebook authData to null to verify cleanAuthData() @@ -952,11 +930,9 @@ public void testSaveAsyncWithLazyAndCurrentUser() throws Exception { setLazy(user); user.setIsCurrentUser(true); ParseUser partialMockUser = spy(user); - doReturn(Task.forResult(null)) - .when(partialMockUser) - .resolveLazinessAsync(Matchers.>any()); + doReturn(Task.forResult(null)).when(partialMockUser).resolveLazinessAsync(any()); - ParseTaskUtils.wait(partialMockUser.saveAsync("sessionToken", Task.forResult(null))); + ParseTaskUtils.wait(partialMockUser.saveAsync("sessionToken", Task.forResult(null))); // Make sure we clean authData assertFalse(partialMockUser.getState().authData().containsKey("facebook")); @@ -975,8 +951,7 @@ public void testSaveAsyncWithLazyAndCurrentUser() throws Exception { public void testSaveAsyncWithLazyAndNotCurrentUser() throws Exception { // Register a mock currentUserController to make setCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Set facebook authData to null to verify cleanAuthData() @@ -986,11 +961,9 @@ public void testSaveAsyncWithLazyAndNotCurrentUser() throws Exception { setLazy(user); user.setIsCurrentUser(false); ParseUser partialMockUser = spy(user); - doReturn(Task.forResult(null)) - .when(partialMockUser) - .resolveLazinessAsync(Matchers.>any()); + doReturn(Task.forResult(null)).when(partialMockUser).resolveLazinessAsync(any()); - ParseTaskUtils.wait(partialMockUser.saveAsync("sessionToken", Task.forResult(null))); + ParseTaskUtils.wait(partialMockUser.saveAsync("sessionToken", Task.forResult(null))); // Make sure we do not clean authData assertTrue(partialMockUser.getAuthData().containsKey("facebook")); @@ -1006,10 +979,10 @@ public void testSaveAsyncWithLazyAndNotCurrentUser() throws Exception { public void testLogOutAsync() throws Exception { // Register a mock sessionController to verify revokeAsync() NetworkSessionController sessionController = mock(NetworkSessionController.class); - when(sessionController.revokeAsync(anyString())).thenReturn(Task.forResult(null)); + when(sessionController.revokeAsync(anyString())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerSessionController(sessionController); ParseAuthenticationManager manager = mock(ParseAuthenticationManager.class); - when(manager.deauthenticateAsync(anyString())).thenReturn(Task.forResult(null)); + when(manager.deauthenticateAsync(anyString())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerAuthenticationManager(manager); // Set user initial state @@ -1057,8 +1030,7 @@ public void testEnableRevocableSessionInBackgroundWithNoCurrentUser() throws Exc ParsePlugins.set(mockPlugins); // Register a mock currentUserController to verify setAsync ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.getAsync(anyBoolean())) - .thenReturn(Task.forResult(null)); + when(currentUserController.getAsync(anyBoolean())).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); ParseTaskUtils.wait(ParseUser.enableRevocableSessionInBackground()); @@ -1161,16 +1133,14 @@ public void testUnlinkFromAsyncWithAuthType() throws Exception { .build(); ParseUser user = ParseObject.from(userState); ParseUser partialMockUser = spy(user); - doReturn(Task.forResult(null)) - .when(partialMockUser) - .saveAsync(anyString(), Matchers.>any()); + doReturn(Task.forResult(null)).when(partialMockUser).saveAsync(anyString(), any()); ParseTaskUtils.wait(partialMockUser.unlinkFromInBackground(authType)); // Verify we delete authData assertNull(user.getAuthData().get("facebook")); // Verify we save the user - verify(partialMockUser, times(1)).saveAsync(eq("sessionToken"), Matchers.>any()); + verify(partialMockUser, times(1)).saveAsync(eq("sessionToken"), any()); } @Test @@ -1193,8 +1163,7 @@ public void testLogInWithNoPassword() throws Exception { public void testLogIn() throws Exception { // Register a mock currentUserController to make setCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Register a mock userController to make logIn work ParseUserController userController = mock(ParseUserController.class); @@ -1226,8 +1195,7 @@ public void testLogIn() throws Exception { public void testLogInWithCallback() throws Exception { // Register a mock currentUserController to make setCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Register a mock userController to make logIn work ParseUserController userController = mock(ParseUserController.class); @@ -1273,8 +1241,7 @@ public void testBecomeWithNoSessionToken() throws Exception { public void testBecome() throws Exception { // Register a mock currentUserController to make setCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Register a mock userController to make getUsreAsync work ParseUserController userController = mock(ParseUserController.class); @@ -1305,8 +1272,7 @@ public void testBecome() throws Exception { public void testBecomeWithCallback() { // Register a mock currentUserController to make setCurrentUser work ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class); - when(currentUserController.setAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + when(currentUserController.setAsync(any(ParseUser.class))).thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Register a mock userController to make getUsreAsync work ParseUserController userController = mock(ParseUserController.class); @@ -1404,7 +1370,7 @@ public void testSynchronizeAuthData() throws Exception { ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Register mock callbacks AuthenticationCallback callbacks = mock(AuthenticationCallback.class); - when(callbacks.onRestore(Matchers.>any())).thenReturn(true); + when(callbacks.onRestore(any())).thenReturn(true); ParseUser.registerAuthenticationCallback("facebook", callbacks); // Set user initial state @@ -1435,7 +1401,7 @@ public void testSynchronizeAllAuthData() throws Exception { ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); // Register mock callbacks AuthenticationCallback callbacks = mock(AuthenticationCallback.class); - when(callbacks.onRestore(Matchers.>any())).thenReturn(true); + when(callbacks.onRestore(any())).thenReturn(true); ParseUser.registerAuthenticationCallback("facebook", callbacks); // Set user initial state @@ -1495,7 +1461,7 @@ public void testPinCurrentUserIfNeededAsync() { currentUser.setObjectId("test"); CachedCurrentUserController currentUserController = mock(CachedCurrentUserController.class); when(currentUserController.setIfNeededAsync(any(ParseUser.class))) - .thenReturn(Task.forResult(null)); + .thenReturn(Task.forResult(null)); ParseCorePlugins.getInstance().registerCurrentUserController(currentUserController); ParseUser user = new ParseUser(); diff --git a/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java b/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java index 42894ed09..76707cb6f 100644 --- a/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java +++ b/twitter/src/main/java/com/parse/twitter/ParseTwitterUtils.java @@ -369,7 +369,7 @@ private static Task callbackOnMainThreadInternalAsync( if (callback == null) { return task; } - final TaskCompletionSource tcs = new TaskCompletionSource(); + final TaskCompletionSource tcs = new TaskCompletionSource(); task.continueWith( (Continuation) task1 -> { diff --git a/twitter/src/test/java/com/parse/twitter/ParseTwitterUtilsTest.java b/twitter/src/test/java/com/parse/twitter/ParseTwitterUtilsTest.java index 49588d0e0..e16510057 100644 --- a/twitter/src/test/java/com/parse/twitter/ParseTwitterUtilsTest.java +++ b/twitter/src/test/java/com/parse/twitter/ParseTwitterUtilsTest.java @@ -10,8 +10,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyMapOf; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doThrow; @@ -32,7 +32,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ParseTwitterUtilsTest { @@ -84,9 +84,7 @@ public void testRestoreAuthenticationFailure() { ArgumentCaptor.forClass(AuthenticationCallback.class); verify(userDelegate).registerAuthenticationCallback(eq("twitter"), captor.capture()); - doThrow(new RuntimeException()) - .when(controller) - .setAuthData(anyMapOf(String.class, String.class)); + doThrow(new RuntimeException()).when(controller).setAuthData(anyMap()); AuthenticationCallback callback = captor.getValue(); Map authData = new HashMap<>(); assertFalse(callback.onRestore(authData)); @@ -111,7 +109,7 @@ public void testIsLinked() { public void testLogInWithToken() { ParseTwitterUtils.isInitialized = true; ParseUser user = mock(ParseUser.class); - when(userDelegate.logInWithInBackground(anyString(), anyMapOf(String.class, String.class))) + when(userDelegate.logInWithInBackground(anyString(), anyMap())) .thenReturn(Task.forResult(user)); String twitterId = "test_id"; @@ -121,8 +119,7 @@ public void testLogInWithToken() { Task task = ParseTwitterUtils.logInInBackground(twitterId, screenName, authToken, authSecret); verify(controller).getAuthData(twitterId, screenName, authToken, authSecret); - verify(userDelegate) - .logInWithInBackground(eq("twitter"), anyMapOf(String.class, String.class)); + verify(userDelegate).logInWithInBackground(eq("twitter"), anyMap()); assertTrue(task.isCompleted()); } @@ -133,7 +130,7 @@ public void testLogInWithContext() { ParseUser user = mock(ParseUser.class); Map authData = new HashMap<>(); when(controller.authenticateAsync(any(Context.class))).thenReturn(Task.forResult(authData)); - when(userDelegate.logInWithInBackground(anyString(), anyMapOf(String.class, String.class))) + when(userDelegate.logInWithInBackground(anyString(), anyMap())) .thenReturn(Task.forResult(user)); Context context = mock(Context.class); @@ -153,8 +150,7 @@ public void testLinkWithToken() { ParseTwitterUtils.isInitialized = true; ParseUser user = mock(ParseUser.class); - when(user.linkWithInBackground(anyString(), anyMapOf(String.class, String.class))) - .thenReturn(Task.forResult(null)); + when(user.linkWithInBackground(anyString(), anyMap())).thenReturn(Task.forResult(null)); String twitterId = "test_id"; String screenName = "test_screen_name"; String authToken = "test_token"; @@ -163,7 +159,7 @@ public void testLinkWithToken() { ParseTwitterUtils.linkInBackground( user, twitterId, screenName, authToken, authSecret); verify(controller).getAuthData(twitterId, screenName, authToken, authSecret); - verify(user).linkWithInBackground(eq("twitter"), anyMapOf(String.class, String.class)); + verify(user).linkWithInBackground(eq("twitter"), anyMap()); assertTrue(task.isCompleted()); } @@ -176,8 +172,7 @@ public void testLinkWithContext() { Context context = mock(Context.class); ParseUser user = mock(ParseUser.class); - when(user.linkWithInBackground(anyString(), anyMapOf(String.class, String.class))) - .thenReturn(Task.forResult(null)); + when(user.linkWithInBackground(anyString(), any())).thenReturn(Task.forResult(null)); Task task = ParseTwitterUtils.linkInBackground(context, user); verify(controller).authenticateAsync(context); verify(user).linkWithInBackground("twitter", authData); @@ -190,7 +185,7 @@ public void testLinkWithContext() { public void testUnlink() { ParseTwitterUtils.isInitialized = true; ParseUser user = mock(ParseUser.class); - when(user.unlinkFromInBackground(anyString())).thenReturn(Task.forResult(null)); + when(user.unlinkFromInBackground(anyString())).thenReturn(Task.forResult(null)); Task task = ParseTwitterUtils.unlinkInBackground(user); verify(user).unlinkFromInBackground("twitter"); verifyNoMoreInteractions(user); diff --git a/twitter/src/test/java/com/parse/twitter/TwitterControllerTest.java b/twitter/src/test/java/com/parse/twitter/TwitterControllerTest.java index 2be1e9857..f11803906 100644 --- a/twitter/src/test/java/com/parse/twitter/TwitterControllerTest.java +++ b/twitter/src/test/java/com/parse/twitter/TwitterControllerTest.java @@ -27,7 +27,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class TwitterControllerTest { From 803eb25484228843a09a5735a543f2092bd0d26f Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Thu, 18 Nov 2021 09:12:50 +0200 Subject: [PATCH 17/21] Migrate from deprecated AsyncTask --- .../main/java/com/parse/twitter/Twitter.java | 240 ++++++++++-------- 1 file changed, 130 insertions(+), 110 deletions(-) diff --git a/twitter/src/main/java/com/parse/twitter/Twitter.java b/twitter/src/main/java/com/parse/twitter/Twitter.java index 483dc0af5..b2067ffe4 100644 --- a/twitter/src/main/java/com/parse/twitter/Twitter.java +++ b/twitter/src/main/java/com/parse/twitter/Twitter.java @@ -10,9 +10,12 @@ import android.content.Context; import android.net.Uri; -import android.os.AsyncTask; -import android.webkit.CookieSyncManager; +import android.os.Handler; +import android.os.Looper; +import android.webkit.CookieManager; import com.parse.twitter.OAuth1FlowDialog.FlowResultHandler; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import oauth.signpost.http.HttpParameters; import se.akerfeldt.okhttp.signpost.OkHttpOAuthConsumer; import se.akerfeldt.okhttp.signpost.OkHttpOAuthProvider; @@ -107,115 +110,132 @@ public void authorize(final Context context, final AsyncCallback callback) { final OkHttpOAuthConsumer consumer = new OkHttpOAuthConsumer(getConsumerKey(), getConsumerSecret()); - // https://stackoverflow.com/a/64969640/1274974 - AsyncTask task = - new AsyncTask() { - private Throwable error; - - @Override - protected String doInBackground(Void... params) { - try { - return provider.retrieveRequestToken(consumer, callbackUrl); - } catch (Throwable e) { - error = e; - } - return null; - } + final ExecutorService executor = Executors.newSingleThreadExecutor(); + final Handler handler = new Handler(Looper.getMainLooper()); + + executor.execute( + () -> { + Throwable error = null; + String requestToken = null; - @Override - protected void onPostExecute(String result) { - super.onPostExecute(result); - if (error != null) { - callback.onFailure(error); - return; - } - CookieSyncManager.createInstance(context); - OAuth1FlowDialog dialog = - new OAuth1FlowDialog( - context, - result, - callbackUrl, - "api.twitter", - new FlowResultHandler() { - - @Override - public void onError( - int errorCode, - String description, - String failingUrl) { - callback.onFailure( - new OAuth1FlowException( - errorCode, - description, - failingUrl)); - } - - @Override - public void onComplete(String callbackUrl) { - CookieSyncManager.getInstance().sync(); - Uri uri = Uri.parse(callbackUrl); - final String verifier = - uri.getQueryParameter(VERIFIER_PARAM); - if (verifier == null) { - callback.onCancel(); - return; - } - AsyncTask getTokenTask = - new AsyncTask< - Void, Void, HttpParameters>() { - private Throwable error; - - @Override - protected HttpParameters doInBackground( - Void... params) { - try { - provider.retrieveAccessToken( - consumer, verifier); - } catch (Throwable e) { - error = e; - } - return provider - .getResponseParameters(); - } - - @Override - protected void onPostExecute( - HttpParameters result) { - super.onPostExecute(result); - if (error != null) { - callback.onFailure(error); - return; - } - try { - setAuthToken( - consumer.getToken()); - setAuthTokenSecret( - consumer - .getTokenSecret()); - setScreenName( - result.getFirst( - SCREEN_NAME_PARAM)); - setUserId( - result.getFirst( - USER_ID_PARAM)); - } catch (Throwable e) { - callback.onFailure(e); - return; - } - callback.onSuccess(Twitter.this); - } - }; - getTokenTask.execute(); - } - - @Override - public void onCancel() { - callback.onCancel(); - } - }); - dialog.show(); + try { + requestToken = provider.retrieveRequestToken(consumer, callbackUrl); + } catch (Throwable e) { + error = e; } - }; - task.execute(); + + final Throwable finalError = error; + final String finalRequestToken = requestToken; + + handler.post( + () -> { + if (finalError != null) { + callback.onFailure(finalError); + return; + } + + OAuth1FlowDialog dialog = + new OAuth1FlowDialog( + context, + finalRequestToken, + callbackUrl, + "api.twitter", + new FlowResultHandler() { + + @Override + public void onError( + int errorCode, + String description, + String failingUrl) { + callback.onFailure( + new OAuth1FlowException( + errorCode, + description, + failingUrl)); + } + + @Override + public void onComplete(String callbackUrl) { + CookieManager.getInstance().flush(); + final Uri uri = Uri.parse(callbackUrl); + final String verifier = + uri.getQueryParameter( + VERIFIER_PARAM); + if (verifier == null) { + callback.onCancel(); + return; + } + + executor.execute( + () -> { + Throwable error = null; + HttpParameters parameters = + null; + + try { + provider + .retrieveAccessToken( + consumer, + verifier); + parameters = + provider + .getResponseParameters(); + } catch (Throwable e) { + error = e; + } + + final Throwable finalError = + error; + final HttpParameters + finalParameters = + parameters; + + handler.post( + () -> { + if (finalError + != null) { + callback + .onFailure( + finalError); + return; + } + try { + setAuthToken( + consumer + .getToken()); + setAuthTokenSecret( + consumer + .getTokenSecret()); + setScreenName( + finalParameters + .getFirst( + SCREEN_NAME_PARAM)); + setUserId( + finalParameters + .getFirst( + USER_ID_PARAM)); + } catch ( + Throwable + e) { + callback + .onFailure( + e); + return; + } + callback.onSuccess( + Twitter + .this); + }); + }); + } + + @Override + public void onCancel() { + callback.onCancel(); + } + }); + dialog.show(); + }); + }); } } From 11bfdce7b1e670b9f5150ac3c799933e9462e5d7 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Thu, 18 Nov 2021 09:19:39 +0200 Subject: [PATCH 18/21] Revert Kotlin to 1.5.31 As not sure if all libraries supports 1.6.0 which was released one or two days ago --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9c03a99e7..c78e1b983 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = "1.6.0" + ext.kotlin_version = "1.5.31" ext.jacocoVersion = '0.8.7' repositories { google() From 8efba1af1f19efd9c8b587484eb9e65e77f87837 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Thu, 18 Nov 2021 11:02:12 +0200 Subject: [PATCH 19/21] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 667c3b18c..ec4393adf 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Snyk Badge](https://snyk.io/test/github/parse-community/Parse-SDK-Android/badge.svg)](https://snyk.io/test/github/parse-community/Parse-SDK-Android) [![codecov](https://codecov.io/gh/parse-community/Parse-SDK-Android/branch/master/graph/badge.svg)](https://codecov.io/gh/parse-community/Parse-SDK-Android) -[![android min api](https://img.shields.io/badge/Android_API->=16-66c718.svg)](https://github.com/parse-community/parse-dashboard/releases) +[![android min api](https://img.shields.io/badge/Android_API->=21-66c718.svg)](https://github.com/parse-community/parse-dashboard/releases) [![auto-release](https://img.shields.io/badge/%F0%9F%9A%80-auto--release-9e34eb.svg)](https://github.com/parse-community/parse-dashboard/releases) [![](https://jitpack.io/v/parse-community/Parse-SDK-Android.svg)](https://jitpack.io/#parse-community/Parse-SDK-Android) From 6727da785388dd8f9aba7f61ab150a64f14f8557 Mon Sep 17 00:00:00 2001 From: Asen Lekov Date: Fri, 19 Nov 2021 09:23:04 +0200 Subject: [PATCH 20/21] Add Compatibility section to README --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index ec4393adf..125a8e635 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ A library that gives you access to the powerful Parse Server backend from your A --- - [Getting Started](#getting-started) + - [Compatibility](#compatibility) - [Add Dependency](#add-dependency) - [Setup](#setup) - [Contributing](#contributing) @@ -32,6 +33,21 @@ A library that gives you access to the powerful Parse Server backend from your A # Getting Started +## Compatibility + +The Android API versions compatibility is defined as follow: + +- Target API level - Try awlays to target the latest available stable one +- Minimum API level - Bump to API 21 starting from 2.1.0 and increment as high as possible, but cover at least 95% of devices. The increment will be done only if some of the dependent libraries requires it or if the statistics points that this API level covers at least 95% of the devices. All API changes will be marked in the release notes. + +| SDK version | Minimum API level | Targeting API level | AGP[^1] | +| ----------- | ----------------- | ------------------- | ------- | +| 1.26 | < API 16 | API 29 | 3.6.2 | +| 2.0 | >= API 16 | API 30 | 4.2.2 | +| 2.1+ | >= API 21 | API 31 | 7.0.3 | + +[^1]: AGP stand for [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) + ## Add Dependency Add this in your root `build.gradle` file (**not** your module `build.gradle` file): @@ -46,6 +62,7 @@ allprojects { ``` Then, add the library to your project `build.gradle` + ```gradle ext { parseVersion = "latest.version.here" @@ -104,6 +121,7 @@ The custom `Application` class must be registered in `AndroidManifest.xml`: ... ``` + Note that if you are testing with a server using `http`, you will need to add `android:usesCleartextTraffic="true"` to your above `` definition, but you should only do this while testing and should use `https` for your final product. See the [guide][guide] for the rest of the SDK usage. @@ -113,6 +131,7 @@ See the [guide][guide] for the rest of the SDK usage. We want to make contributing to this project as easy and transparent as possible. Please refer to the [Contribution Guidelines](CONTRIBUTING.md). # More Parse Android Projects + These are other official libraries we made that can help you create your Parse app. - [ParseGoogleUtils](/google) - Google login/signup. From 9fbe204d9b9d34b7292342acee581b4da2086571 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Thu, 25 Nov 2021 13:47:53 +0100 Subject: [PATCH 21/21] refactor compatibility --- CONTRIBUTING.md | 32 +++++++++++++------------------- README.md | 18 +++++++----------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 53f74c7b8..06bce3e58 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,13 +1,7 @@ # Contributing to Parse SDK for Android We want to make contributing to this project as easy and transparent as possible. -## Our Development Process -Most of our work will be done in public directly on GitHub. There may be changes done through our internal source control, but it will be rare and only as needed. - -### `master` is unsafe -Our goal is to keep `master` stable, but there may be changes that your application may not be compatible with. We'll do our best to publicize any breaking changes, but try to use our specific releases in any production environment. - -### Pull Requests +## Pull Requests We actively welcome your pull requests. When we get one, we'll run some Parse-specific integration tests on it first. From here, we'll need to get a core member to sign off on the changes and then merge the pull request. For API changes we may need to fix internal uses, which could cause some delay. We'll do our best to provide updates and feedback throughout the process. 1. Fork the repo and create your branch from `master`. @@ -16,13 +10,13 @@ We actively welcome your pull requests. When we get one, we'll run some Parse-sp 4. Ensure the test suite passes. 5. Make sure your code lints by running `./gradlew spotlessApply`. -## Bugs -Although we try to keep developing on Parse easy, you still may run into some issues. Technical questions should be asked on [Stack Overflow][stack-overflow], and for everything else we'll be using GitHub issues. +## Android API compatibility -### Known Issues -We use GitHub issues to track public bugs. We will keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new issue, try to make sure your problem doesn't already exist. +Consider the following to ensure a consistent Android API compatibility for the Parse Android SDK: +- Target API level: Target the latest available stable API version. +- Minimum API level: Cover at least ~90% of devices. The increment will be done only if dependencies requires it, if the statistics points that the API level covers at least ~90% of devices, or if a currently supported Android API level does not receive security updates anymore. Minimum API level changes must be marked in the release notes as breaking changes. -### Reporting New Issues +## Reporting an Issue Not all issues are SDK issues. If you're unsure whether your bug is with the SDK or backend, you can test to see if it reproduces with our [REST API][rest-api] and [Parse API Console][parse-api-console]. If it does, you can report backend bugs [here][bug-reports]. To view the REST API network requests issued by the Parse SDK and responses from the Parse backend, please check out [OkHttp Interceptors][network-debugging-tool]. With this tool, you can either log network requests/responses to Android logcat, or log them to Chrome Debugger via Stetho. @@ -41,10 +35,10 @@ This project adheres to the [Contributor Covenant Code of Conduct](https://githu ## License By contributing to Parse Android SDK, you agree that your contributions will be licensed under its license. - [stack-overflow]: http://stackoverflow.com/tags/parse.com - [bug-reports]: https://github.com/parse-community/parse-server - [rest-api]: http://docs.parseplatform.org/rest/guide/ - [network-debugging-tool]: https://github.com/square/okhttp/wiki/Interceptors - [parse-api-console]: http://blog.parseplatform.org/announcements/introducing-the-parse-api-console/ - [stacktrace-or-gtfo]: http://i.imgur.com/jacoj.jpg - [tests-dir]: /parse/src/test/java/com/parse +[stack-overflow]: http://stackoverflow.com/tags/parse.com +[bug-reports]: https://github.com/parse-community/parse-server +[rest-api]: http://docs.parseplatform.org/rest/guide/ +[network-debugging-tool]: https://github.com/square/okhttp/wiki/Interceptors +[parse-api-console]: http://blog.parseplatform.org/announcements/introducing-the-parse-api-console/ +[stacktrace-or-gtfo]: http://i.imgur.com/jacoj.jpg +[tests-dir]: /parse/src/test/java/com/parse diff --git a/README.md b/README.md index 125a8e635..057943729 100644 --- a/README.md +++ b/README.md @@ -35,18 +35,13 @@ A library that gives you access to the powerful Parse Server backend from your A ## Compatibility -The Android API versions compatibility is defined as follow: +The Parse Android SDK has the following Android API and [Gradle Plugin][gradle-plugin] compatibility. -- Target API level - Try awlays to target the latest available stable one -- Minimum API level - Bump to API 21 starting from 2.1.0 and increment as high as possible, but cover at least 95% of devices. The increment will be done only if some of the dependent libraries requires it or if the statistics points that this API level covers at least 95% of the devices. All API changes will be marked in the release notes. - -| SDK version | Minimum API level | Targeting API level | AGP[^1] | -| ----------- | ----------------- | ------------------- | ------- | -| 1.26 | < API 16 | API 29 | 3.6.2 | -| 2.0 | >= API 16 | API 30 | 4.2.2 | -| 2.1+ | >= API 21 | API 31 | 7.0.3 | - -[^1]: AGP stand for [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) +| SDK version | Minimum API level | Targeting API level | Gradle Plugin | +|-------------|-------------------|---------------------|---------------| +| 1.26 | < API 16 | API 29 | 3.6.2 | +| 2.0 | >= API 16 | API 30 | 4.2.2 | +| 2.1 | >= API 21 | API 31 | 7.0.3 | ## Add Dependency @@ -150,3 +145,4 @@ As of April 5, 2017, Parse, LLC has transferred this code to the parse-community [guide]: http://docs.parseplatform.org/android/guide/ [open-collective-link]: https://opencollective.com/parse-server +[gradle-plugin]: https://developer.android.com/studio/releases/gradle-plugin