Skip to content

Commit 15641a2

Browse files
authored
Merge 9aaadc6 into d364ace
2 parents d364ace + 9aaadc6 commit 15641a2

File tree

6 files changed

+105
-54
lines changed

6 files changed

+105
-54
lines changed

sentry-android-distribution/api/sentry-android-distribution.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
public final class io/sentry/android/distribution/DistributionIntegration : io/sentry/IDistributionApi, io/sentry/Integration {
22
public fun <init> (Landroid/content/Context;)V
3-
public fun checkForUpdate (Lio/sentry/IDistributionApi$UpdateCallback;)V
3+
public fun checkForUpdate ()Ljava/util/concurrent/Future;
44
public fun checkForUpdateBlocking ()Lio/sentry/UpdateStatus;
55
public fun downloadUpdate (Lio/sentry/UpdateInfo;)V
66
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V

sentry-android-distribution/src/main/java/io/sentry/android/distribution/DistributionIntegration.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import io.sentry.UpdateInfo
1414
import io.sentry.UpdateStatus
1515
import java.net.SocketTimeoutException
1616
import java.net.UnknownHostException
17+
import java.util.concurrent.Future
1718
import org.jetbrains.annotations.ApiStatus
1819

1920
/**
@@ -84,14 +85,12 @@ public class DistributionIntegration(context: Context) : Integration, IDistribut
8485
}
8586

8687
/**
87-
* Check for available updates asynchronously using a callback.
88+
* Check for available updates asynchronously.
8889
*
89-
* @param onResult Callback that will be called with the UpdateStatus result
90+
* @return Future that will resolve to an UpdateStatus result
9091
*/
91-
public override fun checkForUpdate(onResult: IDistributionApi.UpdateCallback) {
92-
// TODO implement this in a async way
93-
val result = checkForUpdateBlocking()
94-
onResult.onResult(result)
92+
public override fun checkForUpdate(): Future<UpdateStatus> {
93+
return sentryOptions.executorService.submit<UpdateStatus> { checkForUpdateBlocking() }
9594
}
9695

9796
/**

sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/MainActivity.java

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.Collections;
3030
import java.util.List;
3131
import java.util.concurrent.CountDownLatch;
32+
import java.util.concurrent.Future;
3233
import timber.log.Timber;
3334

3435
public class MainActivity extends AppCompatActivity {
@@ -315,35 +316,51 @@ public void run() {
315316
binding.checkForUpdate.setOnClickListener(
316317
view -> {
317318
Toast.makeText(this, "Checking for updates...", Toast.LENGTH_SHORT).show();
318-
Sentry.distribution()
319-
.checkForUpdate(
320-
result -> {
321-
runOnUiThread(
322-
() -> {
323-
String message;
324-
if (result instanceof UpdateStatus.NewRelease) {
325-
UpdateStatus.NewRelease newRelease = (UpdateStatus.NewRelease) result;
326-
message =
327-
"Update available: "
328-
+ newRelease.getInfo().getBuildVersion()
329-
+ " (Build "
330-
+ newRelease.getInfo().getBuildNumber()
331-
+ ")\nDownload URL: "
332-
+ newRelease.getInfo().getDownloadUrl();
333-
} else if (result instanceof UpdateStatus.UpToDate) {
334-
message = "App is up to date!";
335-
} else if (result instanceof UpdateStatus.NoNetwork) {
336-
UpdateStatus.NoNetwork noNetwork = (UpdateStatus.NoNetwork) result;
337-
message = "No network connection: " + noNetwork.getMessage();
338-
} else if (result instanceof UpdateStatus.UpdateError) {
339-
UpdateStatus.UpdateError error = (UpdateStatus.UpdateError) result;
340-
message = "Error checking for updates: " + error.getMessage();
341-
} else {
342-
message = "Unknown status";
343-
}
344-
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
345-
});
346-
});
319+
Future<UpdateStatus> future = Sentry.distribution().checkForUpdate();
320+
// In production, convert this to use your preferred async library (RxJava, Coroutines,
321+
// etc.)
322+
// This sample uses raw threads and Future.get() for simplicity
323+
// Process result on background thread, then update UI
324+
new Thread(
325+
() -> {
326+
try {
327+
UpdateStatus result = future.get();
328+
runOnUiThread(
329+
() -> {
330+
String message;
331+
if (result instanceof UpdateStatus.NewRelease) {
332+
UpdateStatus.NewRelease newRelease = (UpdateStatus.NewRelease) result;
333+
message =
334+
"Update available: "
335+
+ newRelease.getInfo().getBuildVersion()
336+
+ " (Build "
337+
+ newRelease.getInfo().getBuildNumber()
338+
+ ")\nDownload URL: "
339+
+ newRelease.getInfo().getDownloadUrl();
340+
} else if (result instanceof UpdateStatus.UpToDate) {
341+
message = "App is up to date!";
342+
} else if (result instanceof UpdateStatus.NoNetwork) {
343+
UpdateStatus.NoNetwork noNetwork = (UpdateStatus.NoNetwork) result;
344+
message = "No network connection: " + noNetwork.getMessage();
345+
} else if (result instanceof UpdateStatus.UpdateError) {
346+
UpdateStatus.UpdateError error = (UpdateStatus.UpdateError) result;
347+
message = "Error checking for updates: " + error.getMessage();
348+
} else {
349+
message = "Unknown status";
350+
}
351+
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
352+
});
353+
} catch (Exception e) {
354+
runOnUiThread(
355+
() ->
356+
Toast.makeText(
357+
this,
358+
"Error checking for updates: " + e.getMessage(),
359+
Toast.LENGTH_LONG)
360+
.show());
361+
}
362+
})
363+
.start();
347364
});
348365

349366
binding.openCameraActivity.setOnClickListener(

sentry/api/sentry.api

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -776,15 +776,11 @@ public abstract interface class io/sentry/IContinuousProfiler {
776776
}
777777

778778
public abstract interface class io/sentry/IDistributionApi {
779-
public abstract fun checkForUpdate (Lio/sentry/IDistributionApi$UpdateCallback;)V
779+
public abstract fun checkForUpdate ()Ljava/util/concurrent/Future;
780780
public abstract fun checkForUpdateBlocking ()Lio/sentry/UpdateStatus;
781781
public abstract fun downloadUpdate (Lio/sentry/UpdateInfo;)V
782782
}
783783

784-
public abstract interface class io/sentry/IDistributionApi$UpdateCallback {
785-
public abstract fun onResult (Lio/sentry/UpdateStatus;)V
786-
}
787-
788784
public abstract interface class io/sentry/IEnvelopeReader {
789785
public abstract fun read (Ljava/io/InputStream;)Lio/sentry/SentryEnvelope;
790786
}
@@ -1493,7 +1489,7 @@ public final class io/sentry/NoOpContinuousProfiler : io/sentry/IContinuousProfi
14931489
}
14941490

14951491
public final class io/sentry/NoOpDistributionApi : io/sentry/IDistributionApi {
1496-
public fun checkForUpdate (Lio/sentry/IDistributionApi$UpdateCallback;)V
1492+
public fun checkForUpdate ()Ljava/util/concurrent/Future;
14971493
public fun checkForUpdateBlocking ()Lio/sentry/UpdateStatus;
14981494
public fun downloadUpdate (Lio/sentry/UpdateInfo;)V
14991495
public static fun getInstance ()Lio/sentry/NoOpDistributionApi;
Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry;
22

3+
import java.util.concurrent.Future;
34
import org.jetbrains.annotations.ApiStatus;
45
import org.jetbrains.annotations.NotNull;
56

@@ -14,20 +15,21 @@ public interface IDistributionApi {
1415

1516
/**
1617
* Check for available updates synchronously (blocking call). This method will block the calling
17-
* thread while making the network request. Consider using checkForUpdate with callback for
18-
* non-blocking behavior.
18+
* thread while making the network request. Consider using checkForUpdate for non-blocking
19+
* behavior.
1920
*
2021
* @return UpdateStatus indicating if an update is available, up to date, or error
2122
*/
2223
@NotNull
2324
UpdateStatus checkForUpdateBlocking();
2425

2526
/**
26-
* Check for available updates asynchronously using a callback.
27+
* Check for available updates asynchronously.
2728
*
28-
* @param onResult Callback that will be called with the UpdateStatus result
29+
* @return Future that will resolve to an UpdateStatus result
2930
*/
30-
void checkForUpdate(@NotNull UpdateCallback onResult);
31+
@NotNull
32+
Future<UpdateStatus> checkForUpdate();
3133

3234
/**
3335
* Download and install the provided update by opening the download URL in the default browser or
@@ -36,9 +38,4 @@ public interface IDistributionApi {
3638
* @param info Information about the update to download
3739
*/
3840
void downloadUpdate(@NotNull UpdateInfo info);
39-
40-
/** Callback interface for receiving async update check results. */
41-
interface UpdateCallback {
42-
void onResult(@NotNull UpdateStatus status);
43-
}
4441
}

sentry/src/main/java/io/sentry/NoOpDistributionApi.java

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package io.sentry;
22

3+
import java.util.concurrent.ExecutionException;
4+
import java.util.concurrent.Future;
5+
import java.util.concurrent.TimeUnit;
6+
import java.util.concurrent.TimeoutException;
37
import org.jetbrains.annotations.ApiStatus;
48
import org.jetbrains.annotations.NotNull;
59

@@ -21,12 +25,50 @@ public static NoOpDistributionApi getInstance() {
2125
}
2226

2327
@Override
24-
public void checkForUpdate(@NotNull UpdateCallback onResult) {
25-
// No-op implementation - do nothing
28+
public @NotNull Future<UpdateStatus> checkForUpdate() {
29+
return new CompletedFuture<>(UpdateStatus.UpToDate.getInstance());
2630
}
2731

2832
@Override
2933
public void downloadUpdate(@NotNull UpdateInfo info) {
3034
// No-op implementation - do nothing
3135
}
36+
37+
/**
38+
* A Future implementation that is already completed with a result. This is used instead of
39+
* CompletableFuture.completedFuture() to maintain compatibility with Android API 21+.
40+
*/
41+
private static final class CompletedFuture<T> implements Future<T> {
42+
private final T result;
43+
44+
CompletedFuture(T result) {
45+
this.result = result;
46+
}
47+
48+
@Override
49+
public boolean cancel(final boolean mayInterruptIfRunning) {
50+
return false;
51+
}
52+
53+
@Override
54+
public boolean isCancelled() {
55+
return false;
56+
}
57+
58+
@Override
59+
public boolean isDone() {
60+
return true;
61+
}
62+
63+
@Override
64+
public T get() throws ExecutionException {
65+
return result;
66+
}
67+
68+
@Override
69+
public T get(final long timeout, final @NotNull TimeUnit unit)
70+
throws ExecutionException, TimeoutException {
71+
return result;
72+
}
73+
}
3274
}

0 commit comments

Comments
 (0)