diff --git a/.travis.yml b/.travis.yml
index 725a96a9e..d5b72d494 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,5 +25,5 @@ before_script:
- adb shell input keyevent 82 &
script:
- ./gradlew cleanAllModules
- - ./gradlew testAllModules
+ - ./gradlew testAllModulesTravis
- if [[ -n $TRAVIS_TAG ]]; then ./gradlew ship; fi
\ No newline at end of file
diff --git a/android-sdk/src/main/java/com/optimizely/ab/android/sdk/OptimizelyManager.java b/android-sdk/src/main/java/com/optimizely/ab/android/sdk/OptimizelyManager.java
index 02a4895a6..af05b6575 100644
--- a/android-sdk/src/main/java/com/optimizely/ab/android/sdk/OptimizelyManager.java
+++ b/android-sdk/src/main/java/com/optimizely/ab/android/sdk/OptimizelyManager.java
@@ -89,6 +89,16 @@ public class OptimizelyManager {
this.logger = logger;
}
+ @NonNull
+ public Long getDataFileDownloadInterval() {
+ return dataFileDownloadInterval;
+ }
+
+ @NonNull
+ public TimeUnit getDataFileDownloadIntervalTimeUnit() {
+ return dataFileDownloadIntervalTimeUnit;
+ }
+
/**
* Returns the {@link OptimizelyManager} builder
*
@@ -606,6 +616,14 @@ public Builder withDataFileDownloadInterval(long interval, @NonNull TimeUnit tim
public OptimizelyManager build() {
final Logger logger = LoggerFactory.getLogger(OptimizelyManager.class);
+ // AlarmManager doesn't allow intervals less than 60 seconds
+ if (dataFileDownloadIntervalTimeUnit.toMillis(dataFileDownloadInterval) < (60 * 1000)) {
+ dataFileDownloadIntervalTimeUnit = TimeUnit.SECONDS;
+ dataFileDownloadInterval = 60L;
+ logger.warn("Minimum datafile polling interval is 60 seconds. " +
+ "Defaulting to 60 seconds.");
+ }
+
return new OptimizelyManager(projectId,
eventHandlerDispatchInterval,
eventHandlerDispatchIntervalTimeUnit,
diff --git a/android-sdk/src/test/java/com/optimizely/ab/android/sdk/OptimizelyManagerBuilderTest.java b/android-sdk/src/test/java/com/optimizely/ab/android/sdk/OptimizelyManagerBuilderTest.java
new file mode 100644
index 000000000..e4e9e4cfe
--- /dev/null
+++ b/android-sdk/src/test/java/com/optimizely/ab/android/sdk/OptimizelyManagerBuilderTest.java
@@ -0,0 +1,57 @@
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
+
+package com.optimizely.ab.android.sdk;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.concurrent.TimeUnit;
+
+import static junit.framework.Assert.assertEquals;
+
+@RunWith(MockitoJUnitRunner.class)
+public class OptimizelyManagerBuilderTest {
+
+ /**
+ * Verify that building the {@link OptimizelyManager} with a polling interval less than 60
+ * seconds defaults to 60 seconds.
+ */
+ @Test
+ public void testBuildWithInvalidPollingInterval() {
+ OptimizelyManager manager = OptimizelyManager.builder("1")
+ .withDataFileDownloadInterval(5, TimeUnit.SECONDS)
+ .build();
+
+ assertEquals(60L, manager.getDataFileDownloadInterval().longValue());
+ assertEquals(TimeUnit.SECONDS, manager.getDataFileDownloadIntervalTimeUnit());
+ }
+
+ /**
+ * Verify that building the {@link OptimizelyManager} with a polling interval greater than 60
+ * seconds is properly registered.
+ */
+ @Test
+ public void testBuildWithValidPollingInterval() {
+ OptimizelyManager manager = OptimizelyManager.builder("1")
+ .withDataFileDownloadInterval(61, TimeUnit.SECONDS)
+ .build();
+
+ assertEquals(61L, manager.getDataFileDownloadInterval().longValue());
+ assertEquals(TimeUnit.SECONDS, manager.getDataFileDownloadIntervalTimeUnit());
+ }
+}
diff --git a/build.gradle b/build.gradle
index 70197b94a..0eac3040f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -84,6 +84,12 @@ task testAllModules << {
logger.info("Running android tests for all modules")
}
-testAllModules.dependsOn(':android-sdk:connectedAndroidTest', ':android-sdk:test',
+task testAllModulesTravis << {
+ logger.info("Running android tests for Travis")
+}
+
+testAllModulesTravis.dependsOn(':android-sdk:connectedAndroidTest', ':android-sdk:test',
':event-handler:connectedAndroidTest', ':event-handler:test',
':user-profile:connectedAndroidTest', ':shared:connectedAndroidTest')
+
+testAllModules.dependsOn('testAllModulesTravis', ':test-app:connectedAndroidTest')
\ No newline at end of file
diff --git a/test-app/README.md b/test-app/README.md
new file mode 100644
index 000000000..2b9637a89
--- /dev/null
+++ b/test-app/README.md
@@ -0,0 +1,32 @@
+# Optimizely X Android SDK Demo App
+
+This module houses the demo app used to demonstrate how to get started with the Android SDK. The app
+is also used to run integration tests on using the Android Espresso framework.
+
+## Experiments Run
+
+The experiments run in this demo app are part of the mobile-test@optimizely.com account.
+
+We run the following experiment:
+ - Background change in second activity, which is loaded after the splash screen.
+
+## How it works
+
+The SDK is implemented in the following way:
+ - The splash screen initializes the Optimizely manager asynchronously. This starts the datafile
+ fetch.
+ - Once the datafile is fetched and the Optimizely manager is started, we use grab the `optimizelyClient`
+ from the manager and use it to activate the `background_experiment`. This buckets the user and sends
+ an impression event.
+ - We then use the bucketed variation to determine which activity to show. `VariationAActivity` for
+ `variation_a` and `VariationBActivity` for `variation_b`.
+ - Each of those activities include a `Test Conversion` button.
+ - Clicking on that button will call `optimizelyClient.track()` and send a conversion event for the
+ event named `sample_conversion`.
+ - Then the application will navigate to the conversion page to confirm that a conversion event has
+ been sent.
+
+## Running the test app
+
+Run `./gradlew test-app:connectedAndroidTest` to run the Espresso tests.
+
diff --git a/test-app/src/androidTest/java/com/optimizely/ab/android/test_app/MainActivityEspressoTest.java b/test-app/src/androidTest/java/com/optimizely/ab/android/test_app/MainActivityEspressoTest.java
index 8e8c92014..dfd379d16 100644
--- a/test-app/src/androidTest/java/com/optimizely/ab/android/test_app/MainActivityEspressoTest.java
+++ b/test-app/src/androidTest/java/com/optimizely/ab/android/test_app/MainActivityEspressoTest.java
@@ -1,18 +1,18 @@
-/*
- * Copyright 2016, Optimizely
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
package com.optimizely.ab.android.test_app;
import android.app.AlarmManager;
@@ -47,6 +47,7 @@
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static junit.framework.Assert.assertFalse;
@@ -62,7 +63,7 @@ public class MainActivityEspressoTest {
private ServiceScheduler serviceScheduler;
private Intent dataFileServiceIntent, eventIntentService;
- private ActivityTestRule activityTestRule = new ActivityTestRule<>(MainActivity.class);
+ private ActivityTestRule activityTestRule = new ActivityTestRule<>(SplashScreenActivity.class);
@Rule public TestRule chain = RuleChain
.outerRule(new ExternalResource() {
@Override
@@ -148,38 +149,25 @@ protected void after() {
public void experimentActivationForWhitelistUser() throws InterruptedException {
// Check that the text was changed.
// These tests are pointed at a real project.
- // The user 'test_user` is in the whitelist for variation 1 for experiment 0 and experiment 1.
- onView(withId(R.id.button_1))
- .check(matches(withText(context.getString(R.string.main_act_button_1_text_var_1))));
+ // The user 'test_user` is in the whitelist for variation_a for experiment background_experiment
+ onView(withId(R.id.tv_variation_a_text_1))
+ .check(matches(isDisplayed()));
// Espresso will wait for Optimizely to start due to the registered idling resources
- onView(withId(R.id.text_view_1))
- .check(matches(withText(context.getString(R.string.main_act_text_view_1_var_1))));
-
assertTrue(serviceScheduler.isScheduled(dataFileServiceIntent));
- onView(withId(R.id.button_1)) // withId(R.id.my_view) is a ViewMatcher
- .perform(click()); // click() is a ViewAction
-
- onView(withId(R.id.text_view_1))
- .check(matches(withText(context.getString(R.string.secondary_frag_text_view_1_var_1))));
-
- onView(withId(R.id.button_1)) // withId(R.id.my_view) is a ViewMatcher
- .perform(click()); // click() is a ViewAction
+ onView(withId(R.id.btn_variation_conversion)) // withId(R.id.my_view) is a ViewMatcher
+ .perform(click()); // click() is a ViewAction
List> events = CountingIdlingResourceManager.getEvents();
- assertTrue(events.size() == 6);
+ assertTrue(events.size() == 2);
Iterator> iterator = events.iterator();
while (iterator.hasNext()) {
Pair event = iterator.next();
final String url = event.first;
final String payload = event.second;
- if (url.equals("https://logx.optimizely.com/log/decision") && payload.contains("7676481120") && payload.contains("7661891902")
- || url.equals("https://logx.optimizely.com/log/decision") && payload.contains("7651112186") && payload.contains("7674261140")
- || url.equals("https://logx.optimizely.com/log/event") && payload.contains("experiment_0")
- || url.equals("https://logx.optimizely.com/log/event") && payload.contains("experiment_1")
- || url.equals("https://logx.optimizely.com/log/decision") && payload.contains("7680080715") && payload.contains("7685562539")
- || url.equals("https://logx.optimizely.com/log/event") && payload.contains("experiment_2")) {
+ if (url.equals("https://logx.optimizely.com/log/decision") && payload.contains("8126664113") && payload.contains("8146590584")
+ || url.equals("https://logx.optimizely.com/log/event") && payload.contains("sample_conversion")) {
iterator.remove();
}
}
@@ -187,7 +175,6 @@ public void experimentActivationForWhitelistUser() throws InterruptedException {
MyApplication myApplication = (MyApplication) activityTestRule.getActivity().getApplication();
UserProfile userProfile = myApplication.getOptimizelyManager().getUserProfile();
// Being in the white list should override user profile
- assertNull(userProfile.lookup("test_user", "experiment_0"));
- assertNull(userProfile.lookup("test_user", "experiment_1"));
+ assertNull(userProfile.lookup("test_user", "background_experiment"));
}
}
diff --git a/test-app/src/main/AndroidManifest.xml b/test-app/src/main/AndroidManifest.xml
index 58f4bb3b8..bd3bceb46 100644
--- a/test-app/src/main/AndroidManifest.xml
+++ b/test-app/src/main/AndroidManifest.xml
@@ -1,9 +1,26 @@
-
+
+
-
-
+
+
-
+
+
+
-
+
-
+
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/ActivationErrorActivity.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/ActivationErrorActivity.java
new file mode 100644
index 000000000..8df43b1ef
--- /dev/null
+++ b/test-app/src/main/java/com/optimizely/ab/android/test_app/ActivationErrorActivity.java
@@ -0,0 +1,38 @@
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
+package com.optimizely.ab.android.test_app;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+public class ActivationErrorActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_activation_error);
+ Button btnConversion = (Button)findViewById(R.id.btn_conversion_error_back);
+
+ btnConversion.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ onBackPressed();
+ }
+ });
+ }
+}
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/ConversionFragment.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/ConversionFragment.java
new file mode 100644
index 000000000..c46e203cd
--- /dev/null
+++ b/test-app/src/main/java/com/optimizely/ab/android/test_app/ConversionFragment.java
@@ -0,0 +1,66 @@
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
+
+package com.optimizely.ab.android.test_app;
+
+import android.app.Fragment;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+import com.optimizely.ab.android.sdk.OptimizelyClient;
+import com.optimizely.ab.android.sdk.OptimizelyManager;
+import com.optimizely.ab.android.shared.CountingIdlingResourceManager;
+
+public class ConversionFragment extends Fragment {
+
+ Button conversionButton;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_conversion, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ conversionButton = (Button) view.findViewById(R.id.btn_variation_conversion);
+
+ final MyApplication myApplication = (MyApplication) getActivity().getApplication();
+ final OptimizelyManager optimizelyManager = myApplication.getOptimizelyManager();
+
+ conversionButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ String userId = myApplication.getAnonUserId();
+
+ // This tracks a conversion event for the event named `sample_conversion`
+ OptimizelyClient optimizely = optimizelyManager.getOptimizely();
+ optimizely.track("sample_conversion", userId);
+
+ // Utility method for verifying event dispatches in our automated tests
+ CountingIdlingResourceManager.increment(); // increment for conversion event
+
+ Intent intent = new Intent(myApplication.getBaseContext(), EventConfirmationActivity.class);
+ startActivity(intent);
+ }
+ });
+ }
+}
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/EventConfirmationActivity.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/EventConfirmationActivity.java
new file mode 100644
index 000000000..fcfa19f91
--- /dev/null
+++ b/test-app/src/main/java/com/optimizely/ab/android/test_app/EventConfirmationActivity.java
@@ -0,0 +1,28 @@
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
+package com.optimizely.ab.android.test_app;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+public class EventConfirmationActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_event_confirmation);
+ }
+}
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/MainActivity.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/MainActivity.java
deleted file mode 100644
index 6db83ef29..000000000
--- a/test-app/src/main/java/com/optimizely/ab/android/test_app/MainActivity.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2016, Optimizely
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.optimizely.ab.android.test_app;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
-import android.view.View;
-import android.widget.Button;
-import android.widget.TextView;
-
-import com.optimizely.ab.android.sdk.OptimizelyClient;
-import com.optimizely.ab.android.sdk.OptimizelyManager;
-import com.optimizely.ab.android.sdk.OptimizelyStartListener;
-import com.optimizely.ab.android.shared.CountingIdlingResourceManager;
-import com.optimizely.ab.config.Variation;
-
-public class MainActivity extends AppCompatActivity {
-
- // The Idling Resource which will be null in production.
- @Nullable private static CountingIdlingResourceManager countingIdlingResourceManager;
- private OptimizelyManager optimizelyManager;
- private MyApplication myApplication;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Button button = (Button) findViewById(R.id.button_1);
-
- // This could also be done via DI framework such as Dagger
- myApplication = (MyApplication) getApplication();
- optimizelyManager = myApplication.getOptimizelyManager();
-
- // Load Optimizely from a compiled in data file
- final OptimizelyClient optimizely = optimizelyManager.initialize(this, R.raw.data_file);
- CountingIdlingResourceManager.increment(); // For impression event
- Variation variation = optimizely.activate("experiment_0", myApplication.getAnonUserId(), myApplication.getAttributes());
- if (variation != null) {
- if (variation.is("variation_1")) {
- button.setText(R.string.main_act_button_1_text_var_1);
- } else if (variation.is("variation_2")) {
- button.setText(R.string.main_act_button_1_text_var_2);
- }
- } else {
- button.setText(R.string.main_act_button_1_text_default);
- }
-
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- CountingIdlingResourceManager.increment();
- optimizely.track("experiment_0", myApplication.getAnonUserId(), myApplication.getAttributes());
- // For track event
-
- v.getContext().getResources().getString(R.string.app_name);
- Intent intent = new Intent(v.getContext(), SecondaryActivity.class);
- startActivity(intent);
- }
- });
- }
-
- @Override
- protected void onStart() {
- super.onStart();
-
- CountingIdlingResourceManager.increment(); // For Optimizely starting
- optimizelyManager.initialize(this, new OptimizelyStartListener() {
- @Override
- public void onStart(OptimizelyClient optimizely) {
- CountingIdlingResourceManager.decrement(); // For Optimizely starting
- TextView textView1 = (TextView) findViewById(R.id.text_view_1);
- textView1.setVisibility(View.VISIBLE);
- CountingIdlingResourceManager.increment(); // For impression event
- Variation variation = optimizely.activate("experiment_1", myApplication.getAnonUserId());
- if (variation != null) {
- if (variation.is("variation_1")) {
- textView1.setText(R.string.main_act_text_view_1_var_1);
- } else if (variation.is("variation_2")) {
- textView1.setText(R.string.main_act_text_view_1_var_2);
- }
- } else {
- textView1.setText(R.string.main_act_text_view_1_default);
- }
- }
- });
- }
-
-
-}
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/MyApplication.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/MyApplication.java
index 4779aa599..dced661d3 100644
--- a/test-app/src/main/java/com/optimizely/ab/android/test_app/MyApplication.java
+++ b/test-app/src/main/java/com/optimizely/ab/android/test_app/MyApplication.java
@@ -1,18 +1,18 @@
-/**
- * Copyright 2016, Optimizely
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
package com.optimizely.ab.android.test_app;
import android.app.Application;
@@ -30,7 +30,10 @@
public class MyApplication extends Application {
- public static final String PROJECT_ID = "7664231436";
+ // Project ID owned by mobile-test@optimizely.com
+ // if you'd like to configure your own experiment please check out https://developers.optimizely.com/x/solutions/sdks/getting-started/index.html?language=android&platform=mobile
+ // to create your own project and experiment. Then just replace your project ID below.
+ public static final String PROJECT_ID = "8136462271";
private OptimizelyManager optimizelyManager;
public OptimizelyManager getOptimizelyManager() {
@@ -47,10 +50,15 @@ public Map getAttributes() {
}
@NonNull
public String getAnonUserId() {
+ // this is a convenience method that creates and persists an anonymous user id,
+ // which we need to pass into the activate and track calls
SharedPreferences sharedPreferences = getSharedPreferences("user", Context.MODE_PRIVATE);
String id = sharedPreferences.getString("userId", null);
if (id == null) {
id = UUID.randomUUID().toString();
+
+ // comment this out to get a brand new user id every time this function is called.
+ // useful for incrementing results page count for QA purposes
sharedPreferences.edit().putString("userId", id).apply();
}
return id;
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/NotificationService.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/NotificationService.java
index b0fcb2e45..ac689c148 100644
--- a/test-app/src/main/java/com/optimizely/ab/android/test_app/NotificationService.java
+++ b/test-app/src/main/java/com/optimizely/ab/android/test_app/NotificationService.java
@@ -1,18 +1,18 @@
-/**
- * Copyright 2016, Optimizely
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
package com.optimizely.ab.android.test_app;
import android.app.IntentService;
@@ -52,27 +52,28 @@ private void showNotification() {
.setSmallIcon(android.R.drawable.ic_notification_clear_all)
.setContentTitle(getString(R.string.notification_service_notification_title))
.setContentText(getString(R.string.notification_service_notification_text));
+ // @TODO(mng): Add notification back when we add more complex scenario
// Creates an explicit intent for an Activity in your app
- Intent resultIntent = new Intent(this, MainActivity.class);
-
- // The stack builder object will contain an artificial back stack for the
- // started Activity.
- // This ensures that navigating backward from the Activity leads out of
- // your application to the Home screen.
- TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
- // Adds the back stack for the Intent (but not the Intent itself)
- stackBuilder.addParentStack(SecondaryActivity.class);
- // Adds the Intent that starts the Activity to the top of the stack
- stackBuilder.addNextIntent(resultIntent);
- PendingIntent resultPendingIntent =
- stackBuilder.getPendingIntent(
- 0,
- PendingIntent.FLAG_UPDATE_CURRENT
- );
- mBuilder.setContentIntent(resultPendingIntent);
- NotificationManager mNotificationManager =
- (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- // mId allows you to update the notification later on.
- mNotificationManager.notify(0, mBuilder.build());
+// Intent resultIntent = new Intent(this, MainActivity.class);
+//
+// // The stack builder object will contain an artificial back stack for the
+// // started Activity.
+// // This ensures that navigating backward from the Activity leads out of
+// // your application to the Home screen.
+// TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+// // Adds the back stack for the Intent (but not the Intent itself)
+// stackBuilder.addParentStack(SecondaryActivity.class);
+// // Adds the Intent that starts the Activity to the top of the stack
+// stackBuilder.addNextIntent(resultIntent);
+// PendingIntent resultPendingIntent =
+// stackBuilder.getPendingIntent(
+// 0,
+// PendingIntent.FLAG_UPDATE_CURRENT
+// );
+// mBuilder.setContentIntent(resultPendingIntent);
+// NotificationManager mNotificationManager =
+// (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+// // mId allows you to update the notification later on.
+// mNotificationManager.notify(0, mBuilder.build());
}
}
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/SecondaryActivity.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/SecondaryActivity.java
deleted file mode 100644
index 716270205..000000000
--- a/test-app/src/main/java/com/optimizely/ab/android/test_app/SecondaryActivity.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright 2016, Optimizely
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.optimizely.ab.android.test_app;
-
-import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
-
-import com.optimizely.ab.android.sdk.OptimizelyClient;
-import com.optimizely.ab.android.sdk.OptimizelyManager;
-import com.optimizely.ab.android.shared.CountingIdlingResourceManager;
-
-public class SecondaryActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_secondary);
-
- // Get Optimizely from the Intent that started this Activity
- final MyApplication myApplication = (MyApplication) getApplication();
- final OptimizelyManager optimizelyManager = myApplication.getOptimizelyManager();
- OptimizelyClient optimizely = optimizelyManager.getOptimizely();
- CountingIdlingResourceManager.increment(); // For track event
- optimizely.track("experiment_1", myApplication.getAnonUserId());
- }
-
-}
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/SecondaryFragment.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/SecondaryFragment.java
deleted file mode 100644
index edc7c1cdd..000000000
--- a/test-app/src/main/java/com/optimizely/ab/android/test_app/SecondaryFragment.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2016, Optimizely
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.optimizely.ab.android.test_app;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.TextView;
-
-import com.optimizely.ab.android.sdk.OptimizelyClient;
-import com.optimizely.ab.android.sdk.OptimizelyManager;
-import com.optimizely.ab.android.shared.CountingIdlingResourceManager;
-import com.optimizely.ab.config.Variation;
-
-public class SecondaryFragment extends Fragment {
-
- TextView textView1;
- Button button1;
-
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_secondary, container, false);
- }
-
- @Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- textView1 = (TextView) view.findViewById(R.id.text_view_1);
- button1 = (Button) view.findViewById(R.id.button_1);
-
- final MyApplication myApplication = (MyApplication) getActivity().getApplication();
- final OptimizelyManager optimizelyManager = myApplication.getOptimizelyManager();
-
- OptimizelyClient optimizely = optimizelyManager.getOptimizely();
- CountingIdlingResourceManager.increment();
- Variation variation = optimizely.activate("experiment_2", myApplication.getAnonUserId());
- if (variation != null) {
- if (variation.is("variation_1")) {
- textView1.setText(R.string.secondary_frag_text_view_1_var_1);
- } else if (variation.is("variation_2")) {
- textView1.setText(R.string.secondary_frag_text_view_1_var_2);
- }
- } else {
- textView1.setText(R.string.secondary_frag_text_view_1_default);
- }
-
- button1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- final FragmentActivity activity = getActivity();
- Intent intent = new Intent(activity, NotificationService.class);
- activity.startService(intent);
- }
- });
- }
-}
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/SplashScreenActivity.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/SplashScreenActivity.java
new file mode 100644
index 000000000..4607c46d3
--- /dev/null
+++ b/test-app/src/main/java/com/optimizely/ab/android/test_app/SplashScreenActivity.java
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
+package com.optimizely.ab.android.test_app;
+
+import android.content.Intent;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+import com.optimizely.ab.android.sdk.OptimizelyClient;
+import com.optimizely.ab.android.sdk.OptimizelyManager;
+import com.optimizely.ab.android.sdk.OptimizelyStartListener;
+import com.optimizely.ab.android.shared.CountingIdlingResourceManager;
+import com.optimizely.ab.config.Variation;
+
+public class SplashScreenActivity extends AppCompatActivity {
+
+ // The Idling Resource which will be null in production.
+ @Nullable
+ private static CountingIdlingResourceManager countingIdlingResourceManager;
+
+ private OptimizelyManager optimizelyManager;
+ private MyApplication myApplication;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_splash_screen);
+
+ // This could also be done via DI framework such as Dagger
+ myApplication = (MyApplication) getApplication();
+ optimizelyManager = myApplication.getOptimizelyManager();
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+
+ // Initialize Optimizely asynchronously
+ optimizelyManager.initialize(this, new OptimizelyStartListener() {
+
+ @Override
+ public void onStart(OptimizelyClient optimizely) {
+ // this is the control variation, it will show if we are not able to determine which variation to bucket the user into
+ Intent intent = new Intent(myApplication.getBaseContext(), ActivationErrorActivity.class);
+
+ // Activate user and start activity based on the variation we get.
+ // You can pass in any string for the user ID. In this example we just use a convenience method to generate a random one.
+ String userId = myApplication.getAnonUserId();
+ Variation backgroundVariation = optimizelyManager.getOptimizely().activate("background_experiment", userId);
+
+ // Utility method for verifying event dispatches in our automated tests
+ CountingIdlingResourceManager.increment(); // increment for impression event
+
+ // variation is nullable so we should check for null values
+ if (backgroundVariation != null) {
+ // Show activity based on the variation the user got bucketed into
+ if (backgroundVariation.getKey().equals("variation_a")) {
+ intent = new Intent(myApplication.getBaseContext(), VariationAActivity.class);
+ } else if (backgroundVariation.getKey().equals("variation_b")) {
+ intent = new Intent(myApplication.getBaseContext(), VariationBActivity.class);
+ }
+ }
+
+ startActivity(intent);
+ }
+ });
+ }
+}
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/VariationAActivity.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/VariationAActivity.java
new file mode 100644
index 000000000..90ac5c664
--- /dev/null
+++ b/test-app/src/main/java/com/optimizely/ab/android/test_app/VariationAActivity.java
@@ -0,0 +1,28 @@
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
+package com.optimizely.ab.android.test_app;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+public class VariationAActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_variation_a);
+ }
+}
diff --git a/test-app/src/main/java/com/optimizely/ab/android/test_app/VariationBActivity.java b/test-app/src/main/java/com/optimizely/ab/android/test_app/VariationBActivity.java
new file mode 100644
index 000000000..8e3c5f595
--- /dev/null
+++ b/test-app/src/main/java/com/optimizely/ab/android/test_app/VariationBActivity.java
@@ -0,0 +1,29 @@
+/****************************************************************************
+ * Copyright 2017, 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. *
+ * You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
+ * See the License for the specific language governing permissions and *
+ * limitations under the License. *
+ ***************************************************************************/
+
+package com.optimizely.ab.android.test_app;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+public class VariationBActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_variation_b);
+ }
+}
diff --git a/test-app/src/main/res/drawable/ic_background_confirmation.xml b/test-app/src/main/res/drawable/ic_background_confirmation.xml
new file mode 100644
index 000000000..ad20d1102
--- /dev/null
+++ b/test-app/src/main/res/drawable/ic_background_confirmation.xml
@@ -0,0 +1,204 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test-app/src/main/res/drawable/ic_background_error.xml b/test-app/src/main/res/drawable/ic_background_error.xml
new file mode 100644
index 000000000..d89352e65
--- /dev/null
+++ b/test-app/src/main/res/drawable/ic_background_error.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test-app/src/main/res/drawable/ic_background_varia.xml b/test-app/src/main/res/drawable/ic_background_varia.xml
new file mode 100644
index 000000000..59201cab9
--- /dev/null
+++ b/test-app/src/main/res/drawable/ic_background_varia.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/test-app/src/main/res/drawable/ic_background_varib_marina.xml b/test-app/src/main/res/drawable/ic_background_varib_marina.xml
new file mode 100644
index 000000000..2b6eb3457
--- /dev/null
+++ b/test-app/src/main/res/drawable/ic_background_varib_marina.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/test-app/src/main/res/drawable/ic_optimizely_logo.xml b/test-app/src/main/res/drawable/ic_optimizely_logo.xml
new file mode 100644
index 000000000..6a7f1962b
--- /dev/null
+++ b/test-app/src/main/res/drawable/ic_optimizely_logo.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/test-app/src/main/res/layout/activity_activation_error.xml b/test-app/src/main/res/layout/activity_activation_error.xml
new file mode 100644
index 000000000..36c23136e
--- /dev/null
+++ b/test-app/src/main/res/layout/activity_activation_error.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
diff --git a/test-app/src/main/res/layout/activity_event_confirmation.xml b/test-app/src/main/res/layout/activity_event_confirmation.xml
new file mode 100644
index 000000000..098a2d18f
--- /dev/null
+++ b/test-app/src/main/res/layout/activity_event_confirmation.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
diff --git a/test-app/src/main/res/layout/activity_main.xml b/test-app/src/main/res/layout/activity_main.xml
deleted file mode 100644
index 686b7a236..000000000
--- a/test-app/src/main/res/layout/activity_main.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/test-app/src/main/res/layout/activity_secondary.xml b/test-app/src/main/res/layout/activity_secondary.xml
deleted file mode 100644
index 46a3171e5..000000000
--- a/test-app/src/main/res/layout/activity_secondary.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
diff --git a/test-app/src/main/res/layout/activity_splash_screen.xml b/test-app/src/main/res/layout/activity_splash_screen.xml
new file mode 100644
index 000000000..facb17d3c
--- /dev/null
+++ b/test-app/src/main/res/layout/activity_splash_screen.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
diff --git a/test-app/src/main/res/layout/activity_variation_a.xml b/test-app/src/main/res/layout/activity_variation_a.xml
new file mode 100644
index 000000000..b12e00a00
--- /dev/null
+++ b/test-app/src/main/res/layout/activity_variation_a.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
diff --git a/test-app/src/main/res/layout/activity_variation_b.xml b/test-app/src/main/res/layout/activity_variation_b.xml
new file mode 100644
index 000000000..b9336fc19
--- /dev/null
+++ b/test-app/src/main/res/layout/activity_variation_b.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
diff --git a/test-app/src/main/res/layout/fragment_conversion.xml b/test-app/src/main/res/layout/fragment_conversion.xml
new file mode 100644
index 000000000..e55548d37
--- /dev/null
+++ b/test-app/src/main/res/layout/fragment_conversion.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test-app/src/main/res/layout/fragment_secondary.xml b/test-app/src/main/res/layout/fragment_secondary.xml
deleted file mode 100644
index 10a2bb670..000000000
--- a/test-app/src/main/res/layout/fragment_secondary.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test-app/src/main/res/raw/data_file.json b/test-app/src/main/res/raw/data_file.json
index 75a2e4a40..1fa045fc2 100644
--- a/test-app/src/main/res/raw/data_file.json
+++ b/test-app/src/main/res/raw/data_file.json
@@ -1,63 +1,54 @@
{
+ "groups": [],
+ "variables": [],
"experiments": [
{
"status": "Running",
- "key": "experiment_0",
- "layerId": "7674261139",
+ "key": "background_experiment",
+ "layerId": "8143622708",
"trafficAllocation": [
{
- "entityId": "7674261140",
+ "entityId": "8146590584",
"endOfRange": 5000
},
{
- "entityId": "7678410470",
+ "entityId": "8134412703",
"endOfRange": 10000
}
],
- "audienceIds": [
- "7671101484"
- ],
+ "audienceIds": [],
"variations": [
{
- "id": "7674261140",
- "key": "variation_1"
+ "variables": [],
+ "id": "8146590584",
+ "key": "variation_a"
},
{
- "id": "7678410470",
- "key": "variation_2"
+ "variables": [],
+ "id": "8134412703",
+ "key": "variation_b"
}
],
"forcedVariations": {
- "test_user": "variation_1"
+ "test_user": "variation_a"
},
- "id": "7651112186"
- }
- ],
- "version": "2",
- "audiences": [
- {
- "conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"locale\", \"type\": \"custom_attribute\", \"value\": \"en_US\"}]]]",
- "id": "7671101484",
- "name": "Americans"
- }
- ],
- "groups": [],
- "attributes": [
- {
- "id": "7656544299",
- "key": "locale"
+ "id": "8126664113"
}
],
- "projectId": "7664231436",
- "accountId": "3279320409",
+ "audiences": [],
+ "anonymizeIP": false,
+ "accountId": "6384711706",
+ "projectId": "8136462271",
+ "version": "3",
+ "attributes": [],
"events": [
{
"experimentIds": [
- "7651112186"
+ "8126664113"
],
- "id": "7667071273",
- "key": "experiment_0"
+ "id": "8128595839",
+ "key": "sample_conversion"
}
],
- "revision": "16"
+ "revision": "5"
}
\ No newline at end of file
diff --git a/test-app/src/main/res/values/colors.xml b/test-app/src/main/res/values/colors.xml
index 9d0d7a51c..abc12e785 100644
--- a/test-app/src/main/res/values/colors.xml
+++ b/test-app/src/main/res/values/colors.xml
@@ -1,6 +1,7 @@
- #2196F3
+ #003952#1976D2
- #9E9E9E
+ #ff5500
+ #FFFFFF
diff --git a/test-app/src/main/res/values/strings.xml b/test-app/src/main/res/values/strings.xml
index ee154d3da..95e15c89b 100644
--- a/test-app/src/main/res/values/strings.xml
+++ b/test-app/src/main/res/values/strings.xml
@@ -1,5 +1,5 @@
- Optimized
+ Optimizely Demo AppNext ActivityStart Next Activity!Start Second Activity!
diff --git a/test-app/src/main/res/values/styles.xml b/test-app/src/main/res/values/styles.xml
index 5885930df..90e5a386c 100644
--- a/test-app/src/main/res/values/styles.xml
+++ b/test-app/src/main/res/values/styles.xml
@@ -8,4 +8,8 @@
@color/colorAccent
+
+