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