From 812e7f66a6e581167f42f77a2027cea780ad9509 Mon Sep 17 00:00:00 2001 From: NomanShoaib Date: Thu, 11 May 2023 04:53:58 +0500 Subject: [PATCH 1/7] Adds native Android implementation for ODP --- android/build.gradle | 2 +- .../OptimizelyFlutterClient.java | 163 ++++++++++++++++-- .../OptimizelyFlutterSdkPlugin.java | 26 ++- .../helper_classes/ArgumentsParser.java | 35 +++- .../helper_classes/Constants.java | 34 +++- .../helper_classes/Utils.java | 23 ++- example/android/build.gradle | 2 +- 7 files changed, 269 insertions(+), 16 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index d707cf2..5fc5ff0 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -77,7 +77,7 @@ dependencies { implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava' implementation group: 'org.slf4j', name: 'slf4j-android', version: '1.7.25' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.10" - implementation "com.optimizely.ab:android-sdk:3.13.2" + implementation "com.optimizely.ab:android-sdk:4.0.0-beta2" implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8' implementation ('com.google.guava:guava:19.0') { exclude group:'com.google.guava', module:'listenablefuture' diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java index 2e3bd69..ff91c16 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2022, Optimizely, Inc. and contributors * + * Copyright 2022-2023, Optimizely, Inc. and contributors * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * @@ -46,6 +46,7 @@ import com.optimizely.ab.notification.NotificationCenter; import com.optimizely.ab.notification.TrackNotification; import com.optimizely.ab.notification.UpdateConfigNotification; +import com.optimizely.ab.odp.ODPSegmentOption; import com.optimizely.ab.optimizelyconfig.OptimizelyConfig; import com.optimizely.ab.optimizelydecision.OptimizelyDecideOption; import com.optimizely.ab.optimizelydecision.OptimizelyDecision; @@ -53,6 +54,11 @@ import com.optimizely.optimizely_flutter_sdk.helper_classes.Utils; import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.*; +import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.DISABLE_ODP; +import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.SEGMENTS_CACHE_SIZE; +import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.SEGMENTS_CACHE_TIMEOUT_IN_SECONDS; +import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.TIMEOUT_FOR_ODP_EVENT_IN_SECONDS; +import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.RequestParameterKey.TIMEOUT_FOR_SEGMENT_FETCH_IN_SECONDS; import static com.optimizely.optimizely_flutter_sdk.helper_classes.Utils.getNotificationListenerType; import java.util.Collections; @@ -127,16 +133,48 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N notificationIdsTracker.remove(sdkKey); List defaultDecideOptions = argumentsParser.getDecideOptions(); + + // SDK Settings Default Values + int segmentsCacheSize = 100; + int segmentsCacheTimeoutInSecs = 600; + int timeoutForSegmentFetchInSecs = 10; + int timeoutForOdpEventInSecs = 10; + boolean disableOdp = false; + Map sdkSettings = argumentsParser.getOptimizelySdkSettings(); + if (sdkSettings != null) { + if (sdkSettings.containsKey(SEGMENTS_CACHE_SIZE)) { + segmentsCacheSize = (Integer) sdkSettings.get(SEGMENTS_CACHE_SIZE); + } + if (sdkSettings.containsKey(SEGMENTS_CACHE_TIMEOUT_IN_SECONDS)) { + segmentsCacheTimeoutInSecs = (Integer) sdkSettings.get(SEGMENTS_CACHE_TIMEOUT_IN_SECONDS); + } + if (sdkSettings.containsKey(TIMEOUT_FOR_SEGMENT_FETCH_IN_SECONDS)) { + timeoutForSegmentFetchInSecs = (Integer) sdkSettings.get(TIMEOUT_FOR_SEGMENT_FETCH_IN_SECONDS); + } + if (sdkSettings.containsKey(TIMEOUT_FOR_ODP_EVENT_IN_SECONDS)) { + timeoutForOdpEventInSecs = (Integer) sdkSettings.get(TIMEOUT_FOR_ODP_EVENT_IN_SECONDS); + } + if (sdkSettings.containsKey(DISABLE_ODP)) { + disableOdp = (boolean) sdkSettings.get(DISABLE_ODP); + } + } // Creating new instance - OptimizelyManager optimizelyManager = OptimizelyManager.builder() + OptimizelyManager.Builder optimizelyManagerBuilder = OptimizelyManager.builder() .withEventProcessor(batchProcessor) .withEventHandler(eventHandler) .withNotificationCenter(notificationCenter) .withDatafileDownloadInterval(datafilePeriodicDownloadInterval, TimeUnit.SECONDS) .withErrorHandler(new RaiseExceptionErrorHandler()) .withDefaultDecideOptions(defaultDecideOptions) - .withSDKKey(sdkKey) - .build(context); + .withODPSegmentCacheSize(segmentsCacheSize) + .withODPSegmentCacheTimeout(segmentsCacheTimeoutInSecs, TimeUnit.SECONDS) + .withTimeoutForODPSegmentFetch(timeoutForSegmentFetchInSecs) + .withTimeoutForODPEventDispatch(timeoutForOdpEventInSecs) + .withSDKKey(sdkKey); + if (disableOdp) { + optimizelyManagerBuilder.withODPDisabled(); + } + OptimizelyManager optimizelyManager = optimizelyManagerBuilder.build(context); optimizelyManager.initialize(context, null, (OptimizelyClient client) -> { if (client.isValid()) { @@ -158,14 +196,14 @@ protected void createUserContext(ArgumentsParser argumentsParser, @NonNull Resul String userId = argumentsParser.getUserId(); Map attributes = argumentsParser.getAttributes(); - if (userId == null) { - result.success(createResponse(ErrorMessage.INVALID_PARAMS)); - return; - } try { String userContextId = Utils.getRandomUUID(); - - OptimizelyUserContext optlyUserContext = optimizelyClient.createUserContext(userId, attributes); + OptimizelyUserContext optlyUserContext; + if (userId != null) { + optlyUserContext = optimizelyClient.createUserContext(userId, attributes); + } else { + optlyUserContext = optimizelyClient.createUserContext(attributes); + } if (optlyUserContext != null) { if (userContextsTracker.containsKey(sdkKey)) { userContextsTracker.get(sdkKey).put(userContextId, optlyUserContext); @@ -390,6 +428,111 @@ protected void removeAllForcedDecisions(ArgumentsParser argumentsParser, @NonNul result.success(createResponse()); } + /// Returns an array of segments that the user is qualified for. + protected void getQualifiedSegments(ArgumentsParser argumentsParser, @NonNull Result result) { + String sdkKey = argumentsParser.getSdkKey(); + OptimizelyUserContext userContext = getUserContext(argumentsParser); + if (!isUserContextValid(sdkKey, userContext, result)) { + return; + } + List qualifiedSegments = userContext.getQualifiedSegments(); + if (qualifiedSegments != null) { + result.success(createResponse(qualifiedSegments)); + } else { + result.success(ErrorMessage.QUALIFIED_SEGMENTS_NOT_FOUND); + } + } + + /// Sets qualified segments for the user context. + protected void setQualifiedSegments(ArgumentsParser argumentsParser, @NonNull Result result) { + String sdkKey = argumentsParser.getSdkKey(); + OptimizelyUserContext userContext = getUserContext(argumentsParser); + if (!isUserContextValid(sdkKey, userContext, result)) { + return; + } + List qualifiedSegments = argumentsParser.getQualifiedSegments(); + if (qualifiedSegments == null) { + result.success(createResponse(ErrorMessage.INVALID_PARAMS)); + return; + } + userContext.setQualifiedSegments(qualifiedSegments); + result.success(createResponse()); + } + + /// Returns the device vuid. + protected void getVuid(ArgumentsParser argumentsParser, @NonNull Result result) { + String sdkKey = argumentsParser.getSdkKey(); + OptimizelyClient optimizelyClient = getOptimizelyClient(sdkKey); + if (!isOptimizelyClientValid(sdkKey, optimizelyClient, result)) { + return; + } + result.success(createResponse(true, optimizelyClient.getVuid(), "")); + } + + /// Checks if the user is qualified for the given segment. + protected void isQualifiedFor(ArgumentsParser argumentsParser, @NonNull Result result) { + String sdkKey = argumentsParser.getSdkKey(); + OptimizelyUserContext userContext = getUserContext(argumentsParser); + if (!isUserContextValid(sdkKey, userContext, result)) { + return; + } + String segment = argumentsParser.getSegment(); + if (segment == null) { + result.success(createResponse(ErrorMessage.INVALID_PARAMS)); + return; + } + + result.success(createResponse(userContext.isQualifiedFor(segment))); + } + + /// Send an event to the ODP server. + protected void sendODPEvent(ArgumentsParser argumentsParser, @NonNull Result result) { + String sdkKey = argumentsParser.getSdkKey(); + OptimizelyClient optimizelyClient = getOptimizelyClient(sdkKey); + if (!isOptimizelyClientValid(sdkKey, optimizelyClient, result)) { + return; + } + String action = argumentsParser.getAction(); + if (action == null) { + result.success(createResponse(ErrorMessage.INVALID_PARAMS)); + return; + } + + String type = argumentsParser.getType(); + Map identifiers = argumentsParser.getIdentifiers(); + if (identifiers == null) { + identifiers = new HashMap<>(); + } + Map data = argumentsParser.getData(); + if (data == null) { + data = new HashMap<>(); + } + + try { + optimizelyClient.sendODPEvent(type, action, identifiers, data); + result.success(createResponse()); + } catch (Exception ex) { + result.success(createResponse(ex.getMessage())); + } + } + + /// Fetch all qualified segments for the user context. + protected void fetchQualifiedSegments(ArgumentsParser argumentsParser, @NonNull Result result) { + String sdkKey = argumentsParser.getSdkKey(); + OptimizelyUserContext userContext = getUserContext(argumentsParser); + if (!isUserContextValid(sdkKey, userContext, result)) { + return; + } + List segmentOptions = argumentsParser.getSegmentOptions(); + + try { + userContext.fetchQualifiedSegments(segmentOptions); + result.success(createResponse()); + } catch (Exception ex) { + result.success(createResponse(ex.getMessage())); + } + } + protected void close(ArgumentsParser argumentsParser, @NonNull Result result) { String sdkKey = argumentsParser.getSdkKey(); OptimizelyClient optimizelyClient = getOptimizelyClient(sdkKey); diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterSdkPlugin.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterSdkPlugin.java index edc49c7..89f787c 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterSdkPlugin.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterSdkPlugin.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2022, Optimizely, Inc. and contributors * + * Copyright 2022-2023, Optimizely, Inc. and contributors * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * @@ -119,6 +119,30 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { removeAllForcedDecisions(argumentsParser, result); break; } + case APIs.GET_QUALIFIED_SEGMENTS: { + getQualifiedSegments(argumentsParser, result); + break; + } + case APIs.SET_QUALIFIED_SEGMENTS: { + setQualifiedSegments(argumentsParser, result); + break; + } + case APIs.GET_VUID: { + getVuid(argumentsParser, result); + break; + } + case APIs.IS_QUALIFIED_FOR: { + isQualifiedFor(argumentsParser, result); + break; + } + case APIs.SEND_ODP_EVENT: { + sendODPEvent(argumentsParser, result); + break; + } + case APIs.FETCH_QUALIFIED_SEGMENTS: { + fetchQualifiedSegments(argumentsParser, result); + break; + } case APIs.CLOSE: { close(argumentsParser, result); break; diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java index d726f21..605b0aa 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2022, Optimizely, Inc. and contributors * + * Copyright 2022-2023, Optimizely, Inc. and contributors * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * @@ -15,6 +15,7 @@ ***************************************************************************/ package com.optimizely.optimizely_flutter_sdk.helper_classes; +import com.optimizely.ab.odp.ODPSegmentOption; import com.optimizely.ab.optimizelydecision.OptimizelyDecideOption; import java.util.List; @@ -110,4 +111,36 @@ public String getDatafileHostPrefix() { public String getExperimentKey() { return (String) arguments.get(Constants.RequestParameterKey.EXPERIMENT_KEY); } + + public List getQualifiedSegments() { + return (List) arguments.get(Constants.RequestParameterKey.QUALIFIED_SEGMENTS); + } + + public String getSegment() { + return (String) arguments.get(Constants.RequestParameterKey.SEGMENT); + } + + public String getAction() { + return (String) arguments.get(Constants.RequestParameterKey.ACTION); + } + + public String getType() { + return (String) arguments.get(Constants.RequestParameterKey.ODP_EVENT_TYPE); + } + + public Map getIdentifiers() { + return (Map) arguments.get(Constants.RequestParameterKey.IDENTIFIERS); + } + + public Map getData() { + return (Map) arguments.get(Constants.RequestParameterKey.DATA); + } + + public List getSegmentOptions() { + return Utils.getSegmentOptions((List) arguments.get(Constants.RequestParameterKey.OPTIMIZELY_SEGMENT_OPTION)); + } + + public Map getOptimizelySdkSettings() { + return (Map) arguments.get(Constants.RequestParameterKey.OPTIMIZELY_SDK_SETTINGS); + } } diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java index 8e1b40b..1919196 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2022, Optimizely, Inc. and contributors * + * Copyright 2022-2023, Optimizely, Inc. and contributors * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * @@ -38,6 +38,16 @@ public static class APIs { public static final String REMOVE_NOTIFICATION_LISTENER = "removeNotificationListener"; public static final String CLEAR_ALL_NOTIFICATION_LISTENERS = "clearAllNotificationListeners"; public static final String CLEAR_NOTIFICATION_LISTENERS = "clearNotificationListeners"; + + // ODP APIs constants + public static final String SEND_ODP_EVENT = "sendOdpEvent"; + public static final String GET_VUID = "getVuid"; + public static final String GET_QUALIFIED_SEGMENTS = "getQualifiedSegments"; + public static final String SET_QUALIFIED_SEGMENTS = "setQualifiedSegments"; + public static final String IS_QUALIFIED_FOR = "isQualifiedFor"; + public static final String FETCH_QUALIFIED_SEGMENTS = "fetchQualifiedSegments"; + + } public static class NotificationType { @@ -71,6 +81,22 @@ public static class RequestParameterKey { public static final String VARIATION_KEY = "variationKey"; public static final String DATAFILE_HOST_PREFIX = "datafileHostPrefix"; public static final String DATAFILE_HOST_SUFFIX = "datafileHostSuffix"; + + public static final String VUID = "vuid"; + public static final String QUALIFIED_SEGMENTS = "qualifiedSegments"; + public static final String SEGMENT = "segment"; + public static final String ACTION = "action"; + public static final String IDENTIFIERS = "identifiers"; + public static final String DATA = "data"; + public static final String ODP_EVENT_TYPE = "type"; + public static final String OPTIMIZELY_SEGMENT_OPTION = "optimizelySegmentOption"; + public static final String OPTIMIZELY_SDK_SETTINGS = "optimizelySdkSettings"; + public static final String SEGMENTS_CACHE_SIZE = "segmentsCacheSize"; + public static final String SEGMENTS_CACHE_TIMEOUT_IN_SECONDS = "segmentsCacheTimeoutInSecs"; + public static final String TIMEOUT_FOR_SEGMENT_FETCH_IN_SECONDS = "timeoutForSegmentFetchInSecs"; + public static final String TIMEOUT_FOR_ODP_EVENT_IN_SECONDS = "timeoutForOdpEventInSecs"; + public static final String DISABLE_ODP = "disableOdp"; + } public static class ErrorMessage { @@ -80,6 +106,7 @@ public static class ErrorMessage { public static final String OPTIMIZELY_CLIENT_NOT_FOUND = "Optimizely client not found."; public static final String USER_CONTEXT_NOT_FOUND = "User context not found."; public static final String USER_CONTEXT_NOT_CREATED = "User context not created."; + public static final String QUALIFIED_SEGMENTS_NOT_FOUND = "Qualified Segments not found."; } public static class DecisionListenerKeys { @@ -124,4 +151,9 @@ public static class DecideOption { public static final String INCLUDE_REASONS = "includeReasons"; public static final String EXCLUDE_VARIABLES = "excludeVariables"; } + + public static class SegmentOption { + public static final String IGNORE_CACHE = "ignoreCache"; + public static final String RESET_CACHE = "resetCache"; + } } diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java index 7a4fb5d..76ec8c8 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2022, Optimizely, Inc. and contributors * + * Copyright 2022-2023, Optimizely, Inc. and contributors * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * @@ -29,6 +29,7 @@ import com.optimizely.ab.notification.DecisionNotification; import com.optimizely.ab.notification.TrackNotification; import com.optimizely.ab.notification.UpdateConfigNotification; +import com.optimizely.ab.odp.ODPSegmentOption; import com.optimizely.ab.optimizelydecision.OptimizelyDecideOption; public class Utils { @@ -66,6 +67,26 @@ public static List getDecideOptions(List options return convertedOptions; } + public static List getSegmentOptions(List options) { + if(options == null || options.isEmpty()) { + return null; + } + List convertedOptions = new ArrayList<>(); + for(String option: options) { + switch(option) { + case Constants.SegmentOption.IGNORE_CACHE: + convertedOptions.add(ODPSegmentOption.IGNORE_CACHE); + break; + case Constants.SegmentOption.RESET_CACHE: + convertedOptions.add(ODPSegmentOption.RESET_CACHE); + break; + default: + break; + } + } + return convertedOptions; + } + public static Class getNotificationListenerType(String notificationType) { if (notificationType == null || notificationType.isEmpty()) { return null; diff --git a/example/android/build.gradle b/example/android/build.gradle index fbba653..57c3218 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -11,7 +11,7 @@ buildscript { } } ext { - android_sdk_version = "3.13.2" + android_sdk_version = "4.0.0-beta2" } allprojects { repositories { From 8d289dbc8e74779d5e36e96a0766dcecdd6bade8 Mon Sep 17 00:00:00 2001 From: NomanShoaib Date: Mon, 15 May 2023 20:50:14 +0500 Subject: [PATCH 2/7] changed minimum sdk version to 21 --- android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.gradle b/android/build.gradle index 5fc5ff0..df5b447 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -34,7 +34,7 @@ apply plugin: 'com.android.library' ext { compile_sdk_version = 32 build_tools_version = "30.0.3" - min_sdk_version = 14 + min_sdk_version = 21 target_sdk_version = 29 } From 830b9c2d79796b80c1cd3a7b9daf2085b57a266d Mon Sep 17 00:00:00 2001 From: NomanShoaib Date: Wed, 17 May 2023 00:31:42 +0500 Subject: [PATCH 3/7] Updated responses --- .../OptimizelyFlutterClient.java | 14 ++++++++------ example/android/app/build.gradle | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java index ff91c16..ddd0da5 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java @@ -437,9 +437,9 @@ protected void getQualifiedSegments(ArgumentsParser argumentsParser, @NonNull Re } List qualifiedSegments = userContext.getQualifiedSegments(); if (qualifiedSegments != null) { - result.success(createResponse(qualifiedSegments)); + result.success(createResponse(Collections.singletonMap(RequestParameterKey.QUALIFIED_SEGMENTS, qualifiedSegments))); } else { - result.success(ErrorMessage.QUALIFIED_SEGMENTS_NOT_FOUND); + result.success(createResponse(ErrorMessage.QUALIFIED_SEGMENTS_NOT_FOUND)); } } @@ -466,7 +466,7 @@ protected void getVuid(ArgumentsParser argumentsParser, @NonNull Result result) if (!isOptimizelyClientValid(sdkKey, optimizelyClient, result)) { return; } - result.success(createResponse(true, optimizelyClient.getVuid(), "")); + result.success(createResponse(true, Collections.singletonMap(RequestParameterKey.VUID, optimizelyClient.getVuid()), "")); } /// Checks if the user is qualified for the given segment. @@ -493,7 +493,7 @@ protected void sendODPEvent(ArgumentsParser argumentsParser, @NonNull Result res return; } String action = argumentsParser.getAction(); - if (action == null) { + if (action == null || action.isEmpty()) { result.success(createResponse(ErrorMessage.INVALID_PARAMS)); return; } @@ -526,8 +526,10 @@ protected void fetchQualifiedSegments(ArgumentsParser argumentsParser, @NonNull List segmentOptions = argumentsParser.getSegmentOptions(); try { - userContext.fetchQualifiedSegments(segmentOptions); - result.success(createResponse()); + userContext.fetchQualifiedSegments((fetchQualifiedResult) -> { + result.success(createResponse(fetchQualifiedResult)); + },segmentOptions); + } catch (Exception ex) { result.success(createResponse(ex.getMessage())); } diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index e643787..ceec9a6 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -39,7 +39,7 @@ android { applicationId "com.optimizely.optimizely_flutter_sdk_example" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName From ab9015249510e27ca0093b0eac2240a3542e0f19 Mon Sep 17 00:00:00 2001 From: NomanShoaib Date: Wed, 17 May 2023 00:44:01 +0500 Subject: [PATCH 4/7] changed branch for testing --- .github/workflows/flutter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index 03fb086..1089da1 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -49,7 +49,7 @@ jobs: env: SDK: android BUILD_NUMBER: ${{ github.run_id }} - TESTAPP_BRANCH: master + TESTAPP_BRANCH: mnoman/androidTestFix GITHUB_TOKEN: ${{ secrets.CI_USER_TOKEN }} EVENT_TYPE: ${{ github.event_name }} REPO_SLUG: 'optimizely/optimizely-flutter-testapp' From b19065832bd038e531452ed0c18f74030581d60d Mon Sep 17 00:00:00 2001 From: NomanShoaib Date: Wed, 17 May 2023 02:29:37 +0500 Subject: [PATCH 5/7] reverting testapp branch change --- .github/workflows/flutter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flutter.yml b/.github/workflows/flutter.yml index 1089da1..03fb086 100644 --- a/.github/workflows/flutter.yml +++ b/.github/workflows/flutter.yml @@ -49,7 +49,7 @@ jobs: env: SDK: android BUILD_NUMBER: ${{ github.run_id }} - TESTAPP_BRANCH: mnoman/androidTestFix + TESTAPP_BRANCH: master GITHUB_TOKEN: ${{ secrets.CI_USER_TOKEN }} EVENT_TYPE: ${{ github.event_name }} REPO_SLUG: 'optimizely/optimizely-flutter-testapp' From 486e6f3f66b934f0deaa20bd110028056b19a7f0 Mon Sep 17 00:00:00 2001 From: NomanShoaib Date: Wed, 17 May 2023 02:35:35 +0500 Subject: [PATCH 6/7] updated readme and minimum support version of android to 21 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5da0c09..eaadfbf 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Refer to the [Flutter SDK's developer documentation](https://docs.developers.opt See the [pubspec.yaml](https://github.com/optimizely/optimizely-flutter-sdk/blob/master/pubspec.yaml) file for Flutter version requirements. -On the Android platform, the SDK requires a minimum SDK version of 14 or higher and compile SDK version of 32. +On the Android platform, the SDK requires a minimum SDK version of 21 or higher and compile SDK version of 32. On the iOS platform, the SDK requires a minimum version of 10.0. From 63cd2acb0a8a4ecf3366af06ca976e88daae719b Mon Sep 17 00:00:00 2001 From: NomanShoaib Date: Fri, 19 May 2023 20:42:14 +0500 Subject: [PATCH 7/7] Removed try cath block from sendodpevent as it was not usefull --- .../optimizely_flutter_sdk/OptimizelyFlutterClient.java | 8 ++------ .../optimizely_flutter_sdk/helper_classes/Constants.java | 3 --- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java index ddd0da5..8d0ca28 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java @@ -508,12 +508,8 @@ protected void sendODPEvent(ArgumentsParser argumentsParser, @NonNull Result res data = new HashMap<>(); } - try { - optimizelyClient.sendODPEvent(type, action, identifiers, data); - result.success(createResponse()); - } catch (Exception ex) { - result.success(createResponse(ex.getMessage())); - } + optimizelyClient.sendODPEvent(type, action, identifiers, data); + result.success(createResponse()); } /// Fetch all qualified segments for the user context. diff --git a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java index 1919196..2f200db 100644 --- a/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java +++ b/android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java @@ -46,8 +46,6 @@ public static class APIs { public static final String SET_QUALIFIED_SEGMENTS = "setQualifiedSegments"; public static final String IS_QUALIFIED_FOR = "isQualifiedFor"; public static final String FETCH_QUALIFIED_SEGMENTS = "fetchQualifiedSegments"; - - } public static class NotificationType { @@ -96,7 +94,6 @@ public static class RequestParameterKey { public static final String TIMEOUT_FOR_SEGMENT_FETCH_IN_SECONDS = "timeoutForSegmentFetchInSecs"; public static final String TIMEOUT_FOR_ODP_EVENT_IN_SECONDS = "timeoutForOdpEventInSecs"; public static final String DISABLE_ODP = "disableOdp"; - } public static class ErrorMessage {