1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/ash/components/human_presence/human_presence_configuration.h"
#include <optional>
#include "ash/constants/ash_features.h"
#include "base/logging.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "chromeos/ash/components/dbus/hps/hps_service.pb.h"
namespace hps {
namespace {
// Default minimum amount of time for which a positive snooper presence will be
// reported.
constexpr base::TimeDelta kSnoopingProtectionPositiveWindowDefault =
base::Seconds(3);
// Default quick dim delay to configure power_manager.
constexpr base::TimeDelta kQuickDimDelayDefault = base::Seconds(10);
// Default quick lock delay to configure power_manager.
constexpr base::TimeDelta kQuickLockDelayDefault = base::Seconds(130);
// Default value determines whether send feedback to configure power_manager.
constexpr int kShouldSendFeedbackIfUndimmed = false;
// Returns either the integer parameter with the given name, or nullopt if the
// parameter can't be found or parsed.
std::optional<int> GetIntParam(const base::FieldTrialParams& params,
const std::string& feature_name,
const std::string& param_name) {
const std::string full_param_name =
base::StrCat({feature_name, "_", param_name});
const auto it = params.find(full_param_name);
if (it == params.end())
return std::nullopt;
int result;
if (!base::StringToInt(it->second, &result))
return std::nullopt;
return result;
}
// The config to use when no parameters are specified. We need to ensure that
// that empty params induce a working config (as required for, e.g., a
// chrome:://flags entry).
hps::FeatureConfig GetDefaultSnoopingProtectionConfig() {
hps::FeatureConfig config;
// Three consecutive positive/negative/unknown frames are required to change
// the second person presence state to reduce noise.
auto& filter_config = *config.mutable_consecutive_results_filter_config();
filter_config.set_positive_count_threshold(3);
filter_config.set_negative_count_threshold(3);
filter_config.set_uncertain_count_threshold(3);
filter_config.set_positive_score_threshold(40);
filter_config.set_negative_score_threshold(40);
return config;
}
hps::FeatureConfig GetDefaultLockOnLeaveConfig() {
hps::FeatureConfig config;
auto& filter_config = *config.mutable_consecutive_results_filter_config();
// Any positive result will undim the screen.
filter_config.set_positive_count_threshold(1);
// Only dim if at least two consecutive negative result.
filter_config.set_negative_count_threshold(2);
// UNKNOWN will not undim, but it will block quick dim, so it should also be
// fired with confidence.
filter_config.set_uncertain_count_threshold(2);
filter_config.set_positive_score_threshold(0);
filter_config.set_negative_score_threshold(0);
return config;
}
// This function constructs a FeatureConfig proto from feature parameters.
// The FeatureConfig contains one type of FilterConfig that will be used for
// enabling a human presence feature.
//
// If empty parameters are provided, a reasonable default is used.
//
// More details can be found at:
// src/platform2/hps/daemon/filters/filter_factory.h
std::optional<hps::FeatureConfig> ConstructFilterConfigFromFeatureParams(
const base::Feature& feature,
const hps::FeatureConfig& default_value) {
// Load current params map for the feature.
base::FieldTrialParams params;
base::GetFieldTrialParamsByFeature(feature, ¶ms);
// Returns default if no params is set.
if (params.empty()) {
return default_value;
}
const std::string& feature_name = feature.name;
const std::optional<int> filter_config_case =
GetIntParam(params, feature_name, "filter_config_case");
if (!filter_config_case.has_value()) {
LOG(ERROR) << "Filter config error: missing param filter_config_case for "
<< feature_name;
return std::nullopt;
}
switch (*filter_config_case) {
case hps::FeatureConfig::kBasicFilterConfig: {
hps::FeatureConfig config;
config.mutable_basic_filter_config();
return config;
}
case hps::FeatureConfig::kConsecutiveResultsFilterConfig: {
const std::optional<int> positive_count_threshold =
GetIntParam(params, feature_name, "positive_count_threshold");
const std::optional<int> negative_count_threshold =
GetIntParam(params, feature_name, "negative_count_threshold");
const std::optional<int> uncertain_count_threshold =
GetIntParam(params, feature_name, "uncertain_count_threshold");
const std::optional<int> positive_score_threshold =
GetIntParam(params, feature_name, "positive_score_threshold");
const std::optional<int> negative_score_threshold =
GetIntParam(params, feature_name, "negative_score_threshold");
if (!positive_count_threshold.has_value() ||
!negative_count_threshold.has_value() ||
!uncertain_count_threshold.has_value() ||
!positive_score_threshold.has_value() ||
!negative_score_threshold.has_value()) {
LOG(ERROR) << "Filter config error: missing params for "
"ConsecutiveResultsFilterConfig for "
<< feature_name;
return std::nullopt;
}
hps::FeatureConfig config;
auto& filter_config = *config.mutable_consecutive_results_filter_config();
filter_config.set_positive_count_threshold(*positive_count_threshold);
filter_config.set_negative_count_threshold(*negative_count_threshold);
filter_config.set_uncertain_count_threshold(*uncertain_count_threshold);
filter_config.set_positive_score_threshold(*positive_score_threshold);
filter_config.set_negative_score_threshold(*negative_score_threshold);
return config;
}
case hps::FeatureConfig::kAverageFilterConfig: {
const std::optional<int> average_window_size =
GetIntParam(params, feature_name, "average_window_size");
const std::optional<int> positive_score_threshold =
GetIntParam(params, feature_name, "positive_score_threshold");
const std::optional<int> negative_score_threshold =
GetIntParam(params, feature_name, "negative_score_threshold");
const std::optional<int> default_uncertain_score =
GetIntParam(params, feature_name, "default_uncertain_score");
if (!average_window_size.has_value() ||
!positive_score_threshold.has_value() ||
!negative_score_threshold.has_value() ||
!default_uncertain_score.has_value()) {
LOG(ERROR) << "Filter config error: missing params for "
"AverageFilterConfig for "
<< feature_name;
return std::nullopt;
}
hps::FeatureConfig config;
auto& filter_config = *config.mutable_average_filter_config();
filter_config.set_average_window_size(*average_window_size);
filter_config.set_positive_score_threshold(*positive_score_threshold);
filter_config.set_negative_score_threshold(*negative_score_threshold);
filter_config.set_default_uncertain_score(*default_uncertain_score);
return config;
}
default:
return std::nullopt;
}
}
} // namespace
std::optional<hps::FeatureConfig> GetEnableLockOnLeaveConfig() {
return ConstructFilterConfigFromFeatureParams(ash::features::kQuickDim,
GetDefaultLockOnLeaveConfig());
}
std::optional<hps::FeatureConfig> GetEnableSnoopingProtectionConfig() {
return ConstructFilterConfigFromFeatureParams(
ash::features::kSnoopingProtection, GetDefaultSnoopingProtectionConfig());
}
base::TimeDelta GetQuickDimDelay() {
const int quick_dim_ms = base::GetFieldTrialParamByFeatureAsInt(
ash::features::kQuickDim, "QuickDim_quick_dim_ms",
kQuickDimDelayDefault.InMilliseconds());
return base::Milliseconds(quick_dim_ms);
}
base::TimeDelta GetQuickLockDelay() {
const int quick_lock_ms = base::GetFieldTrialParamByFeatureAsInt(
ash::features::kQuickDim, "QuickDim_quick_lock_ms",
kQuickLockDelayDefault.InMilliseconds());
return base::Milliseconds(quick_lock_ms);
}
bool GetQuickDimFeedbackEnabled() {
return base::GetFieldTrialParamByFeatureAsBool(
ash::features::kQuickDim, "QuickDim_send_feedback_if_undimmed",
kShouldSendFeedbackIfUndimmed);
}
base::TimeDelta GetSnoopingProtectionPositiveWindow() {
const int pos_window_ms = base::GetFieldTrialParamByFeatureAsInt(
ash::features::kSnoopingProtection, "SnoopingProtection_pos_window_ms",
kSnoopingProtectionPositiveWindowDefault.InMilliseconds());
return base::Milliseconds(pos_window_ms);
}
} // namespace hps
|