Skip to content

Commit d7886b7

Browse files
mnoman09NomanShoaibyasirfolio3
authored
feat(clearAllNotificationListeners): Adds support for removing all notification listeners (#35)
* Added function to remove all notification listener and listeners of specific type * Resolve issues and mapped listener callbacks to SDKKey. Resolve issue in unit tests while comparing listeners payload. * removed all listeners from callbackids upon intialization * Added separate functions of removing listeners * minor changes in sample app * exposing listener Type as it is going to used for specifying listener type user wants to clear * comment added * Swift implementation. * renamed the function and added listener at the end * removed invalid test case * updated commented code Co-authored-by: mnoman09 <m.nomanshoaib09@gmail.com> Co-authored-by: Yasir Ali <yali@folio3.com>
1 parent ef03ccb commit d7886b7

File tree

14 files changed

+1050
-424
lines changed

14 files changed

+1050
-424
lines changed

android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import com.optimizely.optimizely_flutter_sdk.helper_classes.Utils;
5454

5555
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.*;
56+
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Utils.getNotificationListenerType;
5657

5758
import java.util.Collections;
5859
import java.util.LinkedHashMap;
@@ -66,7 +67,7 @@ public class OptimizelyFlutterClient {
6667

6768
protected static final Map<String, OptimizelyManager> optimizelyManagerTracker = new HashMap<>();
6869
protected static final Map<String, Map<String, OptimizelyUserContext>> userContextsTracker = new HashMap<>();
69-
protected static final Map<Integer, Integer> notificationIdsTracker = new HashMap<>();
70+
protected static final Map<String, Map<Integer, Integer>> notificationIdsTracker = new HashMap<>();
7071

7172

7273
protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @NonNull Result result) {
@@ -123,7 +124,7 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N
123124
getOptimizelyClient(sdkKey).close();
124125
}
125126
optimizelyManagerTracker.remove(sdkKey);
126-
127+
notificationIdsTracker.remove(sdkKey);
127128
// Creating new instance
128129
OptimizelyManager optimizelyManager = OptimizelyManager.builder()
129130
.withEventProcessor(batchProcessor)
@@ -470,15 +471,37 @@ protected void removeNotificationListener(ArgumentsParser argumentsParser, @NonN
470471
return;
471472
}
472473

473-
Integer id = argumentsParser.getNotificaitonID();
474-
String type = argumentsParser.getNotificationType();
475-
476-
if (id == null || type == null) {
474+
Integer id = argumentsParser.getNotificationID();
475+
if (id == null) {
477476
result.success(createResponse(ErrorMessage.INVALID_PARAMS));
478477
return;
479478
}
480479
optimizelyClient.getNotificationCenter().removeNotificationListener(id);
481-
notificationIdsTracker.remove(id);
480+
if (notificationIdsTracker.containsKey(sdkKey))
481+
notificationIdsTracker.get(sdkKey).remove(id);
482+
result.success(createResponse());
483+
}
484+
485+
protected void clearAllNotificationListeners(ArgumentsParser argumentsParser, @NonNull Result result) {
486+
String sdkKey = argumentsParser.getSdkKey();
487+
OptimizelyClient optimizelyClient = getOptimizelyClient(sdkKey);
488+
if (!isOptimizelyClientValid(sdkKey, optimizelyClient, result)) {
489+
return;
490+
}
491+
492+
String type = argumentsParser.getNotificationType();
493+
List<Integer> callBackIds = argumentsParser.getCallBackIds();
494+
495+
if (type == null) {
496+
optimizelyClient.getNotificationCenter().clearAllNotificationListeners();
497+
} else {
498+
optimizelyClient.getNotificationCenter().clearNotificationListeners(getNotificationListenerType(type));
499+
}
500+
if (notificationIdsTracker.containsKey(sdkKey)) {
501+
for (Integer id: callBackIds) {
502+
notificationIdsTracker.get(sdkKey).remove(id);
503+
}
504+
}
482505
result.success(createResponse());
483506
}
484507

@@ -507,7 +530,7 @@ protected void addNotificationListener(ArgumentsParser argumentsParser, @NonNull
507530
return;
508531
}
509532

510-
Integer id = argumentsParser.getNotificaitonID();
533+
Integer id = argumentsParser.getNotificationID();
511534
String type = argumentsParser.getNotificationType();
512535

513536
if (id == null || type == null) {
@@ -523,7 +546,7 @@ protected void addNotificationListener(ArgumentsParser argumentsParser, @NonNull
523546
notificationMap.put(DecisionListenerKeys.USER_ID, decisionNotification.getUserId());
524547
notificationMap.put(DecisionListenerKeys.ATTRIBUTES, decisionNotification.getAttributes());
525548
notificationMap.put(DecisionListenerKeys.DECISION_INFO, decisionNotification.getDecisionInfo());
526-
invokeNotification(id, NotificationType.DECISION, notificationMap);
549+
invokeNotification(id, sdkKey, NotificationType.DECISION, notificationMap);
527550
});
528551
break;
529552
}
@@ -543,7 +566,7 @@ protected void addNotificationListener(ArgumentsParser argumentsParser, @NonNull
543566
notificationMap.put(ActivateListenerKeys.USER_ID, activateNotification.getUserId());
544567
notificationMap.put(ActivateListenerKeys.ATTRIBUTES, activateNotification.getAttributes());
545568
notificationMap.put(ActivateListenerKeys.VARIATION, variationMap);
546-
invokeNotification(id, NotificationType.ACTIVATE, notificationMap);
569+
invokeNotification(id, sdkKey, NotificationType.ACTIVATE, notificationMap);
547570
});
548571
break;
549572
}
@@ -554,7 +577,7 @@ protected void addNotificationListener(ArgumentsParser argumentsParser, @NonNull
554577
notificationMap.put(TrackListenerKeys.USER_ID, trackNotification.getUserId());
555578
notificationMap.put(TrackListenerKeys.ATTRIBUTES, trackNotification.getAttributes());
556579
notificationMap.put(TrackListenerKeys.EVENT_TAGS, trackNotification.getEventTags());
557-
invokeNotification(id, NotificationType.TRACK, notificationMap);
580+
invokeNotification(id, sdkKey, NotificationType.TRACK, notificationMap);
558581
});
559582
break;
560583
}
@@ -565,22 +588,25 @@ protected void addNotificationListener(ArgumentsParser argumentsParser, @NonNull
565588
Map<String, Object> listenerMap = new HashMap<>();
566589
listenerMap.put(LogEventListenerKeys.URL, logEvent.getEndpointUrl());
567590
listenerMap.put(LogEventListenerKeys.PARAMS, eventParams);
568-
invokeNotification(id, NotificationType.LOG_EVENT, listenerMap);
591+
invokeNotification(id, sdkKey, NotificationType.LOG_EVENT, listenerMap);
569592
});
570593
break;
571594
}
572595
case NotificationType.CONFIG_UPDATE: {
573596
notificationId = optimizelyClient.getNotificationCenter().addNotificationHandler(UpdateConfigNotification.class, configUpdate -> {
574597
Map<String, Object> listenerMap = new HashMap<>();
575598
listenerMap.put("Config-update", Collections.emptyMap());
576-
invokeNotification(id, NotificationType.CONFIG_UPDATE, listenerMap);
599+
invokeNotification(id, sdkKey, NotificationType.CONFIG_UPDATE, listenerMap);
577600
});
578601
break;
579602
}
580603
default:
581604
result.success(createResponse(ErrorMessage.INVALID_PARAMS));
582605
}
583-
notificationIdsTracker.put(id, notificationId);
606+
if (!notificationIdsTracker.containsKey(sdkKey)) {
607+
notificationIdsTracker.put(sdkKey, new HashMap<>());
608+
}
609+
notificationIdsTracker.get(sdkKey).put(id, notificationId);
584610
result.success(createResponse());
585611
}
586612

@@ -650,9 +676,10 @@ private boolean isUserContextValid(String sdkKey, OptimizelyUserContext optimize
650676
return true;
651677
}
652678

653-
private void invokeNotification(int id, String notificationType, Map notificationMap) {
679+
private void invokeNotification(int id, String sdkKey, String notificationType, Map notificationMap) {
654680
Map<String, Object> listenerResponse = new HashMap<>();
655681
listenerResponse.put(RequestParameterKey.NOTIFICATION_ID, id);
682+
listenerResponse.put(RequestParameterKey.SDK_KEY, sdkKey);
656683
listenerResponse.put(RequestParameterKey.NOTIFICATION_TYPE, notificationType);
657684
listenerResponse.put(RequestParameterKey.NOTIFICATION_PAYLOAD, notificationMap);
658685
Map<String, Object> listenerUnmodifiable = Collections.unmodifiableMap(listenerResponse);

android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterSdkPlugin.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
7070
removeNotificationListener(argumentsParser, result);
7171
break;
7272
}
73+
case APIs.CLEAR_NOTIFICATION_LISTENERS:
74+
case APIs.CLEAR_ALL_NOTIFICATION_LISTENERS: {
75+
clearAllNotificationListeners(argumentsParser, result);
76+
break;
77+
}
7378
case APIs.GET_OPTIMIZELY_CONFIG: {
7479
getOptimizelyConfig(argumentsParser, result);
7580
break;

android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,18 @@ public String getSdkKey() {
3131
return (String) arguments.get(Constants.RequestParameterKey.SDK_KEY);
3232
}
3333

34-
public Integer getNotificaitonID() {
34+
public Integer getNotificationID() {
3535
return (Integer) arguments.get(Constants.RequestParameterKey.NOTIFICATION_ID);
3636
}
3737

3838
public String getNotificationType() {
3939
return (String) arguments.get(Constants.RequestParameterKey.NOTIFICATION_TYPE);
4040
}
4141

42+
public List<Integer> getCallBackIds() {
43+
return (List<Integer>) arguments.get(Constants.RequestParameterKey.CALLBACK_IDS);
44+
}
45+
4246
public String getUserId() {
4347
return (String) arguments.get(Constants.RequestParameterKey.USER_ID);
4448
}

android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public static class APIs {
3636
public static final String DECIDE = "decide";
3737
public static final String ADD_NOTIFICATION_LISTENER = "addNotificationListener";
3838
public static final String REMOVE_NOTIFICATION_LISTENER = "removeNotificationListener";
39+
public static final String CLEAR_ALL_NOTIFICATION_LISTENERS = "clearAllNotificationListeners";
40+
public static final String CLEAR_NOTIFICATION_LISTENERS = "clearNotificationListeners";
3941
}
4042

4143
public static class NotificationType {
@@ -52,6 +54,7 @@ public static class RequestParameterKey {
5254
public static final String USER_CONTEXT_ID = "userContextId";
5355
public static final String NOTIFICATION_ID = "id";
5456
public static final String NOTIFICATION_TYPE = "type";
57+
public static final String CALLBACK_IDS = "callbackIds";
5558
public static final String NOTIFICATION_PAYLOAD = "payload";
5659
public static final String ATTRIBUTES = "attributes";
5760
public static final String DECIDE_KEYS = "keys";

android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
import static com.optimizely.ab.notification.DecisionNotification.FeatureVariableDecisionNotificationBuilder.SOURCE_INFO;
2525

2626
import com.google.common.base.CaseFormat;
27+
import com.optimizely.ab.event.LogEvent;
28+
import com.optimizely.ab.notification.ActivateNotification;
29+
import com.optimizely.ab.notification.DecisionNotification;
30+
import com.optimizely.ab.notification.TrackNotification;
31+
import com.optimizely.ab.notification.UpdateConfigNotification;
2732
import com.optimizely.ab.optimizelydecision.OptimizelyDecideOption;
2833

2934
public class Utils {
@@ -60,4 +65,22 @@ public static List<OptimizelyDecideOption> getDecideOptions(List<String> options
6065
}
6166
return convertedOptions;
6267
}
68+
69+
public static Class getNotificationListenerType(String notificationType) {
70+
if (notificationType == null || notificationType.isEmpty()) {
71+
return null;
72+
}
73+
74+
Class listenerClass = null;
75+
switch (notificationType) {
76+
case Constants.NotificationType.ACTIVATE: listenerClass = ActivateNotification.class; break;
77+
case Constants.NotificationType.CONFIG_UPDATE: listenerClass = UpdateConfigNotification.class; break;
78+
case Constants.NotificationType.DECISION: listenerClass = DecisionNotification.class; break;
79+
case Constants.NotificationType.LOG_EVENT: listenerClass = LogEvent.class; break;
80+
case Constants.NotificationType.TRACK: listenerClass = TrackNotification.class; break;
81+
default: {
82+
}
83+
}
84+
return listenerClass;
85+
}
6386
}

example/lib/main.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class _MyAppState extends State<MyApp> {
4949
});
5050

5151
// To add decide listener
52-
var cancelDecideListener =
52+
var decideListenerId =
5353
await flutterSDK.addDecisionNotificationListener((notification) {
5454
print("Parsed decision event ....................");
5555
print(notification.type);
@@ -102,10 +102,10 @@ class _MyAppState extends State<MyApp> {
102102
// variationKey: off
103103

104104
// To cancel decide listener
105-
// cancelDecideListener();
105+
// await flutterSDK.removeNotificationListener(decideListenerId);
106106

107107
// To add track listener
108-
var cancelTrackListener =
108+
var trackListenerID =
109109
await flutterSDK.addTrackNotificationListener((notification) {
110110
print("Parsed track event ....................");
111111
print(notification.attributes);
@@ -114,7 +114,7 @@ class _MyAppState extends State<MyApp> {
114114
});
115115

116116
// To add logEvent listener
117-
var cancelLogEventListener =
117+
var logEventListenerId =
118118
await flutterSDK.addLogEventNotificationListener((notification) {
119119
print("Parsed log event ....................");
120120
print(notification.url);
@@ -131,7 +131,7 @@ class _MyAppState extends State<MyApp> {
131131
});
132132

133133
// To cancel track listener
134-
// cancelTrackListener();
134+
//await flutterSDK.removeNotificationListener(trackListenerID);
135135

136136
if (!mounted) return;
137137
}

ios/Classes/HelperClasses/Constants.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ struct API {
3636
static let close = "close"
3737
static let addNotificationListener = "addNotificationListener"
3838
static let removeNotificationListener = "removeNotificationListener"
39+
static let clearNotificationListeners = "clearNotificationListeners"
40+
static let clearAllNotificationListeners = "clearAllNotificationListeners"
3941
}
4042

4143
struct NotificationType {
@@ -60,6 +62,7 @@ struct RequestParameterKey {
6062
static let userContextId = "userContextId"
6163
static let notificationId = "id"
6264
static let notificationType = "type"
65+
static let callbackIds = "callbackIds"
6366
static let notificationPayload = "payload"
6467
static let attributes = "attributes"
6568
static let decideKeys = "keys"

0 commit comments

Comments
 (0)