Skip to content

Commit

Permalink
[ios] Add Location Permissions Field Trial Experiment
Browse files Browse the repository at this point in the history
This change adds setup for a client-driven experiment that buckets
users on First Run into 3 groups, two experiment and one control.

Bug: 1138603
Change-Id: I7c100d173ea2d64e718950047d0c2f04ff4c3fbf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2506749
Commit-Queue: Chris Lu <thegreenfrog@chromium.org>
Reviewed-by: Rohit Rao <rohitrao@chromium.org>
Reviewed-by: Alexei Svitkine <asvitkine@chromium.org>
Reviewed-by: Bo <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824647}
  • Loading branch information
Chris Lu authored and Commit Bot committed Nov 5, 2020
1 parent 282b3c8 commit 702076d
Show file tree
Hide file tree
Showing 27 changed files with 311 additions and 108 deletions.
1 change: 1 addition & 0 deletions android_webview/browser/aw_field_trials.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class AwFieldTrials : public variations::PlatformFieldTrials {
void SetupFieldTrials() override;
void SetupFeatureControllingFieldTrials(
bool has_seed,
const base::FieldTrial::EntropyProvider& low_entropy_provider,
base::FeatureList* feature_list) override {}

private:
Expand Down
1 change: 1 addition & 0 deletions chrome/browser/chrome_browser_field_trials.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void ChromeBrowserFieldTrials::SetupFieldTrials() {

void ChromeBrowserFieldTrials::SetupFeatureControllingFieldTrials(
bool has_seed,
const base::FieldTrial::EntropyProvider& low_entropy_provider,
base::FeatureList* feature_list) {
// Only create the fallback trials if there isn't already a variations seed
// being applied. This should occur during first run when first-run variations
Expand Down
1 change: 1 addition & 0 deletions chrome/browser/chrome_browser_field_trials.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class ChromeBrowserFieldTrials : public variations::PlatformFieldTrials {
void SetupFieldTrials() override;
void SetupFeatureControllingFieldTrials(
bool has_seed,
const base::FieldTrial::EntropyProvider& low_entropy_provider,
base::FeatureList* feature_list) override;
void RegisterSyntheticTrials() override;

Expand Down
12 changes: 1 addition & 11 deletions chrome/browser/flag-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -3044,17 +3044,7 @@
"expiry_milestone": -1
},
{
"name": "location-change-string",
"owners": [ "thegreenfrog", "bling-team" ],
"expiry_milestone": 91
},
{
"name": "location-first-run-modal",
"owners": [ "thegreenfrog", "bling-team" ],
"expiry_milestone": 91
},
{
"name": "location-remove-first-run",
"name": "location-permissions-prompt",
"owners": [ "thegreenfrog", "bling-team" ],
"expiry_milestone": 91
},
Expand Down
5 changes: 4 additions & 1 deletion components/variations/platform_field_trials.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ class PlatformFieldTrials {
// FeatureList::AssociateReportingFieldTrial. |has_seed| indicates that the
// variations service used a seed to create field trials. This can be used to
// prevent associating a field trial with a feature that you expect to be
// controlled by the variations seed.
// controlled by the variations seed. |low_entropy_provider| can be used as a
// parameter to creating a FieldTrial that should be visible to Google web
// properties.
virtual void SetupFeatureControllingFieldTrials(
bool has_seed,
const base::FieldTrial::EntropyProvider& low_entropy_provider,
base::FeatureList* feature_list) = 0;

// Register any synthetic field trials. Will be called later than the above
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,14 +522,16 @@ bool VariationsFieldTrialCreator::SetupFieldTrials(
used_testing_config = true;
}
#endif // BUILDFLAG(FIELDTRIAL_TESTING_ENABLED)
const base::FieldTrial::EntropyProvider& low_entry_provider_ref =
*low_entropy_provider.get();
bool used_seed = false;
if (!used_testing_config) {
used_seed = CreateTrialsFromSeed(std::move(low_entropy_provider),
feature_list.get(), safe_seed_manager);
}

platform_field_trials->SetupFeatureControllingFieldTrials(used_seed,
feature_list.get());
platform_field_trials->SetupFeatureControllingFieldTrials(
used_seed, low_entry_provider_ref, feature_list.get());

base::FeatureList::SetInstance(std::move(feature_list));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class TestPlatformFieldTrials : public PlatformFieldTrials {
void SetupFieldTrials() override {}
void SetupFeatureControllingFieldTrials(
bool has_seed,
const base::FieldTrial::EntropyProvider& low_entropy_provider,
base::FeatureList* feature_list) override {}

private:
Expand Down
3 changes: 1 addition & 2 deletions ios/chrome/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ source_set("browser") {
"ios_chrome_field_trials.h",
"ios_chrome_io_thread.h",
"ios_chrome_io_thread.mm",
"ios_first_run_field_trials.cc",
"ios_first_run_field_trials.h",
"notification_promo.cc",
"notification_promo.h",
]
Expand Down Expand Up @@ -104,6 +102,7 @@ source_set("browser") {
"//ios/chrome/browser/sync/glue",
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/browser/ui/coordinators:chrome_coordinators",
"//ios/chrome/browser/ui/first_run:field_trial",
"//ios/chrome/browser/ui/fullscreen:feature_flags",
"//ios/chrome/browser/ui/omnibox",
"//ios/chrome/browser/ui/toolbar_container:feature_flags",
Expand Down
14 changes: 4 additions & 10 deletions ios/chrome/browser/flags/about_flags.mm
Original file line number Diff line number Diff line change
Expand Up @@ -621,20 +621,14 @@
flag_descriptions::kIncognitoAuthenticationName,
flag_descriptions::kIncognitoAuthenticationDescription, flags_ui::kOsIos,
FEATURE_VALUE_TYPE(kIncognitoAuthentication)},
{"location-first-run-modal", flag_descriptions::kLocationFirstRunModalName,
flag_descriptions::kLocationFirstRunModalDescription, flags_ui::kOsIos,
FEATURE_VALUE_TYPE(kLocationFirstRunModal)},
{"location-remove-first-run",
flag_descriptions::kLocationRemoveFirstRunPromptName,
flag_descriptions::kLocationRemoveFirstRunPromptDescription,
flags_ui::kOsIos, FEATURE_VALUE_TYPE(kLocationRemoveFirstRunPrompt)},
{"location-change-string", flag_descriptions::kLocationStringChangeName,
flag_descriptions::kLocationStringChangeDescription, flags_ui::kOsIos,
FEATURE_VALUE_TYPE(kLocationStringChange)},
{"web-view-native-context-menu",
flag_descriptions::kWebViewNativeContextMenuName,
flag_descriptions::kWebViewNativeContextMenuDescription, flags_ui::kOsIos,
FEATURE_VALUE_TYPE(web::features::kWebViewNativeContextMenu)},
{"location-permissions-prompt",
flag_descriptions::kLocationPermissionsPromptName,
flag_descriptions::kLocationPermissionsPromptDescription, flags_ui::kOsIos,
FEATURE_VALUE_TYPE(kLocationPermissionsPrompt)},
};

bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
Expand Down
22 changes: 5 additions & 17 deletions ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -290,23 +290,11 @@ const char kIOSLookalikeUrlNavigationSuggestionsUIDescription[] =
"When enabled, an interstitial will be shown on navigations to lookalike "
"URLs.";

const char kLocationFirstRunModalName[] =
"Location Permisssions First Run Modal";
const char kLocationFirstRunModalDescription[] =
"When enabled, a modal detailing location data usage in Chrome will be "
"presented just before triggering the native location permissions prompt.";

const char kLocationRemoveFirstRunPromptName[] =
"Remove Location Permissions Prompt in First Run";
const char kLocationRemoveFirstRunPromptDescription[] =
"When enabled, a location permissions prompt will not be triggered right "
"after First Run anymore.";

const char kLocationStringChangeName[] =
"Use New Location Permissions Prompt String";
const char kLocationStringChangeDescription[] =
"When enabled, a better string will used in the location permissions "
"prompt.";
const char kLocationPermissionsPromptName[] =
"Location Permisssions Prompt Experiment";
const char kLocationPermissionsPromptDescription[] =
"When enabled, a different user experience flow will be shown to ask for "
"location permissions.";

const char kLockBottomToolbarName[] = "Lock bottom toolbar";
const char kLockBottomToolbarDescription[] =
Expand Down
18 changes: 4 additions & 14 deletions ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,20 +258,10 @@ extern const char kIOSLegacyTLSInterstitialsDescription[];
extern const char kIOSLookalikeUrlNavigationSuggestionsUIName[];
extern const char kIOSLookalikeUrlNavigationSuggestionsUIDescription[];

// Title and description for the flag to add a First Run modal for location
// permissions.
extern const char kLocationFirstRunModalName[];
extern const char kLocationFirstRunModalDescription[];

// Title and description for the flag to remove the First Run location
// permissions prompt.
extern const char kLocationRemoveFirstRunPromptName[];
extern const char kLocationRemoveFirstRunPromptDescription[];

// Title and description for the flag to change the string in the location
// permissions prompt.
extern const char kLocationStringChangeName[];
extern const char kLocationStringChangeDescription[];
// Title and description for the flag to experiment with different location
// permission user experiences.
extern const char kLocationPermissionsPromptName[];
extern const char kLocationPermissionsPromptDescription[];

// Title and description for the flag to lock the bottom toolbar into place.
extern const char kLockBottomToolbarName[];
Expand Down
6 changes: 6 additions & 0 deletions ios/chrome/browser/ios_chrome_field_trials.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

#include "base/path_service.h"
#include "components/metrics/persistent_histograms.h"
#include "ios/chrome/browser/application_context.h"
#include "ios/chrome/browser/chrome_paths.h"
#import "ios/chrome/browser/ui/first_run/location_permissions_field_trial.h"

void IOSChromeFieldTrials::SetupFieldTrials() {
// Persistent histograms must be enabled as soon as possible.
Expand All @@ -18,7 +20,11 @@ void IOSChromeFieldTrials::SetupFieldTrials() {

void IOSChromeFieldTrials::SetupFeatureControllingFieldTrials(
bool has_seed,
const base::FieldTrial::EntropyProvider& low_entropy_provider,
base::FeatureList* feature_list) {
// Add code here to enable field trials that are active at first run.
// See http://crrev/c/1128269 for an example.
location_permissions_field_trial::Create(
low_entropy_provider, feature_list,
GetApplicationContext()->GetLocalState());
}
1 change: 1 addition & 0 deletions ios/chrome/browser/ios_chrome_field_trials.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class IOSChromeFieldTrials : public variations::PlatformFieldTrials {
void SetupFieldTrials() override;
void SetupFeatureControllingFieldTrials(
bool has_seed,
const base::FieldTrial::EntropyProvider& low_entropy_provider,
base::FeatureList* feature_list) override;

private:
Expand Down
28 changes: 0 additions & 28 deletions ios/chrome/browser/ios_first_run_field_trials.cc

This file was deleted.

1 change: 1 addition & 0 deletions ios/chrome/browser/prefs/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ source_set("browser_prefs") {
"//ios/chrome/browser/ui/authentication",
"//ios/chrome/browser/ui/bookmarks:constants",
"//ios/chrome/browser/ui/bookmarks:core",
"//ios/chrome/browser/ui/first_run:field_trial",
"//ios/chrome/browser/voice:prefs",
"//ios/chrome/browser/web",
"//ios/public/provider/chrome/browser",
Expand Down
2 changes: 2 additions & 0 deletions ios/chrome/browser/prefs/browser_prefs.mm
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#import "ios/chrome/browser/ui/bookmarks/bookmark_mediator.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_path_cache.h"
#import "ios/chrome/browser/ui/bookmarks/bookmark_utils_ios.h"
#import "ios/chrome/browser/ui/first_run/location_permissions_field_trial.h"
#include "ios/chrome/browser/voice/voice_search_prefs_registration.h"
#import "ios/chrome/browser/web/font_size_tab_helper.h"
#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
Expand Down Expand Up @@ -116,6 +117,7 @@ void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
sessions::SessionIdGenerator::RegisterPrefs(registry);
update_client::RegisterPrefs(registry);
variations::VariationsService::RegisterPrefs(registry);
location_permissions_field_trial::RegisterLocalStatePrefs(registry);

// Preferences related to the browser state manager.
registry->RegisterStringPref(prefs::kBrowserStateLastUsed, std::string());
Expand Down
19 changes: 19 additions & 0 deletions ios/chrome/browser/ui/first_run/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

source_set("field_trial") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"ios_first_run_field_trials.cc",
"ios_first_run_field_trials.h",
"location_permissions_field_trial.cc",
"location_permissions_field_trial.h",
]
deps = [
"//base",
"//components/prefs",
"//components/variations",
"//components/version_info",
"//ios/chrome/browser/ui:feature_flags",
"//ios/chrome/common",
]
}

source_set("first_run") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
Expand All @@ -23,6 +41,7 @@ source_set("first_run") {
]
deps = [
":constants",
":field_trial",
"resources:checkbox",
"resources:checkbox_checked",
"resources:first_run_location_permissions",
Expand Down
54 changes: 54 additions & 0 deletions ios/chrome/browser/ui/first_run/ios_first_run_field_trials.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ios/chrome/browser/ui/first_run/ios_first_run_field_trials.h"

// FirstRunFieldTrialGroup
FirstRunFieldTrialGroup::FirstRunFieldTrialGroup(
const std::string& name,
variations::VariationID variation,
base::FieldTrial::Probability percentage)
: name_(name), variation_(variation), percentage_(percentage) {}

FirstRunFieldTrialGroup::~FirstRunFieldTrialGroup() {}

// FirstRunFieldTrialConfig
FirstRunFieldTrialConfig::FirstRunFieldTrialConfig(
const std::string& trial_name)
: trial_name_(trial_name) {}

FirstRunFieldTrialConfig::~FirstRunFieldTrialConfig() {}

scoped_refptr<base::FieldTrial>
FirstRunFieldTrialConfig::CreateOneTimeRandomizedTrial(
const std::string& disabled_group_name,
const base::FieldTrial::EntropyProvider& low_entropy_provider) {
scoped_refptr<base::FieldTrial> trial =
base::FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed(
trial_name_, GetTotalProbability(), disabled_group_name,
base::FieldTrial::ONE_TIME_RANDOMIZED, 0,
/*default_group_number=*/nullptr, &low_entropy_provider);
for (const auto& group : groups_) {
variations::AssociateGoogleVariationID(
variations::GOOGLE_WEB_PROPERTIES_FIRST_PARTY, trial_name_,
group.name(), group.variation());
trial->AppendGroup(group.name(), group.percentage());
}
return trial;
}

int FirstRunFieldTrialConfig::GetTotalProbability() {
int sum = 0;
for (const auto& group : groups_) {
sum += group.percentage();
}
return sum;
}

void FirstRunFieldTrialConfig::AddGroup(
const std::string& name,
variations::VariationID variation,
base::FieldTrial::Probability percentage) {
groups_.emplace_back(name, variation, percentage);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IOS_CHROME_BROWSER_IOS_FIRST_RUN_FIELD_TRIALS_H_
#define IOS_CHROME_BROWSER_IOS_FIRST_RUN_FIELD_TRIALS_H_
#ifndef IOS_CHROME_BROWSER_UI_FIRST_RUN_IOS_FIRST_RUN_FIELD_TRIALS_H_
#define IOS_CHROME_BROWSER_UI_FIRST_RUN_IOS_FIRST_RUN_FIELD_TRIALS_H_

#include <string>
#include <vector>
Expand Down Expand Up @@ -41,12 +41,21 @@ class FirstRunFieldTrialConfig {
FirstRunFieldTrialConfig(const std::string& trial_name);
~FirstRunFieldTrialConfig();

// Creates and returns a one-time randomized FieldTrial with
// |disabled_group_name| with groups configured with Google Variation IDs.
scoped_refptr<base::FieldTrial> CreateOneTimeRandomizedTrial(
const std::string& disabled_group_name,
const base::FieldTrial::EntropyProvider& low_entropy_provider);

// Adds a new FieldTrial group of |name| with a probability of |percentage|.
// |variation| defines a server-side variation configuration.
void AddGroup(const std::string& name,
variations::VariationID variation,
base::FieldTrial::Probability percentage);

// Gets the probability sum of every group in the trial.
int GetTotalProbability();

// Returns a vector of FieldTrial groups for this FieldTrial configuration.
const std::vector<FirstRunFieldTrialGroup>& groups() const { return groups_; }
// Accessors for this FieldTrial.
Expand All @@ -59,4 +68,4 @@ class FirstRunFieldTrialConfig {
DISALLOW_COPY_AND_ASSIGN(FirstRunFieldTrialConfig);
};

#endif // IOS_CHROME_BROWSER_IOS_FIRST_RUN_FIELD_TRIALS_H_
#endif // IOS_CHROME_BROWSER_UI_FIRST_RUN_IOS_FIRST_RUN_FIELD_TRIALS_H_
Loading

0 comments on commit 702076d

Please sign in to comment.