diff --git a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/AndroidTaskExecutor.java b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/AndroidTaskExecutor.java
index b19c204d..e7943679 100644
--- a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/AndroidTaskExecutor.java
+++ b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/AndroidTaskExecutor.java
@@ -6,6 +6,7 @@
import com.launchdarkly.logging.LDLogger;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
@@ -15,12 +16,22 @@
* Standard implementation of {@link TaskExecutor} for use in the Android environment. Besides
* enforcing correct thread usage, this class also ensures that any unchecked exceptions thrown by
* asynchronous tasks are caught and logged.
+ *
T throwExceptionIfNull(T o) {
if (o == null) {
throw new IllegalStateException(
diff --git a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ConnectionMode.java b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ConnectionMode.java
new file mode 100644
index 00000000..a256ec96
--- /dev/null
+++ b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ConnectionMode.java
@@ -0,0 +1,39 @@
+package com.launchdarkly.sdk.android;
+
+/**
+ * Enumerates the built-in FDv2 connection modes. Each mode maps to a
+ * {@link ModeDefinition} that specifies which initializers and synchronizers
+ * are active when the SDK is operating in that mode.
+ *
+ * Not to be confused with {@link ConnectionInformation.ConnectionMode}, which
+ * is the public FDv1 enum representing the SDK's current connection state
+ * (e.g. POLLING, STREAMING, SET_OFFLINE). This class is an internal FDv2
+ * concept describing the desired data-acquisition pipeline.
+ *
+ * This is a closed enum — custom connection modes (spec 5.3.5 TBD) are not
+ * supported in this release.
+ *
+ * Package-private — not part of the public SDK API.
+ *
+ * @see ModeDefinition
+ * @see ModeResolutionTable
+ */
+final class ConnectionMode {
+
+ static final ConnectionMode STREAMING = new ConnectionMode("streaming");
+ static final ConnectionMode POLLING = new ConnectionMode("polling");
+ static final ConnectionMode OFFLINE = new ConnectionMode("offline");
+ static final ConnectionMode ONE_SHOT = new ConnectionMode("one-shot");
+ static final ConnectionMode BACKGROUND = new ConnectionMode("background");
+
+ private final String name;
+
+ private ConnectionMode(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
diff --git a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ConnectivityManager.java b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ConnectivityManager.java
index 22b09e23..d15dda4b 100644
--- a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ConnectivityManager.java
+++ b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ConnectivityManager.java
@@ -6,7 +6,6 @@
import com.launchdarkly.logging.LogValues;
import com.launchdarkly.sdk.LDContext;
import com.launchdarkly.sdk.android.subsystems.Callback;
-import com.launchdarkly.sdk.android.DataModel;
import com.launchdarkly.sdk.fdv2.ChangeSet;
import com.launchdarkly.sdk.android.subsystems.ClientContext;
import com.launchdarkly.sdk.android.subsystems.ComponentConfigurer;
@@ -15,7 +14,7 @@
import com.launchdarkly.sdk.android.subsystems.DataSourceUpdateSink;
import com.launchdarkly.sdk.android.subsystems.DataSourceUpdateSinkV2;
import com.launchdarkly.sdk.android.subsystems.EventProcessor;
-import com.launchdarkly.sdk.fdv2.Selector;
+import com.launchdarkly.sdk.android.subsystems.TransactionalDataStore;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -25,8 +24,6 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
-import static com.launchdarkly.sdk.android.ConnectionInformation.ConnectionMode;
-
class ConnectivityManager {
// Implementation notes:
//
@@ -60,6 +57,7 @@ class ConnectivityManager {
private final ConnectionInformationState connectionInformation;
private final PersistentDataStoreWrapper.PerEnvironmentData environmentStore;
private final EventProcessor eventProcessor;
+ private final TransactionalDataStore transactionalDataStore;
private final PlatformState.ForegroundChangeListener foregroundListener;
private final PlatformState.ConnectivityChangeListener connectivityChangeListener;
private final TaskExecutor taskExecutor;
@@ -74,6 +72,8 @@ class ConnectivityManager {
private final AtomicReference previouslyInBackground = new AtomicReference<>();
private final LDLogger logger;
private volatile boolean initialized = false;
+ private final boolean useFDv2ModeResolution;
+ private volatile ConnectionMode currentFDv2Mode;
// The DataSourceUpdateSinkImpl receives flag updates and status updates from the DataSource.
// This has two purposes: 1. to decouple the data source implementation from the details of how
@@ -105,7 +105,7 @@ public void apply(@NonNull LDContext context, @NonNull ChangeSet