1 // Copyright 2023 The Chromium Authors
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 "base/android/feature_map.h"
6
7 #include <jni.h>
8 #include <stddef.h>
9
10 #include <memory>
11 #include <string>
12
13 #include "base/android/jni_array.h"
14 #include "base/android/jni_string.h"
15 #include "base/base_jni/FeatureMap_jni.h"
16 #include "base/metrics/field_trial_params.h"
17 #include "base/notreached.h"
18
19 namespace base::android {
20
MakeNameToFeaturePair(const Feature * feature)21 std::pair<StringPiece, const Feature*> MakeNameToFeaturePair(
22 const Feature* feature) {
23 return std::make_pair(feature->name, feature);
24 }
25
FeatureMap(std::vector<const Feature * > features_exposed_to_java)26 FeatureMap::FeatureMap(std::vector<const Feature*> features_exposed_to_java) {
27 mapping_ = MakeFlatMap<StringPiece, const Feature*>(
28 features_exposed_to_java, {}, &MakeNameToFeaturePair);
29 }
30
31 FeatureMap::~FeatureMap() = default;
32
FindFeatureExposedToJava(const StringPiece & feature_name)33 const Feature* FeatureMap::FindFeatureExposedToJava(
34 const StringPiece& feature_name) {
35 auto it = mapping_.find(feature_name);
36 if (it != mapping_.end()) {
37 return it->second;
38 }
39
40 NOTREACHED_NORETURN() << "Queried feature cannot be found in FeatureMap: "
41 << feature_name;
42 }
43
JNI_FeatureMap_IsEnabled(JNIEnv * env,jlong jfeature_map,const android::JavaParamRef<jstring> & jfeature_name)44 static jboolean JNI_FeatureMap_IsEnabled(
45 JNIEnv* env,
46 jlong jfeature_map,
47 const android::JavaParamRef<jstring>& jfeature_name) {
48 FeatureMap* feature_map = reinterpret_cast<FeatureMap*>(jfeature_map);
49 const base::Feature* feature = feature_map->FindFeatureExposedToJava(
50 StringPiece(ConvertJavaStringToUTF8(env, jfeature_name)));
51 return base::FeatureList::IsEnabled(*feature);
52 }
53
JNI_FeatureMap_GetFieldTrialParamByFeature(JNIEnv * env,jlong jfeature_map,const JavaParamRef<jstring> & jfeature_name,const JavaParamRef<jstring> & jparam_name)54 static ScopedJavaLocalRef<jstring> JNI_FeatureMap_GetFieldTrialParamByFeature(
55 JNIEnv* env,
56 jlong jfeature_map,
57 const JavaParamRef<jstring>& jfeature_name,
58 const JavaParamRef<jstring>& jparam_name) {
59 FeatureMap* feature_map = reinterpret_cast<FeatureMap*>(jfeature_map);
60 const base::Feature* feature = feature_map->FindFeatureExposedToJava(
61 StringPiece(ConvertJavaStringToUTF8(env, jfeature_name)));
62 const std::string& param_name = ConvertJavaStringToUTF8(env, jparam_name);
63 const std::string& param_value =
64 base::GetFieldTrialParamValueByFeature(*feature, param_name);
65 return ConvertUTF8ToJavaString(env, param_value);
66 }
67
JNI_FeatureMap_GetFieldTrialParamByFeatureAsInt(JNIEnv * env,jlong jfeature_map,const JavaParamRef<jstring> & jfeature_name,const JavaParamRef<jstring> & jparam_name,const jint jdefault_value)68 static jint JNI_FeatureMap_GetFieldTrialParamByFeatureAsInt(
69 JNIEnv* env,
70 jlong jfeature_map,
71 const JavaParamRef<jstring>& jfeature_name,
72 const JavaParamRef<jstring>& jparam_name,
73 const jint jdefault_value) {
74 FeatureMap* feature_map = reinterpret_cast<FeatureMap*>(jfeature_map);
75 const base::Feature* feature = feature_map->FindFeatureExposedToJava(
76 StringPiece(ConvertJavaStringToUTF8(env, jfeature_name)));
77 const std::string& param_name = ConvertJavaStringToUTF8(env, jparam_name);
78 return base::GetFieldTrialParamByFeatureAsInt(*feature, param_name,
79 jdefault_value);
80 }
81
JNI_FeatureMap_GetFieldTrialParamByFeatureAsDouble(JNIEnv * env,jlong jfeature_map,const JavaParamRef<jstring> & jfeature_name,const JavaParamRef<jstring> & jparam_name,const jdouble jdefault_value)82 static jdouble JNI_FeatureMap_GetFieldTrialParamByFeatureAsDouble(
83 JNIEnv* env,
84 jlong jfeature_map,
85 const JavaParamRef<jstring>& jfeature_name,
86 const JavaParamRef<jstring>& jparam_name,
87 const jdouble jdefault_value) {
88 FeatureMap* feature_map = reinterpret_cast<FeatureMap*>(jfeature_map);
89 const base::Feature* feature = feature_map->FindFeatureExposedToJava(
90 StringPiece(ConvertJavaStringToUTF8(env, jfeature_name)));
91 const std::string& param_name = ConvertJavaStringToUTF8(env, jparam_name);
92 return base::GetFieldTrialParamByFeatureAsDouble(*feature, param_name,
93 jdefault_value);
94 }
95
JNI_FeatureMap_GetFieldTrialParamByFeatureAsBoolean(JNIEnv * env,jlong jfeature_map,const JavaParamRef<jstring> & jfeature_name,const JavaParamRef<jstring> & jparam_name,const jboolean jdefault_value)96 static jboolean JNI_FeatureMap_GetFieldTrialParamByFeatureAsBoolean(
97 JNIEnv* env,
98 jlong jfeature_map,
99 const JavaParamRef<jstring>& jfeature_name,
100 const JavaParamRef<jstring>& jparam_name,
101 const jboolean jdefault_value) {
102 FeatureMap* feature_map = reinterpret_cast<FeatureMap*>(jfeature_map);
103 const base::Feature* feature = feature_map->FindFeatureExposedToJava(
104 StringPiece(ConvertJavaStringToUTF8(env, jfeature_name)));
105 const std::string& param_name = ConvertJavaStringToUTF8(env, jparam_name);
106 return base::GetFieldTrialParamByFeatureAsBool(*feature, param_name,
107 jdefault_value);
108 }
109
110 static ScopedJavaLocalRef<jobjectArray>
JNI_FeatureMap_GetFlattedFieldTrialParamsForFeature(JNIEnv * env,jlong jfeature_map,const JavaParamRef<jstring> & jfeature_name)111 JNI_FeatureMap_GetFlattedFieldTrialParamsForFeature(
112 JNIEnv* env,
113 jlong jfeature_map,
114 const JavaParamRef<jstring>& jfeature_name) {
115 FeatureMap* feature_map = reinterpret_cast<FeatureMap*>(jfeature_map);
116 base::FieldTrialParams params;
117 std::vector<std::string> keys_and_values;
118 const base::Feature* feature = feature_map->FindFeatureExposedToJava(
119 StringPiece(ConvertJavaStringToUTF8(env, jfeature_name)));
120 if (feature && base::GetFieldTrialParamsByFeature(*feature, ¶ms)) {
121 for (const auto& param_pair : params) {
122 keys_and_values.push_back(param_pair.first);
123 keys_and_values.push_back(param_pair.second);
124 }
125 }
126 return base::android::ToJavaArrayOfStrings(env, keys_and_values);
127 }
128
129 } // namespace base::android
130