From f240816d1f7ef8010fd351ef6dc91a103eaeb880 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Thu, 14 Mar 2024 20:47:49 +0900 Subject: [PATCH 1/4] feat: Provide opt-out for crash reporting and device capture com.deploygate app can know the shallow-configuration via init event --- .../java/com/deploygate/sdk/DeployGate.java | 90 +++++++-- .../sdk/DeployGateSdkConfiguration.java | 180 ++++++++++++++++++ .../main/java/com/deploygate/sdk/HostApp.java | 49 ++++- .../deploygate/service/DeployGateEvent.java | 7 + .../java/com/deploygate/sdk/HostAppTest.java | 47 ++++- 5 files changed, 350 insertions(+), 23 deletions(-) create mode 100644 sdk/src/main/java/com/deploygate/sdk/DeployGateSdkConfiguration.java diff --git a/sdk/src/main/java/com/deploygate/sdk/DeployGate.java b/sdk/src/main/java/com/deploygate/sdk/DeployGate.java index d9b1420..b017f92 100644 --- a/sdk/src/main/java/com/deploygate/sdk/DeployGate.java +++ b/sdk/src/main/java/com/deploygate/sdk/DeployGate.java @@ -102,7 +102,7 @@ public void onEvent( } else if (DeployGateEvent.ACTION_ONESHOT_LOGCAT.equals(action)) { String captureId = null; - if (mDeployGateClient.isSupported(Compatibility.DEVICE_CAPTURE)) { + if (mHostApp.canUseDeviceCapture() && mDeployGateClient.isSupported(Compatibility.DEVICE_CAPTURE)) { // still nullable captureId = extras.getString(DeployGateEvent.EXTRA_CAPTURE_ID); } @@ -266,25 +266,25 @@ public void run() { */ private DeployGate( Context applicationContext, - String author, - DeployGateCallback callback, - CustomLogConfiguration customLogConfiguration, - HostApp hostApp + HostApp hostApp, + DeployGateSdkConfiguration sdkConfiguration ) { + // Don't hold sdkConfiguration to avoid memory leak + mApplicationContext = applicationContext; mDeployGateClient = new DeployGateClient(applicationContext, DEPLOYGATE_PACKAGE); mHostApp = hostApp; mHandler = new Handler(); mLogcatInstructionSerializer = mHostApp.canUseLogcat ? new LogcatInstructionSerializer(mHostApp.packageName) : ILogcatInstructionSerializer.NULL_INSTANCE; - mCustomLogInstructionSerializer = new CustomLogInstructionSerializer(mHostApp.packageName, customLogConfiguration); + mCustomLogInstructionSerializer = new CustomLogInstructionSerializer(mHostApp.packageName, sdkConfiguration.customLogConfiguration); mCallbacks = new HashSet<>(); mPendingEvents = new HashMap<>(); - mExpectedAuthor = author; + mExpectedAuthor = sdkConfiguration.appOwnerName; prepareBroadcastReceiver(); - if (callback != null) { - mCallbacks.add(callback); + if (sdkConfiguration.callback != null) { + mCallbacks.add(sdkConfiguration.callback); } mInitializedLatch = new CountDownLatch(1); @@ -362,6 +362,7 @@ private void requestServiceInit(final boolean isBoot) { args.putString(DeployGateEvent.EXTRA_EXPECTED_AUTHOR, mExpectedAuthor); args.putInt(DeployGateEvent.EXTRA_SDK_VERSION, mHostApp.sdkVersion); args.putString(DeployGateEvent.EXTRA_SDK_ARTIFACT_VERSION, mHostApp.sdkArtifactVersion); + args.putInt(DeployGateEvent.EXTRA_ACTIVE_FEATURE_FLAGS, mHostApp.activeFeatureFlags); try { mRemoteService.init(mRemoteCallback, mHostApp.packageName, args); } catch (RemoteException e) { @@ -424,6 +425,49 @@ static void clear() { sInstance = null; } + + /** + * Install DeployGate on your application instance. Call this method inside + * of your {@link Application#onCreate()}, in ContentProvider or AndroidX Startup Initializer only once. + * + * @param context Your application's Context. SDK will use {@code context.getApplicationContext} and don't hold this object reference. + * @param sdkConfiguration sdk configuration {@link DeployGateSdkConfiguration} + * + * @throws IllegalStateException + * if this called twice + * @since 4.7.0 + */ + + public static void install(Context context, DeployGateSdkConfiguration sdkConfiguration) { + if (sInstance != null) { + Log.w(TAG, "DeployGate.install was already called. Ignoring."); + return; + } + + Context application = context.getApplicationContext(); + + HostApp hostApp = new HostApp( + application, + sdkConfiguration + ); + + if (!hostApp.isSdkEnabled) { + return; + } + + if (sdkConfiguration.isCrashReportingEnabled) { + Thread.setDefaultUncaughtExceptionHandler(new DeployGateUncaughtExceptionHandler(Thread.getDefaultUncaughtExceptionHandler())); + } else { + Logger.d("DeployGateSDK crash reporting hasn't started"); + } + + sInstance = new DeployGate( + application, + hostApp, + sdkConfiguration + ); + } + /** * Install DeployGate on your application instance. Call this method inside * of your {@link Application#onCreate()} once. @@ -447,6 +491,7 @@ static void clear() { * @throws IllegalStateException * if this called twice * @since r1 + * @deprecated since 4.7.0. Use {@link DeployGate#install(Context, DeployGateSdkConfiguration)} instead. */ public static void install(Application app) { install(app, (String) null); @@ -471,6 +516,7 @@ public static void install(Application app) { * @throws IllegalStateException * if this called twice * @since r2 + * @deprecated since 4.7.0. Use {@link DeployGate#install(Context, DeployGateSdkConfiguration)} instead. */ public static void install( Application app, @@ -505,6 +551,7 @@ public static void install( * @throws IllegalStateException * if this called twice * @since r1 + * @deprecated since 4.7.0. Use {@link DeployGate#install(Context, DeployGateSdkConfiguration)} instead. */ public static void install( Application app, @@ -533,6 +580,7 @@ public static void install( * @throws IllegalStateException * if this called twice * @since r4.2 + * @deprecated since 4.7.0. Use {@link DeployGate#install(Context, DeployGateSdkConfiguration)} instead. */ public static void install( Application app, @@ -563,6 +611,7 @@ public static void install( * @throws IllegalStateException * if this called twice * @since r2 + * @deprecated since 4.7.0. Use {@link DeployGate#install(Context, DeployGateSdkConfiguration)} instead. */ public static void install( Application app, @@ -594,6 +643,7 @@ public static void install( * @throws IllegalStateException * if this called twice * @since r1 + * @deprecated since 4.7.0. Use {@link DeployGate#install(Context, DeployGateSdkConfiguration)} instead. */ public static void install( Application app, @@ -619,6 +669,7 @@ public static void install( * the release build, set this true. * * @since r2 + * @deprecated since 4.7.0. Use {@link DeployGate#install(Context, DeployGateSdkConfiguration)} instead. */ public static void install( Application app, @@ -647,6 +698,7 @@ public static void install( * set a configuration for custom logging * * @since 4.4.0 + * @deprecated since 4.7.0. Use {@link DeployGate#install(Context, DeployGateSdkConfiguration)} instead. */ public static void install( Application app, @@ -655,19 +707,19 @@ public static void install( boolean forceApplyOnReleaseBuild, CustomLogConfiguration customLogConfiguration ) { - if (sInstance != null) { - Log.w(TAG, "DeployGate.install was already called. Ignoring."); - return; - } + DeployGateSdkConfiguration.Builder builder = new DeployGateSdkConfiguration.Builder() + .setAppOwnerName(author) + .setCustomLogConfiguration(customLogConfiguration) + .setCallback(callback); - HostApp hostApp = new HostApp(app.getApplicationContext()); - - if (!forceApplyOnReleaseBuild && !hostApp.debuggable) { - return; + if (forceApplyOnReleaseBuild) { + builder.setEnabledOnNonDebuggableBuild(false); } - Thread.setDefaultUncaughtExceptionHandler(new DeployGateUncaughtExceptionHandler(Thread.getDefaultUncaughtExceptionHandler())); - sInstance = new DeployGate(app.getApplicationContext(), author, callback, customLogConfiguration, hostApp); + install( + app, + builder.build() + ); } /** diff --git a/sdk/src/main/java/com/deploygate/sdk/DeployGateSdkConfiguration.java b/sdk/src/main/java/com/deploygate/sdk/DeployGateSdkConfiguration.java new file mode 100644 index 0000000..4916691 --- /dev/null +++ b/sdk/src/main/java/com/deploygate/sdk/DeployGateSdkConfiguration.java @@ -0,0 +1,180 @@ +package com.deploygate.sdk; + +import com.deploygate.sdk.internal.annotations.Experimental; + +public final class DeployGateSdkConfiguration { + final CustomLogConfiguration customLogConfiguration; + + final boolean isDisabled; + final boolean isEnabledOnNonDebuggableBuild; + + final String appOwnerName; + + final boolean isCrashReportingEnabled; + + + final DeployGateCallback callback; + + final boolean isCaptureEnabled; + + private DeployGateSdkConfiguration( + ) { + this( + true, + new CustomLogConfiguration.Builder().build(), + false, + null, + false, + false, + null + ); + } + + private DeployGateSdkConfiguration( + Builder builder + ) { + this( + builder.isDisabled, + builder.customLogConfiguration, + builder.isEnabledOnNonDebuggableBuild, + builder.appOwnerName, + builder.isCrashReportingEnabled, + builder.isCaptureEnabled, + builder.callback + ); + } + + private DeployGateSdkConfiguration( + boolean isDisabled, + CustomLogConfiguration customLogConfiguration, + boolean isEnabledOnNonDebuggableBuild, + String appOwnerName, + boolean isCrashReportingEnabled, + boolean isCaptureEnabled, + DeployGateCallback callback + ) { + this.customLogConfiguration = customLogConfiguration; + this.isDisabled = isDisabled; + this.isEnabledOnNonDebuggableBuild = isEnabledOnNonDebuggableBuild; + this.appOwnerName = appOwnerName; + this.isCrashReportingEnabled = isCrashReportingEnabled; + this.isCaptureEnabled = isCaptureEnabled; + this.callback = callback; + } + + public static final class Builder { + private CustomLogConfiguration customLogConfiguration = new CustomLogConfiguration.Builder().build(); + + private boolean isDisabled = false; + private boolean isEnabledOnNonDebuggableBuild = false; + + private String appOwnerName = null; + + private boolean isCrashReportingEnabled = true; + + private boolean isCaptureEnabled = true; + + private DeployGateCallback callback = null; + + public Builder() { + } + + /** + * Set a custom log configuration + * + * @param customLogConfiguration + * a configuration object for custom logs like {@link DeployGate#logDebug(String)} + * @see CustomLogConfiguration + * @return self + */ + @Experimental + public Builder setCustomLogConfiguration(CustomLogConfiguration customLogConfiguration) { + this.customLogConfiguration = customLogConfiguration; + return this; + } + + /** + * Ensure the authority of this app to prevent casual redistribution via DeployGate. + * + * @param appOwnerName + * A name of this app's owner on DeployGate. + * @return self + */ + public Builder setAppOwnerName(String appOwnerName) { + this.appOwnerName = appOwnerName; + return this; + } + + /** + * Disable all SDK features. + * + * @param disabled + * Specify true if you would like to disable SDK completely. Defaults to false. + * @return self + */ + public Builder setDisabled(boolean disabled) { + isDisabled = disabled; + return this; + } + + /** + * Enable SDK even on non-debuggable builds. + * + * @param enabledOnNonDebuggableBuild + * Specify true if you would like to enable SDK on non-debuggable builds. Defaults to false. + * @return self + */ + public Builder setEnabledOnNonDebuggableBuild(boolean enabledOnNonDebuggableBuild) { + isEnabledOnNonDebuggableBuild = enabledOnNonDebuggableBuild; + return this; + } + + /** + * Enable DeployGate Capture feature. + * + * @param captureEnabled + * Specify true if you would like to use DeployGate Capture feature if available. Otherwise, false. Defaults to true. + * @return self + */ + @Experimental + public Builder setCaptureEnabled(boolean captureEnabled) { + isCaptureEnabled = captureEnabled; + return this; + } + + /** + * Enable DeployGate Crash reporting feature. + * + * @param crashReportingEnabled + * Specify true if you would like to use DeployGate Crash reporting feature. Otherwise, false. Defaults to true. + * @return self + */ + public Builder setCrashReportingEnabled(boolean crashReportingEnabled) { + isCrashReportingEnabled = crashReportingEnabled; + return this; + } + + /** + * Set a callback of the communication events between DeployGate client app and this app. + * + * @param callback + * Set an instance of callback. The reference won't be released. Please use {@link DeployGate#registerCallback(DeployGateCallback, boolean)} for memory sensitive works. + * @return self + */ + public Builder setCallback(DeployGateCallback callback) { + this.callback = callback; + return this; + } + + /** + * @return a new sdk configuration. + */ + public DeployGateSdkConfiguration build() { + if (isDisabled) { + return new DeployGateSdkConfiguration(); + } else { + return new DeployGateSdkConfiguration(this); + } + } + } +} diff --git a/sdk/src/main/java/com/deploygate/sdk/HostApp.java b/sdk/src/main/java/com/deploygate/sdk/HostApp.java index 42dd6d1..66c38e4 100644 --- a/sdk/src/main/java/com/deploygate/sdk/HostApp.java +++ b/sdk/src/main/java/com/deploygate/sdk/HostApp.java @@ -8,15 +8,45 @@ import com.deploygate.sdk.internal.Logger; +/** + * Shadow of an application that embeds this SDK. + */ class HostApp { public final String packageName; + + /** + * true if SDK is enabled. Nothing should work if this value is false. + */ + public final boolean isSdkEnabled; + + /** + * true if this app can read LogCat. + */ public final boolean canUseLogcat; + + /** + * true if this app is absolutely debuggable. + */ public final boolean debuggable; + + /** + * SDK's model version + */ public final int sdkVersion; + + /** + * SDK's artifact version + */ public final String sdkArtifactVersion; + /** + * Bit flag representation of active features + */ + public final int activeFeatureFlags; + HostApp( - Context context + Context context, + DeployGateSdkConfiguration sdkConfiguration ) { this.packageName = context.getPackageName(); PackageManager pm = context.getPackageManager(); @@ -29,11 +59,13 @@ class HostApp { Logger.w(e, "unexpected code"); } - if (info == null) { + if (info == null || sdkConfiguration.isDisabled) { + this.isSdkEnabled = false; this.debuggable = false; this.canUseLogcat = false; this.sdkVersion = 0; this.sdkArtifactVersion = null; + this.activeFeatureFlags = 0; return; } @@ -47,5 +79,18 @@ class HostApp { this.sdkVersion = info.metaData.getInt("com.deploygate.sdk.version", 0); this.sdkArtifactVersion = info.metaData.getString("com.deploygate.sdk.artifact_version"); + this.isSdkEnabled = debuggable || sdkConfiguration.isEnabledOnNonDebuggableBuild; + + int supportedFeatureFlags = info.metaData.getInt("com.deploygate.sdk.feature_flags", 0); + + if (!sdkConfiguration.isCaptureEnabled) { + supportedFeatureFlags ^= Compatibility.DEVICE_CAPTURE.bitMask; + } + + this.activeFeatureFlags = supportedFeatureFlags; + } + + final boolean canUseDeviceCapture() { + return (activeFeatureFlags & Compatibility.DEVICE_CAPTURE.bitMask) == BuildConfig.DEVICE_CAPTURE; } } diff --git a/sdk/src/main/java/com/deploygate/service/DeployGateEvent.java b/sdk/src/main/java/com/deploygate/service/DeployGateEvent.java index f45f95f..8b12a57 100644 --- a/sdk/src/main/java/com/deploygate/service/DeployGateEvent.java +++ b/sdk/src/main/java/com/deploygate/service/DeployGateEvent.java @@ -41,6 +41,13 @@ public interface DeployGateEvent { * @since 4.7.0 */ public static final String EXTRA_SDK_ARTIFACT_VERSION = "e.sdk-artifact-version"; + + /** + * Only active feature flags on this host app. + * + * @since 4.7.0 + */ + public static final String EXTRA_ACTIVE_FEATURE_FLAGS = "e.active-feature-flags"; public static final String EXTRA_IS_MANAGED = "isManaged"; public static final String EXTRA_IS_AUTHORIZED = "isAuthorized"; public static final String EXTRA_LOGIN_USERNAME = "loginUsername"; diff --git a/sdk/src/test/java/com/deploygate/sdk/HostAppTest.java b/sdk/src/test/java/com/deploygate/sdk/HostAppTest.java index 1a6a39b..192f125 100644 --- a/sdk/src/test/java/com/deploygate/sdk/HostAppTest.java +++ b/sdk/src/test/java/com/deploygate/sdk/HostAppTest.java @@ -26,22 +26,65 @@ public void setUp() { @Test public void default_properties() { - HostApp app = new HostApp(context); + HostApp app = new HostApp( + context, + new DeployGateSdkConfiguration.Builder().build() + ); Truth.assertThat(app.debuggable).isTrue(); Truth.assertThat(app.canUseLogcat).isTrue(); Truth.assertThat(app.packageName).isEqualTo("com.deploygate.sdk.test"); Truth.assertThat(app.sdkVersion).isEqualTo(4); Truth.assertThat(app.sdkArtifactVersion).isEqualTo("4.6.1"); + Truth.assertThat(app.activeFeatureFlags).isEqualTo(31); + Truth.assertThat(app.canUseDeviceCapture()).isTrue(); } @Test @Config(sdk = 16) public void canUseLogcat_is_true_if_sdk_is_equal_to_jb() { - HostApp app = new HostApp(context); + HostApp app = new HostApp( + context, + new DeployGateSdkConfiguration.Builder().build() + ); Truth.assertThat(app.canUseLogcat).isTrue(); } // sdk 15 or lower is not available for robolectric... + + @Test + public void disabled_DeployGateSdkConfiguration_initialize_host_app_as_disabled() { + HostApp app = new HostApp( + context, + new DeployGateSdkConfiguration.Builder().setDisabled(true).build() + ); + + Truth.assertThat(app.debuggable).isFalse(); + Truth.assertThat(app.canUseLogcat).isFalse(); + Truth.assertThat(app.packageName).isEqualTo("com.deploygate.sdk.test"); + Truth.assertThat(app.sdkVersion).isEqualTo(0); + Truth.assertThat(app.sdkArtifactVersion).isNull(); + Truth.assertThat(app.activeFeatureFlags).isEqualTo(0); + Truth.assertThat(app.canUseDeviceCapture()).isFalse(); + } + + @Test + public void can_read_DeployGateSdkConfiguration_setCaptureEnabled() { + HostApp app1 = new HostApp( + context, + new DeployGateSdkConfiguration.Builder().setCaptureEnabled(true).build() + ); + + Truth.assertThat(app1.canUseDeviceCapture()).isTrue(); + Truth.assertThat(app1.activeFeatureFlags).isEqualTo(31); + + HostApp app2 = new HostApp( + context, + new DeployGateSdkConfiguration.Builder().setCaptureEnabled(false).build() + ); + + Truth.assertThat(app2.canUseDeviceCapture()).isFalse(); + Truth.assertThat(app2.activeFeatureFlags).isEqualTo(15); + } } From d0017ed5e452e733c971770ca408062ab4884e62 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Thu, 14 Mar 2024 20:58:27 +0900 Subject: [PATCH 2/4] feat: Make HostApp state *disabled* if an app is a non-debuggable build --- .../main/java/com/deploygate/sdk/HostApp.java | 17 ++++++++--------- .../java/com/deploygate/sdk/HostAppTest.java | 2 -- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/sdk/src/main/java/com/deploygate/sdk/HostApp.java b/sdk/src/main/java/com/deploygate/sdk/HostApp.java index 66c38e4..bc734ce 100644 --- a/sdk/src/main/java/com/deploygate/sdk/HostApp.java +++ b/sdk/src/main/java/com/deploygate/sdk/HostApp.java @@ -24,11 +24,6 @@ class HostApp { */ public final boolean canUseLogcat; - /** - * true if this app is absolutely debuggable. - */ - public final boolean debuggable; - /** * SDK's model version */ @@ -59,9 +54,14 @@ class HostApp { Logger.w(e, "unexpected code"); } - if (info == null || sdkConfiguration.isDisabled) { + boolean shouldDisable = + info == null || info.metaData == null || sdkConfiguration.isDisabled || + !sdkConfiguration.isEnabledOnNonDebuggableBuild && (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != ApplicationInfo.FLAG_DEBUGGABLE; + + if (shouldDisable) { + Logger.d("DeployGate SDK is unavailable on this app"); + this.isSdkEnabled = false; - this.debuggable = false; this.canUseLogcat = false; this.sdkVersion = 0; this.sdkArtifactVersion = null; @@ -69,7 +69,7 @@ class HostApp { return; } - this.debuggable = (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + this.isSdkEnabled = true; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { this.canUseLogcat = true; @@ -79,7 +79,6 @@ class HostApp { this.sdkVersion = info.metaData.getInt("com.deploygate.sdk.version", 0); this.sdkArtifactVersion = info.metaData.getString("com.deploygate.sdk.artifact_version"); - this.isSdkEnabled = debuggable || sdkConfiguration.isEnabledOnNonDebuggableBuild; int supportedFeatureFlags = info.metaData.getInt("com.deploygate.sdk.feature_flags", 0); diff --git a/sdk/src/test/java/com/deploygate/sdk/HostAppTest.java b/sdk/src/test/java/com/deploygate/sdk/HostAppTest.java index 192f125..182a641 100644 --- a/sdk/src/test/java/com/deploygate/sdk/HostAppTest.java +++ b/sdk/src/test/java/com/deploygate/sdk/HostAppTest.java @@ -31,7 +31,6 @@ public void default_properties() { new DeployGateSdkConfiguration.Builder().build() ); - Truth.assertThat(app.debuggable).isTrue(); Truth.assertThat(app.canUseLogcat).isTrue(); Truth.assertThat(app.packageName).isEqualTo("com.deploygate.sdk.test"); Truth.assertThat(app.sdkVersion).isEqualTo(4); @@ -60,7 +59,6 @@ public void disabled_DeployGateSdkConfiguration_initialize_host_app_as_disabled( new DeployGateSdkConfiguration.Builder().setDisabled(true).build() ); - Truth.assertThat(app.debuggable).isFalse(); Truth.assertThat(app.canUseLogcat).isFalse(); Truth.assertThat(app.packageName).isEqualTo("com.deploygate.sdk.test"); Truth.assertThat(app.sdkVersion).isEqualTo(0); From 61ff4b6cb238af504b9f945b67b863bb5be62370 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Fri, 15 Mar 2024 13:37:39 +0900 Subject: [PATCH 3/4] fix: forceApplyOnReleaseBuild has been renamed to setEnabledOnNonDebuggableBuild --- .../main/java/com/deploygate/sdk/DeployGate.java | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/sdk/src/main/java/com/deploygate/sdk/DeployGate.java b/sdk/src/main/java/com/deploygate/sdk/DeployGate.java index b017f92..a9e60a7 100644 --- a/sdk/src/main/java/com/deploygate/sdk/DeployGate.java +++ b/sdk/src/main/java/com/deploygate/sdk/DeployGate.java @@ -707,18 +707,14 @@ public static void install( boolean forceApplyOnReleaseBuild, CustomLogConfiguration customLogConfiguration ) { - DeployGateSdkConfiguration.Builder builder = new DeployGateSdkConfiguration.Builder() - .setAppOwnerName(author) - .setCustomLogConfiguration(customLogConfiguration) - .setCallback(callback); - - if (forceApplyOnReleaseBuild) { - builder.setEnabledOnNonDebuggableBuild(false); - } - install( app, - builder.build() + new DeployGateSdkConfiguration.Builder() + .setAppOwnerName(author) + .setCustomLogConfiguration(customLogConfiguration) + .setEnabledOnNonDebuggableBuild(forceApplyOnReleaseBuild) + .setCallback(callback) + .build() ); } From 504541bc07d0140737b514bd408c55872fff1304 Mon Sep 17 00:00:00 2001 From: Jumpei Matsuda Date: Fri, 15 Mar 2024 13:48:23 +0900 Subject: [PATCH 4/4] refactor: DRY for a disabled configuration --- .../sdk/DeployGateSdkConfiguration.java | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/sdk/src/main/java/com/deploygate/sdk/DeployGateSdkConfiguration.java b/sdk/src/main/java/com/deploygate/sdk/DeployGateSdkConfiguration.java index 4916691..3250aed 100644 --- a/sdk/src/main/java/com/deploygate/sdk/DeployGateSdkConfiguration.java +++ b/sdk/src/main/java/com/deploygate/sdk/DeployGateSdkConfiguration.java @@ -17,19 +17,6 @@ public final class DeployGateSdkConfiguration { final boolean isCaptureEnabled; - private DeployGateSdkConfiguration( - ) { - this( - true, - new CustomLogConfiguration.Builder().build(), - false, - null, - false, - false, - null - ); - } - private DeployGateSdkConfiguration( Builder builder ) { @@ -171,7 +158,8 @@ public Builder setCallback(DeployGateCallback callback) { */ public DeployGateSdkConfiguration build() { if (isDisabled) { - return new DeployGateSdkConfiguration(); + // Create a new builder instance to release all references just in case. + return new DeployGateSdkConfiguration(new Builder().setDisabled(true)); } else { return new DeployGateSdkConfiguration(this); }