1 /*
2  * Copyright (C) 2019 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 package com.android.server.wifi;
18 
19 import static com.android.server.wifi.util.InformationElementUtil.BssLoad.CHANNEL_UTILIZATION_SCALE;
20 
21 import android.content.Context;
22 import android.os.Handler;
23 import android.provider.DeviceConfig;
24 import android.provider.Settings;
25 import android.util.ArraySet;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 import com.android.wifi.flags.FeatureFlags;
29 
30 import java.util.Collections;
31 import java.util.Optional;
32 import java.util.Set;
33 import java.util.concurrent.TimeUnit;
34 import java.util.function.Consumer;
35 
36 /**
37  * This class allows getting all configurable flags from DeviceConfig.
38  */
39 public class DeviceConfigFacade {
40     private final Context mContext;
41     private final WifiMetrics mWifiMetrics;
42 
43     private static final String NAMESPACE = "wifi";
44     private final FeatureFlags mFeatureFlags;
45 
46     // Default values of fields
47     @VisibleForTesting
48     protected static final int DEFAULT_ABNORMAL_CONNECTION_DURATION_MS =
49             (int) TimeUnit.SECONDS.toMillis(30);
50     // Default duration for evaluating Wifi condition to trigger a data stall
51     // measured in milliseconds
52     public static final int DEFAULT_DATA_STALL_DURATION_MS = 1500;
53     // Default threshold of Tx throughput below which to trigger a data stall measured in Kbps
54     public static final int DEFAULT_DATA_STALL_TX_TPUT_THR_KBPS = 2000;
55     // Default threshold of Rx throughput below which to trigger a data stall measured in Kbps
56     public static final int DEFAULT_DATA_STALL_RX_TPUT_THR_KBPS = 2000;
57     // Default threshold of Tx packet error rate above which to trigger a data stall in percentage
58     public static final int DEFAULT_DATA_STALL_TX_PER_THR = 90;
59     // Default threshold of CCA level above which to trigger a data stall
60     public static final int DEFAULT_DATA_STALL_CCA_LEVEL_THR = CHANNEL_UTILIZATION_SCALE;
61     // Default low threshold of L2 sufficient Tx throughput in Kbps
62     public static final int DEFAULT_TX_TPUT_SUFFICIENT_THR_LOW_KBPS = 2000;
63     // Default high threshold of L2 sufficient Tx throughput in Kbps
64     public static final int DEFAULT_TX_TPUT_SUFFICIENT_THR_HIGH_KBPS = 8000;
65     // Default low threshold of L2 sufficient Rx throughput in Kbps
66     public static final int DEFAULT_RX_TPUT_SUFFICIENT_THR_LOW_KBPS = 2000;
67     // Default high threshold of L2 sufficient Rx throughput in Kbps
68     public static final int DEFAULT_RX_TPUT_SUFFICIENT_THR_HIGH_KBPS = 8000;
69     // Numerator part of default threshold of L2 throughput over L3 throughput ratio
70     public static final int DEFAULT_TPUT_SUFFICIENT_RATIO_THR_NUM = 2;
71     // Denominator part of default threshold of L2 throughput over L3 throughput ratio
72     public static final int DEFAULT_TPUT_SUFFICIENT_RATIO_THR_DEN = 1;
73     // Default threshold of Tx packet per second
74     public static final int DEFAULT_TX_PACKET_PER_SECOND_THR = 2;
75     // Default threshold of Rx packet per second
76     public static final int DEFAULT_RX_PACKET_PER_SECOND_THR = 2;
77     // Default high threshold values for various connection/disconnection cases
78     // All of them are in percent with respect to connection attempts
79     static final int DEFAULT_CONNECTION_FAILURE_HIGH_THR_PERCENT = 40;
80     static final int DEFAULT_CONNECTION_FAILURE_DISCONNECTION_HIGH_THR_PERCENT = 30;
81     static final int DEFAULT_ASSOC_REJECTION_HIGH_THR_PERCENT = 30;
82     static final int DEFAULT_ASSOC_TIMEOUT_HIGH_THR_PERCENT = 30;
83     static final int DEFAULT_AUTH_FAILURE_HIGH_THR_PERCENT = 30;
84     static final int DEFAULT_SHORT_CONNECTION_NONLOCAL_HIGH_THR_PERCENT = 20;
85     static final int DEFAULT_DISCONNECTION_NONLOCAL_HIGH_THR_PERCENT = 25;
86     // Default health monitor abnormal count minimum for various cases
87     static final int DEFAULT_CONNECTION_FAILURE_COUNT_MIN = 6;
88     static final int DEFAULT_CONNECTION_FAILURE_DISCONNECTION_COUNT_MIN = 5;
89     static final int DEFAULT_ASSOC_REJECTION_COUNT_MIN  = 3;
90     static final int DEFAULT_ASSOC_TIMEOUT_COUNT_MIN  = 3;
91     static final int DEFAULT_AUTH_FAILURE_COUNT_MIN  = 3;
92     static final int DEFAULT_SHORT_CONNECTION_NONLOCAL_COUNT_MIN  = 3;
93     static final int DEFAULT_DISCONNECTION_NONLOCAL_COUNT_MIN  = 3;
94     // Numerator part of default ratio threshold values for all cases
95     static final int DEFAULT_HEALTH_MONITOR_RATIO_THR_NUMERATOR = 4;
96     // Denominator part of ratio threshold for all cases
97     static final int HEALTH_MONITOR_RATIO_THR_DENOMINATOR = 2;
98     // Minimum RSSI in dBm for connection stats collection
99     // Connection or disconnection events with RSSI below this threshold are not
100     // included in connection stats collection.
101     static final int DEFAULT_HEALTH_MONITOR_MIN_RSSI_THR_DBM = -68;
102     // Default minimum number of connection attempts to qualify daily detection
103     static final int DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT = 10;
104     // Default minimum wait time between two bug report captures
105     static final int DEFAULT_BUG_REPORT_MIN_WINDOW_MS = 3_600_000;
106     // Default report-high threshold to take-bug-report threshold ratio.
107     // It should be larger than 1 since the bar to take bugreport should be higher.
108     static final int DEFAULT_BUG_REPORT_THRESHOLD_EXTRA_RATIO = 2;
109     // Default overlapping connection duration threshold in ms to trigger bug report
110     static final int DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS = 75_000;
111     // At low traffic, Tx link speed values below the following threshold
112     // are ignored because it could be due to low rate management frames
113     static final int DEFAULT_TX_LINK_SPEED_LOW_THRESHOLD_MBPS = 9;
114     // At low traffic, Rx link speed values below the following threshold
115     // are ignored because it could be due to low rate management frames
116     static final int DEFAULT_RX_LINK_SPEED_LOW_THRESHOLD_MBPS = 9;
117     // Default health monitor short connection duration threshold in ms
118     static final int DEFAULT_HEALTH_MONITOR_SHORT_CONNECTION_DURATION_THR_MS = 20_000;
119 
120     // Default mask for abnormal disconnection reason codes.
121     // Each bit of mask corresponds to a reason code defined in 802.11 standard section 9.4.1.7
122     // For example, b0 for reason code 0, b1 for reason code 1, etc.
123     // Bits below are abnormal disconnection reasons and thus are set to 1
124     // b0: reserved (e.g., STA heartbeat failure)
125     // b2: invalid auth
126     // b4: disassociated due to inactivity
127     // b6 and b7: invalid class 2 and 3 frames
128     // b34: disassociated due to missing ACKs
129     static final long DEFAULT_ABNORMAL_DISCONNECTION_REASON_CODE_MASK = 0x4_0000_00d5L;
130     // Default maximum interval between last RSSI poll and disconnection
131     static final int DEFAULT_HEALTH_MONITOR_RSSI_POLL_VALID_TIME_MS = 2_100;
132     // Default maximum interval between scan and connection attempt in non-stationary state
133     static final int DEFAULT_NONSTATIONARY_SCAN_RSSI_VALID_TIME_MS = 5_000;
134     // Default maximum interval between scan and connection attempt in stationary state
135     static final int DEFAULT_STATIONARY_SCAN_RSSI_VALID_TIME_MS = 8_000;
136     // Default health monitor firmware alert valid time.
137     // -1 disables firmware alert time check
138     static final int DEFAULT_HEALTH_MONITOR_FW_ALERT_VALID_TIME_MS = -1;
139     // Default minimum confirmation duration for sending network score to connectivity service
140     // when score breaches low. The actual confirmation duration is longer in general and it
141     // depends on the score evaluation period normally controlled by
142     // 'com.android.wifi.resources.R' config_wifiPollRssiIntervalMilliseconds.
143     static final int DEFAULT_MIN_CONFIRMATION_DURATION_SEND_LOW_SCORE_MS = 5000;
144     // Default minimum confirmation duration for sending network score to connectivity service
145     // when score breaches high. The actual confirmation duration is longer in general and it
146     // depends on the score evaluation period normally controlled by
147     // 'com.android.wifi.resources.R' config_wifiPollRssiIntervalMilliseconds.
148     static final int DEFAULT_MIN_CONFIRMATION_DURATION_SEND_HIGH_SCORE_MS = 0;
149     // Default RSSI threshold in dBm above which low score is not sent to connectivity service
150     // when external scorer takes action.
151     static final int DEFAULT_RSSI_THRESHOLD_NOT_SEND_LOW_SCORE_TO_CS_DBM = -67;
152     // Maximum traffic stats threshold for link bandwidth estimator
153     static final int DEFAULT_TRAFFIC_STATS_THRESHOLD_MAX_KB = 8000;
154     static final int DEFAULT_BANDWIDTH_ESTIMATOR_TIME_CONSTANT_LARGE_SEC = 6;
155     // Cached values of fields updated via updateDeviceConfigFlags()
156     private boolean mIsAbnormalConnectionBugreportEnabled;
157     private int mAbnormalConnectionDurationMs;
158     private int mDataStallDurationMs;
159     private int mDataStallTxTputThrKbps;
160     private int mDataStallRxTputThrKbps;
161     private int mDataStallTxPerThr;
162     private int mDataStallCcaLevelThr;
163     private int mTxTputSufficientLowThrKbps;
164     private int mTxTputSufficientHighThrKbps;
165     private int mRxTputSufficientLowThrKbps;
166     private int mRxTputSufficientHighThrKbps;
167     private int mTputSufficientRatioThrNum;
168     private int mTputSufficientRatioThrDen;
169     private int mTxPktPerSecondThr;
170     private int mRxPktPerSecondThr;
171     private int mConnectionFailureHighThrPercent;
172     private int mConnectionFailureCountMin;
173     private int mConnectionFailureDisconnectionHighThrPercent;
174     private int mConnectionFailureDisconnectionCountMin;
175     private int mAssocRejectionHighThrPercent;
176     private int mAssocRejectionCountMin;
177     private int mAssocTimeoutHighThrPercent;
178     private int mAssocTimeoutCountMin;
179     private int mAuthFailureHighThrPercent;
180     private int mAuthFailureCountMin;
181     private int mShortConnectionNonlocalHighThrPercent;
182     private int mShortConnectionNonlocalCountMin;
183     private int mDisconnectionNonlocalHighThrPercent;
184     private int mDisconnectionNonlocalCountMin;
185     private int mHealthMonitorRatioThrNumerator;
186     private int mHealthMonitorMinRssiThrDbm;
187     private Set<String> mRandomizationFlakySsidHotlist;
188     private Set<String> mNonPersistentMacRandomizationSsidAllowlist;
189     private Set<String> mNonPersistentMacRandomizationSsidBlocklist;
190     private boolean mIsAbnormalConnectionFailureBugreportEnabled;
191     private boolean mIsAbnormalDisconnectionBugreportEnabled;
192     private int mHealthMonitorMinNumConnectionAttempt;
193     private int mBugReportMinWindowMs;
194     private int mBugReportThresholdExtraRatio;
195     private boolean mWifiBatterySaverEnabled;
196     private boolean mIsOverlappingConnectionBugreportEnabled;
197     private int mOverlappingConnectionDurationThresholdMs;
198     private int mTxLinkSpeedLowThresholdMbps;
199     private int mRxLinkSpeedLowThresholdMbps;
200     private int mHealthMonitorShortConnectionDurationThrMs;
201     private long mAbnormalDisconnectionReasonCodeMask;
202     private int mHealthMonitorRssiPollValidTimeMs;
203     private int mNonstationaryScanRssiValidTimeMs;
204     private int mStationaryScanRssiValidTimeMs;
205     private int mHealthMonitorFwAlertValidTimeMs;
206     private int mMinConfirmationDurationSendLowScoreMs;
207     private int mMinConfirmationDurationSendHighScoreMs;
208     private int mRssiThresholdNotSendLowScoreToCsDbm;
209     private int mTrafficStatsThresholdMaxKbyte;
210     private int mBandwidthEstimatorLargeTimeConstantSec;
211     private boolean mInterfaceFailureBugreportEnabled;
212     private boolean mP2pFailureBugreportEnabled;
213     private boolean mApmEnhancementEnabled;
214     private boolean mAwareSuspensionEnabled;
215     private boolean mHighPerfLockDeprecated;
216     private Optional<Boolean> mOobPseudonymEnabled = Optional.empty();
217     private Consumer<Boolean> mOobPseudonymFeatureFlagChangedListener = null;
218     private boolean mApplicationQosPolicyApiEnabled;
219     private boolean mAdjustPollRssiIntervalEnabled;
220     private boolean mSoftwarePnoEnabled;
221     private boolean mIncludePasspointSsidsInPnoScans;
222     private boolean mHandleRssiOrganicKernelFailuresEnabled;
223     private Set<String> mDisabledAutoBugreports = Collections.EMPTY_SET;
224 
225     private final Handler mWifiHandler;
226 
DeviceConfigFacade(Context context, Handler handler, WifiMetrics wifiMetrics)227     public DeviceConfigFacade(Context context, Handler handler, WifiMetrics wifiMetrics) {
228         mContext = context;
229         mWifiMetrics = wifiMetrics;
230         mWifiHandler = handler;
231         mFeatureFlags = new com.android.wifi.flags.FeatureFlagsImpl();
232         updateDeviceConfigFlags();
233         DeviceConfig.addOnPropertiesChangedListener(
234                 NAMESPACE,
235                 command -> handler.post(command),
236                 properties -> {
237                     updateDeviceConfigFlags();
238                 });
239     }
240 
updateDeviceConfigFlags()241     private void updateDeviceConfigFlags() {
242         mIsAbnormalConnectionBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
243                 "abnormal_connection_bugreport_enabled", false);
244         mAbnormalConnectionDurationMs = DeviceConfig.getInt(NAMESPACE,
245                 "abnormal_connection_duration_ms",
246                 DEFAULT_ABNORMAL_CONNECTION_DURATION_MS);
247 
248         mDataStallDurationMs = DeviceConfig.getInt(NAMESPACE,
249                 "data_stall_duration_ms", DEFAULT_DATA_STALL_DURATION_MS);
250         mDataStallTxTputThrKbps = DeviceConfig.getInt(NAMESPACE,
251                 "data_stall_tx_tput_thr_kbps", DEFAULT_DATA_STALL_TX_TPUT_THR_KBPS);
252         mDataStallRxTputThrKbps = DeviceConfig.getInt(NAMESPACE,
253                 "data_stall_rx_tput_thr_kbps", DEFAULT_DATA_STALL_RX_TPUT_THR_KBPS);
254         mDataStallTxPerThr = DeviceConfig.getInt(NAMESPACE,
255                 "data_stall_tx_per_thr", DEFAULT_DATA_STALL_TX_PER_THR);
256         mDataStallCcaLevelThr = DeviceConfig.getInt(NAMESPACE,
257                 "data_stall_cca_level_thr", DEFAULT_DATA_STALL_CCA_LEVEL_THR);
258         mWifiMetrics.setDataStallDurationMs(mDataStallDurationMs);
259         mWifiMetrics.setDataStallTxTputThrKbps(mDataStallTxTputThrKbps);
260         mWifiMetrics.setDataStallRxTputThrKbps(mDataStallRxTputThrKbps);
261         mWifiMetrics.setDataStallTxPerThr(mDataStallTxPerThr);
262         mWifiMetrics.setDataStallCcaLevelThr(mDataStallCcaLevelThr);
263 
264         mTxTputSufficientLowThrKbps = DeviceConfig.getInt(NAMESPACE,
265                 "tput_sufficient_low_thr_kbps", DEFAULT_TX_TPUT_SUFFICIENT_THR_LOW_KBPS);
266         mTxTputSufficientHighThrKbps = DeviceConfig.getInt(NAMESPACE,
267                 "tput_sufficient_high_thr_kbps", DEFAULT_TX_TPUT_SUFFICIENT_THR_HIGH_KBPS);
268         mRxTputSufficientLowThrKbps = DeviceConfig.getInt(NAMESPACE,
269                 "rx_tput_sufficient_low_thr_kbps", DEFAULT_RX_TPUT_SUFFICIENT_THR_LOW_KBPS);
270         mRxTputSufficientHighThrKbps = DeviceConfig.getInt(NAMESPACE,
271                 "rx_tput_sufficient_high_thr_kbps", DEFAULT_RX_TPUT_SUFFICIENT_THR_HIGH_KBPS);
272         mTputSufficientRatioThrNum = DeviceConfig.getInt(NAMESPACE,
273                 "tput_sufficient_ratio_thr_num", DEFAULT_TPUT_SUFFICIENT_RATIO_THR_NUM);
274         mTputSufficientRatioThrDen = DeviceConfig.getInt(NAMESPACE,
275                 "tput_sufficient_ratio_thr_den", DEFAULT_TPUT_SUFFICIENT_RATIO_THR_DEN);
276         mTxPktPerSecondThr = DeviceConfig.getInt(NAMESPACE,
277                 "tx_pkt_per_second_thr", DEFAULT_TX_PACKET_PER_SECOND_THR);
278         mRxPktPerSecondThr = DeviceConfig.getInt(NAMESPACE,
279                 "rx_pkt_per_second_thr", DEFAULT_RX_PACKET_PER_SECOND_THR);
280 
281         mConnectionFailureHighThrPercent = DeviceConfig.getInt(NAMESPACE,
282                 "connection_failure_high_thr_percent",
283                 DEFAULT_CONNECTION_FAILURE_HIGH_THR_PERCENT);
284         mConnectionFailureCountMin = DeviceConfig.getInt(NAMESPACE,
285                 "connection_failure_count_min",
286                 DEFAULT_CONNECTION_FAILURE_COUNT_MIN);
287         mConnectionFailureDisconnectionHighThrPercent = DeviceConfig.getInt(NAMESPACE,
288                 "connection_failure_disconnection_high_thr_percent",
289                 DEFAULT_CONNECTION_FAILURE_DISCONNECTION_HIGH_THR_PERCENT);
290         mConnectionFailureDisconnectionCountMin = DeviceConfig.getInt(NAMESPACE,
291                 "connection_failure_disconnection_count_min",
292                 DEFAULT_CONNECTION_FAILURE_DISCONNECTION_COUNT_MIN);
293         mAssocRejectionHighThrPercent = DeviceConfig.getInt(NAMESPACE,
294                 "assoc_rejection_high_thr_percent",
295                 DEFAULT_ASSOC_REJECTION_HIGH_THR_PERCENT);
296         mAssocRejectionCountMin = DeviceConfig.getInt(NAMESPACE,
297                 "assoc_rejection_count_min",
298                 DEFAULT_ASSOC_REJECTION_COUNT_MIN);
299         mAssocTimeoutHighThrPercent = DeviceConfig.getInt(NAMESPACE,
300                 "assoc_timeout_high_thr_percent",
301                 DEFAULT_ASSOC_TIMEOUT_HIGH_THR_PERCENT);
302         mAssocTimeoutCountMin = DeviceConfig.getInt(NAMESPACE,
303                 "assoc_timeout_count_min",
304                 DEFAULT_ASSOC_TIMEOUT_COUNT_MIN);
305         mAuthFailureHighThrPercent = DeviceConfig.getInt(NAMESPACE,
306                 "auth_failure_high_thr_percent",
307                 DEFAULT_AUTH_FAILURE_HIGH_THR_PERCENT);
308         mAuthFailureCountMin = DeviceConfig.getInt(NAMESPACE,
309                 "auth_failure_count_min",
310                 DEFAULT_AUTH_FAILURE_COUNT_MIN);
311         mShortConnectionNonlocalHighThrPercent = DeviceConfig.getInt(NAMESPACE,
312                 "short_connection_nonlocal_high_thr_percent",
313                 DEFAULT_SHORT_CONNECTION_NONLOCAL_HIGH_THR_PERCENT);
314         mShortConnectionNonlocalCountMin = DeviceConfig.getInt(NAMESPACE,
315                 "short_connection_nonlocal_count_min",
316                 DEFAULT_SHORT_CONNECTION_NONLOCAL_COUNT_MIN);
317         mDisconnectionNonlocalHighThrPercent = DeviceConfig.getInt(NAMESPACE,
318                 "disconnection_nonlocal_high_thr_percent",
319                 DEFAULT_DISCONNECTION_NONLOCAL_HIGH_THR_PERCENT);
320         mDisconnectionNonlocalCountMin = DeviceConfig.getInt(NAMESPACE,
321                 "disconnection_nonlocal_count_min",
322                 DEFAULT_DISCONNECTION_NONLOCAL_COUNT_MIN);
323         mHealthMonitorRatioThrNumerator = DeviceConfig.getInt(NAMESPACE,
324                 "health_monitor_ratio_thr_numerator",
325                 DEFAULT_HEALTH_MONITOR_RATIO_THR_NUMERATOR);
326         mHealthMonitorMinRssiThrDbm = DeviceConfig.getInt(NAMESPACE,
327                 "health_monitor_min_rssi_thr_dbm",
328                 DEFAULT_HEALTH_MONITOR_MIN_RSSI_THR_DBM);
329 
330         mRandomizationFlakySsidHotlist =
331                 getUnmodifiableSetQuoted("randomization_flaky_ssid_hotlist");
332         mNonPersistentMacRandomizationSsidAllowlist =
333                 getUnmodifiableSetQuoted("aggressive_randomization_ssid_allowlist");
334         mNonPersistentMacRandomizationSsidBlocklist =
335                 getUnmodifiableSetQuoted("aggressive_randomization_ssid_blocklist");
336 
337         mIsAbnormalConnectionFailureBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
338                 "abnormal_connection_failure_bugreport_enabled", false);
339         mIsAbnormalDisconnectionBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
340                 "abnormal_disconnection_bugreport_enabled", false);
341         mHealthMonitorMinNumConnectionAttempt = DeviceConfig.getInt(NAMESPACE,
342                 "health_monitor_min_num_connection_attempt",
343                 DEFAULT_HEALTH_MONITOR_MIN_NUM_CONNECTION_ATTEMPT);
344         mBugReportMinWindowMs = DeviceConfig.getInt(NAMESPACE,
345                 "bug_report_min_window_ms",
346                 DEFAULT_BUG_REPORT_MIN_WINDOW_MS);
347         mBugReportThresholdExtraRatio = DeviceConfig.getInt(NAMESPACE,
348                 "report_bug_report_threshold_extra_ratio",
349                 DEFAULT_BUG_REPORT_THRESHOLD_EXTRA_RATIO);
350         mIsOverlappingConnectionBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
351                 "overlapping_connection_bugreport_enabled", false);
352         mOverlappingConnectionDurationThresholdMs = DeviceConfig.getInt(NAMESPACE,
353                 "overlapping_connection_duration_threshold_ms",
354                 DEFAULT_OVERLAPPING_CONNECTION_DURATION_THRESHOLD_MS);
355         mTxLinkSpeedLowThresholdMbps = DeviceConfig.getInt(NAMESPACE,
356                 "tx_link_speed_low_threshold_mbps",
357                 DEFAULT_TX_LINK_SPEED_LOW_THRESHOLD_MBPS);
358         mRxLinkSpeedLowThresholdMbps = DeviceConfig.getInt(NAMESPACE,
359                 "rx_link_speed_low_threshold_mbps",
360                 DEFAULT_RX_LINK_SPEED_LOW_THRESHOLD_MBPS);
361         mWifiBatterySaverEnabled = DeviceConfig.getBoolean(NAMESPACE, "battery_saver_enabled",
362                 false);
363         mHealthMonitorShortConnectionDurationThrMs = DeviceConfig.getInt(NAMESPACE,
364                 "health_monitor_short_connection_duration_thr_ms",
365                 DEFAULT_HEALTH_MONITOR_SHORT_CONNECTION_DURATION_THR_MS);
366         mAbnormalDisconnectionReasonCodeMask = DeviceConfig.getLong(NAMESPACE,
367                 "abnormal_disconnection_reason_code_mask",
368                 DEFAULT_ABNORMAL_DISCONNECTION_REASON_CODE_MASK);
369         mHealthMonitorRssiPollValidTimeMs = DeviceConfig.getInt(NAMESPACE,
370                 "health_monitor_rssi_poll_valid_time_ms",
371                 DEFAULT_HEALTH_MONITOR_RSSI_POLL_VALID_TIME_MS);
372         mNonstationaryScanRssiValidTimeMs = DeviceConfig.getInt(NAMESPACE,
373                 "nonstationary_scan_rssi_valid_time_ms",
374                 DEFAULT_NONSTATIONARY_SCAN_RSSI_VALID_TIME_MS);
375         mStationaryScanRssiValidTimeMs = DeviceConfig.getInt(NAMESPACE,
376                 "stationary_scan_rssi_valid_time_ms",
377                 DEFAULT_STATIONARY_SCAN_RSSI_VALID_TIME_MS);
378         mHealthMonitorFwAlertValidTimeMs = DeviceConfig.getInt(NAMESPACE,
379                 "health_monitor_fw_alert_valid_time_ms",
380                 DEFAULT_HEALTH_MONITOR_FW_ALERT_VALID_TIME_MS);
381         mWifiMetrics.setHealthMonitorRssiPollValidTimeMs(mHealthMonitorRssiPollValidTimeMs);
382         mMinConfirmationDurationSendLowScoreMs = DeviceConfig.getInt(NAMESPACE,
383                 "min_confirmation_duration_send_low_score_ms",
384                 DEFAULT_MIN_CONFIRMATION_DURATION_SEND_LOW_SCORE_MS);
385         mMinConfirmationDurationSendHighScoreMs = DeviceConfig.getInt(NAMESPACE,
386                 "min_confirmation_duration_send_high_score_ms",
387                 DEFAULT_MIN_CONFIRMATION_DURATION_SEND_HIGH_SCORE_MS);
388         mRssiThresholdNotSendLowScoreToCsDbm = DeviceConfig.getInt(NAMESPACE,
389                 "rssi_threshold_not_send_low_score_to_cs_dbm",
390                 DEFAULT_RSSI_THRESHOLD_NOT_SEND_LOW_SCORE_TO_CS_DBM);
391         mTrafficStatsThresholdMaxKbyte = DeviceConfig.getInt(NAMESPACE,
392                 "traffic_stats_threshold_max_kbyte", DEFAULT_TRAFFIC_STATS_THRESHOLD_MAX_KB);
393         mBandwidthEstimatorLargeTimeConstantSec = DeviceConfig.getInt(NAMESPACE,
394                 "bandwidth_estimator_time_constant_large_sec",
395                 DEFAULT_BANDWIDTH_ESTIMATOR_TIME_CONSTANT_LARGE_SEC);
396         mInterfaceFailureBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
397                 "interface_failure_bugreport_enabled", false);
398         mP2pFailureBugreportEnabled = DeviceConfig.getBoolean(NAMESPACE,
399                 "p2p_failure_bugreport_enabled", false);
400         mApmEnhancementEnabled = DeviceConfig.getBoolean(NAMESPACE,
401                 "apm_enhancement_enabled", false);
402         mAwareSuspensionEnabled = DeviceConfig.getBoolean(NAMESPACE,
403                 "aware_suspension_enabled", true);
404         mHighPerfLockDeprecated = DeviceConfig.getBoolean(NAMESPACE,
405                 "high_perf_lock_deprecated", true);
406         boolean oobPseudonymEnabled = DeviceConfig.getBoolean(NAMESPACE,
407                 "oob_pseudonym_enabled", true);
408         if (mOobPseudonymEnabled.isPresent()
409                 && mOobPseudonymEnabled.get() != oobPseudonymEnabled
410                 && mOobPseudonymFeatureFlagChangedListener != null) {
411             mWifiHandler.post(
412                     () -> mOobPseudonymFeatureFlagChangedListener.accept(oobPseudonymEnabled));
413         }
414         mOobPseudonymEnabled = Optional.of(oobPseudonymEnabled);
415         mApplicationQosPolicyApiEnabled = DeviceConfig.getBoolean(NAMESPACE,
416                 "application_qos_policy_api_enabled", true);
417         mAdjustPollRssiIntervalEnabled =
418                 DeviceConfig.getBoolean(NAMESPACE, "adjust_poll_rssi_interval_enabled", false);
419         mSoftwarePnoEnabled = DeviceConfig.getBoolean(NAMESPACE,
420                 "software_pno_enabled", false);
421         mIncludePasspointSsidsInPnoScans = DeviceConfig.getBoolean(NAMESPACE,
422                 "include_passpoint_ssids_in_pno_scans", true);
423         mHandleRssiOrganicKernelFailuresEnabled = DeviceConfig.getBoolean(NAMESPACE,
424                 "handle_rssi_organic_kernel_failures_enabled", true);
425         mDisabledAutoBugreports = getDisabledAutoBugreports();
426     }
427 
getDisabledAutoBugreports()428     private Set<String> getDisabledAutoBugreports() {
429         String rawList = DeviceConfig.getString(NAMESPACE,
430                 "disabled_auto_bugreport_title_and_description", null);
431         if (rawList == null || rawList.isEmpty()) {
432             return Collections.EMPTY_SET;
433         }
434         Set<String> result = new ArraySet<>();
435         String[] list = rawList.split(",");
436         for (String cur : list) {
437             if (cur.length() == 0) {
438                 continue;
439             }
440             result.add(cur);
441         }
442         return Collections.unmodifiableSet(result);
443     }
444 
getUnmodifiableSetQuoted(String key)445     private Set<String> getUnmodifiableSetQuoted(String key) {
446         String rawList = DeviceConfig.getString(NAMESPACE, key, "");
447         Set<String> result = new ArraySet<>();
448         String[] list = rawList.split(",");
449         for (String cur : list) {
450             if (cur.length() == 0) {
451                 continue;
452             }
453             result.add("\"" + cur + "\"");
454         }
455         return Collections.unmodifiableSet(result);
456     }
457 
458     /**
459      * Gets the feature flag for reporting abnormally long connections.
460      */
isAbnormalConnectionBugreportEnabled()461     public boolean isAbnormalConnectionBugreportEnabled() {
462         return mIsAbnormalConnectionBugreportEnabled;
463     }
464 
465     /**
466      * Gets the threshold for classifying abnormally long connections.
467      */
getAbnormalConnectionDurationMs()468     public int getAbnormalConnectionDurationMs() {
469         return mAbnormalConnectionDurationMs;
470     }
471 
472     /**
473      * Gets the duration of evaluating Wifi condition to trigger a data stall.
474      */
getDataStallDurationMs()475     public int getDataStallDurationMs() {
476         return mDataStallDurationMs;
477     }
478 
479     /**
480      * Gets the threshold of Tx throughput below which to trigger a data stall.
481      */
getDataStallTxTputThrKbps()482     public int getDataStallTxTputThrKbps() {
483         return mDataStallTxTputThrKbps;
484     }
485 
486     /**
487      * Gets the threshold of Rx throughput below which to trigger a data stall.
488      */
getDataStallRxTputThrKbps()489     public int getDataStallRxTputThrKbps() {
490         return mDataStallRxTputThrKbps;
491     }
492 
493     /**
494      * Gets the threshold of Tx packet error rate above which to trigger a data stall.
495      */
getDataStallTxPerThr()496     public int getDataStallTxPerThr() {
497         return mDataStallTxPerThr;
498     }
499 
500     /**
501      * Gets the threshold of CCA level above which to trigger a data stall.
502      */
getDataStallCcaLevelThr()503     public int getDataStallCcaLevelThr() {
504         return mDataStallCcaLevelThr;
505     }
506 
507     /**
508      * Gets the low threshold of L2 throughput below which L2 throughput is always insufficient
509      */
getTxTputSufficientLowThrKbps()510     public int getTxTputSufficientLowThrKbps() {
511         return mTxTputSufficientLowThrKbps;
512     }
513 
514     /**
515      * Gets the high threshold of L2 throughput above which L2 throughput is always sufficient
516      */
getTxTputSufficientHighThrKbps()517     public int getTxTputSufficientHighThrKbps() {
518         return mTxTputSufficientHighThrKbps;
519     }
520 
521     /**
522      * Gets the low threshold of L2 throughput below which L2 Rx throughput is always insufficient
523      */
getRxTputSufficientLowThrKbps()524     public int getRxTputSufficientLowThrKbps() {
525         return mRxTputSufficientLowThrKbps;
526     }
527 
528     /**
529      * Gets the high threshold of L2 throughput above which L2 Rx throughput is always sufficient
530      */
getRxTputSufficientHighThrKbps()531     public int getRxTputSufficientHighThrKbps() {
532         return mRxTputSufficientHighThrKbps;
533     }
534 
535     /**
536      * Gets the numerator part of L2 throughput over L3 throughput ratio sufficiency threshold
537      * above which L2 throughput is sufficient
538      */
getTputSufficientRatioThrNum()539     public int getTputSufficientRatioThrNum() {
540         return mTputSufficientRatioThrNum;
541     }
542 
543     /**
544      * Gets the denominator part of L2 throughput over L3 throughput ratio sufficiency threshold
545      * above which L2 throughput is sufficient
546      */
getTputSufficientRatioThrDen()547     public int getTputSufficientRatioThrDen() {
548         return mTputSufficientRatioThrDen;
549     }
550 
551     /**
552      * Gets the threshold of Tx packet per second
553      * below which Tx throughput sufficiency check will always pass
554      */
getTxPktPerSecondThr()555     public int getTxPktPerSecondThr() {
556         return mTxPktPerSecondThr;
557     }
558 
559     /**
560      * Gets the threshold of Rx packet per second
561      * below which Rx throughput sufficiency check will always pass
562      */
getRxPktPerSecondThr()563     public int getRxPktPerSecondThr() {
564         return mRxPktPerSecondThr;
565     }
566 
567     /**
568      * Gets the high threshold of connection failure rate in percent
569      */
getConnectionFailureHighThrPercent()570     public int getConnectionFailureHighThrPercent() {
571         return mConnectionFailureHighThrPercent;
572     }
573 
574     /**
575      * Gets connection-failure-due-to-disconnection min count
576      */
getConnectionFailureDisconnectionCountMin()577     public int getConnectionFailureDisconnectionCountMin() {
578         return mConnectionFailureDisconnectionCountMin;
579     }
580 
581     /**
582      * Gets the high threshold of connection-failure-due-to-disconnection rate in percent
583      */
getConnectionFailureDisconnectionHighThrPercent()584     public int getConnectionFailureDisconnectionHighThrPercent() {
585         return mConnectionFailureDisconnectionHighThrPercent;
586     }
587 
588     /**
589      * Gets connection failure min count
590      */
getConnectionFailureCountMin()591     public int getConnectionFailureCountMin() {
592         return mConnectionFailureCountMin;
593     }
594 
595     /**
596      * Gets the high threshold of association rejection rate in percent
597      */
getAssocRejectionHighThrPercent()598     public int getAssocRejectionHighThrPercent() {
599         return mAssocRejectionHighThrPercent;
600     }
601 
602     /**
603      * Gets association rejection min count
604      */
getAssocRejectionCountMin()605     public int getAssocRejectionCountMin() {
606         return mAssocRejectionCountMin;
607     }
608 
609     /**
610      * Gets the high threshold of association timeout rate in percent
611      */
getAssocTimeoutHighThrPercent()612     public int getAssocTimeoutHighThrPercent() {
613         return mAssocTimeoutHighThrPercent;
614     }
615 
616     /**
617      * Gets association timeout min count
618      */
getAssocTimeoutCountMin()619     public int getAssocTimeoutCountMin() {
620         return mAssocTimeoutCountMin;
621     }
622 
623 
624     /**
625      * Gets the high threshold of authentication failure rate in percent
626      */
getAuthFailureHighThrPercent()627     public int getAuthFailureHighThrPercent() {
628         return mAuthFailureHighThrPercent;
629     }
630 
631     /**
632      * Gets authentication failure min count
633      */
getAuthFailureCountMin()634     public int getAuthFailureCountMin() {
635         return mAuthFailureCountMin;
636     }
637 
638     /**
639      * Gets the high threshold of nonlocal short connection rate in percent
640      */
getShortConnectionNonlocalHighThrPercent()641     public int getShortConnectionNonlocalHighThrPercent() {
642         return mShortConnectionNonlocalHighThrPercent;
643     }
644 
645     /**
646      * Gets nonlocal short connection min count
647      */
getShortConnectionNonlocalCountMin()648     public int getShortConnectionNonlocalCountMin() {
649         return mShortConnectionNonlocalCountMin;
650     }
651 
652     /**
653      * Gets the high threshold of nonlocal disconnection rate in percent
654      */
getDisconnectionNonlocalHighThrPercent()655     public int getDisconnectionNonlocalHighThrPercent() {
656         return mDisconnectionNonlocalHighThrPercent;
657     }
658 
659     /**
660      * Gets nonlocal disconnection min count
661      */
getDisconnectionNonlocalCountMin()662     public int getDisconnectionNonlocalCountMin() {
663         return mDisconnectionNonlocalCountMin;
664     }
665 
666     /**
667      * Gets health monitor ratio threshold, numerator part
668      */
getHealthMonitorRatioThrNumerator()669     public int getHealthMonitorRatioThrNumerator() {
670         return mHealthMonitorRatioThrNumerator;
671     }
672 
673     /**
674      * Gets health monitor min RSSI threshold in dBm
675      */
getHealthMonitorMinRssiThrDbm()676     public int getHealthMonitorMinRssiThrDbm() {
677         return mHealthMonitorMinRssiThrDbm;
678     }
679 
680     /**
681      * Gets the Set of SSIDs in the flaky SSID hotlist.
682      */
getRandomizationFlakySsidHotlist()683     public Set<String> getRandomizationFlakySsidHotlist() {
684         return mRandomizationFlakySsidHotlist;
685     }
686 
687     /**
688      * Gets the list of SSIDs for non-persistent MAC randomization.
689      */
getNonPersistentMacRandomizationSsidAllowlist()690     public Set<String> getNonPersistentMacRandomizationSsidAllowlist() {
691         return mNonPersistentMacRandomizationSsidAllowlist;
692     }
693 
694     /**
695      * Gets the list of SSIDs that non-persistent MAC randomization should not be used for.
696      */
getNonPersistentMacRandomizationSsidBlocklist()697     public Set<String> getNonPersistentMacRandomizationSsidBlocklist() {
698         return mNonPersistentMacRandomizationSsidBlocklist;
699     }
700     /**
701      * Gets the feature flag for reporting abnormal connection failure.
702      */
isAbnormalConnectionFailureBugreportEnabled()703     public boolean isAbnormalConnectionFailureBugreportEnabled() {
704         return mIsAbnormalConnectionFailureBugreportEnabled;
705     }
706 
707     /**
708      * Gets the feature flag for reporting abnormal disconnection.
709      */
isAbnormalDisconnectionBugreportEnabled()710     public boolean isAbnormalDisconnectionBugreportEnabled() {
711         return mIsAbnormalDisconnectionBugreportEnabled;
712     }
713 
714     /**
715      * Gets health monitor min number of connection attempt threshold
716      */
getHealthMonitorMinNumConnectionAttempt()717     public int getHealthMonitorMinNumConnectionAttempt() {
718         return mHealthMonitorMinNumConnectionAttempt;
719     }
720 
721     /**
722      * Gets minimum wait time between two bug report captures
723      */
getBugReportMinWindowMs()724     public int getBugReportMinWindowMs() {
725         return mBugReportMinWindowMs;
726     }
727 
728     /**
729      * Gets the extra ratio of threshold to trigger bug report.
730      */
getBugReportThresholdExtraRatio()731     public int getBugReportThresholdExtraRatio() {
732         return mBugReportThresholdExtraRatio;
733     }
734 
735     /**
736      * Gets the feature flag for reporting overlapping connection.
737      */
isOverlappingConnectionBugreportEnabled()738     public boolean isOverlappingConnectionBugreportEnabled() {
739         return mIsOverlappingConnectionBugreportEnabled;
740     }
741 
742     /**
743      * Gets overlapping connection duration threshold in ms
744      */
getOverlappingConnectionDurationThresholdMs()745     public int getOverlappingConnectionDurationThresholdMs() {
746         return mOverlappingConnectionDurationThresholdMs;
747     }
748 
749     /**
750      * Gets the threshold of link speed below which Tx link speed is ignored at low traffic
751      */
getTxLinkSpeedLowThresholdMbps()752     public int getTxLinkSpeedLowThresholdMbps() {
753         return mTxLinkSpeedLowThresholdMbps;
754     }
755 
756     /**
757      * Gets the threshold of link speed below which Rx link speed is ignored at low traffic
758      */
getRxLinkSpeedLowThresholdMbps()759     public int getRxLinkSpeedLowThresholdMbps() {
760         return mRxLinkSpeedLowThresholdMbps;
761     }
762 
763     /**
764      * Gets the feature flag for Wifi battery saver.
765      */
isWifiBatterySaverEnabled()766     public boolean isWifiBatterySaverEnabled() {
767         return mWifiBatterySaverEnabled;
768     }
769 
770     /**
771      * Gets health monitor short connection duration threshold in ms
772      */
getHealthMonitorShortConnectionDurationThrMs()773     public int getHealthMonitorShortConnectionDurationThrMs() {
774         return mHealthMonitorShortConnectionDurationThrMs;
775     }
776 
777     /**
778      * Gets abnormal disconnection reason code mask
779      */
getAbnormalDisconnectionReasonCodeMask()780     public long getAbnormalDisconnectionReasonCodeMask() {
781         return mAbnormalDisconnectionReasonCodeMask;
782     }
783 
784     /**
785      * Gets health monitor RSSI poll valid time in ms
786      */
getHealthMonitorRssiPollValidTimeMs()787     public int getHealthMonitorRssiPollValidTimeMs() {
788         return mHealthMonitorRssiPollValidTimeMs;
789     }
790 
791     /**
792      * Gets scan rssi valid time in ms when device is in non-stationary state
793      */
getNonstationaryScanRssiValidTimeMs()794     public int getNonstationaryScanRssiValidTimeMs() {
795         return mNonstationaryScanRssiValidTimeMs;
796     }
797 
798     /**
799      * Gets scan rssi valid time in ms when device is in stationary state
800      */
getStationaryScanRssiValidTimeMs()801     public int getStationaryScanRssiValidTimeMs() {
802         return mStationaryScanRssiValidTimeMs;
803     }
804 
805     /**
806      * Gets health monitor firmware alert valid time in ms,
807      * -1 disables firmware alert time check
808      */
getHealthMonitorFwAlertValidTimeMs()809     public int getHealthMonitorFwAlertValidTimeMs() {
810         return mHealthMonitorFwAlertValidTimeMs;
811     }
812 
813     /**
814      * Gets the minimum confirmation duration for sending network score to connectivity service
815      * when score breaches low.
816      */
getMinConfirmationDurationSendLowScoreMs()817     public int getMinConfirmationDurationSendLowScoreMs() {
818         return mMinConfirmationDurationSendLowScoreMs;
819     }
820 
821     /**
822      * Gets the minimum confirmation duration for sending network score to connectivity service
823      * when score breaches high.
824      */
getMinConfirmationDurationSendHighScoreMs()825     public int getMinConfirmationDurationSendHighScoreMs() {
826         return mMinConfirmationDurationSendHighScoreMs;
827     }
828 
829     /**
830      * Gets the RSSI threshold above which low score is not sent to connectivity service when
831      * external scorer takes action.
832      */
getRssiThresholdNotSendLowScoreToCsDbm()833     public int getRssiThresholdNotSendLowScoreToCsDbm() {
834         return mRssiThresholdNotSendLowScoreToCsDbm;
835     }
836 
837     /**
838      * Gets traffic stats maximum threshold in KByte
839      */
getTrafficStatsThresholdMaxKbyte()840     public int getTrafficStatsThresholdMaxKbyte() {
841         return mTrafficStatsThresholdMaxKbyte;
842     }
843 
844     /**
845      * Gets bandwidth estimator large time constant in second
846      */
getBandwidthEstimatorLargeTimeConstantSec()847     public int getBandwidthEstimatorLargeTimeConstantSec() {
848         return mBandwidthEstimatorLargeTimeConstantSec;
849     }
850 
851     /**
852      * Gets the feature flag for reporting interface setup failure
853      */
isInterfaceFailureBugreportEnabled()854     public boolean isInterfaceFailureBugreportEnabled() {
855         return mInterfaceFailureBugreportEnabled;
856     }
857 
858     /**
859      * Gets the feature flag for reporting p2p setup failure
860      */
isP2pFailureBugreportEnabled()861     public boolean isP2pFailureBugreportEnabled() {
862         return mP2pFailureBugreportEnabled;
863     }
864 
865     /**
866      * Gets the feature flag for APM enhancement
867      */
isApmEnhancementEnabled()868     public boolean isApmEnhancementEnabled() {
869         // reads the value set by Bluetooth device config for APM enhancement feature flag
870         return Settings.Global.getInt(
871                 mContext.getContentResolver(), "apm_enhancement_enabled", 0) == 1;
872     }
873 
874     /**
875      * Gets the feature flag for Aware suspension
876      */
isAwareSuspensionEnabled()877     public boolean isAwareSuspensionEnabled() {
878         return mAwareSuspensionEnabled;
879     }
880 
881     /**
882      * Gets the feature flag for High Perf lock deprecation
883      */
isHighPerfLockDeprecated()884     public boolean isHighPerfLockDeprecated() {
885         return mHighPerfLockDeprecated;
886     }
887 
888     /**
889      * Gets the feature flag for the OOB pseudonym of EAP-SIM/AKA/AKA'
890      */
isOobPseudonymEnabled()891     public boolean isOobPseudonymEnabled() {
892         return mOobPseudonymEnabled.isPresent() && mOobPseudonymEnabled.get();
893     }
894 
895     /**
896      * Gets the feature flag indicating whether the application QoS policy API is enabled.
897      */
isApplicationQosPolicyApiEnabled()898     public boolean isApplicationQosPolicyApiEnabled() {
899         return mApplicationQosPolicyApiEnabled;
900     }
901 
902     /**
903      * Gets the feature flag for adjusting link layer stats and RSSI polling interval
904      */
isAdjustPollRssiIntervalEnabled()905     public boolean isAdjustPollRssiIntervalEnabled() {
906         return mAdjustPollRssiIntervalEnabled;
907     }
908 
909     /**
910      * Gets the feature flag for Software PNO
911      */
isSoftwarePnoEnabled()912     public boolean isSoftwarePnoEnabled() {
913         return mSoftwarePnoEnabled;
914     }
915 
916     /**
917      * Gets the feature flag indicating whether Passpoint SSIDs should be included in PNO scans.
918      */
includePasspointSsidsInPnoScans()919     public boolean includePasspointSsidsInPnoScans() {
920         return mIncludePasspointSsidsInPnoScans;
921     }
922 
923     /**
924      * Gets the feature flag indicating whether handling IP reachability failures triggered from
925      * Wi-Fi RSSI polling or organic kernel probes the same as failure post roaming.
926      */
isHandleRssiOrganicKernelFailuresEnabled()927     public boolean isHandleRssiOrganicKernelFailuresEnabled() {
928         return mHandleRssiOrganicKernelFailuresEnabled;
929     }
930 
931     /*
932      * Sets the listener to be notified when the OOB Pseudonym feature is enabled;
933      * Only 1 listener is accepted.
934      */
setOobPseudonymFeatureFlagChangedListener( Consumer<Boolean> listener)935     public void setOobPseudonymFeatureFlagChangedListener(
936             Consumer<Boolean> listener) {
937         mOobPseudonymFeatureFlagChangedListener = listener;
938     }
939 
940     /**
941      * Get the set of bugreports that are explicitly disabled.
942      * @return A Set of String to indicate disabled auto-bugreports trigger points.
943      */
getDisabledAutoBugreportTitleAndDetails()944     public Set<String> getDisabledAutoBugreportTitleAndDetails() {
945         return mDisabledAutoBugreports;
946     }
947 
getFeatureFlags()948     public FeatureFlags getFeatureFlags() {
949         return mFeatureFlags;
950     }
951 }
952