Commit 085fd952 authored by scheib's avatar scheib Committed by Commit bot

bluetooth: web: Chooser RSSI indicator now based on percentile buckets

This change updates the mapping from RSSI values into signal strength
icon levels. It is made after reviewing a month of recorded UMA
data for RSSI values encountered by users.

A new design of how we map values to displayed levels is documented
in the change.

See these charts for measured data:
https://goo.gl/photos/pCoAkF7mPyza9B1k7

BUG=629689

Review-Url: https://codereview.chromium.org/2561883002
Cr-Commit-Position: refs/heads/master@{#438009}
parent 06340ec1
......@@ -30,19 +30,45 @@ using UUIDSet = device::BluetoothDevice::UUIDSet;
namespace {
// Anything worse than or equal to this will show 0 bars.
const int kMinRSSI = -100;
// Anything better than or equal to this will show the maximum bars.
const int kMaxRSSI = -55;
// Number of RSSI levels used in the signal strength image.
const int kNumSignalStrengthLevels = 5;
const content::UMARSSISignalStrengthLevel kRSSISignalStrengthEnumTable[] = {
content::UMARSSISignalStrengthLevel::LEVEL_0,
content::UMARSSISignalStrengthLevel::LEVEL_1,
content::UMARSSISignalStrengthLevel::LEVEL_2,
content::UMARSSISignalStrengthLevel::LEVEL_3,
content::UMARSSISignalStrengthLevel::LEVEL_4};
// Signal Strength Display Notes:
//
// RSSI values are displayed by the chooser to empower a user to differentiate
// between multiple devices with the same name, comparing devices with different
// names is a secondary goal. It is important that a user is able to move closer
// and farther away from a device and have it transition between two different
// signal strength levels, thus we want to spread RSSI values out evenly accross
// displayed levels.
//
// RSSI values from UMA in RecordRSSISignalStrength are charted here:
// https://goo.gl/photos/pCoAkF7mPyza9B1k7 (2016-12-08)
// with a copy-paste of table data at every 5dBm:
// dBm CDF* Histogram Bucket Quantity (hand drawn estimate)
// -100 00.0% -
// -95 00.4% --
// -90 01.9% ---
// -85 05.1% ---
// -80 09.2% ----
// -75 14.9% -----
// -70 22.0% ------
// -65 32.4% --------
// -60 47.9% ---------
// -55 60.4% --------
// -50 72.8% ---------
// -45 85.5% -------
// -40 94.5% -----
// -35 97.4% ---
// -30 99.0% --
// -25 99.7% -
//
// CDF: Cumulative Distribution Function:
// https://en.wikipedia.org/wiki/Cumulative_distribution_function
//
// Conversion to signal strengths is done by selecting 4 threshold points
// equally spaced through the CDF.
const int k20thPercentileRSSI = -71;
const int k40thPercentileRSSI = -63;
const int k60thPercentileRSSI = -55;
const int k80thPercentileRSSI = -47;
} // namespace
......@@ -436,24 +462,22 @@ int BluetoothDeviceChooserController::CalculateSignalStrengthLevel(
int8_t rssi) {
RecordRSSISignalStrength(rssi);
if (rssi <= kMinRSSI) {
RecordRSSISignalStrengthLevel(
UMARSSISignalStrengthLevel::LESS_THAN_OR_EQUAL_TO_MIN_RSSI);
if (rssi < k20thPercentileRSSI) {
RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_0);
return 0;
} else if (rssi < k40thPercentileRSSI) {
RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_1);
return 1;
} else if (rssi < k60thPercentileRSSI) {
RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_2);
return 2;
} else if (rssi < k80thPercentileRSSI) {
RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_3);
return 3;
} else {
RecordRSSISignalStrengthLevel(content::UMARSSISignalStrengthLevel::LEVEL_4);
return 4;
}
if (rssi >= kMaxRSSI) {
RecordRSSISignalStrengthLevel(
UMARSSISignalStrengthLevel::GREATER_THAN_OR_EQUAL_TO_MAX_RSSI);
return kNumSignalStrengthLevels - 1;
}
double input_range = kMaxRSSI - kMinRSSI;
double output_range = kNumSignalStrengthLevels - 1;
int level = static_cast<int>((rssi - kMinRSSI) * output_range / input_range);
DCHECK(kNumSignalStrengthLevels == arraysize(kRSSISignalStrengthEnumTable));
RecordRSSISignalStrengthLevel(kRSSISignalStrengthEnumTable[level]);
return level;
}
void BluetoothDeviceChooserController::SetTestScanDurationForTesting() {
......
......@@ -13,23 +13,25 @@ TEST_F(BluetoothDeviceChooserControllerTest, CalculateSignalStrengthLevel) {
EXPECT_EQ(
0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-128));
EXPECT_EQ(
0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-100));
EXPECT_EQ(
0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-89));
0, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-72));
EXPECT_EQ(
1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-88));
1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-71));
EXPECT_EQ(
1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-78));
1, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-64));
EXPECT_EQ(
2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-77));
2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-63));
EXPECT_EQ(
2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-67));
2, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-56));
EXPECT_EQ(
3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-66));
3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-55));
EXPECT_EQ(
3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-56));
3, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-48));
EXPECT_EQ(
4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-55));
4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(-47));
EXPECT_EQ(
4, BluetoothDeviceChooserController::CalculateSignalStrengthLevel(127));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment