blob: 0b0ca946b2cc7bee876ab61f69a331fbf477eec2 [file] [log] [blame]
// Copyright 2021 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 "chrome/browser/apps/app_service/app_platform_metrics_service.h"
#include <memory>
#include <utility>
#include "base/metrics/histogram_base.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "base/util/values/values_util.h"
#include "chrome/browser/apps/app_service/app_platform_metrics.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/test/base/test_browser_window_aura.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/dbus/power/fake_power_manager_client.h"
#include "chromeos/dbus/power_manager/idle.pb.h"
#include "chromeos/dbus/power_manager/suspend.pb.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/services/app_service/public/cpp/app_registry_cache.h"
#include "components/services/app_service/public/cpp/instance_registry.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/common/constants.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
namespace apps {
namespace {
constexpr char kStartTime[] = "1 Jan 2021 21:00";
constexpr apps::InstanceState kActiveInstanceState =
static_cast<apps::InstanceState>(
apps::InstanceState::kStarted | apps::InstanceState::kRunning |
apps::InstanceState::kActive | apps::InstanceState::kVisible);
constexpr apps::InstanceState kInactiveInstanceState =
static_cast<apps::InstanceState>(apps::InstanceState::kStarted |
apps::InstanceState::kRunning);
void SetScreenOff(bool is_screen_off) {
power_manager::ScreenIdleState screen_idle_state;
screen_idle_state.set_off(is_screen_off);
chromeos::FakePowerManagerClient::Get()->SendScreenIdleStateChanged(
screen_idle_state);
}
void SetSuspendImminent() {
chromeos::FakePowerManagerClient::Get()->SendSuspendImminent(
power_manager::SuspendImminent_Reason_OTHER);
}
apps::mojom::AppPtr MakeApp(const char* app_id,
apps::mojom::AppType app_type,
apps::mojom::InstallSource install_source) {
apps::mojom::AppPtr app = apps::mojom::App::New();
app->app_id = app_id;
app->app_type = app_type;
app->install_source = install_source;
return app;
}
} // namespace
// Tests for family user metrics service.
class AppPlatformMetricsServiceTest : public testing::Test {
public:
void SetUp() override {
base::Time start_time;
EXPECT_TRUE(base::Time::FromUTCString(kStartTime, &start_time));
base::TimeDelta forward_by = start_time - base::Time::Now();
EXPECT_LT(base::TimeDelta(), forward_by);
task_environment_.AdvanceClock(forward_by);
GetPrefService()->SetInteger(
kAppPlatformMetricsDayId,
start_time.UTCMidnight().since_origin().InDaysFloored());
chromeos::PowerManagerClient::InitializeFake();
app_platform_metrics_service_ =
std::make_unique<AppPlatformMetricsService>(&testing_profile_);
app_platform_metrics_service_->Start(
apps::AppServiceProxyFactory::GetForProfile(&testing_profile_)
->AppRegistryCache(),
apps::AppServiceProxyFactory::GetForProfile(&testing_profile_)
->InstanceRegistry());
InstallApps();
}
void TearDown() override {
app_platform_metrics_service_.reset();
chromeos::PowerManagerClient::Shutdown();
browser_window1_.reset();
browser_window2_.reset();
}
void InstallApps() {
auto* proxy =
apps::AppServiceProxyFactory::GetForProfile(&testing_profile_);
std::vector<apps::mojom::AppPtr> deltas;
apps::AppRegistryCache& cache = proxy->AppRegistryCache();
deltas.push_back(MakeApp(/*app_id=*/"u", apps::mojom::AppType::kUnknown,
apps::mojom::InstallSource::kUnknown));
deltas.push_back(MakeApp(/*app_id=*/"a", apps::mojom::AppType::kArc,
apps::mojom::InstallSource::kUser));
deltas.push_back(MakeApp(/*app_id=*/"bu", apps::mojom::AppType::kBuiltIn,
apps::mojom::InstallSource::kSystem));
deltas.push_back(MakeApp(/*app_id=*/"c", apps::mojom::AppType::kCrostini,
apps::mojom::InstallSource::kUser));
deltas.push_back(MakeApp(/*app_id=*/"w", apps::mojom::AppType::kWeb,
apps::mojom::InstallSource::kSync));
deltas.push_back(MakeApp(
/*app_id=*/"m", apps::mojom::AppType::kMacOs,
apps::mojom::InstallSource::kUnknown));
deltas.push_back(MakeApp(
/*app_id=*/"p", apps::mojom::AppType::kPluginVm,
apps::mojom::InstallSource::kUser));
deltas.push_back(MakeApp(
/*app_id=*/"l", apps::mojom::AppType::kStandaloneBrowser,
apps::mojom::InstallSource::kSystem));
deltas.push_back(MakeApp(
/*app_id=*/"lcr", apps::mojom::AppType::kStandaloneBrowserExtension,
apps::mojom::InstallSource::kUser));
deltas.push_back(MakeApp(
/*app_id=*/"r", apps::mojom::AppType::kRemote,
apps::mojom::InstallSource::kPolicy));
deltas.push_back(MakeApp(/*app_id=*/"bo", apps::mojom::AppType::kBorealis,
apps::mojom::InstallSource::kOem));
deltas.push_back(MakeApp(/*app_id=*/"s", apps::mojom::AppType::kSystemWeb,
apps::mojom::InstallSource::kDefault));
cache.OnApps(std::move(deltas), apps::mojom::AppType::kUnknown,
false /* should_notify_initialized */);
}
void InstallOneApp(const std::string& app_id, apps::mojom::AppType app_type) {
auto* proxy =
apps::AppServiceProxyFactory::GetForProfile(&testing_profile_);
std::vector<apps::mojom::AppPtr> deltas;
apps::AppRegistryCache& cache = proxy->AppRegistryCache();
deltas.push_back(
MakeApp(app_id.c_str(), app_type, apps::mojom::InstallSource::kUser));
cache.OnApps(std::move(deltas), apps::mojom::AppType::kUnknown,
false /* should_notify_initialized */);
}
void VerifyMetrics() {
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(AppTypeName::kArc),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kArc, apps::mojom::InstallSource::kUser),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kBuiltIn),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kBuiltIn, apps::mojom::InstallSource::kSystem),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kCrostini),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kCrostini, apps::mojom::InstallSource::kUser),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kChromeApp),
/*expected_count=*/0);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(AppTypeName::kWeb),
/*expected_count=*/0);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kWeb, apps::mojom::InstallSource::kSync),
/*expected_count=*/0);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kMacOs),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kMacOs, apps::mojom::InstallSource::kUnknown),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kPluginVm),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kPluginVm, apps::mojom::InstallSource::kUser),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kStandaloneBrowser),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kStandaloneBrowser,
apps::mojom::InstallSource::kSystem),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kStandaloneBrowserExtension),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kStandaloneBrowserExtension,
apps::mojom::InstallSource::kUser),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kRemote),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kRemote, apps::mojom::InstallSource::kPolicy),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kBorealis),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kBorealis, apps::mojom::InstallSource::kOem),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(
AppTypeName::kSystemWeb),
/*expected_count=*/1);
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsCountPerInstallSourceHistogramNameForTest(
AppTypeName::kSystemWeb, apps::mojom::InstallSource::kDefault),
/*expected_count=*/1);
}
void ModifyInstance(const std::string& app_id,
aura::Window* window,
apps::InstanceState state) {
std::unique_ptr<apps::Instance> instance = std::make_unique<apps::Instance>(
app_id, std::make_unique<apps::Instance::InstanceKey>(window));
instance->UpdateState(state, base::Time::Now());
std::vector<std::unique_ptr<apps::Instance>> deltas;
deltas.push_back(std::move(instance));
apps::AppServiceProxyFactory::GetForProfile(&testing_profile_)
->InstanceRegistry()
.OnInstances(deltas);
}
std::unique_ptr<Browser> CreateBrowserWithAuraWindow1() {
std::unique_ptr<aura::Window> window = std::make_unique<aura::Window>(
&delegate1_, aura::client::WINDOW_TYPE_NORMAL);
window->SetId(0);
window->Init(ui::LAYER_TEXTURED);
Browser::CreateParams params(&testing_profile_, true);
params.type = Browser::TYPE_NORMAL;
browser_window1_ =
std::make_unique<TestBrowserWindowAura>(std::move(window));
params.window = browser_window1_.get();
return std::unique_ptr<Browser>(Browser::Create(params));
}
std::unique_ptr<Browser> CreateBrowserWithAuraWindow2() {
std::unique_ptr<aura::Window> window = std::make_unique<aura::Window>(
&delegate2_, aura::client::WINDOW_TYPE_NORMAL);
window->SetId(0);
window->Init(ui::LAYER_TEXTURED);
Browser::CreateParams params(&testing_profile_, true);
params.type = Browser::TYPE_NORMAL;
browser_window2_ =
std::make_unique<TestBrowserWindowAura>(std::move(window));
params.window = browser_window2_.get();
return std::unique_ptr<Browser>(Browser::Create(params));
}
void VerifyAppRunningDuration(const base::TimeDelta time_delta,
AppTypeName app_type_name) {
DictionaryPrefUpdate update(GetPrefService(), kAppRunningDuration);
std::string key = GetAppTypeHistogramName(app_type_name);
absl::optional<base::TimeDelta> unreported_duration =
util::ValueToTimeDelta(update->FindPath(key));
if (time_delta.is_zero()) {
EXPECT_FALSE(unreported_duration.has_value());
return;
}
ASSERT_TRUE(unreported_duration.has_value());
EXPECT_EQ(time_delta, unreported_duration.value());
}
void VerifyAppRunningDurationCountHistogram(base::HistogramBase::Count count,
AppTypeName app_type_name) {
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsRunningDurationHistogramNameForTest(
app_type_name),
count);
}
void VerifyAppRunningDurationHistogram(base::TimeDelta time_delta,
base::HistogramBase::Count count,
AppTypeName app_type_name) {
histogram_tester().ExpectTimeBucketCount(
AppPlatformMetrics::GetAppsRunningDurationHistogramNameForTest(
app_type_name),
time_delta, count);
}
void VerifyAppRunningPercentageCountHistogram(
base::HistogramBase::Count count,
AppTypeName app_type_name) {
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsRunningPercentageHistogramNameForTest(
app_type_name),
count);
}
void VerifyAppRunningPercentageHistogram(
int count,
base::HistogramBase::Count expected_count,
AppTypeName app_type_name) {
histogram_tester().ExpectBucketCount(
AppPlatformMetrics::GetAppsRunningPercentageHistogramNameForTest(
app_type_name),
count, expected_count);
}
void VerifyAppActivatedCount(int count, AppTypeName app_type_name) {
DictionaryPrefUpdate update(GetPrefService(), kAppActivatedCount);
std::string key = GetAppTypeHistogramName(app_type_name);
absl::optional<int> activated_count = update->FindIntPath(key);
if (count == 0) {
EXPECT_FALSE(activated_count.has_value());
return;
}
ASSERT_TRUE(activated_count.has_value());
EXPECT_EQ(count, activated_count.value());
}
void VerifyAppActivatedCountHistogram(base::HistogramBase::Count count,
AppTypeName app_type_name) {
histogram_tester().ExpectTotalCount(
AppPlatformMetrics::GetAppsActivatedCountHistogramNameForTest(
app_type_name),
count);
}
void VerifyAppActivatedHistogram(int count,
base::HistogramBase::Count expected_count,
AppTypeName app_type_name) {
histogram_tester().ExpectBucketCount(
AppPlatformMetrics::GetAppsActivatedCountHistogramNameForTest(
app_type_name),
count, expected_count);
}
void VerifyAppUsageTimeCountHistogram(base::HistogramBase::Count count,
AppTypeName app_type_name) {
histogram_tester_.ExpectTotalCount(
AppPlatformMetrics::GetAppsUsageTimeHistogramNameForTest(app_type_name),
count);
}
void VerifyAppUsageTimeHistogram(base::TimeDelta time_delta,
base::HistogramBase::Count count,
AppTypeName app_type_name) {
histogram_tester().ExpectTimeBucketCount(
AppPlatformMetrics::GetAppsUsageTimeHistogramNameForTest(app_type_name),
time_delta, count);
}
protected:
sync_preferences::TestingPrefServiceSyncable* GetPrefService() {
return testing_profile_.GetTestingPrefService();
}
int GetDayIdPref() {
return GetPrefService()->GetInteger(kAppPlatformMetricsDayId);
}
base::HistogramTester& histogram_tester() { return histogram_tester_; }
content::BrowserTaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
private:
TestingProfile testing_profile_;
base::HistogramTester histogram_tester_;
std::unique_ptr<AppPlatformMetricsService> app_platform_metrics_service_;
std::unique_ptr<TestBrowserWindowAura> browser_window1_;
std::unique_ptr<TestBrowserWindowAura> browser_window2_;
aura::test::TestWindowDelegate delegate1_;
aura::test::TestWindowDelegate delegate2_;
};
// Tests OnNewDay() is called after more than one day passes.
TEST_F(AppPlatformMetricsServiceTest, MoreThanOneDay) {
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1) +
base::TimeDelta::FromHours(1));
VerifyMetrics();
EXPECT_EQ(AppPlatformMetricsService::GetDayIdForTesting(base::Time::Now()),
GetDayIdPref());
}
// Tests OnNewDay() is called at midnight.
TEST_F(AppPlatformMetricsServiceTest, UntilMidnight) {
task_environment_.FastForwardBy(base::TimeDelta::FromHours(3));
VerifyMetrics();
EXPECT_EQ(AppPlatformMetricsService::GetDayIdForTesting(base::Time::Now()),
GetDayIdPref());
}
// Tests OnNewDay() is not called before midnight.
TEST_F(AppPlatformMetricsServiceTest, LessThanOneDay) {
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
histogram_tester().ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(AppTypeName::kArc),
/*expected_count=*/0);
EXPECT_EQ(AppPlatformMetricsService::GetDayIdForTesting(base::Time::Now()),
GetDayIdPref());
}
// Tests OnNewDay() is called after one day passes, even when the device is
// idle.
TEST_F(AppPlatformMetricsServiceTest, MoreThanOneDayDeviceIdle) {
SetScreenOff(true);
SetSuspendImminent();
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
VerifyMetrics();
EXPECT_EQ(AppPlatformMetricsService::GetDayIdForTesting(base::Time::Now()),
GetDayIdPref());
}
// Tests the UMA metrics that count the number of installed apps.
TEST_F(AppPlatformMetricsServiceTest, InstallApps) {
task_environment_.FastForwardBy(base::TimeDelta::FromHours(3));
VerifyMetrics();
InstallOneApp("aa", apps::mojom::AppType::kArc);
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
histogram_tester().ExpectTotalCount(
AppPlatformMetrics::GetAppsCountHistogramNameForTest(AppTypeName::kArc),
/*expected_count=*/2);
}
TEST_F(AppPlatformMetricsServiceTest, BrowserWindow) {
InstallOneApp(extension_misc::kChromeAppId, apps::mojom::AppType::kExtension);
BrowserList* active_browser_list = BrowserList::GetInstance();
// Expect BrowserList is empty at the beginning.
EXPECT_EQ(0U, active_browser_list->size());
std::unique_ptr<Browser> browser1 = CreateBrowserWithAuraWindow1();
EXPECT_EQ(1U, active_browser_list->size());
// Set the browser window active.
ModifyInstance(extension_misc::kChromeAppId,
browser1->window()->GetNativeWindow(), kActiveInstanceState);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppActivatedCount(/*expected_count=*/1, AppTypeName::kChromeBrowser);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(20));
// Set the browser window running in the background.
ModifyInstance(extension_misc::kChromeAppId,
browser1->window()->GetNativeWindow(), kInactiveInstanceState);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppRunningDuration(base::TimeDelta::FromMinutes(30),
AppTypeName::kChromeBrowser);
// Test multiple browsers.
std::unique_ptr<Browser> browser2 = CreateBrowserWithAuraWindow2();
EXPECT_EQ(2U, active_browser_list->size());
ModifyInstance(extension_misc::kChromeAppId,
browser2->window()->GetNativeWindow(), kActiveInstanceState);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppActivatedCount(/*expected_count=*/2, AppTypeName::kChromeBrowser);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(20));
ModifyInstance(extension_misc::kChromeAppId,
browser2->window()->GetNativeWindow(),
apps::InstanceState::kDestroyed);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppRunningDuration(base::TimeDelta::FromHours(1),
AppTypeName::kChromeBrowser);
// Test date change.
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
VerifyAppRunningDurationCountHistogram(/*expected_count=*/1,
AppTypeName::kChromeBrowser);
VerifyAppRunningDurationHistogram(base::TimeDelta::FromHours(1),
/*expected_count=*/1,
AppTypeName::kChromeBrowser);
VerifyAppRunningPercentageCountHistogram(/*expected_count=*/1,
AppTypeName::kChromeBrowser);
VerifyAppRunningPercentageHistogram(100,
/*expected_count=*/1,
AppTypeName::kChromeBrowser);
VerifyAppActivatedCountHistogram(/*expected_count=*/1,
AppTypeName::kChromeBrowser);
VerifyAppActivatedHistogram(/*count*/ 2, /*expected_count=*/1,
AppTypeName::kChromeBrowser);
}
// Tests the UMA metrics when launching an app in one day .
TEST_F(AppPlatformMetricsServiceTest, OpenWindowInOneDay) {
std::string app_id = "aa";
InstallOneApp(app_id, apps::mojom::AppType::kArc);
// Create a window to simulate launching the app.
auto window = std::make_unique<aura::Window>(nullptr);
window->Init(ui::LAYER_NOT_DRAWN);
ModifyInstance(app_id, window.get(), apps::InstanceState::kActive);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppActivatedCount(/*expected_count=*/1, AppTypeName::kArc);
// Close the window after running one hour.
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(50));
ModifyInstance(app_id, window.get(), apps::InstanceState::kDestroyed);
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
VerifyAppRunningDuration(base::TimeDelta::FromHours(1), AppTypeName::kArc);
// One day passes.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
VerifyAppRunningDurationCountHistogram(/*expected_count=*/1,
AppTypeName::kArc);
VerifyAppRunningDurationHistogram(base::TimeDelta::FromHours(1),
/*expected_count=*/1, AppTypeName::kArc);
VerifyAppActivatedCountHistogram(/*expected_count=*/1, AppTypeName::kArc);
VerifyAppActivatedHistogram(/*count*/ 1, /*expected_count=*/1,
AppTypeName::kArc);
VerifyAppRunningDuration(base::TimeDelta(), AppTypeName::kArc);
VerifyAppActivatedCount(/*expected_count=*/0, AppTypeName::kArc);
// One more day passes.
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
VerifyAppRunningDurationCountHistogram(/*expected_count=*/1,
AppTypeName::kArc);
VerifyAppRunningDurationHistogram(base::TimeDelta::FromHours(1),
/*expected_count=*/1, AppTypeName::kArc);
VerifyAppRunningPercentageCountHistogram(/*expected_count=*/1,
AppTypeName::kArc);
VerifyAppRunningPercentageHistogram(100,
/*expected_count=*/1, AppTypeName::kArc);
VerifyAppActivatedCountHistogram(/*expected_count=*/1, AppTypeName::kArc);
}
// Tests the UMA metrics when launching an app multiple days.
TEST_F(AppPlatformMetricsServiceTest, OpenWindowInMultipleDays) {
std::string app_id = "aa";
InstallOneApp(app_id, apps::mojom::AppType::kArc);
// Create a window to simulate launching the app.
auto window = std::make_unique<aura::Window>(nullptr);
window->Init(ui::LAYER_NOT_DRAWN);
ModifyInstance(app_id, window.get(), apps::InstanceState::kActive);
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
VerifyAppActivatedCount(/*expected_count=*/1, AppTypeName::kArc);
// One day passes.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(2));
VerifyAppRunningDurationCountHistogram(/*expected_count=*/1,
AppTypeName::kArc);
VerifyAppActivatedCountHistogram(/*expected_count=*/1, AppTypeName::kArc);
VerifyAppActivatedHistogram(/*count*/ 1, /*expected_count=*/1,
AppTypeName::kArc);
task_environment_.FastForwardBy(base::TimeDelta::FromHours(2));
// Close the window after running five hours.
ModifyInstance(app_id, window.get(), apps::InstanceState::kDestroyed);
VerifyAppRunningDurationCountHistogram(/*expected_count=*/1,
AppTypeName::kArc);
VerifyAppRunningDurationHistogram(base::TimeDelta::FromHours(3),
/*expected_count=*/1, AppTypeName::kArc);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppRunningDuration(base::TimeDelta::FromHours(2), AppTypeName::kArc);
// One more day passes.
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
VerifyAppRunningDurationCountHistogram(/*expected_count=*/2,
AppTypeName::kArc);
VerifyAppRunningDurationHistogram(base::TimeDelta::FromHours(3),
/*expected_count=*/1, AppTypeName::kArc);
VerifyAppRunningDurationHistogram(base::TimeDelta::FromHours(2),
/*expected_count=*/1, AppTypeName::kArc);
VerifyAppActivatedCountHistogram(/*expected_count=*/1, AppTypeName::kArc);
VerifyAppRunningDuration(base::TimeDelta::FromHours(0), AppTypeName::kArc);
VerifyAppActivatedCount(/*expected_count=*/0, AppTypeName::kArc);
}
// Tests the UMA metrics when an app window is reactivated.
TEST_F(AppPlatformMetricsServiceTest, ReactiveWindow) {
std::string app_id = "aa";
InstallOneApp(app_id, apps::mojom::AppType::kArc);
// Create a window to simulate launching the app.
auto window = std::make_unique<aura::Window>(nullptr);
window->Init(ui::LAYER_NOT_DRAWN);
ModifyInstance(app_id, window.get(), apps::InstanceState::kActive);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(30));
ModifyInstance(app_id, window.get(), kActiveInstanceState);
VerifyAppActivatedCount(/*expected_count=*/1, AppTypeName::kArc);
// Inactiva the window after running one hour.
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(30));
ModifyInstance(app_id, window.get(), kInactiveInstanceState);
// Activa the window after running one hour.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
ModifyInstance(app_id, window.get(), kActiveInstanceState);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppActivatedCount(/*expected_count=*/2, AppTypeName::kArc);
// Close the window after running half hour.
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(20));
ModifyInstance(app_id, window.get(), apps::InstanceState::kDestroyed);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppRunningDuration(
base::TimeDelta::FromHours(1) + base::TimeDelta::FromMinutes(30),
AppTypeName::kArc);
// One day passes.
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(20));
VerifyAppRunningDurationCountHistogram(/*expected_count=*/1,
AppTypeName::kArc);
VerifyAppRunningDurationHistogram(
base::TimeDelta::FromHours(1) + base::TimeDelta::FromMinutes(30),
/*expected_count=*/1, AppTypeName::kArc);
VerifyAppActivatedCountHistogram(/*expected_count=*/1, AppTypeName::kArc);
VerifyAppActivatedHistogram(/*count*/ 2, /*expected_count=*/1,
AppTypeName::kArc);
// 20 hours passes.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(20));
// Create a new window.
window = std::make_unique<aura::Window>(nullptr);
window->Init(ui::LAYER_NOT_DRAWN);
ModifyInstance(app_id, window.get(), kActiveInstanceState);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppActivatedCount(/*expected_count=*/1, AppTypeName::kArc);
// Inactiva the window after running one hour.
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(50));
ModifyInstance(app_id, window.get(), kInactiveInstanceState);
// Activa the window after running one hour.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
ModifyInstance(app_id, window.get(), kActiveInstanceState);
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
VerifyAppActivatedCount(/*expected_count=*/2, AppTypeName::kArc);
// One more day passes.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
VerifyAppRunningDurationCountHistogram(/*expected_count=*/2,
AppTypeName::kArc);
VerifyAppRunningDurationHistogram(base::TimeDelta::FromHours(3),
/*expected_count=*/1, AppTypeName::kArc);
VerifyAppActivatedCountHistogram(/*expected_count=*/2, AppTypeName::kArc);
VerifyAppActivatedHistogram(/*count*/ 2, /*expected_count=*/2,
AppTypeName::kArc);
// Inactiva the window after running one hour.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(3));
ModifyInstance(app_id, window.get(), kInactiveInstanceState);
// Close the window after running five hour.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
ModifyInstance(app_id, window.get(), apps::InstanceState::kDestroyed);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(10));
VerifyAppRunningDuration(base::TimeDelta::FromHours(3), AppTypeName::kArc);
// One more day passes.
task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
VerifyAppRunningDurationCountHistogram(/*expected_count=*/3,
AppTypeName::kArc);
VerifyAppRunningDurationHistogram(base::TimeDelta::FromHours(3),
/*expected_count=*/2, AppTypeName::kArc);
VerifyAppActivatedCountHistogram(/*expected_count=*/2, AppTypeName::kArc);
VerifyAppRunningDuration(base::TimeDelta::FromHours(0), AppTypeName::kArc);
VerifyAppActivatedCount(/*expected_count=*/0, AppTypeName::kArc);
}
// Tests the app running percentage UMA metrics when launch a browser window
// and an ARC app in one day.
TEST_F(AppPlatformMetricsServiceTest, AppRunningPercentrage) {
// Launch a browser window.
InstallOneApp(extension_misc::kChromeAppId, apps::mojom::AppType::kExtension);
std::unique_ptr<Browser> browser = CreateBrowserWithAuraWindow1();
EXPECT_EQ(1U, BrowserList::GetInstance()->size());
// Set the browser window active.
ModifyInstance(extension_misc::kChromeAppId,
browser->window()->GetNativeWindow(), kActiveInstanceState);
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
// Set the browser window running in the background.
ModifyInstance(extension_misc::kChromeAppId,
browser->window()->GetNativeWindow(), kInactiveInstanceState);
// Launch an ARC app.
std::string app_id = "aa";
InstallOneApp(app_id, apps::mojom::AppType::kArc);
// Create a window to simulate launching the app.
auto window = std::make_unique<aura::Window>(nullptr);
window->Init(ui::LAYER_NOT_DRAWN);
ModifyInstance(app_id, window.get(), apps::InstanceState::kActive);
// Close the window after running one hour.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
ModifyInstance(app_id, window.get(), apps::InstanceState::kDestroyed);
// One day passes.
task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
VerifyAppRunningPercentageCountHistogram(/*expected_count=*/1,
AppTypeName::kChromeBrowser);
VerifyAppRunningPercentageCountHistogram(/*expected_count=*/1,
AppTypeName::kArc);
VerifyAppRunningPercentageHistogram(50,
/*expected_count=*/1,
AppTypeName::kChromeBrowser);
VerifyAppRunningPercentageHistogram(50,
/*expected_count=*/1, AppTypeName::kArc);
}
TEST_F(AppPlatformMetricsServiceTest, UsageTime) {
// Create an ARC app window.
std::string app_id = "aa";
InstallOneApp(app_id, apps::mojom::AppType::kArc);
auto window = std::make_unique<aura::Window>(nullptr);
window->Init(ui::LAYER_NOT_DRAWN);
ModifyInstance(app_id, window.get(), apps::InstanceState::kActive);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(5));
VerifyAppUsageTimeCountHistogram(/*expected_count=*/1, AppTypeName::kArc);
VerifyAppUsageTimeHistogram(base::TimeDelta::FromMinutes(5),
/*expected_count=*/1, AppTypeName::kArc);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(2));
ModifyInstance(app_id, window.get(), kInactiveInstanceState);
// Create a browser window
InstallOneApp(extension_misc::kChromeAppId, apps::mojom::AppType::kExtension);
std::unique_ptr<Browser> browser = CreateBrowserWithAuraWindow1();
EXPECT_EQ(1U, BrowserList::GetInstance()->size());
// Set the browser window active.
ModifyInstance(extension_misc::kChromeAppId,
browser->window()->GetNativeWindow(), kActiveInstanceState);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(3));
VerifyAppUsageTimeCountHistogram(/*expected_count=*/2, AppTypeName::kArc);
VerifyAppUsageTimeHistogram(base::TimeDelta::FromMinutes(2),
/*expected_count=*/1, AppTypeName::kArc);
VerifyAppUsageTimeCountHistogram(/*expected_count=*/1,
AppTypeName::kChromeBrowser);
VerifyAppUsageTimeHistogram(base::TimeDelta::FromMinutes(3),
/*expected_count=*/1,
AppTypeName::kChromeBrowser);
task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(15));
VerifyAppUsageTimeCountHistogram(/*expected_count=*/2, AppTypeName::kArc);
VerifyAppUsageTimeCountHistogram(/*expected_count=*/4,
AppTypeName::kChromeBrowser);
VerifyAppUsageTimeHistogram(base::TimeDelta::FromMinutes(5),
/*expected_count=*/3,
AppTypeName::kChromeBrowser);
}
} // namespace apps