Skip to content

Commit 0245a56

Browse files
[Java] Add new device ID module tests add device ID type to scenario tests (#161)
* feat: new device id change callback * feat: call after onDeviceId * refactor: usage of device id changed in module device id * feat: did changes * feat: add device id type to scenario tests * fix: tests * revert: scenario changes * feat: missing comments * feat: new device id module calls to scenarioo device id tests * feat: missing changelog * fix: update existing tests * fix: add check to callback * refactor: remove unnecessary callback * feat: test ccases * fix: login and logout * refactor: device id module * fix: remove unnecessary params * feat: new tests * fix: rq access index * feat: multiple device id check * fix: test * fix: device id change logic * fix: device id callbacks * fix: module events req * fix: module event check and test cases comments * fix: new ids * fix: added missings tests * feat: buggy test for device id change * refactor: remove unsued * fix: changed index of features * fix: end any view * feat: finish up tests * misc * fix: without merge not started session * fix: add missing test cases --------- Co-authored-by: Artūrs Kadiķis <[email protected]>
1 parent 3ac8fa1 commit 0245a56

File tree

13 files changed

+688
-111
lines changed

13 files changed

+688
-111
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
* 'enableRemoteConfigAutomaticTriggers' to automatically download remote config values on init
1515
* 'remoteConfigRegisterGlobalCallback(RCDownloadCallback callback)' to register a remote config callback
1616
* Added the ability to set the user profile picture with an URL
17-
* Added to a way to get device id type by calling "Countly::deviceId::getType" via "instance()" call
17+
* Added the DeviceId interface. It is accessible through "Countly::instance()::deviceId()" call.
18+
* Added a way to get device id type by calling "Countly::deviceId::getType" via "instance()" call
1819
* The SDK now uses a different file for internal configuration. Old file will be deleted.
1920

2021
* Fixed a bug where it was not possible to send a profile picture with binary data

sdk-java/src/main/java/ly/count/sdk/java/internal/CoreFeature.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
import java.util.Map;
55

66
public enum CoreFeature {
7-
Sessions(1 << 1, ModuleSessions::new),
8-
Events(1 << 2, ModuleEvents::new),
7+
Events(1 << 1, ModuleEvents::new),
8+
Sessions(1 << 2, ModuleSessions::new),
99
Views(1 << 3, ModuleViews::new),
1010
CrashReporting(1 << 4, ModuleCrash::new),
1111
Location(1 << 5),

sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleBase.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package ly.count.sdk.java.internal;
22

3-
import ly.count.sdk.java.Config;
43
import ly.count.sdk.java.Session;
54

65
/**
76
* Created by artem on 05/01/2017.
8-
*
97
* Contract:
108
* <ul>
119
* <li>ModuleBase instances must provide empty constructor with no parameters.</li>
@@ -33,18 +31,6 @@ public void init(InternalConfig config) {
3331
internalConfig = config;
3432
}
3533

36-
/**
37-
* Device ID has been acquired from the device id provider.
38-
* Can be invoked multiple times throughout the ModuleBase lifecycle.
39-
* Parameters can be instance equal (==), meaning that id haven't changed.
40-
*
41-
* @param config InternalConfig to run in
42-
* @param deviceId deviceId valid from now on
43-
* @param oldDeviceId deviceId valid previously if any
44-
*/
45-
public void onDeviceId(InternalConfig config, Config.DID deviceId, Config.DID oldDeviceId) {
46-
}
47-
4834
/**
4935
* App users opted out of analytics, or the developer changed essential preferences.
5036
* Clear all module-related data, close any resources, and prepare to start from a clean sheet.
@@ -131,6 +117,9 @@ protected void initFinished(InternalConfig config) {
131117

132118
/**
133119
* Called when the device id is changed.
120+
*
121+
* @param oldDeviceId old device id
122+
* @param withMerge if the device id change is with merge or not
134123
*/
135124
protected void deviceIdChanged(String oldDeviceId, boolean withMerge) {
136125

sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleDeviceIdCore.java

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public void initFinished(final InternalConfig config) {
8181
L.d("[ModuleDeviceIdCore] initFinished, Got developer id [" + did + "]");
8282
} else {
8383
// regular flow - acquire id using specified strategy
84-
did = acquireId(config);
84+
did = acquireId();
8585
}
8686

8787
config.setDeviceId(did);
@@ -97,28 +97,16 @@ public void initFinished(final InternalConfig config) {
9797
public void deviceIdChanged(String oldDeviceId, boolean withMerge) {
9898
L.d("[ModuleDeviceIdCore] deviceIdChanged, oldDeviceId [" + oldDeviceId + "] withMerge [" + withMerge + "]");
9999
Config.DID deviceId = internalConfig.getDeviceId();
100-
SessionImpl session = SDKCore.instance.getSession();
101-
102-
if (deviceId != null && oldDeviceId != null && !deviceId.id.equals(oldDeviceId)) {
103-
// device id changed
104-
if (session != null && session.isActive()) {
105-
// end previous session
106-
L.d("[ModuleDeviceIdCore] Ending session because device id was changed from [" + oldDeviceId + "]");
107-
session.end(null, null, oldDeviceId);
108-
}
109-
110-
// add device id change request
111-
Request request = ModuleRequests.nonSessionRequest(internalConfig);
112100

113-
//if we are missing the device ID, add it
114-
if (!request.params.has(Params.PARAM_DEVICE_ID)) {
115-
request.params.add(Params.PARAM_DEVICE_ID, deviceId.id);
116-
}
117-
//add the old device ID every time
118-
request.params.add(Params.PARAM_OLD_DEVICE_ID, oldDeviceId);
101+
if (Utils.isEmptyOrNull(deviceId.id) || Utils.isEmptyOrNull(oldDeviceId)) {
102+
L.w("[ModuleDeviceIdCore] deviceIdChanged, Empty id passed to changeDeviceId method");
103+
return;
104+
}
119105

120-
ModuleRequests.pushAsync(internalConfig, request);
121-
SDKCore.instance.onSignal(internalConfig, SDKCore.Signal.DID.getIndex());
106+
//if without merge then we should not send this request
107+
if (withMerge) {
108+
// add device id change request and add the old device ID every time
109+
ModuleRequests.pushAsync(internalConfig, new Request(Params.PARAM_OLD_DEVICE_ID, oldDeviceId));
122110
}
123111
}
124112

@@ -139,7 +127,7 @@ public void login(String id) {
139127
* - send corresponding request to server.
140128
*/
141129
public void logout() {
142-
Config.DID did = acquireId(internalConfig);
130+
Config.DID did = acquireId();
143131
changeDeviceIdInternal(did.id, DeviceIdType.fromInt(did.strategy, L), false);
144132
}
145133

@@ -163,41 +151,30 @@ protected void changeDeviceIdInternal(String id, DeviceIdType type, boolean with
163151
return;
164152
}
165153

166-
Config.DID did = new Config.DID(type.index, id);
167154
internalConfig.storageProvider.setDeviceIdType(type.name());
168155
internalConfig.storageProvider.setDeviceID(id);
169-
internalConfig.setDeviceId(did);
170-
171-
if (!withMerge) {
172-
SessionImpl session = SDKCore.instance.getSession();
173-
if (session != null) {
174-
L.d("[ModuleDeviceIdCore] changeDeviceIdInternal, Ending session because device id was unset from [" + old.id + "]");
175-
session.end(null, null, old.id);
176-
}
177-
}
156+
internalConfig.setDeviceId(new Config.DID(type.index, id));
178157

179158
SDKCore.instance.notifyModulesDeviceIdChanged(old.id, withMerge);
180159
}
181160

182161
/**
183162
* Gets id of the strategy supplied. In case strategy is not available, returns a fallback strategy.
184163
* In case strategy is available but id cannot be acquired right now, returns null.
185-
*
186-
* @param config InternalConfig to run in
187164
*/
188-
protected Config.DID acquireId(final InternalConfig config) {
189-
L.i("[ModuleDeviceIdCore] acquireId, Acquiring device id of strategy [" + config.getDeviceIdStrategy() + "]");
165+
protected Config.DID acquireId() {
166+
L.i("[ModuleDeviceIdCore] acquireId, Acquiring device id of strategy [" + internalConfig.getDeviceIdStrategy() + "]");
190167
Config.DID did = null;
191168

192-
int index = config.getDeviceIdStrategy();
169+
int index = internalConfig.getDeviceIdStrategy();
193170

194171
while (index >= 0) {
195172
DeviceIdGenerator generator = generators.get(index);
196173
if (generator == null) {
197174
L.w("[ModuleDeviceIdCore] Device id strategy [" + index + "] is not available. Falling back to next one.");
198175
index--;
199176
} else {
200-
String id = generator.generate(config);
177+
String id = generator.generate(internalConfig);
201178
if (Utils.isNotEmpty(id)) {
202179
did = new Config.DID(index, id);
203180
break;
@@ -214,7 +191,7 @@ protected Config.DID acquireId(final InternalConfig config) {
214191
}
215192
L.d("[ModuleDeviceIdCore] acquireId, Got device id: " + did);
216193
} else {
217-
L.i("[ModuleDeviceIdCore] acquireId, No device id of strategy [" + config.getDeviceIdStrategy() + "] is available yet");
194+
L.i("[ModuleDeviceIdCore] acquireId, No device id of strategy [" + internalConfig.getDeviceIdStrategy() + "] is available yet");
218195
}
219196

220197
return did;

sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleEvents.java

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package ly.count.sdk.java.internal;
22

3-
import java.util.HashMap;
43
import java.util.List;
54
import java.util.Map;
5+
import java.util.concurrent.ConcurrentHashMap;
66
import java.util.stream.Collectors;
77
import ly.count.sdk.java.Countly;
8+
import ly.count.sdk.java.Session;
9+
import ly.count.sdk.java.View;
810

911
public class ModuleEvents extends ModuleBase {
1012
protected EventQueue eventQueue = null;
11-
final Map<String, EventImpl> timedEvents = new HashMap<>();
13+
final Map<String, EventImpl> timedEvents = new ConcurrentHashMap<>();
1214
protected Events eventsInterface = null;
1315

1416
@Override
@@ -22,14 +24,39 @@ public void init(InternalConfig config) {
2224

2325
@Override
2426
protected void onTimer() {
25-
addEventsToRequestQ();
27+
addEventsToRequestQ(null);
2628
}
2729

2830
@Override
2931
public Boolean onRequest(Request request) {
3032
return true;
3133
}
3234

35+
@Override
36+
public void deviceIdChanged(String oldDeviceId, boolean withMerge) {
37+
super.deviceIdChanged(oldDeviceId, withMerge);
38+
L.d("[ModuleEvents] deviceIdChanged: oldDeviceId = " + oldDeviceId + ", withMerge = " + withMerge);
39+
if (!withMerge) {
40+
for (Map.Entry<String, EventImpl> timedEventEntry : timedEvents.entrySet()) {
41+
L.d("[ModuleEvents] deviceIdChanged, Ending timed event: [" + timedEventEntry.getKey() + "]");
42+
endEventInternal(timedEventEntry.getKey(), timedEventEntry.getValue().segmentation, timedEventEntry.getValue().count, timedEventEntry.getValue().sum);
43+
}
44+
45+
// this part is to end and record the current view if exists
46+
Session session = Countly.session();
47+
if ((session != null && session.isActive())) {
48+
View currentView = ((SessionImpl) session).currentView;
49+
if (currentView != null) {
50+
currentView.stop(true);
51+
} else {
52+
Storage.pushAsync(internalConfig, ((SessionImpl) Countly.session()));
53+
}
54+
}
55+
56+
addEventsToRequestQ(oldDeviceId);
57+
}
58+
}
59+
3360
@Override
3461
public void stop(InternalConfig config, final boolean clear) {
3562
super.stop(config, clear);
@@ -39,11 +66,18 @@ public void stop(InternalConfig config, final boolean clear) {
3966
}
4067
}
4168

42-
private synchronized void addEventsToRequestQ() {
69+
private synchronized void addEventsToRequestQ(String deviceId) {
4370
L.d("[ModuleEvents] addEventsToRequestQ");
4471

72+
if (eventQueue.eventQueueMemoryCache.isEmpty()) {
73+
L.d("[ModuleEvents] addEventsToRequestQ, eventQueueMemoryCache is empty, skipping");
74+
return;
75+
}
76+
4577
Request request = new Request();
46-
request.params.add("device_id", Countly.instance().getDeviceId());
78+
if (deviceId != null) {
79+
request.params.add("device_id", deviceId);
80+
}
4781
request.params.arr("events").put(eventQueue.eventQueueMemoryCache).add();
4882
request.own(ModuleEvents.class);
4983

@@ -93,7 +127,7 @@ private void addEventToQueue(EventImpl event) {
93127
private void checkEventQueueToSend(boolean forceSend) {
94128
L.d("[ModuleEvents] queue size:[" + eventQueue.eqSize() + "] || forceSend: " + forceSend);
95129
if (forceSend || (eventQueue.eqSize() >= internalConfig.getEventsBufferSize())) {
96-
addEventsToRequestQ();
130+
addEventsToRequestQ(null);
97131
}
98132
}
99133

sdk-java/src/main/java/ly/count/sdk/java/internal/ModuleSessions.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,19 @@ public void stop(InternalConfig config, boolean clear) {
6060
/**
6161
* Handles one single case of device id change with auto sessions handling, see first {@code if} here:
6262
*
63-
* @see ModuleDeviceIdCore#onDeviceId(InternalConfig, Config.DID, Config.DID)
63+
* @see ModuleDeviceIdCore#deviceIdChanged(String, boolean)
6464
*/
65-
public void onDeviceId(final InternalConfig config, final Config.DID deviceId, final Config.DID oldDeviceId) {
66-
L.d("[ModuleSessions] onDeviceId " + deviceId + ", old " + oldDeviceId);
67-
if (deviceId != null && oldDeviceId != null && !deviceId.equals(oldDeviceId) && getSession() == null) {
68-
session(config, null).begin();
65+
@Override
66+
public void deviceIdChanged(String oldDeviceId, boolean withMerge) {
67+
Config.DID deviceId = internalConfig.getDeviceId();
68+
L.d("[ModuleSessions] deviceIdChanged, " + deviceId + ", old " + oldDeviceId);
69+
if (!withMerge && session != null && session.isActive()) {
70+
L.d("[ModuleSessions] deviceIdChanged, Ending session because device id was unset from [" + oldDeviceId + "]");
71+
session.end(null, null, oldDeviceId);
72+
}
73+
74+
if (deviceId != null && oldDeviceId != null && (session == null || !session.isActive()) && !withMerge) {
75+
session(internalConfig, null).begin();
6976
}
7077
}
7178

sdk-java/src/main/java/ly/count/sdk/java/internal/SDKCore.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public SDKCore() {
4949
}
5050

5151
protected Log L = null;
52-
private static ModuleBase testDummyModule = null;//set during testing when trying to check the SDK's lifecycle
52+
protected static ModuleBase testDummyModule = null;//set during testing when trying to check the SDK's lifecycle
5353

5454
protected static void registerDefaultModuleMappings() {
5555
moduleMappings.put(CoreFeature.DeviceId.getIndex(), ModuleDeviceIdCore.class);
@@ -588,12 +588,14 @@ public void onCrash(final InternalConfig config, Throwable t, boolean fatal, Str
588588
}
589589

590590
public void notifyModulesDeviceIdChanged(@Nullable String old, final boolean withMerge) {
591-
L.d("[SDKCore] deviceIdChanged, newDeviceId:[" + config.getDeviceId() + "], oldDeviceId:[ " + old + "]");
591+
L.d("[SDKCore] notifyModulesDeviceIdChanged, newDeviceId:[" + config.getDeviceId() + "], oldDeviceId:[ " + old + "]");
592592
Config.DID id = config.getDeviceId();
593-
modules.forEach((feature, module) -> module.deviceIdChanged(old, withMerge));
594-
if (id != null) {
595-
user.id = id.id;
593+
if (id.id.equals(old)) {
594+
L.d("[SDKCore] notifyModulesDeviceIdChanged, newDeviceId is the same as oldDeviceId, skipping");
595+
return;
596596
}
597+
modules.forEach((feature, module) -> module.deviceIdChanged(old, withMerge));
598+
user.id = id.id;
597599
}
598600

599601
public void login(String id) {

sdk-java/src/main/java/ly/count/sdk/java/internal/SessionImpl.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,6 @@ Future<Boolean> end(Long now, final Tasks.Callback<Boolean> callback, String did
189189

190190
this.consents = SDKCore.instance.consents;
191191

192-
// // TODO: check if needed
193-
// for (Event event: timedEvents.values()) {
194-
// event.endAndRecord();
195-
// }
196-
197192
if (currentView != null) {
198193
currentView.stop(true);
199194
} else {

0 commit comments

Comments
 (0)