Skip to content

Commit 0aa3fec

Browse files
authored
Merge pull request #523 from Countly/disable_view_behavior
Disable option for restarting manual views on fg/bg
2 parents 14f0202 + 482e6a3 commit 0aa3fec

File tree

4 files changed

+109
-3
lines changed

4 files changed

+109
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 25.4.9
2+
* Added a new config option `disableViewRestartForManualRecording()` to disable auto close/restart behavior of manual views on app background/foreground actions.
3+
14
## 25.4.8
25
* Mitigated an issue where push notifications were not shown when consent was not required and app was killed.
36

sdk/src/androidTest/java/ly/count/android/sdk/ModuleViewsTests.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,6 +2062,92 @@ public void autoViewTracking_consentRemoval() throws JSONException {
20622062
Assert.assertEquals(9, TestUtils.getCurrentRQ().length);
20632063
}
20642064

2065+
/**
2066+
* "startView" with bg/fg switch case
2067+
* - Validate that after an auto stopped view is started and app gone to background
2068+
* running view should not stop because behavior is disabled
2069+
* - After coming from the background to foreground no view should be started because behavior is disabled
2070+
*
2071+
* @throws InterruptedException if the thread is interrupted
2072+
* @throws JSONException if the JSON is not valid
2073+
*/
2074+
@Test
2075+
public void startView_restartAfterActivityComesFromForeground_behaviorDisabled() throws InterruptedException, JSONException {
2076+
CountlyConfig countlyConfig = TestUtils.createScenarioEventIDConfig(TestUtils.incrementalViewIdGenerator(), TestUtils.incrementalEventIdGenerator());
2077+
countlyConfig.setApplication(null);
2078+
countlyConfig.setContext(TestUtils.getContext());
2079+
countlyConfig.disableViewRestartForManualRecording();
2080+
countlyConfig.setEventQueueSizeToSend(1);
2081+
Countly countly = new Countly().init(countlyConfig);
2082+
2083+
Activity activity = mock(Activity.class);
2084+
2085+
TestUtils.assertRQSize(0);
2086+
2087+
countly.onStart(activity);
2088+
countly.views().startView("test");
2089+
2090+
ModuleSessionsTests.validateSessionBeginRequest(0, TestUtils.commonDeviceId);
2091+
ModuleEventsTests.validateEventInRQ(TestUtils.commonDeviceId, ModuleViews.ORIENTATION_EVENT_KEY, null, 1, 0.0, 0.0, "ide1", "_CLY_", "", "_CLY_", 1, 3, 0, 1);
2092+
validateView("test", 0.0, 2, 3, true, true, null, "idv1", "");
2093+
2094+
Thread.sleep(1000);
2095+
2096+
countly.onStop();
2097+
ModuleSessionsTests.validateSessionEndRequest(3, 1, TestUtils.commonDeviceId);
2098+
Thread.sleep(1000);
2099+
countly.onStart(activity);
2100+
2101+
ModuleSessionsTests.validateSessionBeginRequest(4, TestUtils.commonDeviceId);
2102+
ModuleEventsTests.validateEventInRQ(TestUtils.commonDeviceId, ModuleViews.ORIENTATION_EVENT_KEY, null, 1, 0.0, 0.0, "ide2", "_CLY_", "idv1", "_CLY_", 5, 6, 0, 1);
2103+
2104+
Thread.sleep(1000);
2105+
2106+
countly.views().stopViewWithName("test");
2107+
validateView("test", 3.0, 6, 7, false, false, null, "idv1", "");
2108+
countly.onStop();
2109+
2110+
ModuleSessionsTests.validateSessionEndRequest(7, 1, TestUtils.commonDeviceId);
2111+
TestUtils.assertRQSize(8);
2112+
}
2113+
2114+
/**
2115+
* Auto view tracking with restart is disabled for manual views
2116+
* Validate that after an auto stopped view is started and app gone to background
2117+
* running view should stop because auto views are not affected by the disabled behavior
2118+
*
2119+
* @throws JSONException if the JSON is not valid
2120+
*/
2121+
@Test
2122+
public void autoViewTracking_restartDisabledForManualViews() throws JSONException, InterruptedException {
2123+
CountlyConfig countlyConfig = TestUtils.createBaseConfig(TestUtils.getContext());
2124+
countlyConfig.setLoggingEnabled(true);
2125+
countlyConfig.enableAutomaticViewTracking();
2126+
countlyConfig.disableViewRestartForManualRecording();
2127+
countlyConfig.setEventQueueSizeToSend(1);
2128+
2129+
Countly countly = new Countly().init(countlyConfig);
2130+
2131+
Activity activity = Mockito.mock(Activity.class);
2132+
countly.onStart(activity);
2133+
2134+
ModuleSessionsTests.validateSessionBeginRequest(0, TestUtils.commonDeviceId);
2135+
ModuleEventsTests.validateEventInRQ("[CLY]_orientation", TestUtils.map("mode", "portrait"), 1, 0, 0, 1, 3);
2136+
validateView(activity.getClass().getName(), 0.0, 2, 3, true, true, TestUtils.map(), "_CLY_", "_CLY_", null);
2137+
Thread.sleep(1000);
2138+
countly.onStop();
2139+
ModuleSessionsTests.validateSessionEndRequest(3, 1, TestUtils.commonDeviceId);
2140+
validateView(activity.getClass().getName(), 1.0, 4, 5, false, false, null, "_CLY_", "_CLY_");
2141+
2142+
countly.onStart(activity);
2143+
Thread.sleep(1000);
2144+
ModuleSessionsTests.validateSessionBeginRequest(5, TestUtils.commonDeviceId);
2145+
ModuleEventsTests.validateEventInRQ("[CLY]_orientation", TestUtils.map("mode", "portrait"), 1, 0, 0, 6, 8);
2146+
2147+
validateView(activity.getClass().getName(), 0.0, 7, 8, true, true, TestUtils.map(), "_CLY_", "_CLY_", null);
2148+
Assert.assertEquals(8, TestUtils.getCurrentRQ().length);
2149+
}
2150+
20652151
static void validateView(String viewName, Double viewDuration, int idx, int size, boolean start, boolean visit, Map<String, Object> customSegmentation, String id, String pvid) throws JSONException {
20662152
validateView(viewName, viewDuration, idx, size, start, visit, customSegmentation, id, pvid, null);
20672153
}

sdk/src/main/java/ly/count/android/sdk/CountlyConfig.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ public class CountlyConfig {
216216
// If set to true, the SDK will not store the default push consent state on initialization for not requiring consent
217217
boolean disableStoringDefaultPushConsent = false;
218218

219+
// If set to true, the SDK will not restart manual views while switching between foreground and background
220+
boolean disableViewRestartForManualRecording = false;
221+
219222
/**
220223
* THIS VARIABLE SHOULD NOT BE USED
221224
* IT IS ONLY FOR INTERNAL TESTING
@@ -1116,6 +1119,19 @@ public synchronized CountlyConfig disableStoringDefaultPushConsent() {
11161119
return this;
11171120
}
11181121

1122+
/**
1123+
* Disable view restart when manual view recording is done.
1124+
* By default, if automatic view tracking is not enabled and a manual view is recorded,
1125+
* the SDK was restarting the views to properly track the view duration in bg/fg transitions.
1126+
* Now, with this option enabled, the SDK will not restart the views on manual view recording.
1127+
*
1128+
* @return Returns the same config object for convenient linking
1129+
*/
1130+
public synchronized CountlyConfig disableViewRestartForManualRecording() {
1131+
this.disableViewRestartForManualRecording = true;
1132+
return this;
1133+
}
1134+
11191135
/**
11201136
* APM configuration interface to be used with CountlyConfig
11211137
*/

sdk/src/main/java/ly/count/android/sdk/ModuleViews.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class ModuleViews extends ModuleBase implements ViewIdProvider {
2020
String currentViewName = "";
2121
private boolean firstView = true;
2222
boolean autoViewTracker = false;
23+
boolean restartManualViews = true;
2324
boolean automaticTrackingShouldUseShortName = false;
2425

2526
//track orientation changes
@@ -84,6 +85,7 @@ static class ViewData {
8485
setGlobalViewSegmentationInternal(config.globalViewSegmentation);
8586
autoTrackingActivityExceptions = config.automaticViewTrackingExceptions;
8687
trackOrientationChanges = config.trackOrientationChange;
88+
restartManualViews = !config.disableViewRestartForManualRecording;
8789

8890
viewsInterface = new Views();
8991
}
@@ -552,7 +554,7 @@ void onActivityStopped(int updatedActivityCount) {
552554
}
553555
}
554556

555-
if (updatedActivityCount <= 0) {
557+
if (updatedActivityCount <= 0 && (autoViewTracker || restartManualViews)) {
556558
//if we go to the background, stop all running views
557559
stopRunningViewsAndSend();
558560
}
@@ -587,8 +589,7 @@ void onActivityStarted(Activity activity, int updatedActivityCount) {
587589
}
588590
}
589591

590-
if (updatedActivityCount == 1) {
591-
//if we go to the background, stop all running views
592+
if (updatedActivityCount == 1 && (autoViewTracker || restartManualViews)) {
592593
startStoppedViews();
593594
}
594595
}

0 commit comments

Comments
 (0)