diff --git a/CHANGELOG.md b/CHANGELOG.md index 425a4172..95d45655 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog for DP3T-SDK Android + +## version 2.0.2 (22.01.2021) + +- make sure GoogleExposureClient does not block thread forever, but times out after 5min. This to prevent Workers to be stuck, if an EN method does not call the success or error callback, due to an error or misconfiguration in the EN framework. + ## version 2.0.1 (22.12.2020) - updated all dependencies diff --git a/dp3t-sdk/sdk/build.gradle b/dp3t-sdk/sdk/build.gradle index 0107c59e..c6c1ab0e 100644 --- a/dp3t-sdk/sdk/build.gradle +++ b/dp3t-sdk/sdk/build.gradle @@ -21,8 +21,8 @@ android { defaultConfig { minSdkVersion 23 targetSdkVersion 30 - versionCode 201 - versionName "2.0.1" + versionCode 202 + versionName "2.0.2" testInstrumentationRunnerArgument 'androidx.benchmark.suppressErrors', 'EMULATOR,LOW-BATTERY,ACTIVITY-MISSING,DEBUGGABLE,UNLOCKED,UNSUSTAINED-ACTIVITY-MISSING' testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" diff --git a/dp3t-sdk/sdk/src/main/java/org/dpppt/android/sdk/internal/nearby/GoogleExposureClient.java b/dp3t-sdk/sdk/src/main/java/org/dpppt/android/sdk/internal/nearby/GoogleExposureClient.java index aef0436a..e5660d4e 100644 --- a/dp3t-sdk/sdk/src/main/java/org/dpppt/android/sdk/internal/nearby/GoogleExposureClient.java +++ b/dp3t-sdk/sdk/src/main/java/org/dpppt/android/sdk/internal/nearby/GoogleExposureClient.java @@ -17,6 +17,7 @@ import java.io.File; import java.util.List; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import com.google.android.gms.common.api.ApiException; import com.google.android.gms.nearby.Nearby; @@ -33,6 +34,8 @@ public class GoogleExposureClient { private static final String EITHER_EXCEPTION_OR_RESULT_MUST_BE_SET = "either exception or result must be set"; + private static final long TIMEOUT_EXPOSURE_CLIENT_CALL_MS = 5 * 60 * 1000L;//5min + private static GoogleExposureClient instance; private final ExposureNotificationClient exposureNotificationClient; @@ -131,7 +134,10 @@ public List getTemporaryExposureKeyHistorySynchronous() th countDownLatch.countDown(); }); - countDownLatch.await(); + boolean noTimeout = countDownLatch.await(TIMEOUT_EXPOSURE_CLIENT_CALL_MS, TimeUnit.MILLISECONDS); + if (!noTimeout) { + throw new IllegalStateException("getTemporaryExposureKeyHistory() did not result in success or failure in time."); + } if (results[0] instanceof Exception) { throw (Exception) results[0]; @@ -159,7 +165,12 @@ public void provideDiagnosisKeys(List keys) throws Exception { exceptions[0] = e; countDownLatch.countDown(); }); - countDownLatch.await(); + + boolean noTimeout = countDownLatch.await(TIMEOUT_EXPOSURE_CLIENT_CALL_MS, TimeUnit.MILLISECONDS); + if (!noTimeout) { + throw new IllegalStateException("provideDiagnosisKeys() did not result in success or failure in time."); + } + if (exceptions[0] != null) { throw exceptions[0]; } @@ -189,7 +200,11 @@ public void provideDiagnosisKeys(List keys, ExposureConfiguration exposure exceptions[0] = e; countDownLatch.countDown(); }); - countDownLatch.await(); + + boolean noTimeout = countDownLatch.await(TIMEOUT_EXPOSURE_CLIENT_CALL_MS, TimeUnit.MILLISECONDS); + if (!noTimeout) { + throw new IllegalStateException("provideDiagnosisKeys() did not result in success or failure in time."); + } if (exceptions[0] != null) { throw exceptions[0]; @@ -214,7 +229,10 @@ public ExposureSummary getExposureSummary(String token) throws Exception { countDownLatch.countDown(); }); - countDownLatch.await(); + boolean noTimeout = countDownLatch.await(TIMEOUT_EXPOSURE_CLIENT_CALL_MS, TimeUnit.MILLISECONDS); + if (!noTimeout) { + throw new IllegalStateException("getExposureSummary() did not result in success or failure in time."); + } if (results[0] instanceof Exception) { throw (Exception) results[0]; @@ -238,7 +256,12 @@ public List getExposureWindows() throws Exception { results[0] = e; countDownLatch.countDown(); }); - countDownLatch.await(); + + boolean noTimeout = countDownLatch.await(TIMEOUT_EXPOSURE_CLIENT_CALL_MS, TimeUnit.MILLISECONDS); + if (!noTimeout) { + throw new IllegalStateException("getExposureWindows() did not result in success or failure in time."); + } + if (results[0] instanceof Exception) { throw (Exception) results[0]; } else if (results[0] instanceof List) { @@ -268,7 +291,12 @@ public Integer getCalibrationConfidence() throws Exception { results[0] = e; countDownLatch.countDown(); }); - countDownLatch.await(); + + boolean noTimeout = countDownLatch.await(TIMEOUT_EXPOSURE_CLIENT_CALL_MS, TimeUnit.MILLISECONDS); + if (!noTimeout) { + throw new IllegalStateException("getCalibrationConfidence() did not result in success or failure in time."); + } + if (results[0] instanceof Exception) { throw (Exception) results[0]; } else if (results[0] instanceof Integer) {