1 /** 2 * Copyright (c) 2020, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "Experiments.h" 18 19 #include <android-base/format.h> 20 #include <netdutils/DumpWriter.h> 21 #include <string> 22 23 #include "util.h" 24 25 namespace android::net { 26 27 using netdutils::DumpWriter; 28 using netdutils::ScopedIndent; 29 30 Experiments* Experiments::getInstance() { 31 // Instantiated on first use. 32 static Experiments instance{getExperimentFlagInt}; 33 return &instance; 34 } 35 36 Experiments::Experiments(GetExperimentFlagIntFunction getExperimentFlagIntFunction) 37 : mGetExperimentFlagIntFunction(std::move(getExperimentFlagIntFunction)) { 38 updateInternal(); 39 } 40 41 void Experiments::update() { 42 updateInternal(); 43 } 44 45 void Experiments::dump(DumpWriter& dw) const { 46 std::lock_guard guard(mMutex); 47 dw.println("Experiments list: "); 48 for (const auto& [key, value] : mFlagsMapInt) { 49 ScopedIndent indentStats(dw); 50 if (value == Experiments::kFlagIntDefault) { 51 dw.println(fmt::format("{}: UNSET", key)); 52 } else { 53 dw.println(fmt::format("{}: {}", key, value)); 54 } 55 } 56 } 57 58 void Experiments::updateInternal() { 59 std::lock_guard guard(mMutex); 60 for (const auto& key : kExperimentFlagKeyList) { 61 mFlagsMapInt[key] = mGetExperimentFlagIntFunction(key, Experiments::kFlagIntDefault); 62 } 63 } 64 65 int Experiments::getFlag(std::string_view key, int defaultValue) const { 66 std::lock_guard guard(mMutex); 67 auto it = mFlagsMapInt.find(key); 68 if (it != mFlagsMapInt.end() && it->second != Experiments::kFlagIntDefault) { 69 return it->second; 70 } 71 return defaultValue; 72 } 73 74 } // namespace android::net 75