• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

optimizely / optimizely-flutter-sdk / 12072954613

28 Nov 2024 04:55PM CUT coverage: 84.898%. Remained the same
12072954613

push

github

web-flow
chore: version updated (#79)

624 of 735 relevant lines covered (84.9%)

1.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.23
/lib/src/optimizely_client_wrapper.dart
1
/// **************************************************************************
2
/// Copyright 2022-2023, Optimizely, Inc. and contributors                   *
3
///                                                                          *
4
/// Licensed under the Apache License, Version 2.0 (the "License");          *
5
/// you may not use this file except in compliance with the License.         *
6
/// You may obtain a copy of the License at                                  *
7
///                                                                          *
8
///    http://www.apache.org/licenses/LICENSE-2.0                            *
9
///                                                                          *
10
/// Unless required by applicable law or agreed to in writing, software      *
11
/// distributed under the License is distributed on an "AS IS" BASIS,        *
12
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13
/// See the License for the specific language governing permissions and      *
14
/// limitations under the License.                                           *
15
///**************************************************************************/
16

17
import 'dart:async';
18
import 'package:flutter/foundation.dart';
19
import 'package:flutter/services.dart';
20
import 'package:optimizely_flutter_sdk/optimizely_flutter_sdk.dart';
21
import 'package:optimizely_flutter_sdk/package_info.dart';
22
import 'package:optimizely_flutter_sdk/src/data_objects/activate_listener_response.dart';
23
import 'package:optimizely_flutter_sdk/src/data_objects/activate_response.dart';
24
import 'package:optimizely_flutter_sdk/src/data_objects/base_response.dart';
25
import 'package:optimizely_flutter_sdk/src/data_objects/get_variation_response.dart';
26
import 'package:optimizely_flutter_sdk/src/data_objects/get_vuid_response.dart';
27
import 'package:optimizely_flutter_sdk/src/data_objects/optimizely_config_response.dart';
28
import 'package:optimizely_flutter_sdk/src/utils/constants.dart';
29
import 'package:optimizely_flutter_sdk/src/utils/utils.dart';
30

31
enum ListenerType { activate, track, decision, logEvent, projectConfigUpdate }
32

33
enum ClientPlatform { iOS, android }
34

35
typedef ActivateNotificationCallback = void Function(
36
    ActivateListenerResponse msg);
37
typedef DecisionNotificationCallback = void Function(
38
    DecisionListenerResponse msg);
39
typedef TrackNotificationCallback = void Function(TrackListenerResponse msg);
40
typedef LogEventNotificationCallback = void Function(
41
    LogEventListenerResponse msg);
42
typedef MultiUseCallback = void Function(dynamic msg);
43

44
/// The internal client class for the Optimizely Flutter SDK used by the main OptimizelyFlutterSdk class.
45
class OptimizelyClientWrapper {
46
  static const MethodChannel _channel = MethodChannel('optimizely_flutter_sdk');
47
  static int nextCallbackId = 0;
48
  static Map<String, Map<int, ActivateNotificationCallback>>
49
      activateCallbacksById = {};
3✔
50
  static Map<String, Map<int, DecisionNotificationCallback>>
51
      decisionCallbacksById = {};
1✔
52
  static Map<String, Map<int, TrackNotificationCallback>> trackCallbacksById =
1✔
53
      {};
×
54
  static Map<String, Map<int, LogEventNotificationCallback>>
55
      logEventCallbacksById = {};
1✔
56
  static Map<String, Map<int, MultiUseCallback>> configUpdateCallbacksById = {};
1✔
57

58
  /// Starts Optimizely SDK (Synchronous) with provided sdkKey and options.
59
  static Future<BaseResponse> initializeClient(
1✔
60
      String sdkKey,
61
      EventOptions eventOptions,
62
      int datafilePeriodicDownloadInterval,
63
      Map<ClientPlatform, DatafileHostOptions> datafileHostOptions,
64
      Set<OptimizelyDecideOption> defaultDecideOptions,
65
      OptimizelyLogLevel defaultLogLevel,
66
      SDKSettings sdkSettings) async {
67
    _channel.setMethodCallHandler(methodCallHandler);
1✔
68
    final convertedOptions = Utils.convertDecideOptions(defaultDecideOptions);
1✔
69
    final convertedLogLevel = Utils.convertLogLevel(defaultLogLevel);
1✔
70
    const sdkVersion = PackageInfo.version;
71

72
    Map<String, dynamic> requestDict = {
1✔
73
      Constants.sdkKey: sdkKey,
74
      Constants.sdkVersion: sdkVersion,
75
      Constants.datafilePeriodicDownloadInterval:
76
          datafilePeriodicDownloadInterval,
77
      Constants.optimizelyDecideOption: convertedOptions,
78
      Constants.defaultLogLevel: convertedLogLevel,
79
      Constants.eventBatchSize: eventOptions.batchSize,
1✔
80
      Constants.eventTimeInterval: eventOptions.timeInterval,
1✔
81
      Constants.eventMaxQueueSize: eventOptions.maxQueueSize,
1✔
82
    };
83

84
    // Odp Request params
85
    Map<String, dynamic> optimizelySdkSettings = {
1✔
86
      Constants.segmentsCacheSize: sdkSettings.segmentsCacheSize,
1✔
87
      Constants.segmentsCacheTimeoutInSecs:
88
          sdkSettings.segmentsCacheTimeoutInSecs,
1✔
89
      Constants.timeoutForSegmentFetchInSecs:
90
          sdkSettings.timeoutForSegmentFetchInSecs,
1✔
91
      Constants.timeoutForOdpEventInSecs: sdkSettings.timeoutForOdpEventInSecs,
1✔
92
      Constants.disableOdp: sdkSettings.disableOdp,
1✔
93
      Constants.enableVuid: sdkSettings.enableVuid,
1✔
94
    };
95
    requestDict[Constants.optimizelySdkSettings] = optimizelySdkSettings;
1✔
96

97
    // clearing notification listeners, if they are mapped to the same sdkKey.
98
    activateCallbacksById.remove(sdkKey);
2✔
99
    decisionCallbacksById.remove(sdkKey);
2✔
100
    trackCallbacksById.remove(sdkKey);
2✔
101
    logEventCallbacksById.remove(sdkKey);
2✔
102
    configUpdateCallbacksById.remove(sdkKey);
2✔
103

104
    datafileHostOptions.forEach((platform, datafileoptions) {
2✔
105
      // Pass datafile host only if non empty value for current platform is provided
106
      if (platform.name == defaultTargetPlatform.name &&
4✔
107
          datafileoptions.datafileHostPrefix.isNotEmpty &&
2✔
108
          datafileoptions.datafileHostSuffix.isNotEmpty) {
2✔
109
        requestDict[Constants.datafileHostPrefix] =
1✔
110
            datafileoptions.datafileHostPrefix;
1✔
111
        requestDict[Constants.datafileHostSuffix] =
1✔
112
            datafileoptions.datafileHostSuffix;
1✔
113
      }
114
    });
115

116
    final result = Map<String, dynamic>.from(
1✔
117
        await _channel.invokeMethod(Constants.initializeMethod, requestDict));
1✔
118
    return BaseResponse(result);
1✔
119
  }
120

121
  /// Use the activate method to start an experiment.
122
  ///  The activate call will conditionally activate an experiment for a user based on the provided experiment key and a randomized hash of the provided user ID.
123
  ///  If the user satisfies audience conditions for the experiment and the experiment is valid and running, the function returns the variation the user is bucketed into.
124
  ///  Otherwise, activate returns empty variationKey. Make sure that your code adequately deals with the case when the experiment is not activated (e.g. execute the default variation).
125
  static Future<ActivateResponse> activate(
1✔
126
      String sdkKey, String experimentKey, String userId,
127
      [Map<String, dynamic> attributes = const {}]) async {
128
    final result = Map<String, dynamic>.from(
1✔
129
        await _channel.invokeMethod(Constants.activate, {
2✔
130
      Constants.sdkKey: sdkKey,
131
      Constants.experimentKey: experimentKey,
132
      Constants.userId: userId,
133
      Constants.attributes: Utils.convertToTypedMap(attributes)
1✔
134
    }));
135
    return ActivateResponse(result);
1✔
136
  }
137

138
  /// Get variation for experiment and user ID with user attributes.
139
  static Future<GetVariationResponse> getVariation(
1✔
140
      String sdkKey, String experimentKey, String userId,
141
      [Map<String, dynamic> attributes = const {}]) async {
142
    final result = Map<String, dynamic>.from(
1✔
143
        await _channel.invokeMethod(Constants.getVariation, {
2✔
144
      Constants.sdkKey: sdkKey,
145
      Constants.experimentKey: experimentKey,
146
      Constants.userId: userId,
147
      Constants.attributes: Utils.convertToTypedMap(attributes)
1✔
148
    }));
149
    return GetVariationResponse(result);
1✔
150
  }
151

152
  /// Get forced variation for experiment and user ID.
153
  static Future<GetVariationResponse> getForcedVariation(
1✔
154
      String sdkKey, String experimentKey, String userId) async {
155
    final result = Map<String, dynamic>.from(
1✔
156
        await _channel.invokeMethod(Constants.getForcedVariation, {
2✔
157
      Constants.sdkKey: sdkKey,
158
      Constants.experimentKey: experimentKey,
159
      Constants.userId: userId,
160
    }));
161
    return GetVariationResponse(result);
1✔
162
  }
163

164
  /// Set forced variation for experiment and user ID to variationKey.
165
  static Future<BaseResponse> setForcedVariation(
1✔
166
      String sdkKey, String experimentKey, String userId,
167
      [String variationKey = ""]) async {
168
    Map<String, dynamic> request = {
1✔
169
      Constants.sdkKey: sdkKey,
170
      Constants.experimentKey: experimentKey,
171
      Constants.userId: userId,
172
    };
173
    if (variationKey != "") {
1✔
174
      request[Constants.variationKey] = variationKey;
1✔
175
    }
176
    final result = Map<String, dynamic>.from(
1✔
177
        await _channel.invokeMethod(Constants.setForcedVariation, request));
1✔
178
    return BaseResponse(result);
1✔
179
  }
180

181
  /// Returns a snapshot of the current project configuration.
182
  static Future<OptimizelyConfigResponse> getOptimizelyConfig(
1✔
183
      String sdkKey) async {
184
    final result = Map<String, dynamic>.from(await _channel.invokeMethod(
2✔
185
        Constants.getOptimizelyConfigMethod, {Constants.sdkKey: sdkKey}));
1✔
186
    return OptimizelyConfigResponse(result);
1✔
187
  }
188

189
  /// Send an event to the ODP server.
190
  static Future<BaseResponse> sendOdpEvent(String sdkKey, String action,
1✔
191
      {String? type,
192
      Map<String, String> identifiers = const {},
193
      Map<String, dynamic> data = const {}}) async {
194
    Map<String, dynamic> request = {
1✔
195
      Constants.sdkKey: sdkKey,
196
      Constants.action: action,
197
      Constants.identifiers: identifiers,
198
      Constants.data: Utils.convertToTypedMap(data)
1✔
199
    };
200
    if (type != null) {
201
      request[Constants.type] = type;
1✔
202
    }
203

204
    final result = Map<String, dynamic>.from(
1✔
205
        await _channel.invokeMethod(Constants.sendOdpEventMethod, request));
1✔
206
    return BaseResponse(result);
1✔
207
  }
208

209
  /// Returns the device vuid (read only)
210
  static Future<GetVuidResponse> getVuid(String sdkKey) async {
1✔
211
    final result = Map<String, dynamic>.from(
1✔
212
        await _channel.invokeMethod(Constants.getVuidMethod, {
2✔
213
      Constants.sdkKey: sdkKey,
214
    }));
215
    return GetVuidResponse(result);
1✔
216
  }
217

218
  /// Remove notification listener by notification id.
219
  static Future<BaseResponse> removeNotificationListener(
1✔
220
      String sdkKey, int id) async {
221
    Map<String, dynamic> request = {Constants.sdkKey: sdkKey, Constants.id: id};
1✔
222

223
    activateCallbacksById[sdkKey]?.remove(id);
3✔
224
    decisionCallbacksById[sdkKey]?.remove(id);
3✔
225
    logEventCallbacksById[sdkKey]?.remove(id);
3✔
226
    configUpdateCallbacksById[sdkKey]?.remove(id);
3✔
227
    trackCallbacksById[sdkKey]?.remove(id);
3✔
228

229
    final result = Map<String, dynamic>.from(await _channel.invokeMethod(
2✔
230
        Constants.removeNotificationListenerMethod, request));
231
    return BaseResponse(result);
1✔
232
  }
233

234
  /// Remove notification listeners by notification type.
235
  static Future<BaseResponse> clearNotificationListeners(
1✔
236
      String sdkKey, ListenerType listenerType) async {
237
    var callbackIds = _clearAllCallbacks(sdkKey, listenerType);
1✔
238
    Map<String, dynamic> request = {
1✔
239
      Constants.sdkKey: sdkKey,
240
      Constants.type: listenerType.name,
1✔
241
      Constants.callbackIds: callbackIds
242
    };
243
    final result = Map<String, dynamic>.from(await _channel.invokeMethod(
2✔
244
        Constants.clearNotificationListenersMethod, request));
245
    return BaseResponse(result);
1✔
246
  }
247

248
  /// Removes all notification listeners.
249
  static Future<BaseResponse> clearAllNotificationListeners(
1✔
250
      String sdkKey) async {
251
    var callbackIds = _clearAllCallbacks(sdkKey);
1✔
252
    Map<String, dynamic> request = {
1✔
253
      Constants.sdkKey: sdkKey,
254
      Constants.callbackIds: callbackIds
255
    };
256
    final result = Map<String, dynamic>.from(await _channel.invokeMethod(
2✔
257
        Constants.clearAllNotificationListenersMethod, request));
258
    return BaseResponse(result);
1✔
259
  }
260

261
  /// Returns a success true if optimizely client closed successfully.
262
  static Future<BaseResponse> close(String sdkKey) async {
1✔
263
    final result = Map<String, dynamic>.from(await _channel
1✔
264
        .invokeMethod(Constants.close, {Constants.sdkKey: sdkKey}));
2✔
265
    return BaseResponse(result);
1✔
266
  }
267

268
  /// Creates a context of the user for which decision APIs will be called.
269
  ///
270
  /// A user context will only be created successfully when the SDK is fully configured using initializeClient.
271
  static Future<OptimizelyUserContext?> createUserContext(String sdkKey,
1✔
272
      {String? userId, Map<String, dynamic> attributes = const {}}) async {
273
    Map<String, dynamic> request = {
1✔
274
      Constants.sdkKey: sdkKey,
275
      Constants.attributes: Utils.convertToTypedMap(attributes)
1✔
276
    };
277
    if (userId != null) {
278
      request[Constants.userId] = userId;
1✔
279
    }
280
    final result = Map<String, dynamic>.from(await _channel.invokeMethod(
2✔
281
        Constants.createUserContextMethod, request));
282

283
    if (result[Constants.responseSuccess] == true) {
2✔
284
      final response =
285
          Map<String, dynamic>.from(result[Constants.responseResult]);
2✔
286
      return OptimizelyUserContext(
1✔
287
          sdkKey, response[Constants.userContextId], _channel);
1✔
288
    }
289
    return null;
290
  }
291

292
  static List<int> _clearAllCallbacks(String sdkKey,
1✔
293
      [ListenerType? listenerType]) {
294
    var callbackIds = <int>[];
1✔
295
    if (listenerType == null || listenerType == ListenerType.activate) {
1✔
296
      if (activateCallbacksById.containsKey(sdkKey)) {
2✔
297
        callbackIds.addAll(activateCallbacksById[sdkKey]!.keys);
4✔
298
        activateCallbacksById[sdkKey]!.clear();
3✔
299
      }
300
    }
301
    if (listenerType == null || listenerType == ListenerType.decision) {
1✔
302
      if (decisionCallbacksById.containsKey(sdkKey)) {
2✔
303
        callbackIds.addAll(decisionCallbacksById[sdkKey]!.keys);
4✔
304
        decisionCallbacksById[sdkKey]!.clear();
3✔
305
      }
306
    }
307
    if (listenerType == null || listenerType == ListenerType.logEvent) {
1✔
308
      if (logEventCallbacksById.containsKey(sdkKey)) {
2✔
309
        callbackIds.addAll(logEventCallbacksById[sdkKey]!.keys);
4✔
310
        logEventCallbacksById[sdkKey]!.clear();
3✔
311
      }
312
    }
313
    if (listenerType == null ||
314
        listenerType == ListenerType.projectConfigUpdate) {
1✔
315
      if (configUpdateCallbacksById.containsKey(sdkKey)) {
2✔
316
        callbackIds.addAll(configUpdateCallbacksById[sdkKey]!.keys);
4✔
317
        configUpdateCallbacksById[sdkKey]!.clear();
3✔
318
      }
319
    }
320
    if (listenerType == null || listenerType == ListenerType.track) {
1✔
321
      if (trackCallbacksById.containsKey(sdkKey)) {
2✔
322
        callbackIds.addAll(trackCallbacksById[sdkKey]!.keys);
4✔
323
        trackCallbacksById[sdkKey]!.clear();
3✔
324
      }
325
    }
326
    return callbackIds;
327
  }
328

329
  static bool checkCallBackExist(String sdkKey, dynamic callback) {
1✔
330
    if (activateCallbacksById.containsKey(sdkKey)) {
2✔
331
      for (var k in activateCallbacksById[sdkKey]!.keys) {
4✔
332
        if (activateCallbacksById[sdkKey]![k] == callback) {
4✔
333
          return true;
334
        }
335
      }
336
    }
337
    if (decisionCallbacksById.containsKey(sdkKey)) {
2✔
338
      for (var k in decisionCallbacksById[sdkKey]!.keys) {
4✔
339
        if (decisionCallbacksById[sdkKey]![k] == callback) {
4✔
340
          return true;
341
        }
342
      }
343
    }
344
    if (trackCallbacksById.containsKey(sdkKey)) {
2✔
345
      for (var k in trackCallbacksById[sdkKey]!.keys) {
4✔
346
        if (trackCallbacksById[sdkKey]![k] == callback) {
4✔
347
          return true;
348
        }
349
      }
350
    }
351
    if (logEventCallbacksById.containsKey(sdkKey)) {
2✔
352
      for (var k in logEventCallbacksById[sdkKey]!.keys) {
4✔
353
        if (logEventCallbacksById[sdkKey]![k] == callback) {
4✔
354
          return true;
355
        }
356
      }
357
    }
358
    if (configUpdateCallbacksById.containsKey(sdkKey)) {
2✔
359
      for (var k in configUpdateCallbacksById[sdkKey]!.keys) {
4✔
360
        if (configUpdateCallbacksById[sdkKey]![k] == callback) {
4✔
361
          return true;
362
        }
363
      }
364
    }
365
    return false;
366
  }
367

368
  static Future<int> addActivateNotificationListener(
1✔
369
      String sdkKey, ActivateNotificationCallback callback) async {
370
    _channel.setMethodCallHandler(methodCallHandler);
1✔
371

372
    if (checkCallBackExist(sdkKey, callback)) {
1✔
373
      // ignore: avoid_print
374
      print("callback already exists.");
1✔
375
      return -1;
1✔
376
    }
377

378
    int currentListenerId = nextCallbackId++;
1✔
379
    activateCallbacksById.putIfAbsent(sdkKey, () => {});
4✔
380
    activateCallbacksById[sdkKey]?[currentListenerId] = callback;
3✔
381
    final listenerTypeStr = ListenerType.activate.name;
1✔
382
    await _channel.invokeMethod(Constants.addNotificationListenerMethod, {
2✔
383
      Constants.sdkKey: sdkKey,
384
      Constants.id: currentListenerId,
385
      Constants.type: listenerTypeStr
386
    });
387
    // Returning an id that allows the user to remove the added notification listener.
388
    return currentListenerId;
389
  }
390

391
  static Future<int> addDecisionNotificationListener(
1✔
392
      String sdkKey, DecisionNotificationCallback callback) async {
393
    _channel.setMethodCallHandler(methodCallHandler);
1✔
394

395
    if (checkCallBackExist(sdkKey, callback)) {
1✔
396
      // ignore: avoid_print
397
      print("callback already exists.");
×
398
      return -1;
×
399
    }
400

401
    int currentListenerId = nextCallbackId++;
1✔
402
    decisionCallbacksById.putIfAbsent(sdkKey, () => {});
4✔
403
    decisionCallbacksById[sdkKey]?[currentListenerId] = callback;
3✔
404
    final listenerTypeStr = ListenerType.decision.name;
1✔
405
    await _channel.invokeMethod(Constants.addNotificationListenerMethod, {
2✔
406
      Constants.sdkKey: sdkKey,
407
      Constants.id: currentListenerId,
408
      Constants.type: listenerTypeStr
409
    });
410
    // Returning an id that allows the user to remove the added notification listener
411
    return currentListenerId;
412
  }
413

414
  static Future<int> addTrackNotificationListener(
1✔
415
      String sdkKey, TrackNotificationCallback callback) async {
416
    _channel.setMethodCallHandler(methodCallHandler);
1✔
417

418
    if (checkCallBackExist(sdkKey, callback)) {
1✔
419
      // ignore: avoid_print
420
      print("callback already exists.");
1✔
421
      return -1;
1✔
422
    }
423

424
    int currentListenerId = nextCallbackId++;
1✔
425
    trackCallbacksById.putIfAbsent(sdkKey, () => {});
4✔
426
    trackCallbacksById[sdkKey]?[currentListenerId] = callback;
3✔
427
    final listenerTypeStr = ListenerType.track.name;
1✔
428
    await _channel.invokeMethod(Constants.addNotificationListenerMethod, {
2✔
429
      Constants.sdkKey: sdkKey,
430
      Constants.id: currentListenerId,
431
      Constants.type: listenerTypeStr
432
    });
433
    // Returning an id that allows the user to remove the added notification listener
434
    return currentListenerId;
435
  }
436

437
  static Future<int> addLogEventNotificationListener(
1✔
438
      String sdkKey, LogEventNotificationCallback callback) async {
439
    _channel.setMethodCallHandler(methodCallHandler);
1✔
440

441
    if (checkCallBackExist(sdkKey, callback)) {
1✔
442
      // ignore: avoid_print
443
      print("callback already exists.");
1✔
444
      return -1;
1✔
445
    }
446

447
    int currentListenerId = nextCallbackId++;
1✔
448
    logEventCallbacksById.putIfAbsent(sdkKey, () => {});
4✔
449
    logEventCallbacksById[sdkKey]?[currentListenerId] = callback;
3✔
450
    final listenerTypeStr = ListenerType.logEvent.name;
1✔
451
    await _channel.invokeMethod(Constants.addNotificationListenerMethod, {
2✔
452
      Constants.sdkKey: sdkKey,
453
      Constants.id: currentListenerId,
454
      Constants.type: listenerTypeStr
455
    });
456
    // Returning an id that allows the user to remove the added notification listener
457
    return currentListenerId;
458
  }
459

460
  /// Allows user to listen to supported notifications.
461
  static Future<int> addConfigUpdateNotificationListener(
1✔
462
      String sdkKey, MultiUseCallback callback) async {
463
    _channel.setMethodCallHandler(methodCallHandler);
1✔
464

465
    if (checkCallBackExist(sdkKey, callback)) {
1✔
466
      // ignore: avoid_print
467
      print("callback already exists.");
1✔
468
      return -1;
1✔
469
    }
470

471
    int currentListenerId = nextCallbackId++;
1✔
472
    configUpdateCallbacksById.putIfAbsent(sdkKey, () => {});
4✔
473
    configUpdateCallbacksById[sdkKey]?[currentListenerId] = callback;
3✔
474
    final listenerTypeStr = ListenerType.projectConfigUpdate.name;
1✔
475
    await _channel.invokeMethod(Constants.addNotificationListenerMethod, {
2✔
476
      Constants.sdkKey: sdkKey,
477
      Constants.id: currentListenerId,
478
      Constants.type: listenerTypeStr
479
    });
480
    // Returning an id that allows the user to remove the added notification listener
481
    return currentListenerId;
482
  }
483

484
  static Future<void> methodCallHandler(MethodCall call) async {
1✔
485
    final id = call.arguments[Constants.id];
2✔
486
    final sdkKey = call.arguments[Constants.sdkKey];
2✔
487
    final payload = call.arguments[Constants.payload];
2✔
488
    if (id is int && payload != null) {
1✔
489
      switch (call.method) {
1✔
490
        case Constants.activateCallBackListener:
1✔
491
          final response =
492
              ActivateListenerResponse(Map<String, dynamic>.from(payload));
2✔
493
          if (activateCallbacksById.containsKey(sdkKey) &&
2✔
494
              activateCallbacksById[sdkKey]!.containsKey(id)) {
3✔
495
            activateCallbacksById[sdkKey]![id]!(response);
4✔
496
          }
497
          break;
498
        case Constants.decisionCallBackListener:
1✔
499
          final response =
500
              DecisionListenerResponse(Map<String, dynamic>.from(payload));
2✔
501
          if (decisionCallbacksById.containsKey(sdkKey) &&
2✔
502
              decisionCallbacksById[sdkKey]!.containsKey(id)) {
3✔
503
            decisionCallbacksById[sdkKey]![id]!(response);
4✔
504
          }
505
          break;
506
        case Constants.trackCallBackListener:
1✔
507
          final response =
508
              TrackListenerResponse(Map<String, dynamic>.from(payload));
2✔
509
          if (trackCallbacksById.containsKey(sdkKey) &&
2✔
510
              trackCallbacksById[sdkKey]!.containsKey(id)) {
3✔
511
            trackCallbacksById[sdkKey]![id]!(response);
4✔
512
          }
513
          break;
514
        case Constants.logEventCallbackListener:
1✔
515
          final response =
516
              LogEventListenerResponse(Map<String, dynamic>.from(payload));
2✔
517
          if (logEventCallbacksById.containsKey(sdkKey) &&
2✔
518
              logEventCallbacksById[sdkKey]!.containsKey(id)) {
3✔
519
            logEventCallbacksById[sdkKey]![id]!(response);
4✔
520
          }
521
          break;
522
        case Constants.configUpdateCallBackListener:
1✔
523
          if (configUpdateCallbacksById.containsKey(sdkKey) &&
2✔
524
              configUpdateCallbacksById[sdkKey]!.containsKey(id)) {
3✔
525
            configUpdateCallbacksById[sdkKey]![id]!(payload);
4✔
526
          }
527
          break;
528
        default:
529
          // ignore: avoid_print
530
          print('Method ${call.method} not implemented.');
×
531
      }
532
    }
533
  }
534
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc