#include <map>
#include <string>
#include "base/android/jni_string.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_list_including_low_anonymity.h"
#include "base/metrics/field_trial_params.h"
#include "base/no_destructor.h"
#include "base/base_jni/FieldTrialList_jni.h"
namespace {
class TrialLogger : public base::FieldTrialList::Observer {
public:
TrialLogger() = default;
TrialLogger(const TrialLogger&) = delete;
TrialLogger& operator=(const TrialLogger&) = delete;
void OnFieldTrialGroupFinalized(const base::FieldTrial& trial,
const std::string& group_name) override {
Log(trial.trial_name(), group_name);
}
static void Log(const std::string& trial_name,
const std::string& group_name) {
LOG(INFO) << "Active field trial \"" << trial_name << "\" in group \""
<< group_name << '"';
}
protected:
~TrialLogger() override = default;
};
TrialLogger* GetTrialLogger() {
static base::NoDestructor<TrialLogger> trial_logger;
return trial_logger.get();
}
}
static std::string JNI_FieldTrialList_FindFullName(JNIEnv* env,
std::string& trial_name) {
return base::FieldTrialList::FindFullName(trial_name);
}
static jboolean JNI_FieldTrialList_TrialExists(JNIEnv* env,
std::string& trial_name) {
return base::FieldTrialList::TrialExists(trial_name);
}
static std::string JNI_FieldTrialList_GetVariationParameter(
JNIEnv* env,
std::string& trial_name,
std::string& parameter_key) {
std::map<std::string, std::string> parameters;
base::GetFieldTrialParams(trial_name, ¶meters);
return parameters[parameter_key];
}
static void JNI_FieldTrialList_LogActiveTrials(JNIEnv* env);
class AndroidFieldTrialListLogActiveTrialsFriendHelper {
private:
friend void ::JNI_FieldTrialList_LogActiveTrials(JNIEnv* env);
static bool AddObserver(base::FieldTrialList::Observer* observer) {
return base::FieldTrialListIncludingLowAnonymity::AddObserver(observer);
}
static void GetActiveFieldTrialGroups(
base::FieldTrial::ActiveGroups* active_groups) {
base::FieldTrialListIncludingLowAnonymity::GetActiveFieldTrialGroups(
active_groups);
}
};
static void JNI_FieldTrialList_LogActiveTrials(JNIEnv* env) {
static int called_count = 0;
DCHECK_EQ(called_count++, 0);
LOG(INFO) << "Logging active field trials...";
AndroidFieldTrialListLogActiveTrialsFriendHelper::AddObserver(
GetTrialLogger());
std::vector<base::FieldTrial::ActiveGroup> active_groups;
AndroidFieldTrialListLogActiveTrialsFriendHelper::GetActiveFieldTrialGroups(
&active_groups);
for (const base::FieldTrial::ActiveGroup& group : active_groups) {
TrialLogger::Log(group.trial_name, group.group_name);
}
}
static jboolean JNI_FieldTrialList_CreateFieldTrial(JNIEnv* env,
std::string& trial_name,
std::string& group_name) {
return base::FieldTrialList::CreateFieldTrial(trial_name, group_name) !=
nullptr;
}
DEFINE_JNI(FieldTrialList)