blob: 3ab024b8498c7db9a9e2ee0644782b0bc242ffd4 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/machine_learning/user_settings_event_logger.h"
#include "ash/display/screen_orientation_controller.h"
#include "ash/display/screen_orientation_controller_test_api.h"
#include "ash/shell.h"
#include "ash/system/machine_learning/user_settings_event.pb.h"
#include "ash/system/night_light/night_light_controller_impl.h"
#include "ash/system/power/power_status.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/test/simple_test_clock.h"
#include "base/test/task_environment.h"
#include "chromeos/dbus/power_manager/backlight.pb.h"
#include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
#include "components/ukm/test_ukm_recorder.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/test/display_manager_test_api.h"
namespace ash {
namespace ml {
namespace {
using chromeos::network_config::mojom::CellularStateProperties;
using chromeos::network_config::mojom::CellularStatePropertiesPtr;
using chromeos::network_config::mojom::NetworkStateProperties;
using chromeos::network_config::mojom::NetworkStatePropertiesPtr;
using chromeos::network_config::mojom::NetworkType;
using chromeos::network_config::mojom::NetworkTypeStateProperties;
using chromeos::network_config::mojom::SecurityType;
using chromeos::network_config::mojom::WiFiStateProperties;
using chromeos::network_config::mojom::WiFiStatePropertiesPtr;
using display::Display;
using power_manager::PowerSupplyProperties;
using ukm::TestUkmRecorder;
NetworkStatePropertiesPtr CreateWifiNetwork(int signal_strength,
SecurityType security_type) {
NetworkStatePropertiesPtr network = NetworkStateProperties::New();
WiFiStatePropertiesPtr wifi = WiFiStateProperties::New();
wifi->signal_strength = signal_strength;
wifi->security = security_type;
network->type = NetworkType::kWiFi;
network->type_state = NetworkTypeStateProperties::New();
network->type_state->set_wifi(std::move(wifi));
return network;
}
NetworkStatePropertiesPtr CreateCellularNetwork(int signal_strength) {
NetworkStatePropertiesPtr network = NetworkStateProperties::New();
CellularStatePropertiesPtr cellular = CellularStateProperties::New();
cellular->signal_strength = signal_strength;
network->type = NetworkType::kCellular;
network->type_state = NetworkTypeStateProperties::New();
network->type_state->set_cellular(std::move(cellular));
return network;
}
class FakeNightLightDelegate : public NightLightControllerImpl::Delegate {
public:
FakeNightLightDelegate() = default;
~FakeNightLightDelegate() override = default;
FakeNightLightDelegate(const FakeNightLightDelegate&) = delete;
FakeNightLightDelegate& operator=(const FakeNightLightDelegate&) = delete;
void SetFakeNow(TimeOfDay time) { fake_now_ = time.ToTimeToday(); }
void SetFakeSunset(TimeOfDay time) { fake_sunset_ = time.ToTimeToday(); }
void SetFakeSunrise(TimeOfDay time) { fake_sunrise_ = time.ToTimeToday(); }
// NightLightControllerImpl::Delegate:
base::Time GetNow() const override { return fake_now_; }
base::Time GetSunsetTime() const override { return fake_sunset_; }
base::Time GetSunriseTime() const override { return fake_sunrise_; }
bool SetGeoposition(
const NightLightController::SimpleGeoposition& position) override {
return false;
}
bool HasGeoposition() const override { return false; }
private:
base::Time fake_now_;
base::Time fake_sunset_;
base::Time fake_sunrise_;
};
} // namespace
class UserSettingsEventLoggerTest : public AshTestBase {
public:
UserSettingsEventLoggerTest()
: AshTestBase(
base::test::TaskEnvironment::TimeSource::MOCK_TIME,
base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED) {}
~UserSettingsEventLoggerTest() override = default;
UserSettingsEventLoggerTest(const UserSettingsEventLoggerTest&) = delete;
UserSettingsEventLoggerTest& operator=(const UserSettingsEventLoggerTest&) =
delete;
void SetUp() override {
AshTestBase::SetUp();
logger_ = UserSettingsEventLogger::Get();
}
protected:
void FastForwardBySeconds(const int seconds) {
task_environment()->FastForwardBy(base::TimeDelta::FromSeconds(seconds));
}
std::vector<const ukm::mojom::UkmEntry*> GetUkmEntries() {
return ukm_recorder_.GetEntriesByName(
ukm::builders::UserSettingsEvent::kEntryName);
}
// Volume features are logged at the end of the timer delay.
void LogVolumeAndWait(const int volume) {
logger_->OnOutputNodeVolumeChanged(0, volume);
task_environment()->FastForwardBy(kSliderDelay);
}
void SetMuteAndWait(const bool mute_on) {
logger_->OnOutputMuteChanged(mute_on);
task_environment()->FastForwardBy(kSliderDelay);
}
void LogBrightness(const int brightness,
const bool initiated_by_user = true) {
power_manager::BacklightBrightnessChange change;
change.set_cause(
initiated_by_user
? power_manager::BacklightBrightnessChange_Cause_USER_REQUEST
: power_manager::BacklightBrightnessChange_Cause_OTHER);
change.set_percent(brightness);
logger_->ScreenBrightnessChanged(change);
}
// Brightness features are logged at the end of the timer delay.
void LogBrightnessAndWait(const int current_level,
const bool initiated_by_user = true) {
LogBrightness(current_level, initiated_by_user);
task_environment()->FastForwardBy(kSliderDelay);
}
void LogSharedFeatures() {
UserSettingsEvent event;
logger_->PopulateSharedFeatures(&event);
logger_->SendToUkmAndAppList(event);
}
UserSettingsEventLogger* logger_;
private:
ukm::TestAutoSetUkmRecorder ukm_recorder_;
};
TEST_F(UserSettingsEventLoggerTest, TestLogWifiEvent) {
logger_->LogNetworkUkmEvent(
*CreateWifiNetwork(50, SecurityType::kNone).get());
logger_->LogNetworkUkmEvent(
*CreateWifiNetwork(25, SecurityType::kWpaEap).get());
const auto& entries = GetUkmEntries();
ASSERT_EQ(2ul, entries.size());
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::WIFI);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "SignalStrength", 50);
TestUkmRecorder::ExpectEntryMetric(entry, "HasWifiSecurity", false);
entry = entries[1];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::WIFI);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "SignalStrength", 25);
TestUkmRecorder::ExpectEntryMetric(entry, "HasWifiSecurity", true);
}
TEST_F(UserSettingsEventLoggerTest, TestLogCellularEvent) {
logger_->LogNetworkUkmEvent(*CreateCellularNetwork(50).get());
logger_->LogNetworkUkmEvent(*CreateCellularNetwork(25).get());
const auto& entries = GetUkmEntries();
ASSERT_EQ(2ul, entries.size());
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::CELLULAR);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "SignalStrength", 50);
TestUkmRecorder::ExpectEntryMetric(entry, "UsedCellularInSession", false);
entry = entries[1];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::CELLULAR);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "SignalStrength", 25);
// After the first cellular event, |UsedCellularInSession| should now be true.
TestUkmRecorder::ExpectEntryMetric(entry, "UsedCellularInSession", true);
}
TEST_F(UserSettingsEventLoggerTest, TestLogBluetoothEvent) {
// Log an event with a null bluetooth address.
logger_->LogBluetoothUkmEvent(BluetoothAddress());
const auto& entries = GetUkmEntries();
ASSERT_EQ(1ul, entries.size());
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::BLUETOOTH);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
// |is_paired_bluetooth_device| is tested manually.
}
TEST_F(UserSettingsEventLoggerTest, TestLogNightLightEvent) {
Shell::Get()->night_light_controller()->SetScheduleType(
NightLightController::ScheduleType::kSunsetToSunrise);
logger_->LogNightLightUkmEvent(true);
Shell::Get()->night_light_controller()->SetScheduleType(
NightLightController::ScheduleType::kNone);
logger_->LogNightLightUkmEvent(false);
const auto& entries = GetUkmEntries();
ASSERT_EQ(2ul, entries.size());
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::NIGHT_LIGHT);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "PreviousValue", false);
TestUkmRecorder::ExpectEntryMetric(entry, "CurrentValue", true);
TestUkmRecorder::ExpectEntryMetric(entry, "HasNightLightSchedule", true);
entry = entries[1];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::NIGHT_LIGHT);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "PreviousValue", true);
TestUkmRecorder::ExpectEntryMetric(entry, "CurrentValue", false);
TestUkmRecorder::ExpectEntryMetric(entry, "HasNightLightSchedule", false);
}
TEST_F(UserSettingsEventLoggerTest, TestNightLightSunsetFeature) {
auto night_light_delegate = std::make_unique<FakeNightLightDelegate>();
auto* night_light = night_light_delegate.get();
Shell::Get()->night_light_controller()->SetDelegateForTesting(
std::move(night_light_delegate));
// Set fake sunrise and sunset to 6am and 6pm.
night_light->SetFakeSunrise(TimeOfDay(6 * 60));
night_light->SetFakeSunset(TimeOfDay(18 * 60));
// Log events at 3am, 12pm, and 11pm.
night_light->SetFakeNow(TimeOfDay(3 * 60));
logger_->LogNightLightUkmEvent(false);
night_light->SetFakeNow(TimeOfDay(12 * 60));
logger_->LogNightLightUkmEvent(false);
night_light->SetFakeNow(TimeOfDay(23 * 60));
logger_->LogNightLightUkmEvent(false);
const auto& entries = GetUkmEntries();
ASSERT_EQ(3ul, entries.size());
TestUkmRecorder::ExpectEntryMetric(entries[0], "IsAfterSunset", true);
TestUkmRecorder::ExpectEntryMetric(entries[1], "IsAfterSunset", false);
TestUkmRecorder::ExpectEntryMetric(entries[2], "IsAfterSunset", true);
}
TEST_F(UserSettingsEventLoggerTest, TestLogQuietModeEvent) {
// Log an event that quiet mode has been switched on.
logger_->LogQuietModeUkmEvent(true);
// Start two casting sessions.
logger_->OnCastingSessionStartedOrStopped(true);
logger_->OnCastingSessionStartedOrStopped(true);
logger_->LogQuietModeUkmEvent(false);
// End one casting session.
logger_->OnCastingSessionStartedOrStopped(false);
FastForwardBySeconds(301);
logger_->LogQuietModeUkmEvent(false);
// End the final casting session. |is_recently_presenting| should remain true
// for 5 minutes, with 1 second given for leeway on either side.
logger_->OnCastingSessionStartedOrStopped(false);
FastForwardBySeconds(299);
logger_->LogQuietModeUkmEvent(false);
FastForwardBySeconds(2);
logger_->LogQuietModeUkmEvent(false);
const auto& entries = GetUkmEntries();
ASSERT_EQ(5ul, entries.size());
// Check that the first entry has all details recorded correctly.
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::DO_NOT_DISTURB);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "PreviousValue", false);
TestUkmRecorder::ExpectEntryMetric(entry, "CurrentValue", true);
TestUkmRecorder::ExpectEntryMetric(entry, "IsRecentlyPresenting", false);
// Check that subsequent entries correctly record |is_recently_presenting|.
TestUkmRecorder::ExpectEntryMetric(entries[1], "IsRecentlyPresenting", true);
TestUkmRecorder::ExpectEntryMetric(entries[2], "IsRecentlyPresenting", true);
TestUkmRecorder::ExpectEntryMetric(entries[3], "IsRecentlyPresenting", true);
TestUkmRecorder::ExpectEntryMetric(entries[4], "IsRecentlyPresenting", false);
}
TEST_F(UserSettingsEventLoggerTest, TestLogAccessibilityEvent) {
// Log an event that high contrast mode has been enabled.
logger_->LogAccessibilityUkmEvent(UserSettingsEvent::Event::HIGH_CONTRAST,
true);
const auto& entries = GetUkmEntries();
ASSERT_EQ(1ul, entries.size());
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::ACCESSIBILITY);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "PreviousValue", false);
TestUkmRecorder::ExpectEntryMetric(entry, "CurrentValue", true);
TestUkmRecorder::ExpectEntryMetric(entry, "AccessibilityId",
UserSettingsEvent::Event::HIGH_CONTRAST);
}
TEST_F(UserSettingsEventLoggerTest, TestLogVolumeFeatures) {
LogVolumeAndWait(23);
LogVolumeAndWait(98);
SetMuteAndWait(true);
SetMuteAndWait(false);
LogVolumeAndWait(20);
SetMuteAndWait(true);
LogVolumeAndWait(50);
const auto& entries = GetUkmEntries();
ASSERT_EQ(7ul, entries.size());
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::VOLUME);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "CurrentValue", 23);
TestUkmRecorder::ExpectEntryMetric(entries[1], "PreviousValue", 23);
TestUkmRecorder::ExpectEntryMetric(entries[1], "CurrentValue", 98);
TestUkmRecorder::ExpectEntryMetric(entries[2], "PreviousValue", 98);
TestUkmRecorder::ExpectEntryMetric(entries[2], "CurrentValue", 0);
TestUkmRecorder::ExpectEntryMetric(entries[3], "PreviousValue", 0);
TestUkmRecorder::ExpectEntryMetric(entries[3], "CurrentValue", 98);
TestUkmRecorder::ExpectEntryMetric(entries[4], "PreviousValue", 98);
TestUkmRecorder::ExpectEntryMetric(entries[4], "CurrentValue", 20);
TestUkmRecorder::ExpectEntryMetric(entries[5], "PreviousValue", 20);
TestUkmRecorder::ExpectEntryMetric(entries[5], "CurrentValue", 0);
TestUkmRecorder::ExpectEntryMetric(entries[6], "PreviousValue", 0);
TestUkmRecorder::ExpectEntryMetric(entries[6], "CurrentValue", 50);
}
TEST_F(UserSettingsEventLoggerTest, TestVolumeDelay) {
LogVolumeAndWait(10);
// Only log an event if there is a pause of |kSliderDelay|.
logger_->OnOutputNodeVolumeChanged(0, 11);
task_environment()->FastForwardBy(kSliderDelay / 2);
logger_->OnOutputNodeVolumeChanged(0, 12);
task_environment()->FastForwardBy(kSliderDelay / 2);
logger_->OnOutputNodeVolumeChanged(0, 13);
task_environment()->FastForwardBy(kSliderDelay);
const auto& entries = GetUkmEntries();
ASSERT_EQ(2ul, entries.size());
TestUkmRecorder::ExpectEntryMetric(entries[0], "CurrentValue", 10);
TestUkmRecorder::ExpectEntryMetric(entries[1], "PreviousValue", 10);
TestUkmRecorder::ExpectEntryMetric(entries[1], "CurrentValue", 13);
}
TEST_F(UserSettingsEventLoggerTest, TestLogBrightnessReason) {
LogBrightnessAndWait(1);
LogBrightnessAndWait(2);
LogBrightnessAndWait(3, false); // Not logged, but updates the brightness.
LogBrightnessAndWait(4);
const auto& entries = GetUkmEntries();
ASSERT_EQ(3ul, entries.size());
// Check that the first entry has basic details recorded correctly.
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::BRIGHTNESS);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
EXPECT_FALSE(TestUkmRecorder::EntryHasMetric(entry, "PreviousValue"));
TestUkmRecorder::ExpectEntryMetric(entry, "CurrentValue", 1);
// Check that subsequent entries correctly record values.
TestUkmRecorder::ExpectEntryMetric(entries[1], "PreviousValue", 1);
TestUkmRecorder::ExpectEntryMetric(entries[1], "CurrentValue", 2);
TestUkmRecorder::ExpectEntryMetric(entries[2], "PreviousValue", 3);
TestUkmRecorder::ExpectEntryMetric(entries[2], "CurrentValue", 4);
}
TEST_F(UserSettingsEventLoggerTest, TestLogRecentlyFullscreen) {
LogBrightnessAndWait(0);
// Enter fullscreen.
logger_->OnFullscreenStateChanged(true, nullptr);
LogBrightnessAndWait(0);
// Exit fullscreen. |is_recently_fullscreen| should remain true for 5 minutes,
// with 1 second given for leeway on either side.
logger_->OnFullscreenStateChanged(false, nullptr);
FastForwardBySeconds(299 - kSliderDelay.InSeconds());
LogBrightnessAndWait(0);
FastForwardBySeconds(2);
LogBrightnessAndWait(0);
const auto& entries = GetUkmEntries();
ASSERT_EQ(4ul, entries.size());
TestUkmRecorder::ExpectEntryMetric(entries[0], "IsRecentlyFullscreen", false);
TestUkmRecorder::ExpectEntryMetric(entries[1], "IsRecentlyFullscreen", true);
TestUkmRecorder::ExpectEntryMetric(entries[2], "IsRecentlyFullscreen", true);
TestUkmRecorder::ExpectEntryMetric(entries[3], "IsRecentlyFullscreen", false);
}
TEST_F(UserSettingsEventLoggerTest, TestBrightnessDelay) {
LogBrightnessAndWait(10, false); // Set an initial unlogged value.
// Only log an event if there is a pause of |kSliderDelay|.
LogBrightness(11);
task_environment()->FastForwardBy(kSliderDelay / 2);
LogBrightness(12);
task_environment()->FastForwardBy(kSliderDelay / 2);
LogBrightness(13);
LogBrightness(14, false);
LogBrightness(15);
LogBrightness(16, false);
task_environment()->FastForwardBy(kSliderDelay);
LogBrightnessAndWait(17);
const auto& entries = GetUkmEntries();
ASSERT_EQ(2ul, entries.size());
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "SettingId",
UserSettingsEvent::Event::BRIGHTNESS);
TestUkmRecorder::ExpectEntryMetric(entry, "SettingType",
UserSettingsEvent::Event::QUICK_SETTINGS);
TestUkmRecorder::ExpectEntryMetric(entry, "PreviousValue", 10);
TestUkmRecorder::ExpectEntryMetric(entry, "CurrentValue", 15);
entry = entries[1];
TestUkmRecorder::ExpectEntryMetric(entry, "PreviousValue", 16);
TestUkmRecorder::ExpectEntryMetric(entry, "CurrentValue", 17);
}
TEST_F(UserSettingsEventLoggerTest, TestLogDatetimeFeatures) {
base::SimpleTestClock test_clock;
logger_->SetClockForTesting(&test_clock);
base::Time fake_time;
ASSERT_TRUE(base::Time::FromString("Thu, 7 Nov 2019 14:58:00", &fake_time));
test_clock.SetNow(fake_time);
LogSharedFeatures();
ASSERT_TRUE(base::Time::FromString("Fri, 8 Nov 2019 04:24:00", &fake_time));
test_clock.SetNow(fake_time);
LogSharedFeatures();
const auto& entries = GetUkmEntries();
ASSERT_EQ(2ul, entries.size());
const auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "HourOfDay", 14);
TestUkmRecorder::ExpectEntryMetric(entry, "DayOfWeek",
UserSettingsEvent::Features::THU);
entry = entries[1];
TestUkmRecorder::ExpectEntryMetric(entry, "HourOfDay", 4);
TestUkmRecorder::ExpectEntryMetric(entry, "DayOfWeek",
UserSettingsEvent::Features::FRI);
}
TEST_F(UserSettingsEventLoggerTest, TestLogPowerFeatures) {
PowerSupplyProperties fake_power;
fake_power.set_battery_percent(56.0);
fake_power.set_external_power(PowerSupplyProperties::DISCONNECTED);
PowerStatus::Get()->SetProtoForTesting(fake_power);
LogSharedFeatures();
fake_power.set_external_power(PowerSupplyProperties::AC);
PowerStatus::Get()->SetProtoForTesting(fake_power);
LogSharedFeatures();
fake_power.set_external_power(PowerSupplyProperties::USB);
PowerStatus::Get()->SetProtoForTesting(fake_power);
LogSharedFeatures();
const auto& entries = GetUkmEntries();
ASSERT_EQ(3ul, entries.size());
auto* entry = entries[0];
TestUkmRecorder::ExpectEntryMetric(entry, "BatteryPercentage", 56);
TestUkmRecorder::ExpectEntryMetric(entry, "IsCharging", false);
TestUkmRecorder::ExpectEntryMetric(entries[1], "IsCharging", true);
TestUkmRecorder::ExpectEntryMetric(entries[2], "IsCharging", true);
}
TEST_F(UserSettingsEventLoggerTest, TestLogAudio) {
LogSharedFeatures();
logger_->OnOutputStarted();
LogSharedFeatures();
logger_->OnOutputStopped();
LogSharedFeatures();
const auto& entries = GetUkmEntries();
ASSERT_EQ(3ul, entries.size());
TestUkmRecorder::ExpectEntryMetric(entries[0], "IsPlayingAudio", false);
TestUkmRecorder::ExpectEntryMetric(entries[1], "IsPlayingAudio", true);
TestUkmRecorder::ExpectEntryMetric(entries[2], "IsPlayingAudio", false);
}
TEST_F(UserSettingsEventLoggerTest, TestLogVideo) {
LogSharedFeatures();
logger_->OnVideoStateChanged(VideoDetector::State::PLAYING_FULLSCREEN);
LogSharedFeatures();
logger_->OnVideoStateChanged(VideoDetector::State::NOT_PLAYING);
LogSharedFeatures();
logger_->OnVideoStateChanged(VideoDetector::State::PLAYING_WINDOWED);
LogSharedFeatures();
const auto& entries = GetUkmEntries();
ASSERT_EQ(4ul, entries.size());
TestUkmRecorder::ExpectEntryMetric(entries[0], "IsPlayingVideo", false);
TestUkmRecorder::ExpectEntryMetric(entries[1], "IsPlayingVideo", true);
TestUkmRecorder::ExpectEntryMetric(entries[2], "IsPlayingVideo", false);
TestUkmRecorder::ExpectEntryMetric(entries[3], "IsPlayingVideo", true);
}
TEST_F(UserSettingsEventLoggerTest, TestLogTabletMode) {
auto* tablet_mode_controller = Shell::Get()->tablet_mode_controller();
tablet_mode_controller->SetEnabledForTest(true);
LogSharedFeatures();
tablet_mode_controller->SetEnabledForTest(false);
LogSharedFeatures();
const auto& entries = GetUkmEntries();
ASSERT_EQ(2ul, entries.size());
TestUkmRecorder::ExpectEntryMetric(entries[0], "DeviceMode",
UserSettingsEvent::Features::TABLET_MODE);
TestUkmRecorder::ExpectEntryMetric(
entries[1], "DeviceMode", UserSettingsEvent::Features::CLAMSHELL_MODE);
}
TEST_F(UserSettingsEventLoggerTest, TestLogOrientation) {
display::test::ScopedSetInternalDisplayId set_internal_display(
Shell::Get()->display_manager(),
display::Screen::GetScreen()->GetPrimaryDisplay().id());
ScreenOrientationControllerTestApi orientation_test_api(
Shell::Get()->screen_orientation_controller());
orientation_test_api.SetDisplayRotation(Display::ROTATE_0,
Display::RotationSource::ACTIVE);
LogSharedFeatures();
orientation_test_api.SetDisplayRotation(Display::ROTATE_90,
Display::RotationSource::ACTIVE);
LogSharedFeatures();
orientation_test_api.SetDisplayRotation(Display::ROTATE_180,
Display::RotationSource::ACTIVE);
LogSharedFeatures();
orientation_test_api.SetDisplayRotation(Display::ROTATE_270,
Display::RotationSource::ACTIVE);
LogSharedFeatures();
const auto& entries = GetUkmEntries();
ASSERT_EQ(4ul, entries.size());
TestUkmRecorder::ExpectEntryMetric(entries[0], "DeviceOrientation",
UserSettingsEvent::Features::LANDSCAPE);
TestUkmRecorder::ExpectEntryMetric(entries[1], "DeviceOrientation",
UserSettingsEvent::Features::PORTRAIT);
TestUkmRecorder::ExpectEntryMetric(entries[2], "DeviceOrientation",
UserSettingsEvent::Features::LANDSCAPE);
TestUkmRecorder::ExpectEntryMetric(entries[3], "DeviceOrientation",
UserSettingsEvent::Features::PORTRAIT);
}
} // namespace ml
} // namespace ash