1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <jni.h>
6
7 #include <map>
8 #include <string>
9
10 #include "base/android/jni_string.h"
11 #include "base/base_jni_headers/FieldTrialList_jni.h"
12 #include "base/lazy_instance.h"
13 #include "base/macros.h"
14 #include "base/metrics/field_trial.h"
15 #include "base/metrics/field_trial_params.h"
16
17 using base::android::ConvertJavaStringToUTF8;
18 using base::android::ConvertUTF8ToJavaString;
19 using base::android::JavaParamRef;
20 using base::android::ScopedJavaLocalRef;
21
22 namespace {
23
24 // Log trials and their groups on activation, for debugging purposes.
25 class TrialLogger : public base::FieldTrialList::Observer {
26 public:
TrialLogger()27 TrialLogger() {}
28
OnFieldTrialGroupFinalized(const std::string & trial_name,const std::string & group_name)29 void OnFieldTrialGroupFinalized(const std::string& trial_name,
30 const std::string& group_name) override {
31 Log(trial_name, group_name);
32 }
33
Log(const std::string & trial_name,const std::string & group_name)34 static void Log(const std::string& trial_name,
35 const std::string& group_name) {
36 LOG(INFO) << "Active field trial \"" << trial_name
37 << "\" in group \"" << group_name<< '"';
38 }
39
40 protected:
~TrialLogger()41 ~TrialLogger() override {}
42
43 private:
44 DISALLOW_COPY_AND_ASSIGN(TrialLogger);
45 };
46
47 base::LazyInstance<TrialLogger>::Leaky g_trial_logger =
48 LAZY_INSTANCE_INITIALIZER;
49
50 } // namespace
51
JNI_FieldTrialList_FindFullName(JNIEnv * env,const JavaParamRef<jstring> & jtrial_name)52 static ScopedJavaLocalRef<jstring> JNI_FieldTrialList_FindFullName(
53 JNIEnv* env,
54 const JavaParamRef<jstring>& jtrial_name) {
55 std::string trial_name(ConvertJavaStringToUTF8(env, jtrial_name));
56 return ConvertUTF8ToJavaString(
57 env, base::FieldTrialList::FindFullName(trial_name));
58 }
59
JNI_FieldTrialList_TrialExists(JNIEnv * env,const JavaParamRef<jstring> & jtrial_name)60 static jboolean JNI_FieldTrialList_TrialExists(
61 JNIEnv* env,
62 const JavaParamRef<jstring>& jtrial_name) {
63 std::string trial_name(ConvertJavaStringToUTF8(env, jtrial_name));
64 return base::FieldTrialList::TrialExists(trial_name);
65 }
66
JNI_FieldTrialList_GetVariationParameter(JNIEnv * env,const JavaParamRef<jstring> & jtrial_name,const JavaParamRef<jstring> & jparameter_key)67 static ScopedJavaLocalRef<jstring> JNI_FieldTrialList_GetVariationParameter(
68 JNIEnv* env,
69 const JavaParamRef<jstring>& jtrial_name,
70 const JavaParamRef<jstring>& jparameter_key) {
71 std::map<std::string, std::string> parameters;
72 base::GetFieldTrialParams(ConvertJavaStringToUTF8(env, jtrial_name),
73 ¶meters);
74 return ConvertUTF8ToJavaString(
75 env, parameters[ConvertJavaStringToUTF8(env, jparameter_key)]);
76 }
77
JNI_FieldTrialList_LogActiveTrials(JNIEnv * env)78 static void JNI_FieldTrialList_LogActiveTrials(JNIEnv* env) {
79 DCHECK(!g_trial_logger.IsCreated()); // This need only be called once.
80
81 LOG(INFO) << "Logging active field trials...";
82 base::FieldTrialList::AddObserver(&g_trial_logger.Get());
83
84 // Log any trials that were already active before adding the observer.
85 std::vector<base::FieldTrial::ActiveGroup> active_groups;
86 base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
87 for (const base::FieldTrial::ActiveGroup& group : active_groups) {
88 TrialLogger::Log(group.trial_name, group.group_name);
89 }
90 }
91
JNI_FieldTrialList_CreateFieldTrial(JNIEnv * env,const JavaParamRef<jstring> & jtrial_name,const JavaParamRef<jstring> & jgroup_name)92 static jboolean JNI_FieldTrialList_CreateFieldTrial(
93 JNIEnv* env,
94 const JavaParamRef<jstring>& jtrial_name,
95 const JavaParamRef<jstring>& jgroup_name) {
96 return base::FieldTrialList::CreateFieldTrial(
97 ConvertJavaStringToUTF8(env, jtrial_name),
98 ConvertJavaStringToUTF8(env, jgroup_name)) != nullptr;
99 }
100