From 07b0394cbf02db7b8e3f86d883007ec9a977fab8 Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Tue, 12 Nov 2024 09:54:38 +0300 Subject: [PATCH 001/147] feat: server config for disabling/enabling unhandled crash reporting --- CHANGELOG.md | 3 +++ .../android/sdk/ConnectionProcessorTests.java | 4 +++ .../android/sdk/ConfigurationProvider.java | 2 ++ .../android/sdk/ModuleConfiguration.java | 25 +++++++++++++++++-- .../ly/count/android/sdk/ModuleCrash.java | 4 ++- 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 561960946..f9e598b70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## XX.XX.XX +* Added a new server configuration to manage uncaught crash reporting. + ## 24.7.5 * ! Minor breaking change ! All active views will now automatically stop when consent for "views" is revoked. diff --git a/sdk/src/androidTest/java/ly/count/android/sdk/ConnectionProcessorTests.java b/sdk/src/androidTest/java/ly/count/android/sdk/ConnectionProcessorTests.java index f0ae4d761..b3a70f55f 100644 --- a/sdk/src/androidTest/java/ly/count/android/sdk/ConnectionProcessorTests.java +++ b/sdk/src/androidTest/java/ly/count/android/sdk/ConnectionProcessorTests.java @@ -77,6 +77,10 @@ public void setUp() { @Override public boolean getTrackingEnabled() { return true; } + + @Override public boolean getCrashReportingEnabled() { + return true; + } }; Countly.sharedInstance().setLoggingEnabled(true); diff --git a/sdk/src/main/java/ly/count/android/sdk/ConfigurationProvider.java b/sdk/src/main/java/ly/count/android/sdk/ConfigurationProvider.java index b0134fec9..f6d44882d 100644 --- a/sdk/src/main/java/ly/count/android/sdk/ConfigurationProvider.java +++ b/sdk/src/main/java/ly/count/android/sdk/ConfigurationProvider.java @@ -4,4 +4,6 @@ interface ConfigurationProvider { boolean getNetworkingEnabled(); boolean getTrackingEnabled(); + + boolean getCrashReportingEnabled(); } diff --git a/sdk/src/main/java/ly/count/android/sdk/ModuleConfiguration.java b/sdk/src/main/java/ly/count/android/sdk/ModuleConfiguration.java index 331d7d51c..9623eb00f 100644 --- a/sdk/src/main/java/ly/count/android/sdk/ModuleConfiguration.java +++ b/sdk/src/main/java/ly/count/android/sdk/ModuleConfiguration.java @@ -15,6 +15,7 @@ class ModuleConfiguration extends ModuleBase implements ConfigurationProvider { //config keys final static String keyTracking = "tracking"; final static String keyNetworking = "networking"; + final static String keyCrashReporting = "crashes"; //request keys final static String keyRTimestamp = "t"; @@ -23,9 +24,11 @@ class ModuleConfiguration extends ModuleBase implements ConfigurationProvider { final static boolean defaultVTracking = true; final static boolean defaultVNetworking = true; + final static boolean defaultVCrashReporting = true; boolean currentVTracking = true; boolean currentVNetworking = true; + boolean currentVCrashReporting = true; boolean configurationFetched = false; ModuleConfiguration(@NonNull Countly cly, @NonNull CountlyConfig config) { @@ -92,6 +95,7 @@ void updateConfigVariables() { //set all to defaults currentVNetworking = defaultVNetworking; currentVTracking = defaultVTracking; + currentVCrashReporting = defaultVCrashReporting; if (latestRetrievedConfiguration == null) { //no config, don't continue @@ -103,7 +107,7 @@ void updateConfigVariables() { try { currentVNetworking = latestRetrievedConfiguration.getBoolean(keyNetworking); } catch (JSONException e) { - L.w("[ModuleConfiguration] updateConfigs, failed to load 'networking', " + e); + L.w("[ModuleConfiguration] updateConfigVariables, failed to load 'networking', " + e); } } @@ -112,7 +116,16 @@ void updateConfigVariables() { try { currentVTracking = latestRetrievedConfiguration.getBoolean(keyTracking); } catch (JSONException e) { - L.w("[ModuleConfiguration] updateConfigs, failed to load 'tracking', " + e); + L.w("[ModuleConfiguration] updateConfigVariables, failed to load 'tracking', " + e); + } + } + + //tracking + if (latestRetrievedConfiguration.has(keyCrashReporting)) { + try { + currentVCrashReporting = latestRetrievedConfiguration.getBoolean(keyCrashReporting); + } catch (JSONException e) { + L.w("[ModuleConfiguration] updateConfigVariables, failed to load 'crash_reporting', " + e); } } } @@ -231,4 +244,12 @@ public boolean getTrackingEnabled() { } return currentVTracking; } + + @Override + public boolean getCrashReportingEnabled() { + if (!serverConfigEnabled) { + return defaultVCrashReporting; + } + return currentVCrashReporting; + } } diff --git a/sdk/src/main/java/ly/count/android/sdk/ModuleCrash.java b/sdk/src/main/java/ly/count/android/sdk/ModuleCrash.java index 8985e33fa..8d7d62240 100644 --- a/sdk/src/main/java/ly/count/android/sdk/ModuleCrash.java +++ b/sdk/src/main/java/ly/count/android/sdk/ModuleCrash.java @@ -338,8 +338,10 @@ Countly addBreadcrumbInternal(@Nullable String breadcrumb) { @Override void initFinished(@NonNull CountlyConfig config) { //enable unhandled crash reporting - if (config.crashes.enableUnhandledCrashReporting) { + if (config.crashes.enableUnhandledCrashReporting && (config.configProvider == null || config.configProvider.getCrashReportingEnabled())) { enableCrashReporting(); + } else if (config.crashes.enableUnhandledCrashReporting) { + L.w("[ModuleCrash] initFinished, Crash reporting is enabled in the configuration, but it is not enabled in the config provider"); } //check for previous native crash dumps From 5255300afaec44b06f26ed4a9d07a963ba704c23 Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Tue, 12 Nov 2024 10:03:23 +0300 Subject: [PATCH 002/147] fix: draft test --- .../android/sdk/ModuleConfigurationTests.java | 51 ++++++++++++++++--- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/sdk/src/androidTest/java/ly/count/android/sdk/ModuleConfigurationTests.java b/sdk/src/androidTest/java/ly/count/android/sdk/ModuleConfigurationTests.java index 4b74e725e..c4de7e0f0 100644 --- a/sdk/src/androidTest/java/ly/count/android/sdk/ModuleConfigurationTests.java +++ b/sdk/src/androidTest/java/ly/count/android/sdk/ModuleConfigurationTests.java @@ -64,7 +64,7 @@ public void init_enabled_storageEmpty() { */ @Test public void init_enabled_storageAllowing() throws JSONException { - countlyStore.setServerConfig(getStorageString(true, true)); + countlyStore.setServerConfig(getStorageString(true, true, true)); CountlyConfig config = TestUtils.createConfigurationConfig(true, null); Countly countly = (new Countly()).init(config); @@ -82,7 +82,7 @@ public void init_enabled_storageAllowing() throws JSONException { */ @Test public void init_enabled_storageForbidding() throws JSONException { - countlyStore.setServerConfig(getStorageString(false, false)); + countlyStore.setServerConfig(getStorageString(false, false, false)); CountlyConfig config = TestUtils.createConfigurationConfig(true, null); Countly countly = (new Countly()).init(config); @@ -90,6 +90,7 @@ public void init_enabled_storageForbidding() throws JSONException { Assert.assertNotNull(countlyStore.getServerConfig()); Assert.assertFalse(countly.moduleConfiguration.getNetworkingEnabled()); Assert.assertFalse(countly.moduleConfiguration.getTrackingEnabled()); + Assert.assertFalse(countly.moduleConfiguration.getCrashReportingEnabled()); } /** @@ -101,7 +102,7 @@ public void init_enabled_storageForbidding() throws JSONException { */ @Test public void init_disabled_storageAllowing() throws JSONException { - countlyStore.setServerConfig(getStorageString(true, true)); + countlyStore.setServerConfig(getStorageString(true, true, true)); CountlyConfig config = TestUtils.createConfigurationConfig(false, null); Countly countly = Countly.sharedInstance().init(config); @@ -119,7 +120,7 @@ public void init_disabled_storageAllowing() throws JSONException { */ @Test public void init_disabled_storageForbidding() throws JSONException { - countlyStore.setServerConfig(getStorageString(false, false)); + countlyStore.setServerConfig(getStorageString(false, false, false)); CountlyConfig config = TestUtils.createConfigurationConfig(false, null); Countly countly = (new Countly()).init(config); @@ -165,13 +166,14 @@ public void validatingTrackingConfig() throws JSONException { Assert.assertEquals("", countlyStore.getRequestQueueRaw()); Assert.assertEquals(0, countlyStore.getEvents().length); - countlyStore.setServerConfig(getStorageString(false, false)); + countlyStore.setServerConfig(getStorageString(false, false, false)); CountlyConfig config = TestUtils.createConfigurationConfig(true, null); Countly countly = (new Countly()).init(config); Assert.assertFalse(countly.moduleConfiguration.getNetworkingEnabled()); Assert.assertFalse(countly.moduleConfiguration.getTrackingEnabled()); + Assert.assertFalse(countly.moduleConfiguration.getCrashReportingEnabled()); //try events countly.events().recordEvent("d"); @@ -189,6 +191,41 @@ public void validatingTrackingConfig() throws JSONException { Assert.assertEquals(0, countlyStore.getEvents().length); } + /** + * Only disable crashes to try out unhandled crash reporting + * Make sure that call is called but no request is added to the RQ + */ + @Test + public void validatingCrashReportingConfig() throws JSONException { + //nothing in queues initially + Assert.assertEquals("", countlyStore.getRequestQueueRaw()); + Assert.assertEquals(0, countlyStore.getEvents().length); + + countlyStore.setServerConfig(getStorageString(true, true, false)); + + CountlyConfig config = TestUtils.createConfigurationConfig(true, null); + Countly countly = (new Countly()).init(config); + + Assert.assertTrue(countly.moduleConfiguration.getNetworkingEnabled()); + Assert.assertTrue(countly.moduleConfiguration.getTrackingEnabled()); + Assert.assertFalse(countly.moduleConfiguration.getCrashReportingEnabled()); + + //try events + countly.events().recordEvent("d"); + countly.events().recordEvent("1"); + + //try a non event recording + countly.crashes().recordHandledException(new Exception()); + + //try a direct request + countly.requestQueue().addDirectRequest(new HashMap<>()); + + countly.requestQueue().attemptToSendStoredRequests(); + + Assert.assertEquals("", countlyStore.getRequestQueueRaw()); + Assert.assertEquals(2, countlyStore.getEvents().length); + } + /** * Making sure that bad config responses are rejected */ @@ -239,6 +276,7 @@ Countly initAndValidateConfigParsingResult(String targetResponse, boolean respon void assertConfigDefault(Countly countly) { Assert.assertTrue(countly.moduleConfiguration.getNetworkingEnabled()); Assert.assertTrue(countly.moduleConfiguration.getTrackingEnabled()); + Assert.assertTrue(countly.moduleConfiguration.getCrashReportingEnabled()); } ImmediateRequestGenerator createIRGForSpecificResponse(final String targetResponse) { @@ -267,12 +305,13 @@ ImmediateRequestGenerator createIRGForSpecificResponse(final String targetRespon } //creates the stringified storage object with all the required properties - String getStorageString(boolean tracking, boolean networking) throws JSONException { + String getStorageString(boolean tracking, boolean networking, boolean crashes) throws JSONException { JSONObject jsonObject = new JSONObject(); JSONObject jsonObjectConfig = new JSONObject(); jsonObjectConfig.put("tracking", tracking); jsonObjectConfig.put("networking", networking); + jsonObjectConfig.put("crashes", crashes); jsonObject.put("v", 1); jsonObject.put("t", 1_681_808_287_464L); From 7ae15210ef313b7ceabaef0c021cc96f31971a45 Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Tue, 12 Nov 2024 16:21:29 +0300 Subject: [PATCH 003/147] feat: test for crash reporting server conf --- .../android/sdk/ModuleConfigurationTests.java | 51 ++++++++++++++----- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/sdk/src/androidTest/java/ly/count/android/sdk/ModuleConfigurationTests.java b/sdk/src/androidTest/java/ly/count/android/sdk/ModuleConfigurationTests.java index c4de7e0f0..f74a61434 100644 --- a/sdk/src/androidTest/java/ly/count/android/sdk/ModuleConfigurationTests.java +++ b/sdk/src/androidTest/java/ly/count/android/sdk/ModuleConfigurationTests.java @@ -2,6 +2,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import java.util.HashMap; +import java.util.concurrent.atomic.AtomicInteger; import org.json.JSONException; import org.json.JSONObject; import org.junit.After; @@ -10,20 +11,21 @@ import org.junit.Test; import org.junit.runner.RunWith; -import static org.mockito.Mockito.mock; - @RunWith(AndroidJUnit4.class) public class ModuleConfigurationTests { CountlyStore countlyStore; @Before public void setUp() { - countlyStore = new CountlyStore(TestUtils.getContext(), mock(ModuleLog.class)); + countlyStore = TestUtils.getCountyStore(); countlyStore.clear(); + Countly.sharedInstance().halt(); } @After public void tearDown() { + TestUtils.getCountyStore().clear(); + Countly.sharedInstance().halt(); } /** @@ -194,25 +196,46 @@ public void validatingTrackingConfig() throws JSONException { /** * Only disable crashes to try out unhandled crash reporting * Make sure that call is called but no request is added to the RQ + * Call count to the unhandled crash reporting call should be 1 because countly SDK won't call and override the default handler + * And validate that no crash request is generated */ @Test public void validatingCrashReportingConfig() throws JSONException { - //nothing in queues initially - Assert.assertEquals("", countlyStore.getRequestQueueRaw()); - Assert.assertEquals(0, countlyStore.getEvents().length); - - countlyStore.setServerConfig(getStorageString(true, true, false)); - - CountlyConfig config = TestUtils.createConfigurationConfig(true, null); - Countly countly = (new Countly()).init(config); + AtomicInteger callCount = new AtomicInteger(0); + RuntimeException unhandledException = new RuntimeException("Simulated unhandled exception"); + // Create a new thread to simulate unhandled exception + Thread threadThrows = new Thread(() -> { + // This will throw an unhandled exception in this thread + throw unhandledException; + }); + + Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { + Assert.assertEquals(unhandledException, throwable); + Assert.assertEquals(threadThrows, thread); + callCount.incrementAndGet(); + }); + + TestUtils.getCountyStore().setServerConfig(getStorageString(true, true, false)); + CountlyConfig config = TestUtils.createBaseConfig(); + config.enableServerConfiguration().setEventQueueSizeToSend(2); + config.crashes.enableCrashReporting(); // this call will enable unhandled crash reporting + Countly countly = new Countly().init(config); Assert.assertTrue(countly.moduleConfiguration.getNetworkingEnabled()); Assert.assertTrue(countly.moduleConfiguration.getTrackingEnabled()); Assert.assertFalse(countly.moduleConfiguration.getCrashReportingEnabled()); + // Start the thread and wait for it to terminate + threadThrows.start(); + try { + threadThrows.join(); // Wait for thread to finish + } catch (InterruptedException ignored) { + } + //try events countly.events().recordEvent("d"); countly.events().recordEvent("1"); + Assert.assertEquals(1, callCount.get()); //try a non event recording countly.crashes().recordHandledException(new Exception()); @@ -222,8 +245,10 @@ public void validatingCrashReportingConfig() throws JSONException { countly.requestQueue().attemptToSendStoredRequests(); - Assert.assertEquals("", countlyStore.getRequestQueueRaw()); - Assert.assertEquals(2, countlyStore.getEvents().length); + // There are two requests in total, but they are not containing unhandled exception + Assert.assertEquals(2, TestUtils.getCurrentRQ("Simulated unhandled exception").length); + Assert.assertNull(TestUtils.getCurrentRQ("Simulated unhandled exception")[0]); + Assert.assertNull(TestUtils.getCurrentRQ("Simulated unhandled exception")[1]); } /** From 5c84344d823b50d2bf2e78230d0df9c26bb4de91 Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Sat, 16 Nov 2024 15:36:42 +0300 Subject: [PATCH 004/147] fix: global content callback --- CHANGELOG.md | 1 + sdk/src/main/java/ly/count/android/sdk/ModuleContent.java | 4 +++- .../main/java/ly/count/android/sdk/TransparentActivity.java | 5 +++-- .../java/ly/count/android/sdk/TransparentActivityConfig.java | 2 -- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eaa44fff..6d7e79883 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## XX.XX.XX * Mitigated an issue where visibility could have been wrongly assigned if a view was closed while going to background. (Experimental!) +* Fixed a bug where passing the global content callback was not possible. ## 24.7.5 * ! Minor breaking change ! All active views will now automatically stop when consent for "views" is revoked. diff --git a/sdk/src/main/java/ly/count/android/sdk/ModuleContent.java b/sdk/src/main/java/ly/count/android/sdk/ModuleContent.java index ffbf7c673..8e0f49567 100644 --- a/sdk/src/main/java/ly/count/android/sdk/ModuleContent.java +++ b/sdk/src/main/java/ly/count/android/sdk/ModuleContent.java @@ -162,7 +162,9 @@ private TransparentActivityConfig extractOrientationPlacements(@NonNull JSONObje TransparentActivityConfig config = new TransparentActivityConfig((int) Math.ceil(x * density), (int) Math.ceil(y * density), (int) Math.ceil(w * density), (int) Math.ceil(h * density)); config.url = content; - config.globalContentCallback = globalContentCallback; + // TODO, passing callback with an intent is impossible, need to find a way to pass it + // Currently, the callback is set as a static variable in TransparentActivity + TransparentActivity.globalContentCallback = globalContentCallback; return config; } diff --git a/sdk/src/main/java/ly/count/android/sdk/TransparentActivity.java b/sdk/src/main/java/ly/count/android/sdk/TransparentActivity.java index 4dcb87591..6e1ea42ba 100644 --- a/sdk/src/main/java/ly/count/android/sdk/TransparentActivity.java +++ b/sdk/src/main/java/ly/count/android/sdk/TransparentActivity.java @@ -35,6 +35,7 @@ public class TransparentActivity extends Activity { TransparentActivityConfig configPortrait = null; WebView webView; RelativeLayout relativeLayout; + static ContentCallback globalContentCallback; @Override protected void onCreate(Bundle savedInstanceState) { @@ -211,8 +212,8 @@ private boolean contentUrlAction(String url, TransparentActivityConfig config, W } if (query.containsKey("close") && Objects.equals(query.get("close"), "1")) { - if (config.globalContentCallback != null) { // TODO: verify this later - config.globalContentCallback.onContentCallback(ContentStatus.CLOSED, query); + if (globalContentCallback != null) { // TODO: verify this later + globalContentCallback.onContentCallback(ContentStatus.CLOSED, query); } ModuleContent.waitForDelay = 2; // this is indicating that we will wait 1 min after closing the content and before fetching the next one finish(); diff --git a/sdk/src/main/java/ly/count/android/sdk/TransparentActivityConfig.java b/sdk/src/main/java/ly/count/android/sdk/TransparentActivityConfig.java index cba8e52b4..466416e48 100644 --- a/sdk/src/main/java/ly/count/android/sdk/TransparentActivityConfig.java +++ b/sdk/src/main/java/ly/count/android/sdk/TransparentActivityConfig.java @@ -11,7 +11,6 @@ class TransparentActivityConfig implements Serializable { Integer height; String url; List listeners; - ContentCallback globalContentCallback; TransparentActivityConfig(Integer x, Integer y, Integer width, Integer height) { this.x = x; @@ -19,6 +18,5 @@ class TransparentActivityConfig implements Serializable { this.width = width; this.height = height; this.listeners = new ArrayList<>(); - this.globalContentCallback = null; } } \ No newline at end of file From 2d265e3d86cab3316cb708f1a31474c26234d04b Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Mon, 18 Nov 2024 15:11:32 +0300 Subject: [PATCH 005/147] feat: added support for language to contents1 --- CHANGELOG.md | 2 ++ sdk/src/main/java/ly/count/android/sdk/ConnectionQueue.java | 4 ++-- sdk/src/main/java/ly/count/android/sdk/ModuleContent.java | 5 ++++- .../main/java/ly/count/android/sdk/RequestQueueProvider.java | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eaa44fff..f65bf368b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ ## XX.XX.XX +* Added language support for the contents. + * Mitigated an issue where visibility could have been wrongly assigned if a view was closed while going to background. (Experimental!) ## 24.7.5 diff --git a/sdk/src/main/java/ly/count/android/sdk/ConnectionQueue.java b/sdk/src/main/java/ly/count/android/sdk/ConnectionQueue.java index 3511df032..ba466b26e 100644 --- a/sdk/src/main/java/ly/count/android/sdk/ConnectionQueue.java +++ b/sdk/src/main/java/ly/count/android/sdk/ConnectionQueue.java @@ -823,7 +823,7 @@ public String prepareHealthCheckRequest(String preparedMetrics) { return prepareCommonRequestData() + "&metrics=" + preparedMetrics; } - public String prepareFetchContents(int portraitWidth, int portraitHeight, int landscapeWidth, int landscapeHeight, String[] categories) { + public String prepareFetchContents(int portraitWidth, int portraitHeight, int landscapeWidth, int landscapeHeight, String[] categories, String language) { JSONObject json = new JSONObject(); try { @@ -841,7 +841,7 @@ public String prepareFetchContents(int portraitWidth, int portraitHeight, int la L.e("Error while preparing fetch contents request"); } - return prepareCommonRequestData() + "&method=queue" + "&category=" + Arrays.asList(categories) + "&resolution=" + UtilsNetworking.urlEncodeString(json.toString()); + return prepareCommonRequestData() + "&method=queue" + "&category=" + Arrays.asList(categories) + "&resolution=" + UtilsNetworking.urlEncodeString(json.toString()) + "&la=" + language; } @Override diff --git a/sdk/src/main/java/ly/count/android/sdk/ModuleContent.java b/sdk/src/main/java/ly/count/android/sdk/ModuleContent.java index ffbf7c673..b6d030590 100644 --- a/sdk/src/main/java/ly/count/android/sdk/ModuleContent.java +++ b/sdk/src/main/java/ly/count/android/sdk/ModuleContent.java @@ -8,6 +8,7 @@ import androidx.annotation.Nullable; import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.json.JSONArray; @@ -121,7 +122,9 @@ private String prepareContentFetchRequest(@NonNull DisplayMetrics displayMetrics int landscapeWidth = portrait ? scaledHeight : scaledWidth; int landscapeHeight = portrait ? scaledWidth : scaledHeight; - return requestQueueProvider.prepareFetchContents(portraitWidth, portraitHeight, landscapeWidth, landscapeHeight, categories); + String language = Locale.getDefault().getLanguage().toLowerCase(); + + return requestQueueProvider.prepareFetchContents(portraitWidth, portraitHeight, landscapeWidth, landscapeHeight, categories, language); } boolean validateResponse(@NonNull JSONObject response) { diff --git a/sdk/src/main/java/ly/count/android/sdk/RequestQueueProvider.java b/sdk/src/main/java/ly/count/android/sdk/RequestQueueProvider.java index 25407bcaa..d9497bc6d 100644 --- a/sdk/src/main/java/ly/count/android/sdk/RequestQueueProvider.java +++ b/sdk/src/main/java/ly/count/android/sdk/RequestQueueProvider.java @@ -70,5 +70,5 @@ interface RequestQueueProvider { String prepareHealthCheckRequest(String preparedMetrics); - String prepareFetchContents(int portraitWidth, int portraitHeight, int landscapeWidth, int landscapeHeight, String[] categories); + String prepareFetchContents(int portraitWidth, int portraitHeight, int landscapeWidth, int landscapeHeight, String[] categories, String language); } From 2a7bbce0e4638dd97a9585f9431d6b85cb562a4c Mon Sep 17 00:00:00 2001 From: turtledreams <62231246+turtledreams@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:38:24 +0900 Subject: [PATCH 006/147] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f65bf368b..dff92660c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ ## XX.XX.XX -* Added language support for the contents. +* Added support for localization of content blocks. * Mitigated an issue where visibility could have been wrongly assigned if a view was closed while going to background. (Experimental!) From 4fcafa35618b6a96e54cb893b9d100c359ed62a2 Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Thu, 21 Nov 2024 09:50:03 +0300 Subject: [PATCH 007/147] feat: RC1 7.6 --- CHANGELOG.md | 2 +- gradle.properties | 2 +- sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java | 2 +- sdk/src/main/java/ly/count/android/sdk/Countly.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70bbfea0e..d74ee68fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## XX.XX.XX +## 24.7.6 * Added support for localization of content blocks. * Mitigated an issue where visibility could have been wrongly assigned if a view was closed while going to background. (Experimental!) diff --git a/gradle.properties b/gradle.properties index d7097fa31..5c6a450ce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,7 +22,7 @@ org.gradle.configureondemand=true android.useAndroidX=true android.enableJetifier=true # RELEASE FIELD SECTION -VERSION_NAME=24.7.5 +VERSION_NAME=24.7.6-RC1 GROUP=ly.count.android POM_URL=https://github.com/Countly/countly-sdk-android POM_SCM_URL=https://github.com/Countly/countly-sdk-android diff --git a/sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java b/sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java index a3b5362db..4396ed680 100644 --- a/sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java +++ b/sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java @@ -44,7 +44,7 @@ public class TestUtils { public final static String commonAppKey = "appkey"; public final static String commonDeviceId = "1234"; public final static String SDK_NAME = "java-native-android"; - public final static String SDK_VERSION = "24.7.5"; + public final static String SDK_VERSION = "24.7.6-RC1"; public static final int MAX_THREAD_COUNT_PER_STACK_TRACE = 50; public static class Activity2 extends Activity { diff --git a/sdk/src/main/java/ly/count/android/sdk/Countly.java b/sdk/src/main/java/ly/count/android/sdk/Countly.java index c481e68bb..c058cbc05 100644 --- a/sdk/src/main/java/ly/count/android/sdk/Countly.java +++ b/sdk/src/main/java/ly/count/android/sdk/Countly.java @@ -47,7 +47,7 @@ of this software and associated documentation files (the "Software"), to deal */ public class Countly { - private final String DEFAULT_COUNTLY_SDK_VERSION_STRING = "24.7.5"; + private final String DEFAULT_COUNTLY_SDK_VERSION_STRING = "24.7.6-RC1"; /** * Used as request meta data on every request From 3f5edf74c5cdb6cc8cc988a203571bbe4623c4d5 Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Thu, 21 Nov 2024 13:37:54 +0300 Subject: [PATCH 008/147] feat: 24.7.6 --- gradle.properties | 2 +- sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java | 2 +- sdk/src/main/java/ly/count/android/sdk/Countly.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5c6a450ce..2c4f3706c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,7 +22,7 @@ org.gradle.configureondemand=true android.useAndroidX=true android.enableJetifier=true # RELEASE FIELD SECTION -VERSION_NAME=24.7.6-RC1 +VERSION_NAME=24.7.6 GROUP=ly.count.android POM_URL=https://github.com/Countly/countly-sdk-android POM_SCM_URL=https://github.com/Countly/countly-sdk-android diff --git a/sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java b/sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java index 4396ed680..5e3eda25e 100644 --- a/sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java +++ b/sdk/src/androidTest/java/ly/count/android/sdk/TestUtils.java @@ -44,7 +44,7 @@ public class TestUtils { public final static String commonAppKey = "appkey"; public final static String commonDeviceId = "1234"; public final static String SDK_NAME = "java-native-android"; - public final static String SDK_VERSION = "24.7.6-RC1"; + public final static String SDK_VERSION = "24.7.6"; public static final int MAX_THREAD_COUNT_PER_STACK_TRACE = 50; public static class Activity2 extends Activity { diff --git a/sdk/src/main/java/ly/count/android/sdk/Countly.java b/sdk/src/main/java/ly/count/android/sdk/Countly.java index c058cbc05..860f952f1 100644 --- a/sdk/src/main/java/ly/count/android/sdk/Countly.java +++ b/sdk/src/main/java/ly/count/android/sdk/Countly.java @@ -47,7 +47,7 @@ of this software and associated documentation files (the "Software"), to deal */ public class Countly { - private final String DEFAULT_COUNTLY_SDK_VERSION_STRING = "24.7.6-RC1"; + private final String DEFAULT_COUNTLY_SDK_VERSION_STRING = "24.7.6"; /** * Used as request meta data on every request From 63b2416334bce3064f92fdccc71a2fe6d19c5d5b Mon Sep 17 00:00:00 2001 From: Arif Burak Demiray Date: Wed, 27 Nov 2024 10:04:41 +0300 Subject: [PATCH 009/147] feat: deprecated calls --- .../demo/ActivityExampleAutoViewTracking.java | 5 +- .../android/demo/ActivityExampleFeedback.java | 22 ++ .../main/java/ly/count/android/demo/App.java | 24 +-- .../res/layout/activity_example_feedback.xml | 188 ++++++++++-------- 4 files changed, 142 insertions(+), 97 deletions(-) diff --git a/app/src/main/java/ly/count/android/demo/ActivityExampleAutoViewTracking.java b/app/src/main/java/ly/count/android/demo/ActivityExampleAutoViewTracking.java index 64c570ca9..d9cdf6a31 100644 --- a/app/src/main/java/ly/count/android/demo/ActivityExampleAutoViewTracking.java +++ b/app/src/main/java/ly/count/android/demo/ActivityExampleAutoViewTracking.java @@ -4,6 +4,7 @@ import android.os.Bundle; import android.view.View; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import ly.count.android.sdk.Countly; @@ -40,7 +41,6 @@ public void onClickStartView2(View v) { Toast.makeText(getApplicationContext(), "Clicked startView 2", Toast.LENGTH_SHORT).show(); } - public void onClickPauseViewWithID(View v) { Countly.sharedInstance().views().pauseViewWithID(viewID); Toast.makeText(getApplicationContext(), "Clicked pauseViewWithID 1", Toast.LENGTH_SHORT).show(); @@ -99,9 +99,8 @@ public void onStop() { } @Override - public void onConfigurationChanged(Configuration newConfig) { + public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); Countly.sharedInstance().onConfigurationChanged(newConfig); } - } diff --git a/app/src/main/java/ly/count/android/demo/ActivityExampleFeedback.java b/app/src/main/java/ly/count/android/demo/ActivityExampleFeedback.java index 0fcab479b..a1932e7b0 100644 --- a/app/src/main/java/ly/count/android/demo/ActivityExampleFeedback.java +++ b/app/src/main/java/ly/count/android/demo/ActivityExampleFeedback.java @@ -3,6 +3,7 @@ import android.os.Bundle; import android.util.Log; import android.view.View; +import android.widget.Button; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import java.util.List; @@ -23,6 +24,27 @@ public class ActivityExampleFeedback extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_example_feedback); + + final Button presentSurvey = findViewById(R.id.presentSurvey); + presentSurvey.setOnClickListener(new View.OnClickListener() { + @Override public void onClick(View v) { + Countly.sharedInstance().feedback().presentSurvey(ActivityExampleFeedback.this); + } + }); + + final Button presentRating = findViewById(R.id.presentRating); + presentRating.setOnClickListener(new View.OnClickListener() { + @Override public void onClick(View v) { + Countly.sharedInstance().feedback().presentRating(ActivityExampleFeedback.this); + } + }); + + final Button presentNPS = findViewById(R.id.presentNPS); + presentNPS.setOnClickListener(new View.OnClickListener() { + @Override public void onClick(View v) { + Countly.sharedInstance().feedback().presentNPS(ActivityExampleFeedback.this); + } + }); } public void onClickViewOther02(View v) { diff --git a/app/src/main/java/ly/count/android/demo/App.java b/app/src/main/java/ly/count/android/demo/App.java index b5e63aa66..42f90d236 100644 --- a/app/src/main/java/ly/count/android/demo/App.java +++ b/app/src/main/java/ly/count/android/demo/App.java @@ -25,7 +25,8 @@ import java.util.concurrent.ConcurrentHashMap; import ly.count.android.sdk.Countly; import ly.count.android.sdk.CountlyConfig; -import ly.count.android.sdk.CrashFilterCallback; +import ly.count.android.sdk.CrashData; +import ly.count.android.sdk.GlobalCrashFilterCallback; import ly.count.android.sdk.ModuleLog; import ly.count.android.sdk.messaging.CountlyConfigPush; import ly.count.android.sdk.messaging.CountlyPush; @@ -171,17 +172,6 @@ public void onCreate() { } } }) - - .enableCrashReporting() - .setRecordAllThreadsWithCrash() - .setCustomCrashSegment(customCrashSegmentation) - .setCrashFilterCallback(new CrashFilterCallback() { - @Override - public boolean filterCrash(String crash) { - return crash.contains("crash"); - } - }) - .enableAutomaticViewTracking() // uncomment the line below to enable auto enrolling the user to AB experiments when downloading RC data //.enrollABOnRCDownload() @@ -234,6 +224,16 @@ public boolean filterCrash(String crash) { .setUserProperties(customUserProperties); + config.crashes + .enableCrashReporting() + .enableRecordAllThreadsWithCrash() + .setCustomCrashSegmentation(customCrashSegmentation) + .setGlobalCrashFilterCallback(new GlobalCrashFilterCallback() { + @Override public boolean filterCrash(CrashData crash) { + return crash.getStackTrace().contains("secret"); + } + }); + config.apm.enableAppStartTimeTracking() .enableForegroundBackgroundTracking() .setAppStartTimestampOverride(applicationStartTimestamp); diff --git a/app/src/main/res/layout/activity_example_feedback.xml b/app/src/main/res/layout/activity_example_feedback.xml index 72e13ca06..1f0dc79a7 100644 --- a/app/src/main/res/layout/activity_example_feedback.xml +++ b/app/src/main/res/layout/activity_example_feedback.xml @@ -1,100 +1,124 @@ - -