From 2e19e51ecf8aff32e1fdba90e00995b5868690da Mon Sep 17 00:00:00 2001 From: Krystof Woldrich Date: Wed, 16 Nov 2022 15:18:15 +0100 Subject: [PATCH] Fix activity holder access, return build info --- .../api/sentry-android-core.api | 2 +- .../core/AndroidOptionsInitializer.java | 2 +- .../android/core/CurrentActivityHolder.java | 7 ++---- .../core/ScreenshotEventProcessor.java | 22 +++++++++---------- .../core/internal/util/ActivityUtils.java | 20 ----------------- .../core/internal/util/ScreenshotUtils.java | 20 +++++++++++++---- .../core/ScreenshotEventProcessorTest.kt | 3 ++- 7 files changed, 33 insertions(+), 43 deletions(-) delete mode 100644 sentry-android-core/src/main/java/io/sentry/android/core/internal/util/ActivityUtils.java diff --git a/sentry-android-core/api/sentry-android-core.api b/sentry-android-core/api/sentry-android-core.api index 42afa2f72e..1759624b6c 100644 --- a/sentry-android-core/api/sentry-android-core.api +++ b/sentry-android-core/api/sentry-android-core.api @@ -122,7 +122,7 @@ public final class io/sentry/android/core/PhoneStateBreadcrumbsIntegration : io/ } public final class io/sentry/android/core/ScreenshotEventProcessor : android/app/Application$ActivityLifecycleCallbacks, io/sentry/EventProcessor, java/io/Closeable { - public fun (Landroid/app/Application;Lio/sentry/android/core/SentryAndroidOptions;)V + public fun (Landroid/app/Application;Lio/sentry/android/core/SentryAndroidOptions;Lio/sentry/android/core/BuildInfoProvider;)V public fun close ()V public fun onActivityCreated (Landroid/app/Activity;Landroid/os/Bundle;)V public fun onActivityDestroyed (Landroid/app/Activity;)V diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java index a375653d7d..21206cc026 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java @@ -209,7 +209,7 @@ private static void installDefaultIntegrations( if (isFragmentAvailable) { options.addIntegration(new FragmentLifecycleIntegration((Application) context, true, true)); } - options.addEventProcessor(new ScreenshotEventProcessor((Application) context, options)); + options.addEventProcessor(new ScreenshotEventProcessor((Application) context, options, buildInfoProvider)); } else { options .getLogger() diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityHolder.java b/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityHolder.java index c7b4a91817..659dd0400c 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityHolder.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/CurrentActivityHolder.java @@ -5,19 +5,16 @@ import androidx.annotation.Nullable; import java.lang.ref.WeakReference; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @ApiStatus.Internal public class CurrentActivityHolder { - private static @Nullable CurrentActivityHolder instance; + private static @NotNull CurrentActivityHolder instance = new CurrentActivityHolder(); private @Nullable WeakReference currentActivity; public static CurrentActivityHolder getInstance() { - if (instance != null) { - return instance; - } - instance = new CurrentActivityHolder(); return instance; } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ScreenshotEventProcessor.java b/sentry-android-core/src/main/java/io/sentry/android/core/ScreenshotEventProcessor.java index 22582cece2..ff279e0002 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/ScreenshotEventProcessor.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/ScreenshotEventProcessor.java @@ -30,14 +30,14 @@ public final class ScreenshotEventProcessor private final @NotNull Application application; private final @NotNull SentryAndroidOptions options; - private final @NotNull CurrentActivityHolder currentActivityHolder; + private final @NotNull BuildInfoProvider buildInfoProvider; private boolean lifecycleCallbackInstalled = true; public ScreenshotEventProcessor( - final @NotNull Application application, final @NotNull SentryAndroidOptions options) { + final @NotNull Application application, final @NotNull SentryAndroidOptions options, final @NotNull BuildInfoProvider buildInfoProvider) { this.application = Objects.requireNonNull(application, "Application is required"); this.options = Objects.requireNonNull(options, "SentryAndroidOptions is required"); - this.currentActivityHolder = CurrentActivityHolder.getInstance(); + this.buildInfoProvider = Objects.requireNonNull(buildInfoProvider, "BuildInfoProvider is required"); application.registerActivityLifecycleCallbacks(this); } @@ -60,24 +60,24 @@ public ScreenshotEventProcessor( return event; } - if (currentActivityHolder.getActivity() == null || HintUtils.isFromHybridSdk(hint)) { + if (CurrentActivityHolder.getInstance().getActivity() == null || HintUtils.isFromHybridSdk(hint)) { return event; } final byte[] screenshot = - takeScreenshot(currentActivityHolder.getActivity(), options.getLogger()); + takeScreenshot(CurrentActivityHolder.getInstance().getActivity(), options.getLogger(), buildInfoProvider); if (screenshot == null) { return event; } hint.setScreenshot(Attachment.fromScreenshot(screenshot)); - hint.set(ANDROID_ACTIVITY, currentActivityHolder.getActivity()); + hint.set(ANDROID_ACTIVITY, CurrentActivityHolder.getInstance().getActivity()); return event; } @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { - currentActivityHolder.setActivity(activity); + CurrentActivityHolder.getInstance().setActivity(activity); } @Override @@ -112,17 +112,17 @@ public void onActivityDestroyed(@NonNull Activity activity) { public void close() throws IOException { if (options.isAttachScreenshot()) { application.unregisterActivityLifecycleCallbacks(this); - currentActivityHolder.clearActivity(); + CurrentActivityHolder.getInstance().clearActivity(); } } private void cleanCurrentActivity(@NonNull Activity activity) { - if (currentActivityHolder.getActivity() == activity) { - currentActivityHolder.clearActivity(); + if (CurrentActivityHolder.getInstance().getActivity() == activity) { + CurrentActivityHolder.getInstance().clearActivity(); } } private void setCurrentActivity(@NonNull Activity activity) { - currentActivityHolder.setActivity(activity); + CurrentActivityHolder.getInstance().setActivity(activity); } } diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/ActivityUtils.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/ActivityUtils.java deleted file mode 100644 index 3a494eb414..0000000000 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/ActivityUtils.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.sentry.android.core.internal.util; - -import android.app.Activity; -import android.os.Build; -import androidx.annotation.Nullable; -import org.jetbrains.annotations.ApiStatus; - -@ApiStatus.Internal -public class ActivityUtils { - public static boolean isActivityValid(@Nullable Activity activity) { - if (activity == null) { - return false; - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - return !activity.isFinishing() && !activity.isDestroyed(); - } else { - return !activity.isFinishing(); - } - } -} diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/ScreenshotUtils.java b/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/ScreenshotUtils.java index 3c1703c0d2..e34265bd7b 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/ScreenshotUtils.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/internal/util/ScreenshotUtils.java @@ -1,14 +1,15 @@ package io.sentry.android.core.internal.util; -import static io.sentry.android.core.internal.util.ActivityUtils.isActivityValid; - import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.os.Build; import android.view.View; import androidx.annotation.Nullable; import io.sentry.ILogger; import io.sentry.SentryLevel; +import io.sentry.android.core.BuildInfoProvider; + import java.io.ByteArrayOutputStream; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -16,12 +17,12 @@ @ApiStatus.Internal public class ScreenshotUtils { public static @Nullable byte[] takeScreenshot( - final @Nullable Activity activity, final @NotNull ILogger logger) { + final @Nullable Activity activity, final @NotNull ILogger logger, final @NotNull BuildInfoProvider buildInfoProvider) { if (activity == null) { return null; } - if (!isActivityValid(activity) + if (!isActivityValid(activity, buildInfoProvider) || activity.getWindow() == null || activity.getWindow().getDecorView() == null || activity.getWindow().getDecorView().getRootView() == null) { @@ -61,4 +62,15 @@ public class ScreenshotUtils { } return null; } + + public static boolean isActivityValid(final @Nullable Activity activity, final @NotNull BuildInfoProvider buildInfoProvider) { + if (activity == null) { + return false; + } + if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + return !activity.isFinishing() && !activity.isDestroyed(); + } else { + return !activity.isFinishing(); + } + } } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/ScreenshotEventProcessorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/ScreenshotEventProcessorTest.kt index c220c73fb2..3d81b176bf 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/ScreenshotEventProcessorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/ScreenshotEventProcessorTest.kt @@ -28,6 +28,7 @@ class ScreenshotEventProcessorTest { private class Fixture { val application = mock() + val buildInfo = mock() val activity = mock() val window = mock() val view = mock() @@ -48,7 +49,7 @@ class ScreenshotEventProcessorTest { fun getSut(attachScreenshot: Boolean = false): ScreenshotEventProcessor { options.isAttachScreenshot = attachScreenshot - return ScreenshotEventProcessor(application, options) + return ScreenshotEventProcessor(application, options, buildInfo) } }